Add.
[shishi.git] / lib / kdcreq.c
blob189a53dde00726f218f0ec384ca260d3700f02cf
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
23 #include "internal.h"
25 /* Get _shishi_print_armored_data, etc. */
26 #include "diskio.h"
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
41 static Shishi_asn1
42 _shishi_kdcreq (Shishi * handle, int as)
44 int res;
45 Shishi_asn1 node;
46 const char *servicebuf[3];
47 uint32_t nonce;
49 if (as)
50 node = shishi_asn1_asreq (handle);
51 else
52 node = shishi_asn1_tgsreq (handle);
53 if (!node)
54 return NULL;
56 res = shishi_asn1_write (handle, node, "pvno",
57 SHISHI_KDCREQ_DEFAULT_PVNO,
58 SHISHI_KDCREQ_DEFAULT_PVNO_LEN);
59 if (res != SHISHI_OK)
60 goto error;
62 if (as)
63 res = shishi_asn1_write (handle, node, "msg-type",
64 SHISHI_AS_REQ_DEFAULT_MSG_TYPE,
65 SHISHI_AS_REQ_DEFAULT_MSG_TYPE_LEN);
66 else
67 res = shishi_asn1_write (handle, node, "msg-type",
68 SHISHI_TGS_REQ_DEFAULT_MSG_TYPE,
69 SHISHI_TGS_REQ_DEFAULT_MSG_TYPE_LEN);
70 if (res != SHISHI_OK)
71 goto error;
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);
76 if (res != SHISHI_OK)
77 goto error;
79 if (as)
80 res = shishi_kdcreq_set_cname (handle, node, SHISHI_NT_PRINCIPAL,
81 shishi_principal_default (handle));
82 else
83 res = shishi_asn1_write (handle, node, "req-body.cname", NULL, 0);
84 if (res != SHISHI_OK)
85 goto error;
87 res = shishi_kdcreq_set_realm (handle, node, shishi_realm_default (handle));
88 if (res != SHISHI_OK)
89 goto error;
91 servicebuf[0] = "krbtgt";
92 servicebuf[1] = shishi_realm_default (handle);
93 servicebuf[2] = NULL;
94 res = shishi_kdcreq_set_sname (handle, node,
95 SHISHI_NT_PRINCIPAL, servicebuf);
96 if (res != SHISHI_OK)
97 goto error;
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)
103 goto error;
105 res = shishi_asn1_write (handle, node, "req-body.till",
106 shishi_generalize_time (handle,
107 time (NULL) +
108 handle->ticketlife), 0);
109 if (res != SHISHI_OK)
110 goto error;
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)
116 goto error;
118 res = shishi_kdcreq_set_etype (handle, node, handle->clientkdcetypes,
119 handle->nclientkdcetypes);
120 if (res != SHISHI_OK)
121 goto error;
123 res = shishi_asn1_write (handle, node, "req-body.addresses", NULL, 0);
124 if (res != SHISHI_OK)
125 goto error;
127 res = shishi_asn1_write (handle, node,
128 "req-body.enc-authorization-data", NULL, 0);
129 if (res != SHISHI_OK)
130 goto error;
132 res =
133 shishi_asn1_write (handle, node, "req-body.additional-tickets", NULL, 0);
134 if (res != SHISHI_OK)
135 goto error;
137 return node;
139 error:
140 shishi_asn1_done (handle, node);
141 return NULL;
145 * shishi_asreq:
146 * @handle: shishi handle as allocated by shishi_init().
148 * This function creates a new AS-REQ, populated with some default
149 * values.
151 * Return value: Returns the AS-REQ or NULL on failure.
153 Shishi_asn1
154 shishi_asreq (Shishi * handle)
156 return _shishi_kdcreq (handle, 1);
160 * shishi_tgsreq:
161 * @handle: shishi handle as allocated by shishi_init().
163 * This function creates a new TGS-REQ, populated with some default
164 * values.
166 * Return value: Returns the TGS-REQ or NULL on failure.
168 Shishi_asn1
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
215 * if it exists.
217 * Return value: Returns SHISHI_OK iff successful.
220 shishi_kdcreq_to_file (Shishi * handle, Shishi_asn1 kdcreq,
221 int filetype, const char *filename)
223 FILE *fh;
224 int res;
226 if (VERBOSE (handle))
227 printf (_("Writing KDC-REQ to %s...\n"), filename);
229 fh = fopen (filename, "w");
230 if (fh == NULL)
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);
239 else
240 res = shishi_kdcreq_save (handle, fh, kdcreq);
241 if (res != SHISHI_OK)
242 return res;
244 res = fclose (fh);
245 if (res != 0)
246 return SHISHI_IO_ERROR;
248 if (VERBOSE (handle))
249 printf (_("Writing KDC-REQ to %s...done\n"), filename);
251 return SHISHI_OK;
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
261 * variable.
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)
303 int res;
304 FILE *fh;
306 if (VERBOSE (handle))
307 printf (_("Reading KDC-REQ from %s...\n"), filename);
309 fh = fopen (filename, "r");
310 if (fh == NULL)
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);
319 else
320 res = shishi_kdcreq_read (handle, fh, kdcreq);
321 if (res != SHISHI_OK)
322 return res;
324 res = fclose (fh);
325 if (res != 0)
326 return SHISHI_IO_ERROR;
328 if (VERBOSE (handle))
329 printf (_("Reading KDC-REQ from %s...done\n"), filename);
331 return SHISHI_OK;
335 shishi_kdcreq_nonce (Shishi * handle, Shishi_asn1 kdcreq, uint32_t * nonce)
337 int res;
339 res = shishi_asn1_read_uint32 (handle, kdcreq, "req-body.nonce", nonce);
340 if (res != SHISHI_OK)
341 return res;
343 return 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)
359 int res;
361 res = shishi_asn1_write_uint32 (handle, kdcreq, "req-body.nonce", nonce);
362 if (res != SHISHI_OK)
363 return res;
365 return 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
373 * SHISHI_NT_UNKNOWN.
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,
382 Shishi_asn1 kdcreq,
383 Shishi_name_type name_type, const char *principal)
385 int res;
387 res = shishi_principal_set (handle, kdcreq, "req-body.cname", principal);
388 if (res != SHISHI_OK)
389 return res;
391 return 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",
415 client, clientlen);
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,
436 Shishi_asn1 asreq,
437 char **client, size_t * clientlen)
439 return shishi_principal_name_realm (handle,
440 asreq, "req-body.cname",
441 asreq, "req-body.realm",
442 client, clientlen);
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",
466 realm, realmlen);
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",
474 realm, realmlen);
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,
489 const char *realm)
491 int res;
493 res = shishi_asn1_write (handle, kdcreq, "req-body.realm", realm, 0);
494 if (res != SHISHI_OK)
495 return res;
497 return 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",
521 server, serverlen);
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
529 * SHISHI_NT_UNKNOWN.
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,
538 Shishi_asn1 kdcreq,
539 Shishi_name_type name_type, const char *sname[])
541 int res;
543 res = shishi_principal_name_set (handle, kdcreq, "req-body.sname",
544 name_type, sname);
545 if (res != SHISHI_OK)
546 return res;
548 return SHISHI_OK;
552 shishi_kdcreq_set_server (Shishi * handle, Shishi_asn1 req,
553 const char *server)
555 int res;
557 res = shishi_principal_set (handle, req, "req-body.sname", server);
558 if (res != SHISHI_OK)
559 return res;
561 return SHISHI_OK;
565 shishi_kdcreq_set_realmserver (Shishi * handle,
566 Shishi_asn1 req, char *realm, char *server)
568 int res;
570 res = shishi_kdcreq_set_realm (handle, req, realm);
571 if (res != SHISHI_OK)
572 return res;
574 res = shishi_kdcreq_set_server (handle, req, server);
575 if (res != SHISHI_OK)
576 return res;
578 return 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
614 * KDC-REQ.
616 time_t
617 shishi_kdcreq_tillc (Shishi * handle, Shishi_asn1 kdcreq)
619 char *till;
620 size_t tilllen;
621 time_t t = (time_t) - 1;
622 int res;
624 res = shishi_kdcreq_till (handle, kdcreq, &till, &tilllen);
625 if (res != SHISHI_OK)
626 return t;
628 if (tilllen == SHISHI_GENERALIZEDTIME_LENGTH + 1) /* XXX why +1 ? */
629 t = shishi_generalize_ctime (handle, till);
631 free (till);
633 return t;
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
644 * is number 1.
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)
652 char *buf;
653 int res;
655 asprintf (&buf, "req-body.etype.?%d", netype);
656 res = shishi_asn1_read_int32 (handle, kdcreq, buf, etype);
657 if (res != SHISHI_OK)
658 return res;
660 return 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)
679 int res;
680 char *buf;
681 int i;
683 res = shishi_asn1_write (handle, kdcreq, "req-body.etype", NULL, 0);
684 if (res != SHISHI_OK)
685 return res;
687 for (i = 1; i <= netype; i++)
689 res = shishi_asn1_write (handle, kdcreq, "req-body.etype", "NEW", 1);
690 if (res != SHISHI_OK)
691 return res;
693 asprintf (&buf, "req-body.etype.?%d", i);
694 res = shishi_asn1_write_int32 (handle, kdcreq, buf, etype[i - 1]);
695 free (buf);
696 if (res != SHISHI_OK)
697 return res;
700 return 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
757 * request.
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
912 * option.
914 * This flag is new since RFC 1510
916 * Return value: Returns non-0 iff disable-transited-check flag is set
917 * in KDC-REQ.
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
1042 * flags.
1044 * Return value: Returns SHISHI_OK iff successful.
1047 shishi_kdcreq_options_set (Shishi * handle,
1048 Shishi_asn1 kdcreq, uint32_t options)
1050 int res;
1052 res = shishi_asn1_write_bitstring (handle, kdcreq,
1053 "req-body.kdc-options", options);
1054 if (res != SHISHI_OK)
1055 return res;
1057 return 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)
1074 uint32_t options;
1075 int res;
1077 res = shishi_kdcreq_options (handle, kdcreq, &options);
1078 if (res != SHISHI_OK)
1079 return res;
1081 options |= option;
1083 res = shishi_kdcreq_options_set (handle, kdcreq, options);
1084 if (res != SHISHI_OK)
1085 return res;
1087 return 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)
1102 int res;
1104 res = shishi_asn1_write (handle, kdcreq, "padata", NULL, 0);
1105 if (res != SHISHI_OK)
1106 return res;
1108 return 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,
1128 Shishi_asn1 kdcreq,
1129 Shishi_padata_type padatatype,
1130 char **out, size_t * outlen)
1132 char *format;
1133 int res;
1134 size_t i, n;
1136 res = shishi_asn1_number_of_elements (handle, kdcreq, "padata", &n);
1137 if (res != SHISHI_OK)
1138 return res;
1140 *out = NULL;
1141 *outlen = 0;
1143 for (i = 1; i <= n; i++)
1145 int32_t patype;
1147 asprintf (&format, "padata.?%d.padata-type", i);
1148 res = shishi_asn1_read_int32 (handle, kdcreq, format, &patype);
1149 free (format);
1150 if (res != SHISHI_OK)
1151 return res;
1153 if (patype == (int32_t) padatatype)
1155 asprintf (&format, "padata.?%d.padata-value", i);
1156 res = shishi_asn1_read (handle, kdcreq, format, out, outlen);
1157 free (format);
1158 if (res != SHISHI_OK)
1159 return res;
1160 break;
1164 return 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)
1184 char *der;
1185 size_t derlen;
1186 int rc;
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,
1192 &der, &derlen);
1193 if (rc != SHISHI_OK)
1194 return rc;
1196 *apreq = shishi_der2asn1_apreq (handle, der, derlen);
1197 if (!*apreq)
1198 return SHISHI_ASN1_ERROR;
1200 if (VERBOSEASN1 (handle))
1201 shishi_apreq_print (handle, stdout, *apreq);
1203 return SHISHI_OK;
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,
1224 Shishi_asn1 kdcreq,
1225 int padatatype, const char *data, size_t datalen)
1227 char *format;
1228 int res;
1229 size_t i;
1231 res = shishi_asn1_write (handle, kdcreq, "padata", "NEW", 1);
1232 if (res != SHISHI_OK)
1233 return res;
1235 res = shishi_asn1_number_of_elements (handle, kdcreq, "padata", &i);
1236 if (res != SHISHI_OK)
1237 return res;
1239 asprintf (&format, "padata.?%d.padata-value", i);
1240 res = shishi_asn1_write (handle, kdcreq, format, data, datalen);
1241 free (format);
1242 if (res != SHISHI_OK)
1243 return res;
1245 asprintf (&format, "padata.?%d.padata-type", i);
1246 res = shishi_asn1_write_uint32 (handle, kdcreq, format, padatatype);
1247 free (format);
1248 if (res != SHISHI_OK)
1249 return res;
1251 return 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)
1271 int res;
1272 char *data;
1273 size_t datalen;
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));
1280 return res;
1283 res = shishi_kdcreq_add_padata (handle, kdcreq,
1284 SHISHI_PA_TGS_REQ, data, datalen);
1285 free (data);
1286 if (res != SHISHI_OK)
1287 return res;
1289 return res;
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,
1304 Shishi_asn1 kdcreq,
1305 Shishi_key *key)
1307 char *der, *data;
1308 size_t derlen, datalen;
1309 Shishi_asn1 pa;
1310 struct timespec ts;
1311 int rc;
1312 Shishi_asn1 ed;
1314 pa = shishi_asn1_pa_enc_ts_enc (handle);
1315 if (!pa)
1316 return SHISHI_ASN1_ERROR;
1318 gettime (&ts);
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)
1324 return rc;
1326 rc = shishi_asn1_write_integer (handle, pa, "pausec", ts.tv_nsec / 1000);
1327 if (rc != SHISHI_OK)
1328 return rc;
1330 rc = shishi_asn1_to_der (handle, pa, &der, &derlen);
1331 if (rc != SHISHI_OK)
1332 return rc;
1334 rc = shishi_encrypt (handle, key, SHISHI_KEYUSAGE_ASREQ_PA_ENC_TIMESTAMP,
1335 der, derlen, &data, &datalen);
1336 free (der);
1337 if (rc != SHISHI_OK)
1338 return rc;
1340 ed = shishi_asn1_encrypteddata (handle);
1341 if (!ed)
1342 return SHISHI_ASN1_ERROR;
1344 rc = shishi_asn1_write_integer (handle, ed, "etype", shishi_key_type (key));
1345 if (rc != SHISHI_OK)
1346 return rc;
1348 rc = shishi_asn1_write (handle, ed, "cipher", data, datalen);
1349 if (rc != SHISHI_OK)
1350 return rc;
1352 rc = shishi_asn1_write (handle, ed, "kvno", NULL, 0);
1353 if (rc != SHISHI_OK)
1354 return rc;
1356 rc = shishi_asn1_to_der (handle, ed, &der, &derlen);
1357 free (data);
1358 if (rc != SHISHI_OK)
1359 return rc;
1361 rc = shishi_kdcreq_add_padata (handle, kdcreq, SHISHI_PA_ENC_TIMESTAMP,
1362 der, derlen);
1363 free (der);
1364 if (rc != SHISHI_OK)
1365 return rc;
1367 return rc;
1371 shishi_kdcreq_build (Shishi * handle, Shishi_asn1 kdcreq)
1373 int res;
1374 size_t n;
1375 int msgtype;
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");
1385 return res;
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");
1395 return res;
1399 res = shishi_asn1_read_integer (handle, kdcreq, "msg-type", &msgtype);
1400 if (res != SHISHI_OK)
1401 return res;
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");
1411 return res;
1416 return SHISHI_OK;