Пример #1
0
        /// <summary>
        /// initialize the response of challenge
        /// </summary>
        /// <param name="flags">the flag for challenge</param>
        /// <param name="challenge">the challenge packet</param>
        /// <param name="targetInfo">the target info of avpairs</param>
        /// <param name="responseKeyLM">the response lm key</param>
        /// <param name="lmChallengeResponse">the challenge lm response</param>
        /// <param name="ntChallengeResponse">the nt challenge response</param>
        private void InitializeChallengeResponse(
            NegotiateTypes flags,
            NlmpChallengePacket challenge,
            ICollection <AV_PAIR> targetInfo,
            out byte[] responseKeyLM,
            out byte[] lmChallengeResponse,
            out byte[] ntChallengeResponse
            )
        {
            // responseKeyNT
            byte[] responseKeyNT = NlmpUtility.GetResponseKeyNt(
                this.client.Config.Version, this.currentActiveCredential.DomainName,
                this.currentActiveCredential.AccountName, this.currentActiveCredential.Password);

            // responseKeyLM
            responseKeyLM = NlmpUtility.GetResponseKeyLm(
                this.client.Config.Version, this.currentActiveCredential.DomainName,
                this.currentActiveCredential.AccountName, this.currentActiveCredential.Password);

            // lmChallengeResponse
            lmChallengeResponse = null;

            // ntChallengeResponse
            ntChallengeResponse = null;

            ComputeResponse(
                flags, challenge.Payload.ServerChallenge, targetInfo, responseKeyNT, responseKeyLM,
                out lmChallengeResponse, out ntChallengeResponse);

            UpdateLmChallengeResponse(targetInfo, ref lmChallengeResponse);
        }
Пример #2
0
        /// <summary>
        /// initialize the exportedSessionKey and internal keys
        /// </summary>
        /// <param name="flags">the flags of challenge</param>
        /// <param name="challenge">the challenge packet</param>
        /// <param name="responseKeyLM">the response key lm</param>
        /// <param name="lmChallengeResponse">the challenge response lm</param>
        /// <param name="encryptedRandomSessionKey">the encrypted random session key</param>
        /// <param name="exportedSessionKey">the exported session key</param>
        private void InitializeKeys(
            NegotiateTypes flags,
            NlmpChallengePacket challenge,
            byte[] responseKeyLM,
            byte[] lmChallengeResponse,
            out byte[] encryptedRandomSessionKey,
            out byte[] exportedSessionKey
            )
        {
            // keyExchangeKey
            byte[] keyExchangeKey = null;

            // get random session key
            NlmpUtility.GetEncryptedRandomSessionKey(
                this.client.Config.Version, flags, this.client.Context.SessionBaseKey, lmChallengeResponse,
                responseKeyLM, challenge.Payload.ServerChallenge, out encryptedRandomSessionKey, out keyExchangeKey,
                out exportedSessionKey);

            this.client.Context.ClientSigningKey = NlmpUtility.SignKey(flags, exportedSessionKey, "Client");
            this.client.Context.ServerSigningKey = NlmpUtility.SignKey(flags, exportedSessionKey, "Server");
            this.client.Context.ClientSealingKey = NlmpUtility.SealKey(flags, exportedSessionKey, "Client");
            this.client.Context.ServerSealingKey = NlmpUtility.SealKey(flags, exportedSessionKey, "Server");

            NlmpUtility.RC4Init(this.client.Context.ClientHandle, this.client.Context.ClientSealingKey);
            NlmpUtility.RC4Init(this.client.Context.ServerHandle, this.client.Context.ServerSealingKey);
        }
        /// <summary>
        /// create a challenge packet. This packet contains CHALLENGE_MESSAGE. The CHALLENGE_MESSAGE defines an NTLM
        /// challenge message that is sent from the server to the client. The CHALLENGE_MESSAGE is used by the server
        /// to challenge the client to prove its identity.
        /// </summary>
        /// <param name="negotiateFlags">The client sets flags to indicate options it supports.</param>
        /// <param name="version">
        /// This structure is used for debugging purposes only. In normal (non-debugging) protocol messages, it is
        /// ignored and does not affect the NTLM message processing.
        /// </param>
        /// <param name="serverChallenge">contains the NTLM challenge. The challenge is a 64-bit nonce.</param>
        /// <param name="targetName">
        /// TargetName contains the name of the server authentication realm, and MUST be expressed in the negotiated
        /// character set. A server that is a member of a domain returns the domain of which it is a member, and a
        /// server that is not a member of a domain returns the server name. This param can be null.
        /// </param>
        /// <param name="targetInfo">
        /// TargetInfo contains a sequence of AV_PAIR structures.This param can be null.
        /// </param>
        /// <returns>the NlmpChallengePacket</returns>
        /// <noException></noException>
        public NlmpChallengePacket CreateChallengePacket(
            NegotiateTypes negotiateFlags,
            VERSION version,
            ulong serverChallenge,
            string targetName,
            ICollection <AV_PAIR> targetInfo
            )
        {
            NlmpChallengePacket packet = new NlmpChallengePacket();

            packet.SetNegotiateFlags(negotiateFlags);

            if (NlmpUtility.IsVersionRequired(negotiateFlags))
            {
                packet.SetVersion(version);
            }

            packet.SetServerChallenge(serverChallenge);

            if (NlmpUtility.IsDomainType(negotiateFlags) || NlmpUtility.IsServerType(negotiateFlags))
            {
                packet.SetTargetName(targetName);
            }

            // generate bytes of targetinfo
            byte[] targetInfoBytes = NlmpUtility.AvPairCollectionGetBytes(targetInfo);

            // initialize targetinfofield
            packet.SetTargetInfo(targetInfoBytes);

            return(packet);
        }
