File: patch.krb4_32_64

package info (click to toggle)
krb5 1.4.4-7etch1
  • links: PTS
  • area: main
  • in suites: etch-m68k
  • size: 49,200 kB
  • ctags: 25,837
  • sloc: ansic: 270,278; exp: 21,157; makefile: 10,635; sh: 6,403; yacc: 2,515; perl: 1,925; cpp: 743; awk: 449; python: 379; asm: 248; lex: 190; sed: 172; csh: 147
file content (489 lines) | stat: -rw-r--r-- 16,306 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
Only in trunk.asedeno/src: configure
diff -wru3 trunk/src/lib/krb4/krb4int.h trunk.asedeno/src/lib/krb4/krb4int.h
--- trunk/src/lib/krb4/krb4int.h	2006-05-26 10:48:06.000000000 -0400
+++ trunk.asedeno/src/lib/krb4/krb4int.h	2006-06-02 14:59:43.000000000 -0400
@@ -90,7 +90,9 @@
 char *krb_stime(long *);
 
 /* tf_util.c */
-int tf_save_cred(char *, char *, char *, C_Block, int , int, KTEXT, long);
+int tf_save_cred(char *, char *, char *, C_Block, int , int, KTEXT, KRB4_32);
+int KRB5_CALLCONV real_tf_get_cred(CREDENTIALS *c);
+
 
 /* unix_glue.c */
 int krb_start_session(char *);
@@ -112,7 +114,7 @@
 void krb4int_et_fini(void);
 
 int krb4int_save_credentials_addr(
-    char *, char *, char *, C_Block, int, int, KTEXT, long, KRB_UINT32);
+    char *, char *, char *, C_Block, int, int, KTEXT, KRB4_32, KRB_UINT32);
 
 int krb4int_send_to_kdc_addr(KTEXT, KTEXT, char *,
 			     struct sockaddr *, socklen_t *);
diff -wru3 trunk/src/lib/krb4/memcache.c trunk.asedeno/src/lib/krb4/memcache.c
--- trunk/src/lib/krb4/memcache.c	2006-05-26 10:48:06.000000000 -0400
+++ trunk.asedeno/src/lib/krb4/memcache.c	2006-06-02 14:13:07.000000000 -0400
@@ -470,7 +470,7 @@
 	int lifetime;		/* Lifetime */
 	int kvno;		/* Key version number */
     	KTEXT ticket; 		/* The ticket itself */
