Пример #1
0
 /// <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();
 }
Пример #2
0
        public void TestCreateNegotiationMessage()
        {
            var data    = Convert.FromBase64String("TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAGAvAjAAAADw==");
            var message = new NtlmNegotiateMessage(data);

            Assert.IsTrue(message.Type == MessageType.Negotiation);
        }
Пример #3
0
        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));
        }
Пример #5
0
        // 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");
        }
Пример #6
0
        // 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");
        }
Пример #7
0
        // 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");
        }
Пример #8
0
        // 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");
        }
Пример #9
0
        /// <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());
        }
Пример #10
0
        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]);
        }