2
* lib/krb4/decomp_tkt.c
4
* Copyright 1985, 1986, 1987, 1988, 2000, 2001 by the Massachusetts
5
* Institute of Technology. All Rights Reserved.
7
* Export of this software from the United States of America may
8
* require a specific license from the United States Government.
9
* It is the responsibility of any person or organization contemplating
10
* export to obtain such a license before exporting.
12
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13
* distribute this software and its documentation for any purpose and
14
* without fee is hereby granted, provided that the above copyright
15
* notice appear in all copies and that both that copyright notice and
16
* this permission notice appear in supporting documentation, and that
17
* the name of M.I.T. not be used in advertising or publicity pertaining
18
* to distribution of the software without specific, written prior
19
* permission. Furthermore if you modify this software you must label
20
* your software as modified software and not distribute it in such a
21
* fashion that it might be confused with the original M.I.T. software.
22
* M.I.T. makes no representations about the suitability of
23
* this software for any purpose. It is provided "as is" without express
24
* or implied warranty.
32
#include "krb54proto.h"
33
#include "port-sockets.h"
35
#ifdef KRB_CRYPT_DEBUG
39
static int dcmp_tkt_int (KTEXT tkt, unsigned char *flags,
40
char *pname, char *pinstance, char *prealm,
41
unsigned KRB4_32 *paddress, C_Block session,
42
int *life, unsigned KRB4_32 *time_sec,
43
char *sname, char *sinstance, C_Block key,
44
Key_schedule key_s, krb5_keyblock *k5key);
46
* This routine takes a ticket and pointers to the variables that
47
* should be filled in based on the information in the ticket. It
49
* decrypts the ticket using the given key, and
51
* fills in values for its arguments.
53
* Note: if the client realm field in the ticket is the null string,
54
* then the "prealm" variable is filled in with the local realm (as
55
* defined by KRB_REALM).
57
* If the ticket byte order is different than the host's byte order
58
* (as indicated by the byte order bit of the "flags" field), then
59
* the KDC timestamp "time_sec" is byte-swapped. The other fields
60
* potentially affected by byte order, "paddress" and "session" are
63
* The routine returns KFAILURE if any of the "pname", "pinstance",
64
* or "prealm" fields is too big, otherwise it returns KSUCCESS.
66
* The corresponding routine to generate tickets is create_ticket.
67
* When changes are made to this routine, the corresponding changes
68
* should also be made to that file.
70
* See create_ticket.c for the format of the ticket packet.
73
int KRB5_CALLCONV /* XXX should this be exported on win32? */
74
decomp_ticket(tkt, flags, pname, pinstance, prealm, paddress, session,
75
life, time_sec, sname, sinstance, key, key_s)
76
KTEXT tkt; /* The ticket to be decoded */
77
unsigned char *flags; /* Kerberos ticket flags */
78
char *pname; /* Authentication name */
79
char *pinstance; /* Principal's instance */
80
char *prealm; /* Principal's authentication domain */
81
unsigned KRB4_32 *paddress; /* Net address of entity
82
* requesting ticket */
83
C_Block session; /* Session key inserted in ticket */
84
int *life; /* Lifetime of the ticket */
85
unsigned KRB4_32 *time_sec; /* Issue time and date */
86
char *sname; /* Service name */
87
char *sinstance; /* Service instance */
88
C_Block key; /* Service's secret key
89
* (to decrypt the ticket) */
90
Key_schedule key_s; /* The precomputed key schedule */
93
dcmp_tkt_int(tkt, flags, pname, pinstance, prealm,
94
paddress, session, life, time_sec, sname, sinstance,
99
decomp_tkt_krb5(tkt, flags, pname, pinstance, prealm, paddress, session,
100
life, time_sec, sname, sinstance, k5key)
101
KTEXT tkt; /* The ticket to be decoded */
102
unsigned char *flags; /* Kerberos ticket flags */
103
char *pname; /* Authentication name */
104
char *pinstance; /* Principal's instance */
105
char *prealm; /* Principal's authentication domain */
106
unsigned KRB4_32 *paddress; /* Net address of entity
107
* requesting ticket */
108
C_Block session; /* Session key inserted in ticket */
109
int *life; /* Lifetime of the ticket */
110
unsigned KRB4_32 *time_sec; /* Issue time and date */
111
char *sname; /* Service name */
112
char *sinstance; /* Service instance */
113
krb5_keyblock *k5key; /* krb5 keyblock of service */
115
C_Block key; /* placeholder; doesn't get used */
116
Key_schedule key_s; /* placeholder; doesn't get used */
119
dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session,
120
life, time_sec, sname, sinstance, key, key_s, k5key);
124
dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session,
125
life, time_sec, sname, sinstance, key, key_s, k5key)
126
KTEXT tkt; /* The ticket to be decoded */
127
unsigned char *flags; /* Kerberos ticket flags */
128
char *pname; /* Authentication name */
129
char *pinstance; /* Principal's instance */
130
char *prealm; /* Principal's authentication domain */
131
unsigned KRB4_32 *paddress; /* Net address of entity
132
* requesting ticket */
133
C_Block session; /* Session key inserted in ticket */
134
int *life; /* Lifetime of the ticket */
135
unsigned KRB4_32 *time_sec; /* Issue time and date */
136
char *sname; /* Service name */
137
char *sinstance; /* Service instance */
138
C_Block key; /* Service's secret key
139
* (to decrypt the ticket) */
140
Key_schedule key_s; /* The precomputed key schedule */
141
krb5_keyblock *k5key; /* krb5 keyblock of service */
143
int tkt_le; /* little-endian ticket? */
144
unsigned char *ptr = tkt->dat;
146
struct in_addr paddr;
148
/* Be really paranoid. */
149
if (sizeof(paddr.s_addr) != 4)
153
/* Do the decryption */
154
#ifdef KRB_CRYPT_DEBUG
157
char *keybuf[BUFSIZ]; /* Avoid secret stuff in stdio buffers */
159
fp = fopen("/kerberos/tkt.des", "wb");
161
fwrite(tkt->dat, 1, tkt->length, fp);
163
memset(keybuf, 0, sizeof(keybuf)); /* Clear the buffer */
172
in.enctype = k5key->enctype;
174
in.ciphertext.length = tkt->length;
175
in.ciphertext.data = (char *)tkt->dat;
176
out.length = tkt->length;
177
out.data = malloc((size_t)tkt->length);
178
if (out.data == NULL)
179
return KFAILURE; /* XXX maybe ENOMEM? */
181
/* XXX note the following assumes that context arg isn't used */
183
krb5_c_decrypt(NULL, k5key,
184
KRB5_KEYUSAGE_KDC_REP_TICKET, NULL, &in, &out);
189
memcpy(tkt->dat, out.data, out.length);
190
memset(out.data, 0, out.length);
194
pcbc_encrypt((C_Block *)tkt->dat, (C_Block *)tkt->dat,
195
(long)tkt->length, key_s, (C_Block *)key, 0);
197
#endif /* ! NOENCRYPTION */
198
#ifdef KRB_CRYPT_DEBUG
201
char *keybuf[BUFSIZ]; /* Avoid secret stuff in stdio buffers */
203
fp = fopen("/kerberos/tkt.clear", "wb");
205
fwrite(tkt->dat, 1, tkt->length, fp);
207
memset(keybuf, 0, sizeof(keybuf)); /* Clear the buffer */
211
#define TKT_REMAIN (tkt->length - (ptr - tkt->dat))
216
tkt_le = (*flags >> K_FLAG_ORDER) & 1;
218
len = krb4int_strnlen((char *)ptr, TKT_REMAIN) + 1;
219
if (len <= 0 || len > ANAME_SZ)
221
memcpy(pname, ptr, (size_t)len);
224
len = krb4int_strnlen((char *)ptr, TKT_REMAIN) + 1;
225
if (len <= 0 || len > INST_SZ)
227
memcpy(pinstance, ptr, (size_t)len);
230
len = krb4int_strnlen((char *)ptr, TKT_REMAIN) + 1;
231
if (len <= 0 || len > REALM_SZ)
233
memcpy(prealm, ptr, (size_t)len);
237
* This hack may be needed for some really krb4 servers, such as
238
* AFS kaserver (?), that fail to fill in the realm of a ticket
239
* under some circumstances.
242
krb_get_lrealm(prealm, 1);
245
* Ensure there's enough remaining in the ticket to get the
248
if (TKT_REMAIN < 4 + 8 + 1 + 4)
251
memcpy(&paddr.s_addr, ptr, sizeof(paddr.s_addr));
252
ptr += sizeof(paddr.s_addr);
253
*paddress = paddr.s_addr;
255
memcpy(session, ptr, 8); /* session key */
258
#ifdef notdef /* DONT SWAP SESSION KEY spm 10/22/86 */
260
swap_C_Block(session);
265
KRB4_GET32(*time_sec, ptr, tkt_le);
267
len = krb4int_strnlen((char *)ptr, TKT_REMAIN) + 1;
268
if (len <= 0 || len > SNAME_SZ)
270
memcpy(sname, ptr, (size_t)len);
273
len = krb4int_strnlen((char *)ptr, TKT_REMAIN) + 1;
274
if (len <= 0 || len > INST_SZ)
276
memcpy(sinstance, ptr, (size_t)len);
280
#ifdef KRB_CRYPT_DEBUG
282
krb_log("service=%s.%s len(sname)=%d, len(sinstance)=%d",
283
sname, sinstance, strlen(sname), strlen(sinstance));
284
krb_log("ptr - tkt->dat=%d",(char *)ptr - (char *)tkt->dat);
289
if (kret != KSUCCESS) {
290
memset(session, 0, sizeof(session));
291
memset(tkt->dat, 0, (size_t)tkt->length);