1 /* ccache.c --- Credential Cache compatibility ticket set handling.
2 * Copyright (C) 2002, 2003, 2004, 2006, 2007 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful, but
12 * 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, see http://www.gnu.org/licenses or write
18 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
19 * Floor, Boston, MA 02110-1301, USA
27 * shishi_tkts_default_ccache_guess:
28 * @handle: Shishi library handle create by shishi_init().
30 * Guesses the default ccache ticket filename; it is the contents of
31 * the environment variable KRB5CCNAME or /tmp/krb5cc_<UID> where
32 * <UID> is the user's identity in decimal, as returned by getuid().
34 * Return value: Returns default ccache filename as a string that has
35 * to be deallocated with free() by the caller.
38 shishi_tkts_default_ccache_guess (Shishi
* handle
)
42 envfile
= getenv ("KRB5CCNAME");
44 return xstrdup (envfile
);
46 return xasprintf("/tmp/krb5cc_%u", (unsigned long) getuid ());
50 * shishi_tkts_default_ccache:
51 * @handle: Shishi library handle create by shishi_init().
53 * Get filename of default ccache filename.
55 * Return value: Returns the default ccache filename used in the
56 * library. The string is not a copy, so don't modify or deallocate
60 shishi_tkts_default_ccache (Shishi
* handle
)
62 if (!handle
->ccachedefault
)
66 p
= shishi_tkts_default_ccache_guess (handle
);
67 shishi_tkts_default_ccache_set (handle
, p
);
71 return handle
->ccachedefault
;
75 * shishi_tkts_default_ccache_set:
76 * @handle: Shishi library handle create by shishi_init().
77 * @ccache: string with new default ccache filename, or
78 * NULL to reset to default.
80 * Set the default ccache filename used in the library. The string is
81 * copied into the library, so you can dispose of the variable
82 * immediately after calling this function.
85 shishi_tkts_default_ccache_set (Shishi
* handle
, const char *ccache
)
87 if (handle
->ccachedefault
)
88 free (handle
->ccachedefault
);
90 handle
->ccachedefault
= xstrdup (ccache
);
92 handle
->ccachedefault
= NULL
;
96 * shishi_tkts_add_ccache_mem:
97 * @handle: shishi handle as allocated by shishi_init().
98 * @data: constant memory buffer with ccache of @len size.
99 * @len: size of memory buffer with ccache data.
100 * @tkts: allocated key set to store tickets in.
102 * Read tickets from a ccache data structure, and add them to the
105 * The ccache format is proprietary, and this function support (at
106 * least) the 0x0504 format. See the section The Credential Cache
107 * Binary File Format in the Shishi manual for a description of the
110 * Returns: Returns %SHISHI_CCACHE_ERROR if the data does not
111 * represent a valid ccache structure, and %SHISHI_OK on success.
114 shishi_tkts_add_ccache_mem (Shishi
* handle
,
115 const char *data
, size_t len
,
119 struct ccache ccache
;
121 if (VERBOSENOISE (handle
))
123 printf ("ccache len %d (0x%x)\n", len
, len
);
124 _shishi_hexprint (data
, len
);
127 rc
= ccache_parse (data
, len
, &ccache
);
129 return SHISHI_CCACHE_ERROR
;
131 if (VERBOSENOISE (handle
))
132 ccache_print (&ccache
);
134 while (ccache
.credentialslen
)
136 struct ccache_credential cred
;
141 rc
= ccache_parse_credential (ccache
.credentials
,
142 ccache
.credentialslen
, &cred
, &n
);
144 return SHISHI_CCACHE_ERROR
;
146 if (VERBOSENOISE (handle
))
147 ccache_print_credential (&cred
);
149 /* Sanity check credential first. */
151 if (shishi_cipher_keylen (cred
.key
.keytype
) != cred
.key
.keylen
)
154 ticket
= shishi_der2asn1_ticket (handle
, cred
.ticket
.data
,
159 /* Let's create a new ticket... */
161 rc
= shishi_tkt (handle
, &tkt
);
165 shishi_tkt_ticket_set (tkt
, ticket
);
168 char *cname
[CCACHE_MAX_COMPONENTS
+ 1];
171 for (i
= 0; i
< cred
.client
.num_components
172 && i
< CCACHE_MAX_COMPONENTS
; i
++)
173 cname
[i
] = cred
.client
.components
[i
].data
;
176 rc
= shishi_kdcrep_crealm_set (handle
,
177 shishi_tkt_kdcrep (tkt
),
178 cred
.client
.realm
.data
);
182 rc
= shishi_kdcrep_cname_set (handle
,
183 shishi_tkt_kdcrep (tkt
),
184 cred
.client
.name_type
,
191 char *sname
[CCACHE_MAX_COMPONENTS
+ 1];
194 for (i
= 0; i
< cred
.server
.num_components
195 && i
< CCACHE_MAX_COMPONENTS
; i
++)
196 sname
[i
] = cred
.server
.components
[i
].data
;
199 rc
= shishi_enckdcreppart_srealm_set (handle
,
200 shishi_tkt_enckdcreppart (tkt
),
201 cred
.server
.realm
.data
);
205 rc
= shishi_enckdcreppart_sname_set (handle
,
206 shishi_tkt_enckdcreppart (tkt
),
207 cred
.server
.name_type
,
213 rc
= shishi_tkt_flags_set (tkt
, cred
.tktflags
);
217 rc
= shishi_enckdcreppart_authtime_set
219 shishi_tkt_enckdcreppart (tkt
),
220 shishi_generalize_time (handle
, cred
.authtime
));
224 rc
= shishi_enckdcreppart_starttime_set
226 shishi_tkt_enckdcreppart (tkt
),
227 cred
.starttime
? shishi_generalize_time (handle
, cred
.starttime
)
232 rc
= shishi_enckdcreppart_endtime_set
234 shishi_tkt_enckdcreppart (tkt
),
235 shishi_generalize_time (handle
, cred
.endtime
));
239 rc
= shishi_enckdcreppart_renew_till_set
241 shishi_tkt_enckdcreppart (tkt
),
242 cred
.renew_till
? shishi_generalize_time (handle
, cred
.renew_till
)
249 rc
= shishi_enckdcreppart_nonce_set (handle
,
250 shishi_tkt_enckdcreppart (tkt
),
256 rc
= shishi_kdcrep_set_ticket (handle
, shishi_tkt_kdcrep (tkt
),
257 shishi_tkt_ticket (tkt
));
261 rc
= shishi_kdcrep_set_enc_part (handle
, shishi_tkt_kdcrep (tkt
),
271 rc
= shishi_key (handle
, &key
);
275 shishi_key_type_set (key
, cred
.key
.keytype
);
276 shishi_key_value_set (key
, cred
.key
.keyvalue
);
277 rc
= shishi_tkt_key_set (tkt
, key
);
281 shishi_key_done (key
);
284 /* Add new ticket to the set... */
286 rc
= shishi_tkts_add (tkts
, tkt
);
290 ccache
.credentials
+= n
;
291 ccache
.credentialslen
-= n
;
298 rc
= shishi_tkts_to_ccache_mem (handle
, tkts
, &data
, &len
);
299 printf ("gaah res %d\n", rc
);
307 * shishi_tkts_add_ccache_file:
308 * @handle: shishi handle as allocated by shishi_init().
309 * @filename: name of file to read.
310 * @tkts: allocated ticket set to store tickets in.
312 * Read tickets from a ccache data structure, and add them to the
315 * The ccache format is proprietary, and this function support (at
316 * least) the 0x0504 format. See the section The Credential Cache
317 * Binary File Format in the Shishi manual for a description of the
320 * Returns: Returns %SHISHI_IO_ERROR if the file cannot be read,
321 * %SHISHI_CCACHE_ERROR if the data cannot be parsed as a valid ccache
322 * structure, and %SHISHI_OK on success.
325 shishi_tkts_add_ccache_file (Shishi
* handle
,
326 const char *filename
,
330 char *ccache
= read_file (filename
, &len
);
334 return SHISHI_IO_ERROR
;
336 rc
= shishi_tkts_add_ccache_mem (handle
, ccache
, len
, tkts
);
344 * shishi_tkts_from_ccache_mem:
345 * @handle: shishi handle as allocated by shishi_init().
346 * @data: constant memory buffer with ccache of @len size.
347 * @len: size of memory buffer with ccache data.
348 * @outtkts: pointer to ticket set that will be allocated and populated,
349 * must be deallocated by caller on succes.
351 * Read tickets from a ccache data structure, and add them to the
354 * The ccache format is proprietary, and this function support (at
355 * least) the 0x0504 format. See the section The Credential Cache
356 * Binary File Format in the Shishi manual for a description of the
359 * Returns: Returns %SHISHI_CCACHE_ERROR if the data does not
360 * represent a valid ccache structure, and %SHISHI_OK on success.
363 shishi_tkts_from_ccache_mem (Shishi
* handle
,
364 const char *data
, size_t len
,
365 Shishi_tkts
**outtkts
)
369 rc
= shishi_tkts (handle
, outtkts
);
373 rc
= shishi_tkts_add_ccache_mem (handle
, data
, len
, *outtkts
);
376 shishi_tkts_done (outtkts
);
384 * shishi_tkts_from_ccache_file:
385 * @handle: shishi handle as allocated by shishi_init().
386 * @filename: name of file to read.
387 * @outtkts: pointer to ticket set that will be allocated and populated,
388 * must be deallocated by caller on succes.
390 * Read tickets from a ccache data structure, and add them to the
393 * The ccache format is proprietary, and this function support (at
394 * least) the 0x0504 format. See the section The Credential Cache
395 * Binary File Format in the Shishi manual for a description of the
398 * Returns: Returns %SHISHI_IO_ERROR if the file cannot be read,
399 * %SHISHI_CCACHE_ERROR if the data cannot be parsed as a valid ccache
400 * structure, and %SHISHI_OK on success.
403 shishi_tkts_from_ccache_file (Shishi
* handle
,
404 const char *filename
,
405 Shishi_tkts
**outtkts
)
409 rc
= shishi_tkts (handle
, outtkts
);
413 rc
= shishi_tkts_add_ccache_file (handle
, filename
, *outtkts
);
416 shishi_tkts_done (outtkts
);
424 shishi_tkt_to_ccache_mem (Shishi
*handle
,
426 char **data
, size_t *len
)
428 struct ccache_credential cred
;
433 memset (&cred
, 0, sizeof (cred
));
435 rc
= shishi_asn1_to_der (handle
, shishi_tkt_ticket (tkt
),
436 &cred
.ticket
.data
, &cred
.ticket
.length
);
440 /* Sanity check credential first. */
442 if (shishi_key_length (shishi_tkt_key (tkt
)) > CCACHE_MAX_KEYLEN
)
443 return SHISHI_CCACHE_ERROR
;
445 rc
= shishi_asn1_read (handle
, shishi_tkt_kdcrep (tkt
), "crealm",
446 &cred
.client
.realm
.data
,
447 &cred
.client
.realm
.length
);
451 rc
= shishi_asn1_read (handle
, shishi_tkt_enckdcreppart (tkt
), "srealm",
452 &cred
.server
.realm
.data
,
453 &cred
.server
.realm
.length
);
459 char *cname
[CCACHE_MAX_COMPONENTS
+ 1];
462 for (i
= 0; i
< cred
.client
.num_components
463 && i
< CCACHE_MAX_COMPONENTS
; i
++)
464 cname
[i
] = cred
.client
.components
[i
].data
;
467 rc
= shishi_kdcrep_crealm_set (handle
,
468 shishi_tkt_kdcrep (tkt
),
469 cred
.client
.realm
.data
);
473 rc
= shishi_kdcrep_cname_set (handle
,
474 shishi_tkt_kdcrep (tkt
),
475 cred
.client
.name_type
,
482 char *sname
[CCACHE_MAX_COMPONENTS
+ 1];
485 for (i
= 0; i
< cred
.server
.num_components
486 && i
< CCACHE_MAX_COMPONENTS
; i
++)
487 sname
[i
] = cred
.server
.components
[i
].data
;
490 rc
= shishi_enckdcreppart_srealm_set (handle
,
491 shishi_tkt_enckdcreppart (tkt
),
492 cred
.server
.realm
.data
);
496 rc
= shishi_enckdcreppart_sname_set (handle
,
497 shishi_tkt_enckdcreppart (tkt
),
498 cred
.server
.name_type
,
505 rc
= shishi_tkt_flags (tkt
, &cred
.tktflags
);
511 rc
= shishi_ctime (handle
, shishi_tkt_enckdcreppart (tkt
),
520 rc
= shishi_ctime (handle
, shishi_tkt_enckdcreppart (tkt
),
522 if (rc
== SHISHI_ASN1_NO_ELEMENT
)
524 else if (rc
!= SHISHI_OK
)
531 rc
= shishi_ctime (handle
, shishi_tkt_enckdcreppart (tkt
),
540 rc
= shishi_ctime (handle
, shishi_tkt_enckdcreppart (tkt
),
542 if (rc
== SHISHI_ASN1_NO_ELEMENT
)
544 else if (rc
!= SHISHI_OK
)
549 cred
.key
.keylen
= shishi_key_length (shishi_tkt_key (tkt
));
550 cred
.key
.keytype
= shishi_key_type (shishi_tkt_key (tkt
));
551 memcpy (cred
.key
.storage
, shishi_key_value (shishi_tkt_key (tkt
)),
552 shishi_key_length (shishi_tkt_key (tkt
)));
553 cred
.key
.keyvalue
= &cred
.key
.storage
[0];
556 rc
= ccache_pack_credential (&cred
, tmp
, &i
);
557 printf ("rc %d len %d\n", rc
, i
);
560 struct ccache_credential foo
;
563 rc
= ccache_parse_credential (tmp
, i
, &foo
, &n
);
565 return SHISHI_CCACHE_ERROR
;
568 ccache_print_credential (&foo
);
570 _shishi_escapeprint (tmp
, i
);
575 shishi_tkts_to_ccache_mem (Shishi
*handle
,
577 char **data
, size_t *len
)
583 for (i
= 0; i
< shishi_tkts_size (tkts
); i
++)
585 Shishi_tkt
*tkt
= shishi_tkts_nth (tkts
, i
);
586 struct ccache_credential cred
;
588 printf ("ccache %d\n", i
);
591 return SHISHI_INVALID_TKTS
;
593 rc
= shishi_tkt_to_ccache_mem (handle
, tkt
, data
, len
);
594 printf ("f %d\n", rc
);
598 memset (&info
, 0, sizeof (info
));
600 rc
= ccache_pack (&info
, *data
, *len
);
601 printf ("pack res %d len %d\n", rc
, *len
);