public void KERB_VALIDATION_INFO() { base.Logging(); //Create kerberos test client and connect client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[1].Username, this.testConfig.LocalRealm.User[1].Password, KerberosAccountType.User, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid); BaseTestSite.Log.Add(LogEntryKind.Comment, "Construct Kerberos client for testing."); //Create and send AS request // Kerberos Proxy Service is used if (this.testConfig.UseProxy) { BaseTestSite.Log.Add(LogEntryKind.Comment, "Initialize KKDCP Client ."); KKDCPClient proxyClient = new KKDCPClient(proxyClientConfig); proxyClient.TargetDomain = this.testConfig.LocalRealm.RealmName; client.UseProxy = true; client.ProxyClient = proxyClient; } Adapter.PacHelper.commonUserFields commonUserFields = new Adapter.PacHelper.commonUserFields(); if (this.testConfig.LocalRealm.KDC[0].IsWindows) { //Don't use the same user account for ldap querys, it will change the current user account attributes NetworkCredential cred = new NetworkCredential(this.testConfig.LocalRealm.User[2].Username, this.testConfig.LocalRealm.User[2].Password, this.testConfig.LocalRealm.RealmName); commonUserFields = Adapter.PacHelper.GetCommonUserFields(this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[1].Username, cred); } KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with no PA data."); //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(); BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); //Create and send TGS request client.SendTgsRequest(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, options); KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), tgsResponse.Response.ticket.realm.Value.ToLower(), "The realm in ticket should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname), "The Service principal name in ticket should match expected."); EncryptionKey key = testConfig.QueryKey(this.testConfig.LocalRealm.ClientComputer.DefaultServiceName, this.testConfig.LocalRealm.RealmName, this.client.Context.SelectedEType); tgsResponse.DecryptTicket(key); //tgsResponse.DecryptTicket(this.testConfig.LocalRealm.ClientComputer.Password, this.testConfig.LocalRealm.ClientComputer.ServiceSalt); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), tgsResponse.TicketEncPart.crealm.Value.ToLower(), "The realm in ticket encrypted part should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].Username.ToLower(), KerberosUtility.PrincipalName2String(tgsResponse.TicketEncPart.cname).ToLower(), "The client principal name in ticket encrypted part should match expected."); //Verify PAC if (this.testConfig.IsKileImplemented) { BaseTestSite.Assert.IsNotNull(tgsResponse.TicketEncPart.authorization_data, "The ticket contains Authorization data."); AdWin2KPac adWin2kPac = FindOneInAuthData<AdWin2KPac>(tgsResponse.TicketEncPart.authorization_data.Elements); BaseTestSite.Assert.IsNotNull(adWin2kPac, "The Authorization data contains AdWin2KPac."); KerbValidationInfo kerbValidationInfo = null; foreach (var buf in adWin2kPac.Pac.PacInfoBuffers) { if (buf is KerbValidationInfo) { kerbValidationInfo = buf as KerbValidationInfo; break; } } BaseTestSite.Assert.IsNotNull(kerbValidationInfo, "KerbValidationInfo is generated."); if (this.testConfig.LocalRealm.KDC[0].IsWindows) { var flogonTime = (long)kerbValidationInfo.NativeKerbValidationInfo.LogonTime.dwHighDateTime << 32 | (long)kerbValidationInfo.NativeKerbValidationInfo.LogonTime.dwLowDateTime; if (flogonTime != 0x7FFFFFFFFFFFFFFF) { System.DateTime logonTime = System.DateTime.FromFileTime(flogonTime); } BaseTestSite.Assert.AreEqual(commonUserFields.LogonTime, flogonTime, "LogonTime in KERB_VALIDATION_INFO structure should be equal to that in AD."); long fPasswordLastSet = (long)kerbValidationInfo.NativeKerbValidationInfo.PasswordLastSet.dwHighDateTime << 32 | (long)kerbValidationInfo.NativeKerbValidationInfo.PasswordLastSet.dwLowDateTime; if (fPasswordLastSet != 0x7FFFFFFFFFFFFFFF) { System.DateTime passwordLastSet = System.DateTime.FromFileTime(fPasswordLastSet); } BaseTestSite.Assert.AreEqual(commonUserFields.PasswordLastSet, fPasswordLastSet, "PasswordLastSet in KERB_VALIDATION_INFO structure should be equal to that in AD."); var effectiveName = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.EffectiveName.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].Username.ToLower(), effectiveName.ToLower(), "The EffectiveName field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.UserName field of the SamrQueryInformationUser2 response message."); string fullName = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.FullName.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].Username.ToLower(), fullName.ToLower(), "The FullName field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.FullName field of the SamrQueryInformationUser2 response message."); string logonScript = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.LogonScript.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.ScriptPath, logonScript, "The LogonScript field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.ScriptPath field of the SamrQueryInformationUser2 response message."); string profilePath = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.ProfilePath.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.ProfilePath, profilePath, "The ProfilePath field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.ProfilePath field of the SamrQueryInformationUser2 response message."); string homeDirectory = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.HomeDirectory.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.HomeDirectory, homeDirectory, "The HomeDirectory field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.HomeDirectory field of the SamrQueryInformationUser2 response message."); string homeDirectoryDrive = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.HomeDirectoryDrive.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.HomeDrive, homeDirectoryDrive, "The HomeDirectoryDrive field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.HomeDirectoryDrive field of the SamrQueryInformationUser2 response message."); ushort logonCount = kerbValidationInfo.NativeKerbValidationInfo.LogonCount; BaseTestSite.Assert.AreEqual(commonUserFields.LogonCount, logonCount, "The LogonCount field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.LogonCount field of the SamrQueryInformationUser2 response message."); ushort badPasswordCount = kerbValidationInfo.NativeKerbValidationInfo.BadPasswordCount; BaseTestSite.Assert.AreEqual(commonUserFields.BadPwdCount, badPasswordCount, "The BadPasswordCount field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.BadPasswordCount field of the SamrQueryInformationUser2 response message."); uint userId = kerbValidationInfo.NativeKerbValidationInfo.UserId; BaseTestSite.Assert.AreEqual(commonUserFields.userId, userId, "The UserID field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.UserId field of the SamrQueryInformationUser2 response message."); uint primaryGroupId = kerbValidationInfo.NativeKerbValidationInfo.PrimaryGroupId; BaseTestSite.Assert.AreEqual(commonUserFields.primaryGroupId, primaryGroupId, "The PrimaryGroupId field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.PrimaryGroupId field of the SamrQueryInformationUser2 response message."); var userAccountControl = kerbValidationInfo.NativeKerbValidationInfo.UserAccountControl; //not the same with what is in the Active Directory //BaseTestSite.Assert.AreEqual(commonUserFields.userAccountControl, userAccountControl, "The BadPasswordCount field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.BadPasswordCount field of the SamrQueryInformationUser2 response message."); //read only, need SUT adapter uint groupCount = kerbValidationInfo.NativeKerbValidationInfo.GroupCount; BaseTestSite.Assert.AreEqual(commonUserFields.groupCount, groupCount, "The GroupCount field SHOULD be set to the Groups.MembershipCount field of the SamrGetGroupsForUser response message."); //read only, need SUT adapter Microsoft.Protocols.TestTools.StackSdk.Security.Pac._GROUP_MEMBERSHIP[] groupIds = kerbValidationInfo.NativeKerbValidationInfo.GroupIds; BaseTestSite.Assert.AreEqual(commonUserFields.groupIds.Length, groupIds.Length, "The GroupIds field SHOULD be set to the Groups.Group field of the SamrGetGroupsForUser response message."); BaseTestSite.Assert.IsTrue(groupIds.Select(id => id.RelativeId).OrderBy(id => id).SequenceEqual(commonUserFields.groupIds.OrderBy(id => id)), "The GroupIds field SHOULD be set to the Groups.Group field of the SamrGetGroupsForUser response message."); UserFlags_Values userFlags = kerbValidationInfo.NativeKerbValidationInfo.UserFlags; BaseTestSite.Assert.AreEqual(UserFlags_Values.ExtraSids, UserFlags_Values.ExtraSids & userFlags, "The D bit SHOULD be set in the UserFlags field if the ExtraSids field is populated and contains additional SIDs and all other bits MUST be set to zero."); byte[] userSessionKey = kerbValidationInfo.NativeKerbValidationInfo.UserSessionKey; byte[] allZero = userSessionKey; Array.Clear(allZero, 0, allZero.Length); BaseTestSite.Assert.AreEqual(allZero, userSessionKey, "The UserSessionKey field MUST be set to zero."); string logonServer = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.LogonServer.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.KDC[0].NetBiosName.Remove(this.testConfig.LocalRealm.KDC[0].NetBiosName.IndexOf("$")), logonServer, "The LogonServer SHOULD be set to NetbiosServerName."); string logonDomainName = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.LogonDomainName.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.Remove(this.testConfig.LocalRealm.RealmName.IndexOf(".")).ToLower(), logonDomainName.ToLower(), "The LogonDomainName SHOULD be set to NetbiosDomainName."); BaseTestSite.Assert.AreEqual(1, kerbValidationInfo.NativeKerbValidationInfo.LogonDomainId.Length, "The number of LogonDomainId should always be 1."); foreach (_RPC_SID element in kerbValidationInfo.NativeKerbValidationInfo.LogonDomainId) { byte[] expectedIdentifierAuthority = new byte[6] { 0, 0, 0, 0, 0, 5 }; BaseTestSite.Assert.AreEqual(expectedIdentifierAuthority.Length, element.IdentifierAuthority.Value.Length, "IdentifierAuthority 000005 stands for S-1-5"); for (int i = 0; i < expectedIdentifierAuthority.Length; i++) { BaseTestSite.Assert.AreEqual(expectedIdentifierAuthority[i], element.IdentifierAuthority.Value[i], "IdentifierAuthority element {0} should match expected.", i); } uint[] expectedSubAuthority = commonUserFields.domainSid; BaseTestSite.Assert.AreEqual(expectedSubAuthority.Length, element.SubAuthorityCount, "SubAuthorityCount should match expected."); for (int i = 0; i < expectedSubAuthority.Length; i++) { BaseTestSite.Assert.AreEqual(commonUserFields.domainSid[i], element.SubAuthority[i], "SubAuthorityCount element {0} should match expected."); } } KERB_VALIDATION_INFO_Reserved1_Values[] reserved1 = kerbValidationInfo.NativeKerbValidationInfo.Reserved1; BaseTestSite.Assert.AreEqual(2, reserved1.Length, "The Reserved1 field MUST be set to a two-element array of unsigned 32-bit integers."); foreach (KERB_VALIDATION_INFO_Reserved1_Values element in reserved1) { BaseTestSite.Assert.AreEqual(KERB_VALIDATION_INFO_Reserved1_Values.V1, element, "Each element of the array MUST be zero."); } KERB_VALIDATION_INFO_Reserved3_Values[] reserved3 = kerbValidationInfo.NativeKerbValidationInfo.Reserved3; BaseTestSite.Assert.AreEqual(7, reserved3.Length, "The Reserved1 field MUST be set to a seven-element array of unsigned 32-bit integers."); foreach (KERB_VALIDATION_INFO_Reserved3_Values element in reserved3) { BaseTestSite.Assert.AreEqual(KERB_VALIDATION_INFO_Reserved3_Values.V1, element, "Each element of the array MUST be zero."); } //sidcount =2 because, one for AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY SID and one for CLAIMS_VALID SID uint expectedSidCount = 2; BaseTestSite.Assert.AreEqual(expectedSidCount, kerbValidationInfo.NativeKerbValidationInfo.SidCount, "The SidCount includes the number of one AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY, one CLAIMS_VALID."); KERB_SID_AND_ATTRIBUTES[] expectedDefaultExtraSids = new KERB_SID_AND_ATTRIBUTES[expectedSidCount]; //The CLAIMS_VALID SID is "S-1-5-21-0-0-0-497" _RPC_SID CLAIMS_VALID = new _RPC_SID(); CLAIMS_VALID.Revision = 0x01; CLAIMS_VALID.IdentifierAuthority = new _RPC_SID_IDENTIFIER_AUTHORITY(); CLAIMS_VALID.IdentifierAuthority.Value = new byte[] { 0, 0, 0, 0, 0, 5 }; CLAIMS_VALID.SubAuthorityCount = 5; CLAIMS_VALID.SubAuthority = new uint[] { 21, 0, 0, 0, 497 }; expectedDefaultExtraSids[0] = new KERB_SID_AND_ATTRIBUTES(); expectedDefaultExtraSids[0].Attributes = Attributes_Values.Mandatory | Attributes_Values.EnabledByDefault | Attributes_Values.Enabled; expectedDefaultExtraSids[0].SID = new _RPC_SID[1]; expectedDefaultExtraSids[0].SID[0] = CLAIMS_VALID; //The AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY SID is "S-1-18-1" _RPC_SID AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY = new _RPC_SID(); AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.Revision = 0x01; AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.IdentifierAuthority = new _RPC_SID_IDENTIFIER_AUTHORITY(); AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.IdentifierAuthority.Value = new byte[] { 0, 0, 0, 0, 0, 18 }; AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.SubAuthorityCount = 1; AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.SubAuthority = new uint[] { 1 }; expectedDefaultExtraSids[1] = new KERB_SID_AND_ATTRIBUTES(); expectedDefaultExtraSids[1].Attributes = Attributes_Values.Mandatory | Attributes_Values.EnabledByDefault | Attributes_Values.Enabled; expectedDefaultExtraSids[1].SID = new _RPC_SID[1]; expectedDefaultExtraSids[1].SID[0] = AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY; var expectedExtraSids = expectedDefaultExtraSids; uint res = expectedSidCount; for (int i = 0; i < expectedSidCount; i++) { for (int j = 0; j < expectedSidCount; j++) { if (Adapter.PacHelper.ExtraSidsAreEqual(expectedExtraSids[i], kerbValidationInfo.NativeKerbValidationInfo.ExtraSids[j])) { res--; } } } BaseTestSite.Assert.AreEqual((uint)0, res, "The ExtraSids field contains the pointer to a list which is the list copied from the PAC in the TGT plus a list constructed from the domain local groups, notice domain local groups is equal to 0 in this test case."); BaseTestSite.Assert.IsNull(kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupDomainSid, "The ResourceGroupDomainSid field MUST be set to zero."); BaseTestSite.Assert.AreEqual((uint)0, kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupCount, "The ResourceGroupCount field MUST be set to zero."); BaseTestSite.Assert.IsNull(kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupIds, "The ResourceGroupIds field MUST be set to zero."); } else { string effectiveName = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.EffectiveName.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].Username.ToLower(), effectiveName.ToLower(), "The EffectiveName field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.UserName field of the SamrQueryInformationUser2 response message."); string fullName = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.FullName.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].Username.ToLower(), fullName.ToLower(), "The FullName field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.FullName field of the SamrQueryInformationUser2 response message."); string logonScript = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.LogonScript.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.ScriptPath, logonScript, "The LogonScript field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.ScriptPath field of the SamrQueryInformationUser2 response message."); string profilePath = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.ProfilePath.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.ProfilePath, profilePath, "The ProfilePath field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.ProfilePath field of the SamrQueryInformationUser2 response message."); string homeDirectory = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.HomeDirectory.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.HomeDirectory, homeDirectory, "The HomeDirectory field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.HomeDirectory field of the SamrQueryInformationUser2 response message."); string homeDirectoryDrive = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.HomeDirectoryDrive.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.HomeDrive, homeDirectoryDrive, "The HomeDirectoryDrive field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.HomeDirectoryDrive field of the SamrQueryInformationUser2 response message."); uint userId = kerbValidationInfo.NativeKerbValidationInfo.UserId; BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.UserID, userId, "The UserID field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.UserId field of the SamrQueryInformationUser2 response message."); uint primaryGroupId = kerbValidationInfo.NativeKerbValidationInfo.PrimaryGroupId; BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.PrimaryGroupId, primaryGroupId, "The PrimaryGroupId field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.PrimaryGroupId field of the SamrQueryInformationUser2 response message."); uint userAccountControl = kerbValidationInfo.NativeKerbValidationInfo.UserAccountControl; BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.UserAccountControl, userAccountControl, "The BadPasswordCount field SHOULD be set to the Buffer.SAMPR_USER_ALL_INFORMATION.BadPasswordCount field of the SamrQueryInformationUser2 response message."); uint groupCount = kerbValidationInfo.NativeKerbValidationInfo.GroupCount; BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[1].DomainAccountInfo.GroupCount, groupCount, "The GroupCount field SHOULD be set to the Groups.MembershipCount field of the SamrGetGroupsForUser response message."); UserFlags_Values userFlags = kerbValidationInfo.NativeKerbValidationInfo.UserFlags; BaseTestSite.Assert.AreEqual(UserFlags_Values.ExtraSids, UserFlags_Values.ExtraSids & userFlags, "The D bit SHOULD be set in the UserFlags field if the ExtraSids field is populated and contains additional SIDs and all other bits MUST be set to zero."); byte[] userSessionKey = kerbValidationInfo.NativeKerbValidationInfo.UserSessionKey; byte[] allZero = userSessionKey; Array.Clear(allZero, 0, allZero.Length); BaseTestSite.Assert.AreEqual(allZero, userSessionKey, "The UserSessionKey field MUST be set to zero."); string logonServer = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.LogonServer.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.KDC[0].NetBiosName.Remove(this.testConfig.LocalRealm.KDC[0].NetBiosName.IndexOf("$")), logonServer, "The LogonServer SHOULD be set to NetbiosServerName."); string logonDomainName = Adapter.PacHelper.ConvertUnicode2String(kerbValidationInfo.NativeKerbValidationInfo.LogonDomainName.Buffer); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.Remove(this.testConfig.LocalRealm.RealmName.IndexOf(".")).ToLower(), logonDomainName.ToLower(), "The LogonDomainName SHOULD be set to NetbiosDomainName."); KERB_VALIDATION_INFO_Reserved1_Values[] reserved1 = kerbValidationInfo.NativeKerbValidationInfo.Reserved1; BaseTestSite.Assert.AreEqual(2, reserved1.Length, "The Reserved1 field MUST be set to a two-element array of unsigned 32-bit integers."); foreach (KERB_VALIDATION_INFO_Reserved1_Values element in reserved1) { BaseTestSite.Assert.AreEqual(KERB_VALIDATION_INFO_Reserved1_Values.V1, element, "Each element of the array MUST be zero."); } KERB_VALIDATION_INFO_Reserved3_Values[] reserved3 = kerbValidationInfo.NativeKerbValidationInfo.Reserved3; BaseTestSite.Assert.AreEqual(7, reserved3.Length, "The Reserved1 field MUST be set to a seven-element array of unsigned 32-bit integers."); foreach (KERB_VALIDATION_INFO_Reserved3_Values element in reserved3) { BaseTestSite.Assert.AreEqual(KERB_VALIDATION_INFO_Reserved3_Values.V1, element, "Each element of the array MUST be zero."); } //sidcount =2 because, one for AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY SID and one for CLAIMS_VALID SID uint expectedSidCount = 2; BaseTestSite.Assert.AreEqual(expectedSidCount, kerbValidationInfo.NativeKerbValidationInfo.SidCount, "The SidCount includes the number of one AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY, one CLAIMS_VALID."); KERB_SID_AND_ATTRIBUTES[] expectedDefaultExtraSids = new KERB_SID_AND_ATTRIBUTES[expectedSidCount]; //The CLAIMS_VALID SID is "S-1-5-21-0-0-0-497" _RPC_SID CLAIMS_VALID = new _RPC_SID(); CLAIMS_VALID.Revision = 0x01; CLAIMS_VALID.IdentifierAuthority = new _RPC_SID_IDENTIFIER_AUTHORITY(); CLAIMS_VALID.IdentifierAuthority.Value = new byte[] { 0, 0, 0, 0, 0, 5 }; CLAIMS_VALID.SubAuthorityCount = 5; CLAIMS_VALID.SubAuthority = new uint[] { 21, 0, 0, 0, 497 }; expectedDefaultExtraSids[0] = new KERB_SID_AND_ATTRIBUTES(); expectedDefaultExtraSids[0].Attributes = Attributes_Values.Mandatory | Attributes_Values.EnabledByDefault | Attributes_Values.Enabled; expectedDefaultExtraSids[0].SID = new _RPC_SID[1]; expectedDefaultExtraSids[0].SID[0] = CLAIMS_VALID; //The AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY SID is "S-1-18-1" _RPC_SID AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY = new _RPC_SID(); AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.Revision = 0x01; AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.IdentifierAuthority = new _RPC_SID_IDENTIFIER_AUTHORITY(); AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.IdentifierAuthority.Value = new byte[] { 0, 0, 0, 0, 0, 18 }; AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.SubAuthorityCount = 1; AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.SubAuthority = new uint[] { 1 }; expectedDefaultExtraSids[1] = new KERB_SID_AND_ATTRIBUTES(); expectedDefaultExtraSids[1].Attributes = Attributes_Values.Mandatory | Attributes_Values.EnabledByDefault | Attributes_Values.Enabled; expectedDefaultExtraSids[1].SID = new _RPC_SID[1]; expectedDefaultExtraSids[1].SID[0] = AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY; var expectedExtraSids = expectedDefaultExtraSids; uint res = expectedSidCount; for (int i = 0; i < expectedSidCount; i++) { for (int j = 0; j < expectedSidCount; j++) { if (Adapter.PacHelper.ExtraSidsAreEqual(expectedExtraSids[i], kerbValidationInfo.NativeKerbValidationInfo.ExtraSids[j])) { res--; } } } BaseTestSite.Assert.AreEqual((uint)0, res, "The ExtraSids field contains the pointer to a list which is the list copied from the PAC in the TGT plus a list constructed from the domain local groups, notice domain local groups is equal to 0 in this test case."); BaseTestSite.Assert.IsNull(kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupDomainSid, "The ResourceGroupDomainSid field MUST be set to zero."); BaseTestSite.Assert.AreEqual((uint)kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupIds.Length, kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupCount, "The ResourceGroupCount field MUST be set to zero."); BaseTestSite.Assert.IsNull(kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupIds, "The ResourceGroupIds field MUST be set to zero."); } } }
public void DomainLocalGroupMembershipWithDisableResourceSIDCompressionSet() { base.Logging(); //Create kerberos test client and connect client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[13].Username, this.testConfig.LocalRealm.User[13].Password, KerberosAccountType.User, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid); BaseTestSite.Log.Add(LogEntryKind.Comment, "Construct Kerberos client for testing."); //Create and send AS request // Kerberos Proxy Service is used if (this.testConfig.UseProxy) { BaseTestSite.Log.Add(LogEntryKind.Comment, "Initialize KKDCP Client ."); KKDCPClient proxyClient = new KKDCPClient(proxyClientConfig); proxyClient.TargetDomain = this.testConfig.LocalRealm.RealmName; client.UseProxy = true; client.ProxyClient = proxyClient; } Adapter.PacHelper.commonUserFields commonUserFields = new Adapter.PacHelper.commonUserFields(); if (this.testConfig.LocalRealm.KDC[0].IsWindows) { //Don't use the same user account for ldap querys, it will change the current user account attributes NetworkCredential cred = new NetworkCredential(this.testConfig.LocalRealm.Admin.Username, this.testConfig.LocalRealm.Admin.Password, this.testConfig.LocalRealm.RealmName); commonUserFields = Adapter.PacHelper.GetCommonUserFields(this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[13].Username, cred); } KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with no PA data."); //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(); BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); //Create and send TGS request client.SendTgsRequest(this.testConfig.LocalRealm.LocalResources[1].DefaultServiceName, options, seqOfPaData); KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), tgsResponse.Response.ticket.realm.Value.ToLower(), "The realm in ticket should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.LocalResources[1].DefaultServiceName, KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname), "The Service principal name in ticket should match expected."); tgsResponse.DecryptTicket(this.testConfig.LocalRealm.LocalResources[1].Password, this.testConfig.LocalRealm.LocalResources[1].ServiceSalt); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), tgsResponse.TicketEncPart.crealm.Value.ToLower(), "The realm in ticket encrypted part should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[13].Username.ToLower(), KerberosUtility.PrincipalName2String(tgsResponse.TicketEncPart.cname).ToLower(), "The client principal name in ticket encrypted part should match expected."); //Verify PAC if (this.testConfig.IsKileImplemented && this.testConfig.LocalRealm.KDC[0].IsWindows) { BaseTestSite.Assert.IsNotNull(tgsResponse.TicketEncPart.authorization_data, "The ticket contains Authorization data."); AdWin2KPac adWin2kPac = FindOneInAuthData<AdWin2KPac>(tgsResponse.TicketEncPart.authorization_data.Elements); BaseTestSite.Assert.IsNotNull(adWin2kPac, "The Authorization data contains AdWin2KPac."); KerbValidationInfo kerbValidationInfo = null; foreach (var buf in adWin2kPac.Pac.PacInfoBuffers) { if (buf is KerbValidationInfo) { kerbValidationInfo = buf as KerbValidationInfo; break; } } BaseTestSite.Assert.IsNotNull(kerbValidationInfo, "KerbValidationInfo is generated."); //sidcount =2 because, one for AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY SID and one for CLAIMS_VALID SID uint resourceGroupCount = this.testConfig.LocalRealm.ResourceGroups.GroupCount; uint expectedSidCount = 2 + resourceGroupCount; BaseTestSite.Assert.AreEqual(expectedSidCount, kerbValidationInfo.NativeKerbValidationInfo.SidCount, "The SidCount includes the number of one AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY, one CLAIMS_VALID and the number of localResourceGroup SIDs."); //BaseTestSite.Assert.IsNull(kerbValidationInfo.NativeKerbValidationInfo.ExtraSids, "."); KERB_SID_AND_ATTRIBUTES[] expectedDefaultExtraSids = new KERB_SID_AND_ATTRIBUTES[2]; //The CLAIMS_VALID SID is "S-1-5-21-0-0-0-497" _RPC_SID CLAIMS_VALID = new _RPC_SID(); CLAIMS_VALID.Revision = 0x01; CLAIMS_VALID.IdentifierAuthority = new _RPC_SID_IDENTIFIER_AUTHORITY(); CLAIMS_VALID.IdentifierAuthority.Value = new byte[] { 0, 0, 0, 0, 0, 5 }; CLAIMS_VALID.SubAuthorityCount = 5; CLAIMS_VALID.SubAuthority = new uint[] { 21, 0, 0, 0, 497 }; expectedDefaultExtraSids[0] = new KERB_SID_AND_ATTRIBUTES(); expectedDefaultExtraSids[0].Attributes = Attributes_Values.Mandatory | Attributes_Values.EnabledByDefault | Attributes_Values.Enabled; expectedDefaultExtraSids[0].SID = new _RPC_SID[1]; expectedDefaultExtraSids[0].SID[0] = CLAIMS_VALID; //The AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY SID is "S-1-18-1" _RPC_SID AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY = new _RPC_SID(); AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.Revision = 0x01; AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.IdentifierAuthority = new _RPC_SID_IDENTIFIER_AUTHORITY(); AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.IdentifierAuthority.Value = new byte[] { 0, 0, 0, 0, 0, 18 }; AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.SubAuthorityCount = 1; AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY.SubAuthority = new uint[] { 1 }; expectedDefaultExtraSids[1] = new KERB_SID_AND_ATTRIBUTES(); expectedDefaultExtraSids[1].Attributes = Attributes_Values.Mandatory | Attributes_Values.EnabledByDefault | Attributes_Values.Enabled; expectedDefaultExtraSids[1].SID = new _RPC_SID[1]; expectedDefaultExtraSids[1].SID[0] = AUTHENTICATION_AUTHORITY_ASSERTED_IDENTITY; Adapter.Group[] resourceGroups = this.testConfig.LocalRealm.ResourceGroups.Groups; NetworkCredential cred = new NetworkCredential(this.testConfig.LocalRealm.Admin.Username, this.testConfig.LocalRealm.Admin.Password, this.testConfig.LocalRealm.RealmName); KERB_SID_AND_ATTRIBUTES[] expectedResourceGroupExtraSids = Adapter.PacHelper.GetResourceGroupExtraSids(this.testConfig.LocalRealm.RealmName, cred, resourceGroupCount, resourceGroups); var expectedExtraSids = expectedDefaultExtraSids.Concat(expectedResourceGroupExtraSids).ToArray(); var res = expectedSidCount; for (int i = 0; i < expectedSidCount; i++) { for (int j = 0; j < expectedSidCount; j++) { if(Adapter.PacHelper.ExtraSidsAreEqual(expectedExtraSids[i], kerbValidationInfo.NativeKerbValidationInfo.ExtraSids[j])) { res--; } } } BaseTestSite.Assert.AreEqual((uint)0, res, "The ExtraSids field contains the pointer to a list which is the list copied from the PAC in the TGT plus a list constructed from the domain local groups..."); } }
public void DomainLocalGroupMembershipWithDisableResourceSIDCompressionUnset() { base.Logging(); //Create kerberos test client and connect client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[13].Username, this.testConfig.LocalRealm.User[13].Password, KerberosAccountType.User, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid); BaseTestSite.Log.Add(LogEntryKind.Comment, "Construct Kerberos client for testing."); //Create and send AS request // Kerberos Proxy Service is used if (this.testConfig.UseProxy) { BaseTestSite.Log.Add(LogEntryKind.Comment, "Initialize KKDCP Client ."); KKDCPClient proxyClient = new KKDCPClient(proxyClientConfig); proxyClient.TargetDomain = this.testConfig.LocalRealm.RealmName; client.UseProxy = true; client.ProxyClient = proxyClient; } Adapter.PacHelper.commonUserFields commonUserFields = new Adapter.PacHelper.commonUserFields(); if (this.testConfig.LocalRealm.KDC[0].IsWindows) { //Don't use the same user account for ldap querys, it will change the current user account attributes NetworkCredential cred = new NetworkCredential(this.testConfig.LocalRealm.Admin.Username, this.testConfig.LocalRealm.Admin.Password, this.testConfig.LocalRealm.RealmName); commonUserFields = Adapter.PacHelper.GetCommonUserFields(this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[13].Username, cred); } KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with no PA data."); //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(); BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); //Create and send TGS request client.SendTgsRequest(this.testConfig.LocalRealm.LocalResources[0].DefaultServiceName, options, seqOfPaData); KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), tgsResponse.Response.ticket.realm.Value.ToLower(), "The realm in ticket should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.LocalResources[0].DefaultServiceName, KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname), "The Service principal name in ticket should match expected."); //EncryptionKey key = testConfig.QueryKey(this.testConfig.LocalRealm.LocalResources[0].DefaultServiceName, this.testConfig.LocalRealm.RealmName, this.client.Context.SelectedEType); //tgsResponse.DecryptTicket(key); tgsResponse.DecryptTicket(this.testConfig.LocalRealm.LocalResources[0].Password, this.testConfig.LocalRealm.LocalResources[0].ServiceSalt); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), tgsResponse.TicketEncPart.crealm.Value.ToLower(), "The realm in ticket encrypted part should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[13].Username, KerberosUtility.PrincipalName2String(tgsResponse.TicketEncPart.cname), "The client principal name in ticket encrypted part should match expected."); //Verify PAC if (this.testConfig.IsKileImplemented && this.testConfig.LocalRealm.KDC[0].IsWindows) { BaseTestSite.Assert.IsNotNull(tgsResponse.TicketEncPart.authorization_data, "The ticket contains Authorization data."); AdWin2KPac adWin2kPac = FindOneInAuthData<AdWin2KPac>(tgsResponse.TicketEncPart.authorization_data.Elements); BaseTestSite.Assert.IsNotNull(adWin2kPac, "The Authorization data contains AdWin2KPac."); KerbValidationInfo kerbValidationInfo = null; foreach (var buf in adWin2kPac.Pac.PacInfoBuffers) { if (buf is KerbValidationInfo) { kerbValidationInfo = buf as KerbValidationInfo; break; } } BaseTestSite.Assert.IsNotNull(kerbValidationInfo, "KerbValidationInfo is generated."); BaseTestSite.Assert.AreEqual(1, kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupDomainSid.Length, "The number of ResourceGroupDomainSid should be 1 as is configured."); foreach (_RPC_SID element in kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupDomainSid) { byte[] expectedIdentifierAuthority = new byte[6] { 0, 0, 0, 0, 0, 5 }; BaseTestSite.Assert.AreEqual(expectedIdentifierAuthority.Length, element.IdentifierAuthority.Value.Length, "IdentifierAuthority 000005 stands for S-1-5"); BaseTestSite.Assert.IsTrue(element.IdentifierAuthority.Value.SequenceEqual(expectedIdentifierAuthority), "IdentifierAuthority elements should match expected."); uint[] expectedSubAuthority = commonUserFields.domainSid; BaseTestSite.Assert.AreEqual(expectedSubAuthority.Length, element.SubAuthorityCount, "SubAuthorityCount should match expected."); BaseTestSite.Assert.IsTrue(element.SubAuthority.SequenceEqual(expectedSubAuthority), "SubAuthorityCount elements should match expected."); } uint resourceGroupCount = this.testConfig.LocalRealm.ResourceGroups.GroupCount; BaseTestSite.Assert.AreEqual((uint)resourceGroupCount, kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupCount, "The ResourceGroupCount field contains the number of groups in the ResourceGroupIds field."); Adapter.Group[] resourceGroups = this.testConfig.LocalRealm.ResourceGroups.Groups; NetworkCredential cred = new NetworkCredential(this.testConfig.LocalRealm.Admin.Username, this.testConfig.LocalRealm.Admin.Password, this.testConfig.LocalRealm.RealmName); uint[] expectedResourceGroupIds = Adapter.PacHelper.GetResourceGroupIds(this.testConfig.LocalRealm.RealmName, cred, resourceGroupCount, resourceGroups); for (int i = 0; i < resourceGroupCount; i++) { BaseTestSite.Assert.AreEqual(Attributes_Values.Mandatory | Attributes_Values.EnabledByDefault | Attributes_Values.Enabled | Attributes_Values.Resource, kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupIds[i].Attributes, "The Attributes have the A, B, C and E bits set to 1, and all other bits set to zero."); } BaseTestSite.Assert.IsTrue(kerbValidationInfo.NativeKerbValidationInfo.ResourceGroupIds.Select(id => id.RelativeId).OrderBy(id => id).SequenceEqual(expectedResourceGroupIds.OrderBy(id => id)), "RelativeId contains the RID of the value pmsgOut.ppDsNames.Sid."); } }
public void CrossRealmGetReferralTGT() { base.Logging(); client = new KerberosTestClient(this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[1].Username, this.testConfig.LocalRealm.User[1].Password, KerberosAccountType.User, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid); // Kerberos Proxy Service is used if (this.testConfig.UseProxy) { BaseTestSite.Log.Add(LogEntryKind.Comment, "Initialize KKDCP Client ."); KKDCPClient proxyClient = new KKDCPClient(proxyClientConfig); proxyClient.TargetDomain = this.testConfig.LocalRealm.RealmName; client.UseProxy = true; client.ProxyClient = proxyClient; } //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); Asn1SequenceOf<PA_DATA> seqOfPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data }); //Create and send AS request client.SendAsRequest(options, seqOfPaData); KerberosAsResponse asResponse = client.ExpectAsResponse(); //Create and send TGS request if (this.testConfig.TrustType == Adapter.TrustType.Forest) { client.SendTgsRequest(this.testConfig.TrustedRealm.FileServer[0].Smb2ServiceName, options); } else if (this.testConfig.TrustType == Adapter.TrustType.Realm) { client.SendTgsRequest(this.testConfig.TrustedRealm.KDC[0].DefaultServiceName, options); } KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); EncryptionKey key = testConfig.QueryKey( this.testConfig.TrustedRealm.KDC[0].DefaultServiceName + "@" + this.testConfig.LocalRealm.RealmName, client.Context.Realm.ToString(), client.Context.SelectedEType); tgsResponse.DecryptTicket(key); 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."); //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 referral 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."); //verify referral info PaSvrReferralInfo paSvrReferralInfo = null; foreach (PA_DATA item in tgsResponse.EncPart.pa_datas.Elements) { if (item.padata_type.Value == (long)PaDataType.PA_SVR_REFERRAL_INFO) { paSvrReferralInfo = PaSvrReferralInfo.Parse(item); break; } } BaseTestSite.Assert.IsNotNull(paSvrReferralInfo, "Tgs response should include PaSvrReferralInfo in encrypted part."); BaseTestSite.Assert.AreEqual(this.testConfig.TrustedRealm.RealmName.ToLower(), paSvrReferralInfo.PaSvrReferralData.referred_realm.Value.ToLower(), "Realm name in PaSvrReferralInfo should match expect trusted realm name."); //decrypt ticket in the TGS response key = testConfig.QueryKey(this.testConfig.TrustedRealm.FileServer[0].Smb2ServiceName, client.Context.Realm.ToString(), client.Context.SelectedEType); refTgsResponse.DecryptTicket(key); //verify the unencrypted part 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[1].Username.ToLower(), KerberosUtility.PrincipalName2String(refTgsResponse.TicketEncPart.cname).ToLower(), "User name in service ticket encrypted part should match expected."); //Verify PAC if (this.testConfig.IsKileImplemented) { BaseTestSite.Assert.IsNotNull(tgsResponse.TicketEncPart.authorization_data, "The ticket contains Authorization data."); AdWin2KPac adWin2kPac = FindOneInAuthData<AdWin2KPac>(tgsResponse.TicketEncPart.authorization_data.Elements); BaseTestSite.Assert.IsNotNull(adWin2kPac, "The Authorization data contains AdWin2KPac."); foreach (var buf in adWin2kPac.Pac.PacInfoBuffers) { if (buf is KerbValidationInfo) { KerbValidationInfo kerbValidationInfo =null ; kerbValidationInfo=buf as KerbValidationInfo; uint userId = kerbValidationInfo.NativeKerbValidationInfo.UserId; Adapter.PacHelper.commonUserFields commonUserFields = new Adapter.PacHelper.commonUserFields(); if (this.testConfig.LocalRealm.KDC[0].IsWindows) { //Don't use the same user account for ldap querys, it will change the current user account attributes NetworkCredential cred = new NetworkCredential(this.testConfig.LocalRealm.Admin.Username, this.testConfig.LocalRealm.Admin.Password, this.testConfig.LocalRealm.RealmName); commonUserFields = Adapter.PacHelper.GetCommonUserFields(this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[1].Username, cred); } BaseTestSite.Assert.AreEqual(commonUserFields.userId, userId, "The UserID field SHOULD match local realm client user sid."); } if (buf is PacClientInfo) { PacClientInfo pacClientInfo = null; pacClientInfo = buf as PacClientInfo; BaseTestSite.Assert.IsNotNull(pacClientInfo, "PAC_CLIENT_INFO is generated."); var authTimeInPac = DtypUtility.ToDateTime(pacClientInfo.NativePacClientInfo.ClientId).ToString("yyyyMMddHHmmss") + "Z"; var c = asResponse.EncPart.authtime; BaseTestSite.Assert.AreEqual( asResponse.EncPart.authtime.ToString(), authTimeInPac, "ClientId field is a FILETIME structure in little-endian format that contains the Kerberos initial TGT auth time."); string clientName = new string(pacClientInfo.NativePacClientInfo.Name); BaseTestSite.Assert.AreEqual( pacClientInfo.NativePacClientInfo.Name.Length * sizeof(char), pacClientInfo.NativePacClientInfo.NameLength, "The User NameLength field should match the client user account name length."); BaseTestSite.Assert.AreEqual( this.testConfig.LocalRealm.User[1].Username.ToLower(), clientName.ToLower(), "The User Name field should match the client user account name."); } if (buf is UpnDnsInfo) { UpnDnsInfo upnDnsInfo = null; upnDnsInfo = buf as UpnDnsInfo; BaseTestSite.Assert.IsNotNull(buf, "UPN_DNS_INFO is generated."); BaseTestSite.Assert.AreEqual(upnDnsInfo.Upn.Length * 2, upnDnsInfo.NativeUpnDnsInfo.UpnLength, "The UpnLength field SHOULD be the length of the UPN field, in bytes."); //upnDnsInfo.NativeUpnDnsInfo.UpnOffset; BaseTestSite.Assert.AreEqual(upnDnsInfo.DnsDomain.Length * 2, upnDnsInfo.NativeUpnDnsInfo.DnsDomainNameLength, "The DnsDomainNameLength field SHOULD be the length of the DnsDomainName field, in bytes."); //upnDnsInfo.NativeUpnDnsInfo.DnsDomainNameOffset; BaseTestSite.Assert.AreEqual(upnDnsInfo.Upn.ToLower(), this.testConfig.LocalRealm.User[1].Username.ToLower() + "@" + this.testConfig.LocalRealm.RealmName.ToLower(), "The UPN field should be the user principal name in local realm "); BaseTestSite.Assert.AreEqual(upnDnsInfo.DnsDomain.ToLower(), this.testConfig.LocalRealm.RealmName.ToLower(), "The dnsDomain field should be the local realm name"); } if (buf is PacServerSignature) { PacServerSignature serverSignature = null; serverSignature = buf as PacServerSignature; BaseTestSite.Assert.IsNotNull(serverSignature, "Server Signature is generated."); } if(buf is PacKdcSignature) { PacKdcSignature kdcSignature = null; kdcSignature = buf as PacKdcSignature; BaseTestSite.Assert.IsNotNull(kdcSignature, "KDC Signature is generated."); } } } }