1 /* ccache.c --- Credential Cache compatibility ticket set handling.
2 * Copyright (C) 2002, 2003, 2004, 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
26 * shishi_tkts_default_ccache_guess:
27 * @handle: Shishi library handle create by shishi_init().
29 * Guesses the default ccache ticket filename; it is the contents of
30 * the environment variable KRB5CCNAME or /tmp/krb5cc_<UID> where
31 * <UID> is the user's identity in decimal, as returned by getuid().
33 * Return value: Returns default ccache filename as a string that has
34 * to be deallocated with free() by the caller.
37 shishi_tkts_default_ccache_guess (Shishi
* handle
)
41 envfile
= getenv ("KRB5CCNAME");
43 return xstrdup (envfile
);
45 return xasprintf("/tmp/krb5cc_%u", (unsigned long) getuid ());
49 * shishi_tkts_default_ccache:
50 * @handle: Shishi library handle create by shishi_init().
52 * Get filename of default ccache filename.
54 * Return value: Returns the default ccache filename used in the
55 * library. The string is not a copy, so don't modify or deallocate
59 shishi_tkts_default_ccache (Shishi
* handle
)
61 if (!handle
->ccachedefault
)
65 p
= shishi_tkts_default_ccache_guess (handle
);
66 shishi_tkts_default_ccache_set (handle
, p
);
70 return handle
->ccachedefault
;
74 * shishi_tkts_default_ccache_set:
75 * @handle: Shishi library handle create by shishi_init().
76 * @ccache: string with new default ccache filename, or
77 * NULL to reset to default.
79 * Set the default ccache filename used in the library. The string is
80 * copied into the library, so you can dispose of the variable
81 * immediately after calling this function.
84 shishi_tkts_default_ccache_set (Shishi
* handle
, const char *ccache
)
86 if (handle
->ccachedefault
)
87 free (handle
->ccachedefault
);
89 handle
->ccachedefault
= xstrdup (ccache
);
91 handle
->ccachedefault
= NULL
;
95 * shishi_tkts_add_ccache_mem:
96 * @handle: shishi handle as allocated by shishi_init().
97 * @data: constant memory buffer with ccache of @len size.
98 * @len: size of memory buffer with ccache data.
99 * @tkts: allocated key set to store tickets in.
101 * Read tickets from a ccache data structure, and add them to the
104 * The ccache format is proprietary, and this function support (at
105 * least) the 0x0504 format. See the section The Credential Cache
106 * Binary File Format in the Shishi manual for a description of the
109 * Returns: Returns %SHISHI_CCACHE_ERROR if the data does not
110 * represent a valid ccache structure, and %SHISHI_OK on success.
113 shishi_tkts_add_ccache_mem (Shishi
* handle
,
114 const char *data
, size_t len
,
118 struct ccache ccache
;
120 if (VERBOSENOISE (handle
))
122 printf ("ccache len %d (0x%x)\n", len
, len
);
123 _shishi_hexprint (data
, len
);
126 rc
= ccache_parse (data
, len
, &ccache
);
128 return SHISHI_CCACHE_ERROR
;
130 if (VERBOSENOISE (handle
))
131 ccache_print (&ccache
);
133 while (ccache
.credentialslen
)
135 struct ccache_credential cred
;
140 rc
= ccache_parse_credential (ccache
.credentials
,
141 ccache
.credentialslen
, &cred
, &n
);
143 return SHISHI_CCACHE_ERROR
;
145 if (VERBOSENOISE (handle
))
146 ccache_print_credential (&cred
);
148 /* Sanity check credential first. */
150 if (shishi_cipher_keylen (cred
.key
.keytype
) != cred
.key
.keylen
)
153 ticket
= shishi_der2asn1_ticket (handle
, cred
.ticket
.data
,
158 /* Let's create a new ticket... */
160 rc
= shishi_tkt (handle
, &tkt
);
164 shishi_tkt_ticket_set (tkt
, ticket
);
167 char *cname
[CCACHE_MAX_COMPONENTS
+ 1];
170 for (i
= 0; i
< cred
.client
.num_components
171 && i
< CCACHE_MAX_COMPONENTS
; i
++)
172 cname
[i
] = cred
.client
.components
[i
].data
;
175 rc
= shishi_kdcrep_crealm_set (handle
,
176 shishi_tkt_kdcrep (tkt
),
177 cred
.client
.realm
.data
);
181 rc
= shishi_kdcrep_cname_set (handle
,
182 shishi_tkt_kdcrep (tkt
),
183 cred
.client
.name_type
,
190 char *sname
[CCACHE_MAX_COMPONENTS
+ 1];
193 for (i
= 0; i
< cred
.server
.num_components
194 && i
< CCACHE_MAX_COMPONENTS
; i
++)
195 sname
[i
] = cred
.server
.components
[i
].data
;
198 rc
= shishi_enckdcreppart_srealm_set (handle
,
199 shishi_tkt_enckdcreppart (tkt
),
200 cred
.server
.realm
.data
);
204 rc
= shishi_enckdcreppart_sname_set (handle
,
205 shishi_tkt_enckdcreppart (tkt
),
206 cred
.server
.name_type
,
212 rc
= shishi_tkt_flags_set (tkt
, cred
.tktflags
);
216 rc
= shishi_enckdcreppart_authtime_set
218 shishi_tkt_enckdcreppart (tkt
),
219 shishi_generalize_time (handle
, cred
.authtime
));
223 rc
= shishi_enckdcreppart_starttime_set
225 shishi_tkt_enckdcreppart (tkt
),
226 cred
.starttime
? shishi_generalize_time (handle
, cred
.starttime
)
231 rc
= shishi_enckdcreppart_endtime_set
233 shishi_tkt_enckdcreppart (tkt
),
234 shishi_generalize_time (handle
, cred
.endtime
));
238 rc
= shishi_enckdcreppart_renew_till_set
240 shishi_tkt_enckdcreppart (tkt
),
241 cred
.renew_till
? shishi_generalize_time (handle
, cred
.renew_till
)
248 rc
= shishi_enckdcreppart_nonce_set (handle
,
249 shishi_tkt_enckdcreppart (tkt
),
255 rc
= shishi_kdcrep_set_ticket (handle
, shishi_tkt_kdcrep (tkt
),
256 shishi_tkt_ticket (tkt
));
260 rc
= shishi_kdcrep_set_enc_part (handle
, shishi_tkt_kdcrep (tkt
),
270 rc
= shishi_key (handle
, &key
);
274 shishi_key_type_set (key
, cred
.key
.keytype
);
275 shishi_key_value_set (key
, cred
.key
.keyvalue
);
276 rc
= shishi_tkt_key_set (tkt
, key
);
280 shishi_key_done (key
);
283 /* Add new ticket to the set... */
285 rc
= shishi_tkts_add (tkts
, tkt
);
289 ccache
.credentials
+= n
;
290 ccache
.credentialslen
-= n
;
297 rc
= shishi_tkts_to_ccache_mem (handle
, tkts
, &data
, &len
);
298 printf ("gaah res %d\n", rc
);
306 * shishi_tkts_add_ccache_file:
307 * @handle: shishi handle as allocated by shishi_init().
308 * @filename: name of file to read.
309 * @tkts: allocated ticket set to store tickets in.
311 * Read tickets from a ccache data structure, and add them to the
314 * The ccache format is proprietary, and this function support (at
315 * least) the 0x0504 format. See the section The Credential Cache
316 * Binary File Format in the Shishi manual for a description of the
319 * Returns: Returns %SHISHI_IO_ERROR if the file cannot be read,
320 * %SHISHI_CCACHE_ERROR if the data cannot be parsed as a valid ccache
321 * structure, and %SHISHI_OK on success.
324 shishi_tkts_add_ccache_file (Shishi
* handle
,
325 const char *filename
,
329 char *ccache
= read_file (filename
, &len
);
333 return SHISHI_IO_ERROR
;
335 rc
= shishi_tkts_add_ccache_mem (handle
, ccache
, len
, tkts
);
343 * shishi_tkts_from_ccache_mem:
344 * @handle: shishi handle as allocated by shishi_init().
345 * @data: constant memory buffer with ccache of @len size.
346 * @len: size of memory buffer with ccache data.
347 * @outtkts: pointer to ticket set that will be allocated and populated,
348 * must be deallocated by caller on succes.
350 * Read tickets from a ccache data structure, and add them to the
353 * The ccache format is proprietary, and this function support (at
354 * least) the 0x0504 format. See the section The Credential Cache
355 * Binary File Format in the Shishi manual for a description of the
358 * Returns: Returns %SHISHI_CCACHE_ERROR if the data does not
359 * represent a valid ccache structure, and %SHISHI_OK on success.
362 shishi_tkts_from_ccache_mem (Shishi
* handle
,
363 const char *data
, size_t len
,
364 Shishi_tkts
**outtkts
)
368 rc
= shishi_tkts (handle
, outtkts
);
372 rc
= shishi_tkts_add_ccache_mem (handle
, data
, len
, *outtkts
);
375 shishi_tkts_done (outtkts
);
383 * shishi_tkts_from_ccache_file:
384 * @handle: shishi handle as allocated by shishi_init().
385 * @filename: name of file to read.
386 * @outtkts: pointer to ticket set that will be allocated and populated,
387 * must be deallocated by caller on succes.
389 * Read tickets from a ccache data structure, and add them to the
392 * The ccache format is proprietary, and this function support (at
393 * least) the 0x0504 format. See the section The Credential Cache
394 * Binary File Format in the Shishi manual for a description of the
397 * Returns: Returns %SHISHI_IO_ERROR if the file cannot be read,
398 * %SHISHI_CCACHE_ERROR if the data cannot be parsed as a valid ccache
399 * structure, and %SHISHI_OK on success.
402 shishi_tkts_from_ccache_file (Shishi
* handle
,
403 const char *filename
,
404 Shishi_tkts
**outtkts
)
408 rc
= shishi_tkts (handle
, outtkts
);
412 rc
= shishi_tkts_add_ccache_file (handle
, filename
, *outtkts
);
415 shishi_tkts_done (outtkts
);
423 shishi_tkt_to_ccache_mem (Shishi
*handle
,
425 char **data
, size_t *len
)
427 struct ccache_credential cred
;
432 memset (&cred
, 0, sizeof (cred
));
434 rc
= shishi_asn1_to_der (handle
, shishi_tkt_ticket (tkt
),
435 &cred
.ticket
.data
, &cred
.ticket
.length
);
439 /* Sanity check credential first. */
441 if (shishi_key_length (shishi_tkt_key (tkt
)) > CCACHE_MAX_KEYLEN
)
442 return SHISHI_CCACHE_ERROR
;
444 rc
= shishi_asn1_read (handle
, shishi_tkt_kdcrep (tkt
), "crealm",
445 &cred
.client
.realm
.data
,
446 &cred
.client
.realm
.length
);
450 rc
= shishi_asn1_read (handle
, shishi_tkt_enckdcreppart (tkt
), "srealm",
451 &cred
.server
.realm
.data
,
452 &cred
.server
.realm
.length
);
458 char *cname
[CCACHE_MAX_COMPONENTS
+ 1];
461 for (i
= 0; i
< cred
.client
.num_components
462 && i
< CCACHE_MAX_COMPONENTS
; i
++)
463 cname
[i
] = cred
.client
.components
[i
].data
;
466 rc
= shishi_kdcrep_crealm_set (handle
,
467 shishi_tkt_kdcrep (tkt
),
468 cred
.client
.realm
.data
);
472 rc
= shishi_kdcrep_cname_set (handle
,
473 shishi_tkt_kdcrep (tkt
),
474 cred
.client
.name_type
,
481 char *sname
[CCACHE_MAX_COMPONENTS
+ 1];
484 for (i
= 0; i
< cred
.server
.num_components
485 && i
< CCACHE_MAX_COMPONENTS
; i
++)
486 sname
[i
] = cred
.server
.components
[i
].data
;
489 rc
= shishi_enckdcreppart_srealm_set (handle
,
490 shishi_tkt_enckdcreppart (tkt
),
491 cred
.server
.realm
.data
);
495 rc
= shishi_enckdcreppart_sname_set (handle
,
496 shishi_tkt_enckdcreppart (tkt
),
497 cred
.server
.name_type
,
504 rc
= shishi_tkt_flags (tkt
, &cred
.tktflags
);
510 rc
= shishi_ctime (handle
, shishi_tkt_enckdcreppart (tkt
),
519 rc
= shishi_ctime (handle
, shishi_tkt_enckdcreppart (tkt
),
521 if (rc
== SHISHI_ASN1_NO_ELEMENT
)
523 else if (rc
!= SHISHI_OK
)
530 rc
= shishi_ctime (handle
, shishi_tkt_enckdcreppart (tkt
),
539 rc
= shishi_ctime (handle
, shishi_tkt_enckdcreppart (tkt
),
541 if (rc
== SHISHI_ASN1_NO_ELEMENT
)
543 else if (rc
!= SHISHI_OK
)
548 cred
.key
.keylen
= shishi_key_length (shishi_tkt_key (tkt
));
549 cred
.key
.keytype
= shishi_key_type (shishi_tkt_key (tkt
));
550 memcpy (cred
.key
.storage
, shishi_key_value (shishi_tkt_key (tkt
)),
551 shishi_key_length (shishi_tkt_key (tkt
)));
552 cred
.key
.keyvalue
= &cred
.key
.storage
[0];
555 rc
= ccache_pack_credential (&cred
, tmp
, &i
);
556 printf ("rc %d len %d\n", rc
, i
);
559 struct ccache_credential foo
;
562 rc
= ccache_parse_credential (tmp
, i
, &foo
, &n
);
564 return SHISHI_CCACHE_ERROR
;
567 ccache_print_credential (&foo
);
569 _shishi_escapeprint (tmp
, i
);
574 shishi_tkts_to_ccache_mem (Shishi
*handle
,
576 char **data
, size_t *len
)
582 for (i
= 0; i
< shishi_tkts_size (tkts
); i
++)
584 Shishi_tkt
*tkt
= shishi_tkts_nth (tkts
, i
);
585 struct ccache_credential cred
;
587 printf ("ccache %d\n", i
);
590 return SHISHI_INVALID_TKTS
;
592 rc
= shishi_tkt_to_ccache_mem (handle
, tkt
, data
, len
);
593 printf ("f %d\n", rc
);
597 memset (&info
, 0, sizeof (info
));
599 rc
= ccache_pack (&info
, *data
, *len
);
600 printf ("pack res %d len %d\n", rc
, *len
);