Пример #4
0
        /// <summary>
        /// compute response
        /// </summary>
        /// <param name="flags">the flags for challenge</param>
        /// <param name="serverChallenge">the server challenge</param>
        /// <param name="targetInfo">the target info contains avpairs</param>
        /// <param name="responseKeyNT">the response nt key</param>
        /// <param name="responseKeyLM">the response lm key</param>
        /// <param name="lmChallengeResponse">the challenge response lm</param>
        /// <param name="ntChallengeResponse">the challenge response nt</param>
        private void ComputeResponse(
            NegotiateTypes flags,
            ulong serverChallenge,
            ICollection <AV_PAIR> targetInfo,
            byte[] responseKeyNT,
            byte[] responseKeyLM,
            out byte[] lmChallengeResponse,
            out byte[] ntChallengeResponse
            )
        {
            // clientChallenge, a random 8 bytes.
            ulong clientChallenge = NlmpUtility.BytesToSecurityUInt64(NlmpUtility.Nonce(8));

            // time
            ulong time = 0;

            if (!NlmpUtility.IsNtlmV1(this.client.Config.Version))
            {
                time = NlmpUtility.GetTime(targetInfo);
            }

            byte[] sessionBaseKey = null;

            // compute response
            NlmpUtility.ComputeResponse(
                this.client.Config.Version, flags, responseKeyNT, responseKeyLM, serverChallenge, clientChallenge,
                time, NlmpUtility.AvPairCollectionGetBytes(targetInfo), out ntChallengeResponse,
                out lmChallengeResponse, out sessionBaseKey);

            // save key to context
            this.client.Context.SessionBaseKey = sessionBaseKey;
        }
        /// <summary>
        /// create a challenge packet. This packet contains CHALLENGE_MESSAGE. The CHALLENGE_MESSAGE defines an NTLM 
        /// challenge message that is sent from the server to the client. The CHALLENGE_MESSAGE is used by the server  
        /// to challenge the client to prove its identity.
        /// </summary>
        /// <param name="negotiateFlags">The client sets flags to indicate options it supports.</param>
        /// <param name="version">
        /// This structure is used for debugging purposes only. In normal (non-debugging) protocol messages, it is
        /// ignored and does not affect the NTLM message processing.
        /// </param>
        /// <param name="serverChallenge">contains the NTLM challenge. The challenge is a 64-bit nonce.</param>
        /// <param name="targetName">
        /// TargetName contains the name of the server authentication realm, and MUST be expressed in the negotiated 
        /// character set. A server that is a member of a domain returns the domain of which it is a member, and a 
        /// server that is not a member of a domain returns the server name. This param can be null.
        /// </param>
        /// <param name="targetInfo">
        /// TargetInfo contains a sequence of AV_PAIR structures.This param can be null.
        /// </param>
        /// <returns>the NlmpChallengePacket</returns>
        /// <noException></noException>
        public NlmpChallengePacket CreateChallengePacket(
            NegotiateTypes negotiateFlags,
            VERSION version,
            ulong serverChallenge,
            string targetName,
            ICollection<AV_PAIR> targetInfo
            )
        {
            NlmpChallengePacket packet = new NlmpChallengePacket();

            packet.SetNegotiateFlags(negotiateFlags);

            if (NlmpUtility.IsVersionRequired(negotiateFlags))
            {
                packet.SetVersion(version);
            }

            packet.SetServerChallenge(serverChallenge);

            if (NlmpUtility.IsDomainType(negotiateFlags) || NlmpUtility.IsServerType(negotiateFlags))
            {
                packet.SetTargetName(targetName);
            }

            // generate bytes of targetinfo
            byte[] targetInfoBytes = NlmpUtility.AvPairCollectionGetBytes(targetInfo);

            // initialize targetinfofield
            packet.SetTargetInfo(targetInfoBytes);

            return packet;
        }
        /// <summary>
        /// initialize the negotiate flags
        /// </summary>
        /// <returns>the negotiate flags for authenticate</returns>
        private NegotiateTypes InitializeNegotiateFlags()
        {
            NegotiateTypes flags = this.Context.ClientConfigFlags;

            flags |= NegotiateTypes.NTLMSSP_NEGOTIATE_TARGET_INFO;

            return(flags);
        }
Пример #7
0
        /// <summary>
        /// get the security token,using the token from server
        /// </summary>
        /// <param name="serverToken">the token from server challenge</param>
        /// <returns>the security token</returns>
        private byte[] GetSecurityToken(
            byte[] serverToken
            )
        {
            if (this.client == null)
            {
                throw new InvalidOperationException("The client is null! You must initialize this field first!");
            }

            // the challenge packet from server
            NlmpChallengePacket challenge = new NlmpChallengePacket(serverToken);

            NegotiateTypes flags = InitializeNegotiateFlags(challenge.Payload.NegotiateFlags);

            // the target info
            ICollection <AV_PAIR> targetInfo = InitializeTargetInfo(challenge.Payload.TargetInfo);

            // responseKeyLM
            byte[] responseKeyLM;

            // lmChallengeResponse
            byte[] lmChallengeResponse;

            // ntChallengeResponse
            byte[] ntChallengeResponse;

            // initialize the challenge response
            InitializeChallengeResponse(
                flags, challenge, targetInfo, out responseKeyLM, out lmChallengeResponse, out ntChallengeResponse);

            // encryptedRandomSessionKey
            byte[] encryptedRandomSessionKey = null;

            // exportedSessionKey
            byte[] exportedSessionKey = null;

            // initialize keys
            InitializeKeys(
                flags, challenge, responseKeyLM, lmChallengeResponse, out encryptedRandomSessionKey,
                out exportedSessionKey);

            // save the exported sessionkey
            this.client.Context.ExportedSessionKey = exportedSessionKey;

            // create challenge packet
            NlmpAuthenticatePacket packet = this.client.CreateAuthenticatePacket(
                flags, NlmpUtility.GetVersion(), lmChallengeResponse, ntChallengeResponse,
                this.currentActiveCredential.DomainName, this.currentActiveCredential.AccountName,
                Environment.MachineName, encryptedRandomSessionKey);

            // initialize the mic of challenge packet
            InitializeChallengeMIC(exportedSessionKey, targetInfo, packet, challenge);

            return(packet.ToBytes());
        }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="flags">Negotiation flags.</param>
 /// <param name="clientCredential">Client account credential.</param>
 /// <param name="isDomainJoined">Joined in a domain or not</param>
 /// <param name="netbiosDomainName">Netbios domain name.</param>
 /// <param name="netbiosMachineName">Netbios machine name.</param>
 public NlmpServerSecurityConfig(
     NegotiateTypes flags,
     NlmpClientCredential clientCredential,
     bool isDomainJoined,
     string netbiosDomainName,
     string netbiosMachineName)
     : base(SecurityPackageType.Ntlm)
 {
     this.negotiateflags = flags;
     this.clientCredential = clientCredential;
     this.isDomainJoined = isDomainJoined;
     this.netbiosDomainName = netbiosDomainName;
     this.netbiosMachineName = netbiosMachineName;
     this.targetName = clientCredential.TargetName;
 }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="flags">Negotiation flags.</param>
 /// <param name="clientCredential">Client account credential.</param>
 /// <param name="isDomainJoined">Joined in a domain or not</param>
 /// <param name="netbiosDomainName">Netbios domain name.</param>
 /// <param name="netbiosMachineName">Netbios machine name.</param>
 public NlmpServerSecurityConfig(
     NegotiateTypes flags,
     NlmpClientCredential clientCredential,
     bool isDomainJoined,
     string netbiosDomainName,
     string netbiosMachineName)
     : base(SecurityPackageType.Ntlm)
 {
     this.negotiateflags     = flags;
     this.clientCredential   = clientCredential;
     this.isDomainJoined     = isDomainJoined;
     this.netbiosDomainName  = netbiosDomainName;
     this.netbiosMachineName = netbiosMachineName;
     this.targetName         = clientCredential.TargetName;
 }
