1 /* ticket.c ticket handling
2 * Copyright (C) 2002 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 ASN1_TYPE enckdcreppart
;
34 shishi_ticket_realm_get (Shishi
* handle
,
35 ASN1_TYPE ticket
, char *realm
, int *realmlen
)
37 return _shishi_asn1_field (handle
, ticket
, realm
, realmlen
, "Ticket.realm");
41 shishi_ticket_sname_get (Shishi
* handle
,
42 ASN1_TYPE ticket
, char *server
, int *serverlen
)
44 return shishi_principal_name_get (handle
, ticket
, "Ticket.sname",
49 shishi_ticket_snamerealm_get (Shishi
* handle
,
51 char *serverrealm
, int *serverrealmlen
)
53 return shishi_principal_name_realm_get (handle
, ticket
, "Ticket.sname",
54 ticket
, "Ticket.realm",
55 serverrealm
, serverrealmlen
);
59 * shishi_asn1ticket_get_enc_part_etype:
60 * @handle: shishi handle as allocated by shishi_init().
61 * @kdcrep: Ticket variable to get value from.
62 * @etype: output variable that holds the value.
64 * Extract Ticket.enc-part.etype.
66 * Return value: Returns SHISHI_OK iff successful.
69 shishi_asn1ticket_get_enc_part_etype (Shishi
* handle
,
70 ASN1_TYPE ticket
, int *etype
)
76 buflen
= sizeof (*etype
);
77 res
= _shishi_asn1_field (handle
, ticket
,
78 (char *) etype
, &buflen
, "Ticket.enc-part.etype");
84 * shishi_ticket_principal:
85 * @handle: shishi handle as allocated by shishi_init().
86 * @ticket: input variable with ticket info.
88 * Return value: Returns client principal of ticket.
91 shishi_ticket_principal (Shishi_ticket
* ticket
)
93 return ticket
->principal
? ticket
->principal
: "<none>";
97 * shishi_ticket_ticket:
98 * @handle: shishi handle as allocated by shishi_init().
99 * @ticket: input variable with ticket info.
101 * Return value: Returns actual ticket.
104 shishi_ticket_ticket (Shishi_ticket
* ticket
)
106 return ticket
->ticket
;
110 * shishi_ticket_enckdcreppart:
111 * @handle: shishi handle as allocated by shishi_init().
112 * @ticket: input variable with ticket info.
114 * Return value: Returns auxilliary ticket information.
117 shishi_ticket_enckdcreppart (Shishi_ticket
* ticket
)
119 return ticket
->enckdcreppart
;
124 * @ticket: input variable with ticket info.
126 * Return value: Returns key extracted from enckdcreppart.
129 shishi_ticket_key (Shishi_ticket
* ticket
)
135 res
= shishi_enckdcreppart_get_key (ticket
->handle
,
136 shishi_ticket_enckdcreppart (ticket
),
138 if (res
!= SHISHI_OK
)
147 * @handle: shishi handle as allocated by shishi_init().
148 * @principal: input variable with client principal of ticket.
149 * @ticket: input variable with ticket.
150 * @enckdcreppart: input variable with auxilliary ticket information.
152 * Create a new ticket handle.
154 * Return value: Returns new ticket handle, or %NULL on error.
157 shishi_ticket (Shishi
* handle
, char *principal
,
158 ASN1_TYPE ticket
, ASN1_TYPE enckdcreppart
)
162 tkt
= malloc (sizeof (*tkt
));
166 memset(tkt
, 0, sizeof(*tkt
));
168 tkt
->handle
= handle
;
169 tkt
->principal
= principal
;
170 tkt
->ticket
= ticket
;
171 tkt
->enckdcreppart
= enckdcreppart
;
177 shishi_ticket_flags (Shishi_ticket
* ticket
, int *flags
)
179 int len
= sizeof (*flags
);
182 res
= _shishi_asn1_field (ticket
->handle
, ticket
->enckdcreppart
,
183 (char *) flags
, &len
, "EncKDCRepPart.flags");
188 shishi_ticket_forwardable_p (Shishi_ticket
* ticket
)
192 shishi_ticket_flags (ticket
, &flags
);
194 return flags
& SHISHI_TICKETFLAGS_FORWARDABLE
;
198 shishi_ticket_forwarded_p (Shishi_ticket
* ticket
)
202 shishi_ticket_flags (ticket
, &flags
);
204 return flags
& SHISHI_TICKETFLAGS_FORWARDED
;
208 shishi_ticket_proxiable_p (Shishi_ticket
* ticket
)
212 shishi_ticket_flags (ticket
, &flags
);
214 return flags
& SHISHI_TICKETFLAGS_PROXIABLE
;
218 shishi_ticket_proxy_p (Shishi_ticket
* ticket
)
222 shishi_ticket_flags (ticket
, &flags
);
224 return flags
& SHISHI_TICKETFLAGS_PROXY
;
228 shishi_ticket_may_postdate_p (Shishi_ticket
* ticket
)
232 shishi_ticket_flags (ticket
, &flags
);
234 return flags
& SHISHI_TICKETFLAGS_MAY_POSTDATE
;
238 shishi_ticket_postdated_p (Shishi_ticket
* ticket
)
242 shishi_ticket_flags (ticket
, &flags
);
244 return flags
& SHISHI_TICKETFLAGS_POSTDATED
;
248 shishi_ticket_invalid_p (Shishi_ticket
* ticket
)
252 shishi_ticket_flags (ticket
, &flags
);
254 return flags
& SHISHI_TICKETFLAGS_INVALID
;
258 shishi_ticket_renewable_p (Shishi_ticket
* ticket
)
262 shishi_ticket_flags (ticket
, &flags
);
264 return flags
& SHISHI_TICKETFLAGS_RENEWABLE
;
268 shishi_ticket_initial_p (Shishi_ticket
* ticket
)
272 shishi_ticket_flags (ticket
, &flags
);
274 return flags
& SHISHI_TICKETFLAGS_INITIAL
;
278 shishi_ticket_pre_authent_p (Shishi_ticket
* ticket
)
282 shishi_ticket_flags (ticket
, &flags
);
284 return flags
& SHISHI_TICKETFLAGS_PRE_AUTHENT
;
288 shishi_ticket_hw_authent_p (Shishi_ticket
* ticket
)
292 shishi_ticket_flags (ticket
, &flags
);
294 return flags
& SHISHI_TICKETFLAGS_HW_AUTHENT
;
298 shishi_ticket_transited_policy_checked_p (Shishi_ticket
* ticket
)
302 shishi_ticket_flags (ticket
, &flags
);
304 return flags
& SHISHI_TICKETFLAGS_TRANSITED_POLICY_CHECKED
;
308 shishi_ticket_ok_as_delegate_p (Shishi_ticket
* ticket
)
312 shishi_ticket_flags (ticket
, &flags
);
314 return flags
& SHISHI_TICKETFLAGS_OK_AS_DELEGATE
;
318 shishi_ticket_realm (Shishi_ticket
* ticket
, const char *realm
, int *realmlen
)
320 return shishi_ticket_realm_get (ticket
->handle
, ticket
->ticket
,
325 shishi_ticket_server (Shishi_ticket
* ticket
,
326 const char *service
, int *servicelen
)
328 return shishi_ticket_sname_get (ticket
->handle
, ticket
->ticket
,
329 service
, servicelen
);
333 shishi_ticket_server_p (Shishi_ticket
* ticket
, const char *service
)
339 buflen
= strlen (service
) + 1;
340 buf
= malloc (buflen
);
344 res
= shishi_ticket_server (ticket
, buf
, &buflen
);
345 if (res
!= SHISHI_OK
)
352 if (strcmp (service
, buf
) != 0)
364 shishi_ticket_server_realm (Shishi_ticket
* ticket
,
365 char *servicerealm
, int *servicerealmlen
)
367 return shishi_ticket_snamerealm_get (ticket
->handle
, ticket
->ticket
,
368 servicerealm
, servicerealmlen
);
372 shishi_ticket_keytype (Shishi_ticket
* ticket
, int *etype
)
374 return _shishi_asn1_integer_field (ticket
->handle
,
375 ticket
->enckdcreppart
, etype
,
376 "EncKDCRepPart.key.keytype");
380 shishi_ticket_authtime (Shishi_ticket
* ticket
,
381 char *authtime
, int *authtimelen
)
383 return _shishi_asn1_field (ticket
->handle
, ticket
->enckdcreppart
,
384 authtime
, authtimelen
, "EncKDCRepPart.authtime");
388 shishi_ticket_authctime (Shishi_ticket
* ticket
)
390 char authtime
[GENERALIZEDTIME_TIME_LEN
+ 1];
395 authtimelen
= sizeof (authtime
);
396 res
= shishi_ticket_authtime (ticket
, authtime
, &authtimelen
);
397 if (res
!= SHISHI_OK
)
400 authtime
[GENERALIZEDTIME_TIME_LEN
] = '\0';
402 t
= shishi_generalize_ctime (ticket
->handle
, authtime
);
408 shishi_ticket_starttime (Shishi_ticket
* ticket
,
409 char *starttime
, int *starttimelen
)
411 return _shishi_asn1_optional_field (ticket
->handle
, ticket
->enckdcreppart
,
412 starttime
, starttimelen
,
413 "EncKDCRepPart.starttime");
417 shishi_ticket_startctime (Shishi_ticket
* ticket
)
419 char starttime
[GENERALIZEDTIME_TIME_LEN
+ 1];
424 starttimelen
= sizeof (starttime
);
425 res
= shishi_ticket_starttime (ticket
, starttime
, &starttimelen
);
426 if (res
!= SHISHI_OK
|| starttimelen
== 0)
429 starttime
[GENERALIZEDTIME_TIME_LEN
] = '\0';
431 t
= shishi_generalize_ctime (ticket
->handle
, starttime
);
437 shishi_ticket_endtime (Shishi_ticket
* ticket
, char *endtime
, int *endtimelen
)
439 return _shishi_asn1_field (ticket
->handle
, ticket
->enckdcreppart
,
440 endtime
, endtimelen
, "EncKDCRepPart.endtime");
444 shishi_ticket_endctime (Shishi_ticket
* ticket
)
446 char endtime
[GENERALIZEDTIME_TIME_LEN
+ 1];
451 endtimelen
= sizeof (endtime
);
452 res
= shishi_ticket_endtime (ticket
, endtime
, &endtimelen
);
453 if (res
!= SHISHI_OK
)
456 endtime
[GENERALIZEDTIME_TIME_LEN
] = '\0';
458 t
= shishi_generalize_ctime (ticket
->handle
, endtime
);
464 shishi_ticket_renew_till (Shishi_ticket
* ticket
,
465 char *renewtill
, int *renewtilllen
)
467 return _shishi_asn1_optional_field (ticket
->handle
, ticket
->enckdcreppart
,
468 renewtill
, renewtilllen
,
469 "EncKDCRepPart.renew-till");
473 shishi_ticket_renew_tillc (Shishi_ticket
* ticket
)
475 char renewtill
[GENERALIZEDTIME_TIME_LEN
+ 1];
480 renewtilllen
= sizeof (renewtill
);
481 res
= shishi_ticket_renew_till (ticket
, renewtill
, &renewtilllen
);
482 if (res
!= SHISHI_OK
|| renewtilllen
== 0)
485 renewtill
[GENERALIZEDTIME_TIME_LEN
] = '\0';
487 t
= shishi_generalize_ctime (ticket
->handle
, renewtill
);
493 shishi_ticket_valid_at_time_p (Shishi_ticket
* ticket
, time_t now
)
495 time_t starttime
, endtime
;
497 starttime
= shishi_ticket_startctime (ticket
);
498 if (starttime
== (time_t) - 1)
499 starttime
= shishi_ticket_authctime (ticket
);
500 endtime
= shishi_ticket_endctime (ticket
);
502 return starttime
<= now
&& now
<= endtime
;
506 shishi_ticket_valid_now_p (Shishi_ticket
* ticket
)
508 return shishi_ticket_valid_at_time_p (ticket
, time (NULL
));
512 shishi_ticket_print (Shishi_ticket
* ticket
, FILE * fh
)
521 printf ("%s:\n", shishi_ticket_principal (ticket
));
523 t
= shishi_ticket_authctime (ticket
);
524 printf (_("Authtime:\t%s"), ctime (&t
));
526 t
= shishi_ticket_startctime (ticket
);
527 if (t
!= (time_t) - 1)
528 printf (_("Starttime:\t%s"), ctime (&t
));
530 t
= shishi_ticket_endctime (ticket
);
532 p
[strlen (p
) - 1] = '\0';
533 printf (_("Endtime:\t%s\t%s\n"), p
,
534 shishi_ticket_valid_now_p (ticket
) ? "valid" : "EXPIRED");
536 t
= shishi_ticket_renew_tillc (ticket
);
537 if (t
!= (time_t) - 1)
538 printf (_("Renewable until:\t%s"), ctime (&t
));
540 buflen
= sizeof (buf
);
542 res
= shishi_ticket_server (ticket
, buf
, &buflen
);
543 if (res
!= SHISHI_OK
)
546 printf (_("Service:\t%s\n"), buf
);
548 res
= shishi_ticket_keytype (ticket
, &etype
);
549 if (res
!= SHISHI_OK
)
551 printf (_("Key type:\t%s (%d)\n"), shishi_cipher_name (etype
), etype
);
553 res
= shishi_ticket_flags (ticket
, &flags
);
554 if (res
!= SHISHI_OK
)
557 ("Flags:\t%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n"),
558 flags
, shishi_ticket_forwardable_p (ticket
) ? "FORWARDABLE" :
559 "", shishi_ticket_forwarded_p (ticket
) ? "FORWARDED" : "",
560 shishi_ticket_proxiable_p (ticket
) ? "PROXIABLE" : "",
561 shishi_ticket_proxy_p (ticket
) ? "PROXY" : "",
562 shishi_ticket_may_postdate_p (ticket
) ? "MAYPOSTDATE" : "",
563 shishi_ticket_postdated_p (ticket
) ? "POSTDATED" : "",
564 shishi_ticket_invalid_p (ticket
) ? "INVALID" : "",
565 shishi_ticket_renewable_p (ticket
) ? "RENEWABLE" : "",
566 shishi_ticket_initial_p (ticket
) ? "INITIAL" : "",
567 shishi_ticket_pre_authent_p (ticket
) ? "PREAUTHENT" : "",
568 shishi_ticket_hw_authent_p (ticket
) ? "HWAUTHENT" : "",
569 shishi_ticket_transited_policy_checked_p (ticket
) ?
570 "TRANSITEDPOLICYCHECKED" : "",
571 shishi_ticket_ok_as_delegate_p (ticket
) ? "OKASDELEGATE" : "");
579 shishi_ticket_decrypt (Shishi
* handle
,
582 ASN1_TYPE
* encticketpart
)
587 unsigned char buf
[BUFSIZ
];
588 unsigned char cipher
[BUFSIZ
];
589 int realmlen
= BUFSIZ
;
593 res
= shishi_asn1ticket_get_enc_part_etype (handle
, ticket
, &etype
);
594 if (res
!= SHISHI_OK
)
597 if (etype
!= shishi_key_type(key
))
598 return SHISHI_KDCREP_BAD_KEYTYPE
;
601 res
= _shishi_asn1_field (handle
, ticket
, cipher
, &cipherlen
,
602 "Ticket.enc-part.cipher");
603 if (res
!= SHISHI_OK
)
606 res
= shishi_decrypt (handle
, key
, SHISHI_KEYUSAGE_KDCREP_TICKET
,
607 cipher
, cipherlen
, buf
, &buflen
);
609 if (res
!= SHISHI_OK
)
611 if (VERBOSE (handle
))
612 printf ("des_decrypt failed: %s\n", shishi_strerror_details (handle
));
613 shishi_error_printf (handle
,
614 "des_decrypt fail, most likely wrong password\n");
618 /* The crypto is so 1980; no length indicator. Trim off pad bytes
619 until we can parse it. */
620 for (i
= 0; i
< 8; i
++)
622 if (VERBOSEASN1 (handle
))
623 printf ("Trying with %d pad in enckdcrep...\n", i
);
625 *encticketpart
= shishi_d2a_encticketpart (handle
, &buf
[0], buflen
- i
);
626 if (*encticketpart
!= ASN1_TYPE_EMPTY
)
630 if (*encticketpart
== ASN1_TYPE_EMPTY
)
632 shishi_error_printf (handle
, "Could not DER decode EncTicketPart. "
633 "Password probably correct (decrypt ok) though\n");
634 return SHISHI_ASN1_ERROR
;