예제 #1
0
        /// <summary>
        /// verify the implicit ntlm session security token.
        /// this api is invoked by protocol need the implicit Ntlm authenticate, such as CifsSdk and the SmbSdk with
        /// none extended session security.
        /// </summary>
        /// <param name="accountName">the user name which determined by the security context of the user initiating the
        /// connection to share</param>
        /// <param name="domainName">the Primary Domain of the user</param>
        /// <param name="serverTime">the time of the server</param>
        /// <param name="caseInsensitivePassword">the NtChallengeResponse</param>
        /// <param name="caseSensitivePassword">the LmChallengeResponse</param>
        /// <returns>success or fail</returns>
        public bool VerifySecurityToken(
            //string workstationName,
            string accountName,
            string domainName,
            ulong serverTime,
            byte[] caseInsensitivePassword,
            byte[] caseSensitivePassword)
        {
            if (string.IsNullOrEmpty(accountName))
            {
                return(false);
            }

            this.systemTime = serverTime;
            NlmpAuthenticatePacket authenticatePacket = new NlmpAuthenticatePacket();

            authenticatePacket.SetNtChallengeResponse(caseSensitivePassword);
            authenticatePacket.SetLmChallengeResponse(caseInsensitivePassword);
            authenticatePacket.SetDomainName(domainName);
            authenticatePacket.SetUserName(accountName);
            authenticatePacket.SetWorkstation(string.Empty);
            authenticatePacket.SetEncryptedRandomSessionKey(new byte[0]);

            try
            {
                this.AcceptAuthenticatePacket(authenticatePacket);
            }
            catch (InvalidOperationException)
            {
                return(false);
            }
            catch (ArgumentException) // caseSensitivePassword or caseInsensitivePassword is not long enough
            {
                return(false);
            }
            return(true);
        }
        /// <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 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>
        /// verify the implicit ntlm session security token.
        /// this api is invoked by protocol need the implicit Ntlm authenticate, such as CifsSdk and the SmbSdk with
        /// none extended session security.
        /// </summary>
        /// <param name="accountName">the user name which determined by the security context of the user initiating the
        /// connection to share</param>
        /// <param name="domainName">the Primary Domain of the user</param>
        /// <param name="serverTime">the time of the server</param>
        /// <param name="caseInsensitivePassword">the NtChallengeResponse</param>
        /// <param name="caseSensitivePassword">the LmChallengeResponse</param>
        /// <returns>success or fail</returns>
        public bool VerifySecurityToken(
            //string workstationName,
            string accountName,
            string domainName,
            ulong serverTime,
            byte[] caseInsensitivePassword,
            byte[] caseSensitivePassword)
        {
            if (string.IsNullOrEmpty(accountName))
            {
                return false;
            }

            this.systemTime = serverTime;
            NlmpAuthenticatePacket authenticatePacket = new NlmpAuthenticatePacket();
            authenticatePacket.SetNtChallengeResponse(caseSensitivePassword);
            authenticatePacket.SetLmChallengeResponse(caseInsensitivePassword);
            authenticatePacket.SetDomainName(domainName);
            authenticatePacket.SetUserName(accountName);
            authenticatePacket.SetWorkstation(string.Empty);
            authenticatePacket.SetEncryptedRandomSessionKey(new byte[0]);

            try
            {
                this.AcceptAuthenticatePacket(authenticatePacket);
            }
            catch (InvalidOperationException)
            {
                return false;
            }
            catch (ArgumentException) // caseSensitivePassword or caseInsensitivePassword is not long enough
            {
                return false;
            }
            return true;
        }