Пример #10
0
        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="flags">the negotiate flags indicates the capabilities of server or client</param>
        /// <param name="clientCredential">
        /// the credential of client. server sdk can not retrieve password from AD/Account Database;<para/>
        /// instead, server sdk get the user credential from this parameter.
        /// </param>
        /// <param name="isDomainJoined">whether the server joined to domain</param>
        /// <param name="netbiosDomainName">the netbios domain name of server</param>
        /// <param name="netbiosMachineName">the netbios machine name of server</param>
        public NlmpServerSecurityContext(
            NegotiateTypes flags,
            NlmpClientCredential clientCredential,
            bool isDomainJoined,
            string netbiosDomainName,
            string netbiosMachineName)
        {
            this.version    = new NlmpVersion();
            this.nlmpServer = new NlmpServer();

            this.nlmpServer.Context.NegFlg           = flags;
            this.nlmpServer.Context.ClientCredential = clientCredential;
            this.nlmpServer.Context.IsDomainJoined   = isDomainJoined;
            this.nlmpServer.Context.NbDomainName     = netbiosDomainName;
            this.nlmpServer.Context.NbMachineName    = netbiosMachineName;

            this.needContinueProcessing = true;
        }
Пример #11
0
        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="flags">the negotiate flags indicates the capabilities of server or client</param>
        /// <param name="isDomainJoined">whether the server joined to domain</param>
        /// <param name="netbiosDomainName">the netbios domain name of server</param>
        /// <param name="netbiosMachineName">the netbios machine name of server</param>
        /// <param name="verifyAuthenticatePacketInDcMethod">
        /// the delegate method used to verify authentication packet in AD/Account Database;
        /// </param>
        public NlmpServerSecurityContext(
            NegotiateTypes flags,
            bool isDomainJoined,
            string netbiosDomainName,
            string netbiosMachineName,
            VerifyAuthenticatePacketInDcMethod verifyAuthenticatePacketInDcMethod)
        {
            this.version    = new NlmpVersion();
            this.nlmpServer = new NlmpServer();

            this.nlmpServer.Context.NegFlg           = flags;
            this.nlmpServer.Context.ClientCredential = null;
            this.nlmpServer.Context.IsDomainJoined   = isDomainJoined;
            this.nlmpServer.Context.NbDomainName     = netbiosDomainName;
            this.nlmpServer.Context.NbMachineName    = netbiosMachineName;

            this.needContinueProcessing       = true;
            this.verifyAuthenticatePacketInDc = verifyAuthenticatePacketInDcMethod;
        }
Пример #12
0
        /// <summary>
        /// generated negotiate flags for challenge packet
        /// </summary>
        /// <param name="negotiatePacket">the negotiate packet from client</param>
        /// <returns>the negotiate flags to generate challenge packet</returns>
        private NegotiateTypes GeneratedNegotiateFlags(NlmpNegotiatePacket negotiatePacket)
        {
            NegotiateTypes negotiateFlags = this.nlmpServer.Context.NegFlg;

            // in the connectionless mode, the negotiate is null, return the flags in context.
            if (negotiatePacket == null)
            {
                return(negotiateFlags);
            }

            // Unicode or oem
            if (NegotiateTypes.NTLMSSP_NEGOTIATE_UNICODE ==
                (negotiatePacket.Payload.NegotiateFlags & NegotiateTypes.NTLMSSP_NEGOTIATE_UNICODE))
            {
                negotiateFlags |= NegotiateTypes.NTLMSSP_NEGOTIATE_UNICODE;
            }
            else if (NegotiateTypes.NTLM_NEGOTIATE_OEM ==
                     (negotiatePacket.Payload.NegotiateFlags & NegotiateTypes.NTLM_NEGOTIATE_OEM))
            {
                negotiateFlags |= NegotiateTypes.NTLM_NEGOTIATE_OEM;
            }
            // extended security or lm
            if (NegotiateTypes.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY ==
                (negotiatePacket.Payload.NegotiateFlags &
                 NegotiateTypes.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY))
            {
                negotiateFlags |= NegotiateTypes.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY;
            }
            else if (NegotiateTypes.NTLMSSP_NEGOTIATE_LM_KEY ==
                     (negotiatePacket.Payload.NegotiateFlags & NegotiateTypes.NTLMSSP_NEGOTIATE_LM_KEY))
            {
                negotiateFlags |= NegotiateTypes.NTLMSSP_NEGOTIATE_LM_KEY;
            }
            // target info
            if (NegotiateTypes.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY ==
                (negotiateFlags & NegotiateTypes.NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY))
            {
                negotiateFlags |= NegotiateTypes.NTLMSSP_NEGOTIATE_TARGET_INFO;
            }

            return(negotiateFlags);
        }
