public void APDS_S3_TC06_DIGEST_REJECT_ALGTYPE_MD5_ASSUMED()
        {
            //authentication request with  MD5(AlgType:0x02)
            IgnoredFields ignorefFields  = new IgnoredFields();
            Status        responseStatus = apdsServerAdapter.GenerateDigestRequest(
                true,
                AccountInformation.Valid,
                DigestType_Values.Basic,
                AlgType_Values.NotPresentAndMD5Assumed,
                ignorefFields);

            //
            //Configured in PTFConfig file,default SHOULD to true and MAY to false.
            //
            string isR300182Implemented = "true";

            //
            //Check OS version
            //
            if (isServerWindows)
            {
                if (null == isR300182Implemented)
                {
                    Site.Properties.Add("R300182Implemented", Boolean.TrueString);
                    isR300182Implemented = Boolean.TrueString;
                }
            }
            if (null != isR300182Implemented)
            {
                bool implSigns   = Boolean.Parse(isR300182Implemented);
                bool isSatisfied = ((uint)Status.NotSupported == (uint)responseStatus);

                //
                //Verify MS-APDS requirment:MS-APDS_R300182
                //
                Site.CaptureRequirementIfAreEqual <Boolean>(
                    implSigns,
                    isSatisfied,
                    300182,
                    @"If the AlgType field of the DIGEST_VALIDATION_REQ (section 2.2.3.1) is not set to 0x03, 
                    then the DC SHOULD return SEC_E_QOP_NOT_SUPPORTED.<22>");
            }
        }
        public void APDS_S3_TC02_DIGEST_OVER_HTTP_INVALID_INFO()
        {
            IgnoredFields ignorefFields  = new IgnoredFields();
            Status        responseStatus = apdsServerAdapter.GenerateDigestRequest(
                true,
                AccountInformation.AccountNotExist,
                DigestType_Values.Basic,
                AlgType_Values.MD5SessDigestAndChecksum,
                ignorefFields);

            //test cases validation
            Site.CaptureRequirementIfAreEqual <Status>(
                Status.LogonFailure,
                responseStatus,
                100,
                @"On logon failure, it[status field in the DIGEST_VALIDATION_RESP Message] MUST be set to STATUS_LOGON_FAILURE.");

            //test cases validation
            Site.CaptureRequirementIfAreNotEqual <Status>(
                Status.Success,
                responseStatus,
                186,
                @"If unsuccessful, the digest validation server DC MUST return an error code as an error status in NRPC API.");
        }
コード例 #3
0
        /// <summary>
        /// This method constructs the digest request structure which is required to send from protocol client to protocol server.
        /// </summary>
        /// <param name="digestType">It indicates the DigestType field of the DIGEST_VALIDATION_REQ</param>
        /// <param name="algType">It indicates the AlgType field of the DIGEST_VALIDATION_REQ </param>
        /// <param name="ignoredFields">It indicates the fields that should be ignored by DC in DIGEST_VALIDATION_REQ </param>
        /// <param name="digestReq">The request structure for digest validation</param>
        private void GetDigestRequest(
            DigestType_Values digestType,
            AlgType_Values algType,
            IgnoredFields ignoredFields,
            out DIGEST_VALIDATION_REQ digestReq)
        {
            // create a temporary payload structure
            DIGEST_VALIDATION_REQ_Payload reqLoad = new DIGEST_VALIDATION_REQ_Payload();

            reqLoad.AccountName = currentUserName;
            reqLoad.Algorithm   = acceptedAlgType;
            reqLoad.Authzid     = "";
            reqLoad.Nonce       = GenerateNonce();
            reqLoad.CNonce      = reqLoad.Nonce;
            reqLoad.Hentity     = "";
            reqLoad.NonceCount  = nonceCountString;
            reqLoad.QOP         = "";
            reqLoad.Realm       = sutDomainName;
            reqLoad.URI         = "/";
            reqLoad.Username    = currentUserName;

            string servicename = serverName;
            string response    = string.Empty;

            if (digestType == DigestType_Values.Basic)
            {
                reqLoad.Method = httpRequestMethodString;

                // calling RFC 2617 algorithms for calculating H(A1) and Response, when HTTP is involved.
                string strHA1 = DigestCalcHA1HTTP(
                    reqLoad.Algorithm,
                    reqLoad.Username,
                    reqLoad.Realm,
                    currentPassword,
                    reqLoad.Nonce,
                    reqLoad.CNonce,
                    false);

                digestSessionKey = strHA1;

                response = DigestCalcResponseHTTP(
                    strHA1,
                    reqLoad.Nonce,
                    reqLoad.NonceCount,
                    reqLoad.CNonce,
                    reqLoad.QOP,
                    reqLoad.Method,
                    reqLoad.URI,
                    reqLoad.Hentity,
                    false);
            }
            else if (digestType == DigestType_Values.SASL)
            {
                reqLoad.Method = saslRequestMethodString;

                // calling RFC 2617 algorithms for calculating H(A1) and Response, when SASL is involved.
                string strHA1 = DigestCalcHA1SASL(
                    reqLoad.Authzid,
                    reqLoad.Username,
                    reqLoad.Realm,
                    currentPassword,
                    reqLoad.Nonce,
                    reqLoad.CNonce,
                    false);

                digestSessionKey = strHA1;

                response = DigestCalcResponseSASL(
                    strHA1,
                    reqLoad.Nonce,
                    reqLoad.NonceCount,
                    reqLoad.CNonce,
                    reqLoad.QOP,
                    reqLoad.URI,
                    false,
                    false);
            }
            string basicDigestCredentialString = "Digest username="******",realm=" + reqLoad.Realm
                                                 + ",nonce=" + reqLoad.Nonce
                                                 + ",uri=" + reqLoad.URI
                                                 + ",cnonce=" + reqLoad.CNonce
                                                 + ",nc=" + reqLoad.NonceCount
                                                 + ",algorithm=" + reqLoad.Algorithm
                                                 + ",response=" + response
                                                 + ",qop=" + reqLoad.QOP
                                                 + ",charset=" + encodingCodePageString
                                                 + ",service-name=" + servicename;

            DpspResponse dpspResponse = DpspBasicResponse.Decode(basicDigestCredentialString);

            DIGEST_VALIDATION_REQ digestValidationReq = ApdsUtility.CreateDigestValidationRequestPacket(
                clientComputerName,
                string.Empty,
                string.Empty,
                reqLoad.Method,
                digestType,
                acceptedAlgType,
                dpspResponse);

            digestValidationReq.CharsetType = CharsetType_Values.ISO8859_1;
            digestValidationReq.AlgType     = algType;
            digestValidationReq.Flags       = (DIGEST_VALIDATION_FLAGS)5;
            digestValidationReq.Reserved3   = (DIGEST_VALIDATION_REQ_Reserved3_Values)ignoredFields.reserved3;
            digestValidationReq.Reserved4   = (Reserved4_Values)ignoredFields.reserved4;

            digestReq = digestValidationReq;
        }
コード例 #4
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);
        }