/// <summary> /// Construct KERB_VERIFY_PAC_REQUEST structure /// </summary> /// <param name="serverSignature"> /// PAC_SIGNATURE_DATA Signature value ([MS-PAC] section 2.8) /// for the Server Signature ([MS-PAC] section 2.8.1) /// </param> /// <param name="kdcSignature"> /// PAC_SIGNATURE_DATA SignatureType value ([MS-PAC] section 2.8) /// for the Key Distribution Center (KDC) Signature ([MS-PAC] section 2.8.1) /// </param> /// <returns>KERB_VERIFY_PAC_REQUEST structure</returns> public static KERB_VERIFY_PAC_REQUEST CreateKerbVerifyPacRequest( PAC_SIGNATURE_DATA serverSignature, PAC_SIGNATURE_DATA kdcSignature) { KERB_VERIFY_PAC_REQUEST kerbVerifyPacRequest = new KERB_VERIFY_PAC_REQUEST(); // ChecksumAndSignature (variable): The PAC_SIGNATURE_DATA Signature value // ([MS-PAC] section 2.8) for the Server Signature ([MS-PAC] section 2.8.1) in the PAC. // It MUST be followed by the PAC_SIGNATURE_DATA Signature value ([MS-PAC] section 2.8) // for the KDC Signature ([MS-PAC] section 2.8.1) in the PAC. int checksumAndSignatureLength = serverSignature.Signature.Length + kdcSignature.Signature.Length; byte[] checksumAndSignature = new byte[checksumAndSignatureLength]; checksumAndSignature = ArrayUtility.ConcatenateArrays <byte>( serverSignature.Signature, kdcSignature.Signature); kerbVerifyPacRequest.MessageType = KERB_VERIFY_PAC_REQUEST_MessageType_Values.Default; kerbVerifyPacRequest.SignatureType = (uint)kdcSignature.SignatureType; kerbVerifyPacRequest.SignatureLength = (uint)kdcSignature.Signature.Length; kerbVerifyPacRequest.ChecksumLength = (uint)serverSignature.Signature.Length; kerbVerifyPacRequest.ChecksumAndSignature = checksumAndSignature; return(kerbVerifyPacRequest); }
/// <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); }