-	long issue_date;	/* The issue time */
+	KRB4_32 issue_date;	/* The issue time */
 	KRB_UINT32 laddr;
 {
 	CREDENTIALS	cr;
@@ -500,7 +500,7 @@
     int		lifetime,
     int		kvno,
     KTEXT	ticket,
-    long	issue_date)
+    KRB4_32	issue_date)
 {
     return krb4int_save_credentials_addr(name, inst, realm, session,
 					 lifetime, kvno, ticket,
diff -wru3 trunk/src/lib/krb4/save_creds.c trunk.asedeno/src/lib/krb4/save_creds.c
--- trunk/src/lib/krb4/save_creds.c	2006-05-26 10:48:06.000000000 -0400
+++ trunk.asedeno/src/lib/krb4/save_creds.c	2006-06-02 14:35:53.000000000 -0400
@@ -54,7 +54,7 @@
     int lifetime;		/* Lifetime */
     int kvno;			/* Key version number */
     KTEXT ticket;		/* The ticket itself */
-    long issue_date;		/* The issue time */
+    KRB4_32 issue_date;		/* The issue time */
     KRB_UINT32 local_addr;
 {
     int tf_status;   /* return values of the tf_util calls */
@@ -83,5 +83,5 @@
 {
     return krb4int_save_credentials_addr(service, instance, realm,
 					 session, lifetime, kvno,
-					 ticket, issue_date, 0);
+					 ticket, (KRB4_32)issue_date, 0);
 }
diff -wru3 trunk/src/lib/krb4/tf_util.c trunk.asedeno/src/lib/krb4/tf_util.c
--- trunk/src/lib/krb4/tf_util.c	2006-05-26 10:48:06.000000000 -0400
+++ trunk.asedeno/src/lib/krb4/tf_util.c	2006-06-02 14:13:07.000000000 -0400
@@ -28,6 +28,8 @@
 #include "k5-int.h"
 #include "krb4int.h"
 
+#include "../crypto/aes/aesopt.h"
+
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
@@ -43,6 +45,8 @@
 #include <sys/shm.h>
 #endif /* TKT_SHMEM */
 
+
+
 #define TOO_BIG -1
 #define TF_LCK_RETRY ((unsigned)2)	/* seconds to sleep before
 					 * retry if ticket file is
@@ -93,6 +97,165 @@
 #endif
 #endif
 
+
+#if (PLATFORM_BYTE_ORDER == AES_LITTLE_ENDIAN)
+/* This was taken from jhutz's patch for heimdal krb4. It only
+ * applies to little endian systems. Big endian systems have a
+ * less elegant solution documented below.
+ *
+ * This record is written after every real ticket, to ensure that
+ * both 32- and 64-bit readers will perceive the next real ticket
+ * as starting in the same place.  This record looks like a ticket
+ * with the following properties:
+ *   Field         32-bit             64-bit
+ *   ============  =================  =================
+ *   sname         "."                "."
+ *   sinst         ""                 ""
+ *   srealm        ".."               ".."
+ *   session key   002E2E00 xxxxxxxx  xxxxxxxx 00000000
+ *   lifetime      0                  0
+ *   kvno          0                  12
+ *   ticket        12 nulls           4 nulls
+ *   issue         0                  0
+ *
+ * Our code always reads and writes the 32-bit format, but knows
+ * to skip 00000000 at the front of a record, and to completely
+ * ignore tickets for the special alignment principal.
+ */
+static unsigned char align_rec[] = {
+    0x2e, 0x00, 0x00, 0x2e, 0x2e, 0x00, 0x00, 0x2e,
+    0x2e, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00,
+    0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00
+};
+
+#else /* Big Endian */
+
+/* These alignment records are for big endian systems. We need more
+ * of them because the portion of the 64-bit issue_date that overlaps
+ * with the start of a ticket on 32-bit systems contains an unpredictable
+ * number of NULL bytes. Preceeding these records is a second copy of the
+ * 32-bit issue_date. The srealm for the alignment records is always one of
+ * ".." or "?.."
+ */
+
+/* No NULL bytes
+ * This is actually two alignment records since both 32- and 64-bit
+ * readers will agree on everything in the first record up through the
+ * issue_date size, except where sname starts.
+ *   Field (1)     32-bit             64-bit
+ *   ============  =================  =================
+ *   sname         "????."            "."
+ *   sinst         ""                 ""
+ *   srealm        ".."               ".."
+ *   session key   00000000 xxxxxxxx  00000000 xxxxxxxx
+ *   lifetime      0                  0
+ *   kvno          0                  0
+ *   ticket        4 nulls           4 nulls
+ *   issue         0                  0
+ *
+ *   Field (2)     32-bit             64-bit
+ *   ============  =================  =================
+ *   sname         "."                "."
+ *   sinst         ""                 ""
+ *   srealm        ".."               ".."
+ *   session key   002E2E00 xxxxxxxx  xxxxxxxx 00000000
+ *   lifetime      0                  0
+ *   kvno          0                  12
+ *   ticket        12 nulls           4 nulls
+ *   issue         0                  0
+ *
+ */
+static unsigned char align_rec_0[] = {
+    0x2e, 0x00, 0x00, 0x2e, 0x2e, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x2e, 0x00, 0x00, 0x2e, 0x2e, 0x00,
+    0x00, 0x2e, 0x2e, 0x00, 0xff, 0xff, 0xff, 0xff,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00
+};
+
+/* One NULL byte
+ *   Field         32-bit             64-bit
+ *   ============  =================  =================
+ *   sname         "x"  |"xx"|"xxx"   "."
+ *   sinst         "xx."|"x."|"."     ".."
+ *   srealm        ".."               "..."
+ *   session key   2E2E2E00 xxxxxxxx  xxxxxxxx 00000000
+ *   lifetime      0                  0
+ *   kvno          0                  12
+ *   ticket        12 nulls           4 nulls
+ *   issue         0                  0
+ */
+static unsigned char align_rec_1[] = {
+    0x2e, 0x00, 0x2e, 0x2e, 0x00, 0x2e, 0x2e, 0x2e,
+    0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00
+};
+
+/* Two NULL bytes
+ *   Field         32-bit             64-bit
+ *   ============  =================  =================
+ *   sname         "x"  |"x" |"xx"    ".."
+ *   sinst         ""   |"x" |""      ""
+ *   srealm        "x.."|".."|".."    ".."
+ *   session key   002E2E00 xxxxxxxx  xxxxxxxx 00000000
+ *   lifetime      0                  0
+ *   kvno          0                  12
+ *   ticket        12 nulls           4 nulls
+ *   issue         0                  0
+ */
+ static unsigned char align_rec_2[] = {
+    0x2e, 0x2e, 0x00, 0x00, 0x2e, 0x2e, 0x00, 0xff,
+    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00,
+    0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/* Three NULL bytes
+ * Things break here for 32-bit krb4 libraries that don't
+ * understand this alignment record. We can't really do
+ * anything about the fact that the three strings ended
+ * in the duplicate timestamp. The good news is that this
+ * only happens once every 0x1000000 seconds, once roughly
+ * every six and a half months. We'll live.
+ *
+ * Discussion on the krbdev list has suggested the
+ * issue_date be incremented by one in this case to avoid
+ * the problem. I'm leaving this here just in case.
+ *
+ *   Field         32-bit             64-bit
+ *   ============  =================  =================
+ *   sname         ""                 "."
+ *   sinst         ""                 ""
+ *   srealm        ""                 ".."
+ *   session key   2E00002E 2E00FFFF  xxxx0000 0000xxxx
+ *   lifetime      0                  0
+ *   kvno          4294901760         917504
+ *   ticket        14 nulls           4 nulls
+ *   issue         0                  0
+ */
+/*
+static unsigned char align_rec_3[] = {
+    0x2e, 0x00, 0x00, 0x2e, 0x2e, 0x00, 0xff, 0xff,
+    0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+*/
+#endif /* (PLATFORM_BYTE_ORDER == AES_LITTLE_ENDIAN) */
+
 /*
  * fd must be initialized to something that won't ever occur as a real
  * file descriptor. Since open(2) returns only non-negative numbers as
@@ -136,7 +299,7 @@
  *              int             lifetime
  *              int             kvno
  *              KTEXT_ST        ticket_st
- *              long            issue_date
+ *              KRB4_32         issue_date
  *
  * Strings are stored NUL-terminated, and read back until a NUL is
  * found or the indicated number of bytes have been read.  (So if you
@@ -519,19 +682,43 @@
  * EOF          - end of file encountered
  */
 
-int KRB5_CALLCONV tf_get_cred(c)
+int KRB5_CALLCONV real_tf_get_cred(c)
     CREDENTIALS *c;
 {
     KTEXT   ticket = &c->ticket_st;	/* pointer to ticket */
     int     k_errno;
-    long issue_date;
+    unsigned char nullbuf[3];  /* used for 64-bit issue_date tf compatibility */
 
     if (fd < 0) {
 	if (krb_debug)
 	    fprintf(stderr, "tf_get_cred called before tf_init.\n");
 	return TKT_FIL_INI;
     }
-    if ((k_errno = tf_gets(c->service, SNAME_SZ)) < 2)
+    if ((k_errno = tf_gets(c->service, SNAME_SZ)) < 2) {
+
+#if (PLATFORM_BYTE_ORDER == AES_BIG_ENDIAN)
+	/* If we're big endian then we can have a null service name as part of
+	 * an alignment record. */
+	if (k_errno < 2)
+	    switch (k_errno) {
+	    case TOO_BIG:
+		tf_close();
+		return TKT_FIL_FMT;
+	    case 0:
+		return EOF;
+	    }
+#else /* Little Endian */
+	/* If we read an empty service name, it's possible that's because
+	 * the file was written by someone who thinks issue_date should be
+	 * 64 bits.  If that is the case, there will be three more zeros,
+	 * followed by the real record.*/
+
+	if (k_errno == 1 && 
+	    tf_read(nullbuf, 3) == 3 &&
+	    !nullbuf[0] && !nullbuf[1] && !nullbuf[2])
+	    k_errno = tf_gets(c->service, SNAME_SZ);
+
+	if (k_errno < 2)
 	switch (k_errno) {
 	case TOO_BIG:
 	case 1:		/* can't be just a null */
@@ -540,6 +727,9 @@
 	case 0:
 	    return EOF;
 	}
+#endif /*(PLATFORM_BYTE_ORDER == AES_BIG_ENDIAN)*/
+
+    }
     if ((k_errno = tf_gets(c->instance, INST_SZ)) < 1)
 	switch (k_errno) {
 	case TOO_BIG:
@@ -547,7 +737,7 @@
 	case 0:
 	    return EOF;
 	}
-    if ((k_errno = tf_gets(c->realm, REALM_SZ)) < 2)
+    if ((k_errno = tf_gets(c->realm, REALM_SZ)) < 2) {
 	switch (k_errno) {
 	case TOO_BIG:
 	case 1:		/* can't be just a null */
@@ -556,6 +746,8 @@
 	case 0:
 	    return EOF;
 	}
+    }
+    
     if (
 	tf_read((char *) (c->session), KEY_SZ) < 1 ||
 	tf_read((char *) &(c->lifetime), sizeof(c->lifetime)) < 1 ||
@@ -565,12 +757,74 @@
     /* don't try to read a silly amount into ticket->dat */
 	ticket->length > MAX_KTXT_LEN ||
 	tf_read((char *) (ticket->dat), ticket->length) < 1 ||
-	tf_read((char *) &(issue_date), sizeof(issue_date)) < 1
+	tf_read((char *) &(c->issue_date), sizeof(c->issue_date)) < 1
 	) {
 	tf_close();
 	return TKT_FIL_FMT;
     }
-    c->issue_date = issue_date;
+
+#if (PLATFORM_BYTE_ORDER == AES_BIG_ENDIAN)
+    /* If the issue_date is 0 and we're not dealing with an alignment
+       record, then it's likely we've run into an issue_date written by
+       a 64-bit library that is using long instead of KRB4_32. Let's get
+       the next four bytes instead.
+     */
+    if (0 == c->issue_date) {
+	int len = strlen(c->realm);
+	if (!(2 == len && 0 == strcmp(c->realm, "..")) &&
+	    !(3 == len && 0 == strcmp(c->realm + 1, ".."))) {
+	    if (tf_read((char *) &(c->issue_date), sizeof(c->issue_date)) < 1) {
+		tf_close();
+		return TKT_FIL_FMT;
+	    }
+	}
+    }
+
+#endif
+    
+    return KSUCCESS;
+}
+
+int KRB5_CALLCONV tf_get_cred(c)
+    CREDENTIALS *c;
+{
+    int     k_errno;
+    int     fake;
+    
+    do {
+	fake = 0;
+	k_errno = real_tf_get_cred(c);
+	if (k_errno)
+	    return k_errno;
+	
+#if (PLATFORM_BYTE_ORDER == AES_BIG_ENDIAN)
+	/* Here we're checking to see if the realm is one of the 
+	 * alignment record realms, ".." or "?..", so we can skip it.
+	 * If it's not, then we need to verify that the service name
+	 * was not null as this should be a valid ticket.
+	 */
+	{
+	    int len = strlen(c->realm);
+	    if (2 == len && 0 == strcmp(c->realm, ".."))
+		fake = 1;
+	    if (3 == len && 0 == strcmp(c->realm + 1, ".."))
+		fake = 1;
+	    if (!fake && 0 == strlen(c->service)) {
+		tf_close();
+		return TKT_FIL_FMT;
+	    }
+	}
+#else /* Little Endian */
+	/* Here we're checking to see if the service principal is the
+	 * special alignment record principal ".@..", so we can skip it.
+	 */
+	if (strcmp(c->service, ".") == 0 &&
+	    strcmp(c->instance, "") == 0 &&
+	    strcmp(c->realm, "..") == 0)
+	    fake = 1;
+#endif /* (PLATFORM_BYTE_ORDER == AES_BIG_ENDIAN) */
+    } while (fake);
+    
 #ifdef TKT_SHMEM
     memcpy(c->session, tmp_shm_addr, KEY_SZ);
     tmp_shm_addr += KEY_SZ;
@@ -711,7 +965,7 @@
     int     lifetime;		/* Lifetime */
     int     kvno;		/* Key version number */
     KTEXT   ticket;		/* The ticket itself */
-    long    issue_date;		/* The issue time */
+    KRB4_32 issue_date;		/* The issue time */
 {
 
     off_t   lseek();
@@ -777,9 +1031,65 @@
     if (write(fd, (char *) (ticket->dat), count) != count)
 	goto bad;
     /* Issue date */
-    if (write(fd, (char *) &issue_date, sizeof(long))
-	!= sizeof(long))
+    if (write(fd, (char *) &issue_date, sizeof(KRB4_32))
+	!= sizeof(KRB4_32))
+	goto bad;
+    /* Alignment Record */
+#if (PLATFORM_BYTE_ORDER == AES_BIG_ENDIAN)
+    {
+	int null_bytes = 0;
+	if (0 == (issue_date & 0xff000000))
+	    ++null_bytes;
+	if (0 == (issue_date & 0x00ff0000))
+	    ++null_bytes;
+	if (0 == (issue_date & 0x0000ff00))
+	    ++null_bytes;
+	if (0 == (issue_date & 0x000000ff))
+	    ++null_bytes;
+	
+	switch(null_bytes) {
+	case 0:
+	    /* Issue date */
+	    if (write(fd, (char *) &issue_date, sizeof(KRB4_32))
+		!= sizeof(KRB4_32))
 	goto bad;
+	    if (write(fd, align_rec_0, sizeof(align_rec_0))
+		!= sizeof(align_rec_0))
+		goto bad;
+	    break;
+	    
+	case 1:
+	    if (write(fd, (char *) &issue_date, sizeof(KRB4_32))
+		!= sizeof(KRB4_32))
+		goto bad;
+	    if (write(fd, align_rec_1, sizeof(align_rec_1))
+		!= sizeof(align_rec_1))
+		goto bad;
+	    break;
+	    
+	case 3:
+	    /* Three NULLS are troublesome but rare. We'll just pretend 
+	     * they don't exist by decrementing the issue_date.
+	     */
+	    --issue_date;
+	case 2:
+	    if (write(fd, (char *) &issue_date, sizeof(KRB4_32))
+		!= sizeof(KRB4_32))
+		goto bad;
+	    if (write(fd, align_rec_2, sizeof(align_rec_2))
+		!= sizeof(align_rec_2))
+		goto bad;
+	    break;
+	    
+	default:
+	    goto bad;
+	}
+	
+    }    
+#else
+    if (write(fd, align_rec, sizeof(align_rec)) != sizeof(align_rec))
+	goto bad;
+#endif 
 
     /* Actually, we should check each write for success */
     return (KSUCCESS);