1 /* kdcreq.c --- Key distribution (AS/TGS) request functions.
2 * Copyright (C) 2002, 2003, 2004, 2005, 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
25 /* Get _shishi_print_armored_data, etc. */
28 #define SHISHI_KDCREQ_DEFAULT_PVNO "5"
29 #define SHISHI_KDCREQ_DEFAULT_PVNO_LEN 0
30 #define SHISHI_AS_REQ_DEFAULT_MSG_TYPE "10"
31 #define SHISHI_AS_REQ_DEFAULT_MSG_TYPE_LEN 0
32 #define SHISHI_TGS_REQ_DEFAULT_MSG_TYPE "12"
33 #define SHISHI_TGS_REQ_DEFAULT_MSG_TYPE_LEN 0
34 #define SHISHI_KDCREQ_DEFAULT_REQ_BODY_KDC_OPTIONS "\x00\x00\x00\x00"
35 #define SHISHI_KDCREQ_DEFAULT_REQ_BODY_KDC_OPTIONS_LEN 32
36 #define SHISHI_KDCREQ_DEFAULT_REQ_BODY_SNAME_NAME_TYPE "1" /* SHISHI_NT_PRINCIPAL */
37 #define SHISHI_KDCREQ_DEFAULT_REQ_BODY_SNAME_NAME_TYPE_LEN 0
38 #define SHISHI_KDCREQ_DEFAULT_REQ_BODY_TILL ""
39 #define SHISHI_KDCREQ_DEFAULT_REQ_BODY_TILL_LEN 1
42 _shishi_kdcreq (Shishi
* handle
, int as
)
46 const char *servicebuf
[3];
50 node
= shishi_asn1_asreq (handle
);
52 node
= shishi_asn1_tgsreq (handle
);
56 res
= shishi_asn1_write (handle
, node
, "pvno",
57 SHISHI_KDCREQ_DEFAULT_PVNO
,
58 SHISHI_KDCREQ_DEFAULT_PVNO_LEN
);
63 res
= shishi_asn1_write (handle
, node
, "msg-type",
64 SHISHI_AS_REQ_DEFAULT_MSG_TYPE
,
65 SHISHI_AS_REQ_DEFAULT_MSG_TYPE_LEN
);
67 res
= shishi_asn1_write (handle
, node
, "msg-type",
68 SHISHI_TGS_REQ_DEFAULT_MSG_TYPE
,
69 SHISHI_TGS_REQ_DEFAULT_MSG_TYPE_LEN
);
73 res
= shishi_asn1_write (handle
, node
, "req-body.kdc-options",
74 SHISHI_KDCREQ_DEFAULT_REQ_BODY_KDC_OPTIONS
,
75 SHISHI_KDCREQ_DEFAULT_REQ_BODY_KDC_OPTIONS_LEN
);
80 res
= shishi_kdcreq_set_cname (handle
, node
, SHISHI_NT_PRINCIPAL
,
81 shishi_principal_default (handle
));
83 res
= shishi_asn1_write (handle
, node
, "req-body.cname", NULL
, 0);
87 res
= shishi_kdcreq_set_realm (handle
, node
, shishi_realm_default (handle
));
91 servicebuf
[0] = "krbtgt";
92 servicebuf
[1] = shishi_realm_default (handle
);
94 res
= shishi_kdcreq_set_sname (handle
, node
,
95 SHISHI_NT_PRINCIPAL
, servicebuf
);
99 res
= shishi_asn1_write (handle
, node
, "req-body.sname.name-type",
100 SHISHI_KDCREQ_DEFAULT_REQ_BODY_SNAME_NAME_TYPE
,
101 SHISHI_KDCREQ_DEFAULT_REQ_BODY_SNAME_NAME_TYPE_LEN
);
102 if (res
!= SHISHI_OK
)
105 res
= shishi_asn1_write (handle
, node
, "req-body.till",
106 shishi_generalize_time (handle
,
108 handle
->ticketlife
), 0);
109 if (res
!= SHISHI_OK
)
112 shishi_randomize (handle
, 0, &nonce
, sizeof (nonce
));
113 nonce
&= 0x7FFFFFFF; /* XXX fix _libtasn1_convert_integer. */
114 res
= shishi_kdcreq_nonce_set (handle
, node
, nonce
);
115 if (res
!= SHISHI_OK
)
118 res
= shishi_kdcreq_set_etype (handle
, node
, handle
->clientkdcetypes
,
119 handle
->nclientkdcetypes
);
120 if (res
!= SHISHI_OK
)
123 res
= shishi_asn1_write (handle
, node
, "req-body.addresses", NULL
, 0);
124 if (res
!= SHISHI_OK
)
127 res
= shishi_asn1_write (handle
, node
,
128 "req-body.enc-authorization-data", NULL
, 0);
129 if (res
!= SHISHI_OK
)
133 shishi_asn1_write (handle
, node
, "req-body.additional-tickets", NULL
, 0);
134 if (res
!= SHISHI_OK
)
140 shishi_asn1_done (handle
, node
);
146 * @handle: shishi handle as allocated by shishi_init().
148 * This function creates a new AS-REQ, populated with some default
151 * Return value: Returns the AS-REQ or NULL on failure.
154 shishi_asreq (Shishi
* handle
)
156 return _shishi_kdcreq (handle
, 1);
161 * @handle: shishi handle as allocated by shishi_init().
163 * This function creates a new TGS-REQ, populated with some default
166 * Return value: Returns the TGS-REQ or NULL on failure.
169 shishi_tgsreq (Shishi
* handle
)
171 return _shishi_kdcreq (handle
, 0);
175 * shishi_kdcreq_print:
176 * @handle: shishi handle as allocated by shishi_init().
177 * @fh: file handle open for writing.
178 * @kdcreq: KDC-REQ to print.
180 * Print ASCII armored DER encoding of KDC-REQ to file.
182 * Return value: Returns SHISHI_OK iff successful.
185 shishi_kdcreq_print (Shishi
* handle
, FILE * fh
, Shishi_asn1 kdcreq
)
187 return _shishi_print_armored_data (handle
, fh
, kdcreq
, "KDC-REQ", NULL
);
191 * shishi_kdcreq_save:
192 * @handle: shishi handle as allocated by shishi_init().
193 * @fh: file handle open for writing.
194 * @kdcreq: KDC-REQ to save.
196 * Print DER encoding of KDC-REQ to file.
198 * Return value: Returns SHISHI_OK iff successful.
201 shishi_kdcreq_save (Shishi
* handle
, FILE * fh
, Shishi_asn1 kdcreq
)
203 return _shishi_save_data (handle
, fh
, kdcreq
, "KDC-REQ");
207 * shishi_kdcreq_to_file:
208 * @handle: shishi handle as allocated by shishi_init().
209 * @kdcreq: KDC-REQ to save.
210 * @filetype: input variable specifying type of file to be written,
211 * see Shishi_filetype.
212 * @filename: input variable with filename to write to.
214 * Write KDC-REQ to file in specified TYPE. The file will be truncated
217 * Return value: Returns SHISHI_OK iff successful.
220 shishi_kdcreq_to_file (Shishi
* handle
, Shishi_asn1 kdcreq
,
221 int filetype
, const char *filename
)
226 if (VERBOSE (handle
))
227 printf (_("Writing KDC-REQ to %s...\n"), filename
);
229 fh
= fopen (filename
, "w");
231 return SHISHI_FOPEN_ERROR
;
233 if (VERBOSE (handle
))
234 printf (_("Writing KDC-REQ in %s format...\n"),
235 filetype
== SHISHI_FILETYPE_TEXT
? "TEXT" : "DER");
237 if (filetype
== SHISHI_FILETYPE_TEXT
)
238 res
= shishi_kdcreq_print (handle
, fh
, kdcreq
);
240 res
= shishi_kdcreq_save (handle
, fh
, kdcreq
);
241 if (res
!= SHISHI_OK
)
246 return SHISHI_IO_ERROR
;
248 if (VERBOSE (handle
))
249 printf (_("Writing KDC-REQ to %s...done\n"), filename
);
255 * shishi_kdcreq_parse:
256 * @handle: shishi handle as allocated by shishi_init().
257 * @fh: file handle open for reading.
258 * @kdcreq: output variable with newly allocated KDC-REQ.
260 * Read ASCII armored DER encoded KDC-REQ from file and populate given
263 * Return value: Returns SHISHI_OK iff successful.
266 shishi_kdcreq_parse (Shishi
* handle
, FILE * fh
, Shishi_asn1
* kdcreq
)
268 return _shishi_kdcreq_input (handle
, fh
, kdcreq
, 0);
272 * shishi_kdcreq_read:
273 * @handle: shishi handle as allocated by shishi_init().
274 * @fh: file handle open for reading.
275 * @kdcreq: output variable with newly allocated KDC-REQ.
277 * Read DER encoded KDC-REQ from file and populate given variable.
279 * Return value: Returns SHISHI_OK iff successful.
282 shishi_kdcreq_read (Shishi
* handle
, FILE * fh
, Shishi_asn1
* kdcreq
)
284 return _shishi_kdcreq_input (handle
, fh
, kdcreq
, 1);
288 * shishi_kdcreq_from_file:
289 * @handle: shishi handle as allocated by shishi_init().
290 * @kdcreq: output variable with newly allocated KDC-REQ.
291 * @filetype: input variable specifying type of file to be read,
292 * see Shishi_filetype.
293 * @filename: input variable with filename to read from.
295 * Read KDC-REQ from file in specified TYPE.
297 * Return value: Returns SHISHI_OK iff successful.
300 shishi_kdcreq_from_file (Shishi
* handle
, Shishi_asn1
* kdcreq
,
301 int filetype
, const char *filename
)
306 if (VERBOSE (handle
))
307 printf (_("Reading KDC-REQ from %s...\n"), filename
);
309 fh
= fopen (filename
, "r");
311 return SHISHI_FOPEN_ERROR
;
313 if (VERBOSE (handle
))
314 printf (_("Reading KDC-REQ in %s format...\n"),
315 filetype
== SHISHI_FILETYPE_TEXT
? "TEXT" : "DER");
317 if (filetype
== SHISHI_FILETYPE_TEXT
)
318 res
= shishi_kdcreq_parse (handle
, fh
, kdcreq
);
320 res
= shishi_kdcreq_read (handle
, fh
, kdcreq
);
321 if (res
!= SHISHI_OK
)
326 return SHISHI_IO_ERROR
;
328 if (VERBOSE (handle
))
329 printf (_("Reading KDC-REQ from %s...done\n"), filename
);
335 shishi_kdcreq_nonce (Shishi
* handle
, Shishi_asn1 kdcreq
, uint32_t * nonce
)
339 res
= shishi_asn1_read_uint32 (handle
, kdcreq
, "req-body.nonce", nonce
);
340 if (res
!= SHISHI_OK
)
347 * shishi_kdcreq_nonce_set:
348 * @handle: shishi handle as allocated by shishi_init().
349 * @kdcreq: KDC-REQ variable to set client name field in.
350 * @nonce: integer nonce to store in KDC-REQ.
352 * Store nonce number field in KDC-REQ.
354 * Return value: Returns %SHISHI_OK iff successful.
357 shishi_kdcreq_nonce_set (Shishi
* handle
, Shishi_asn1 kdcreq
, uint32_t nonce
)
361 res
= shishi_asn1_write_uint32 (handle
, kdcreq
, "req-body.nonce", nonce
);
362 if (res
!= SHISHI_OK
)
369 * shishi_kdcreq_set_cname:
370 * @handle: shishi handle as allocated by shishi_init().
371 * @kdcreq: KDC-REQ variable to set client name field in.
372 * @name_type: type of principial, see Shishi_name_type, usually
374 * @principal: input array with principal name.
376 * Set the client name field in the KDC-REQ.
378 * Return value: Returns SHISHI_OK iff successful.
381 shishi_kdcreq_set_cname (Shishi
* handle
,
383 Shishi_name_type name_type
, const char *principal
)
387 res
= shishi_principal_set (handle
, kdcreq
, "req-body.cname", principal
);
388 if (res
!= SHISHI_OK
)
395 * shishi_kdcreq_client:
396 * @handle: Shishi library handle create by shishi_init().
397 * @kdcreq: KDC-REQ variable to get client name from.
398 * @client: pointer to newly allocated zero terminated string containing
399 * principal name. May be %NULL (to only populate @clientlen).
400 * @clientlen: pointer to length of @client on output, excluding terminating
401 * zero. May be %NULL (to only populate @client).
403 * Represent client principal name in KDC-REQ as zero-terminated
404 * string. The string is allocate by this function, and it is the
405 * responsibility of the caller to deallocate it. Note that the
406 * output length @clientlen does not include the terminating zero.
408 * Return value: Returns SHISHI_OK iff successful.
411 shishi_kdcreq_client (Shishi
* handle
, Shishi_asn1 kdcreq
,
412 char **client
, size_t * clientlen
)
414 return shishi_principal_name (handle
, kdcreq
, "req-body.cname",
419 * shishi_asreq_clientrealm:
420 * @handle: Shishi library handle create by shishi_init().
421 * @asreq: AS-REQ variable to get client name and realm from.
422 * @client: pointer to newly allocated zero terminated string containing
423 * principal name and realm. May be %NULL (to only populate @clientlen).
424 * @clientlen: pointer to length of @client on output, excluding terminating
425 * zero. May be %NULL (to only populate @client).
427 * Convert cname and realm fields from AS-REQ to printable principal
428 * name format. The string is allocate by this function, and it is
429 * the responsibility of the caller to deallocate it. Note that the
430 * output length @clientlen does not include the terminating zero.
432 * Return value: Returns SHISHI_OK iff successful.
435 shishi_asreq_clientrealm (Shishi
* handle
,
437 char **client
, size_t * clientlen
)
439 return shishi_principal_name_realm (handle
,
440 asreq
, "req-body.cname",
441 asreq
, "req-body.realm",
446 * shishi_kdcreq_realm:
447 * @handle: Shishi library handle create by shishi_init().
448 * @kdcreq: KDC-REQ variable to get client name from.
449 * @realm: pointer to newly allocated zero terminated string containing
450 * realm. May be %NULL (to only populate @realmlen).
451 * @realmlen: pointer to length of @realm on output, excluding terminating
452 * zero. May be %NULL (to only populate @realmlen).
454 * Get realm field in KDC-REQ as zero-terminated string. The string
455 * is allocate by this function, and it is the responsibility of the
456 * caller to deallocate it. Note that the output length @realmlen
457 * does not include the terminating zero.
459 * Return value: Returns SHISHI_OK iff successful.
462 shishi_kdcreq_realm (Shishi
* handle
, Shishi_asn1 kdcreq
,
463 char **realm
, size_t * realmlen
)
465 return shishi_asn1_read_optional (handle
, kdcreq
, "req-body.realm",
470 shishi_kdcreq_realm_get (Shishi
* handle
, Shishi_asn1 kdcreq
,
471 char **realm
, size_t * realmlen
)
473 return shishi_asn1_read_optional (handle
, kdcreq
, "req-body.realm",
478 * shishi_kdcreq_set_realm:
479 * @handle: shishi handle as allocated by shishi_init().
480 * @kdcreq: KDC-REQ variable to set realm field in.
481 * @realm: input array with name of realm.
483 * Set the realm field in the KDC-REQ.
485 * Return value: Returns SHISHI_OK iff successful.
488 shishi_kdcreq_set_realm (Shishi
* handle
, Shishi_asn1 kdcreq
,
493 res
= shishi_asn1_write (handle
, kdcreq
, "req-body.realm", realm
, 0);
494 if (res
!= SHISHI_OK
)
501 * shishi_kdcreq_server:
502 * @handle: Shishi library handle create by shishi_init().
503 * @kdcreq: KDC-REQ variable to get server name from.
504 * @server: pointer to newly allocated zero terminated string containing
505 * principal name. May be %NULL (to only populate @serverlen).
506 * @serverlen: pointer to length of @server on output, excluding terminating
507 * zero. May be %NULL (to only populate @server).
509 * Represent server principal name in KDC-REQ as zero-terminated
510 * string. The string is allocate by this function, and it is the
511 * responsibility of the caller to deallocate it. Note that the
512 * output length @serverlen does not include the terminating zero.
514 * Return value: Returns SHISHI_OK iff successful.
517 shishi_kdcreq_server (Shishi
* handle
, Shishi_asn1 kdcreq
,
518 char **server
, size_t * serverlen
)
520 return shishi_principal_name (handle
, kdcreq
, "req-body.sname",
525 * shishi_kdcreq_set_sname:
526 * @handle: shishi handle as allocated by shishi_init().
527 * @kdcreq: KDC-REQ variable to set server name field in.
528 * @name_type: type of principial, see Shishi_name_type, usually
530 * @sname: input array with principal name.
532 * Set the server name field in the KDC-REQ.
534 * Return value: Returns SHISHI_OK iff successful.
537 shishi_kdcreq_set_sname (Shishi
* handle
,
539 Shishi_name_type name_type
, const char *sname
[])
543 res
= shishi_principal_name_set (handle
, kdcreq
, "req-body.sname",
545 if (res
!= SHISHI_OK
)
552 shishi_kdcreq_set_server (Shishi
* handle
, Shishi_asn1 req
,
557 res
= shishi_principal_set (handle
, req
, "req-body.sname", server
);
558 if (res
!= SHISHI_OK
)
565 shishi_kdcreq_set_realmserver (Shishi
* handle
,
566 Shishi_asn1 req
, char *realm
, char *server
)
570 res
= shishi_kdcreq_set_realm (handle
, req
, realm
);
571 if (res
!= SHISHI_OK
)
574 res
= shishi_kdcreq_set_server (handle
, req
, server
);
575 if (res
!= SHISHI_OK
)
582 * shishi_kdcreq_till:
583 * @handle: Shishi library handle create by shishi_init().
584 * @kdcreq: KDC-REQ variable to get client name from.
585 * @till: pointer to newly allocated zero terminated string containing
586 * "till" field with generalized time. May be %NULL (to only
587 * populate @realmlen).
588 * @tilllen: pointer to length of @till on output, excluding
589 * terminating zero. May be %NULL (to only populate @tilllen).
591 * Get "till" field (i.e. "endtime") in KDC-REQ, as zero-terminated
592 * string. The string is typically 15 characters long. The string is
593 * allocated by this function, and it is the responsibility of the
594 * caller to deallocate it. Note that the output length @realmlen
595 * does not include the terminating zero.
597 * Return value: Returns SHISHI_OK iff successful.
600 shishi_kdcreq_till (Shishi
* handle
, Shishi_asn1 kdcreq
,
601 char **till
, size_t * tilllen
)
603 return shishi_asn1_read (handle
, kdcreq
, "req-body.till", till
, tilllen
);
607 * shishi_kdcreq_tillc:
608 * @handle: Shishi library handle create by shishi_init().
609 * @kdcreq: KDC-REQ variable to get till field from.
611 * Extract C time corresponding to the "till" field.
613 * Return value: Returns C time interpretation of the "till" field in
617 shishi_kdcreq_tillc (Shishi
* handle
, Shishi_asn1 kdcreq
)
621 time_t t
= (time_t) - 1;
624 res
= shishi_kdcreq_till (handle
, kdcreq
, &till
, &tilllen
);
625 if (res
!= SHISHI_OK
)
628 if (tilllen
== SHISHI_GENERALIZEDTIME_LENGTH
+ 1) /* XXX why +1 ? */
629 t
= shishi_generalize_ctime (handle
, till
);
637 * shishi_kdcreq_etype:
638 * @handle: shishi handle as allocated by shishi_init().
639 * @kdcreq: KDC-REQ variable to get etype field from.
640 * @etype: output encryption type.
641 * @netype: element number to return.
643 * Return the netype:th encryption type from KDC-REQ. The first etype
646 * Return value: Returns SHISHI_OK iff etype successful set.
649 shishi_kdcreq_etype (Shishi
* handle
,
650 Shishi_asn1 kdcreq
, int32_t * etype
, int netype
)
655 asprintf (&buf
, "req-body.etype.?%d", netype
);
656 res
= shishi_asn1_read_int32 (handle
, kdcreq
, buf
, etype
);
657 if (res
!= SHISHI_OK
)
664 * shishi_kdcreq_set_etype:
665 * @handle: shishi handle as allocated by shishi_init().
666 * @kdcreq: KDC-REQ variable to set etype field in.
667 * @etype: input array with encryption types.
668 * @netype: number of elements in input array with encryption types.
670 * Set the list of supported or wanted encryption types in the
671 * request. The list should be sorted in priority order.
673 * Return value: Returns SHISHI_OK iff successful.
676 shishi_kdcreq_set_etype (Shishi
* handle
,
677 Shishi_asn1 kdcreq
, int32_t * etype
, int netype
)
683 res
= shishi_asn1_write (handle
, kdcreq
, "req-body.etype", NULL
, 0);
684 if (res
!= SHISHI_OK
)
687 for (i
= 1; i
<= netype
; i
++)
689 res
= shishi_asn1_write (handle
, kdcreq
, "req-body.etype", "NEW", 1);
690 if (res
!= SHISHI_OK
)
693 asprintf (&buf
, "req-body.etype.?%d", i
);
694 res
= shishi_asn1_write_int32 (handle
, kdcreq
, buf
, etype
[i
- 1]);
696 if (res
!= SHISHI_OK
)
704 * shishi_kdcreq_options:
705 * @handle: shishi handle as allocated by shishi_init().
706 * @kdcreq: KDC-REQ variable to get kdc-options field from.
707 * @flags: pointer to output integer with flags.
709 * Extract KDC-Options from KDC-REQ.
711 * Return value: Returns SHISHI_OK iff successful.
714 shishi_kdcreq_options (Shishi
* handle
, Shishi_asn1 kdcreq
, uint32_t * flags
)
716 return shishi_asn1_read_bitstring (handle
, kdcreq
,
717 "req-body.kdc-options", flags
);
721 * shishi_kdcreq_forwardable_p:
722 * @handle: shishi handle as allocated by shishi_init().
723 * @kdcreq: KDC-REQ variable to get kdc-options field from.
725 * Determine if KDC-Option forwardable flag is set.
727 * The FORWARDABLE option indicates that the ticket to be issued is to
728 * have its forwardable flag set. It may only be set on the initial
729 * request, or in a subsequent request if the ticket-granting ticket
730 * on which it is based is also forwardable.
732 * Return value: Returns non-0 iff forwardable flag is set in KDC-REQ.
735 shishi_kdcreq_forwardable_p (Shishi
* handle
, Shishi_asn1 kdcreq
)
737 uint32_t options
= 0;
739 shishi_kdcreq_options (handle
, kdcreq
, &options
);
741 return options
& SHISHI_KDCOPTIONS_FORWARDABLE
;
745 * shishi_kdcreq_forwarded_p:
746 * @handle: shishi handle as allocated by shishi_init().
747 * @kdcreq: KDC-REQ variable to get kdc-options field from.
749 * Determine if KDC-Option forwarded flag is set.
751 * The FORWARDED option is only specified in a request to the
752 * ticket-granting server and will only be honored if the
753 * ticket-granting ticket in the request has its FORWARDABLE bit
754 * set. This option indicates that this is a request for
755 * forwarding. The address(es) of the host from which the resulting
756 * ticket is to be valid are included in the addresses field of the
759 * Return value: Returns non-0 iff forwarded flag is set in KDC-REQ.
762 shishi_kdcreq_forwarded_p (Shishi
* handle
, Shishi_asn1 kdcreq
)
764 uint32_t options
= 0;
766 shishi_kdcreq_options (handle
, kdcreq
, &options
);
768 return options
& SHISHI_KDCOPTIONS_FORWARDED
;
772 * shishi_kdcreq_proxiable_p:
773 * @handle: shishi handle as allocated by shishi_init().
774 * @kdcreq: KDC-REQ variable to get kdc-options field from.
776 * Determine if KDC-Option proxiable flag is set.
778 * The PROXIABLE option indicates that the ticket to be issued is to
779 * have its proxiable flag set. It may only be set on the initial
780 * request, or in a subsequent request if the ticket-granting ticket
781 * on which it is based is also proxiable.
783 * Return value: Returns non-0 iff proxiable flag is set in KDC-REQ.
786 shishi_kdcreq_proxiable_p (Shishi
* handle
, Shishi_asn1 kdcreq
)
788 uint32_t options
= 0;
790 shishi_kdcreq_options (handle
, kdcreq
, &options
);
792 return options
& SHISHI_KDCOPTIONS_PROXIABLE
;
796 * shishi_kdcreq_proxy_p:
797 * @handle: shishi handle as allocated by shishi_init().
798 * @kdcreq: KDC-REQ variable to get kdc-options field from.
800 * Determine if KDC-Option proxy flag is set.
802 * The PROXY option indicates that this is a request for a proxy. This
803 * option will only be honored if the ticket-granting ticket in the
804 * request has its PROXIABLE bit set. The address(es) of the host
805 * from which the resulting ticket is to be valid are included in the
806 * addresses field of the request.
808 * Return value: Returns non-0 iff proxy flag is set in KDC-REQ.
811 shishi_kdcreq_proxy_p (Shishi
* handle
, Shishi_asn1 kdcreq
)
813 uint32_t options
= 0;
815 shishi_kdcreq_options (handle
, kdcreq
, &options
);
817 return options
& SHISHI_KDCOPTIONS_PROXY
;
821 * shishi_kdcreq_allow_postdate_p:
822 * @handle: shishi handle as allocated by shishi_init().
823 * @kdcreq: KDC-REQ variable to get kdc-options field from.
825 * Determine if KDC-Option allow-postdate flag is set.
827 * The ALLOW-POSTDATE option indicates that the ticket to be issued is
828 * to have its MAY-POSTDATE flag set. It may only be set on the
829 * initial request, or in a subsequent request if the ticket-granting
830 * ticket on which it is based also has its MAY-POSTDATE flag set.
832 * Return value: Returns non-0 iff allow-postdate flag is set in KDC-REQ.
835 shishi_kdcreq_allow_postdate_p (Shishi
* handle
, Shishi_asn1 kdcreq
)
837 uint32_t options
= 0;
839 shishi_kdcreq_options (handle
, kdcreq
, &options
);
841 return options
& SHISHI_KDCOPTIONS_ALLOW_POSTDATE
;
845 * shishi_kdcreq_postdated_p:
846 * @handle: shishi handle as allocated by shishi_init().
847 * @kdcreq: KDC-REQ variable to get kdc-options field from.
849 * Determine if KDC-Option postdated flag is set.
851 * The POSTDATED option indicates that this is a request for a
852 * postdated ticket. This option will only be honored if the
853 * ticket-granting ticket on which it is based has its MAY-POSTDATE
854 * flag set. The resulting ticket will also have its INVALID flag set,
855 * and that flag may be reset by a subsequent request to the KDC after
856 * the starttime in the ticket has been reached.
858 * Return value: Returns non-0 iff postdated flag is set in KDC-REQ.
861 shishi_kdcreq_postdated_p (Shishi
* handle
, Shishi_asn1 kdcreq
)
863 uint32_t options
= 0;
865 shishi_kdcreq_options (handle
, kdcreq
, &options
);
867 return options
& SHISHI_KDCOPTIONS_POSTDATED
;
871 * shishi_kdcreq_renewable_p:
872 * @handle: shishi handle as allocated by shishi_init().
873 * @kdcreq: KDC-REQ variable to get kdc-options field from.
875 * Determine if KDC-Option renewable flag is set.
877 * The RENEWABLE option indicates that the ticket to be issued is to
878 * have its RENEWABLE flag set. It may only be set on the initial
879 * request, or when the ticket-granting ticket on which the request is
880 * based is also renewable. If this option is requested, then the
881 * rtime field in the request contains the desired absolute expiration
882 * time for the ticket.
884 * Return value: Returns non-0 iff renewable flag is set in KDC-REQ.
887 shishi_kdcreq_renewable_p (Shishi
* handle
, Shishi_asn1 kdcreq
)
889 uint32_t options
= 0;
891 shishi_kdcreq_options (handle
, kdcreq
, &options
);
893 return options
& SHISHI_KDCOPTIONS_RENEWABLE
;
897 * shishi_kdcreq_disable_transited_check_p:
898 * @handle: shishi handle as allocated by shishi_init().
899 * @kdcreq: KDC-REQ variable to get kdc-options field from.
901 * Determine if KDC-Option disable-transited-check flag is set.
903 * By default the KDC will check the transited field of a
904 * ticket-granting-ticket against the policy of the local realm before
905 * it will issue derivative tickets based on the ticket-granting
906 * ticket. If this flag is set in the request, checking of the
907 * transited field is disabled. Tickets issued without the performance
908 * of this check will be noted by the reset (0) value of the
909 * TRANSITED-POLICY-CHECKED flag, indicating to the application server
910 * that the tranisted field must be checked locally. KDCs are
911 * encouraged but not required to honor the DISABLE-TRANSITED-CHECK
914 * This flag is new since RFC 1510
916 * Return value: Returns non-0 iff disable-transited-check flag is set
920 shishi_kdcreq_disable_transited_check_p (Shishi
* handle
, Shishi_asn1 kdcreq
)
922 uint32_t options
= 0;
924 shishi_kdcreq_options (handle
, kdcreq
, &options
);
926 return options
& SHISHI_KDCOPTIONS_DISABLE_TRANSITED_CHECK
;
930 * shishi_kdcreq_renewable_ok_p:
931 * @handle: shishi handle as allocated by shishi_init().
932 * @kdcreq: KDC-REQ variable to get kdc-options field from.
934 * Determine if KDC-Option renewable-ok flag is set.
936 * The RENEWABLE-OK option indicates that a renewable ticket will be
937 * acceptable if a ticket with the requested life cannot otherwise be
938 * provided. If a ticket with the requested life cannot be provided,
939 * then a renewable ticket may be issued with a renew-till equal to
940 * the requested endtime. The value of the renew-till field may still
941 * be limited by local limits, or limits selected by the individual
942 * principal or server.
944 * Return value: Returns non-0 iff renewable-ok flag is set in KDC-REQ.
947 shishi_kdcreq_renewable_ok_p (Shishi
* handle
, Shishi_asn1 kdcreq
)
949 uint32_t options
= 0;
951 shishi_kdcreq_options (handle
, kdcreq
, &options
);
953 return options
& SHISHI_KDCOPTIONS_RENEWABLE_OK
;
957 * shishi_kdcreq_enc_tkt_in_skey_p:
958 * @handle: shishi handle as allocated by shishi_init().
959 * @kdcreq: KDC-REQ variable to get kdc-options field from.
961 * Determine if KDC-Option enc-tkt-in-skey flag is set.
963 * This option is used only by the ticket-granting service. The
964 * ENC-TKT-IN-SKEY option indicates that the ticket for the end server
965 * is to be encrypted in the session key from the additional
966 * ticket-granting ticket provided.
968 * Return value: Returns non-0 iff enc-tkt-in-skey flag is set in KDC-REQ.
971 shishi_kdcreq_enc_tkt_in_skey_p (Shishi
* handle
, Shishi_asn1 kdcreq
)
973 uint32_t options
= 0;
975 shishi_kdcreq_options (handle
, kdcreq
, &options
);
977 return options
& SHISHI_KDCOPTIONS_ENC_TKT_IN_SKEY
;
981 * shishi_kdcreq_renew_p:
982 * @handle: shishi handle as allocated by shishi_init().
983 * @kdcreq: KDC-REQ variable to get kdc-options field from.
985 * Determine if KDC-Option renew flag is set.
987 * This option is used only by the ticket-granting service. The RENEW
988 * option indicates that the present request is for a renewal. The
989 * ticket provided is encrypted in the secret key for the server on
990 * which it is valid. This option will only be honored if the ticket
991 * to be renewed has its RENEWABLE flag set and if the time in its
992 * renew-till field has not passed. The ticket to be renewed is passed
993 * in the padata field as part of the authentication header.
995 * Return value: Returns non-0 iff renew flag is set in KDC-REQ.
998 shishi_kdcreq_renew_p (Shishi
* handle
, Shishi_asn1 kdcreq
)
1000 uint32_t options
= 0;
1002 shishi_kdcreq_options (handle
, kdcreq
, &options
);
1004 return options
& SHISHI_KDCOPTIONS_RENEW
;
1008 * shishi_kdcreq_validate_p:
1009 * @handle: shishi handle as allocated by shishi_init().
1010 * @kdcreq: KDC-REQ variable to get kdc-options field from.
1012 * Determine if KDC-Option validate flag is set.
1014 * This option is used only by the ticket-granting service. The
1015 * VALIDATE option indicates that the request is to validate a
1016 * postdated ticket. It will only be honored if the ticket presented
1017 * is postdated, presently has its INVALID flag set, and would be
1018 * otherwise usable at this time. A ticket cannot be validated before
1019 * its starttime. The ticket presented for validation is encrypted in
1020 * the key of the server for which it is valid and is passed in the
1021 * padata field as part of the authentication header.
1023 * Return value: Returns non-0 iff validate flag is set in KDC-REQ.
1026 shishi_kdcreq_validate_p (Shishi
* handle
, Shishi_asn1 kdcreq
)
1028 uint32_t options
= 0;
1030 shishi_kdcreq_options (handle
, kdcreq
, &options
);
1032 return options
& SHISHI_KDCOPTIONS_VALIDATE
;
1036 * shishi_kdcreq_options_set:
1037 * @handle: shishi handle as allocated by shishi_init().
1038 * @kdcreq: KDC-REQ variable to set etype field in.
1039 * @options: integer with flags to store in KDC-REQ.
1041 * Set options in KDC-REQ. Note that this reset any already existing
1044 * Return value: Returns SHISHI_OK iff successful.
1047 shishi_kdcreq_options_set (Shishi
* handle
,
1048 Shishi_asn1 kdcreq
, uint32_t options
)
1052 res
= shishi_asn1_write_bitstring (handle
, kdcreq
,
1053 "req-body.kdc-options", options
);
1054 if (res
!= SHISHI_OK
)
1061 * shishi_kdcreq_options_add:
1062 * @handle: shishi handle as allocated by shishi_init().
1063 * @kdcreq: KDC-REQ variable to set etype field in.
1064 * @option: integer with options to add in KDC-REQ.
1066 * Add KDC-Option to KDC-REQ. This preserves all existing options.
1068 * Return value: Returns SHISHI_OK iff successful.
1071 shishi_kdcreq_options_add (Shishi
* handle
,
1072 Shishi_asn1 kdcreq
, uint32_t option
)
1077 res
= shishi_kdcreq_options (handle
, kdcreq
, &options
);
1078 if (res
!= SHISHI_OK
)
1083 res
= shishi_kdcreq_options_set (handle
, kdcreq
, options
);
1084 if (res
!= SHISHI_OK
)
1091 * shishi_kdcreq_clear_padata:
1092 * @handle: shishi handle as allocated by shishi_init().
1093 * @kdcreq: KDC-REQ to remove PA-DATA from.
1095 * Remove the padata field from KDC-REQ.
1097 * Return value: Returns SHISHI_OK iff successful.
1100 shishi_kdcreq_clear_padata (Shishi
* handle
, Shishi_asn1 kdcreq
)
1104 res
= shishi_asn1_write (handle
, kdcreq
, "padata", NULL
, 0);
1105 if (res
!= SHISHI_OK
)
1112 * shishi_kdcreq_get_padata:
1113 * @handle: shishi handle as allocated by shishi_init().
1114 * @kdcreq: KDC-REQ to get PA-DATA from.
1115 * @padatatype: type of PA-DATA, see Shishi_padata_type.
1116 * @out: output array with newly allocated PA-DATA value.
1117 * @outlen: size of output array with PA-DATA value.
1119 * Get pre authentication data (PA-DATA) from KDC-REQ. Pre
1120 * authentication data is used to pass various information to KDC,
1121 * such as in case of a SHISHI_PA_TGS_REQ padatatype the AP-REQ that
1122 * authenticates the user to get the ticket.
1124 * Return value: Returns SHISHI_OK iff successful.
1127 shishi_kdcreq_get_padata (Shishi
* handle
,
1129 Shishi_padata_type padatatype
,
1130 char **out
, size_t * outlen
)
1136 res
= shishi_asn1_number_of_elements (handle
, kdcreq
, "padata", &n
);
1137 if (res
!= SHISHI_OK
)
1143 for (i
= 1; i
<= n
; i
++)
1147 asprintf (&format
, "padata.?%d.padata-type", i
);
1148 res
= shishi_asn1_read_int32 (handle
, kdcreq
, format
, &patype
);
1150 if (res
!= SHISHI_OK
)
1153 if (patype
== (int32_t) padatatype
)
1155 asprintf (&format
, "padata.?%d.padata-value", i
);
1156 res
= shishi_asn1_read (handle
, kdcreq
, format
, out
, outlen
);
1158 if (res
!= SHISHI_OK
)
1168 * shishi_kdcreq_get_padata_tgs:
1169 * @handle: shishi handle as allocated by shishi_init().
1170 * @kdcreq: KDC-REQ to get PA-TGS-REQ from.
1171 * @apreq: Output variable with newly allocated AP-REQ.
1173 * Extract TGS pre-authentication data from KDC-REQ. The data is an
1174 * AP-REQ that authenticates the request. This function call
1175 * shishi_kdcreq_get_padata() with a SHISHI_PA_TGS_REQ padatatype and
1176 * DER decode the result (if any).
1178 * Return value: Returns SHISHI_OK iff successful.
1181 shishi_kdcreq_get_padata_tgs (Shishi
* handle
,
1182 Shishi_asn1 kdcreq
, Shishi_asn1
* apreq
)
1188 if (VERBOSE (handle
))
1189 printf ("Extracting AP-REQ from KDC-REQ...\n");
1191 rc
= shishi_kdcreq_get_padata (handle
, kdcreq
, SHISHI_PA_TGS_REQ
,
1193 if (rc
!= SHISHI_OK
)
1196 *apreq
= shishi_der2asn1_apreq (handle
, der
, derlen
);
1198 return SHISHI_ASN1_ERROR
;
1200 if (VERBOSEASN1 (handle
))
1201 shishi_apreq_print (handle
, stdout
, *apreq
);
1207 * shishi_kdcreq_add_padata:
1208 * @handle: shishi handle as allocated by shishi_init().
1209 * @kdcreq: KDC-REQ to add PA-DATA to.
1210 * @padatatype: type of PA-DATA, see Shishi_padata_type.
1211 * @data: input array with PA-DATA value.
1212 * @datalen: size of input array with PA-DATA value.
1214 * Add new pre authentication data (PA-DATA) to KDC-REQ. This is used
1215 * to pass various information to KDC, such as in case of a
1216 * SHISHI_PA_TGS_REQ padatatype the AP-REQ that authenticates the user
1217 * to get the ticket. (But also see shishi_kdcreq_add_padata_tgs()
1218 * which takes an AP-REQ directly.)
1220 * Return value: Returns SHISHI_OK iff successful.
1223 shishi_kdcreq_add_padata (Shishi
* handle
,
1225 int padatatype
, const char *data
, size_t datalen
)
1231 res
= shishi_asn1_write (handle
, kdcreq
, "padata", "NEW", 1);
1232 if (res
!= SHISHI_OK
)
1235 res
= shishi_asn1_number_of_elements (handle
, kdcreq
, "padata", &i
);
1236 if (res
!= SHISHI_OK
)
1239 asprintf (&format
, "padata.?%d.padata-value", i
);
1240 res
= shishi_asn1_write (handle
, kdcreq
, format
, data
, datalen
);
1242 if (res
!= SHISHI_OK
)
1245 asprintf (&format
, "padata.?%d.padata-type", i
);
1246 res
= shishi_asn1_write_uint32 (handle
, kdcreq
, format
, padatatype
);
1248 if (res
!= SHISHI_OK
)
1255 * shishi_kdcreq_add_padata_tgs:
1256 * @handle: shishi handle as allocated by shishi_init().
1257 * @kdcreq: KDC-REQ to add PA-DATA to.
1258 * @apreq: AP-REQ to add as PA-DATA.
1260 * Add TGS pre-authentication data to KDC-REQ. The data is an AP-REQ
1261 * that authenticates the request. This functions simply DER encodes
1262 * the AP-REQ and calls shishi_kdcreq_add_padata() with a
1263 * SHISHI_PA_TGS_REQ padatatype.
1265 * Return value: Returns SHISHI_OK iff successful.
1268 shishi_kdcreq_add_padata_tgs (Shishi
* handle
,
1269 Shishi_asn1 kdcreq
, Shishi_asn1 apreq
)
1275 res
= shishi_asn1_to_der (handle
, apreq
, &data
, &datalen
);
1276 if (res
!= SHISHI_OK
)
1278 shishi_error_printf (handle
, "Could not DER encode AP-REQ: %s\n",
1279 shishi_strerror (res
));
1283 res
= shishi_kdcreq_add_padata (handle
, kdcreq
,
1284 SHISHI_PA_TGS_REQ
, data
, datalen
);
1286 if (res
!= SHISHI_OK
)
1293 * shishi_kdcreq_add_padata_preauth:
1294 * @handle: shishi handle as allocated by shishi_init().
1295 * @kdcreq: KDC-REQ to add pre-authentication data to.
1296 * @key: Key used to encrypt pre-auth data.
1298 * Add pre-authentication data to KDC-REQ.
1300 * Return value: Returns SHISHI_OK iff successful.
1303 shishi_kdcreq_add_padata_preauth (Shishi
* handle
,
1308 size_t derlen
, datalen
;
1314 pa
= shishi_asn1_pa_enc_ts_enc (handle
);
1316 return SHISHI_ASN1_ERROR
;
1320 rc
= shishi_asn1_write (handle
, pa
, "patimestamp",
1321 shishi_generalize_time (handle
, ts
.tv_sec
),
1322 SHISHI_GENERALIZEDTIME_LENGTH
);
1323 if (rc
!= SHISHI_OK
)
1326 rc
= shishi_asn1_write_integer (handle
, pa
, "pausec", ts
.tv_nsec
/ 1000);
1327 if (rc
!= SHISHI_OK
)
1330 rc
= shishi_asn1_to_der (handle
, pa
, &der
, &derlen
);
1331 if (rc
!= SHISHI_OK
)
1334 rc
= shishi_encrypt (handle
, key
, SHISHI_KEYUSAGE_ASREQ_PA_ENC_TIMESTAMP
,
1335 der
, derlen
, &data
, &datalen
);
1337 if (rc
!= SHISHI_OK
)
1340 ed
= shishi_asn1_encrypteddata (handle
);
1342 return SHISHI_ASN1_ERROR
;
1344 rc
= shishi_asn1_write_integer (handle
, ed
, "etype", shishi_key_type (key
));
1345 if (rc
!= SHISHI_OK
)
1348 rc
= shishi_asn1_write (handle
, ed
, "cipher", data
, datalen
);
1349 if (rc
!= SHISHI_OK
)
1352 rc
= shishi_asn1_write (handle
, ed
, "kvno", NULL
, 0);
1353 if (rc
!= SHISHI_OK
)
1356 rc
= shishi_asn1_to_der (handle
, ed
, &der
, &derlen
);
1358 if (rc
!= SHISHI_OK
)
1361 rc
= shishi_kdcreq_add_padata (handle
, kdcreq
, SHISHI_PA_ENC_TIMESTAMP
,
1364 if (rc
!= SHISHI_OK
)
1371 shishi_kdcreq_build (Shishi
* handle
, Shishi_asn1 kdcreq
)
1377 shishi_verbose (handle
, "Building KDC-REQ...");
1379 if (shishi_asn1_empty_p (handle
, kdcreq
, "req-body.rtime"))
1381 res
= shishi_asn1_write (handle
, kdcreq
, "req-body.rtime", NULL
, 0);
1382 if (res
!= SHISHI_OK
)
1384 shishi_error_printf (handle
, "Could not write rtime\n");
1389 if (shishi_asn1_empty_p (handle
, kdcreq
, "req-body.from"))
1391 res
= shishi_asn1_write (handle
, kdcreq
, "req-body.from", NULL
, 0);
1392 if (res
!= SHISHI_OK
)
1394 shishi_error_printf (handle
, "Could not write from\n");
1399 res
= shishi_asn1_read_integer (handle
, kdcreq
, "msg-type", &msgtype
);
1400 if (res
!= SHISHI_OK
)
1402 if (msgtype
== SHISHI_MSGTYPE_AS_REQ
)
1404 res
= shishi_asn1_number_of_elements (handle
, kdcreq
, "padata", &n
);
1405 if (res
== SHISHI_OK
&& n
== 0)
1407 res
= shishi_kdcreq_clear_padata (handle
, kdcreq
);
1408 if (res
!= SHISHI_OK
)
1410 shishi_error_printf (handle
, "Could not write padata\n");