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); } } }