Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / kauth / test / test_badtix.c
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12
13
14 #include <sys/types.h>
15 #include <des.h>
16 #include <afs/auth.h>
17 #include <afs/cellconfig.h>
18 #include <rx/xdr.h>
19 #include <rx/rx.h>
20 #include <rx/rxkad.h>
21 #include <lock.h>
22 #include <ubik.h>
23 #include <lwp.h>
24 #include "kauth.h"
25 #include "kautils.h"
26
27 char *whoami;
28 char *localCell;
29 char name[MAXKTCNAMELEN] = "guest";
30 char inst[MAXKTCNAMELEN] = "";
31
32 char aname[] = "AuthServer";
33 char ainst[] = "Admin";
34
35 static
36 print_entry(tentry, name, instance)
37 struct kaentryinfo *tentry;
38 char *name;
39 char *instance;
40 {
41 Date now = time(0);
42 char bob[KA_TIMESTR_LEN];
43
44 if (tentry->minor_version != KAMINORVERSION)
45 printf("Minor version number mismatch: got %d, expected %d\n",
46 tentry->minor_version, KAMINORVERSION);
47 ka_PrintUserID("User data for ", name, instance, "");
48 {
49 char *prefix = " (";
50 #define NEWPREFIX "+"
51 if (tentry->flags & KAFADMIN) {
52 printf("%sADMIN", prefix);
53 prefix = NEWPREFIX;
54 }
55 if (tentry->flags & KAFNOTGS) {
56 printf("%sNOTGS", prefix);
57 prefix = NEWPREFIX;
58 }
59 if (tentry->flags & KAFNOCPW) {
60 printf("%sNOCPW", prefix);
61 prefix = NEWPREFIX;
62 }
63 if (tentry->flags & KAFNOSEAL) {
64 printf("%sNOSEAL", prefix);
65 prefix = NEWPREFIX;
66 }
67 if (tentry->user_expiration <= now) {
68 printf("%sexpired", prefix);
69 prefix = NEWPREFIX;
70 }
71 if (strcmp(prefix, NEWPREFIX) == 0)
72 printf(")\n");
73 else
74 printf("\n");
75 }
76 printf(" key (%d):", tentry->key_version);
77 ka_PrintBytes(&tentry->key, sizeof(tentry->key));
78 ka_timestr(tentry->change_password_time, bob, KA_TIMESTR_LEN);
79 printf(", last cpw: %s\n", bob);
80 ka_timestr(tentry->user_expiration, bob, KA_TIMESTR_LEN);
81 printf(" entry expires on %s. Max ticket lifetime %.2f hours.\n", bob,
82 tentry->max_ticket_lifetime / 3600.0);
83 ka_timestr(tentry->modification_time, bob, KA_TIMESTR_LEN);
84 printf(" last mod on %s by ", bob);
85 ka_PrintUserID("", tentry->modification_user.name,
86 tentry->modification_user.instance, "\n");
87 }
88
89 int
90 sign(x)
91 int x;
92 {
93 if (x < 0)
94 return -1;
95 if (x > 0)
96 return 1;
97 return 0;
98 }
99
100 void
101 TestOldKeys(userkey)
102 struct ktc_encryptionKey *userkey;
103 {
104
105 #define MAXADMINTOKENS 30
106 #define MAXTGSTOKENS 10
107 int nAdminTokens, nTGSTokens;
108 struct ktc_token adminTokens[MAXADMINTOKENS];
109 struct ktc_token tgsTokens[MAXTGSTOKENS];
110
111 /* depends on 10 updates in 10 seconds to get AutoCPW to trigger,
112 * also 90 seconds is the maximum password age,
113 * also 11 old keys per block. */
114
115 static int OKTestVector[] = {
116 0, 1000, 3000, 1005, 1005, 1005, 1006, 1006, 1007, 1007, 1007, 1007,
117 1008,
118 1011, 3012, 3012, 1015, 3017, 3017, 3017,
119 1021, 2024, 4024, 13026, 1028, 1028, 1028, 1028, 1028, 1028, 1028,
120 1028,
121 1031, 1031, 13032, 13032, 13032, 13032, 13032, 13032, 2037, 4037,
122 13040, 13040, 13041, 13041, 13042, 13042, 2049, 4049,
123 13050, 13051, 13052, 54, 55, 56,
124 2061, 4061, 65, 65, 65, 65, 65, 65, 65, 65, 65,
125 2073, 4073, 13073, 13073, 13074, 13075, 77,
126 2085, 4085, 85, 85, 85, 85, 85, 85, 85,
127 13093,
128 2100, 1103 /* should change primary on aa */ , 4105,
129 13111
130 };
131 int nOKTestVector = sizeof(OKTestVector) / sizeof(int);
132
133 long code;
134 struct ktc_token tgt;
135 struct ktc_token atoken;
136 struct ubik_client *aconn; /* connection to authentication service */
137 struct ubik_client *tgsConn; /* connection to TGS */
138 struct ubik_client *adminConn; /* connection to maintenance service */
139 struct ktc_token ttoken;
140 struct kaentryinfo aentry;
141 struct ka_debugInfo info;
142 Date now = time(0);
143 Date start;
144 int notify;
145 int i;
146 struct ktc_encryptionKey key;
147 char *aaname = "krbtgt";
148 char *aainst = "FAKECELL.EDU";
149
150 printf("checking old keys\n");
151
152 /* get tickets */
153 if ((code =
154 ka_AuthServerConn(localCell, KA_AUTHENTICATION_SERVICE, 0, &aconn))
155 || (code =
156 ka_Authenticate(name, inst, localCell, aconn,
157 KA_TICKET_GRANTING_SERVICE, userkey, now,
158 now + 3600, &tgt, 0))
159 || (code =
160 ka_Authenticate(name, inst, localCell, aconn,
161 KA_MAINTENANCE_SERVICE, userkey, now, now + 3600,
162 &atoken, 0))
163 || (code =
164 ka_AuthServerConn(localCell, KA_TICKET_GRANTING_SERVICE, 0,
165 &tgsConn))
166 || (code =
167 ka_AuthServerConn(localCell, KA_MAINTENANCE_SERVICE, &atoken,
168 &adminConn))
169 ) {
170 abort:
171 afs_com_err(whoami, code, "testing old keys");
172 exit(1);
173 }
174
175 code = ubik_Call(KAM_GetRandomKey, adminConn, 0, &key);
176 if (code)
177 goto abort;
178 code = ubik_Call(KAM_CreateUser, adminConn, 0, aaname, aainst, key);
179 if (code == KAEXIST)
180 printf("Alternate Admin User already exists\n");
181 else if (code)
182 goto abort;
183
184 nAdminTokens = nTGSTokens = 0;
185 start = time(0);
186 notify = 10;
187 for (i = 0; i < nOKTestVector; i++) {
188 int v = OKTestVector[i]; /* get test vector */
189 int sleep;
190
191 sleep = v % 1000;
192 v = v / 1000;
193
194 if ((now = time(0)) < start + sleep)
195 IOMGR_Sleep(start + sleep - now);
196 else
197 IOMGR_Poll();
198 now = time(0);
199 if (sleep >= notify) {
200 printf("Now at %d seconds\n", sleep);
201 notify = sleep + 10;
202 }
203
204 switch (v) {
205 case 1: /* set krbtgt.FAKECELL.EDU password */
206 code = ubik_Call(KAM_GetRandomKey, adminConn, 0, &key);
207 if (code)
208 goto abort_1;
209 code =
210 ubik_Call(KAM_SetPassword, adminConn, 0, aaname, aainst, 0,
211 key);
212 break;
213 case 3: /* set AuthServer.Admin password */
214 case 13: /* and remember admin ticket */
215 code = ubik_Call(KAM_GetRandomKey, adminConn, 0, &key);
216 if (code)
217 goto abort_1;
218 code =
219 ubik_Call(KAM_SetPassword, adminConn, 0, aname, ainst, 0,
220 key);
221 if (v == 3)
222 break;
223 case 4: /* remeber Admin ticket and TGS ticket */
224 if (nAdminTokens >= MAXADMINTOKENS)
225 printf("Too many admin tokens\n");
226 else
227 code =
228 ka_Authenticate(name, inst, localCell, aconn,
229 KA_MAINTENANCE_SERVICE, userkey, now,
230 now + 3600, &adminTokens[nAdminTokens++],
231 0);
232 if (code)
233 goto abort_1;
234 if (v != 4)
235 break;
236 if (nTGSTokens >= MAXTGSTOKENS)
237 printf("Too many tgs tokens\n");
238 else
239 code =
240 ka_Authenticate(name, inst, localCell, aconn,
241 KA_TICKET_GRANTING_SERVICE, userkey, now,
242 now + 3600, &tgsTokens[nTGSTokens++], 0);
243 break;
244 case 2:
245 code =
246 ubik_Call(KAM_Debug, adminConn, 0, KAMAJORVERSION, 0, &info);
247 if (code)
248 goto abort_1;
249 now = time(0);
250 printf
251 ("Now at %d seconds (really %d): %d updates and %d seconds remaining\n",
252 sleep, (now - start), info.updatesRemaining,
253 info.nextAutoCPW - now);
254 if (info.updatesRemaining > 1)
255 printf("Too many updates needed at time %d\n", sleep);
256 while ((now = time(0)) < info.nextAutoCPW) {
257 printf("...waiting for next auto CPW\n");
258 if (info.nextAutoCPW - now > 1)
259 IOMGR_Sleep(1);
260 else
261 IOMGR_Poll();
262 }
263 code =
264 ubik_Call(KAM_SetFields, adminConn, 0, name, inst, 0, 0,
265 100 * 3600, 0, /* spares */ 0,
266 0);
267 break;
268 case 0:
269 code =
270 ubik_Call(KAM_GetEntry, adminConn, 0, aname, ainst,
271 KAMAJORVERSION, &aentry);
272 break;
273 }
274 if (code) {
275 abort_1:
276 afs_com_err(whoami, code, "at %d seconds: calling server with v=%x",
277 sleep, v);
278 exit(2);
279 }
280 }
281
282 printf("Trying %d Admin tokens\n", nAdminTokens);
283 for (i = 0; i < nAdminTokens; i++) {
284 int j;
285 struct ubik_client *conn;
286
287 for (j = i + 1; j < nAdminTokens; j++)
288 if (adminTokens[i].kvno == adminTokens[j].kvno)
289 printf("Two admin tokens with kvno %d: %d and %d\n",
290 (int)adminTokens[i].kvno, i, j);
291
292 code =
293 ka_AuthServerConn(localCell, KA_MAINTENANCE_SERVICE,
294 &adminTokens[i], &conn);
295 if (code) {
296 abort_ta:
297 afs_com_err(whoami, code, "Checking admin token #%d with kvno %d\n",
298 i, (int)adminTokens[i].kvno);
299 exit(5);
300 }
301 code =
302 ubik_Call(KAM_GetEntry, conn, 0, aname, ainst, KAMAJORVERSION,
303 &aentry);
304 if (code)
305 goto abort_ta;
306 }
307
308 printf("Trying %d TGS tokens\n", nTGSTokens);
309 for (i = 0; i < nTGSTokens; i++) {
310 int j;
311 struct ktc_token token;
312
313 for (j = i + 1; j < nTGSTokens; j++)
314 if (tgsTokens[i].kvno == tgsTokens[j].kvno)
315 printf("Two tgs tokens with kvno %d: %d and %d\n",
316 (int)tgsTokens[i].kvno, i, j);
317
318 code =
319 ka_GetToken(name, inst, localCell, name, inst, tgsConn, now,
320 now + 3600, &tgsTokens[i], "", &token);
321 if (code) {
322 afs_com_err(whoami, code, "Checking tgs token #%d with kvno %d\n", i,
323 (int)tgsTokens[i].kvno);
324 exit(6);
325 }
326 }
327
328 code = ubik_Call(KAM_DeleteUser, adminConn, 0, aaname, aainst);
329 if (code) {
330 afs_com_err(whoami, code, "Deleting alternate admin user");
331 exit(3);
332 }
333 return;
334 }
335
336 int
337 main(argc, argv)
338 int argc;
339 char *argv[];
340 {
341 int i, j;
342 long serverList[MAXSERVERS];
343 int code;
344 char *args[3];
345 struct ktc_encryptionKey key;
346 struct ktc_token tgt;
347 struct ktc_token token;
348 struct ktc_token atoken;
349 struct ubik_client *aconn; /* connection to authentication service */
350 struct ubik_client *conn;
351 struct ubik_client *lpbkConn = 0;
352 struct kaentryinfo tentry;
353 Date now = time(0);
354 Date end;
355 char password[BUFSIZ];
356 #if (BUFSIZ<=1000)
357 password needs to be at least 1000 chars long;
358 #endif
359 static char source[] =
360 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0987654321";
361 static int truncate[] =
362 { 1000, 750, 562, 432, 316, 237, 178, 133, 100, 75, 56, 42, 32, 24,
363 18, 13, 10, 8, 6, 4, 3, 2, 1, 0
364 };
365 static char answer[sizeof(truncate) / sizeof(int)][32] =
366 { "\250y\3161\315\250\361\274", "\212\133\133\345\236\206\362\200",
367 "\230b\354\334\302F\352\040", "\001\221T\016\265T\376\100",
368 "X\002\224g\250\221\214\340", "\241p\304\032\135\0328\361",
369 "\010\352\037\236sp\046\212", "\3522\352\325\247\313\023W",
370 "\023\310\034\315\265\227L\203", "z\373RJ\233\304\046m",
371 "\310\244\032\375\3704\045\323", "n\224\3022\034\376\013\247",
372 "\217\343\302\364\177\277\052\214",
373 "\357\337\010\054sv\332\057", "\373\373\316u\247\302\362g",
374 "\214O\007m\320\221\301\174", "\002\057OQ\031p\370u",
375 "k\224s\235\362\247\230\206", "\364\233\334\211\235\217k\205",
376 "\352\203m\212s\337\211d",
377 "k\354\256\364\222\352\265\323", "\205\135d\351\326\334\260\313",
378 "\345\250\331\340\265hd\222",
379 "\346\265\352\136\316\205\217\313"
380 };
381 struct ktc_encryptionKey correct_key;
382 char hostname[64];
383
384 whoami = argv[0];
385 args[0] = "";
386 args[1] = "-servers";
387
388 /* get this host */
389 gethostname(hostname, sizeof(hostname));
390 args[2] = hostname;
391
392 /* test string hacking */
393 if ((strcmp(lcstring(name, "AbcDe", 5), "abcd") != 0)
394 || (strcmp(lcstring(name, "AbcDe", 6), "abcde") != 0)
395 || (strcmp(ucstring(inst, "AbcDe", 4), "ABC") != 0)
396 || (strcmp(ucstring(inst, "AbcDe", sizeof(inst)), "ABCDE") != 0)) {
397 printf("uc/lc string problem\n");
398 exit(1);
399 }
400 #define tryscc(A,B,a,b) (sign(strcasecmp (A,B)) != sign (strcmp (a,b)))
401 if (tryscc("Abc", "abc", "abc", "abc") || tryscc("aB", "ABC", "ab", "abc")
402 || tryscc("ABC", "ab", "abc", "ab")
403 || tryscc("Abcd", "aBg", "abcd", "abg")) {
404 printf("strcasecmp problem\n");
405 exit(1);
406 }
407
408 strcpy(password, "");
409 for (i = 0; i < 100; i++)
410 for (j = 0; j < 10; j++)
411 password[i * 10 + j] = source[i % (sizeof(source) - 1)];
412
413 code = ka_CellConfig(AFSCONF_CLIENTNAME);
414 if (code)
415 afs_com_err(whoami, code, "calling cell config");
416 localCell = ka_LocalCell();
417
418 for (i = 0; i < (sizeof(truncate) / sizeof(int)); i++) {
419 password[truncate[i]] = 0;
420 ka_StringToKey(password, "andy.edu", &key);
421 ka_ReadBytes(answer[i], &correct_key, sizeof(key));
422 if (memcmp(&key, &correct_key, sizeof(key)) != 0) {
423 printf
424 ("String to key error converting '%s'; should be '%s' instead got '",
425 password, answer[i]);
426 ka_PrintBytes(&key, sizeof(key));
427 printf("'\n");
428 exit(1);
429 }
430 }
431 memset(password, 0, sizeof(password));
432 j = 0; /* current password length */
433 for (i = (sizeof(truncate) / sizeof(int)) - 1; i >= 0; i--) {
434 while (j < truncate[i]) {
435 password[j] = source[j / 10 % (sizeof(source) - 1)];
436 j++;
437 }
438 ka_StringToKey(password, "andy.edu", &key);
439 ka_ReadBytes(answer[i], &correct_key, sizeof(key));
440 if (memcmp(&key, &correct_key, sizeof(key)) != 0) {
441 printf
442 ("String to key error converting '%s'; should be '%s' instead got '",
443 password, answer[i]);
444 ka_PrintBytes(&key, sizeof(key));
445 printf("'\n");
446 }
447 }
448
449 strcpy(name, "guest");
450 strcpy(inst, "");
451
452 code = rx_Init(0);
453 if (code) {
454 afs_com_err(whoami, code, "rx_Init'ing");
455 exit(1);
456 }
457 if (code = ka_Init(0)) {
458 afs_com_err(whoami, code, "ka_Init'ing");
459 exit(1);
460 }
461 if (code = ubik_ParseClientList(3, args, serverList)) {
462 afs_com_err(whoami, code, "parsing Ubik server list");
463 exit(1);
464 }
465 ka_ExplicitCell(localCell, serverList);
466
467 {
468 struct rx_connection *conns[2];
469 struct rx_securityClass *sc;
470 int si; /* security class index */
471
472 sc = rxnull_NewClientSecurityObject();
473 si = RX_SECIDX_NULL;
474 conns[0] =
475 rx_NewConnection(htonl(INADDR_LOOPBACK), htons(AFSCONF_KAUTHPORT),
476 KA_MAINTENANCE_SERVICE, sc, si);
477 conns[1] = 0;
478 code = ubik_ClientInit(conns, &lpbkConn);
479 if (code) {
480 abort_4:
481 afs_com_err(whoami, code,
482 "getting %s's password via loopback connection to GetPassword",
483 name);
484 exit(1);
485 }
486 code = ubik_Call(KAM_GetPassword, lpbkConn, 0, name, &key);
487 if (code == KANOAUTH) {
488 printf("GetPassword disabled\n");
489 ka_StringToKey(name, localCell, &key);
490 } else if (code)
491 goto abort_4;
492 }
493
494 /* first just get TGS ticket */
495 code = ka_AuthServerConn(localCell, KA_AUTHENTICATION_SERVICE, 0, &aconn);
496 if (code) {
497 abort:
498 afs_com_err(whoami, code, "connecting to authentication service");
499 exit(1);
500 }
501 end = now + 100 * 3600 + 2;
502 code =
503 ka_Authenticate(name, inst, localCell, aconn,
504 KA_TICKET_GRANTING_SERVICE, &key, now, end, &tgt, 0);
505 if (code)
506 goto abort;
507 if (tgt.endTime == end) {
508 fprintf(stderr,
509 "*** AuthTicket expires too late: must be old style sever ***\n");
510 } else if (tgt.endTime != now + 100 * 3600) {
511 fprintf(stderr, "Bogus expiration because lifetime (%d) wrong\n",
512 tgt.endTime - tgt.startTime);
513 exit(1);
514 }
515
516 /* try to get ticket w/ time jitter */
517 code =
518 ka_Authenticate(name, inst, localCell, aconn, KA_MAINTENANCE_SERVICE,
519 &key, now + KTC_TIME_UNCERTAINTY / 2, now + 3600,
520 &token, 0);
521 if (code) {
522 abort_1:
523 afs_com_err(whoami, code, "using admin ticket with time jitter");
524 exit(1);
525 }
526
527 code =
528 ka_AuthServerConn(localCell, KA_MAINTENANCE_SERVICE, &token, &conn);
529 if (code)
530 goto abort_1;
531 code =
532 ubik_Call(KAM_GetEntry, conn, 0, name, inst, KAMAJORVERSION, &tentry);
533 if (code)
534 goto abort_1;
535 print_entry(&tentry, name, inst);
536
537 {
538 struct ktc_encryptionKey badkey;
539
540 memcpy(&badkey, &key, sizeof(badkey));
541 *(int *)&badkey ^= 1; /* toggle some bit */
542 code = ubik_Call(KAM_SetPassword, conn, 0, name, inst, 0, badkey);
543 if (code != KABADKEY) {
544 abort_5:
545 afs_com_err(whoami, code, "Trying to set bad key");
546 exit(1);
547 }
548 memset(&badkey, 0, sizeof(badkey));
549 code = ubik_Call(KAM_SetPassword, conn, 0, name, inst, 0, badkey);
550 if (code != KABADKEY)
551 goto abort_5;
552 code = ubik_Call(KAM_SetPassword, conn, 0, name, inst, 9999, key);
553 if (code != KABADARGUMENT)
554 goto abort_5;
555 }
556
557 /* try using ticket with no expiration time */
558 {
559 struct ktc_encryptionKey akey;
560 struct kaentryinfo aentry;
561
562 ka_StringToKey("authserv", localCell, &akey);
563
564 code = ubik_Call(KAM_SetPassword, conn, 0, aname, ainst, 0, akey);
565 if (code) {
566 abort_6:
567 afs_com_err(whoami, code, "Checking SetPassword");
568 exit(2);
569 }
570 code =
571 ubik_Call(KAM_GetEntry, conn, 0, aname, ainst, KAMAJORVERSION,
572 &aentry);
573 if (code)
574 goto abort_6;
575 atoken.kvno = aentry.key_version;
576 for (i = 0; i < sizeof(aentry.key); i++)
577 if (((char *)&aentry.key)[i]) {
578 code = KABADKEY;
579 goto abort_6;
580 }
581 code = ubik_Call(KAM_GetRandomKey, conn, 0, &atoken.sessionKey);
582 if (code)
583 goto abort_3;
584 printf("Got random sessionKey: ");
585 ka_PrintBytes(&atoken.sessionKey, sizeof(key));
586 printf("\n");
587
588 atoken.startTime = 0;
589 atoken.endTime = NEVERDATE;
590 code =
591 tkt_MakeTicket(atoken.ticket, &atoken.ticketLen, &akey, name,
592 inst, "", atoken.startTime, atoken.endTime,
593 &atoken.sessionKey, 0, aname, ainst);
594 if (code) {
595 abort_3:
596 afs_com_err(whoami, code, "faking up AuthServer ticket");
597 exit(1);
598 }
599 {
600 struct ktc_principal client;
601 struct ktc_encryptionKey sessionkey;
602 Date start, end;
603 long host;
604
605 code =
606 tkt_DecodeTicket(atoken.ticket, atoken.ticketLen, &akey,
607 client.name, client.instance, client.cell,
608 &sessionkey, &host, &start, &end);
609 if (code)
610 goto abort_3;
611 if (code = tkt_CheckTimes(start, end, time(0)) <= 0)
612 goto abort_3;
613
614 if (!des_check_key_parity(&sessionkey)
615 || des_is_weak_key(&sessionkey)) {
616 code = KABADKEY;
617 goto abort_3;
618 }
619 }
620 }
621
622 code =
623 ka_AuthServerConn(localCell, KA_MAINTENANCE_SERVICE, &atoken, &conn);
624 if (code)
625 goto abort_3;
626 {
627 struct kaentryinfo entry;
628
629 code =
630 ubik_Call(KAM_GetEntry, conn, 0, name, inst, KAMAJORVERSION,
631 &entry);
632 if (code)
633 goto abort_3;
634 if (memcmp(&tentry, &entry, sizeof(entry)) != 0) {
635 printf("Entries obtained not the same!\n");
636 print_entry(&entry, name, inst);
637 }
638 }
639
640 /* try bashing a ticket to make sure it fails to work */
641 memset(atoken.ticket + 10, 0, 1);
642 code =
643 ka_AuthServerConn(localCell, KA_MAINTENANCE_SERVICE, &atoken, &conn);
644 if (code) {
645 afs_com_err(whoami, code, "contacting admin server with bashed ticket");
646 exit(0); /* this is supposed to happen */
647 }
648 code =
649 ubik_Call(KAM_GetEntry, conn, 0, name, inst, KAMAJORVERSION, &tentry);
650 if (code != RXKADBADTICKET) {
651 afs_com_err(whoami, code,
652 "GetEntry failed to fail even with damaged ticket!!!!\n");
653 exit(1);
654 }
655
656 TestOldKeys(&key);
657
658 printf("All clear!\n");
659 if (argc == 2) {
660 code = setpag();
661 if (code)
662 afs_com_err(whoami, code, "calling SetPAG");
663 else
664 printf("Calling SetPAG and exec'ing %s\n", argv[1]);
665 execve(argv[1], argv + 1, 0);
666 perror("execve returned");
667 }
668 exit(0);
669 }