Esempio n. 1
0
        /// <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);
        }
Esempio n. 2
0
        /// <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);
        }
Esempio n. 3
0
        /// <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);
        }
Esempio n. 4
0
        /// <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);
        }
Esempio n. 5
0
        /// <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);
        }
Esempio n. 6
0
        /// <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.");
            }
        }
Esempio n. 8
0
        /// <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);
        }