using S22.Sasl.Mechanisms.Ntlm; using System; namespace S22.Sasl.Mechanisms { /// /// Implements the Sasl NTLMv2 authentication method which addresses /// some of the security issues present in NTLM version 1. /// internal class SaslNtlmv2 : SaslNtlm { /// /// Private constructor for use with Sasl.SaslFactory. /// protected SaslNtlmv2() { // Nothing to do here. } /// /// Creates and initializes a new instance of the SaslNtlmv2 class /// using the specified username and password. /// /// The username to authenticate with. /// The plaintext password to authenticate /// with. /// Thrown if the username /// or the password parameter is null. /// Thrown if the username /// parameter is empty. public SaslNtlmv2(string username, string password) : base(username, password) { } /// /// Computes the client response to the specified NTLM challenge. /// /// The challenge sent by the server /// The response to the NTLM challenge. /// Thrown if the response could not /// be computed. protected override byte[] ComputeResponse(byte[] challenge) { if (step == 1) completed = true; byte[] ret = step == 0 ? ComputeInitialResponse(challenge) : ComputeChallengeResponse(challenge); step = step + 1; return ret; } /// /// Computes the actual challenge response to an NTLM challenge /// which is sent as part of an NTLM type 2 message. /// /// The challenge sent by the server. /// The response to the NTLM challenge. /// Thrown if the challenge /// response could not be computed. protected new byte[] ComputeChallengeResponse(byte[] challenge) { try { Type2Message msg = Type2Message.Deserialize(challenge); // This creates an NTLMv2 challenge response. byte[] data = new Type3Message(Username, Password, msg.Challenge, Username, true, msg.TargetName, msg.RawTargetInformation).Serialize(); return data; } catch (Exception e) { throw new SaslException("The challenge response could not be " + "computed.", e); } } } }