internal override void DecodeBuffer(byte[] buffer, int index, int count)
        {
            NativeClaimsSetMetadata = PacUtility.NdrUnmarshal<PAC_CLIENT_CLAIMS_INFO>(
                buffer,
                index,
                count,
                FormatString.OffsetClientClaim, false, 4);

            byte[] decompressed = null;
            int decompressedLen = -1;
            if (NativeClaimsSetMetadata.Claims.usCompressionFormat != CLAIMS_COMPRESSION_FORMAT.COMPRESSION_FORMAT_NONE)
            {
                uint err = ClaimsCompression.Decompress(NativeClaimsSetMetadata.Claims.usCompressionFormat,
                    NativeClaimsSetMetadata.Claims.ClaimsSet,
                    (int)NativeClaimsSetMetadata.Claims.ulUncompressedClaimsSetSize,
                    out decompressed);
                if (err != 0)
                {
                    throw new Exception("Failed to decompress CLAIMS_SET data, error code is :" + err);
                }
                decompressedLen = decompressed.Length;
            }
            else
            {
                decompressed = NativeClaimsSetMetadata.Claims.ClaimsSet;
                decompressedLen = (int)NativeClaimsSetMetadata.Claims.ulClaimsSetSize;
            }
            NativeClaimSet = PacUtility.NdrUnmarshal<CLAIMS_SET>(
                decompressed,
                0,
                decompressedLen,
                FormatString.OffsetClaimSet, false, 4);
        }
