/// <summary>
        /// Creates the NTLM negotiate (Type 1) message.
        /// </summary>
        protected override void BuildMessage()
        {
            int initialLength = SignatureLength + MessageTypeLength + FlagsLength + SecurityBufferLength * 2 + VersionLength;

            int domainBytesLength = 0;

            if (domainBytes != null)
            {
                domainBytesLength = domainBytes.Length;
            }

            int hostBytesLength = 0;

            if (hostBytes != null)
            {
                hostBytesLength = hostBytes.Length;
            }

            // Now, build the message. Calculate its length first, including
            // signature or type.
            int finalLength = initialLength + hostBytesLength + domainBytesLength;

            // Set up the response. This will initialize the signature, message
            // type, and flags.
            InitializeMessage(finalLength, NtlmMessageType.Negotiate);

            // Flags. These are the complete set of flags we support.
            AddUInt((uint)flags);

            // Domain length (two times).
            AddUShort(domainBytesLength);
            AddUShort(domainBytesLength);

            // Domain offset.
            AddUInt(Convert.ToUInt32(hostBytesLength + initialLength));

            // Host length (two times).
            AddUShort(hostBytesLength);
            AddUShort(hostBytesLength);

            // Host offset (always 32 + 8).
            AddUInt(Convert.ToUInt32(initialLength));

            // Add version (for debugging purposes)
            NtlmVersion version = new NtlmVersion(5, 1, 2600);

            AddBytes(version.AsBytes());

            // Host (workstation) String.
            if (hostBytes != null)
            {
                AddBytes(hostBytes);
            }

            // Domain String.
            if (domainBytes != null)
            {
                AddBytes(domainBytes);
            }
        }
Пример #2
0
        /// <summary>
        /// Creates the NTLM authenticate (Type 3) message.
        /// </summary>
        protected override void BuildMessage()
        {
            int ntlmResponseLength = ntlmResponse.Length;
            int lmResponseLength   = lmResponse.Length;

            int domainLength = domainBytes != null ? domainBytes.Length : 0;
            int hostLength   = hostBytes != null ? hostBytes.Length : 0;
            int userLength   = userBytes.Length;
            int sessionKeyLength;

            if (sessionKey != null)
            {
                sessionKeyLength = sessionKey.Length;
            }
            else
            {
                sessionKeyLength = 0;
            }

            // Calculate the layout within the packet
            int lmResponseOffset = 72;

            if (isMessageIntegrityCodeRequired)
            {
                lmResponseOffset += 16;
            }

            int ntlmResponseOffset = lmResponseOffset + lmResponseLength;
            int domainOffset       = ntlmResponseOffset + ntlmResponseLength;
            int userOffset         = domainOffset + domainLength;
            int hostOffset         = userOffset + userLength;
            int sessionKeyOffset   = hostOffset + hostLength;
            int finalLength        = sessionKeyOffset + sessionKeyLength;

            // Start the response. Length includes signature and type
            InitializeMessage(finalLength, NtlmMessageType.Authenticate);

            // LM Resp Length (twice)
            AddUShort(lmResponseLength);
            AddUShort(lmResponseLength);

            // LM Resp Offset
            AddUInt(Convert.ToUInt32(lmResponseOffset));

            // NT Resp Length (twice)
            AddUShort(ntlmResponseLength);
            AddUShort(ntlmResponseLength);

            // NT Resp Offset
            AddUInt(Convert.ToUInt32(ntlmResponseOffset));

            // Domain length (twice)
            AddUShort(domainLength);
            AddUShort(domainLength);

            // Domain offset.
            AddUInt(Convert.ToUInt32(domainOffset));

            // User Length (twice)
            AddUShort(userLength);
            AddUShort(userLength);

            // User offset
            AddUInt(Convert.ToUInt32(userOffset));

            // Host length (twice)
            AddUShort(hostLength);
            AddUShort(hostLength);

            // Host offset
            AddUInt(Convert.ToUInt32(hostOffset));

            // Session key length (twice)
            AddUShort(sessionKeyLength);
            AddUShort(sessionKeyLength);

            // Session key offset
            AddUInt(Convert.ToUInt32(sessionKeyOffset));

            // Flags.
            AddUInt((uint)negotiatedOptionFlags);

            // OS version values (only used for debugging purposes,
            // so we are hard-coding 5.1.2600, or Windows XP). A
            // future version should likely query the actual OS.
            NtlmVersion version = new NtlmVersion(5, 1, 2600);

            AddBytes(version.AsBytes());

            int micPosition = -1;

            if (isMessageIntegrityCodeRequired)
            {
                micPosition            = CurrentOutputPosition;
                CurrentOutputPosition += 16;
            }

            // Add the actual data
            AddBytes(lmResponse);
            AddBytes(ntlmResponse);
            AddBytes(domainBytes);
            AddBytes(userBytes);
            AddBytes(hostBytes);
            if (sessionKey != null)
            {
                AddBytes(sessionKey);
            }

            // Write the mic back into its slot in the message
            if (isMessageIntegrityCodeRequired)
            {
                // Computation of message integrity code (MIC) as specified
                // in [MS-NLMP] section 3.2.5.1.2.
                List <byte> data = new List <byte>();
                data.AddRange(type1Message);
                data.AddRange(type2Message);
                data.AddRange(MessageContents);
                byte[] mic;
                using (HMACMD5 hmac = new HMACMD5(exportedSessionKey))
                {
                    mic = hmac.ComputeHash(data.ToArray());
                }

                Array.Copy(mic, 0, MessageContents, micPosition, mic.Length);
            }
        }