Пример #13
0
        /// <summary>
        /// Update ServerChallenge to this context
        /// </summary>
        /// <param name="serverChallenge">the serverChallenge to update</param>
        public void UpdateServerChallenge(ulong serverChallenge)
        {
            #region Prepare the Nlmp Negotiate Flags

            // the flags for negotiage
            NegotiateTypes nlmpFlags = NegotiateTypes.NTLMSSP_NEGOTIATE_NTLM | NegotiateTypes.NTLM_NEGOTIATE_OEM;

            #endregion

            #region Prepare the ServerName

            List <AV_PAIR> pairs = new List <AV_PAIR>();

            NlmpUtility.AddAVPair(pairs, AV_PAIR_IDs.MsvAvEOL, 0x00, null);

            #endregion

            this.challenge = this.nlmpServer.CreateChallengePacket(nlmpFlags, NlmpUtility.GetVersion(), serverChallenge,
                                                                   GenerateTargetName(), pairs);
            this.token = this.challenge.ToBytes();
        }
Пример #14
0
        /// <summary>
        /// initialize the negotiate flags
        /// </summary>
        /// <returns>the negotiate flags for authenticate</returns>
        private NegotiateTypes InitializeNegotiateFlags(NegotiateTypes challengeFlags)
        {
            NegotiateTypes flags = this.Context.ClientConfigFlags;

            flags |= NegotiateTypes.NTLMSSP_NEGOTIATE_TARGET_INFO;

            // A==1: The choice of character set encoding MUST be Unicode.
            // A==0 and B==1: The choice of character set encoding MUST be OEM.
            // A==0 and B==0: The protocol MUST return SEC_E_INVALID_TOKEN.
            if (NegotiateTypes.NTLMSSP_NEGOTIATE_UNICODE == (challengeFlags & NegotiateTypes.NTLMSSP_NEGOTIATE_UNICODE))
            {
                if (flags.HasFlag(NegotiateTypes.NTLM_NEGOTIATE_OEM))
                {
                    flags ^= NegotiateTypes.NTLM_NEGOTIATE_OEM;
                }
                if (!flags.HasFlag(NegotiateTypes.NTLMSSP_NEGOTIATE_UNICODE))
                {
                    flags |= NegotiateTypes.NTLMSSP_NEGOTIATE_UNICODE;
                }
            }
            else if (NegotiateTypes.NTLM_NEGOTIATE_OEM == (challengeFlags & NegotiateTypes.NTLM_NEGOTIATE_OEM))
            {
                if (flags.HasFlag(NegotiateTypes.NTLMSSP_NEGOTIATE_UNICODE))
                {
                    flags ^= NegotiateTypes.NTLMSSP_NEGOTIATE_UNICODE;
                }
                if (!flags.HasFlag(NegotiateTypes.NTLM_NEGOTIATE_OEM))
                {
                    flags |= NegotiateTypes.NTLM_NEGOTIATE_OEM;
                }
            }
            else
            {
                throw new Exception("The protocol MUST return SEC_E_INVALID_TOKEN");
            }

            return(flags);
        }
Пример #15
0
        /// <summary>
        /// accept the negotiate packet, generated the challenge packet.
        /// </summary>
        /// <param name="negotiatePacket">the negotiate packet</param>
        private void AcceptNegotiatePacket(NlmpNegotiatePacket negotiatePacket)
        {
            // save the negotiate, to valid the mic when authenticate.
            this.negotiate = negotiatePacket;

            // generated negotiate flags for challenge packet
            NegotiateTypes negotiateFlags = GeneratedNegotiateFlags(negotiatePacket);

            // initialize target name
            string targetName = GenerateTargetName();

            // initialize av pairs.
            ICollection <AV_PAIR> targetInfo = GenerateTargetInfo();

            VERSION sspiVersion = NlmpUtility.GetVersion();
            // the serverChallenge is 8 bytes.
            ulong serverChallenge = BitConverter.ToUInt64(NlmpUtility.Nonce(8), 0);

            NlmpChallengePacket challengePacket = this.nlmpServer.CreateChallengePacket(
                negotiateFlags, sspiVersion, serverChallenge, targetName, targetInfo);

            this.challenge = challengePacket;
            this.token     = challengePacket.ToBytes();
        }
 /// <summary>
 /// set the negotiate flags
 /// </summary>
 /// <param name="negotiateFlags">the new flags</param>
 public abstract void SetNegotiateFlags(
     NegotiateTypes negotiateFlags
     );
 /// <summary>
 /// set the negotiate flags
 /// </summary>
 /// <param name="negotiateFlags">the new flags</param>
 public override void SetNegotiateFlags(
     NegotiateTypes negotiateFlags
     )
 {
     payload.NegotiateFlags = negotiateFlags;
 }
 /// <summary>
 /// set the negotiate flags
 /// </summary>
 /// <param name="negotiateFlags">the new flags</param>
 public override void SetNegotiateFlags(NegotiateTypes negotiateFlags)
 {
 }
        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="flags">the negotiate flags indicates the capabilities of server or client</param>
        /// <param name="clientCredential">
        /// the credential of client. server sdk can not retrieve password from AD/Account Database;<para/>
        /// instead, server sdk get the user credential from this parameter.
        /// </param>
        /// <param name="isDomainJoined">whether the server joined to domain</param>
        /// <param name="netbiosDomainName">the netbios domain name of server</param>
        /// <param name="netbiosMachineName">the netbios machine name of server</param>
        public NlmpServerSecurityContext(
            NegotiateTypes flags,
            NlmpClientCredential clientCredential,
            bool isDomainJoined,
            string netbiosDomainName,
            string netbiosMachineName)
        {
            this.version = new NlmpVersion();
            this.nlmpServer = new NlmpServer();

            this.nlmpServer.Context.NegFlg = flags;
            this.nlmpServer.Context.ClientCredential = clientCredential;
            this.nlmpServer.Context.IsDomainJoined = isDomainJoined;
            this.nlmpServer.Context.NbDomainName = netbiosDomainName;
            this.nlmpServer.Context.NbMachineName = netbiosMachineName;

            this.needContinueProcessing = true;
        }
        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="flags">the negotiate flags indicates the capabilities of server or client</param>        
        /// <param name="isDomainJoined">whether the server joined to domain</param>
        /// <param name="netbiosDomainName">the netbios domain name of server</param>
        /// <param name="netbiosMachineName">the netbios machine name of server</param>
        /// <param name="verifyAuthenticatePacketInDcMethod">
        /// the delegate method used to verify authentication packet in AD/Account Database;        
        /// </param>
        public NlmpServerSecurityContext(
            NegotiateTypes flags,
            bool isDomainJoined,
            string netbiosDomainName,
            string netbiosMachineName,
            VerifyAuthenticatePacketInDcMethod verifyAuthenticatePacketInDcMethod)
        {
            this.version = new NlmpVersion();
            this.nlmpServer = new NlmpServer();

            this.nlmpServer.Context.NegFlg = flags;
            this.nlmpServer.Context.ClientCredential = null;
            this.nlmpServer.Context.IsDomainJoined = isDomainJoined;
            this.nlmpServer.Context.NbDomainName = netbiosDomainName;
            this.nlmpServer.Context.NbMachineName = netbiosMachineName;

            this.needContinueProcessing = true;
            this.verifyAuthenticatePacketInDc = verifyAuthenticatePacketInDcMethod;
        }
