1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.server.kerberos.protocol;
21
22
23 import java.util.HashSet;
24 import java.util.Set;
25
26 import javax.security.auth.kerberos.KerberosPrincipal;
27
28 import org.apache.directory.server.kerberos.kdc.KdcServer;
29 import org.apache.directory.server.kerberos.shared.KerberosMessageType;
30 import org.apache.directory.server.kerberos.shared.crypto.encryption.CipherTextHandler;
31 import org.apache.directory.server.kerberos.shared.crypto.encryption.EncryptionType;
32 import org.apache.directory.server.kerberos.shared.messages.AuthenticationReply;
33 import org.apache.directory.server.kerberos.shared.messages.ErrorMessage;
34 import org.apache.directory.server.kerberos.shared.messages.KdcRequest;
35 import org.apache.directory.server.kerberos.shared.messages.value.KdcOptions;
36 import org.apache.directory.server.kerberos.shared.messages.value.KerberosTime;
37 import org.apache.directory.server.kerberos.shared.messages.value.PaData;
38 import org.apache.directory.server.kerberos.shared.messages.value.RequestBodyModifier;
39 import org.apache.directory.server.kerberos.shared.store.PrincipalStore;
40
41
42
43
44
45
46
47
48 public class AuthenticationServiceTest extends AbstractAuthenticationServiceTest
49 {
50 private KdcServer config;
51 private PrincipalStore store;
52 private KerberosProtocolHandler handler;
53 private DummySession session;
54
55
56
57
58
59 public AuthenticationServiceTest()
60 {
61 config = new KdcServer();
62 store = new MapPrincipalStoreImpl();
63 handler = new KerberosProtocolHandler( config, store );
64 session = new DummySession();
65 lockBox = new CipherTextHandler();
66 }
67
68
69
70
71
72
73
74
75 public void testRequestArchetype()
76 {
77 RequestBodyModifier modifier = new RequestBodyModifier();
78 modifier.setClientName( getPrincipalName( "hnelson" ) );
79 modifier.setServerName( getPrincipalName( "hnelson" ) );
80 modifier.setRealm( "EXAMPLE.COM" );
81 modifier.setEType( config.getEncryptionTypes() );
82
83 KerberosTime till = new KerberosTime();
84 modifier.setTill( till );
85
86 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, null, modifier.getRequestBody() );
87
88 handler.messageReceived( session, message );
89
90 ErrorMessage error = ( ErrorMessage ) session.getMessage();
91
92 assertEquals( "Additional pre-authentication required", 25, error.getErrorCode() );
93 }
94
95
96
97
98
99 public void testProtocolVersionNumber()
100 {
101 RequestBodyModifier modifier = new RequestBodyModifier();
102 modifier.setClientName( getPrincipalName( "hnelson" ) );
103 modifier.setServerName( getPrincipalName( "hnelson" ) );
104 modifier.setRealm( "EXAMPLE.COM" );
105 modifier.setEType( config.getEncryptionTypes() );
106
107 KdcRequest message = new KdcRequest( 4, KerberosMessageType.AS_REQ, null, modifier.getRequestBody() );
108
109 handler.messageReceived( session, message );
110
111 ErrorMessage error = ( ErrorMessage ) session.getMessage();
112 assertEquals( "Requested protocol version number not supported", 3, error.getErrorCode() );
113 }
114
115
116
117
118
119
120 public void testIncorrectMessageDirection()
121 {
122 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REP, null, null );
123
124 handler.messageReceived( session, message );
125
126 ErrorMessage error = ( ErrorMessage ) session.getMessage();
127 assertEquals( "Incorrect message direction", 47, error.getErrorCode() );
128
129 message = new KdcRequest( 5, KerberosMessageType.TGS_REP, null, null );
130
131 handler.messageReceived( session, message );
132
133 error = ( ErrorMessage ) session.getMessage();
134 assertEquals( "Incorrect message direction", 47, error.getErrorCode() );
135 }
136
137
138
139
140
141
142
143
144
145 public void testClientNotFound()
146 {
147 RequestBodyModifier modifier = new RequestBodyModifier();
148 modifier.setClientName( getPrincipalName( "baduser" ) );
149 modifier.setServerName( getPrincipalName( "hnelson" ) );
150 modifier.setRealm( "EXAMPLE.COM" );
151 modifier.setEType( config.getEncryptionTypes() );
152
153 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, null, modifier.getRequestBody() );
154
155 handler.messageReceived( session, message );
156
157 ErrorMessage error = ( ErrorMessage ) session.getMessage();
158 assertEquals( "Client not found in Kerberos database", 6, error.getErrorCode() );
159 }
160
161
162
163
164
165
166
167
168
169
170
171 public void testEncryptionTypeNoSupport() throws Exception
172 {
173 RequestBodyModifier modifier = new RequestBodyModifier();
174 modifier.setClientName( getPrincipalName( "hnelson" ) );
175 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
176 modifier.setRealm( "EXAMPLE.COM" );
177
178 Set<EncryptionType> encryptionTypes = new HashSet<EncryptionType>();
179 encryptionTypes.add( EncryptionType.DES3_CBC_MD5 );
180
181 modifier.setEType( encryptionTypes );
182
183 modifier.setKdcOptions( new KdcOptions() );
184
185 long now = System.currentTimeMillis();
186
187 KerberosTime requestedEndTime = new KerberosTime( now + KerberosTime.DAY );
188 modifier.setTill( requestedEndTime );
189
190 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
191
192 String passPhrase = "secret";
193 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
194
195 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
196
197 handler.messageReceived( session, message );
198
199 ErrorMessage error = ( ErrorMessage ) session.getMessage();
200 assertEquals( "KDC has no support for encryption type", 14, error.getErrorCode() );
201 }
202
203
204
205
206
207
208
209 public void testServerNotFound() throws Exception
210 {
211 RequestBodyModifier modifier = new RequestBodyModifier();
212 modifier.setClientName( getPrincipalName( "hnelson" ) );
213 modifier.setServerName( getPrincipalName( "badserver" ) );
214 modifier.setRealm( "EXAMPLE.COM" );
215 modifier.setEType( config.getEncryptionTypes() );
216
217 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
218
219 String passPhrase = "secret";
220 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
221
222 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
223
224 handler.messageReceived( session, message );
225
226 ErrorMessage error = ( ErrorMessage ) session.getMessage();
227 assertEquals( "Server not found in Kerberos database", 7, error.getErrorCode() );
228 }
229
230
231
232
233
234
235 public void testClientNullKey()
236 {
237 RequestBodyModifier modifier = new RequestBodyModifier();
238 modifier.setClientName( getPrincipalName( "tquist" ) );
239 modifier.setServerName( getPrincipalName( "hnelson" ) );
240 modifier.setRealm( "EXAMPLE.COM" );
241 modifier.setEType( config.getEncryptionTypes() );
242
243 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, null, modifier.getRequestBody() );
244
245 handler.messageReceived( session, message );
246
247 ErrorMessage error = ( ErrorMessage ) session.getMessage();
248 assertEquals( "The client or server has a null key", 9, error.getErrorCode() );
249 }
250
251
252
253
254
255
256
257
258 public void testServerNullKey() throws Exception
259 {
260 RequestBodyModifier modifier = new RequestBodyModifier();
261 modifier.setClientName( getPrincipalName( "hnelson" ) );
262 modifier.setServerName( getPrincipalName( "tquist" ) );
263 modifier.setRealm( "EXAMPLE.COM" );
264 modifier.setEType( config.getEncryptionTypes() );
265
266 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
267
268 String passPhrase = "secret";
269 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
270
271 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
272
273 handler.messageReceived( session, message );
274
275 ErrorMessage error = ( ErrorMessage ) session.getMessage();
276 assertEquals( "The client or server has a null key", 9, error.getErrorCode() );
277 }
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292 public void testStartTimeAbsentNoPostdate() throws Exception
293 {
294 RequestBodyModifier modifier = new RequestBodyModifier();
295 modifier.setClientName( getPrincipalName( "hnelson" ) );
296 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
297 modifier.setRealm( "EXAMPLE.COM" );
298 modifier.setEType( config.getEncryptionTypes() );
299
300 modifier.setKdcOptions( new KdcOptions() );
301
302 long now = System.currentTimeMillis();
303
304 KerberosTime requestedEndTime = new KerberosTime( now + KerberosTime.DAY );
305 modifier.setTill( requestedEndTime );
306
307 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
308
309 String passPhrase = "secret";
310 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
311
312 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
313
314 handler.messageReceived( session, message );
315
316 AuthenticationReply reply = ( AuthenticationReply ) session.getMessage();
317
318 KerberosTime expectedStartTime = new KerberosTime( now );
319 boolean isClose = reply.getStartTime() == null
320 || Math.abs( reply.getStartTime().getTime() - expectedStartTime.getTime() ) < 5000;
321 assertTrue( "Expected start time", isClose );
322 }
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337 public void testStartTimeInThePastNoPostdate() throws Exception
338 {
339 RequestBodyModifier modifier = new RequestBodyModifier();
340 modifier.setClientName( getPrincipalName( "hnelson" ) );
341 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
342 modifier.setRealm( "EXAMPLE.COM" );
343 modifier.setEType( config.getEncryptionTypes() );
344
345 modifier.setKdcOptions( new KdcOptions() );
346
347 long now = System.currentTimeMillis();
348
349 KerberosTime requestedStartTime = new KerberosTime( now + -1 * KerberosTime.DAY );
350 modifier.setFrom( requestedStartTime );
351
352 KerberosTime requestedEndTime = new KerberosTime( now + KerberosTime.DAY );
353 modifier.setTill( requestedEndTime );
354
355 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
356
357 String passPhrase = "secret";
358 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
359
360 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
361
362 handler.messageReceived( session, message );
363
364 AuthenticationReply reply = ( AuthenticationReply ) session.getMessage();
365
366 KerberosTime expectedStartTime = new KerberosTime( now );
367 boolean isClose = reply.getStartTime() == null
368 || Math.abs( reply.getStartTime().getTime() - expectedStartTime.getTime() ) < 5000;
369 assertTrue( "Expected start time", isClose );
370 }
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385 public void testStartTimeAcceptableClockSkewNoPostdate() throws Exception
386 {
387 RequestBodyModifier modifier = new RequestBodyModifier();
388 modifier.setClientName( getPrincipalName( "hnelson" ) );
389 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
390 modifier.setRealm( "EXAMPLE.COM" );
391 modifier.setEType( config.getEncryptionTypes() );
392
393 modifier.setKdcOptions( new KdcOptions() );
394
395 long now = System.currentTimeMillis();
396
397 KerberosTime requestedStartTime = new KerberosTime( now );
398 modifier.setFrom( requestedStartTime );
399
400 KerberosTime requestedEndTime = new KerberosTime( now + KerberosTime.DAY );
401 modifier.setTill( requestedEndTime );
402
403 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
404
405 String passPhrase = "secret";
406 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
407
408 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
409
410 handler.messageReceived( session, message );
411
412 AuthenticationReply reply = ( AuthenticationReply ) session.getMessage();
413
414 KerberosTime expectedStartTime = new KerberosTime( now );
415 boolean isClose = reply.getStartTime() == null
416 || Math.abs( reply.getStartTime().getTime() - expectedStartTime.getTime() ) < 5000;
417 assertTrue( "Expected start time", isClose );
418 }
419
420
421
422
423
424
425
426
427
428
429
430
431 public void testStartTimeOrderNeverValid() throws Exception
432 {
433 RequestBodyModifier modifier = new RequestBodyModifier();
434 modifier.setClientName( getPrincipalName( "hnelson" ) );
435 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
436 modifier.setRealm( "EXAMPLE.COM" );
437 modifier.setEType( config.getEncryptionTypes() );
438
439 KdcOptions kdcOptions = new KdcOptions();
440 kdcOptions.set( KdcOptions.POSTDATED );
441 modifier.setKdcOptions( kdcOptions );
442
443 long now = System.currentTimeMillis();
444
445 KerberosTime requestedStartTime = new KerberosTime( now + KerberosTime.DAY );
446 modifier.setFrom( requestedStartTime );
447
448 KerberosTime requestedEndTime = new KerberosTime( now );
449 modifier.setTill( requestedEndTime );
450
451 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
452 String passPhrase = "secret";
453 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
454
455 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
456
457 handler.messageReceived( session, message );
458
459 ErrorMessage error = ( ErrorMessage ) session.getMessage();
460 assertEquals( "Requested start time is later than end time", 11, error.getErrorCode() );
461 }
462
463
464
465
466
467
468
469
470
471
472
473
474
475 public void testStartTimeMinimumNeverValid() throws Exception
476 {
477 RequestBodyModifier modifier = new RequestBodyModifier();
478 modifier.setClientName( getPrincipalName( "hnelson" ) );
479 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
480 modifier.setRealm( "EXAMPLE.COM" );
481 modifier.setEType( config.getEncryptionTypes() );
482
483 modifier.setKdcOptions( new KdcOptions() );
484
485 long now = System.currentTimeMillis();
486
487 KerberosTime requestedStartTime = new KerberosTime( now );
488 modifier.setFrom( requestedStartTime );
489
490 KerberosTime requestedEndTime = new KerberosTime( now + 4 * KerberosTime.MINUTE );
491 modifier.setTill( requestedEndTime );
492
493 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
494 String passPhrase = "secret";
495 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
496
497 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
498
499 handler.messageReceived( session, message );
500
501 ErrorMessage error = ( ErrorMessage ) session.getMessage();
502 assertEquals( "Requested start time is later than end time", 11, error.getErrorCode() );
503 }
504
505
506
507
508
509
510
511
512
513
514
515
516 public void testStartTimeNoPostdated() throws Exception
517 {
518 RequestBodyModifier modifier = new RequestBodyModifier();
519 modifier.setClientName( getPrincipalName( "hnelson" ) );
520 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
521 modifier.setRealm( "EXAMPLE.COM" );
522 modifier.setEType( config.getEncryptionTypes() );
523
524 modifier.setKdcOptions( new KdcOptions() );
525
526 long now = System.currentTimeMillis();
527
528 KerberosTime requestedStartTime = new KerberosTime( now + 10 * KerberosTime.MINUTE );
529 modifier.setFrom( requestedStartTime );
530
531 KerberosTime requestedEndTime = new KerberosTime( now + KerberosTime.DAY );
532 modifier.setTill( requestedEndTime );
533
534 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
535 String passPhrase = "secret";
536 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
537
538 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
539
540 handler.messageReceived( session, message );
541
542 ErrorMessage error = ( ErrorMessage ) session.getMessage();
543 assertEquals( "Ticket not eligible for postdating", 10, error.getErrorCode() );
544 }
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567 public void testSpecificStartTime() throws Exception
568 {
569 RequestBodyModifier modifier = new RequestBodyModifier();
570 modifier.setClientName( getPrincipalName( "hnelson" ) );
571 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
572 modifier.setRealm( "EXAMPLE.COM" );
573 modifier.setEType( config.getEncryptionTypes() );
574
575 KdcOptions kdcOptions = new KdcOptions();
576 kdcOptions.set( KdcOptions.POSTDATED );
577 modifier.setKdcOptions( kdcOptions );
578
579 long now = System.currentTimeMillis();
580
581 KerberosTime requestedStartTime = new KerberosTime( now + KerberosTime.DAY );
582 modifier.setFrom( requestedStartTime );
583
584 KerberosTime requestedEndTime = new KerberosTime( now + 2 * KerberosTime.DAY );
585 modifier.setTill( requestedEndTime );
586
587 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
588 String passPhrase = "secret";
589 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
590
591 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
592
593 handler.messageReceived( session, message );
594
595 AuthenticationReply reply = ( AuthenticationReply ) session.getMessage();
596
597 assertTrue( "Requested start time", requestedStartTime.equals( reply.getStartTime() ) );
598 assertTrue( "Requested end time", requestedEndTime.equals( reply.getEndTime() ) );
599 assertTrue( "POSTDATED flag", reply.getFlags().isPostdated() );
600 assertTrue( "INVALID flag", reply.getFlags().isInvalid() );
601
602 assertTrue( "Requested start time", requestedStartTime.equals( reply.getTicket().getEncTicketPart().getStartTime() ) );
603 assertTrue( "Requested end time", requestedEndTime.equals( reply.getEndTime() ) );
604 assertTrue( "POSTDATED flag", reply.getTicket().getEncTicketPart().getFlags().isPostdated() );
605 assertTrue( "INVALID flag", reply.getTicket().getEncTicketPart().getFlags().isInvalid() );
606
607 assertTrue( "PRE_AUTHENT flag", reply.getTicket().getEncTicketPart().getFlags().isPreAuth() );
608 }
609
610
611
612
613
614
615
616
617
618
619
620
621 public void testSpecificEndTime() throws Exception
622 {
623 RequestBodyModifier modifier = new RequestBodyModifier();
624 modifier.setClientName( getPrincipalName( "hnelson" ) );
625 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
626 modifier.setRealm( "EXAMPLE.COM" );
627 modifier.setEType( config.getEncryptionTypes() );
628
629 modifier.setKdcOptions( new KdcOptions() );
630
631 long now = System.currentTimeMillis();
632
633 KerberosTime requestedEndTime = new KerberosTime( now + KerberosTime.DAY / 2 );
634 modifier.setTill( requestedEndTime );
635
636 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
637
638 String passPhrase = "secret";
639 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
640
641 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
642
643 handler.messageReceived( session, message );
644
645 AuthenticationReply reply = ( AuthenticationReply ) session.getMessage();
646
647 assertTrue( "Requested end time", requestedEndTime.equals( reply.getEndTime() ) );
648
649 assertTrue( "PRE_AUTHENT flag", reply.getTicket().getEncTicketPart().getFlags().isPreAuth() );
650 }
651
652
653
654
655
656
657
658
659
660
661
662
663
664 public void testEndTimeExceedsMaximumAllowable() throws Exception
665 {
666 RequestBodyModifier modifier = new RequestBodyModifier();
667 modifier.setClientName( getPrincipalName( "hnelson" ) );
668 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
669 modifier.setRealm( "EXAMPLE.COM" );
670 modifier.setEType( config.getEncryptionTypes() );
671
672 modifier.setKdcOptions( new KdcOptions() );
673
674 long now = System.currentTimeMillis();
675
676 KerberosTime requestedEndTime = new KerberosTime( now + KerberosTime.WEEK );
677 modifier.setTill( requestedEndTime );
678
679 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
680
681 String passPhrase = "secret";
682 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
683
684 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
685
686 handler.messageReceived( session, message );
687
688 AuthenticationReply reply = ( AuthenticationReply ) session.getMessage();
689
690 KerberosTime expectedEndTime = new KerberosTime( now + KerberosTime.DAY );
691 boolean isClose = Math.abs( reply.getEndTime().getTime() - expectedEndTime.getTime() ) < 5000;
692 assertTrue( "Expected end time", isClose );
693 }
694
695
696
697
698
699
700
701
702
703 public void testEpochEndTime() throws Exception
704 {
705 RequestBodyModifier modifier = new RequestBodyModifier();
706 modifier.setClientName( getPrincipalName( "hnelson" ) );
707 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
708 modifier.setRealm( "EXAMPLE.COM" );
709 modifier.setEType( config.getEncryptionTypes() );
710
711 modifier.setKdcOptions( new KdcOptions() );
712
713 String epoch = "19700101000000Z";
714 KerberosTime requestedEndTime = KerberosTime.getTime( epoch );
715 modifier.setTill( requestedEndTime );
716
717 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
718
719 String passPhrase = "secret";
720 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
721
722 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
723
724 handler.messageReceived( session, message );
725
726 AuthenticationReply reply = ( AuthenticationReply ) session.getMessage();
727
728 long now = System.currentTimeMillis();
729 KerberosTime expectedEndTime = new KerberosTime( now + KerberosTime.DAY );
730 boolean isClose = Math.abs( reply.getEndTime().getTime() - expectedEndTime.getTime() ) < 5000;
731 assertTrue( "Expected end time", isClose );
732 }
733
734
735
736
737
738
739
740
741 public void testInitialServiceTicket() throws Exception
742 {
743 String servicePrincipalName = "ldap/ldap.example.com@EXAMPLE.COM";
744
745 RequestBodyModifier modifier = new RequestBodyModifier();
746 modifier.setClientName( getPrincipalName( "hnelson" ) );
747 modifier.setServerName( getPrincipalName( servicePrincipalName ) );
748 modifier.setRealm( "EXAMPLE.COM" );
749 modifier.setEType( config.getEncryptionTypes() );
750
751 modifier.setKdcOptions( new KdcOptions() );
752
753 long now = System.currentTimeMillis();
754 KerberosTime requestedEndTime = new KerberosTime( now + 1 * KerberosTime.DAY );
755 modifier.setTill( requestedEndTime );
756
757 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
758 String passPhrase = "secret";
759 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
760
761 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
762
763 handler.messageReceived( session, message );
764
765 AuthenticationReply reply = ( AuthenticationReply ) session.getMessage();
766
767 assertTrue( "INITIAL flag", reply.getFlags().isInitial() );
768 assertFalse( "INVALID flag", reply.getFlags().isInvalid() );
769
770 assertTrue( "INITIAL flag", reply.getTicket().getEncTicketPart().getFlags().isInitial() );
771 assertFalse( "INVALID flag", reply.getTicket().getEncTicketPart().getFlags().isInvalid() );
772
773 assertEquals( "Service principal name", reply.getServerPrincipal().getName(), servicePrincipalName );
774 assertEquals( "Service principal name", reply.getTicket().getServerPrincipal().getName(), servicePrincipalName );
775 }
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791 public void testRenewableOk() throws Exception
792 {
793 RequestBodyModifier modifier = new RequestBodyModifier();
794 modifier.setClientName( getPrincipalName( "hnelson" ) );
795 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
796 modifier.setRealm( "EXAMPLE.COM" );
797 modifier.setEType( config.getEncryptionTypes() );
798
799 KdcOptions kdcOptions = new KdcOptions();
800 kdcOptions.set( KdcOptions.RENEWABLE_OK );
801 modifier.setKdcOptions( kdcOptions );
802
803 long now = System.currentTimeMillis();
804
805 KerberosTime requestedEndTime = new KerberosTime( now + KerberosTime.WEEK );
806 modifier.setTill( requestedEndTime );
807
808 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
809
810 String passPhrase = "secret";
811 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
812
813 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
814
815 handler.messageReceived( session, message );
816
817 AuthenticationReply reply = ( AuthenticationReply ) session.getMessage();
818
819 KerberosTime expectedEndTime = new KerberosTime( now + KerberosTime.DAY );
820 boolean isClose = Math.abs( reply.getEndTime().getTime() - expectedEndTime.getTime() ) < 5000;
821 assertTrue( "Expected end time", isClose );
822
823 assertTrue( "RENEWABLE flag", reply.getFlags().isRenewable() );
824 assertFalse( "INVALID flag", reply.getFlags().isInvalid() );
825
826 KerberosTime expectedRenewTillTime = new KerberosTime( now + KerberosTime.WEEK );
827 isClose = Math.abs( reply.getRenewTill().getTime() - expectedRenewTillTime.getTime() ) < 5000;
828 assertTrue( "Expected renew-till time", isClose );
829 }
830
831
832
833
834
835
836
837
838
839
840
841 public void testForwardableTicket() throws Exception
842 {
843 RequestBodyModifier modifier = new RequestBodyModifier();
844 modifier.setClientName( getPrincipalName( "hnelson" ) );
845 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
846 modifier.setRealm( "EXAMPLE.COM" );
847 modifier.setEType( config.getEncryptionTypes() );
848
849 KdcOptions kdcOptions = new KdcOptions();
850 kdcOptions.set( KdcOptions.FORWARDABLE );
851 modifier.setKdcOptions( kdcOptions );
852
853 long now = System.currentTimeMillis();
854
855 KerberosTime requestedEndTime = new KerberosTime( now + 1 * KerberosTime.DAY );
856 modifier.setTill( requestedEndTime );
857
858 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
859 String passPhrase = "secret";
860 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
861
862 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
863
864 handler.messageReceived( session, message );
865
866 AuthenticationReply reply = ( AuthenticationReply ) session.getMessage();
867
868 assertTrue( "FORWARDABLE flag", reply.getFlags().isForwardable() );
869 assertFalse( "INVALID flag", reply.getFlags().isInvalid() );
870
871 assertTrue( "FORWARDABLE flag", reply.getTicket().getEncTicketPart().getFlags().isForwardable() );
872 assertFalse( "INVALID flag", reply.getTicket().getEncTicketPart().getFlags().isInvalid() );
873 }
874
875
876
877
878
879
880
881
882
883
884
885 public void testAllowPostdate() throws Exception
886 {
887 RequestBodyModifier modifier = new RequestBodyModifier();
888 modifier.setClientName( getPrincipalName( "hnelson" ) );
889 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
890 modifier.setRealm( "EXAMPLE.COM" );
891 modifier.setEType( config.getEncryptionTypes() );
892
893 KdcOptions kdcOptions = new KdcOptions();
894 kdcOptions.set( KdcOptions.ALLOW_POSTDATE );
895 modifier.setKdcOptions( kdcOptions );
896
897 long now = System.currentTimeMillis();
898
899 KerberosTime requestedEndTime = new KerberosTime( now + 1 * KerberosTime.DAY );
900 modifier.setTill( requestedEndTime );
901
902 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
903 String passPhrase = "secret";
904 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
905
906 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
907
908 handler.messageReceived( session, message );
909
910 AuthenticationReply reply = ( AuthenticationReply ) session.getMessage();
911
912 assertTrue( "MAY_POSTDATE flag", reply.getFlags().isMayPosdate() );
913 assertFalse( "INVALID flag", reply.getFlags().isInvalid() );
914
915 assertTrue( "MAY_POSTDATE flag", reply.getTicket().getEncTicketPart().getFlags().isMayPosdate() );
916 assertFalse( "INVALID flag", reply.getTicket().getEncTicketPart().getFlags().isInvalid() );
917 }
918
919
920
921
922
923
924
925
926
927
928
929 public void testProxiableTicket() throws Exception
930 {
931 RequestBodyModifier modifier = new RequestBodyModifier();
932 modifier.setClientName( getPrincipalName( "hnelson" ) );
933 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
934 modifier.setRealm( "EXAMPLE.COM" );
935 modifier.setEType( config.getEncryptionTypes() );
936
937 KdcOptions kdcOptions = new KdcOptions();
938 kdcOptions.set( KdcOptions.PROXIABLE );
939 modifier.setKdcOptions( kdcOptions );
940
941 long now = System.currentTimeMillis();
942
943 KerberosTime requestedEndTime = new KerberosTime( now + 1 * KerberosTime.DAY );
944 modifier.setTill( requestedEndTime );
945
946 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
947 String passPhrase = "secret";
948 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
949
950 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
951
952 handler.messageReceived( session, message );
953
954 AuthenticationReply reply = ( AuthenticationReply ) session.getMessage();
955
956 assertTrue( "PROXIABLE flag", reply.getFlags().isProxiable() );
957 assertFalse( "INVALID flag", reply.getFlags().isInvalid() );
958
959 assertTrue( "PROXIABLE flag", reply.getTicket().getEncTicketPart().getFlags().isProxiable() );
960 assertFalse( "INVALID flag", reply.getTicket().getEncTicketPart().getFlags().isInvalid() );
961 }
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976 public void testRenewableTicket() throws Exception
977 {
978 RequestBodyModifier modifier = new RequestBodyModifier();
979 modifier.setClientName( getPrincipalName( "hnelson" ) );
980 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
981 modifier.setRealm( "EXAMPLE.COM" );
982 modifier.setEType( config.getEncryptionTypes() );
983
984 KdcOptions kdcOptions = new KdcOptions();
985 kdcOptions.set( KdcOptions.RENEWABLE );
986 modifier.setKdcOptions( kdcOptions );
987
988 long now = System.currentTimeMillis();
989
990 KerberosTime requestedEndTime = new KerberosTime( now + 1 * KerberosTime.DAY );
991 modifier.setTill( requestedEndTime );
992
993 KerberosTime requestedRenewTillTime = new KerberosTime( now + KerberosTime.WEEK / 2 );
994 modifier.setRtime( requestedRenewTillTime );
995
996 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
997 String passPhrase = "secret";
998 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
999
1000 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
1001
1002 handler.messageReceived( session, message );
1003
1004 AuthenticationReply reply = ( AuthenticationReply ) session.getMessage();
1005
1006 assertTrue( "RENEWABLE flag", reply.getFlags().isRenewable() );
1007 assertFalse( "INVALID flag", reply.getFlags().isInvalid() );
1008
1009 assertTrue( "RENEWABLE flag", reply.getTicket().getEncTicketPart().getFlags().isRenewable() );
1010 assertFalse( "INVALID flag", reply.getTicket().getEncTicketPart().getFlags().isInvalid() );
1011
1012 assertTrue( "Requested renew-till time", requestedRenewTillTime.equals( reply.getRenewTill() ) );
1013 }
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029 public void testRenewableTicketExceedsMaximumAllowable() throws Exception
1030 {
1031 RequestBodyModifier modifier = new RequestBodyModifier();
1032 modifier.setClientName( getPrincipalName( "hnelson" ) );
1033 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
1034 modifier.setRealm( "EXAMPLE.COM" );
1035 modifier.setEType( config.getEncryptionTypes() );
1036
1037 KdcOptions kdcOptions = new KdcOptions();
1038 kdcOptions.set( KdcOptions.RENEWABLE );
1039 modifier.setKdcOptions( kdcOptions );
1040
1041 long now = System.currentTimeMillis();
1042
1043 KerberosTime requestedEndTime = new KerberosTime( now + 1 * KerberosTime.DAY );
1044 modifier.setTill( requestedEndTime );
1045
1046 KerberosTime requestedRenewTillTime = new KerberosTime( now + 2 * KerberosTime.WEEK );
1047 modifier.setRtime( requestedRenewTillTime );
1048
1049 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
1050 String passPhrase = "secret";
1051 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
1052
1053 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
1054
1055 handler.messageReceived( session, message );
1056
1057 AuthenticationReply reply = ( AuthenticationReply ) session.getMessage();
1058
1059 assertTrue( "RENEWABLE flag", reply.getFlags().isRenewable() );
1060 assertFalse( "INVALID flag", reply.getFlags().isInvalid() );
1061
1062 assertTrue( "RENEWABLE flag", reply.getTicket().getEncTicketPart().getFlags().isRenewable() );
1063 assertFalse( "INVALID flag", reply.getTicket().getEncTicketPart().getFlags().isInvalid() );
1064
1065 KerberosTime expectedRenewTillTime = new KerberosTime( now + KerberosTime.WEEK );
1066 boolean isClose = Math.abs( reply.getRenewTill().getTime() - expectedRenewTillTime.getTime() ) < 5000;
1067 assertTrue( "Expected renew-till time", isClose );
1068 }
1069
1070
1071
1072
1073
1074
1075
1076
1077 public void testBadOptionRenew() throws Exception
1078 {
1079 RequestBodyModifier modifier = new RequestBodyModifier();
1080 modifier.setClientName( getPrincipalName( "hnelson" ) );
1081 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
1082 modifier.setRealm( "EXAMPLE.COM" );
1083 modifier.setEType( config.getEncryptionTypes() );
1084
1085 KdcOptions kdcOptions = new KdcOptions();
1086 kdcOptions.set( KdcOptions.RENEW );
1087 modifier.setKdcOptions( kdcOptions );
1088
1089 long now = System.currentTimeMillis();
1090
1091 KerberosTime requestedEndTime = new KerberosTime( now + 1 * KerberosTime.DAY );
1092 modifier.setTill( requestedEndTime );
1093
1094 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
1095 String passPhrase = "secret";
1096 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
1097
1098 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
1099
1100 handler.messageReceived( session, message );
1101
1102 ErrorMessage error = ( ErrorMessage ) session.getMessage();
1103 assertEquals( "KDC cannot accommodate requested option", 13, error.getErrorCode() );
1104 }
1105
1106
1107
1108
1109
1110
1111
1112
1113 public void testBadOptionValidate() throws Exception
1114 {
1115 RequestBodyModifier modifier = new RequestBodyModifier();
1116 modifier.setClientName( getPrincipalName( "hnelson" ) );
1117 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
1118 modifier.setRealm( "EXAMPLE.COM" );
1119 modifier.setEType( config.getEncryptionTypes() );
1120
1121 KdcOptions kdcOptions = new KdcOptions();
1122 kdcOptions.set( KdcOptions.VALIDATE );
1123 modifier.setKdcOptions( kdcOptions );
1124
1125 long now = System.currentTimeMillis();
1126
1127 KerberosTime requestedEndTime = new KerberosTime( now + 1 * KerberosTime.DAY );
1128 modifier.setTill( requestedEndTime );
1129
1130 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
1131 String passPhrase = "secret";
1132 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
1133
1134 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
1135
1136 handler.messageReceived( session, message );
1137
1138 ErrorMessage error = ( ErrorMessage ) session.getMessage();
1139 assertEquals( "KDC cannot accommodate requested option", 13, error.getErrorCode() );
1140 }
1141
1142
1143
1144
1145
1146
1147
1148
1149 public void testBadOptionProxy() throws Exception
1150 {
1151 RequestBodyModifier modifier = new RequestBodyModifier();
1152 modifier.setClientName( getPrincipalName( "hnelson" ) );
1153 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
1154 modifier.setRealm( "EXAMPLE.COM" );
1155 modifier.setEType( config.getEncryptionTypes() );
1156
1157 KdcOptions kdcOptions = new KdcOptions();
1158 kdcOptions.set( KdcOptions.PROXY );
1159 modifier.setKdcOptions( kdcOptions );
1160
1161 long now = System.currentTimeMillis();
1162
1163 KerberosTime requestedEndTime = new KerberosTime( now + 1 * KerberosTime.DAY );
1164 modifier.setTill( requestedEndTime );
1165
1166 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
1167 String passPhrase = "secret";
1168 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
1169
1170 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
1171
1172 handler.messageReceived( session, message );
1173
1174 ErrorMessage error = ( ErrorMessage ) session.getMessage();
1175 assertEquals( "KDC cannot accommodate requested option", 13, error.getErrorCode() );
1176 }
1177
1178
1179
1180
1181
1182
1183
1184
1185 public void testBadOptionForwarded() throws Exception
1186 {
1187 RequestBodyModifier modifier = new RequestBodyModifier();
1188 modifier.setClientName( getPrincipalName( "hnelson" ) );
1189 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
1190 modifier.setRealm( "EXAMPLE.COM" );
1191 modifier.setEType( config.getEncryptionTypes() );
1192
1193 KdcOptions kdcOptions = new KdcOptions();
1194 kdcOptions.set( KdcOptions.FORWARDED );
1195 modifier.setKdcOptions( kdcOptions );
1196
1197 long now = System.currentTimeMillis();
1198
1199 KerberosTime requestedEndTime = new KerberosTime( now + 1 * KerberosTime.DAY );
1200 modifier.setTill( requestedEndTime );
1201
1202 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
1203 String passPhrase = "secret";
1204 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
1205
1206 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
1207
1208 handler.messageReceived( session, message );
1209
1210 ErrorMessage error = ( ErrorMessage ) session.getMessage();
1211 assertEquals( "KDC cannot accommodate requested option", 13, error.getErrorCode() );
1212 }
1213
1214
1215
1216
1217
1218
1219
1220
1221 public void testBadOptionEncTktInSkey() throws Exception
1222 {
1223 RequestBodyModifier modifier = new RequestBodyModifier();
1224 modifier.setClientName( getPrincipalName( "hnelson" ) );
1225 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
1226 modifier.setRealm( "EXAMPLE.COM" );
1227 modifier.setEType( config.getEncryptionTypes() );
1228
1229 KdcOptions kdcOptions = new KdcOptions();
1230 kdcOptions.set( KdcOptions.ENC_TKT_IN_SKEY );
1231 modifier.setKdcOptions( kdcOptions );
1232
1233 long now = System.currentTimeMillis();
1234
1235 KerberosTime requestedEndTime = new KerberosTime( now + 1 * KerberosTime.DAY );
1236 modifier.setTill( requestedEndTime );
1237
1238 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
1239 String passPhrase = "secret";
1240 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
1241
1242 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
1243
1244 handler.messageReceived( session, message );
1245
1246 ErrorMessage error = ( ErrorMessage ) session.getMessage();
1247 assertEquals( "KDC cannot accommodate requested option", 13, error.getErrorCode() );
1248 }
1249 }