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