/// <summary> /// Reset the state of the SASL mechanism. /// </summary> /// <remarks> /// Resets the state of the SASL mechanism. /// </remarks> public override void Reset() { negotiatedChannelBinding = false; state = LoginState.Negotiate; negotiate = null; base.Reset(); }
public void TestCreateNegotiationMessage() { var data = Convert.FromBase64String("TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAGAvAjAAAADw=="); var message = new NtlmNegotiateMessage(data); Assert.IsTrue(message.Type == MessageType.Negotiation); }
NtlmAuthenticateMessage GetChallengeResponse(string domain, string userName, string password, byte[] token, int startIndex, int length) { var challenge = new NtlmChallengeMessage(token, startIndex, length); var authenticate = new NtlmAuthenticateMessage(negotiate, challenge, userName, password, domain, Workstation) { ClientChallenge = Nonce, Timestamp = Timestamp }; byte[] channelBindingToken = null; if (AllowChannelBinding && challenge.TargetInfo != null) { // Only bother with attempting to channel-bind if the CHALLENGE_MESSAGE's TargetInfo is not NULL. // Not sure which channel-binding types are supported by NTLM, but I am told that supposedly the // System.Net.Mail.SmtpClient uses tls-unique, so we'll go with that... negotiatedChannelBinding = TryGetChannelBindingToken(ChannelBindingKind.Endpoint, out channelBindingToken); } authenticate.ComputeNtlmV2(ServicePrincipalName, IsUnverifiedServicePrincipalName, channelBindingToken); if (channelBindingToken != null) { Array.Clear(channelBindingToken, 0, channelBindingToken.Length); } negotiate = null; return(authenticate); }
public void TestParseNtlmNegotiationMessage() { const string originHex = "4e544c4d53535000010000000732000006000600330000000b000b0028000000050093080000000f574f524b53544154494f4e444f4d41494e"; var message1 = NtlmNegotiateMessage.Parse(originHex.HexToBytes()); Assert.IsTrue(message1.Signature == Constants.Ntlmssp); Assert.IsTrue(message1.Type == MessageType.Negotiation); Assert.IsTrue(message1.Flags == (MessageFlag.NegotiateUnicode | MessageFlag.NegotiateOem | MessageFlag.RequestTarget | MessageFlag.NegotiateNtlm | MessageFlag.NegotiateDomainSupplied | MessageFlag.NegotiateWorkstationSupplied)); Assert.IsTrue(message1.Message.DomainNameLength == 6); Assert.IsTrue(message1.Message.DomainNameSpace == 6); Assert.IsTrue(message1.Message.DomainNameOffset == 51); Assert.IsTrue(message1.Message.HostNameLength == 11); Assert.IsTrue(message1.Message.HostNameSpace == 11); Assert.IsTrue(message1.Message.HostNameOffset == 40); Assert.IsTrue(message1.Message.OsMajorVersion == 5); Assert.IsTrue(message1.Message.OsMinorVersion == 0); Assert.IsTrue(message1.Message.OsBuildNumber == 2195); Assert.IsTrue(message1.Domain == "DOMAIN"); Assert.IsTrue(message1.Host == "WORKSTATION"); var actualHex = message1.ToBytes().BytesToHex(); Assert.IsTrue(originHex.Equals(actualHex, StringComparison.InvariantCultureIgnoreCase)); }
// Example from http://www.innovation.ch/java/ntlm.html public void TestEncodeJavaExample() { var type1 = new NtlmNegotiateMessage(NtlmFlags.NegotiateUnicode | NtlmFlags.NegotiateOem | NtlmFlags.RequestTarget | NtlmFlags.NegotiateNtlm | NtlmFlags.NegotiateAlwaysSign, "Ursa-Minor", "LightCity"); Assert.AreEqual(1, type1.Type, "Type"); Assert.AreEqual((NtlmFlags)0xb207, type1.Flags, "Flags"); Assert.AreEqual("4E-54-4C-4D-53-53-50-00-01-00-00-00-07-B2-00-00-0A-00-0A-00-29-00-00-00-09-00-09-00-20-00-00-00-4C-49-47-48-54-43-49-54-59-55-52-53-41-2D-4D-49-4E-4F-52", BitConverter.ToString(type1.Encode()), "Encode"); }
// Example from http://www.innovation.ch/java/ntlm.html public void TestEncodeJavaExample() { var type1 = new NtlmNegotiateMessage(NtlmFlags.NegotiateUnicode | NtlmFlags.NegotiateOem | NtlmFlags.RequestTarget | NtlmFlags.NegotiateNtlm | NtlmFlags.NegotiateAlwaysSign, "Ursa-Minor", "LightCity"); Assert.AreEqual(1, type1.Type, "Type"); Assert.AreEqual((NtlmFlags)0xb207, type1.Flags, "Flags"); Assert.AreEqual("TlRMTVNTUAABAAAAB7IAAAoACgAxAAAACQAJACgAAAAAAAAAAAAAAExJR0hUQ0lUWVVSU0EtTUlOT1I=", Convert.ToBase64String(type1.Encode()), "Encode"); }
// Example from http://davenport.sourceforge.net/ntlm.html#NtlmNegotiateMessageExample public void TestDecodeDavenportExample() { byte[] rawData = { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x32, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x20, 0x00, 0x00, 0x00, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x54, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x44, 0x4f, 0x4d, 0x41, 0x49, 0x4e }; var type1 = new NtlmNegotiateMessage(rawData, 0, rawData.Length); Assert.AreEqual(1, type1.Type, "Type"); Assert.AreEqual((NtlmFlags)0x3207, type1.Flags, "Flags"); Assert.AreEqual("DOMAIN", type1.Domain, "Domain"); Assert.AreEqual("WORKSTATION", type1.Workstation, "Workstation"); }
// Example from http://www.innovation.ch/java/ntlm.html public void TestDecodeJavaExample() { byte[] rawData = { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0xb2, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x29, 0x00, 0x00, 0x00, 0x09, 0x00, 0x09, 0x00, 0x20, 0x00, 0x00, 0x00, 0x4c, 0x49, 0x47, 0x48, 0x54, 0x43, 0x49, 0x54, 0x59, 0x55, 0x52, 0x53, 0x41, 0x2d, 0x4d, 0x49, 0x4e, 0x4f, 0x52 }; var type1 = new NtlmNegotiateMessage(rawData, 0, rawData.Length); Assert.AreEqual(1, type1.Type, "Type"); Assert.AreEqual((NtlmFlags)0xb203, type1.Flags, "Flags"); Assert.AreEqual("URSA-MINOR", type1.Domain, "Domain"); Assert.AreEqual("LIGHTCITY", type1.Workstation, "Workstation"); }
/// <summary> /// Parse the server's challenge token and return the next challenge response. /// </summary> /// <remarks> /// Parses the server's challenge token and returns the next challenge response. /// </remarks> /// <returns>The next challenge response.</returns> /// <param name="token">The server's challenge token.</param> /// <param name="startIndex">The index into the token specifying where the server's challenge begins.</param> /// <param name="length">The length of the server's challenge.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.NotSupportedException"> /// The SASL mechanism does not support SASL-IR. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="SaslException"> /// An error has occurred while parsing the server's challenge token. /// </exception> protected override byte[] Challenge(byte[] token, int startIndex, int length, CancellationToken cancellationToken) { if (IsAuthenticated) { return(null); } string userName = Credentials.UserName; string domain = Credentials.Domain; NtlmMessageBase message = null; if (string.IsNullOrEmpty(domain)) { int index; if ((index = userName.LastIndexOf('@')) != -1) { domain = userName.Substring(index + 1); userName = userName.Substring(0, index); } else { if ((index = userName.IndexOf('\\')) == -1) { index = userName.IndexOf('/'); } if (index >= 0) { domain = userName.Substring(0, index); userName = userName.Substring(index + 1); } } } switch (state) { case LoginState.Negotiate: message = negotiate = new NtlmNegotiateMessage(domain, Workstation, OSVersion); state = LoginState.Challenge; break; case LoginState.Challenge: var password = Credentials.Password; message = GetChallengeResponse(domain, userName, password, token, startIndex, length); IsAuthenticated = true; break; } return(message?.Encode()); }
public void TestArgumentExceptions() { byte[] badMessageData = { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x01, 0x00, 0x00, 0x00, 0x00 }; var NtlmNegotiate = new NtlmNegotiateMessage(); var NtlmChallenge = new NtlmChallengeMessage(); var NtlmAuthenticate = new NtlmAuthenticateMessage(NtlmNegotiate, NtlmChallenge, "username", "password", "domain", "workstation"); Assert.Throws <ArgumentNullException> (() => new NtlmAuthenticateMessage(null, NtlmChallenge, "username", "password", "domain", "workstation")); Assert.Throws <ArgumentNullException> (() => new NtlmAuthenticateMessage(NtlmNegotiate, null, "username", "password", "domain", "workstation")); Assert.Throws <ArgumentNullException> (() => new NtlmAuthenticateMessage(NtlmNegotiate, NtlmChallenge, null, "password", "domain", "workstation")); Assert.Throws <ArgumentNullException> (() => new NtlmAuthenticateMessage(NtlmNegotiate, NtlmChallenge, "username", null, "domain", "workstation")); Assert.Throws <ArgumentNullException> (() => new NtlmAuthenticateMessage(null, 0, 16)); Assert.Throws <ArgumentOutOfRangeException> (() => new NtlmAuthenticateMessage(new byte[8], 0, 8)); Assert.Throws <ArgumentOutOfRangeException> (() => new NtlmAuthenticateMessage(new byte[8], -1, 8)); Assert.Throws <ArgumentException> (() => new NtlmAuthenticateMessage(badMessageData, 0, badMessageData.Length)); Assert.DoesNotThrow(() => NtlmAuthenticate.ClientChallenge = null); Assert.Throws <ArgumentException> (() => NtlmAuthenticate.ClientChallenge = new byte[9]); }