/// <summary> /// copy constructor. /// </summary> public NlmpNegotiatePacket( NlmpNegotiatePacket stackPacket ) : base(stackPacket) { this.payload = stackPacket.payload; if (stackPacket.payload.DomainName != null) { this.payload.DomainName = new byte[stackPacket.payload.DomainName.Length]; Array.Copy( stackPacket.payload.DomainName, this.payload.DomainName, stackPacket.payload.DomainName.Length ); } if (stackPacket.payload.WorkstationName != null) { this.payload.WorkstationName = new byte[stackPacket.payload.WorkstationName.Length]; Array.Copy( stackPacket.payload.WorkstationName, this.payload.WorkstationName, stackPacket.payload.WorkstationName.Length); } }
/// <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> /// get the security token /// </summary> /// <returns>the security token</returns> private byte[] GetSecurityToken() { if (this.client == null) { throw new InvalidOperationException("The client is null! You must initialize this field first!"); } // get current version VERSION version = NlmpUtility.GetVersion(); NlmpNegotiatePacket packet = this.client.CreateNegotiatePacket( this.Context.ClientConfigFlags, version, this.currentActiveCredential.DomainName, this.currentActiveCredential.TargetName); this.negotiate = packet; return packet.ToBytes(); }
/// <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 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> /// 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; }
/// <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(); }