/// <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 context from a token. /// </summary> /// <param name="serverToken">the token from server</param> public override void Initialize(byte[] serverToken) { if (serverToken == null) { this.clientSequenceNumber = 0; this.serverSequenceNumber = 0; string domainName = string.Empty; string workstationName = string.Empty; if (!NlmpUtility.IsVersionRequired(this.Context.ClientConfigFlags)) { if (NlmpUtility.IsDomainNameSupplied(this.Context.ClientConfigFlags)) { domainName = this.Credential.DomainName; } if (NlmpUtility.IsWorkstationSupplied(this.Context.ClientConfigFlags)) { workstationName = Environment.MachineName; } } this.currentActiveCredential = new NlmpClientCredential( workstationName, domainName, this.Credential.AccountName, this.Credential.Password); this.token = GetSecurityToken(workstationName); this.needContinueProcessing = true; } else { this.currentActiveCredential = Credential; this.token = GetSecurityToken(serverToken); this.needContinueProcessing = false; } }
/// <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); }