Пример #21
0
 /// <summary>
 /// set the negotiate flags
 /// </summary>
 /// <param name="negotiateFlags">the new flags</param>
 public abstract void SetNegotiateFlags(
     NegotiateTypes negotiateFlags
     );
Пример #22
0
        public void GetSecurityToken(
            NlmpVersion ntlmVersion,
            string domainName,
            string userName,
            string password,
            ulong serverTime,
            ulong serverChallenge,
            out byte[] caseInsensitivePassword,
            out byte[] caseSensitivePassword)
        {
            if (ntlmVersion != NlmpVersion.v1 && ntlmVersion != NlmpVersion.v2)
            {
                throw new ArgumentException(
                          string.Format("the ntlmVersion({0}) must be valid NlmpVersion value", ntlmVersion), "ntlmVersion");
            }

            caseInsensitivePassword = null;
            caseSensitivePassword   = null;

            #region Prepare the TargetInfo

            byte[] targetInfo = null;

            List <AV_PAIR> pairs = new List <AV_PAIR>();
            NlmpUtility.AddAVPair(pairs, AV_PAIR_IDs.MsvAvEOL, 0x00, null);

            targetInfo = NlmpUtility.AvPairCollectionGetBytes(pairs);
            #endregion

            #region Prepare the Nlmp Negotiate Flags

            // the flags for negotiate
            NegotiateTypes nlmpFlags = NegotiateTypes.NTLMSSP_NEGOTIATE_NTLM | NegotiateTypes.NTLM_NEGOTIATE_OEM;

            #endregion

            // exported to application for the SessionKey.
            byte[] sessionBaseKey = null;

            #region Prepare the keys

            // responseKeyNT
            byte[] responseKeyNT = NlmpUtility.GetResponseKeyNt(ntlmVersion, domainName, userName, password);

            // responseKeyLM
            byte[] responseKeyLM = NlmpUtility.GetResponseKeyLm(ntlmVersion, domainName, userName, password);

            #endregion

            #region Compute Response

            // clientChallenge, a 8 bytes random number.
            ulong clientChallenge = BitConverter.ToUInt64(NlmpUtility.Nonce(8), 0);

            // compute response
            NlmpUtility.ComputeResponse(
                ntlmVersion, nlmpFlags, responseKeyNT, responseKeyLM, serverChallenge, clientChallenge, serverTime,
                targetInfo, out caseSensitivePassword, out caseInsensitivePassword, out sessionBaseKey);

            #endregion
        }
 /// <summary>
 /// set the negotiate flags
 /// </summary>
 /// <param name="negotiateFlags">the new flags</param>
 public override void SetNegotiateFlags(
     NegotiateTypes negotiateFlags
     )
 {
     payload.NegotiateFlags = negotiateFlags;
 }
        /// <summary>
        /// initialize the response of challenge
        /// </summary>
        /// <param name="flags">the flag for challenge</param>
        /// <param name="challenge">the challenge packet</param>
        /// <param name="targetInfo">the target info of avpairs</param>
        /// <param name="responseKeyLM">the response lm key</param>
        /// <param name="lmChallengeResponse">the challenge lm response</param>
        /// <param name="ntChallengeResponse">the nt challenge response</param>
        private void InitializeChallengeResponse(
            NegotiateTypes flags,
            NlmpChallengePacket challenge,
            ICollection<AV_PAIR> targetInfo,
            out byte[] responseKeyLM,
            out byte[] lmChallengeResponse,
            out byte[] ntChallengeResponse
            )
        {
            // responseKeyNT
            byte[] responseKeyNT = NlmpUtility.GetResponseKeyNt(
                this.client.Config.Version, this.currentActiveCredential.DomainName,
                this.currentActiveCredential.AccountName, this.currentActiveCredential.Password);

            // responseKeyLM
            responseKeyLM = NlmpUtility.GetResponseKeyLm(
                this.client.Config.Version, this.currentActiveCredential.DomainName,
                this.currentActiveCredential.AccountName, this.currentActiveCredential.Password);

            // lmChallengeResponse
            lmChallengeResponse = null;

            // ntChallengeResponse
            ntChallengeResponse = null;

            ComputeResponse(
                flags, challenge.Payload.ServerChallenge, targetInfo, responseKeyNT, responseKeyLM,
                out lmChallengeResponse, out ntChallengeResponse);

            UpdateLmChallengeResponse(challenge.Payload.TargetInfo, ref lmChallengeResponse);
        }
        /// <summary>
        /// this function create an authenticate packet.
        /// after client received the challenge packet from server, client create an authenticate packet to server.
        /// the authenticate packet contains the authentication information of user that is generated by the credential
        /// of user.
        /// this function does not set the mic field of packet. it must be set manually if need.
        /// </summary>
        /// <param name="negotiateFlags">this flags indicates the capabilities that client supports.</param>
        /// <param name="version">
        /// This structure is used for debugging purposes only. In normal (non-debugging) protocol messages, it is
        /// ignored and does not affect the NTLM message processing.
        /// </param>
        /// <param name="lmChallengeResponse">
        /// An LM_RESPONSE or LMv2_RESPONSE structure that contains the computed LM response to the challenge. If
        /// NTLM v2 authentication is configured, LmChallengeResponse MUST be an LMv2_RESPONSE structure. Otherwise,
        /// it MUST be an LM_RESPONSE structure.
        /// </param>
        /// <param name="ntChallengeResponse">
        /// An NTLM_RESPONSE or NTLMv2_RESPONSE structure that contains the computed NT response to the challenge.
        /// If NTLM v2 authentication is configured, NtChallengeResponse MUST be an NTLMv2_RESPONSE. Otherwise, it
        /// MUST be an NTLM_RESPONSE structure.
        /// </param>
        /// <param name="domainName">
        /// The domain or computer name hosting the user account. DomainName MUST be encoded in the negotiated
        /// character set. This param can not be null.
        /// </param>
        /// <param name="userName">
        /// The name of the user to be authenticated. UserName MUST be encoded in the negotiated character set. This
        /// param can not be null.
        /// </param>
        /// <param name="workstation">
        /// The name of the computer to which the user is logged on. Workstation MUST be encoded in the negotiated
        /// character set. This param can not be null.
        /// </param>
        /// <param name="encryptedRandomSessionKey">
        /// The client's encrypted random session key. This param can be null.
        /// </param>
        /// <returns>the authenticate packet</returns>
        /// <exception cref="System.ArgumentNullException">
        /// when LM is using, the ntChallengeResponse should be null!
        /// </exception>
        public NlmpAuthenticatePacket CreateAuthenticatePacket(
            NegotiateTypes negotiateFlags,
            VERSION version,
            byte[] lmChallengeResponse,
            byte[] ntChallengeResponse,
            string domainName,
            string userName,
            string workstation,
            byte[] encryptedRandomSessionKey
            )
        {
            #region Parameter check

            if (domainName == null)
            {
                throw new ArgumentNullException("domainName");
            }

            if (userName == null)
            {
                throw new ArgumentNullException("userName");
            }

            if (workstation == null)
            {
                throw new ArgumentNullException("workstation");
            }

            if (NlmpUtility.IsLm(negotiateFlags) && ntChallengeResponse != null)
            {
                throw new ArgumentException(
                          "when LM is using, the ntChallengeResponse should be null!", "ntChallengeResponse");
            }

            #endregion

            NlmpAuthenticatePacket packet = new NlmpAuthenticatePacket();

            // update flags
            packet.SetNegotiateFlags(negotiateFlags);

            // if version required, update version
            if (NlmpUtility.IsVersionRequired(negotiateFlags))
            {
                packet.SetVersion(version);
            }

            // update domain name
            packet.SetDomainName(domainName);

            // update user name
            packet.SetUserName(userName);

            // if version required, update workstation
            if (NlmpUtility.IsVersionRequired(negotiateFlags))
            {
                packet.SetWorkstation(workstation);
            }

            // update lmChallengeResponse
            packet.SetLmChallengeResponse(lmChallengeResponse);

            // update ntChallengeResponse
            packet.SetNtChallengeResponse(ntChallengeResponse);

            // update encryptedRandomSessionKey
            packet.SetEncryptedRandomSessionKey(encryptedRandomSessionKey);

            return(packet);
        }
        /// <summary>
        /// this function create a negotiate packet.
        /// client send the negotiate packet to server to indicate the supported capabilities.
        /// in connection-oriented mode, this is the first packet that client send to server.
        /// </summary>
        /// <param name="negotiateFlags">this flags indicates the capabilities that client supports.</param>
        /// <param name="version">
        /// This structure is used for debugging purposes only. In normal (non-debugging) protocol messages, it is
        /// ignored and does not affect the NTLM message processing.
        /// </param>
        /// <param name="domainName">
        /// DomainName contains the name of the client authentication domain that MUST be encoded using the OEM
        /// character set. This param can not be null.
        /// </param>
        /// <param name="workstationName">
        /// WorkstationName contains the name of the client machine that MUST be encoded using the OEM character
        /// set. Otherwise, this data is not present. This param can not be null.
        /// </param>
        /// <returns>the negotiate packet</returns>
        /// <exception cref="ArgumentNullException">domainName must not be null</exception>
        /// <exception cref="ArgumentNullException">workstationName must not be null</exception>
        /// <exception cref="ArgumentException">
        /// when version is required, the domainName and workstationName must be string.Empty
        /// </exception>
        public NlmpNegotiatePacket CreateNegotiatePacket(
            NegotiateTypes negotiateFlags,
            VERSION version,
            string domainName,
            string workstationName
            )
        {
            #region Parameter validation

            if (NlmpUtility.IsConnectionless(negotiateFlags))
            {
                throw new NotSupportedException("NEGOTIATE message is not supported under Connectionless mode.");
            }

            if (NlmpUtility.IsDomainNameSupplied(negotiateFlags) && (domainName == null))
            {
                throw new ArgumentNullException("domainName");
            }

            if (NlmpUtility.IsWorkstationSupplied(negotiateFlags) && (workstationName == null))
            {
                throw new ArgumentNullException("workstationName");
            }

            if (NlmpUtility.IsVersionRequired(negotiateFlags))
            {
                if (domainName.Length != 0)
                {
                    throw new ArgumentException(
                              "when version is required, the domainName should be string.Empty!", "domainName");
                }

                if (workstationName.Length != 0)
                {
                    throw new ArgumentException(
                              "when version is required, the workstationName should be string.Empty!", "workstationName");
                }
            }
            else
            {
                if (NlmpUtility.IsDomainNameSupplied(negotiateFlags) && domainName.Length == 0)
                {
                    throw new ArgumentException(
                              "when version is not required, the domainName should not be string.Empty!", "domainName");
                }

                if (NlmpUtility.IsWorkstationSupplied(negotiateFlags) && workstationName.Length == 0)
                {
                    throw new ArgumentException(
                              "when version is not required, the workstationName should not be string.Empty!",
                              "workstationName");
                }
            }

            #endregion

            NlmpNegotiatePacket packet = new NlmpNegotiatePacket();

            packet.SetNegotiateFlags(negotiateFlags);

            if (NlmpUtility.IsVersionRequired(negotiateFlags))
            {
                packet.SetVersion(version);
            }

            if (NlmpUtility.IsDomainNameSupplied(negotiateFlags))
            {
                packet.SetDomainName(domainName);
            }

            if (NlmpUtility.IsWorkstationSupplied(negotiateFlags))
            {
                packet.SetWorkstationName(workstationName);
            }

            return(packet);
        }
        /// <summary>
        /// this function create an authenticate packet.
        /// after client received the challenge packet from server, client create an authenticate packet to server.
        /// the authenticate packet contains the authentication information of user that is generated by the credential
        /// of user.
        /// this function does not set the mic field of packet. it must be set manually if need.
        /// </summary>
        /// <param name="negotiateFlags">this flags indicates the capabilities that client supports.</param>
        /// <param name="version">
        /// This structure is used for debugging purposes only. In normal (non-debugging) protocol messages, it is 
        /// ignored and does not affect the NTLM message processing.
        /// </param>
        /// <param name="lmChallengeResponse">
        /// An LM_RESPONSE or LMv2_RESPONSE structure that contains the computed LM response to the challenge. If 
        /// NTLM v2 authentication is configured, LmChallengeResponse MUST be an LMv2_RESPONSE structure. Otherwise, 
        /// it MUST be an LM_RESPONSE structure.
        /// </param>
        /// <param name="ntChallengeResponse">
        /// An NTLM_RESPONSE or NTLMv2_RESPONSE structure that contains the computed NT response to the challenge. 
        /// If NTLM v2 authentication is configured, NtChallengeResponse MUST be an NTLMv2_RESPONSE. Otherwise, it 
        /// MUST be an NTLM_RESPONSE structure.
        /// </param>
        /// <param name="domainName">
        /// The domain or computer name hosting the user account. DomainName MUST be encoded in the negotiated 
        /// character set. This param can not be null.
        /// </param>
        /// <param name="userName">
        /// The name of the user to be authenticated. UserName MUST be encoded in the negotiated character set. This 
        /// param can not be null.
        /// </param>
        /// <param name="workstation">
        /// The name of the computer to which the user is logged on. Workstation MUST be encoded in the negotiated 
        /// character set. This param can not be null.
        /// </param>
        /// <param name="encryptedRandomSessionKey">
        /// The client's encrypted random session key. This param can be null.
        /// </param>
        /// <returns>the authenticate packet</returns>
        /// <exception cref="System.ArgumentNullException">
        /// when LM is using, the ntChallengeResponse should be null!
        /// </exception>
        public NlmpAuthenticatePacket CreateAuthenticatePacket(
            NegotiateTypes negotiateFlags,
            VERSION version,
            byte[] lmChallengeResponse,
            byte[] ntChallengeResponse,
            string domainName,
            string userName,
            string workstation,
            byte[] encryptedRandomSessionKey
            )
        {
            #region Parameter check

            if (domainName == null)
            {
                throw new ArgumentNullException("domainName");
            }

            if (userName == null)
            {
                throw new ArgumentNullException("userName");
            }

            if (workstation == null)
            {
                throw new ArgumentNullException("workstation");
            }

            if (NlmpUtility.IsLm(negotiateFlags) && ntChallengeResponse != null)
            {
                throw new ArgumentException(
                    "when LM is using, the ntChallengeResponse should be null!", "ntChallengeResponse");
            }

            #endregion

            NlmpAuthenticatePacket packet = new NlmpAuthenticatePacket();

            // update flags
            packet.SetNegotiateFlags(negotiateFlags);

            // if version required, update version
            if (NlmpUtility.IsVersionRequired(negotiateFlags))
            {
                packet.SetVersion(version);
            }

            // update domain name
            packet.SetDomainName(domainName);

            // update user name
            packet.SetUserName(userName);

            // if version required, update workstation
            if (NlmpUtility.IsVersionRequired(negotiateFlags))
            {
                packet.SetWorkstation(workstation);
            }

            // update lmChallengeResponse
            packet.SetLmChallengeResponse(lmChallengeResponse);

            // update ntChallengeResponse
            packet.SetNtChallengeResponse(ntChallengeResponse);

            // update encryptedRandomSessionKey
            packet.SetEncryptedRandomSessionKey(encryptedRandomSessionKey);

            return packet;
        }
        /// <summary>
        /// compute response
        /// </summary>
        /// <param name="flags">the flags for challenge</param>
        /// <param name="serverChallenge">the server challenge</param>
        /// <param name="targetInfo">the target info contains avpairs</param>
        /// <param name="responseKeyNT">the response nt key</param>
        /// <param name="responseKeyLM">the response lm key</param>
        /// <param name="lmChallengeResponse">the challenge response lm</param>
        /// <param name="ntChallengeResponse">the challenge response nt</param>
        private void ComputeResponse(
            NegotiateTypes flags,
            ulong serverChallenge,
            ICollection<AV_PAIR> targetInfo,
            byte[] responseKeyNT,
            byte[] responseKeyLM,
            out byte[] lmChallengeResponse,
            out byte[] ntChallengeResponse
            )
        {
            // clientChallenge, a random 8 bytes.
            ulong clientChallenge = NlmpUtility.BytesToSecurityUInt64(NlmpUtility.Nonce(8));

            // time
            ulong time = 0;
            if (!NlmpUtility.IsNtlmV1(this.client.Config.Version))
            {
                time = NlmpUtility.GetTime(targetInfo);
            }

            byte[] sessionBaseKey = null;

            // compute response
            NlmpUtility.ComputeResponse(
                this.client.Config.Version, flags, responseKeyNT, responseKeyLM, serverChallenge, clientChallenge,
                time, NlmpUtility.AvPairCollectionGetBytes(targetInfo), out ntChallengeResponse,
                out lmChallengeResponse, out sessionBaseKey);

            // save key to context
            this.client.Context.SessionBaseKey = sessionBaseKey;
        }
        /// <summary>
        /// this function create a negotiate packet.
        /// client send the negotiate packet to server to indicate the supported capabilities.
        /// in connection-oriented mode, this is the first packet that client send to server.
        /// </summary>
        /// <param name="negotiateFlags">this flags indicates the capabilities that client supports.</param>
        /// <param name="version">
        /// This structure is used for debugging purposes only. In normal (non-debugging) protocol messages, it is 
        /// ignored and does not affect the NTLM message processing.
        /// </param>
        /// <param name="domainName">
        /// DomainName contains the name of the client authentication domain that MUST be encoded using the OEM 
        /// character set. This param can not be null.
        /// </param>
        /// <param name="workstationName">
        /// WorkstationName contains the name of the client machine that MUST be encoded using the OEM character 
        /// set. Otherwise, this data is not present. This param can not be null.
        /// </param>
        /// <returns>the negotiate packet</returns>
        /// <exception cref="ArgumentNullException">domainName must not be null</exception>
        /// <exception cref="ArgumentNullException">workstationName must not be null</exception>
        /// <exception cref="ArgumentException">
        /// when version is required, the domainName and workstationName must be string.Empty
        /// </exception>
        public NlmpNegotiatePacket CreateNegotiatePacket(
            NegotiateTypes negotiateFlags,
            VERSION version,
            string domainName,
            string workstationName
            )
        {
            if (NlmpUtility.IsConnectionless(negotiateFlags))
            {
                throw new NotSupportedException("NEGOTIATE message is not supported under Connectionless mode.");
            }

            if (domainName == null)
            {
                throw new ArgumentNullException("domainName");
            }

            if (workstationName == null)
            {
                throw new ArgumentNullException("workstationName");
            }

            #region Parameter validation

            if (NlmpUtility.IsVersionRequired(negotiateFlags))
            {
                if (domainName.Length != 0)
                {
                    throw new ArgumentException(
                        "when version is required, the domainName should be string.Empty!", "domainName");
                }

                if (workstationName.Length != 0)
                {
                    throw new ArgumentException(
                        "when version is required, the workstationName should be string.Empty!", "workstationName");
                }
            }
            else
            {
                if (NlmpUtility.IsDomainNameSupplied(negotiateFlags) && domainName.Length == 0)
                {
                    throw new ArgumentException(
                        "when version is not required, the domainName should not be string.Empty!", "domainName");
                }

                if (NlmpUtility.IsWorkstationSupplied(negotiateFlags) && workstationName.Length == 0)
                {
                    throw new ArgumentException(
                        "when version is not required, the workstationName should not be string.Empty!",
                        "workstationName");
                }
            }

            #endregion

            NlmpNegotiatePacket packet = new NlmpNegotiatePacket();

            packet.SetNegotiateFlags(negotiateFlags);

            if (NlmpUtility.IsVersionRequired(negotiateFlags))
            {
                packet.SetVersion(version);
            }
            else
            {
                if (NlmpUtility.IsDomainNameSupplied(negotiateFlags))
                {
                    packet.SetDomainName(domainName);
                }

                if (NlmpUtility.IsWorkstationSupplied(negotiateFlags))
                {
                    packet.SetWorkstationName(workstationName);
                }
            }

            return packet;
        }
        /// <summary>
        /// initialize the exportedSessionKey and internal keys
        /// </summary>
        /// <param name="flags">the flags of challenge</param>
        /// <param name="challenge">the challenge packet</param>
        /// <param name="responseKeyLM">the response key lm</param>
        /// <param name="lmChallengeResponse">the challenge response lm</param>
        /// <param name="encryptedRandomSessionKey">the encrypted random session key</param>
        /// <param name="exportedSessionKey">the exported session key</param>
        private void InitializeKeys(
            NegotiateTypes flags,
            NlmpChallengePacket challenge,
            byte[] responseKeyLM,
            byte[] lmChallengeResponse,
            out byte[] encryptedRandomSessionKey,
            out byte[] exportedSessionKey
            )
        {
            // keyExchangeKey
            byte[] keyExchangeKey = null;

            // get random session key
            NlmpUtility.GetEncryptedRandomSessionKey(
                this.client.Config.Version, flags, this.client.Context.SessionBaseKey, lmChallengeResponse,
                responseKeyLM, challenge.Payload.ServerChallenge, out encryptedRandomSessionKey, out keyExchangeKey,
                out exportedSessionKey);

            this.client.Context.ClientSigningKey = NlmpUtility.SignKey(flags, exportedSessionKey, "Client");
            this.client.Context.ServerSigningKey = NlmpUtility.SignKey(flags, exportedSessionKey, "Server");
            this.client.Context.ClientSealingKey = NlmpUtility.SealKey(flags, exportedSessionKey, "Client");
            this.client.Context.ServerSealingKey = NlmpUtility.SealKey(flags, exportedSessionKey, "Server");

            NlmpUtility.RC4Init(this.client.Context.ClientHandle, this.client.Context.ClientSealingKey);
            NlmpUtility.RC4Init(this.client.Context.ServerHandle, this.client.Context.ServerSealingKey);
        }
Пример #31
0
 /// <summary>
 /// set the negotiate flags
 /// </summary>
 /// <param name="negotiateFlags">the new flags</param>
 public override void SetNegotiateFlags(NegotiateTypes negotiateFlags)
 {
 }