Пример #2
0
        /// <summary>
        /// This case tests AD source claims in cross realm environment
        /// </summary>
        void claimsTest_Kerberos_CrossRealm_ADSource_User_Only(bool ctaFromConfig)
        {
            client = new KerberosTestClient(this.testConfig.LocalRealm.RealmName,
                 this.testConfig.LocalRealm.User[2].Username,
                 this.testConfig.LocalRealm.User[2].Password,
                 KerberosAccountType.User,
                 testConfig.LocalRealm.KDC[0].IPAddress,
                 testConfig.LocalRealm.KDC[0].Port,
                 testConfig.TransportType,
                 testConfig.SupportedOid);

            //Create and send AS request
            KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE;
            client.SendAsRequest(options, null);
            //Recieve preauthentication required error
            METHOD_DATA methodData;
            KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData);

            //Create sequence of PA data
            string timeStamp = KerberosUtility.CurrentKerberosTime.Value;
            PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp,
                0,
                this.client.Context.SelectedEType,
                this.client.Context.CName.Password,
                this.client.Context.CName.Salt);
            PaPacRequest paPacRequest = new PaPacRequest(true);
            PaPacOptions paPacOptions = new PaPacOptions(PacOptions.Claims | PacOptions.ForwardToFullDc);
            Asn1SequenceOf<PA_DATA> seqOfPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data, paPacOptions.Data });
            //Create and send AS request
            client.SendAsRequest(options, seqOfPaData);
            KerberosAsResponse asResponse = client.ExpectAsResponse();
            Asn1SequenceOf<PA_DATA> seqOfPaData2 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data});
            //Create and send TGS request
            client.SendTgsRequest(this.testConfig.TrustedRealm.KDC[0].DefaultServiceName, options, seqOfPaData2);

            BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send TGS request");
            KerberosTgsResponse tgsResponse = client.ExpectTgsResponse();
            BaseTestSite.Log.Add(LogEntryKind.Comment, "Receive a referral TGS response.");

            BaseTestSite.Assert.AreEqual(this.testConfig.TrustedRealm.KDC[0].DefaultServiceName,
               KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname),
               "The service principal name in referral ticket should match expected.");
            BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(),
               tgsResponse.Response.ticket.realm.Value.ToLower(),
               "The realm name in referral ticket should match expected.");

            EncryptionKey key = testConfig.QueryKey(this.testConfig.TrustedRealm.KDC[0].DefaultServiceName + "@" + this.testConfig.LocalRealm.RealmName, client.Context.Realm.ToString(), client.Context.SelectedEType);
            tgsResponse.DecryptTicket(key);

            CLAIMS_SET claims = new CLAIMS_SET();
            AdWin2KPac adWin2kPac = FindOneInAuthData<AdWin2KPac>(tgsResponse.TicketEncPart.authorization_data.Elements);
            bool foundClaims = false;
            foreach (PacInfoBuffer buf in adWin2kPac.Pac.PacInfoBuffers)
            {
                if (buf.GetType() == typeof(ClientClaimsInfo))
                {
                    claims = ((ClientClaimsInfo)buf).NativeClaimSet;
                    foundClaims = true;
                }
            }
            BaseTestSite.Assert.IsTrue(foundClaims, "Found claims in referral TGS Ticket");
            foundClaims = false;

            #region genertaed transformed claims
            Dictionary<string, string> expectedClaims = new Dictionary<string, string>();
            if (!ctaFromConfig)
            {
                ClaimTransformer transformer = new ClaimTransformer(this.testConfig.TrustedRealm.KDC[0].IPAddress, this.testConfig.TrustedRealm.RealmName, this.testConfig.TrustedRealm.Admin.Username, this.testConfig.TrustedRealm.Admin.Password);
                List<CLAIMS_ARRAY> transformed = null;
                BaseTestSite.Assert.AreEqual<Win32ErrorCode_32>(Win32ErrorCode_32.ERROR_SUCCESS, transformer.TransformClaimsOnTrustTraversal(claims.ClaimsArrays, this.testConfig.LocalRealm.RealmName, true, out transformed), "should successfully transform claims");
                foreach (CLAIMS_ARRAY array in transformed)
                {
                    foreach (CLAIM_ENTRY entry in array.ClaimEntries)
                    {
                        string id = entry.Id;
                        string value = null;
                        switch (entry.Type)
                        {
                            case CLAIM_TYPE.CLAIM_TYPE_BOOLEAN:
                                value = entry.Values.Struct4.BooleanValues[0].ToString();
                                break;
                            case CLAIM_TYPE.CLAIM_TYPE_INT64:
                                value = entry.Values.Struct1.Int64Values[0].ToString();
                                break;
                            case CLAIM_TYPE.CLAIM_TYPE_STRING:
                                value = entry.Values.Struct3.StringValues[0].ToString();
                                break;
                            case CLAIM_TYPE.CLAIM_TYPE_UINT64:
                                value = entry.Values.Struct2.Uint64Values[0].ToString();
                                break;
                            default:
                                BaseTestSite.Assert.Fail("Found invalid claim type during transform, value:" + (int)entry.Type);
                                break;
                        }
                        expectedClaims.Add(id.ToLower(), value.ToLower());
                    }
                }
            }
            else
            {
                string[] tmp = this.testConfig.LocalRealm.User[2].TransformedClaims.ToLower().Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                BaseTestSite.Assert.IsTrue(tmp != null && tmp.Length % 2 == 0, "Claim.Crossforest.TransformedClaims in PTFConfig should be valid and not empty");
                for (int i = 0; i < tmp.Length; i += 2)
                {
                    expectedClaims.Add(tmp[i], tmp[i + 1]);
                }
            }
            #endregion
            //Change realm
            client.ChangeRealm(this.testConfig.TrustedRealm.RealmName,
                this.testConfig.TrustedRealm.KDC[0].IPAddress,
                this.testConfig.TrustedRealm.KDC[0].Port,
                this.testConfig.TransportType);

            //Create and send referal TGS request
            client.SendTgsRequest(this.testConfig.TrustedRealm.FileServer[0].Smb2ServiceName, options);
            KerberosTgsResponse refTgsResponse = client.ExpectTgsResponse();

            BaseTestSite.Assert.AreEqual(this.testConfig.TrustedRealm.FileServer[0].Smb2ServiceName,
                KerberosUtility.PrincipalName2String(refTgsResponse.Response.ticket.sname),
                "The service principal name in service ticket should match expected.");
            BaseTestSite.Assert.AreEqual(this.testConfig.TrustedRealm.RealmName.ToLower(),
                refTgsResponse.Response.ticket.realm.Value.ToLower(),
                "The realm name in service ticket should match expected.");

            key = testConfig.QueryKey(this.testConfig.TrustedRealm.FileServer[0].Smb2ServiceName, client.Context.Realm.ToString(), client.Context.SelectedEType);
            refTgsResponse.DecryptTicket(key);

            BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(),
                refTgsResponse.TicketEncPart.crealm.Value.ToLower(),
                "Realm name in service ticket encrypted part should match expected.");
            BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[2].Username,
                KerberosUtility.PrincipalName2String(refTgsResponse.TicketEncPart.cname).ToLower(),
                "User name in service ticket encrypted part should match expected.");

            adWin2kPac = FindOneInAuthData<AdWin2KPac>(refTgsResponse.TicketEncPart.authorization_data.Elements);
            foreach (PacInfoBuffer buf in adWin2kPac.Pac.PacInfoBuffers)
            {
                if (buf.GetType() == typeof(ClientClaimsInfo))
                {
                    foundClaims = true;
                    claims = ((ClientClaimsInfo)buf).NativeClaimSet;
                }
            }

            int errors = 0;
            BaseTestSite.Assert.IsTrue(foundClaims, "Found claims in reference TGS Ticket");
            for (int i = 0; i < claims.ClaimsArrays[0].ClaimEntries.Length; i++)
            {
                string claimvalue = null;
                if (!expectedClaims.TryGetValue(claims.ClaimsArrays[0].ClaimEntries[i].Id.ToLower(), out claimvalue))
                {
                    errors++;
                    BaseTestSite.Log.Add(LogEntryKind.CheckFailed, "Found unexpected claim with id: " + claims.ClaimsArrays[0].ClaimEntries[i].Id + " after transform");
                }
                else
                {
                    if (claimvalue != claims.ClaimsArrays[0].ClaimEntries[i].Values.Struct3.StringValues[0].ToLower())
                    {
                        errors++;
                        BaseTestSite.Log.Add(
                            LogEntryKind.CheckFailed,
                            "Value of claim \"" + claims.ClaimsArrays[0].ClaimEntries[i].Id + "\" is not expected, expected: " + claimvalue + " ,actual: " + claims.ClaimsArrays[0].ClaimEntries[i].Values.Struct3.StringValues[0]);
                    }
                    expectedClaims.Remove(claims.ClaimsArrays[0].ClaimEntries[i].Id);
                }
            }

            BaseTestSite.Assert.AreEqual(expectedClaims.Count, claims.ClaimsArrays[0].ClaimEntries.Count(),"Claims count should be equal.");
            BaseTestSite.Assert.AreEqual<int>(0, errors, "Expect no error should be found when compare claims from reference TGS ticket");
        }