/// <summary> /// Construct Kerberos PAC pass-through logon information /// </summary> /// <param name="parameterControl"> /// A set of bit flags that contain information pertaining to the logon validation processing. /// </param> /// <param name="domainName">domain name</param> /// <param name="userName">user name</param> /// <param name="serverName">NetBIOS name of server </param> /// <param name="kerbVerifyPacRequest">KERB_VERIFY_PAC_REQUEST packet</param> /// <returns>Kerberos PAC netlogon information structure </returns> public static _NETLOGON_LEVEL CreatePacLogonInfo( NrpcParameterControlFlags parameterControl, string domainName, string userName, string serverName, KERB_VERIFY_PAC_REQUEST kerbVerifyPacRequest) { _NETLOGON_LEVEL netLogonLevel = new _NETLOGON_LEVEL(); byte[] logonData = TypeMarshal.ToBytes <KERB_VERIFY_PAC_REQUEST>(kerbVerifyPacRequest); //Identity: A NETLOGON_LOGON_IDENTITY_INFO structure, as specified in section MS-NRPC 2.2.1.4.15, //that contains information about the logon identity. _NETLOGON_LOGON_IDENTITY_INFO identityInfo = NrpcUtility.CreateNetlogonIdentityInfo( parameterControl, domainName, userName, serverName); netLogonLevel.LogonGeneric = new _NETLOGON_GENERIC_INFO[1]; netLogonLevel.LogonGeneric[0].Identity = identityInfo; netLogonLevel.LogonGeneric[0].PackageName = DtypUtility.ToRpcUnicodeString(KERBEROS_PACKAGENAME); netLogonLevel.LogonGeneric[0].LogonData = logonData; netLogonLevel.LogonGeneric[0].DataLength = (uint)logonData.Length; return(netLogonLevel); }
/// <summary> /// Create DPSP logon information structure /// </summary> /// <param name="parameterControl"> /// A set of bit flags that contain information pertaining to the logon validation processing. /// </param> /// <param name="digestValidationReq">DIGEST_VALIDATION_REQ structure</param> /// <returns>Dpsp netlogon information structure</returns> public static _NETLOGON_LEVEL CreateDpspLogonInfo( NrpcParameterControlFlags parameterControl, DIGEST_VALIDATION_REQ digestValidationReq) { if (digestValidationReq.Payload == null) { throw new ArgumentException( "invalid digestValidationReq parameter: the payload field is null", "digestValidationReq"); } _NETLOGON_LEVEL netLogonLevel = new _NETLOGON_LEVEL(); DIGEST_VALIDATION_REQ_Payload payload = DIGEST_VALIDATION_REQ_Payload.Parse(digestValidationReq.Payload); byte[] logonData = TypeMarshal.ToBytes <DIGEST_VALIDATION_REQ>(digestValidationReq); //Identity: A NETLOGON_LOGON_IDENTITY_INFO structure, as specified in section MS-NRPC 2.2.1.4.15, //that contains information about the logon identity. _NETLOGON_LOGON_IDENTITY_INFO identityInfo = NrpcUtility.CreateNetlogonIdentityInfo( parameterControl, payload.Domain, payload.Username, payload.ServerName); netLogonLevel.LogonGeneric = new _NETLOGON_GENERIC_INFO[1]; netLogonLevel.LogonGeneric[0].Identity = identityInfo; netLogonLevel.LogonGeneric[0].PackageName = DtypUtility.ToRpcUnicodeString(DIGEST_PACKAGENAME); netLogonLevel.LogonGeneric[0].LogonData = logonData; netLogonLevel.LogonGeneric[0].DataLength = (uint)logonData.Length; return(netLogonLevel); }
/// <summary> /// Construct Nlmp pass-through interactive logon information structure /// from client NTLM authenticate response message /// </summary> /// <param name="parameterControl">A set of bit flags /// that contain information pertaining to the logon validation processing. /// </param> /// <param name="domainName">domain name</param> /// <param name="userName">user name</param> /// <param name="password">password</param> /// <param name="serverName">NetBIOS name of server </param> /// <returns>nlmp interactive logon information structure</returns> public static _NETLOGON_LEVEL CreateNlmpInteractiveLogonInfo( NrpcParameterControlFlags parameterControl, string domainName, string userName, string password, string serverName ) { _NETLOGON_LEVEL netLogonLevel = new _NETLOGON_LEVEL(); //LmOwfPassword: LM_OWF_PASSWORD structure, as specified in section 2.2.1.1.3, //that contains the LMOWFv1 of a password. //LMOWFv1 is specified in NTLM v1 Authentication in [MS-NLMP] section 3.3.1. byte[] lmOwf = NlmpUtility.LmOWF(NlmpVersion.v1, domainName, userName, password); //NtOwfPassword: An NT_OWF_PASSWORD structure, as specified in section 2.2.1.1.4, //that contains the NTOWFv1 of a password. //NTOWFv1 is specified in NTLM v1 Authentication in [MS-NLMP] section 3.3.1. byte[] ntOwf = NlmpUtility.NtOWF(NlmpVersion.v1, domainName, userName, password); //Identity: A NETLOGON_LOGON_IDENTITY_INFO structure, as specified in section MS-NRPC 2.2.1.4.15, //that contains information about the logon identity. _NETLOGON_LOGON_IDENTITY_INFO identityInfo = NrpcUtility.CreateNetlogonIdentityInfo( parameterControl, domainName, userName, serverName); netLogonLevel.LogonInteractive = new _NETLOGON_INTERACTIVE_INFO[1]; netLogonLevel.LogonInteractive[0].Identity = identityInfo; netLogonLevel.LogonInteractive[0].LmOwfPassword = new _LM_OWF_PASSWORD(); netLogonLevel.LogonInteractive[0].LmOwfPassword.data = NrpcUtility.CreateCypherBlocks(lmOwf); netLogonLevel.LogonInteractive[0].NtOwfPassword = new _NT_OWF_PASSWORD(); netLogonLevel.LogonInteractive[0].NtOwfPassword.data = NrpcUtility.CreateCypherBlocks(ntOwf); return(netLogonLevel); }
/// <summary> /// Send KERB_VERIFY_PAC_REQUEST message to DC through generic pass-through mechanism /// </summary> /// <param name="serverSignature">Server Signature in the privilege attribute certificate (PAC)</param> /// <param name="kdcSignature">Key Distribution Center (KDC) Signature in the PAC</param> /// <returns></returns> public Status GenerateKerberosValidationRequest( PAC_SIGNATURE_DATA serverSignature, PAC_SIGNATURE_DATA kdcSignature) { _NETLOGON_LOGON_INFO_CLASS logonLevel = _NETLOGON_LOGON_INFO_CLASS.NetlogonGenericInformation; _NETLOGON_VALIDATION_INFO_CLASS validationLevel = _NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationGenericInfo2; //Get Kerberos Request KERB_VERIFY_PAC_REQUEST kerberosReq = ApdsUtility.CreateKerbVerifyPacRequest(serverSignature, kdcSignature); //Create digest validation logon info _NETLOGON_LEVEL netlogonLevel = ApdsUtility.CreatePacLogonInfo( NrpcParameterControlFlags.AllowLogonWithComputerAccount, PrimaryDomainDnsName, DomainAdministratorName, PDCNetbiosName, kerberosReq); //Create Secure Channel EstablishSecureChannel(); //Client calls EncryptNetlogonLevel _NETLOGON_LEVEL encryptedLogonLevel = nrpcClient.EncryptNetlogonLevel( (_NETLOGON_LOGON_INFO_CLASS)logonLevel, netlogonLevel); //Client calls NetrLogonSamLogonEx _NETLOGON_VALIDATION?validationInfomation; byte?authoritative; NrpcNetrLogonSamLogonExtraFlags?extraFlags = NrpcNetrLogonSamLogonExtraFlags.None; result = nrpcClient.NetrLogonSamLogonEx( nrpcClient.Handle, sutComputerName, clientComputerName, logonLevel, encryptedLogonLevel, validationLevel, out validationInfomation, out authoritative, ref extraFlags); // Whether this method use pass-through mechanism or not. bool isPassThroughMethod = false; //Kerberos PAC validation SHOULD use the generic pass-through mechanism ([MS-NRPC] section 3.2.4.1). //For generic pass-through, the LogonLevel is 4(NetlogonGenericInformation) as defined in [MS-NRPC] section 3.2.4.1. //So when the LogonLevel is 4, we can say that NRPC pass-through authentication method is used. if ((int)logonLevel == 4) { isPassThroughMethod = true; } Site.CaptureRequirementIfIsTrue( isPassThroughMethod, 5, @"For domain support, authentication protocols MUST use an NRPC pass-through authentication ([MS-NRPC] section 3.2) method with parameters determined by the authentication protocol being used[to return the response structures to member server]."); Site.CaptureRequirementIfAreEqual <int>( 5, (int)validationLevel, 402, @"The encoded data SHOULD be sent by using the generic pass-through mechanism ([MS-NRPC] section 3.2.4.1)."); if (result == NtStatus.STATUS_SUCCESS) { Site.CaptureRequirementIfIsNull(validationInfomation.Value.ValidationGeneric2[0].ValidationData, 403, @"If the checksum is verified, the DC MUST return STATUS_SUCCESS. There is no return message."); } return((Status)result); }
/// <summary> /// Send Digest request message to DC, and validate the credentials. /// </summary> /// <param name="isValidationSuccess">Indicates whether the validation from server will be success.</param> /// <param name="digestType">Indicates the DigestType field of the request.</param> /// <param name="algType">Indicates the AlgType field of the request.</param> /// <param name="ignoredFields">It indicates the fields that should be ignored by DC in DIGEST_VALIDATION_REQ.</param> /// <returns>Indicates the result status of DC response.</returns> public Status GenerateDigestRequest( Boolean isValidationSuccess, AccountInformation accountInfo, DigestType_Values digestType, AlgType_Values algType, IgnoredFields ignoredFields) { DIGEST_VALIDATION_REQ digestReq; _NETLOGON_LOGON_INFO_CLASS logonLevel = _NETLOGON_LOGON_INFO_CLASS.NetlogonGenericInformation; _NETLOGON_VALIDATION_INFO_CLASS validationLevel = _NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationGenericInfo2; //Compute the password GenerateCurrentCredentials(accountInfo); //Get Digest Request GetDigestRequest(digestType, algType, ignoredFields, out digestReq); //Create digest validation logon info _NETLOGON_LEVEL netlogonLevel = ApdsUtility.CreateDpspLogonInfo( NrpcParameterControlFlags.AllowLogonWithComputerAccount, digestReq); //Create Secure Channel EstablishSecureChannel(); //Client calls EncryptNetlogonLevel _NETLOGON_LEVEL encryptedLogonLevel = nrpcClient.EncryptNetlogonLevel( (_NETLOGON_LOGON_INFO_CLASS)logonLevel, netlogonLevel); //Client calls NetrLogonSamLogonEx _NETLOGON_VALIDATION?validationInfomation; byte?authoritative; NrpcNetrLogonSamLogonExtraFlags?extraFlags = NrpcNetrLogonSamLogonExtraFlags.None; result = nrpcClient.NetrLogonSamLogonEx( nrpcClient.Handle, sutComputerName, clientComputerName, logonLevel, encryptedLogonLevel, validationLevel, out validationInfomation, out authoritative, ref extraFlags); // Whether this method use pass-through mechanism or not. bool isPassThroughMethod = false; // //The Digest validation protocol SHOULD use the generic pass-through mechanism. //For generic pass-through, the LogonLevel is 4(NetlogonGenericInformation) as defined in [MS-NRPC] section 3.2.4.1. //So when the LogonLevel is 4, we can say that NRPC pass-through authentication method is used. // if ((int)logonLevel == 4) { isPassThroughMethod = true; } // //Verify MS-APDS requirment:MS-APDS_R5 // Site.CaptureRequirementIfIsTrue( isPassThroughMethod, 5, @"For domain support, authentication protocols MUST use an NRPC pass-through authentication ([MS-NRPC] section 3.2) method with parameters determined by the authentication protocol being used[to return the response structures to member server]."); // //Verify MS-APDS requirment:MS-APDS_R15 // Site.CaptureRequirementIfAreEqual <int>( 5, (int)validationLevel, 15, @"Digest response messages MUST be encoded as opaque blobs and transported by the generic pass-through capability of Netlogon."); // //Configured in PTFConfig file,default SHOULD to true and MAY to false. // string isR169Implemented = "true"; // //Check OS version // if (isWindows) { // //Verify MS-APDS requirment:MS-APDS_R100169 // Site.CaptureRequirementIfAreEqual <int>( 5, (int)validationLevel, 100169, @"In Windows, the Digest validation protocol uses the generic pass-through mechanism."); if (null == isR169Implemented) { Site.Properties.Add("R169Implemented", Boolean.TrueString); isR169Implemented = Boolean.TrueString; } } if (null != isR169Implemented) { bool implSigns = Boolean.Parse(isR169Implemented); bool isSatisfied = ((int)_NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationGenericInfo2 == 5); // //Verify MS-APDS requirment:MS-APDS_R169 // Site.CaptureRequirementIfAreEqual <Boolean>( implSigns, isSatisfied, 169, string.Format(@"The Digest validation protocol SHOULD use the generic pass-through mechanism. This requirement is {0} implemented.", implSigns ? "" : "not")); } byte[] buf; bool isDigestResStructure = true; DIGEST_VALIDATION_RESP digestValidationResponse = new DIGEST_VALIDATION_RESP(); // Judge whether the digest response is exist, validationData is response point. // if validationData equals 0, no response return from NRPC. if (validationInfomation.Value.ValidationGeneric2 == null) { isDigestResStructure = false; } else { // decrypt validation info buf = NrpcUtility.DecryptBuffer( (nrpcClient.Context.NegotiateFlags & NrpcNegotiateFlags.SupportsAESAndSHA2) == NrpcNegotiateFlags.SupportsAESAndSHA2, nrpcClient.Context.SessionKey, validationInfomation.Value.ValidationGeneric2[0].ValidationData); _NETLOGON_VALIDATION decryptValidationInfo = new _NETLOGON_VALIDATION(); decryptValidationInfo.ValidationGeneric2 = new _NETLOGON_VALIDATION_GENERIC_INFO2[1]; decryptValidationInfo.ValidationGeneric2[0].ValidationData = buf; digestValidationResponse = ApdsUtility.ConvertDataToDigestValidationResponse(decryptValidationInfo); VerifyMessageSyntaxDigestValidCredential(digestValidationResponse, validationLevel, (uint)buf.Length); } if (result != NtStatus.STATUS_SUCCESS) { // //Verify MS-APDS requirment:MS-APDS_R292 // Site.CaptureRequirementIfIsFalse( isDigestResStructure, 292, "[If unsuccessful]It[DC] MUST NOT send back the DIGEST_VALIDATION_RESP message."); VerifyMessageSyntxDigestInvalidResp((uint)result, digestValidationResponse.AuthDataSize); } return((Status)result); }
/// <summary> /// Send NTLM request message to DC for validation. /// </summary> /// <param name="logonLevel">Indicates the logon level.</param> /// <param name="accountInfo">Indicates whether this account is valid in DC validation.</param> /// <param name="isAccessCheckSuccess">Indicates whether the access checked success.</param> /// <param name="validationLevel">Indicates the validation level.</param> /// <returns>Indicates the result status of DC response.</returns> public Status NTLMLogon( _NETLOGON_LOGON_INFO_CLASS logonLevel, AccountInformation accountInfo, Boolean isAccessCheckSuccess, _NETLOGON_VALIDATION_INFO_CLASS validationLevel) { //Compute the password GenerateCurrentCredentials(accountInfo); //Create Secure Channel EstablishSecureChannel(); _NETLOGON_LEVEL netLogonLevel = new _NETLOGON_LEVEL(); if (logonLevel == _NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation) { //Fill InteractiveInfo netLogonLevel = ApdsUtility.CreateNlmpInteractiveLogonInfo( NrpcParameterControlFlags.AllowLogonWithComputerAccount, sutTrustDomainName, currentUserName, currentPassword, sutComputerName); } else if (logonLevel == _NETLOGON_LOGON_INFO_CLASS.NetlogonNetworkInformation) { //Fill Netlogon_Network_Info if (accountInfo == AccountInformation.ManagedServiceAccount) { netLogonLevel = nrpcClient.CreateNetlogonLevel( _NETLOGON_LOGON_INFO_CLASS.NetlogonNetworkInformation, NrpcParameterControlFlags.AllowLogonWithComputerAccount, sutDomainName, // managed service account is created in the local domain currentUserName, currentPassword); } else { netLogonLevel = nrpcClient.CreateNetlogonLevel( _NETLOGON_LOGON_INFO_CLASS.NetlogonNetworkInformation, NrpcParameterControlFlags.AllowLogonWithComputerAccount, sutTrustDomainName, currentUserName, currentPassword); } } _NETLOGON_LEVEL encryptedLogonLevel = nrpcClient.EncryptNetlogonLevel( logonLevel, netLogonLevel); byte?authoritative; _NETLOGON_VALIDATION? validationInformation = new _NETLOGON_VALIDATION(); NrpcNetrLogonSamLogonExtraFlags?extraFlags = NrpcNetrLogonSamLogonExtraFlags.None; result = nrpcClient.NetrLogonSamLogonEx( nrpcClient.Handle, sutComputerName, clientComputerName, logonLevel, encryptedLogonLevel, validationLevel, out validationInformation, out authoritative, ref extraFlags); // Whether this method use pass-through mechanism or not. bool isPassThroughMethod = false; // //For NTLM pass-through, the LogonLevel is 1(NetlogonInteractiveInformation) or 2(NetlogonNetworkInformation) //based on Interactive Logono and Network Logon,as defined in [MS-APDS] section 3.1.5.1 and section 3.1.5.2. //So when the LogonLevel is 1 or 2, we can say that NRPC pass-through authentication method is used. // if ((int)logonLevel == 1 || (int)logonLevel == 2) { isPassThroughMethod = true; } // //Verify MS-APDS requirment:MS-APDS_R5 // Site.CaptureRequirementIfIsTrue( isPassThroughMethod, 5, @"For domain support, authentication protocols MUST use an NRPC pass-through authentication ([MS-NRPC] section 3.2) method with parameters determined by the authentication protocol being used[to return the response structures to member server]."); // //Verify MS-APDS requirment:MS-APDS_R118 //if isPassThroughMethod is true, this requirement can be verified. // Site.CaptureRequirementIfIsTrue( isPassThroughMethod, 118, @"NT LAN Manager (NTLM) interactive logon and network logon MUST receive the authentication response sequence by contacting the DC using an NRPC pass-through authentication method ."); if (result == NtStatus.STATUS_SUCCESS) { if (validationLevel == _NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo4) { VerifyNTLMDataStructure(validationLevel, logonLevel); VerifyMessageSyntxNTLMValidV4Resp( validationInformation.Value.ValidationSam4[0].UserSessionKey.data[0].data, validationInformation.Value.ValidationSam4[0].EffectiveName.ToString()); } else if (validationLevel == _NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo2) { VerifyNTLMDataStructure(validationLevel, logonLevel); } else if (validationLevel == _NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo) { VerifyNTLMDataStructure(validationLevel, logonLevel); } } return((Status)result); }
public void NRPC_Traditional05_VerifyOutOfSequenceMessage() { PlatformType platform; HRESULT result = HRESULT.ERROR_SUCCESS; Site.Log.Add(LogEntryKind.Comment, "Call GetPlatform"); nrpcServerAdapter.GetPlatform(out platform); Site.Log.Add(LogEntryKind.Comment, "Return GetPlatform(out {0})", platform); Site.Log.Add(LogEntryKind.Comment, "Call ConfigServer"); nrpcServerSutControlAdapter.ConfigServer(true, false); Site.Log.Add(LogEntryKind.Comment, "Return ConfigServer"); NrpcServerAdapter adapter = new NrpcServerAdapter(); adapter.Initialize(Site); using (this.nrpcClient = NrpcClient.CreateNrpcClient(adapter.PrimaryDomainDnsName)) { this.nrpcClient.Context.NegotiateFlags = (NrpcNegotiateFlags)NrpcServerAdapter.NegotiateFlags; MachineAccountCredential machineCredential = new MachineAccountCredential( adapter.PrimaryDomainDnsName, adapter.ENDPOINTNetbiosName, adapter.ENDPOINTPassword); NrpcClientSecurityContext secuContext = new NrpcClientSecurityContext( adapter.PrimaryDomainDnsName, adapter.PDCNetbiosName, machineCredential, true, this.nrpcClient.Context.NegotiateFlags); AccountCredential accountCredential = new AccountCredential( adapter.PrimaryDomainDnsName, adapter.DomainAdministratorName, adapter.DomainUserPassword); try { this.nrpcClient.BindOverNamedPipe( adapter.PDCNetbiosName, accountCredential, secuContext, adapter.timeOut); } catch (Exception e) { Site.Log.Add(LogEntryKind.Debug, "Failed to bind NamedPipe to " + adapter.PDCNetbiosName + "due to reason: " + e.Message); Site.Assert.Fail("Failed on init NRPC client on transport NamedPipe"); } this.nrpcClient.Context.SequenceNumber++; _NETLOGON_LOGON_INFO_CLASS logonLevelInfoClass = _NETLOGON_LOGON_INFO_CLASS.NetlogonInteractiveInformation; _NETLOGON_LEVEL logonLevel = this.nrpcClient.CreateNetlogonLevel( logonLevelInfoClass, NrpcParameterControlFlags.AllowLogonWithComputerAccount, adapter.PrimaryDomainDnsName, adapter.DomainAdministratorName, adapter.DomainUserPassword); // Client calls EncryptNetlogonLevel _NETLOGON_LEVEL?encryptedLogonLevel = this.nrpcClient.EncryptNetlogonLevel( logonLevelInfoClass, logonLevel); _NETLOGON_AUTHENTICATOR?serverAuthenticator = this.nrpcClient.CreateEmptyNetlogonAuthenticator(); _NETLOGON_AUTHENTICATOR?clientAuthenticator = this.nrpcClient.ComputeNetlogonAuthenticator(); _NETLOGON_VALIDATION? validationInfomation = null; byte?authoritative = null; try { result = (HRESULT)this.nrpcClient.NetrLogonSamLogon( adapter.PDCNetbiosName, adapter.ENDPOINTNetbiosName, clientAuthenticator, ref serverAuthenticator, logonLevelInfoClass, encryptedLogonLevel, _NETLOGON_VALIDATION_INFO_CLASS.NetlogonValidationSamInfo2, out validationInfomation, out authoritative); } catch (InvalidOperationException e) { result = (HRESULT)int.Parse(e.Message, CultureInfo.InvariantCulture); } // If the sequence number in security context is out of sequence, the server will return an error message. Site.CaptureRequirementIfAreNotEqual <HRESULT>( HRESULT.ERROR_SUCCESS, result, 853, @"[In Receiving an Initial Netlogon Signature Token, The following steps are performed to verify the data and to decrypt with AES if negotiated, otherwise RC4 if required: in step 7: ] If these two [SequenceNumber and CopySeqNumber ] do not match, an error is returned indicating that out-of-sequence data was received."); } }
/// <summary> /// Construct Nlmp pass-through network logon information structure /// from client NTLM authenticate response message /// </summary> /// <param name="parameterControl"> /// A set of bit flags that contain information pertaining to the logon validation processing. /// </param> /// <param name="nlmpAuthenticatePacket"> /// nlmp authenticate response packet sent from client machine /// </param> /// <param name="lmChallenge"> /// nlmp challenge sent from server to client /// </param> /// <returns> /// Nlmp pass-through network logon information /// </returns> /// <exception cref="ArgumentNullException"> /// Thrown when nlmpAuthenticatePacket or lmChallenge is null. /// </exception> /// <exception cref="ArgumentException"> /// Thrown when the length of lmChallenge is not equal to 8 bytes /// </exception> public static _NETLOGON_LEVEL CreateNlmpNetworkLogonInfo( NrpcParameterControlFlags parameterControl, NlmpAuthenticatePacket nlmpAuthenticatePacket, byte[] lmChallenge ) { if (nlmpAuthenticatePacket == null) { throw new ArgumentNullException("nlmpAuthenticatePacket"); } if (lmChallenge == null) { throw new ArgumentNullException("lmChallenge"); } // ServerChallenge (8 bytes): A 64-bit value that contains the NTLM challenge. // The challenge is a 64-bit nonce. The processing of the // ServerChallenge is specified in sections 3.1.5 and 3.2.5. if (lmChallenge.Length != NLMP_SERVER_CHALLENGE_LENGTH) { throw new ArgumentException( "the length of lmChallenge should be 8 bytes", "lmChallenge"); } string domainName; string userName; string logonWorkStation; _NETLOGON_LEVEL netLogonLevel = new _NETLOGON_LEVEL(); if (nlmpAuthenticatePacket.Payload.DomainName != null) { domainName = Encoding.Unicode.GetString(nlmpAuthenticatePacket.Payload.DomainName); } else { throw new ArgumentException( "DomainName field should not be null", "nlmpAuthenticatePacket"); } if (nlmpAuthenticatePacket.Payload.UserName != null) { userName = Encoding.Unicode.GetString(nlmpAuthenticatePacket.Payload.UserName); } else { throw new ArgumentException( "UserName field should not be null", "nlmpAuthenticatePacket"); } if (nlmpAuthenticatePacket.Payload.Workstation != null) { logonWorkStation = Encoding.Unicode.GetString(nlmpAuthenticatePacket.Payload.Workstation); } else { throw new ArgumentException( "WorkStation field should not be null", "nlmpAuthenticatePacket"); } //Identity: A NETLOGON_LOGON_IDENTITY_INFO structure, as specified in section MS-NRPC 2.2.1.4.15, //that contains information about the logon identity. _NETLOGON_LOGON_IDENTITY_INFO identityInfo = NrpcUtility.CreateNetlogonIdentityInfo( parameterControl, domainName, userName, logonWorkStation); netLogonLevel.LogonNetwork = new _NETLOGON_NETWORK_INFO[1]; netLogonLevel.LogonNetwork[0].Identity = identityInfo; netLogonLevel.LogonNetwork[0].LmChallenge = new LM_CHALLENGE(); netLogonLevel.LogonNetwork[0].LmChallenge.data = lmChallenge; netLogonLevel.LogonNetwork[0].LmChallengeResponse = NrpcUtility.CreateString(nlmpAuthenticatePacket.Payload.LmChallengeResponse); netLogonLevel.LogonNetwork[0].NtChallengeResponse = NrpcUtility.CreateString(nlmpAuthenticatePacket.Payload.NtChallengeResponse); return(netLogonLevel); }