using System.Collections.Generic;
using System;
namespace S22.Sasl {
///
/// The abstract base class from which all classes implementing a Sasl
/// authentication mechanism must derive.
///
public abstract class SaslMechanism {
///
/// IANA name of the authentication mechanism.
///
public abstract string Name {
get;
}
///
/// True if the authentication exchange between client and server
/// has been completed.
///
public abstract bool IsCompleted {
get;
}
///
/// True if the mechanism requires initiation by the client.
///
public abstract bool HasInitial {
get;
}
///
/// A map of mechanism-specific properties which are needed by the
/// authentication mechanism to compute it's challenge-responses.
///
public Dictionary Properties {
get;
private set;
}
///
/// Computes the client response to a challenge sent by the server.
///
///
/// The client response to the specified challenge.
protected abstract byte[] ComputeResponse(byte[] challenge);
///
///
public SaslMechanism() {
Properties = new Dictionary();
}
///
/// Retrieves the base64-encoded client response for the specified
/// base64-encoded challenge sent by the server.
///
/// A base64-encoded string representing a challenge
/// sent by the server.
/// A base64-encoded string representing the client response to the
/// server challenge.
/// The IMAP, POP3 and SMTP authentication commands expect challenges
/// and responses to be base64-encoded. This method automatically decodes the
/// server challenge before passing it to the Sasl implementation and
/// encodes the client response to a base64-string before returning it to the
/// caller.
/// The client response could not be retrieved.
/// Refer to the inner exception for error details.
public string GetResponse(string challenge) {
try {
byte[] data = String.IsNullOrEmpty(challenge) ? new byte[0] :
Convert.FromBase64String(challenge);
byte[] response = ComputeResponse(data);
return Convert.ToBase64String(response);
} catch (Exception e) {
throw new SaslException("The challenge-response could not be " +
"retrieved.", e);
}
}
///
/// Retrieves the client response for the specified server challenge.
///
/// A byte array containing the challenge sent by
/// the server.
/// An array of bytes representing the client response to the
/// server challenge.
public byte[] GetResponse(byte[] challenge) {
return ComputeResponse(challenge);
}
}
}