101
#if (PLATFORM_BYTE_ORDER == AES_LITTLE_ENDIAN)
102
/* This was taken from jhutz's patch for heimdal krb4. It only
103
* applies to little endian systems. Big endian systems have a
104
* less elegant solution documented below.
106
* This record is written after every real ticket, to ensure that
107
* both 32- and 64-bit readers will perceive the next real ticket
108
* as starting in the same place. This record looks like a ticket
109
* with the following properties:
110
* Field 32-bit 64-bit
111
* ============ ================= =================
115
* session key 002E2E00 xxxxxxxx xxxxxxxx 00000000
118
* ticket 12 nulls 4 nulls
121
* Our code always reads and writes the 32-bit format, but knows
122
* to skip 00000000 at the front of a record, and to completely
123
* ignore tickets for the special alignment principal.
125
static unsigned char align_rec[] = {
126
0x2e, 0x00, 0x00, 0x2e, 0x2e, 0x00, 0x00, 0x2e,
127
0x2e, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
128
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00,
129
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
130
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134
#else /* Big Endian */
136
/* These alignment records are for big endian systems. We need more
137
* of them because the portion of the 64-bit issue_date that overlaps
138
* with the start of a ticket on 32-bit systems contains an unpredictable
139
* number of NULL bytes. Preceeding these records is a second copy of the
140
* 32-bit issue_date. The srealm for the alignment records is always one of
145
* This is actually two alignment records since both 32- and 64-bit
146
* readers will agree on everything in the first record up through the
147
* issue_date size, except where sname starts.
148
* Field (1) 32-bit 64-bit
149
* ============ ================= =================
153
* session key 00000000 xxxxxxxx 00000000 xxxxxxxx
156
* ticket 4 nulls 4 nulls
159
* Field (2) 32-bit 64-bit
160
* ============ ================= =================
164
* session key 002E2E00 xxxxxxxx xxxxxxxx 00000000
167
* ticket 12 nulls 4 nulls
171
static unsigned char align_rec_0[] = {
172
0x2e, 0x00, 0x00, 0x2e, 0x2e, 0x00, 0x00, 0x00,
173
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
174
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175
0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
176
0x00, 0x00, 0x2e, 0x00, 0x00, 0x2e, 0x2e, 0x00,
177
0x00, 0x2e, 0x2e, 0x00, 0xff, 0xff, 0xff, 0xff,
178
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179
0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04,
180
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181
0x00, 0x00, 0x00, 0x00
185
* Field 32-bit 64-bit
186
* ============ ================= =================
187
* sname "x" |"xx"|"xxx" "."
188
* sinst "xx."|"x."|"." ".."
190
* session key 2E2E2E00 xxxxxxxx xxxxxxxx 00000000
193
* ticket 12 nulls 4 nulls
196
static unsigned char align_rec_1[] = {
197
0x2e, 0x00, 0x2e, 0x2e, 0x00, 0x2e, 0x2e, 0x2e,
198
0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
199
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200
0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
201
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
206
* Field 32-bit 64-bit
207
* ============ ================= =================
208
* sname "x" |"x" |"xx" ".."
209
* sinst "" |"x" |"" ""
210
* srealm "x.."|".."|".." ".."
211
* session key 002E2E00 xxxxxxxx xxxxxxxx 00000000
214
* ticket 12 nulls 4 nulls
217
static unsigned char align_rec_2[] = {
218
0x2e, 0x2e, 0x00, 0x00, 0x2e, 0x2e, 0x00, 0xff,
219
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
220
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00,
221
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
222
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
226
* Things break here for 32-bit krb4 libraries that don't
227
* understand this alignment record. We can't really do
228
* anything about the fact that the three strings ended
229
* in the duplicate timestamp. The good news is that this
230
* only happens once every 0x1000000 seconds, once roughly
231
* every six and a half months. We'll live.
233
* Discussion on the krbdev list has suggested the
234
* issue_date be incremented by one in this case to avoid
235
* the problem. I'm leaving this here just in case.
237
* Field 32-bit 64-bit
238
* ============ ================= =================
242
* session key 2E00002E 2E00FFFF xxxx0000 0000xxxx
244
* kvno 4294901760 917504
245
* ticket 14 nulls 4 nulls
249
static unsigned char align_rec_3[] = {
250
0x2e, 0x00, 0x00, 0x2e, 0x2e, 0x00, 0xff, 0xff,
251
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
252
0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
253
0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
254
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
257
#endif /* (PLATFORM_BYTE_ORDER == AES_LITTLE_ENDIAN) */
97
260
* fd must be initialized to something that won't ever occur as a real
98
261
* file descriptor. Since open(2) returns only non-negative numbers as
565
757
/* don't try to read a silly amount into ticket->dat */
566
758
ticket->length > MAX_KTXT_LEN ||
567
759
tf_read((char *) (ticket->dat), ticket->length) < 1 ||
568
tf_read((char *) &(issue_date), sizeof(issue_date)) < 1
760
tf_read((char *) &(c->issue_date), sizeof(c->issue_date)) < 1
571
763
return TKT_FIL_FMT;
573
c->issue_date = issue_date;
766
#if (PLATFORM_BYTE_ORDER == AES_BIG_ENDIAN)
767
/* If the issue_date is 0 and we're not dealing with an alignment
768
record, then it's likely we've run into an issue_date written by
769
a 64-bit library that is using long instead of KRB4_32. Let's get
770
the next four bytes instead.
772
if (0 == c->issue_date) {
773
int len = strlen(c->realm);
774
if (!(2 == len && 0 == strcmp(c->realm, "..")) &&
775
!(3 == len && 0 == strcmp(c->realm + 1, ".."))) {
776
if (tf_read((char *) &(c->issue_date), sizeof(c->issue_date)) < 1) {
788
int KRB5_CALLCONV tf_get_cred(c)
796
k_errno = real_tf_get_cred(c);
800
#if (PLATFORM_BYTE_ORDER == AES_BIG_ENDIAN)
801
/* Here we're checking to see if the realm is one of the
802
* alignment record realms, ".." or "?..", so we can skip it.
803
* If it's not, then we need to verify that the service name
804
* was not null as this should be a valid ticket.
807
int len = strlen(c->realm);
808
if (2 == len && 0 == strcmp(c->realm, ".."))
810
if (3 == len && 0 == strcmp(c->realm + 1, ".."))
812
if (!fake && 0 == strlen(c->service)) {
817
#else /* Little Endian */
818
/* Here we're checking to see if the service principal is the
819
* special alignment record principal ".@..", so we can skip it.
821
if (strcmp(c->service, ".") == 0 &&
822
strcmp(c->instance, "") == 0 &&
823
strcmp(c->realm, "..") == 0)
825
#endif /* (PLATFORM_BYTE_ORDER == AES_BIG_ENDIAN) */
575
829
memcpy(c->session, tmp_shm_addr, KEY_SZ);
576
830
tmp_shm_addr += KEY_SZ;