Branch data Line data Source code
1 : : /* tkt.c --- Ticket handling.
2 : : * Copyright (C) 2002, 2003, 2004, 2006, 2007, 2010 Simon Josefsson
3 : : *
4 : : * This file is part of Shishi.
5 : : *
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.
10 : : *
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.
15 : : *
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
20 : : *
21 : : */
22 : :
23 : : #include "internal.h"
24 : :
25 : : struct Shishi_tkt
26 : : {
27 : : Shishi *handle;
28 : : Shishi_asn1 ticket;
29 : : Shishi_asn1 kdcrep;
30 : : Shishi_asn1 enckdcreppart;
31 : : Shishi_asn1 encticketpart;
32 : : Shishi_key *key;
33 : : };
34 : :
35 : : /**
36 : : * shishi_tkt:
37 : : * @handle: shishi handle as allocated by shishi_init().
38 : : * @tkt: output variable with newly allocated ticket.
39 : : *
40 : : * Create a new ticket handle.
41 : : *
42 : : * Return value: Returns SHISHI_OK iff successful.
43 : : **/
44 : : int
45 : 2 : shishi_tkt (Shishi * handle, Shishi_tkt ** tkt)
46 : : {
47 : : Shishi_tkt *t;
48 : : int res;
49 : :
50 : 2 : t = xcalloc (1, sizeof (*t));
51 : :
52 : 2 : t->handle = handle;
53 : :
54 : 2 : t->ticket = shishi_ticket (handle);
55 [ - + ]: 2 : if (t->ticket == NULL)
56 : : {
57 : 0 : shishi_error_printf (handle, "Could not create Ticket: %s\n",
58 : : shishi_error (handle));
59 : 0 : return SHISHI_ASN1_ERROR;
60 : : }
61 : :
62 : : /* XXX what about tgs's? */
63 : 2 : t->enckdcreppart = shishi_encasreppart (handle);
64 [ - + ]: 2 : if (t->enckdcreppart == NULL)
65 : : {
66 : 0 : shishi_error_printf (handle, "Could not create EncKDCRepPart: %s\n",
67 : : shishi_error (handle));
68 : 0 : return SHISHI_ASN1_ERROR;
69 : : }
70 : :
71 : 2 : t->encticketpart = shishi_encticketpart (handle);
72 [ - + ]: 2 : if (t->encticketpart == NULL)
73 : : {
74 : 0 : shishi_error_printf (handle, "Could not create EncTicketPart: %s\n",
75 : : shishi_error (handle));
76 : 0 : return SHISHI_ASN1_ERROR;
77 : : }
78 : :
79 : 2 : res = shishi_encticketpart_transited_set (handle,
80 : : t->encticketpart,
81 : : SHISHI_TR_DOMAIN_X500_COMPRESS,
82 : : "", 0);
83 [ - + ]: 2 : if (res != SHISHI_OK)
84 : 0 : return res;
85 : :
86 : 2 : res = shishi_encticketpart_authtime_set
87 : : (handle, t->encticketpart, shishi_generalize_time (handle, time (NULL)));
88 [ - + ]: 2 : if (res != SHISHI_OK)
89 : 0 : return res;
90 : :
91 : 2 : res = shishi_encticketpart_endtime_set
92 : : (handle, t->encticketpart,
93 : : shishi_generalize_time (handle, time (NULL) + 1000));
94 [ - + ]: 2 : if (res != SHISHI_OK)
95 : 0 : return res;
96 : :
97 : 2 : t->kdcrep = shishi_asrep (handle);
98 [ - + ]: 2 : if (t->kdcrep == NULL)
99 : : {
100 : 0 : shishi_error_printf (handle, "Could not create AS-REP: %s\n",
101 : : shishi_error (handle));
102 : 0 : return SHISHI_ASN1_ERROR;
103 : : }
104 : :
105 : : /* XXX We don't allocate t->key here, because shishi_tkt_key()
106 : : relies on it being NULL. Possibly, we should allocate it here
107 : : instead, and simplify shishi_tkt_key(). */
108 : :
109 : 2 : *tkt = t;
110 : :
111 : 2 : return SHISHI_OK;
112 : : }
113 : :
114 : : /**
115 : : * shishi_tkt2:
116 : : * @handle: shishi handle as allocated by shishi_init().
117 : : * @ticket: input variable with ticket.
118 : : * @enckdcreppart: input variable with auxiliary ticket information.
119 : : * @kdcrep: input variable with KDC-REP ticket information.
120 : : *
121 : : * Create a new ticket handle.
122 : : *
123 : : * Return value: Returns new ticket handle, or %NULL on error.
124 : : **/
125 : : Shishi_tkt *
126 : 4 : shishi_tkt2 (Shishi * handle,
127 : : Shishi_asn1 ticket, Shishi_asn1 enckdcreppart,
128 : : Shishi_asn1 kdcrep)
129 : : {
130 : : Shishi_tkt *tkt;
131 : :
132 : 4 : tkt = xcalloc (1, sizeof (*tkt));
133 : :
134 : 4 : tkt->handle = handle;
135 : 4 : tkt->ticket = ticket;
136 : 4 : tkt->enckdcreppart = enckdcreppart;
137 : 4 : tkt->kdcrep = kdcrep;
138 : :
139 : 4 : return tkt;
140 : : }
141 : :
142 : : /**
143 : : * shishi_tkt_done:
144 : : * @tkt: input variable with ticket info.
145 : : *
146 : : * Deallocate resources associated with ticket. The ticket must not
147 : : * be used again after this call.
148 : : **/
149 : : void
150 : 4 : shishi_tkt_done (Shishi_tkt * tkt)
151 : : {
152 [ - + ]: 4 : if (tkt->key)
153 : 0 : shishi_key_done (tkt->key);
154 : 4 : free (tkt);
155 : 4 : }
156 : :
157 : :
158 : : int
159 : 0 : shishi_tkt_build (Shishi_tkt * tkt, Shishi_key * key)
160 : : {
161 : : int res;
162 : :
163 : 0 : res = shishi_ticket_add_enc_part (tkt->handle, tkt->ticket,
164 : : key, tkt->encticketpart);
165 [ # # ]: 0 : if (res != SHISHI_OK)
166 : 0 : return res;
167 : :
168 : 0 : return SHISHI_OK;
169 : : }
170 : :
171 : : /**
172 : : * shishi_tkt_ticket:
173 : : * @tkt: input variable with ticket info.
174 : : *
175 : : * Get ASN.1 Ticket structure from ticket.
176 : : *
177 : : * Return value: Returns actual ticket.
178 : : **/
179 : : Shishi_asn1
180 : 8 : shishi_tkt_ticket (Shishi_tkt * tkt)
181 : : {
182 : 8 : return tkt->ticket;
183 : : }
184 : :
185 : : /**
186 : : * shishi_tkt_ticket_set:
187 : : * @tkt: input variable with ticket info.
188 : : * @ticket: ASN.1 Ticket to store in ticket.
189 : : *
190 : : * Set the ASN.1 Ticket in the Ticket.
191 : : **/
192 : : void
193 : 2 : shishi_tkt_ticket_set (Shishi_tkt * tkt, Shishi_asn1 ticket)
194 : : {
195 [ + - ]: 2 : if (tkt->ticket)
196 : 2 : shishi_asn1_done (tkt->handle, tkt->ticket);
197 : 2 : tkt->ticket = ticket;
198 : 2 : }
199 : :
200 : : /**
201 : : * shishi_tkt_enckdcreppart:
202 : : * @tkt: input variable with ticket info.
203 : : *
204 : : * Get ASN.1 EncKDCRepPart structure from ticket.
205 : : *
206 : : * Return value: Returns auxiliary ticket information.
207 : : **/
208 : : Shishi_asn1
209 : 20 : shishi_tkt_enckdcreppart (Shishi_tkt * tkt)
210 : : {
211 : 20 : return tkt->enckdcreppart;
212 : : }
213 : :
214 : : /**
215 : : * shishi_tkt_enckdcreppart_set:
216 : : * @tkt: structure that holds information about Ticket exchange
217 : : * @enckdcreppart: EncKDCRepPart to store in Ticket.
218 : : *
219 : : * Set the EncKDCRepPart in the Ticket.
220 : : **/
221 : : void
222 : 0 : shishi_tkt_enckdcreppart_set (Shishi_tkt * tkt, Shishi_asn1 enckdcreppart)
223 : : {
224 [ # # ]: 0 : if (tkt->enckdcreppart)
225 : 0 : shishi_asn1_done (tkt->handle, tkt->enckdcreppart);
226 : 0 : tkt->enckdcreppart = enckdcreppart;
227 : 0 : }
228 : :
229 : : /**
230 : : * shishi_tkt_kdcrep:
231 : : * @tkt: input variable with ticket info.
232 : : *
233 : : * Get ASN.1 KDCRep structure from ticket.
234 : : *
235 : : * Return value: Returns KDC-REP information.
236 : : **/
237 : : Shishi_asn1
238 : 14 : shishi_tkt_kdcrep (Shishi_tkt * tkt)
239 : : {
240 : 14 : return tkt->kdcrep;
241 : : }
242 : :
243 : : /**
244 : : * shishi_tkt_encticketpart:
245 : : * @tkt: input variable with ticket info.
246 : : *
247 : : * Get ASN.1 EncTicketPart structure from ticket.
248 : : *
249 : : * Return value: Returns EncTicketPart information.
250 : : **/
251 : : Shishi_asn1
252 : 0 : shishi_tkt_encticketpart (Shishi_tkt * tkt)
253 : : {
254 : 0 : return tkt->encticketpart;
255 : : }
256 : :
257 : : /**
258 : : * shishi_tkt_encticketpart_set:
259 : : * @tkt: input variable with ticket info.
260 : : * @encticketpart: encticketpart to store in ticket.
261 : : *
262 : : * Set the EncTicketPart in the Ticket.
263 : : **/
264 : : void
265 : 0 : shishi_tkt_encticketpart_set (Shishi_tkt * tkt, Shishi_asn1 encticketpart)
266 : : {
267 [ # # ]: 0 : if (tkt->encticketpart)
268 : 0 : shishi_asn1_done (tkt->handle, tkt->encticketpart);
269 : 0 : tkt->encticketpart = encticketpart;
270 : 0 : }
271 : :
272 : : /**
273 : : * shishi_tkt_key:
274 : : * @tkt: input variable with ticket info.
275 : : *
276 : : * Get key used in ticket, by looking first in EncKDCRepPart and then
277 : : * in EncTicketPart. If key is already populated, it is not extracted
278 : : * again.
279 : : *
280 : : * Return value: Returns key extracted from EncKDCRepPart or
281 : : * EncTicketPart.
282 : : **/
283 : : Shishi_key *
284 : 0 : shishi_tkt_key (Shishi_tkt * tkt)
285 : : {
286 : : int rc;
287 : :
288 : : /* XXX We probably shouldn't extract the keys here. Where is this
289 : : extraction actually needed? */
290 [ # # ][ # # ]: 0 : if (!tkt->key && tkt->enckdcreppart)
291 : : {
292 : 0 : rc = shishi_enckdcreppart_get_key (tkt->handle,
293 : : tkt->enckdcreppart, &tkt->key);
294 [ # # ]: 0 : if (rc != SHISHI_OK)
295 : 0 : return NULL;
296 : : }
297 [ # # ][ # # ]: 0 : else if (!tkt->key && tkt->encticketpart)
298 : : {
299 : 0 : rc = shishi_encticketpart_get_key (tkt->handle,
300 : : tkt->encticketpart, &tkt->key);
301 [ # # ]: 0 : if (rc != SHISHI_OK)
302 : 0 : return NULL;
303 : : }
304 : :
305 : 0 : return tkt->key;
306 : : }
307 : :
308 : : /**
309 : : * shishi_tkt_key_set:
310 : : * @tkt: input variable with ticket info.
311 : : * @key: key to store in ticket.
312 : : *
313 : : * Set the key in the EncTicketPart.
314 : : *
315 : : * Return value: Returns SHISHI_OK iff successful.
316 : : **/
317 : : int
318 : 2 : shishi_tkt_key_set (Shishi_tkt * tkt, Shishi_key * key)
319 : : {
320 : : int res;
321 : :
322 : 2 : res = shishi_encticketpart_key_set (tkt->handle, tkt->encticketpart, key);
323 [ - + ]: 2 : if (res != SHISHI_OK)
324 : 0 : return res;
325 : :
326 : 2 : res = shishi_enckdcreppart_key_set (tkt->handle, tkt->enckdcreppart, key);
327 [ - + ]: 2 : if (res != SHISHI_OK)
328 : 0 : return res;
329 : :
330 [ + - ]: 2 : if (!tkt->key)
331 : : {
332 : 2 : res = shishi_key (tkt->handle, &tkt->key);
333 [ - + ]: 2 : if (res != SHISHI_OK)
334 : 0 : return res;
335 : : }
336 : :
337 : 2 : shishi_key_copy (tkt->key, key);
338 : :
339 : 2 : return SHISHI_OK;
340 : : }
341 : :
342 : : int
343 : 0 : shishi_tkt_clientrealm_set (Shishi_tkt * tkt,
344 : : const char *realm, const char *client)
345 : : {
346 : : int res;
347 : :
348 : 0 : res = shishi_encticketpart_crealm_set (tkt->handle,
349 : : tkt->encticketpart, realm);
350 [ # # ]: 0 : if (res != SHISHI_OK)
351 : 0 : return res;
352 : :
353 : 0 : res = shishi_encticketpart_cname_set (tkt->handle,
354 : : tkt->encticketpart,
355 : : SHISHI_NT_UNKNOWN, client);
356 [ # # ]: 0 : if (res != SHISHI_OK)
357 : 0 : return res;
358 : :
359 : 0 : return SHISHI_OK;
360 : : }
361 : :
362 : : int
363 : 0 : shishi_tkt_serverrealm_set (Shishi_tkt * tkt,
364 : : const char *realm, const char *server)
365 : : {
366 : : int res;
367 : :
368 : 0 : res = shishi_ticket_srealmserver_set (tkt->handle, tkt->ticket,
369 : : realm, server);
370 [ # # ]: 0 : if (res != SHISHI_OK)
371 : 0 : return res;
372 : :
373 : 0 : res = shishi_enckdcreppart_srealmserver_set
374 : : (tkt->handle, tkt->enckdcreppart, realm, server);
375 [ # # ]: 0 : if (res != SHISHI_OK)
376 : 0 : return res;
377 : :
378 : 0 : return SHISHI_OK;
379 : : }
380 : :
381 : : /**
382 : : * shishi_tkt_client:
383 : : * @tkt: input variable with ticket info.
384 : : * @client: pointer to newly allocated zero terminated string containing
385 : : * principal name. May be %NULL (to only populate @clientlen).
386 : : * @clientlen: pointer to length of @client on output, excluding terminating
387 : : * zero. May be %NULL (to only populate @client).
388 : : *
389 : : * Represent client principal name in Ticket KDC-REP as
390 : : * zero-terminated string. The string is allocate by this function,
391 : : * and it is the responsibility of the caller to deallocate it. Note
392 : : * that the output length @clientlen does not include the terminating
393 : : * zero.
394 : : *
395 : : * Return value: Returns SHISHI_OK iff successful.
396 : : **/
397 : : int
398 : 3 : shishi_tkt_client (Shishi_tkt * tkt, char **client, size_t * clientlen)
399 : : {
400 : 3 : return shishi_principal_name (tkt->handle, tkt->kdcrep,
401 : : "cname", client, clientlen);
402 : : }
403 : :
404 : : /**
405 : : * shishi_tkt_client_p:
406 : : * @tkt: input variable with ticket info.
407 : : * @client: client name of ticket.
408 : : *
409 : : * Determine if ticket is for specified client.
410 : : *
411 : : * Return value: Returns non-0 iff ticket is for specified client.
412 : : **/
413 : : int
414 : 3 : shishi_tkt_client_p (Shishi_tkt * tkt, const char *client)
415 : : {
416 : : char *buf;
417 : : size_t buflen;
418 : : int res;
419 : :
420 : 3 : res = shishi_tkt_client (tkt, &buf, &buflen);
421 [ - + ]: 3 : if (res != SHISHI_OK)
422 : 0 : return 0;
423 : :
424 : 3 : res = strcmp (client, buf) == 0;
425 : :
426 : 3 : free (buf);
427 : :
428 : 3 : return res;
429 : : }
430 : :
431 : : /**
432 : : * shishi_tkt_clientrealm:
433 : : * @tkt: input variable with ticket info.
434 : : * @client: pointer to newly allocated zero terminated string containing
435 : : * principal name and realm. May be %NULL (to only populate @clientlen).
436 : : * @clientlen: pointer to length of @client on output, excluding terminating
437 : : * zero. May be %NULL (to only populate @client).
438 : : *
439 : : * Convert cname and realm fields from AS-REQ to printable principal
440 : : * name format. The string is allocate by this function, and it is
441 : : * the responsibility of the caller to deallocate it. Note that the
442 : : * output length @clientlen does not include the terminating zero.
443 : : *
444 : : * Return value: Returns SHISHI_OK iff successful.
445 : : **/
446 : : int
447 : 2 : shishi_tkt_clientrealm (Shishi_tkt * tkt, char **client, size_t * clientlen)
448 : : {
449 : 2 : return shishi_principal_name_realm (tkt->handle,
450 : : tkt->kdcrep, "cname",
451 : : tkt->kdcrep, "crealm",
452 : : client, clientlen);
453 : : }
454 : :
455 : : /**
456 : : * shishi_tkt_clientrealm_p:
457 : : * @tkt: input variable with ticket info.
458 : : * @client: principal name (client name and realm) of ticket.
459 : : *
460 : : * Determine if ticket is for specified client principal.
461 : : *
462 : : * Return value: Returns non-0 iff ticket is for specified client principal.
463 : : **/
464 : : int
465 : 0 : shishi_tkt_clientrealm_p (Shishi_tkt * tkt, const char *client)
466 : : {
467 : : char *buf;
468 : : size_t buflen;
469 : : int res;
470 : :
471 : 0 : res = shishi_tkt_clientrealm (tkt, &buf, &buflen);
472 [ # # ]: 0 : if (res != SHISHI_OK)
473 : 0 : return 0;
474 : :
475 : 0 : res = strcmp (client, buf) == 0;
476 : :
477 : 0 : free (buf);
478 : :
479 : 0 : return res;
480 : : }
481 : :
482 : : /**
483 : : * shishi_tkt_realm:
484 : : * @tkt: input variable with ticket info.
485 : : * @realm: pointer to newly allocated character array with realm name.
486 : : * @realmlen: length of newly allocated character array with realm name.
487 : : *
488 : : * Extract realm of server in ticket.
489 : : *
490 : : * Return value: Returns SHISHI_OK iff successful.
491 : : **/
492 : : int
493 : 0 : shishi_tkt_realm (Shishi_tkt * tkt, char **realm, size_t * realmlen)
494 : : {
495 : 0 : return shishi_ticket_realm_get (tkt->handle, tkt->ticket, realm, realmlen);
496 : : }
497 : :
498 : : /**
499 : : * shishi_tkt_server:
500 : : * @tkt: input variable with ticket info.
501 : : * @server: pointer to newly allocated zero terminated string containing
502 : : * principal name. May be %NULL (to only populate @serverlen).
503 : : * @serverlen: pointer to length of @server on output, excluding terminating
504 : : * zero. May be %NULL (to only populate @server).
505 : : *
506 : : * Represent server principal name in Ticket as zero-terminated
507 : : * string. The string is allocate by this function, and it is the
508 : : * responsibility of the caller to deallocate it. Note that the
509 : : * output length @serverlen does not include the terminating zero.
510 : : *
511 : : * Return value: Returns SHISHI_OK iff successful.
512 : : **/
513 : : int
514 : 8 : shishi_tkt_server (Shishi_tkt * tkt, char **server, size_t * serverlen)
515 : : {
516 : 8 : return shishi_ticket_server (tkt->handle, tkt->ticket, server, serverlen);
517 : : }
518 : :
519 : : /**
520 : : * shishi_tkt_server_p:
521 : : * @tkt: input variable with ticket info.
522 : : * @server: server name of ticket.
523 : : *
524 : : * Determine if ticket is for specified server.
525 : : *
526 : : * Return value: Returns non-0 iff ticket is for specified server.
527 : : **/
528 : : int
529 : 6 : shishi_tkt_server_p (Shishi_tkt * tkt, const char *server)
530 : : {
531 : : char *buf;
532 : : int res;
533 : :
534 : 6 : res = shishi_tkt_server (tkt, &buf, NULL);
535 [ - + ]: 6 : if (res != SHISHI_OK)
536 : 0 : return 0;
537 : :
538 : 6 : res = strcmp (server, buf) == 0;
539 : :
540 : 6 : free (buf);
541 : :
542 : 6 : return res;
543 : : }
544 : :
545 : : /**
546 : : * shishi_tkt_flags:
547 : : * @tkt: input variable with ticket info.
548 : : * @flags: pointer to output integer with flags.
549 : : *
550 : : * Extract flags in ticket (i.e., EncKDCRepPart).
551 : : *
552 : : * Return value: Returns SHISHI_OK iff successful.
553 : : **/
554 : : int
555 : 28 : shishi_tkt_flags (Shishi_tkt * tkt, uint32_t * flags)
556 : : {
557 : 28 : return shishi_asn1_read_bitstring (tkt->handle, tkt->enckdcreppart,
558 : : "flags", flags);
559 : : }
560 : :
561 : : /**
562 : : * shishi_tkt_flags_set:
563 : : * @tkt: input variable with ticket info.
564 : : * @flags: integer with flags to store in ticket.
565 : : *
566 : : * Set flags in ticket, i.e., both EncTicketPart and EncKDCRepPart.
567 : : * Note that this reset any already existing flags.
568 : : *
569 : : * Return value: Returns SHISHI_OK iff successful.
570 : : **/
571 : : int
572 : 2 : shishi_tkt_flags_set (Shishi_tkt * tkt, uint32_t flags)
573 : : {
574 : : int res;
575 : :
576 : 2 : res = shishi_encticketpart_flags_set (tkt->handle, tkt->encticketpart,
577 : : flags);
578 [ - + ]: 2 : if (res != SHISHI_OK)
579 : 0 : return res;
580 : :
581 : 2 : res = shishi_enckdcreppart_flags_set (tkt->handle, tkt->enckdcreppart,
582 : : flags);
583 [ - + ]: 2 : if (res != SHISHI_OK)
584 : 0 : return res;
585 : :
586 : 2 : return SHISHI_OK;
587 : : }
588 : :
589 : : /**
590 : : * shishi_tkt_flags_add:
591 : : * @tkt: input variable with ticket info.
592 : : * @flag: integer with flags to store in ticket.
593 : : *
594 : : * Add ticket flags to Ticket and EncKDCRepPart. This preserves all
595 : : * existing options.
596 : : *
597 : : * Return value: Returns SHISHI_OK iff successful.
598 : : **/
599 : : int
600 : 0 : shishi_tkt_flags_add (Shishi_tkt * tkt, uint32_t flag)
601 : : {
602 : : uint32_t flags;
603 : : int res;
604 : :
605 : 0 : res = shishi_tkt_flags (tkt, &flags);
606 [ # # ]: 0 : if (res != SHISHI_OK)
607 : 0 : return res;
608 : :
609 : 0 : flags |= flag;
610 : :
611 : 0 : res = shishi_tkt_flags_set (tkt, flags);
612 [ # # ]: 0 : if (res != SHISHI_OK)
613 : 0 : return res;
614 : :
615 : 0 : return SHISHI_OK;
616 : : }
617 : :
618 : : /**
619 : : * shishi_tkt_forwardable_p:
620 : : * @tkt: input variable with ticket info.
621 : : *
622 : : * Determine if ticket is forwardable.
623 : : *
624 : : * The FORWARDABLE flag in a ticket is normally only interpreted by
625 : : * the ticket-granting service. It can be ignored by application
626 : : * servers. The FORWARDABLE flag has an interpretation similar to
627 : : * that of the PROXIABLE flag, except ticket-granting tickets may also
628 : : * be issued with different network addresses. This flag is reset by
629 : : * default, but users MAY request that it be set by setting the
630 : : * FORWARDABLE option in the AS request when they request their
631 : : * initial ticket-granting ticket.
632 : : *
633 : : * Return value: Returns non-0 iff forwardable flag is set in ticket.
634 : : **/
635 : : int
636 : 2 : shishi_tkt_forwardable_p (Shishi_tkt * tkt)
637 : : {
638 : 2 : uint32_t flags = 0;
639 : :
640 : 2 : shishi_tkt_flags (tkt, &flags);
641 : :
642 : 2 : return flags & SHISHI_TICKETFLAGS_FORWARDABLE;
643 : : }
644 : :
645 : : /**
646 : : * shishi_tkt_forwarded_p:
647 : : * @tkt: input variable with ticket info.
648 : : *
649 : : * Determine if ticket is forwarded.
650 : : *
651 : : * The FORWARDED flag is set by the TGS when a client presents a
652 : : * ticket with the FORWARDABLE flag set and requests a forwarded
653 : : * ticket by specifying the FORWARDED KDC option and supplying a set
654 : : * of addresses for the new ticket. It is also set in all tickets
655 : : * issued based on tickets with the FORWARDED flag set. Application
656 : : * servers may choose to process FORWARDED tickets differently than
657 : : * non-FORWARDED tickets.
658 : : *
659 : : * Return value: Returns non-0 iff forwarded flag is set in ticket.
660 : : **/
661 : : int
662 : 2 : shishi_tkt_forwarded_p (Shishi_tkt * tkt)
663 : : {
664 : 2 : uint32_t flags = 0;
665 : :
666 : 2 : shishi_tkt_flags (tkt, &flags);
667 : :
668 : 2 : return flags & SHISHI_TICKETFLAGS_FORWARDED;
669 : : }
670 : :
671 : : /**
672 : : * shishi_tkt_proxiable_p:
673 : : * @tkt: input variable with ticket info.
674 : : *
675 : : * Determine if ticket is proxiable.
676 : : *
677 : : * The PROXIABLE flag in a ticket is normally only interpreted by the
678 : : * ticket-granting service. It can be ignored by application servers.
679 : : * When set, this flag tells the ticket-granting server that it is OK
680 : : * to issue a new ticket (but not a ticket-granting ticket) with a
681 : : * different network address based on this ticket. This flag is set if
682 : : * requested by the client on initial authentication. By default, the
683 : : * client will request that it be set when requesting a
684 : : * ticket-granting ticket, and reset when requesting any other ticket.
685 : : *
686 : : * Return value: Returns non-0 iff proxiable flag is set in ticket.
687 : : **/
688 : : int
689 : 2 : shishi_tkt_proxiable_p (Shishi_tkt * tkt)
690 : : {
691 : 2 : uint32_t flags = 0;
692 : :
693 : 2 : shishi_tkt_flags (tkt, &flags);
694 : :
695 : 2 : return flags & SHISHI_TICKETFLAGS_PROXIABLE;
696 : : }
697 : :
698 : : /**
699 : : * shishi_tkt_proxy_p:
700 : : * @tkt: input variable with ticket info.
701 : : *
702 : : * Determine if ticket is proxy ticket.
703 : : *
704 : : * The PROXY flag is set in a ticket by the TGS when it issues a proxy
705 : : * ticket. Application servers MAY check this flag and at their
706 : : * option they MAY require additional authentication from the agent
707 : : * presenting the proxy in order to provide an audit trail.
708 : : *
709 : : * Return value: Returns non-0 iff proxy flag is set in ticket.
710 : : **/
711 : : int
712 : 2 : shishi_tkt_proxy_p (Shishi_tkt * tkt)
713 : : {
714 : 2 : uint32_t flags = 0;
715 : :
716 : 2 : shishi_tkt_flags (tkt, &flags);
717 : :
718 : 2 : return flags & SHISHI_TICKETFLAGS_PROXY;
719 : : }
720 : :
721 : : /**
722 : : * shishi_tkt_may_postdate_p:
723 : : * @tkt: input variable with ticket info.
724 : : *
725 : : * Determine if ticket may be used to grant postdated tickets.
726 : : *
727 : : * The MAY-POSTDATE flag in a ticket is normally only interpreted by
728 : : * the ticket-granting service. It can be ignored by application
729 : : * servers. This flag MUST be set in a ticket-granting ticket in
730 : : * order to issue a postdated ticket based on the presented ticket. It
731 : : * is reset by default; it MAY be requested by a client by setting the
732 : : * ALLOW- POSTDATE option in the KRB_AS_REQ message. This flag does
733 : : * not allow a client to obtain a postdated ticket-granting ticket;
734 : : * postdated ticket-granting tickets can only by obtained by
735 : : * requesting the postdating in the KRB_AS_REQ message. The life
736 : : * (endtime-starttime) of a postdated ticket will be the remaining
737 : : * life of the ticket-granting ticket at the time of the request,
738 : : * unless the RENEWABLE option is also set, in which case it can be
739 : : * the full life (endtime-starttime) of the ticket-granting
740 : : * ticket. The KDC MAY limit how far in the future a ticket may be
741 : : * postdated.
742 : : *
743 : : * Return value: Returns non-0 iff may-postdate flag is set in ticket.
744 : : **/
745 : : int
746 : 2 : shishi_tkt_may_postdate_p (Shishi_tkt * tkt)
747 : : {
748 : 2 : uint32_t flags = 0;
749 : :
750 : 2 : shishi_tkt_flags (tkt, &flags);
751 : :
752 : 2 : return flags & SHISHI_TICKETFLAGS_MAY_POSTDATE;
753 : : }
754 : :
755 : : /**
756 : : * shishi_tkt_postdated_p:
757 : : * @tkt: input variable with ticket info.
758 : : *
759 : : * Determine if ticket is postdated.
760 : : *
761 : : * The POSTDATED flag indicates that a ticket has been postdated. The
762 : : * application server can check the authtime field in the ticket to
763 : : * see when the original authentication occurred. Some services MAY
764 : : * choose to reject postdated tickets, or they may only accept them
765 : : * within a certain period after the original authentication. When the
766 : : * KDC issues a POSTDATED ticket, it will also be marked as INVALID,
767 : : * so that the application client MUST present the ticket to the KDC
768 : : * to be validated before use.
769 : : *
770 : : * Return value: Returns non-0 iff postdated flag is set in ticket.
771 : : **/
772 : : int
773 : 2 : shishi_tkt_postdated_p (Shishi_tkt * tkt)
774 : : {
775 : 2 : uint32_t flags = 0;
776 : :
777 : 2 : shishi_tkt_flags (tkt, &flags);
778 : :
779 : 2 : return flags & SHISHI_TICKETFLAGS_POSTDATED;
780 : : }
781 : :
782 : : /**
783 : : * shishi_tkt_invalid_p:
784 : : * @tkt: input variable with ticket info.
785 : : *
786 : : * Determine if ticket is invalid.
787 : : *
788 : : * The INVALID flag indicates that a ticket is invalid. Application
789 : : * servers MUST reject tickets which have this flag set. A postdated
790 : : * ticket will be issued in this form. Invalid tickets MUST be
791 : : * validated by the KDC before use, by presenting them to the KDC in a
792 : : * TGS request with the VALIDATE option specified. The KDC will only
793 : : * validate tickets after their starttime has passed. The validation
794 : : * is required so that postdated tickets which have been stolen before
795 : : * their starttime can be rendered permanently invalid (through a
796 : : * hot-list mechanism).
797 : : *
798 : : * Return value: Returns non-0 iff invalid flag is set in ticket.
799 : : **/
800 : : int
801 : 2 : shishi_tkt_invalid_p (Shishi_tkt * tkt)
802 : : {
803 : 2 : uint32_t flags = 0;
804 : :
805 : 2 : shishi_tkt_flags (tkt, &flags);
806 : :
807 : 2 : return flags & SHISHI_TICKETFLAGS_INVALID;
808 : : }
809 : :
810 : : /**
811 : : * shishi_tkt_renewable_p:
812 : : * @tkt: input variable with ticket info.
813 : : *
814 : : * Determine if ticket is renewable.
815 : : *
816 : : * The RENEWABLE flag in a ticket is normally only interpreted by the
817 : : * ticket-granting service (discussed below in section 3.3). It can
818 : : * usually be ignored by application servers. However, some
819 : : * particularly careful application servers MAY disallow renewable
820 : : * tickets.
821 : : *
822 : : * Return value: Returns non-0 iff renewable flag is set in ticket.
823 : : **/
824 : : int
825 : 2 : shishi_tkt_renewable_p (Shishi_tkt * tkt)
826 : : {
827 : 2 : uint32_t flags = 0;
828 : :
829 : 2 : shishi_tkt_flags (tkt, &flags);
830 : :
831 : 2 : return flags & SHISHI_TICKETFLAGS_RENEWABLE;
832 : : }
833 : :
834 : : /**
835 : : * shishi_tkt_initial_p:
836 : : * @tkt: input variable with ticket info.
837 : : *
838 : : * Determine if ticket was issued using AS exchange.
839 : : *
840 : : * The INITIAL flag indicates that a ticket was issued using the AS
841 : : * protocol, rather than issued based on a ticket-granting ticket.
842 : : * Application servers that want to require the demonstrated knowledge
843 : : * of a client's secret key (e.g. a password-changing program) can
844 : : * insist that this flag be set in any tickets they accept, and thus
845 : : * be assured that the client's key was recently presented to the
846 : : * application client.
847 : : *
848 : : * Return value: Returns non-0 iff initial flag is set in ticket.
849 : : **/
850 : : int
851 : 2 : shishi_tkt_initial_p (Shishi_tkt * tkt)
852 : : {
853 : 2 : uint32_t flags = 0;
854 : :
855 : 2 : shishi_tkt_flags (tkt, &flags);
856 : :
857 : 2 : return flags & SHISHI_TICKETFLAGS_INITIAL;
858 : : }
859 : :
860 : : /**
861 : : * shishi_tkt_pre_authent_p:
862 : : * @tkt: input variable with ticket info.
863 : : *
864 : : * Determine if ticket was pre-authenticated.
865 : : *
866 : : * The PRE-AUTHENT and HW-AUTHENT flags provide additional information
867 : : * about the initial authentication, regardless of whether the current
868 : : * ticket was issued directly (in which case INITIAL will also be set)
869 : : * or issued on the basis of a ticket-granting ticket (in which case
870 : : * the INITIAL flag is clear, but the PRE-AUTHENT and HW-AUTHENT flags
871 : : * are carried forward from the ticket-granting ticket).
872 : : *
873 : : * Return value: Returns non-0 iff pre-authent flag is set in ticket.
874 : : **/
875 : : int
876 : 2 : shishi_tkt_pre_authent_p (Shishi_tkt * tkt)
877 : : {
878 : 2 : uint32_t flags = 0;
879 : :
880 : 2 : shishi_tkt_flags (tkt, &flags);
881 : :
882 : 2 : return flags & SHISHI_TICKETFLAGS_PRE_AUTHENT;
883 : : }
884 : :
885 : : /**
886 : : * shishi_tkt_hw_authent_p:
887 : : * @tkt: input variable with ticket info.
888 : : *
889 : : * Determine if ticket is authenticated using a hardware token.
890 : : *
891 : : * The PRE-AUTHENT and HW-AUTHENT flags provide additional information
892 : : * about the initial authentication, regardless of whether the current
893 : : * ticket was issued directly (in which case INITIAL will also be set)
894 : : * or issued on the basis of a ticket-granting ticket (in which case
895 : : * the INITIAL flag is clear, but the PRE-AUTHENT and HW-AUTHENT flags
896 : : * are carried forward from the ticket-granting ticket).
897 : : *
898 : : * Return value: Returns non-0 iff hw-authent flag is set in ticket.
899 : : **/
900 : : int
901 : 2 : shishi_tkt_hw_authent_p (Shishi_tkt * tkt)
902 : : {
903 : 2 : uint32_t flags = 0;
904 : :
905 : 2 : shishi_tkt_flags (tkt, &flags);
906 : :
907 : 2 : return flags & SHISHI_TICKETFLAGS_HW_AUTHENT;
908 : : }
909 : :
910 : : /**
911 : : * shishi_tkt_transited_policy_checked_p:
912 : : * @tkt: input variable with ticket info.
913 : : *
914 : : * Determine if ticket has been policy checked for transit.
915 : : *
916 : : * The application server is ultimately responsible for accepting or
917 : : * rejecting authentication and SHOULD check that only suitably
918 : : * trusted KDCs are relied upon to authenticate a principal. The
919 : : * transited field in the ticket identifies which realms (and thus
920 : : * which KDCs) were involved in the authentication process and an
921 : : * application server would normally check this field. If any of these
922 : : * are untrusted to authenticate the indicated client principal
923 : : * (probably determined by a realm-based policy), the authentication
924 : : * attempt MUST be rejected. The presence of trusted KDCs in this list
925 : : * does not provide any guarantee; an untrusted KDC may have
926 : : * fabricated the list.
927 : : *
928 : : * While the end server ultimately decides whether authentication is
929 : : * valid, the KDC for the end server's realm MAY apply a realm
930 : : * specific policy for validating the transited field and accepting
931 : : * credentials for cross-realm authentication. When the KDC applies
932 : : * such checks and accepts such cross-realm authentication it will set
933 : : * the TRANSITED-POLICY-CHECKED flag in the service tickets it issues
934 : : * based on the cross-realm TGT. A client MAY request that the KDCs
935 : : * not check the transited field by setting the
936 : : * DISABLE-TRANSITED-CHECK flag. KDCs are encouraged but not required
937 : : * to honor this flag.
938 : : *
939 : : * Application servers MUST either do the transited-realm checks
940 : : * themselves, or reject cross-realm tickets without TRANSITED-POLICY-
941 : : * CHECKED set.
942 : : *
943 : : * Return value: Returns non-0 iff transited-policy-checked flag is
944 : : * set in ticket.
945 : : **/
946 : : int
947 : 2 : shishi_tkt_transited_policy_checked_p (Shishi_tkt * tkt)
948 : : {
949 : 2 : uint32_t flags = 0;
950 : :
951 : 2 : shishi_tkt_flags (tkt, &flags);
952 : :
953 : 2 : return flags & SHISHI_TICKETFLAGS_TRANSITED_POLICY_CHECKED;
954 : : }
955 : :
956 : : /**
957 : : * shishi_tkt_ok_as_delegate_p:
958 : : * @tkt: input variable with ticket info.
959 : : *
960 : : * Determine if ticket is ok as delegated ticket.
961 : : *
962 : : * The copy of the ticket flags in the encrypted part of the KDC reply
963 : : * may have the OK-AS-DELEGATE flag set to indicates to the client
964 : : * that the server specified in the ticket has been determined by
965 : : * policy of the realm to be a suitable recipient of delegation. A
966 : : * client can use the presence of this flag to help it make a decision
967 : : * whether to delegate credentials (either grant a proxy or a
968 : : * forwarded ticket- granting ticket) to this server. It is
969 : : * acceptable to ignore the value of this flag. When setting this
970 : : * flag, an administrator should consider the security and placement
971 : : * of the server on which the service will run, as well as whether the
972 : : * service requires the use of delegated credentials.
973 : : *
974 : : * Return value: Returns non-0 iff ok-as-delegate flag is set in ticket.
975 : : **/
976 : : int
977 : 2 : shishi_tkt_ok_as_delegate_p (Shishi_tkt * tkt)
978 : : {
979 : 2 : uint32_t flags = 0;
980 : :
981 : 2 : shishi_tkt_flags (tkt, &flags);
982 : :
983 : 2 : return flags & SHISHI_TICKETFLAGS_OK_AS_DELEGATE;
984 : : }
985 : :
986 : : /**
987 : : * shishi_tkt_keytype:
988 : : * @tkt: input variable with ticket info.
989 : : * @etype: pointer to encryption type that is set, see Shishi_etype.
990 : : *
991 : : * Extract encryption type of key in ticket (really EncKDCRepPart).
992 : : *
993 : : * Return value: Returns SHISHI_OK iff successful.
994 : : **/
995 : : int
996 : 2 : shishi_tkt_keytype (Shishi_tkt * tkt, int32_t * etype)
997 : : {
998 : 2 : return shishi_asn1_read_int32 (tkt->handle, tkt->enckdcreppart,
999 : : "key.keytype", etype);
1000 : : }
1001 : :
1002 : : /**
1003 : : * shishi_tkt_keytype_fast:
1004 : : * @tkt: input variable with ticket info.
1005 : : *
1006 : : * Extract encryption type of key in ticket (really EncKDCRepPart).
1007 : : *
1008 : : * Return value: Returns encryption type of session key in ticket
1009 : : * (really EncKDCRepPart), or -1 on error.
1010 : : **/
1011 : : int32_t
1012 : 0 : shishi_tkt_keytype_fast (Shishi_tkt * tkt)
1013 : : {
1014 : 0 : int32_t etype = -1;
1015 : : int res;
1016 : :
1017 : 0 : res = shishi_asn1_read_int32 (tkt->handle, tkt->enckdcreppart,
1018 : : "key.keytype", &etype);
1019 [ # # ]: 0 : if (res != SHISHI_OK)
1020 : 0 : return -1;
1021 : :
1022 : 0 : return etype;
1023 : : }
1024 : :
1025 : : /**
1026 : : * shishi_tkt_keytype_p:
1027 : : * @tkt: input variable with ticket info.
1028 : : * @etype: encryption type, see Shishi_etype.
1029 : : *
1030 : : * Determine if key in ticket (really EncKDCRepPart) is of specified
1031 : : * key type (really encryption type).
1032 : : *
1033 : : * Return value: Returns non-0 iff key in ticket is of specified
1034 : : * encryption type.
1035 : : **/
1036 : : int
1037 : 0 : shishi_tkt_keytype_p (Shishi_tkt * tkt, int32_t etype)
1038 : : {
1039 : : int32_t tktetype;
1040 : : int rc;
1041 : :
1042 : 0 : rc = shishi_asn1_read_int32 (tkt->handle, tkt->enckdcreppart,
1043 : : "key.keytype", &tktetype);
1044 [ # # ]: 0 : if (rc != SHISHI_OK)
1045 : 0 : return 0;
1046 : :
1047 : 0 : return etype == tktetype;
1048 : : }
1049 : :
1050 : : int
1051 : 0 : shishi_tkt_lastreq (Shishi_tkt * tkt,
1052 : : char **lrtime, size_t * lrtimelen, int32_t lrtype)
1053 : : {
1054 : : char *format;
1055 : : int32_t tmplrtype;
1056 : : size_t i, n;
1057 : : int res;
1058 : :
1059 : 0 : res = shishi_asn1_number_of_elements (tkt->handle, tkt->enckdcreppart,
1060 : : "last-req", &n);
1061 [ # # ]: 0 : if (res != SHISHI_OK)
1062 : 0 : return res;
1063 : :
1064 [ # # ]: 0 : for (i = 1; i <= n; i++)
1065 : : {
1066 : 0 : asprintf (&format, "last-req.?%d.lr-type", i);
1067 : 0 : res = shishi_asn1_read_int32 (tkt->handle, tkt->enckdcreppart,
1068 : : format, &tmplrtype);
1069 : 0 : free (format);
1070 [ # # ]: 0 : if (res != SHISHI_OK)
1071 : 0 : return res;
1072 : :
1073 [ # # ]: 0 : if (lrtype == tmplrtype)
1074 : : {
1075 : 0 : asprintf (&format, "last-req.?%d.lr-value", i);
1076 : 0 : res = shishi_asn1_read (tkt->handle, tkt->enckdcreppart,
1077 : : format, lrtime, lrtimelen);
1078 : 0 : free (format);
1079 [ # # ]: 0 : if (res != SHISHI_OK)
1080 : 0 : return res;
1081 : :
1082 : 0 : return SHISHI_OK;
1083 : : }
1084 : : }
1085 : :
1086 : 0 : return !SHISHI_OK;
1087 : : }
1088 : :
1089 : : /**
1090 : : * shishi_tkt_lastreqc:
1091 : : * @tkt: input variable with ticket info.
1092 : : * @lrtype: lastreq type to extract, see Shishi_lrtype. E.g.,
1093 : : * SHISHI_LRTYPE_LAST_REQUEST.
1094 : : *
1095 : : * Extract C time corresponding to given lastreq type field in the
1096 : : * ticket.
1097 : : *
1098 : : * Return value: Returns C time interpretation of the specified
1099 : : * lastreq field, or (time_t) -1.
1100 : : **/
1101 : : time_t
1102 : 0 : shishi_tkt_lastreqc (Shishi_tkt * tkt, Shishi_lrtype lrtype)
1103 : : {
1104 : : char *lrtime;
1105 : : size_t lrtimelen;
1106 : 0 : time_t t = (time_t) - 1;
1107 : : int res;
1108 : :
1109 : 0 : res = shishi_tkt_lastreq (tkt, &lrtime, &lrtimelen, lrtype);
1110 [ # # ]: 0 : if (res != SHISHI_OK)
1111 : 0 : return t;
1112 : :
1113 [ # # ]: 0 : if (lrtimelen == SHISHI_GENERALIZEDTIME_LENGTH)
1114 : 0 : t = shishi_generalize_ctime (tkt->handle, lrtime);
1115 : :
1116 : 0 : free (lrtime);
1117 : :
1118 : 0 : return t;
1119 : : }
1120 : :
1121 : : int
1122 : 3 : shishi_tkt_authtime (Shishi_tkt * tkt, char **authtime, size_t * authtimelen)
1123 : : {
1124 : 3 : return shishi_asn1_read (tkt->handle, tkt->enckdcreppart, "authtime",
1125 : : authtime, authtimelen);
1126 : : }
1127 : :
1128 : : /**
1129 : : * shishi_tkt_authctime:
1130 : : * @tkt: input variable with ticket info.
1131 : : *
1132 : : * Extract C time corresponding to the authtime field. The field
1133 : : * holds the time when the original authentication took place that
1134 : : * later resulted in this ticket.
1135 : : *
1136 : : * Return value: Returns C time interpretation of the endtime in ticket.
1137 : : **/
1138 : : time_t
1139 : 3 : shishi_tkt_authctime (Shishi_tkt * tkt)
1140 : : {
1141 : : char *authtime;
1142 : : size_t authtimelen;
1143 : 3 : time_t t = (time_t) - 1;
1144 : : int res;
1145 : :
1146 : 3 : res = shishi_tkt_authtime (tkt, &authtime, &authtimelen);
1147 [ - + ]: 3 : if (res != SHISHI_OK)
1148 : 0 : return t;
1149 : :
1150 [ + - ]: 3 : if (authtimelen == SHISHI_GENERALIZEDTIME_LENGTH + 1) /* XXX why +1 ? */
1151 : 3 : t = shishi_generalize_ctime (tkt->handle, authtime);
1152 : :
1153 : 3 : free (authtime);
1154 : :
1155 : 3 : return t;
1156 : : }
1157 : :
1158 : : int
1159 : 4 : shishi_tkt_starttime (Shishi_tkt * tkt,
1160 : : char **starttime, size_t * starttimelen)
1161 : : {
1162 : 4 : return shishi_asn1_read_optional (tkt->handle, tkt->enckdcreppart,
1163 : : "starttime", starttime, starttimelen);
1164 : : }
1165 : :
1166 : : /**
1167 : : * shishi_tkt_startctime:
1168 : : * @tkt: input variable with ticket info.
1169 : : *
1170 : : * Extract C time corresponding to the starttime field. The field
1171 : : * holds the time where the ticket start to be valid (typically in the
1172 : : * past).
1173 : : *
1174 : : * Return value: Returns C time interpretation of the endtime in ticket.
1175 : : **/
1176 : : time_t
1177 : 4 : shishi_tkt_startctime (Shishi_tkt * tkt)
1178 : : {
1179 : : char *starttime;
1180 : : size_t starttimelen;
1181 : 4 : time_t t = (time_t) - 1;
1182 : : int res;
1183 : :
1184 : 4 : res = shishi_tkt_starttime (tkt, &starttime, &starttimelen);
1185 [ + - + + ]: 4 : if (res != SHISHI_OK || starttimelen == 0)
1186 : 1 : return t;
1187 : :
1188 [ + - ]: 3 : if (starttimelen == SHISHI_GENERALIZEDTIME_LENGTH + 1) /* XXX why +1 ? */
1189 : 3 : t = shishi_generalize_ctime (tkt->handle, starttime);
1190 : :
1191 : 3 : free (starttime);
1192 : :
1193 : 4 : return t;
1194 : : }
1195 : :
1196 : : int
1197 : 4 : shishi_tkt_endtime (Shishi_tkt * tkt, char **endtime, size_t * endtimelen)
1198 : : {
1199 : 4 : return shishi_asn1_read (tkt->handle, tkt->enckdcreppart, "endtime",
1200 : : endtime, endtimelen);
1201 : : }
1202 : :
1203 : : /**
1204 : : * shishi_tkt_endctime:
1205 : : * @tkt: input variable with ticket info.
1206 : : *
1207 : : * Extract C time corresponding to the endtime field. The field holds
1208 : : * the time where the ticket stop being valid.
1209 : : *
1210 : : * Return value: Returns C time interpretation of the endtime in ticket.
1211 : : **/
1212 : : time_t
1213 : 4 : shishi_tkt_endctime (Shishi_tkt * tkt)
1214 : : {
1215 : : char *endtime;
1216 : : size_t endtimelen;
1217 : 4 : time_t t = (time_t) - 1;
1218 : : int res;
1219 : :
1220 : 4 : res = shishi_tkt_endtime (tkt, &endtime, &endtimelen);
1221 [ - + ]: 4 : if (res != SHISHI_OK)
1222 : 0 : return t;
1223 : :
1224 [ + - ]: 4 : if (endtimelen == SHISHI_GENERALIZEDTIME_LENGTH + 1) /* XXX why +1 ? */
1225 : 4 : t = shishi_generalize_ctime (tkt->handle, endtime);
1226 : :
1227 : 4 : free (endtime);
1228 : :
1229 : 4 : return t;
1230 : : }
1231 : :
1232 : : int
1233 : 2 : shishi_tkt_renew_till (Shishi_tkt * tkt,
1234 : : char **renewtill, size_t * renewtilllen)
1235 : : {
1236 : 2 : return shishi_asn1_read_optional (tkt->handle, tkt->enckdcreppart,
1237 : : "renew-till", renewtill, renewtilllen);
1238 : : }
1239 : :
1240 : : /**
1241 : : * shishi_tkt_renew_tillc:
1242 : : * @tkt: input variable with ticket info.
1243 : : *
1244 : : * Extract C time corresponding to the renew-till field. The field
1245 : : * holds the time where the ticket stop being valid for renewal.
1246 : : *
1247 : : * Return value: Returns C time interpretation of the renew-till in ticket.
1248 : : **/
1249 : : time_t
1250 : 2 : shishi_tkt_renew_tillc (Shishi_tkt * tkt)
1251 : : {
1252 : : char *renewtill;
1253 : : size_t renewtilllen;
1254 : 2 : time_t t = (time_t) - 1;
1255 : : int res;
1256 : :
1257 : 2 : res = shishi_tkt_renew_till (tkt, &renewtill, &renewtilllen);
1258 [ + - + - ]: 2 : if (res != SHISHI_OK || renewtilllen == 0)
1259 : 2 : return t;
1260 : :
1261 [ # # ]: 0 : if (renewtilllen == SHISHI_GENERALIZEDTIME_LENGTH + 1) /* XXX why +1 ? */
1262 : 0 : t = shishi_generalize_ctime (tkt->handle, renewtill);
1263 : :
1264 : 0 : free (renewtill);
1265 : :
1266 : 2 : return t;
1267 : : }
1268 : :
1269 : : /**
1270 : : * shishi_tkt_valid_at_time_p:
1271 : : * @tkt: input variable with ticket info.
1272 : : * @now: time to check for.
1273 : : *
1274 : : * Determine if ticket is valid at a specific point in time.
1275 : : *
1276 : : * Return value: Returns non-0 iff ticket is valid (not expired and
1277 : : * after starttime) at specified time.
1278 : : **/
1279 : : int
1280 : 2 : shishi_tkt_valid_at_time_p (Shishi_tkt * tkt, time_t now)
1281 : : {
1282 : : time_t starttime, endtime;
1283 : :
1284 : 2 : starttime = shishi_tkt_startctime (tkt);
1285 [ + + ]: 2 : if (starttime == (time_t) - 1)
1286 : 1 : starttime = shishi_tkt_authctime (tkt);
1287 : 2 : endtime = shishi_tkt_endctime (tkt);
1288 : :
1289 [ + - - + ]: 2 : return starttime <= now && now <= endtime;
1290 : : }
1291 : :
1292 : : /**
1293 : : * shishi_tkt_valid_now_p:
1294 : : * @tkt: input variable with ticket info.
1295 : : *
1296 : : * Determine if ticket is valid now.
1297 : : *
1298 : : * Return value: Returns 0 iff ticket is invalid (expired or not yet
1299 : : * valid).
1300 : : **/
1301 : : int
1302 : 2 : shishi_tkt_valid_now_p (Shishi_tkt * tkt)
1303 : : {
1304 : 2 : return shishi_tkt_valid_at_time_p (tkt, time (NULL));
1305 : : }
1306 : :
1307 : : /**
1308 : : * shishi_tkt_expired_p:
1309 : : * @tkt: input variable with ticket info.
1310 : : *
1311 : : * Determine if ticket has expired (i.e., endtime is in the past).
1312 : : *
1313 : : * Return value: Returns 0 iff ticket has expired.
1314 : : **/
1315 : : int
1316 : 0 : shishi_tkt_expired_p (Shishi_tkt * tkt)
1317 : : {
1318 : 0 : time_t endtime = shishi_tkt_endctime (tkt);
1319 : 0 : time_t now = time (NULL);
1320 : :
1321 : 0 : return endtime < now;
1322 : : }
1323 : :
1324 : : /**
1325 : : * shishi_tkt_lastreq_pretty_print:
1326 : : * @tkt: input variable with ticket info.
1327 : : * @fh: file handle open for writing.
1328 : : *
1329 : : * Print a human readable representation of the various lastreq fields
1330 : : * in the ticket (really EncKDCRepPart).
1331 : : **/
1332 : : void
1333 : 0 : shishi_tkt_lastreq_pretty_print (Shishi_tkt * tkt, FILE * fh)
1334 : : {
1335 : : time_t t;
1336 : :
1337 : 0 : t = shishi_tkt_lastreqc (tkt, SHISHI_LRTYPE_LAST_INITIAL_TGT_REQUEST);
1338 [ # # ]: 0 : if (t != (time_t) - 1)
1339 : 0 : fprintf (fh, _("Time of last initial request for a TGT:\t%s"),
1340 : : ctime (&t));
1341 : :
1342 : 0 : t = shishi_tkt_lastreqc (tkt, SHISHI_LRTYPE_LAST_INITIAL_REQUEST);
1343 [ # # ]: 0 : if (t != (time_t) - 1)
1344 : 0 : fprintf (fh, "Time of last initial request:\t%s", ctime (&t));
1345 : :
1346 : 0 : t = shishi_tkt_lastreqc (tkt, SHISHI_LRTYPE_NEWEST_TGT_ISSUE);
1347 [ # # ]: 0 : if (t != (time_t) - 1)
1348 : 0 : fprintf (fh,
1349 : : "Time of issue for the newest ticket-granting ticket used:\t%s",
1350 : : ctime (&t));
1351 : :
1352 : 0 : t = shishi_tkt_lastreqc (tkt, SHISHI_LRTYPE_LAST_RENEWAL);
1353 [ # # ]: 0 : if (t != (time_t) - 1)
1354 : 0 : fprintf (fh, "Time of the last renewal:\t%s", ctime (&t));
1355 : :
1356 : 0 : t = shishi_tkt_lastreqc (tkt, SHISHI_LRTYPE_LAST_REQUEST);
1357 [ # # ]: 0 : if (t != (time_t) - 1)
1358 : 0 : fprintf (fh, "Time of last request:\t%s", ctime (&t));
1359 : 0 : }
1360 : :
1361 : : /**
1362 : : * shishi_tkt_pretty_print:
1363 : : * @tkt: input variable with ticket info.
1364 : : * @fh: file handle open for writing.
1365 : : *
1366 : : * Print a human readable representation of a ticket to file handle.
1367 : : **/
1368 : : void
1369 : 2 : shishi_tkt_pretty_print (Shishi_tkt * tkt, FILE * fh)
1370 : : {
1371 : : char *buf;
1372 : : char *p;
1373 : : size_t buflen;
1374 : : int keytype, etype;
1375 : : uint32_t flags;
1376 : : int res;
1377 : : time_t t;
1378 : 2 : time_t now = time (NULL);
1379 : :
1380 : 2 : res = shishi_tkt_clientrealm (tkt, &buf, &buflen);
1381 [ + - ]: 2 : if (res == SHISHI_OK)
1382 : : {
1383 : 2 : fprintf (fh, "%s:\n", buf);
1384 : 2 : free (buf);
1385 : : }
1386 : : else
1387 : 0 : fprintf (fh, "<unknown>:\n");
1388 : :
1389 : 2 : t = shishi_tkt_authctime (tkt);
1390 : 2 : fprintf (fh, _("Authtime:\t%s"), ctime (&t));
1391 : :
1392 : 2 : t = shishi_tkt_startctime (tkt);
1393 [ + - ]: 2 : if (t != (time_t) - 1)
1394 : : {
1395 : 2 : p = ctime (&t);
1396 : 2 : p[strlen (p) - 1] = '\0';
1397 : 2 : fprintf (fh, _("Starttime:\t%s"), p);
1398 [ - + ]: 2 : if (t > now)
1399 : 0 : fprintf (fh, " NOT YET VALID");
1400 : 2 : fprintf (fh, "\n");
1401 : : }
1402 : :
1403 : 2 : t = shishi_tkt_endctime (tkt);
1404 [ + - ]: 2 : if (t != (time_t) - 1)
1405 : : {
1406 : 2 : p = ctime (&t);
1407 : 2 : p[strlen (p) - 1] = '\0';
1408 : 2 : fprintf (fh, _("Endtime:\t%s"), p);
1409 [ + - ]: 2 : if (t < now)
1410 : 2 : fprintf (fh, " EXPIRED");
1411 : 2 : fprintf (fh, "\n");
1412 : : }
1413 : :
1414 : 2 : t = shishi_tkt_renew_tillc (tkt);
1415 [ - + ]: 2 : if (t != (time_t) - 1)
1416 : 0 : fprintf (fh, _("Renewable till:\t%s"), ctime (&t));
1417 : :
1418 : 2 : res = shishi_tkt_server (tkt, &buf, NULL);
1419 [ + - ]: 2 : if (res == SHISHI_OK)
1420 : : {
1421 : 2 : res = shishi_ticket_get_enc_part_etype (tkt->handle, tkt->ticket,
1422 : : &keytype);
1423 [ + - ]: 2 : if (res == SHISHI_OK)
1424 : 2 : fprintf (fh, _("Server:\t\t%s key %s (%d)\n"), buf,
1425 : : shishi_cipher_name (keytype), keytype);
1426 : 2 : free (buf);
1427 : : }
1428 : :
1429 : 2 : res = shishi_tkt_keytype (tkt, &keytype);
1430 [ + - ]: 2 : if (res == SHISHI_OK)
1431 : 2 : res = shishi_kdcrep_get_enc_part_etype (tkt->handle, tkt->kdcrep, &etype);
1432 [ + - ]: 2 : if (res == SHISHI_OK)
1433 : 2 : fprintf (fh, _("Ticket key:\t%s (%d) protected by %s (%d)\n"),
1434 : : shishi_cipher_name (keytype), keytype,
1435 : : shishi_cipher_name (etype), etype);
1436 : :
1437 : 2 : res = shishi_tkt_flags (tkt, &flags);
1438 [ + - + - ]: 2 : if (res == SHISHI_OK && flags)
1439 : : {
1440 : 2 : fprintf (fh, _("Ticket flags:\t"));
1441 [ - + ]: 2 : if (shishi_tkt_forwardable_p (tkt))
1442 : 0 : fprintf (fh, "FORWARDABLE ");
1443 [ - + ]: 2 : if (shishi_tkt_forwarded_p (tkt))
1444 : 0 : fprintf (fh, "FORWARDED ");
1445 [ - + ]: 2 : if (shishi_tkt_proxiable_p (tkt))
1446 : 0 : fprintf (fh, "PROXIABLE ");
1447 [ + - ]: 2 : if (shishi_tkt_proxy_p (tkt))
1448 : 2 : fprintf (fh, "PROXY ");
1449 [ - + ]: 2 : if (shishi_tkt_may_postdate_p (tkt))
1450 : 0 : fprintf (fh, "MAYPOSTDATE ");
1451 [ + - ]: 2 : if (shishi_tkt_postdated_p (tkt))
1452 : 2 : fprintf (fh, "POSTDATED ");
1453 [ - + ]: 2 : if (shishi_tkt_invalid_p (tkt))
1454 : 0 : fprintf (fh, "INVALID ");
1455 [ - + ]: 2 : if (shishi_tkt_renewable_p (tkt))
1456 : 0 : fprintf (fh, "RENEWABLE ");
1457 [ - + ]: 2 : if (shishi_tkt_initial_p (tkt))
1458 : 0 : fprintf (fh, "INITIAL ");
1459 [ - + ]: 2 : if (shishi_tkt_pre_authent_p (tkt))
1460 : 0 : fprintf (fh, "PREAUTHENT ");
1461 [ + + ]: 2 : if (shishi_tkt_hw_authent_p (tkt))
1462 : 1 : fprintf (fh, "HWAUTHENT ");
1463 [ - + ]: 2 : if (shishi_tkt_transited_policy_checked_p (tkt))
1464 : 0 : fprintf (fh, "TRANSITEDPOLICYCHECKED ");
1465 [ + - ]: 2 : if (shishi_tkt_ok_as_delegate_p (tkt))
1466 : 2 : fprintf (fh, "OKASDELEGATE ");
1467 : 2 : fprintf (fh, "(%d)\n", flags);
1468 : : }
1469 : 2 : }
1470 : :
1471 : : int
1472 : 0 : shishi_tkt_decrypt (Shishi_tkt * tkt, Shishi_key * key)
1473 : : {
1474 : : int rc;
1475 : : Shishi_asn1 encticketpart;
1476 : :
1477 : 0 : rc = shishi_ticket_decrypt (tkt->handle, tkt->ticket, key, &encticketpart);
1478 [ # # ]: 0 : if (rc != SHISHI_OK)
1479 : 0 : return rc;
1480 : :
1481 : 0 : tkt->encticketpart = encticketpart;
1482 : :
1483 : 0 : return SHISHI_OK;
1484 : : }
|