55
66using System ;
77using System . Collections . Generic ;
8+ using System . Linq ;
89using System . Security . Cryptography . X509Certificates ;
910using Kerberos . NET ;
1011using Kerberos . NET . Client ;
1112using Kerberos . NET . Configuration ;
1213using Kerberos . NET . Credentials ;
1314using Kerberos . NET . Crypto ;
1415using Kerberos . NET . Entities ;
16+ using Kerberos . NET . Entities . Pac ;
1517using Kerberos . NET . Server ;
1618using Microsoft . VisualStudio . TestTools . UnitTesting ;
1719using static Tests . Kerberos . NET . KdcListenerTestBase ;
@@ -33,7 +35,13 @@ public void KdcAsReqHandler_Sync()
3335 {
3436 KrbAsRep asRep = RequestTgt ( cname : Upn , crealm : Realm , srealm : Realm , out _ , out KrbAsReq asReq ) ;
3537
36- ValidateAsRep ( asRep , expectedCName : Upn , expectedCRealm : Realm , expectedSRealm : Realm , asReq ) ;
38+ ValidateAsRep (
39+ asRep ,
40+ expectedCName : Upn ,
41+ expectedCRealm : Realm ,
42+ expectedSRealm : Realm ,
43+ expectPac : true ,
44+ asReq ) ;
3745 }
3846
3947 [ TestMethod ]
@@ -77,7 +85,8 @@ out KrbEncryptionKey sessionKey
7785 expectedCName : Upn ,
7886 expectedCRealm : Realm ,
7987 expectedSName : spn ,
80- expectedSRealm : Realm ) ;
88+ expectedSRealm : Realm ,
89+ expectPac : true ) ;
8190 }
8291
8392 [ TestMethod ]
@@ -91,9 +100,21 @@ public void KdcTgsReqHandler_Sync_ReferralTgt()
91100 Name = new [ ] { Upn2WithoutRealm }
92101 } ;
93102
94- KrbAsRep asRep = CreateReferralTgt ( sourceRealm , destRealm , cname , out KerberosKey tgtKey , out KerberosKey asRepKey , out KrbEncryptionKey sessionKey ) ;
103+ KrbAsRep asRep = CreateReferralTgt (
104+ sourceRealm ,
105+ destRealm ,
106+ cname ,
107+ includePac : true ,
108+ out KerberosKey tgtKey ,
109+ out KerberosKey asRepKey ,
110+ out KrbEncryptionKey sessionKey ) ;
95111
96- ValidateAsRep ( asRep , expectedCName : Upn2WithoutRealm , expectedCRealm : sourceRealm , expectedSRealm : destRealm ) ;
112+ ValidateAsRep (
113+ asRep ,
114+ expectedCName : Upn2WithoutRealm ,
115+ expectedCRealm : sourceRealm ,
116+ expectedSRealm : destRealm ,
117+ expectPac : true ) ;
97118
98119 // Send a TGS-REQ to get a service ticket in the destination realm
99120 var spn = "host/foo." + Realm ;
@@ -131,10 +152,17 @@ out KrbEncryptionKey subSessionKey
131152 expectedCName : Upn2WithoutRealm ,
132153 expectedCRealm : sourceRealm ,
133154 expectedSName : spn ,
134- expectedSRealm : destRealm ) ;
155+ expectedSRealm : destRealm ,
156+ expectPac : true ) ;
135157 }
136158
137- private void ValidateAsRep ( KrbAsRep asRep , string expectedCName , string expectedCRealm , string expectedSRealm , KrbAsReq asReq = null )
159+ private void ValidateAsRep (
160+ KrbAsRep asRep ,
161+ string expectedCName ,
162+ string expectedCRealm ,
163+ string expectedSRealm ,
164+ bool expectPac ,
165+ KrbAsReq asReq = null )
138166 {
139167 Assert . IsNotNull ( asRep ) ;
140168
@@ -170,9 +198,31 @@ private void ValidateAsRep(KrbAsRep asRep, string expectedCName, string expected
170198 Assert . IsNotNull ( ticketEncPart ) ;
171199 Assert . AreEqual ( expectedCRealm , ticketEncPart . CRealm ) ;
172200 Assert . AreEqual ( expectedCName , ticketEncPart . CName . FullyQualifiedName ) ;
201+
202+ // Check PAC fields
203+ bool success = ticketEncPart . TryGetPac ( out PrivilegedAttributeCertificate pac ) ;
204+ if ( ! expectPac )
205+ {
206+ Assert . IsFalse ( success ) ;
207+ Assert . IsNull ( pac ) ;
208+ }
209+ else
210+ {
211+ Assert . IsTrue ( success ) ;
212+ Assert . IsNotNull ( pac ) ;
213+ Assert . AreEqual ( expectedCName , pac . ClientInformation . Name ) ;
214+ }
173215 }
174216
175- private void ValidateTgsRep ( KrbTgsRep tgsRep , KerberosKey subSessionKey , KerberosKey ticketKey , string expectedCName , string expectedCRealm , string expectedSName , string expectedSRealm )
217+ private void ValidateTgsRep (
218+ KrbTgsRep tgsRep ,
219+ KerberosKey subSessionKey ,
220+ KerberosKey ticketKey ,
221+ string expectedCName ,
222+ string expectedCRealm ,
223+ string expectedSName ,
224+ string expectedSRealm ,
225+ bool expectPac )
176226 {
177227 Assert . IsNotNull ( tgsRep ) ;
178228
@@ -200,9 +250,30 @@ private void ValidateTgsRep(KrbTgsRep tgsRep, KerberosKey subSessionKey, Kerbero
200250 Assert . IsNotNull ( ticketEncPart ) ;
201251 Assert . AreEqual ( expectedCRealm , ticketEncPart . CRealm ) ;
202252 Assert . AreEqual ( expectedCName , ticketEncPart . CName . FullyQualifiedName ) ;
253+
254+ // Check PAC fields
255+ bool success = ticketEncPart . TryGetPac ( out PrivilegedAttributeCertificate pac ) ;
256+ if ( ! expectPac )
257+ {
258+ Assert . IsFalse ( success ) ;
259+ Assert . IsNull ( pac ) ;
260+ }
261+ else
262+ {
263+ Assert . IsTrue ( success ) ;
264+ Assert . IsNotNull ( pac ) ;
265+ Assert . AreEqual ( expectedCName , pac . ClientInformation . Name ) ;
266+ }
203267 }
204268
205- private KrbAsRep CreateReferralTgt ( string sourceRealm , string destRealm , KrbPrincipalName cname , out KerberosKey tgtKey , out KerberosKey asRepKey , out KrbEncryptionKey sessionKey )
269+ private KrbAsRep CreateReferralTgt (
270+ string sourceRealm ,
271+ string destRealm ,
272+ KrbPrincipalName cname ,
273+ bool includePac ,
274+ out KerberosKey tgtKey ,
275+ out KerberosKey asRepKey ,
276+ out KrbEncryptionKey sessionKey )
206277 {
207278 var sourceRealmService = new FakeRealmService ( sourceRealm ) ;
208279
@@ -217,6 +288,39 @@ private KrbAsRep CreateReferralTgt(string sourceRealm, string destRealm, KrbPrin
217288
218289 DateTimeOffset now = DateTimeOffset . UtcNow ;
219290
291+ KrbAuthorizationData [ ] authorizationData = null ;
292+
293+ if ( includePac )
294+ {
295+ var pac = clientPrincipal . GeneratePac ( ) ;
296+ Assert . IsNotNull ( pac ) ;
297+
298+ pac . ClientInformation = new PacClientInfo
299+ {
300+ Name = cname . FullyQualifiedName ,
301+ ClientId = RpcFileTime . ConvertWithoutMicroseconds ( now ) ,
302+ } ;
303+
304+ authorizationData = new [ ]
305+ {
306+ new KrbAuthorizationData
307+ {
308+ Type = AuthorizationDataType . AdIfRelevant ,
309+ Data = new KrbAuthorizationDataSequence
310+ {
311+ AuthorizationData = new [ ]
312+ {
313+ new KrbAuthorizationData
314+ {
315+ Type = AuthorizationDataType . AdWin2kPac ,
316+ Data = pac . Encode ( tgtKey , tgtKey )
317+ }
318+ }
319+ } . Encode ( )
320+ }
321+ } ;
322+ }
323+
220324 var encTicketPart = new KrbEncTicketPart ( )
221325 {
222326 CName = cname ,
@@ -227,7 +331,7 @@ private KrbAsRep CreateReferralTgt(string sourceRealm, string destRealm, KrbPrin
227331 EndTime = now . AddHours ( 1 ) ,
228332 RenewTill = now . AddDays ( 30 ) ,
229333 Flags = TicketFlags . PreAuthenticated | TicketFlags . Initial | TicketFlags . Renewable | TicketFlags . Forwardable ,
230- AuthorizationData = null ,
334+ AuthorizationData = authorizationData ,
231335 CAddr = new KrbHostAddress [ ] { } ,
232336 Transited = new KrbTransitedEncoding ( )
233337 } ;
0 commit comments