1 /* ccache.c --- Read MIT style Kerberos Credential Cache file.
2 * Copyright (C) 2006 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 /* See ccache.txt for a description of the file format. */
28 get_uint8 (const void **data
, size_t * len
, uint8_t * i
)
30 const char *p
= *data
;
40 get_uint16 (const void **data
, size_t * len
, uint16_t * i
)
42 const char *p
= *data
;
45 *i
= p
[0] << 8 | p
[1];
52 get_uint32 (const void **data
, size_t * len
, uint32_t * i
)
54 const char *p
= *data
;
57 *i
= ((p
[0] << 24) & 0xFF000000)
58 | ((p
[1] << 16) & 0xFF0000) | ((p
[2] << 8) & 0xFF00) | (p
[3] & 0xFF);
65 parse_principal (const void **data
, size_t * len
,
66 struct ccache_principal
*out
)
71 rc
= get_uint32 (data
, len
, &out
->name_type
);
75 rc
= get_uint32 (data
, len
, &out
->num_components
);
79 if (out
->num_components
>= CCACHE_MAX_COMPONENTS
)
82 rc
= get_uint32 (data
, len
, &out
->realm
.length
);
86 if (*len
< out
->realm
.length
)
88 out
->realm
.data
= *data
;
89 *data
+= out
->realm
.length
;
90 *len
-= out
->realm
.length
;
92 for (n
= 0; n
< out
->num_components
; n
++)
94 rc
= get_uint32 (data
, len
, &out
->components
[n
].length
);
98 if (*len
< out
->components
[n
].length
)
100 out
->components
[n
].data
= *data
;
101 *data
+= out
->components
[n
].length
;
102 *len
-= out
->components
[n
].length
;
109 skip_address (const void **data
, size_t * len
)
115 rc
= get_uint16 (data
, len
, &addrtype
);
119 rc
= get_uint32 (data
, len
, &addrlen
);
132 skip_authdata (const void **data
, size_t * len
)
134 uint16_t authdatatype
;
135 uint32_t authdatalen
;
138 rc
= get_uint16 (data
, len
, &authdatatype
);
142 rc
= get_uint32 (data
, len
, &authdatalen
);
146 if (*len
< authdatalen
)
148 *data
+= authdatalen
;
155 parse_credential (const void **data
, size_t * len
,
156 struct ccache_credential
*out
)
158 struct ccache_principal princ
;
159 uint32_t num_address
;
160 uint32_t num_authdata
;
163 rc
= parse_principal (data
, len
, &out
->client
);
167 rc
= parse_principal (data
, len
, &out
->server
);
171 rc
= get_uint16 (data
, len
, &out
->key
.keytype
);
175 rc
= get_uint16 (data
, len
, &out
->key
.etype
);
179 rc
= get_uint16 (data
, len
, &out
->key
.keylen
);
183 if (*len
< out
->key
.keylen
)
186 out
->key
.keyvalue
= *data
;
188 *data
+= out
->key
.keylen
;
189 *len
-= out
->key
.keylen
;
191 rc
= get_uint32 (data
, len
, &out
->authtime
);
195 rc
= get_uint32 (data
, len
, &out
->starttime
);
199 rc
= get_uint32 (data
, len
, &out
->endtime
);
203 rc
= get_uint32 (data
, len
, &out
->renew_till
);
207 rc
= get_uint8 (data
, len
, &out
->is_skey
);
211 rc
= get_uint32 (data
, len
, &out
->tktflags
);
215 rc
= get_uint32 (data
, len
, &num_address
);
219 for (; num_address
; num_address
--)
221 /* XXX Don't just skip data. */
222 rc
= skip_address (data
, len
);
227 rc
= get_uint32 (data
, len
, &num_authdata
);
231 for (; num_authdata
; num_authdata
--)
233 /* XXX Don't just skip data. */
234 rc
= skip_authdata (data
, len
);
239 rc
= get_uint32 (data
, len
, &out
->ticket
.length
);
243 if (*len
< out
->ticket
.length
)
245 out
->ticket
.data
= *data
;
246 *data
+= out
->ticket
.length
;
247 *len
-= out
->ticket
.length
;
249 rc
= get_uint32 (data
, len
, &out
->second_ticket
.length
);
253 if (*len
< out
->second_ticket
.length
)
255 out
->second_ticket
.data
= *data
;
256 *data
+= out
->second_ticket
.length
;
257 *len
-= out
->second_ticket
.length
;
263 ccache_parse (const void *data
, size_t len
, struct ccache
*out
)
268 rc
= get_uint16 (&data
, &len
, &out
->file_format_version
);
272 rc
= get_uint16 (&data
, &len
, &out
->headerlen
);
278 if (len
< out
->headerlen
)
280 data
+= out
->headerlen
;
281 len
-= out
->headerlen
;
283 rc
= parse_principal (&data
, &len
, &out
->default_principal
);
287 out
->credentials
= data
;
288 out
->credentialslen
= len
;
294 ccache_parse_credential (const void *data
, size_t len
,
295 struct ccache_credential
*out
, size_t * n
)
297 size_t savelen
= len
;
298 int rc
= parse_credential (&data
, &len
, out
);
308 ccache_print (struct ccache
*ccache
)
312 printf ("file_format_version %04x\n", ccache
->file_format_version
);
313 printf ("headerlen %04x\n", ccache
->headerlen
);
314 printf ("default_principal\n");
315 ccache_print_principal (&ccache
->default_principal
);
319 ccache_print_principal (struct ccache_principal
*princ
)
323 printf ("\tname_type %04x\n", princ
->name_type
);
324 printf ("\tnum_components %04x\n", princ
->num_components
);
325 printf ("\trealmlen %04x\n", princ
->realm
.length
);
326 printf ("\trealm %.*s\n", princ
->realm
.length
, princ
->realm
.data
);
328 for (n
= 0; n
< princ
->num_components
; n
++)
330 printf ("\t\tcomponentlen %04x\n", princ
->components
[n
].length
);
331 printf ("\t\tcomponent %.*s\n", princ
->components
[n
].length
,
332 princ
->components
[n
].data
);
337 ccache_print_credential (struct ccache_credential
*cred
)
340 printf ("\tclient:\n");
341 ccache_print_principal (&cred
->client
);
342 printf ("\tserver:\n");
343 ccache_print_principal (&cred
->server
);
345 printf ("\t\tkeytype %04x\n", cred
->key
.keytype
);
346 printf ("\t\tetype %04x\n", cred
->key
.etype
);
347 printf ("\t\tkeylen %04x\n", cred
->key
.keylen
);
348 printf ("\t\tkey value: ");
349 for (i
= 0; i
< cred
->key
.keylen
; i
++)
350 printf ("%02x", ((char *) cred
->key
.keyvalue
)[i
] & 0xFF);
352 printf ("\ttimes:\n");
353 printf ("\t\tauthtime %04x\n", cred
->authtime
);
354 printf ("\t\tstarttime %04x\n", cred
->starttime
);
355 printf ("\t\tendtime %04x\n", cred
->endtime
);
356 printf ("\t\trenew_till %04x\n", cred
->renew_till
);
357 printf ("\tis_skey %04x\n", cred
->is_skey
);
358 printf ("\ttktflags_skey %04x\n", cred
->tktflags
);
359 printf ("\tticketlen %04x\n", cred
->ticket
.length
);
360 printf ("\tsecond_ticketlen %04x\n", cred
->second_ticket
.length
);
365 main (int argc
, char *argv
[])
371 struct ccache ccache
;
372 struct ccache_credential cred
;
377 printf ("Usage: %s <krb5ccache-file>\n", argv
[0]);
381 fh
= fopen (argv
[1], "rb");
384 puts ("Error: cannot open file");
388 len
= fread (buf
, 1, sizeof (buf
), fh
);
390 if (len
>= sizeof (buf
))
392 puts ("Error: file too large");
396 rc
= ccache_parse (buf
, len
, &ccache
);
399 puts ("Error: syntax error");
403 ccache_print (&ccache
);
405 while (ccache
.credentialslen
)
409 rc
= ccache_parse_credential (ccache
.credentials
,
410 ccache
.credentialslen
, &cred
, &n
);
413 printf ("Error: cannot parse credential %d\n", i
);
417 printf ("\nCredential %d:\n", i
++);
419 ccache_print_credential (&cred
);
421 ccache
.credentials
+= n
;
422 ccache
.credentialslen
-= n
;
427 puts ("Error: cannot close file");