Commit | Line | Data |
---|---|---|
805e021f CE |
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 | } |