Branch data Line data Source code
1 : : /* kdcreq.c --- Key distribution (AS/TGS) request functions.
2 : : * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 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 : : /* Get _shishi_print_armored_data, etc. */
26 : : #include "diskio.h"
27 : :
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 : :
39 : : static Shishi_asn1
40 : 0 : _shishi_kdcreq (Shishi * handle, int as)
41 : : {
42 : : int res;
43 : : Shishi_asn1 node;
44 : : const char *servicebuf[3];
45 : : uint32_t nonce;
46 : :
47 [ # # ]: 0 : if (as)
48 : 0 : node = shishi_asn1_asreq (handle);
49 : : else
50 : 0 : node = shishi_asn1_tgsreq (handle);
51 [ # # ]: 0 : if (!node)
52 : 0 : return NULL;
53 : :
54 : 0 : res = shishi_asn1_write (handle, node, "pvno",
55 : : SHISHI_KDCREQ_DEFAULT_PVNO,
56 : : SHISHI_KDCREQ_DEFAULT_PVNO_LEN);
57 [ # # ]: 0 : if (res != SHISHI_OK)
58 : 0 : goto error;
59 : :
60 [ # # ]: 0 : if (as)
61 : 0 : res = shishi_asn1_write (handle, node, "msg-type",
62 : : SHISHI_AS_REQ_DEFAULT_MSG_TYPE,
63 : : SHISHI_AS_REQ_DEFAULT_MSG_TYPE_LEN);
64 : : else
65 : 0 : res = shishi_asn1_write (handle, node, "msg-type",
66 : : SHISHI_TGS_REQ_DEFAULT_MSG_TYPE,
67 : : SHISHI_TGS_REQ_DEFAULT_MSG_TYPE_LEN);
68 [ # # ]: 0 : if (res != SHISHI_OK)
69 : 0 : goto error;
70 : :
71 : 0 : res = shishi_asn1_write (handle, node, "req-body.kdc-options",
72 : : SHISHI_KDCREQ_DEFAULT_REQ_BODY_KDC_OPTIONS,
73 : : SHISHI_KDCREQ_DEFAULT_REQ_BODY_KDC_OPTIONS_LEN);
74 [ # # ]: 0 : if (res != SHISHI_OK)
75 : 0 : goto error;
76 : :
77 [ # # ]: 0 : if (as)
78 : 0 : res = shishi_kdcreq_set_cname (handle, node, SHISHI_NT_PRINCIPAL,
79 : : shishi_principal_default (handle));
80 : : else
81 : 0 : res = shishi_asn1_write (handle, node, "req-body.cname", NULL, 0);
82 [ # # ]: 0 : if (res != SHISHI_OK)
83 : 0 : goto error;
84 : :
85 : 0 : res = shishi_kdcreq_set_realm (handle, node, shishi_realm_default (handle));
86 [ # # ]: 0 : if (res != SHISHI_OK)
87 : 0 : goto error;
88 : :
89 : 0 : servicebuf[0] = "krbtgt";
90 : 0 : servicebuf[1] = shishi_realm_default (handle);
91 : 0 : servicebuf[2] = NULL;
92 : 0 : res = shishi_kdcreq_set_sname (handle, node,
93 : : SHISHI_NT_PRINCIPAL, servicebuf);
94 [ # # ]: 0 : if (res != SHISHI_OK)
95 : 0 : goto error;
96 : :
97 : 0 : res = shishi_asn1_write (handle, node, "req-body.sname.name-type",
98 : : SHISHI_KDCREQ_DEFAULT_REQ_BODY_SNAME_NAME_TYPE,
99 : : SHISHI_KDCREQ_DEFAULT_REQ_BODY_SNAME_NAME_TYPE_LEN);
100 [ # # ]: 0 : if (res != SHISHI_OK)
101 : 0 : goto error;
102 : :
103 : 0 : res = shishi_asn1_write (handle, node, "req-body.till",
104 : : shishi_generalize_time (handle,
105 : : time (NULL) +
106 : : handle->ticketlife), 0);
107 [ # # ]: 0 : if (res != SHISHI_OK)
108 : 0 : goto error;
109 : :
110 : 0 : shishi_randomize (handle, 0, &nonce, sizeof (nonce));
111 : 0 : nonce &= 0x7FFFFFFF; /* XXX fix _libtasn1_convert_integer. */
112 : 0 : res = shishi_kdcreq_nonce_set (handle, node, nonce);
113 [ # # ]: 0 : if (res != SHISHI_OK)
114 : 0 : goto error;
115 : :
116 : 0 : res = shishi_kdcreq_set_etype (handle, node, handle->clientkdcetypes,
117 : 0 : handle->nclientkdcetypes);
118 [ # # ]: 0 : if (res != SHISHI_OK)
119 : 0 : goto error;
120 : :
121 : 0 : res = shishi_asn1_write (handle, node, "req-body.addresses", NULL, 0);
122 [ # # ]: 0 : if (res != SHISHI_OK)
123 : 0 : goto error;
124 : :
125 : 0 : res = shishi_asn1_write (handle, node,
126 : : "req-body.enc-authorization-data", NULL, 0);
127 [ # # ]: 0 : if (res != SHISHI_OK)
128 : 0 : goto error;
129 : :
130 : 0 : res =
131 : 0 : shishi_asn1_write (handle, node, "req-body.additional-tickets", NULL, 0);
132 [ # # ]: 0 : if (res != SHISHI_OK)
133 : 0 : goto error;
134 : :
135 : 0 : return node;
136 : :
137 : : error:
138 : 0 : shishi_asn1_done (handle, node);
139 : 0 : return NULL;
140 : : }
141 : :
142 : : /**
143 : : * shishi_asreq:
144 : : * @handle: shishi handle as allocated by shishi_init().
145 : : *
146 : : * This function creates a new AS-REQ, populated with some default
147 : : * values.
148 : : *
149 : : * Return value: Returns the AS-REQ or NULL on failure.
150 : : **/
151 : : Shishi_asn1
152 : 0 : shishi_asreq (Shishi * handle)
153 : : {
154 : 0 : return _shishi_kdcreq (handle, 1);
155 : : }
156 : :
157 : : /**
158 : : * shishi_tgsreq:
159 : : * @handle: shishi handle as allocated by shishi_init().
160 : : *
161 : : * This function creates a new TGS-REQ, populated with some default
162 : : * values.
163 : : *
164 : : * Return value: Returns the TGS-REQ or NULL on failure.
165 : : **/
166 : : Shishi_asn1
167 : 0 : shishi_tgsreq (Shishi * handle)
168 : : {
169 : 0 : return _shishi_kdcreq (handle, 0);
170 : : }
171 : :
172 : : /**
173 : : * shishi_kdcreq_print:
174 : : * @handle: shishi handle as allocated by shishi_init().
175 : : * @fh: file handle open for writing.
176 : : * @kdcreq: KDC-REQ to print.
177 : : *
178 : : * Print ASCII armored DER encoding of KDC-REQ to file.
179 : : *
180 : : * Return value: Returns SHISHI_OK iff successful.
181 : : **/
182 : : int
183 : 0 : shishi_kdcreq_print (Shishi * handle, FILE * fh, Shishi_asn1 kdcreq)
184 : : {
185 : 0 : return _shishi_print_armored_data (handle, fh, kdcreq, "KDC-REQ", NULL);
186 : : }
187 : :
188 : : /**
189 : : * shishi_kdcreq_save:
190 : : * @handle: shishi handle as allocated by shishi_init().
191 : : * @fh: file handle open for writing.
192 : : * @kdcreq: KDC-REQ to save.
193 : : *
194 : : * Print DER encoding of KDC-REQ to file.
195 : : *
196 : : * Return value: Returns SHISHI_OK iff successful.
197 : : **/
198 : : int
199 : 0 : shishi_kdcreq_save (Shishi * handle, FILE * fh, Shishi_asn1 kdcreq)
200 : : {
201 : 0 : return _shishi_save_data (handle, fh, kdcreq, "KDC-REQ");
202 : : }
203 : :
204 : : /**
205 : : * shishi_kdcreq_to_file:
206 : : * @handle: shishi handle as allocated by shishi_init().
207 : : * @kdcreq: KDC-REQ to save.
208 : : * @filetype: input variable specifying type of file to be written,
209 : : * see Shishi_filetype.
210 : : * @filename: input variable with filename to write to.
211 : : *
212 : : * Write KDC-REQ to file in specified TYPE. The file will be truncated
213 : : * if it exists.
214 : : *
215 : : * Return value: Returns SHISHI_OK iff successful.
216 : : **/
217 : : int
218 : 0 : shishi_kdcreq_to_file (Shishi * handle, Shishi_asn1 kdcreq,
219 : : int filetype, const char *filename)
220 : : {
221 : : FILE *fh;
222 : : int res;
223 : :
224 [ # # ]: 0 : if (VERBOSE (handle))
225 : 0 : printf (_("Writing KDC-REQ to %s...\n"), filename);
226 : :
227 : 0 : fh = fopen (filename, "w");
228 [ # # ]: 0 : if (fh == NULL)
229 : 0 : return SHISHI_FOPEN_ERROR;
230 : :
231 [ # # ]: 0 : if (VERBOSE (handle))
232 [ # # ]: 0 : printf (_("Writing KDC-REQ in %s format...\n"),
233 : : filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
234 : :
235 [ # # ]: 0 : if (filetype == SHISHI_FILETYPE_TEXT)
236 : 0 : res = shishi_kdcreq_print (handle, fh, kdcreq);
237 : : else
238 : 0 : res = shishi_kdcreq_save (handle, fh, kdcreq);
239 [ # # ]: 0 : if (res != SHISHI_OK)
240 : 0 : return res;
241 : :
242 : 0 : res = fclose (fh);
243 [ # # ]: 0 : if (res != 0)
244 : 0 : return SHISHI_IO_ERROR;
245 : :
246 [ # # ]: 0 : if (VERBOSE (handle))
247 : 0 : printf (_("Writing KDC-REQ to %s...done\n"), filename);
248 : :
249 : 0 : return SHISHI_OK;
250 : : }
251 : :
252 : : /**
253 : : * shishi_kdcreq_parse:
254 : : * @handle: shishi handle as allocated by shishi_init().
255 : : * @fh: file handle open for reading.
256 : : * @kdcreq: output variable with newly allocated KDC-REQ.
257 : : *
258 : : * Read ASCII armored DER encoded KDC-REQ from file and populate given
259 : : * variable.
260 : : *
261 : : * Return value: Returns SHISHI_OK iff successful.
262 : : **/
263 : : int
264 : 0 : shishi_kdcreq_parse (Shishi * handle, FILE * fh, Shishi_asn1 * kdcreq)
265 : : {
266 : 0 : return _shishi_kdcreq_input (handle, fh, kdcreq, 0);
267 : : }
268 : :
269 : : /**
270 : : * shishi_kdcreq_read:
271 : : * @handle: shishi handle as allocated by shishi_init().
272 : : * @fh: file handle open for reading.
273 : : * @kdcreq: output variable with newly allocated KDC-REQ.
274 : : *
275 : : * Read DER encoded KDC-REQ from file and populate given variable.
276 : : *
277 : : * Return value: Returns SHISHI_OK iff successful.
278 : : **/
279 : : int
280 : 0 : shishi_kdcreq_read (Shishi * handle, FILE * fh, Shishi_asn1 * kdcreq)
281 : : {
282 : 0 : return _shishi_kdcreq_input (handle, fh, kdcreq, 1);
283 : : }
284 : :
285 : : /**
286 : : * shishi_kdcreq_from_file:
287 : : * @handle: shishi handle as allocated by shishi_init().
288 : : * @kdcreq: output variable with newly allocated KDC-REQ.
289 : : * @filetype: input variable specifying type of file to be read,
290 : : * see Shishi_filetype.
291 : : * @filename: input variable with filename to read from.
292 : : *
293 : : * Read KDC-REQ from file in specified TYPE.
294 : : *
295 : : * Return value: Returns SHISHI_OK iff successful.
296 : : **/
297 : : int
298 : 0 : shishi_kdcreq_from_file (Shishi * handle, Shishi_asn1 * kdcreq,
299 : : int filetype, const char *filename)
300 : : {
301 : : int res;
302 : : FILE *fh;
303 : :
304 [ # # ]: 0 : if (VERBOSE (handle))
305 : 0 : printf (_("Reading KDC-REQ from %s...\n"), filename);
306 : :
307 : 0 : fh = fopen (filename, "r");
308 [ # # ]: 0 : if (fh == NULL)
309 : 0 : return SHISHI_FOPEN_ERROR;
310 : :
311 [ # # ]: 0 : if (VERBOSE (handle))
312 [ # # ]: 0 : printf (_("Reading KDC-REQ in %s format...\n"),
313 : : filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
314 : :
315 [ # # ]: 0 : if (filetype == SHISHI_FILETYPE_TEXT)
316 : 0 : res = shishi_kdcreq_parse (handle, fh, kdcreq);
317 : : else
318 : 0 : res = shishi_kdcreq_read (handle, fh, kdcreq);
319 [ # # ]: 0 : if (res != SHISHI_OK)
320 : 0 : return res;
321 : :
322 : 0 : res = fclose (fh);
323 [ # # ]: 0 : if (res != 0)
324 : 0 : return SHISHI_IO_ERROR;
325 : :
326 [ # # ]: 0 : if (VERBOSE (handle))
327 : 0 : printf (_("Reading KDC-REQ from %s...done\n"), filename);
328 : :
329 : 0 : return SHISHI_OK;
330 : : }
331 : :
332 : : int
333 : 2 : shishi_kdcreq_nonce (Shishi * handle, Shishi_asn1 kdcreq, uint32_t * nonce)
334 : : {
335 : : int res;
336 : :
337 : 2 : res = shishi_asn1_read_uint32 (handle, kdcreq, "req-body.nonce", nonce);
338 [ - + ]: 2 : if (res != SHISHI_OK)
339 : 0 : return res;
340 : :
341 : 2 : return SHISHI_OK;
342 : : }
343 : :
344 : : /**
345 : : * shishi_kdcreq_nonce_set:
346 : : * @handle: shishi handle as allocated by shishi_init().
347 : : * @kdcreq: KDC-REQ variable to set client name field in.
348 : : * @nonce: integer nonce to store in KDC-REQ.
349 : : *
350 : : * Store nonce number field in KDC-REQ.
351 : : *
352 : : * Return value: Returns %SHISHI_OK iff successful.
353 : : **/
354 : : int
355 : 0 : shishi_kdcreq_nonce_set (Shishi * handle, Shishi_asn1 kdcreq, uint32_t nonce)
356 : : {
357 : : int res;
358 : :
359 : 0 : res = shishi_asn1_write_uint32 (handle, kdcreq, "req-body.nonce", nonce);
360 [ # # ]: 0 : if (res != SHISHI_OK)
361 : 0 : return res;
362 : :
363 : 0 : return SHISHI_OK;
364 : : }
365 : :
366 : : /**
367 : : * shishi_kdcreq_set_cname:
368 : : * @handle: shishi handle as allocated by shishi_init().
369 : : * @kdcreq: KDC-REQ variable to set client name field in.
370 : : * @name_type: type of principial, see Shishi_name_type, usually
371 : : * SHISHI_NT_UNKNOWN.
372 : : * @principal: input array with principal name.
373 : : *
374 : : * Set the client name field in the KDC-REQ.
375 : : *
376 : : * Return value: Returns SHISHI_OK iff successful.
377 : : **/
378 : : int
379 : 0 : shishi_kdcreq_set_cname (Shishi * handle,
380 : : Shishi_asn1 kdcreq,
381 : : Shishi_name_type name_type, const char *principal)
382 : : {
383 : : int res;
384 : :
385 : 0 : res = shishi_principal_set (handle, kdcreq, "req-body.cname", principal);
386 [ # # ]: 0 : if (res != SHISHI_OK)
387 : 0 : return res;
388 : :
389 : 0 : return SHISHI_OK;
390 : : }
391 : :
392 : : /**
393 : : * shishi_kdcreq_client:
394 : : * @handle: Shishi library handle create by shishi_init().
395 : : * @kdcreq: KDC-REQ variable to get client name from.
396 : : * @client: pointer to newly allocated zero terminated string containing
397 : : * principal name. May be %NULL (to only populate @clientlen).
398 : : * @clientlen: pointer to length of @client on output, excluding terminating
399 : : * zero. May be %NULL (to only populate @client).
400 : : *
401 : : * Represent client principal name in KDC-REQ as zero-terminated
402 : : * string. The string is allocate by this function, and it is the
403 : : * responsibility of the caller to deallocate it. Note that the
404 : : * output length @clientlen does not include the terminating zero.
405 : : *
406 : : * Return value: Returns SHISHI_OK iff successful.
407 : : **/
408 : : int
409 : 0 : shishi_kdcreq_client (Shishi * handle, Shishi_asn1 kdcreq,
410 : : char **client, size_t * clientlen)
411 : : {
412 : 0 : return shishi_principal_name (handle, kdcreq, "req-body.cname",
413 : : client, clientlen);
414 : : }
415 : :
416 : : /**
417 : : * shishi_asreq_clientrealm:
418 : : * @handle: Shishi library handle create by shishi_init().
419 : : * @asreq: AS-REQ variable to get client name and realm from.
420 : : * @client: pointer to newly allocated zero terminated string containing
421 : : * principal name and realm. May be %NULL (to only populate @clientlen).
422 : : * @clientlen: pointer to length of @client on output, excluding terminating
423 : : * zero. May be %NULL (to only populate @client).
424 : : *
425 : : * Convert cname and realm fields from AS-REQ to printable principal
426 : : * name format. The string is allocate by this function, and it is
427 : : * the responsibility of the caller to deallocate it. Note that the
428 : : * output length @clientlen does not include the terminating zero.
429 : : *
430 : : * Return value: Returns SHISHI_OK iff successful.
431 : : **/
432 : : int
433 : 0 : shishi_asreq_clientrealm (Shishi * handle,
434 : : Shishi_asn1 asreq,
435 : : char **client, size_t * clientlen)
436 : : {
437 : 0 : return shishi_principal_name_realm (handle,
438 : : asreq, "req-body.cname",
439 : : asreq, "req-body.realm",
440 : : client, clientlen);
441 : : }
442 : :
443 : : /**
444 : : * shishi_kdcreq_realm:
445 : : * @handle: Shishi library handle create by shishi_init().
446 : : * @kdcreq: KDC-REQ variable to get client name from.
447 : : * @realm: pointer to newly allocated zero terminated string containing
448 : : * realm. May be %NULL (to only populate @realmlen).
449 : : * @realmlen: pointer to length of @realm on output, excluding terminating
450 : : * zero. May be %NULL (to only populate @realmlen).
451 : : *
452 : : * Get realm field in KDC-REQ as zero-terminated string. The string
453 : : * is allocate by this function, and it is the responsibility of the
454 : : * caller to deallocate it. Note that the output length @realmlen
455 : : * does not include the terminating zero.
456 : : *
457 : : * Return value: Returns SHISHI_OK iff successful.
458 : : **/
459 : : int
460 : 0 : shishi_kdcreq_realm (Shishi * handle, Shishi_asn1 kdcreq,
461 : : char **realm, size_t * realmlen)
462 : : {
463 : 0 : return shishi_asn1_read_optional (handle, kdcreq, "req-body.realm",
464 : : realm, realmlen);
465 : : }
466 : :
467 : : int
468 : 0 : shishi_kdcreq_realm_get (Shishi * handle, Shishi_asn1 kdcreq,
469 : : char **realm, size_t * realmlen)
470 : : {
471 : 0 : return shishi_asn1_read_optional (handle, kdcreq, "req-body.realm",
472 : : realm, realmlen);
473 : : }
474 : :
475 : : /**
476 : : * shishi_kdcreq_set_realm:
477 : : * @handle: shishi handle as allocated by shishi_init().
478 : : * @kdcreq: KDC-REQ variable to set realm field in.
479 : : * @realm: input array with name of realm.
480 : : *
481 : : * Set the realm field in the KDC-REQ.
482 : : *
483 : : * Return value: Returns SHISHI_OK iff successful.
484 : : **/
485 : : int
486 : 0 : shishi_kdcreq_set_realm (Shishi * handle, Shishi_asn1 kdcreq,
487 : : const char *realm)
488 : : {
489 : : int res;
490 : :
491 : 0 : res = shishi_asn1_write (handle, kdcreq, "req-body.realm", realm, 0);
492 [ # # ]: 0 : if (res != SHISHI_OK)
493 : 0 : return res;
494 : :
495 : 0 : return SHISHI_OK;
496 : : }
497 : :
498 : : /**
499 : : * shishi_kdcreq_server:
500 : : * @handle: Shishi library handle create by shishi_init().
501 : : * @kdcreq: KDC-REQ variable to get server name from.
502 : : * @server: pointer to newly allocated zero terminated string containing
503 : : * principal name. May be %NULL (to only populate @serverlen).
504 : : * @serverlen: pointer to length of @server on output, excluding terminating
505 : : * zero. May be %NULL (to only populate @server).
506 : : *
507 : : * Represent server principal name in KDC-REQ as zero-terminated
508 : : * string. The string is allocate by this function, and it is the
509 : : * responsibility of the caller to deallocate it. Note that the
510 : : * output length @serverlen does not include the terminating zero.
511 : : *
512 : : * Return value: Returns SHISHI_OK iff successful.
513 : : **/
514 : : int
515 : 0 : shishi_kdcreq_server (Shishi * handle, Shishi_asn1 kdcreq,
516 : : char **server, size_t * serverlen)
517 : : {
518 : 0 : return shishi_principal_name (handle, kdcreq, "req-body.sname",
519 : : server, serverlen);
520 : : }
521 : :
522 : : /**
523 : : * shishi_kdcreq_set_sname:
524 : : * @handle: shishi handle as allocated by shishi_init().
525 : : * @kdcreq: KDC-REQ variable to set server name field in.
526 : : * @name_type: type of principial, see Shishi_name_type, usually
527 : : * SHISHI_NT_UNKNOWN.
528 : : * @sname: input array with principal name.
529 : : *
530 : : * Set the server name field in the KDC-REQ.
531 : : *
532 : : * Return value: Returns SHISHI_OK iff successful.
533 : : **/
534 : : int
535 : 0 : shishi_kdcreq_set_sname (Shishi * handle,
536 : : Shishi_asn1 kdcreq,
537 : : Shishi_name_type name_type, const char *sname[])
538 : : {
539 : : int res;
540 : :
541 : 0 : res = shishi_principal_name_set (handle, kdcreq, "req-body.sname",
542 : : name_type, sname);
543 [ # # ]: 0 : if (res != SHISHI_OK)
544 : 0 : return res;
545 : :
546 : 0 : return SHISHI_OK;
547 : : }
548 : :
549 : : int
550 : 0 : shishi_kdcreq_set_server (Shishi * handle, Shishi_asn1 req,
551 : : const char *server)
552 : : {
553 : : int res;
554 : :
555 : 0 : res = shishi_principal_set (handle, req, "req-body.sname", server);
556 [ # # ]: 0 : if (res != SHISHI_OK)
557 : 0 : return res;
558 : :
559 : 0 : return SHISHI_OK;
560 : : }
561 : :
562 : : int
563 : 0 : shishi_kdcreq_set_realmserver (Shishi * handle,
564 : : Shishi_asn1 req, char *realm, char *server)
565 : : {
566 : : int res;
567 : :
568 : 0 : res = shishi_kdcreq_set_realm (handle, req, realm);
569 [ # # ]: 0 : if (res != SHISHI_OK)
570 : 0 : return res;
571 : :
572 : 0 : res = shishi_kdcreq_set_server (handle, req, server);
573 [ # # ]: 0 : if (res != SHISHI_OK)
574 : 0 : return res;
575 : :
576 : 0 : return SHISHI_OK;
577 : : }
578 : :
579 : : /**
580 : : * shishi_kdcreq_till:
581 : : * @handle: Shishi library handle create by shishi_init().
582 : : * @kdcreq: KDC-REQ variable to get client name from.
583 : : * @till: pointer to newly allocated zero terminated string containing
584 : : * "till" field with generalized time. May be %NULL (to only
585 : : * populate @realmlen).
586 : : * @tilllen: pointer to length of @till on output, excluding
587 : : * terminating zero. May be %NULL (to only populate @tilllen).
588 : : *
589 : : * Get "till" field (i.e. "endtime") in KDC-REQ, as zero-terminated
590 : : * string. The string is typically 15 characters long. The string is
591 : : * allocated by this function, and it is the responsibility of the
592 : : * caller to deallocate it. Note that the output length @realmlen
593 : : * does not include the terminating zero.
594 : : *
595 : : * Return value: Returns SHISHI_OK iff successful.
596 : : **/
597 : : int
598 : 0 : shishi_kdcreq_till (Shishi * handle, Shishi_asn1 kdcreq,
599 : : char **till, size_t * tilllen)
600 : : {
601 : 0 : return shishi_asn1_read (handle, kdcreq, "req-body.till", till, tilllen);
602 : : }
603 : :
604 : : /**
605 : : * shishi_kdcreq_tillc:
606 : : * @handle: Shishi library handle create by shishi_init().
607 : : * @kdcreq: KDC-REQ variable to get till field from.
608 : : *
609 : : * Extract C time corresponding to the "till" field.
610 : : *
611 : : * Return value: Returns C time interpretation of the "till" field in
612 : : * KDC-REQ.
613 : : **/
614 : : time_t
615 : 0 : shishi_kdcreq_tillc (Shishi * handle, Shishi_asn1 kdcreq)
616 : : {
617 : : char *till;
618 : : size_t tilllen;
619 : 0 : time_t t = (time_t) - 1;
620 : : int res;
621 : :
622 : 0 : res = shishi_kdcreq_till (handle, kdcreq, &till, &tilllen);
623 [ # # ]: 0 : if (res != SHISHI_OK)
624 : 0 : return t;
625 : :
626 [ # # ]: 0 : if (tilllen == SHISHI_GENERALIZEDTIME_LENGTH + 1) /* XXX why +1 ? */
627 : 0 : t = shishi_generalize_ctime (handle, till);
628 : :
629 : 0 : free (till);
630 : :
631 : 0 : return t;
632 : : }
633 : :
634 : : /**
635 : : * shishi_kdcreq_etype:
636 : : * @handle: shishi handle as allocated by shishi_init().
637 : : * @kdcreq: KDC-REQ variable to get etype field from.
638 : : * @etype: output encryption type.
639 : : * @netype: element number to return.
640 : : *
641 : : * Return the netype:th encryption type from KDC-REQ. The first etype
642 : : * is number 1.
643 : : *
644 : : * Return value: Returns SHISHI_OK iff etype successful set.
645 : : **/
646 : : int
647 : 0 : shishi_kdcreq_etype (Shishi * handle,
648 : : Shishi_asn1 kdcreq, int32_t * etype, int netype)
649 : : {
650 : : char *buf;
651 : : int res;
652 : :
653 : 0 : asprintf (&buf, "req-body.etype.?%d", netype);
654 : 0 : res = shishi_asn1_read_int32 (handle, kdcreq, buf, etype);
655 [ # # ]: 0 : if (res != SHISHI_OK)
656 : 0 : return res;
657 : :
658 : 0 : return SHISHI_OK;
659 : : }
660 : :
661 : : /**
662 : : * shishi_kdcreq_set_etype:
663 : : * @handle: shishi handle as allocated by shishi_init().
664 : : * @kdcreq: KDC-REQ variable to set etype field in.
665 : : * @etype: input array with encryption types.
666 : : * @netype: number of elements in input array with encryption types.
667 : : *
668 : : * Set the list of supported or wanted encryption types in the
669 : : * request. The list should be sorted in priority order.
670 : : *
671 : : * Return value: Returns SHISHI_OK iff successful.
672 : : **/
673 : : int
674 : 0 : shishi_kdcreq_set_etype (Shishi * handle,
675 : : Shishi_asn1 kdcreq, int32_t * etype, int netype)
676 : : {
677 : : int res;
678 : : char *buf;
679 : : int i;
680 : :
681 : 0 : res = shishi_asn1_write (handle, kdcreq, "req-body.etype", NULL, 0);
682 [ # # ]: 0 : if (res != SHISHI_OK)
683 : 0 : return res;
684 : :
685 [ # # ]: 0 : for (i = 1; i <= netype; i++)
686 : : {
687 : 0 : res = shishi_asn1_write (handle, kdcreq, "req-body.etype", "NEW", 1);
688 [ # # ]: 0 : if (res != SHISHI_OK)
689 : 0 : return res;
690 : :
691 : 0 : asprintf (&buf, "req-body.etype.?%d", i);
692 : 0 : res = shishi_asn1_write_int32 (handle, kdcreq, buf, etype[i - 1]);
693 : 0 : free (buf);
694 [ # # ]: 0 : if (res != SHISHI_OK)
695 : 0 : return res;
696 : : }
697 : :
698 : 0 : return SHISHI_OK;
699 : : }
700 : :
701 : : /**
702 : : * shishi_kdcreq_options:
703 : : * @handle: shishi handle as allocated by shishi_init().
704 : : * @kdcreq: KDC-REQ variable to get kdc-options field from.
705 : : * @flags: pointer to output integer with flags.
706 : : *
707 : : * Extract KDC-Options from KDC-REQ.
708 : : *
709 : : * Return value: Returns SHISHI_OK iff successful.
710 : : **/
711 : : int
712 : 0 : shishi_kdcreq_options (Shishi * handle, Shishi_asn1 kdcreq, uint32_t * flags)
713 : : {
714 : 0 : return shishi_asn1_read_bitstring (handle, kdcreq,
715 : : "req-body.kdc-options", flags);
716 : : }
717 : :
718 : : /**
719 : : * shishi_kdcreq_forwardable_p:
720 : : * @handle: shishi handle as allocated by shishi_init().
721 : : * @kdcreq: KDC-REQ variable to get kdc-options field from.
722 : : *
723 : : * Determine if KDC-Option forwardable flag is set.
724 : : *
725 : : * The FORWARDABLE option indicates that the ticket to be issued is to
726 : : * have its forwardable flag set. It may only be set on the initial
727 : : * request, or in a subsequent request if the ticket-granting ticket
728 : : * on which it is based is also forwardable.
729 : : *
730 : : * Return value: Returns non-0 iff forwardable flag is set in KDC-REQ.
731 : : **/
732 : : int
733 : 0 : shishi_kdcreq_forwardable_p (Shishi * handle, Shishi_asn1 kdcreq)
734 : : {
735 : 0 : uint32_t options = 0;
736 : :
737 : 0 : shishi_kdcreq_options (handle, kdcreq, &options);
738 : :
739 : 0 : return options & SHISHI_KDCOPTIONS_FORWARDABLE;
740 : : }
741 : :
742 : : /**
743 : : * shishi_kdcreq_forwarded_p:
744 : : * @handle: shishi handle as allocated by shishi_init().
745 : : * @kdcreq: KDC-REQ variable to get kdc-options field from.
746 : : *
747 : : * Determine if KDC-Option forwarded flag is set.
748 : : *
749 : : * The FORWARDED option is only specified in a request to the
750 : : * ticket-granting server and will only be honored if the
751 : : * ticket-granting ticket in the request has its FORWARDABLE bit
752 : : * set. This option indicates that this is a request for
753 : : * forwarding. The address(es) of the host from which the resulting
754 : : * ticket is to be valid are included in the addresses field of the
755 : : * request.
756 : : *
757 : : * Return value: Returns non-0 iff forwarded flag is set in KDC-REQ.
758 : : **/
759 : : int
760 : 0 : shishi_kdcreq_forwarded_p (Shishi * handle, Shishi_asn1 kdcreq)
761 : : {
762 : 0 : uint32_t options = 0;
763 : :
764 : 0 : shishi_kdcreq_options (handle, kdcreq, &options);
765 : :
766 : 0 : return options & SHISHI_KDCOPTIONS_FORWARDED;
767 : : }
768 : :
769 : : /**
770 : : * shishi_kdcreq_proxiable_p:
771 : : * @handle: shishi handle as allocated by shishi_init().
772 : : * @kdcreq: KDC-REQ variable to get kdc-options field from.
773 : : *
774 : : * Determine if KDC-Option proxiable flag is set.
775 : : *
776 : : * The PROXIABLE option indicates that the ticket to be issued is to
777 : : * have its proxiable flag set. It may only be set on the initial
778 : : * request, or in a subsequent request if the ticket-granting ticket
779 : : * on which it is based is also proxiable.
780 : : *
781 : : * Return value: Returns non-0 iff proxiable flag is set in KDC-REQ.
782 : : **/
783 : : int
784 : 0 : shishi_kdcreq_proxiable_p (Shishi * handle, Shishi_asn1 kdcreq)
785 : : {
786 : 0 : uint32_t options = 0;
787 : :
788 : 0 : shishi_kdcreq_options (handle, kdcreq, &options);
789 : :
790 : 0 : return options & SHISHI_KDCOPTIONS_PROXIABLE;
791 : : }
792 : :
793 : : /**
794 : : * shishi_kdcreq_proxy_p:
795 : : * @handle: shishi handle as allocated by shishi_init().
796 : : * @kdcreq: KDC-REQ variable to get kdc-options field from.
797 : : *
798 : : * Determine if KDC-Option proxy flag is set.
799 : : *
800 : : * The PROXY option indicates that this is a request for a proxy. This
801 : : * option will only be honored if the ticket-granting ticket in the
802 : : * request has its PROXIABLE bit set. The address(es) of the host
803 : : * from which the resulting ticket is to be valid are included in the
804 : : * addresses field of the request.
805 : : *
806 : : * Return value: Returns non-0 iff proxy flag is set in KDC-REQ.
807 : : **/
808 : : int
809 : 0 : shishi_kdcreq_proxy_p (Shishi * handle, Shishi_asn1 kdcreq)
810 : : {
811 : 0 : uint32_t options = 0;
812 : :
813 : 0 : shishi_kdcreq_options (handle, kdcreq, &options);
814 : :
815 : 0 : return options & SHISHI_KDCOPTIONS_PROXY;
816 : : }
817 : :
818 : : /**
819 : : * shishi_kdcreq_allow_postdate_p:
820 : : * @handle: shishi handle as allocated by shishi_init().
821 : : * @kdcreq: KDC-REQ variable to get kdc-options field from.
822 : : *
823 : : * Determine if KDC-Option allow-postdate flag is set.
824 : : *
825 : : * The ALLOW-POSTDATE option indicates that the ticket to be issued is
826 : : * to have its MAY-POSTDATE flag set. It may only be set on the
827 : : * initial request, or in a subsequent request if the ticket-granting
828 : : * ticket on which it is based also has its MAY-POSTDATE flag set.
829 : : *
830 : : * Return value: Returns non-0 iff allow-postdate flag is set in KDC-REQ.
831 : : **/
832 : : int
833 : 0 : shishi_kdcreq_allow_postdate_p (Shishi * handle, Shishi_asn1 kdcreq)
834 : : {
835 : 0 : uint32_t options = 0;
836 : :
837 : 0 : shishi_kdcreq_options (handle, kdcreq, &options);
838 : :
839 : 0 : return options & SHISHI_KDCOPTIONS_ALLOW_POSTDATE;
840 : : }
841 : :
842 : : /**
843 : : * shishi_kdcreq_postdated_p:
844 : : * @handle: shishi handle as allocated by shishi_init().
845 : : * @kdcreq: KDC-REQ variable to get kdc-options field from.
846 : : *
847 : : * Determine if KDC-Option postdated flag is set.
848 : : *
849 : : * The POSTDATED option indicates that this is a request for a
850 : : * postdated ticket. This option will only be honored if the
851 : : * ticket-granting ticket on which it is based has its MAY-POSTDATE
852 : : * flag set. The resulting ticket will also have its INVALID flag set,
853 : : * and that flag may be reset by a subsequent request to the KDC after
854 : : * the starttime in the ticket has been reached.
855 : : *
856 : : * Return value: Returns non-0 iff postdated flag is set in KDC-REQ.
857 : : **/
858 : : int
859 : 0 : shishi_kdcreq_postdated_p (Shishi * handle, Shishi_asn1 kdcreq)
860 : : {
861 : 0 : uint32_t options = 0;
862 : :
863 : 0 : shishi_kdcreq_options (handle, kdcreq, &options);
864 : :
865 : 0 : return options & SHISHI_KDCOPTIONS_POSTDATED;
866 : : }
867 : :
868 : : /**
869 : : * shishi_kdcreq_renewable_p:
870 : : * @handle: shishi handle as allocated by shishi_init().
871 : : * @kdcreq: KDC-REQ variable to get kdc-options field from.
872 : : *
873 : : * Determine if KDC-Option renewable flag is set.
874 : : *
875 : : * The RENEWABLE option indicates that the ticket to be issued is to
876 : : * have its RENEWABLE flag set. It may only be set on the initial
877 : : * request, or when the ticket-granting ticket on which the request is
878 : : * based is also renewable. If this option is requested, then the
879 : : * rtime field in the request contains the desired absolute expiration
880 : : * time for the ticket.
881 : : *
882 : : * Return value: Returns non-0 iff renewable flag is set in KDC-REQ.
883 : : **/
884 : : int
885 : 0 : shishi_kdcreq_renewable_p (Shishi * handle, Shishi_asn1 kdcreq)
886 : : {
887 : 0 : uint32_t options = 0;
888 : :
889 : 0 : shishi_kdcreq_options (handle, kdcreq, &options);
890 : :
891 : 0 : return options & SHISHI_KDCOPTIONS_RENEWABLE;
892 : : }
893 : :
894 : : /**
895 : : * shishi_kdcreq_disable_transited_check_p:
896 : : * @handle: shishi handle as allocated by shishi_init().
897 : : * @kdcreq: KDC-REQ variable to get kdc-options field from.
898 : : *
899 : : * Determine if KDC-Option disable-transited-check flag is set.
900 : : *
901 : : * By default the KDC will check the transited field of a
902 : : * ticket-granting-ticket against the policy of the local realm before
903 : : * it will issue derivative tickets based on the ticket-granting
904 : : * ticket. If this flag is set in the request, checking of the
905 : : * transited field is disabled. Tickets issued without the performance
906 : : * of this check will be noted by the reset (0) value of the
907 : : * TRANSITED-POLICY-CHECKED flag, indicating to the application server
908 : : * that the tranisted field must be checked locally. KDCs are
909 : : * encouraged but not required to honor the DISABLE-TRANSITED-CHECK
910 : : * option.
911 : : *
912 : : * This flag is new since RFC 1510
913 : : *
914 : : * Return value: Returns non-0 iff disable-transited-check flag is set
915 : : * in KDC-REQ.
916 : : **/
917 : : int
918 : 0 : shishi_kdcreq_disable_transited_check_p (Shishi * handle, Shishi_asn1 kdcreq)
919 : : {
920 : 0 : uint32_t options = 0;
921 : :
922 : 0 : shishi_kdcreq_options (handle, kdcreq, &options);
923 : :
924 : 0 : return options & SHISHI_KDCOPTIONS_DISABLE_TRANSITED_CHECK;
925 : : }
926 : :
927 : : /**
928 : : * shishi_kdcreq_renewable_ok_p:
929 : : * @handle: shishi handle as allocated by shishi_init().
930 : : * @kdcreq: KDC-REQ variable to get kdc-options field from.
931 : : *
932 : : * Determine if KDC-Option renewable-ok flag is set.
933 : : *
934 : : * The RENEWABLE-OK option indicates that a renewable ticket will be
935 : : * acceptable if a ticket with the requested life cannot otherwise be
936 : : * provided. If a ticket with the requested life cannot be provided,
937 : : * then a renewable ticket may be issued with a renew-till equal to
938 : : * the requested endtime. The value of the renew-till field may still
939 : : * be limited by local limits, or limits selected by the individual
940 : : * principal or server.
941 : : *
942 : : * Return value: Returns non-0 iff renewable-ok flag is set in KDC-REQ.
943 : : **/
944 : : int
945 : 0 : shishi_kdcreq_renewable_ok_p (Shishi * handle, Shishi_asn1 kdcreq)
946 : : {
947 : 0 : uint32_t options = 0;
948 : :
949 : 0 : shishi_kdcreq_options (handle, kdcreq, &options);
950 : :
951 : 0 : return options & SHISHI_KDCOPTIONS_RENEWABLE_OK;
952 : : }
953 : :
954 : : /**
955 : : * shishi_kdcreq_enc_tkt_in_skey_p:
956 : : * @handle: shishi handle as allocated by shishi_init().
957 : : * @kdcreq: KDC-REQ variable to get kdc-options field from.
958 : : *
959 : : * Determine if KDC-Option enc-tkt-in-skey flag is set.
960 : : *
961 : : * This option is used only by the ticket-granting service. The
962 : : * ENC-TKT-IN-SKEY option indicates that the ticket for the end server
963 : : * is to be encrypted in the session key from the additional
964 : : * ticket-granting ticket provided.
965 : : *
966 : : * Return value: Returns non-0 iff enc-tkt-in-skey flag is set in KDC-REQ.
967 : : **/
968 : : int
969 : 0 : shishi_kdcreq_enc_tkt_in_skey_p (Shishi * handle, Shishi_asn1 kdcreq)
970 : : {
971 : 0 : uint32_t options = 0;
972 : :
973 : 0 : shishi_kdcreq_options (handle, kdcreq, &options);
974 : :
975 : 0 : return options & SHISHI_KDCOPTIONS_ENC_TKT_IN_SKEY;
976 : : }
977 : :
978 : : /**
979 : : * shishi_kdcreq_renew_p:
980 : : * @handle: shishi handle as allocated by shishi_init().
981 : : * @kdcreq: KDC-REQ variable to get kdc-options field from.
982 : : *
983 : : * Determine if KDC-Option renew flag is set.
984 : : *
985 : : * This option is used only by the ticket-granting service. The RENEW
986 : : * option indicates that the present request is for a renewal. The
987 : : * ticket provided is encrypted in the secret key for the server on
988 : : * which it is valid. This option will only be honored if the ticket
989 : : * to be renewed has its RENEWABLE flag set and if the time in its
990 : : * renew-till field has not passed. The ticket to be renewed is passed
991 : : * in the padata field as part of the authentication header.
992 : : *
993 : : * Return value: Returns non-0 iff renew flag is set in KDC-REQ.
994 : : **/
995 : : int
996 : 0 : shishi_kdcreq_renew_p (Shishi * handle, Shishi_asn1 kdcreq)
997 : : {
998 : 0 : uint32_t options = 0;
999 : :
1000 : 0 : shishi_kdcreq_options (handle, kdcreq, &options);
1001 : :
1002 : 0 : return options & SHISHI_KDCOPTIONS_RENEW;
1003 : : }
1004 : :
1005 : : /**
1006 : : * shishi_kdcreq_validate_p:
1007 : : * @handle: shishi handle as allocated by shishi_init().
1008 : : * @kdcreq: KDC-REQ variable to get kdc-options field from.
1009 : : *
1010 : : * Determine if KDC-Option validate flag is set.
1011 : : *
1012 : : * This option is used only by the ticket-granting service. The
1013 : : * VALIDATE option indicates that the request is to validate a
1014 : : * postdated ticket. It will only be honored if the ticket presented
1015 : : * is postdated, presently has its INVALID flag set, and would be
1016 : : * otherwise usable at this time. A ticket cannot be validated before
1017 : : * its starttime. The ticket presented for validation is encrypted in
1018 : : * the key of the server for which it is valid and is passed in the
1019 : : * padata field as part of the authentication header.
1020 : : *
1021 : : * Return value: Returns non-0 iff validate flag is set in KDC-REQ.
1022 : : **/
1023 : : int
1024 : 0 : shishi_kdcreq_validate_p (Shishi * handle, Shishi_asn1 kdcreq)
1025 : : {
1026 : 0 : uint32_t options = 0;
1027 : :
1028 : 0 : shishi_kdcreq_options (handle, kdcreq, &options);
1029 : :
1030 : 0 : return options & SHISHI_KDCOPTIONS_VALIDATE;
1031 : : }
1032 : :
1033 : : /**
1034 : : * shishi_kdcreq_options_set:
1035 : : * @handle: shishi handle as allocated by shishi_init().
1036 : : * @kdcreq: KDC-REQ variable to set etype field in.
1037 : : * @options: integer with flags to store in KDC-REQ.
1038 : : *
1039 : : * Set options in KDC-REQ. Note that this reset any already existing
1040 : : * flags.
1041 : : *
1042 : : * Return value: Returns SHISHI_OK iff successful.
1043 : : **/
1044 : : int
1045 : 0 : shishi_kdcreq_options_set (Shishi * handle,
1046 : : Shishi_asn1 kdcreq, uint32_t options)
1047 : : {
1048 : : int res;
1049 : :
1050 : 0 : res = shishi_asn1_write_bitstring (handle, kdcreq,
1051 : : "req-body.kdc-options", options);
1052 [ # # ]: 0 : if (res != SHISHI_OK)
1053 : 0 : return res;
1054 : :
1055 : 0 : return SHISHI_OK;
1056 : : }
1057 : :
1058 : : /**
1059 : : * shishi_kdcreq_options_add:
1060 : : * @handle: shishi handle as allocated by shishi_init().
1061 : : * @kdcreq: KDC-REQ variable to set etype field in.
1062 : : * @option: integer with options to add in KDC-REQ.
1063 : : *
1064 : : * Add KDC-Option to KDC-REQ. This preserves all existing options.
1065 : : *
1066 : : * Return value: Returns SHISHI_OK iff successful.
1067 : : **/
1068 : : int
1069 : 0 : shishi_kdcreq_options_add (Shishi * handle,
1070 : : Shishi_asn1 kdcreq, uint32_t option)
1071 : : {
1072 : : uint32_t options;
1073 : : int res;
1074 : :
1075 : 0 : res = shishi_kdcreq_options (handle, kdcreq, &options);
1076 [ # # ]: 0 : if (res != SHISHI_OK)
1077 : 0 : return res;
1078 : :
1079 : 0 : options |= option;
1080 : :
1081 : 0 : res = shishi_kdcreq_options_set (handle, kdcreq, options);
1082 [ # # ]: 0 : if (res != SHISHI_OK)
1083 : 0 : return res;
1084 : :
1085 : 0 : return SHISHI_OK;
1086 : : }
1087 : :
1088 : : /**
1089 : : * shishi_kdcreq_clear_padata:
1090 : : * @handle: shishi handle as allocated by shishi_init().
1091 : : * @kdcreq: KDC-REQ to remove PA-DATA from.
1092 : : *
1093 : : * Remove the padata field from KDC-REQ.
1094 : : *
1095 : : * Return value: Returns SHISHI_OK iff successful.
1096 : : **/
1097 : : int
1098 : 0 : shishi_kdcreq_clear_padata (Shishi * handle, Shishi_asn1 kdcreq)
1099 : : {
1100 : : int res;
1101 : :
1102 : 0 : res = shishi_asn1_write (handle, kdcreq, "padata", NULL, 0);
1103 [ # # ]: 0 : if (res != SHISHI_OK)
1104 : 0 : return res;
1105 : :
1106 : 0 : return SHISHI_OK;
1107 : : }
1108 : :
1109 : : /**
1110 : : * shishi_kdcreq_get_padata:
1111 : : * @handle: shishi handle as allocated by shishi_init().
1112 : : * @kdcreq: KDC-REQ to get PA-DATA from.
1113 : : * @padatatype: type of PA-DATA, see Shishi_padata_type.
1114 : : * @out: output array with newly allocated PA-DATA value.
1115 : : * @outlen: size of output array with PA-DATA value.
1116 : : *
1117 : : * Get pre authentication data (PA-DATA) from KDC-REQ. Pre
1118 : : * authentication data is used to pass various information to KDC,
1119 : : * such as in case of a SHISHI_PA_TGS_REQ padatatype the AP-REQ that
1120 : : * authenticates the user to get the ticket.
1121 : : *
1122 : : * Return value: Returns SHISHI_OK iff successful.
1123 : : **/
1124 : : int
1125 : 0 : shishi_kdcreq_get_padata (Shishi * handle,
1126 : : Shishi_asn1 kdcreq,
1127 : : Shishi_padata_type padatatype,
1128 : : char **out, size_t * outlen)
1129 : : {
1130 : : char *format;
1131 : : int res;
1132 : : size_t i, n;
1133 : :
1134 : 0 : res = shishi_asn1_number_of_elements (handle, kdcreq, "padata", &n);
1135 [ # # ]: 0 : if (res != SHISHI_OK)
1136 : 0 : return res;
1137 : :
1138 : 0 : *out = NULL;
1139 : 0 : *outlen = 0;
1140 : :
1141 [ # # ]: 0 : for (i = 1; i <= n; i++)
1142 : : {
1143 : : int32_t patype;
1144 : :
1145 : 0 : asprintf (&format, "padata.?%d.padata-type", i);
1146 : 0 : res = shishi_asn1_read_int32 (handle, kdcreq, format, &patype);
1147 : 0 : free (format);
1148 [ # # ]: 0 : if (res != SHISHI_OK)
1149 : 0 : return res;
1150 : :
1151 [ # # ]: 0 : if (patype == (int32_t) padatatype)
1152 : : {
1153 : 0 : asprintf (&format, "padata.?%d.padata-value", i);
1154 : 0 : res = shishi_asn1_read (handle, kdcreq, format, out, outlen);
1155 : 0 : free (format);
1156 [ # # ]: 0 : if (res != SHISHI_OK)
1157 : 0 : return res;
1158 : 0 : break;
1159 : : }
1160 : : }
1161 : :
1162 : 0 : return SHISHI_OK;
1163 : : }
1164 : :
1165 : : /**
1166 : : * shishi_kdcreq_get_padata_tgs:
1167 : : * @handle: shishi handle as allocated by shishi_init().
1168 : : * @kdcreq: KDC-REQ to get PA-TGS-REQ from.
1169 : : * @apreq: Output variable with newly allocated AP-REQ.
1170 : : *
1171 : : * Extract TGS pre-authentication data from KDC-REQ. The data is an
1172 : : * AP-REQ that authenticates the request. This function call
1173 : : * shishi_kdcreq_get_padata() with a SHISHI_PA_TGS_REQ padatatype and
1174 : : * DER decode the result (if any).
1175 : : *
1176 : : * Return value: Returns SHISHI_OK iff successful.
1177 : : **/
1178 : : int
1179 : 0 : shishi_kdcreq_get_padata_tgs (Shishi * handle,
1180 : : Shishi_asn1 kdcreq, Shishi_asn1 * apreq)
1181 : : {
1182 : : char *der;
1183 : : size_t derlen;
1184 : : int rc;
1185 : :
1186 [ # # ]: 0 : if (VERBOSE (handle))
1187 : 0 : printf ("Extracting AP-REQ from KDC-REQ...\n");
1188 : :
1189 : 0 : rc = shishi_kdcreq_get_padata (handle, kdcreq, SHISHI_PA_TGS_REQ,
1190 : : &der, &derlen);
1191 [ # # ]: 0 : if (rc != SHISHI_OK)
1192 : 0 : return rc;
1193 : :
1194 : 0 : *apreq = shishi_der2asn1_apreq (handle, der, derlen);
1195 [ # # ]: 0 : if (!*apreq)
1196 : 0 : return SHISHI_ASN1_ERROR;
1197 : :
1198 [ # # ]: 0 : if (VERBOSEASN1 (handle))
1199 : 0 : shishi_apreq_print (handle, stdout, *apreq);
1200 : :
1201 : 0 : return SHISHI_OK;
1202 : : }
1203 : :
1204 : : /**
1205 : : * shishi_kdcreq_add_padata:
1206 : : * @handle: shishi handle as allocated by shishi_init().
1207 : : * @kdcreq: KDC-REQ to add PA-DATA to.
1208 : : * @padatatype: type of PA-DATA, see Shishi_padata_type.
1209 : : * @data: input array with PA-DATA value.
1210 : : * @datalen: size of input array with PA-DATA value.
1211 : : *
1212 : : * Add new pre authentication data (PA-DATA) to KDC-REQ. This is used
1213 : : * to pass various information to KDC, such as in case of a
1214 : : * SHISHI_PA_TGS_REQ padatatype the AP-REQ that authenticates the user
1215 : : * to get the ticket. (But also see shishi_kdcreq_add_padata_tgs()
1216 : : * which takes an AP-REQ directly.)
1217 : : *
1218 : : * Return value: Returns SHISHI_OK iff successful.
1219 : : **/
1220 : : int
1221 : 0 : shishi_kdcreq_add_padata (Shishi * handle,
1222 : : Shishi_asn1 kdcreq,
1223 : : int padatatype, const char *data, size_t datalen)
1224 : : {
1225 : : char *format;
1226 : : int res;
1227 : : size_t i;
1228 : :
1229 : 0 : res = shishi_asn1_write (handle, kdcreq, "padata", "NEW", 1);
1230 [ # # ]: 0 : if (res != SHISHI_OK)
1231 : 0 : return res;
1232 : :
1233 : 0 : res = shishi_asn1_number_of_elements (handle, kdcreq, "padata", &i);
1234 [ # # ]: 0 : if (res != SHISHI_OK)
1235 : 0 : return res;
1236 : :
1237 : 0 : asprintf (&format, "padata.?%d.padata-value", i);
1238 : 0 : res = shishi_asn1_write (handle, kdcreq, format, data, datalen);
1239 : 0 : free (format);
1240 [ # # ]: 0 : if (res != SHISHI_OK)
1241 : 0 : return res;
1242 : :
1243 : 0 : asprintf (&format, "padata.?%d.padata-type", i);
1244 : 0 : res = shishi_asn1_write_uint32 (handle, kdcreq, format, padatatype);
1245 : 0 : free (format);
1246 [ # # ]: 0 : if (res != SHISHI_OK)
1247 : 0 : return res;
1248 : :
1249 : 0 : return SHISHI_OK;
1250 : : }
1251 : :
1252 : : /**
1253 : : * shishi_kdcreq_add_padata_tgs:
1254 : : * @handle: shishi handle as allocated by shishi_init().
1255 : : * @kdcreq: KDC-REQ to add PA-DATA to.
1256 : : * @apreq: AP-REQ to add as PA-DATA.
1257 : : *
1258 : : * Add TGS pre-authentication data to KDC-REQ. The data is an AP-REQ
1259 : : * that authenticates the request. This functions simply DER encodes
1260 : : * the AP-REQ and calls shishi_kdcreq_add_padata() with a
1261 : : * SHISHI_PA_TGS_REQ padatatype.
1262 : : *
1263 : : * Return value: Returns SHISHI_OK iff successful.
1264 : : **/
1265 : : int
1266 : 0 : shishi_kdcreq_add_padata_tgs (Shishi * handle,
1267 : : Shishi_asn1 kdcreq, Shishi_asn1 apreq)
1268 : : {
1269 : : int res;
1270 : : char *data;
1271 : : size_t datalen;
1272 : :
1273 : 0 : res = shishi_asn1_to_der (handle, apreq, &data, &datalen);
1274 [ # # ]: 0 : if (res != SHISHI_OK)
1275 : : {
1276 : 0 : shishi_error_printf (handle, "Could not DER encode AP-REQ: %s\n",
1277 : : shishi_strerror (res));
1278 : 0 : return res;
1279 : : }
1280 : :
1281 : 0 : res = shishi_kdcreq_add_padata (handle, kdcreq,
1282 : : SHISHI_PA_TGS_REQ, data, datalen);
1283 : 0 : free (data);
1284 [ # # ]: 0 : if (res != SHISHI_OK)
1285 : 0 : return res;
1286 : :
1287 : 0 : return res;
1288 : : }
1289 : :
1290 : : /**
1291 : : * shishi_kdcreq_add_padata_preauth:
1292 : : * @handle: shishi handle as allocated by shishi_init().
1293 : : * @kdcreq: KDC-REQ to add pre-authentication data to.
1294 : : * @key: Key used to encrypt pre-auth data.
1295 : : *
1296 : : * Add pre-authentication data to KDC-REQ.
1297 : : *
1298 : : * Return value: Returns SHISHI_OK iff successful.
1299 : : **/
1300 : : int
1301 : 0 : shishi_kdcreq_add_padata_preauth (Shishi * handle,
1302 : : Shishi_asn1 kdcreq, Shishi_key * key)
1303 : : {
1304 : : char *der, *data;
1305 : : size_t derlen, datalen;
1306 : : Shishi_asn1 pa;
1307 : : struct timeval tv;
1308 : : int rc;
1309 : : Shishi_asn1 ed;
1310 : :
1311 : 0 : pa = shishi_asn1_pa_enc_ts_enc (handle);
1312 [ # # ]: 0 : if (!pa)
1313 : 0 : return SHISHI_ASN1_ERROR;
1314 : :
1315 : 0 : rc = gettimeofday (&tv, NULL);
1316 [ # # ]: 0 : if (rc != 0)
1317 : 0 : return SHISHI_GETTIMEOFDAY_ERROR;
1318 : :
1319 : 0 : rc = shishi_asn1_write (handle, pa, "patimestamp",
1320 : : shishi_generalize_time (handle, tv.tv_sec),
1321 : : SHISHI_GENERALIZEDTIME_LENGTH);
1322 [ # # ]: 0 : if (rc != SHISHI_OK)
1323 : 0 : return rc;
1324 : :
1325 : 0 : rc = shishi_asn1_write_integer (handle, pa, "pausec", tv.tv_usec);
1326 [ # # ]: 0 : if (rc != SHISHI_OK)
1327 : 0 : return rc;
1328 : :
1329 : 0 : rc = shishi_asn1_to_der (handle, pa, &der, &derlen);
1330 [ # # ]: 0 : if (rc != SHISHI_OK)
1331 : 0 : return rc;
1332 : :
1333 : 0 : rc = shishi_encrypt (handle, key, SHISHI_KEYUSAGE_ASREQ_PA_ENC_TIMESTAMP,
1334 : : der, derlen, &data, &datalen);
1335 : 0 : free (der);
1336 [ # # ]: 0 : if (rc != SHISHI_OK)
1337 : 0 : return rc;
1338 : :
1339 : 0 : ed = shishi_asn1_encrypteddata (handle);
1340 [ # # ]: 0 : if (!ed)
1341 : 0 : return SHISHI_ASN1_ERROR;
1342 : :
1343 : 0 : rc = shishi_asn1_write_integer (handle, ed, "etype", shishi_key_type (key));
1344 [ # # ]: 0 : if (rc != SHISHI_OK)
1345 : 0 : return rc;
1346 : :
1347 : 0 : rc = shishi_asn1_write (handle, ed, "cipher", data, datalen);
1348 [ # # ]: 0 : if (rc != SHISHI_OK)
1349 : 0 : return rc;
1350 : :
1351 : 0 : rc = shishi_asn1_write (handle, ed, "kvno", NULL, 0);
1352 [ # # ]: 0 : if (rc != SHISHI_OK)
1353 : 0 : return rc;
1354 : :
1355 : 0 : rc = shishi_asn1_to_der (handle, ed, &der, &derlen);
1356 : 0 : free (data);
1357 [ # # ]: 0 : if (rc != SHISHI_OK)
1358 : 0 : return rc;
1359 : :
1360 : 0 : rc = shishi_kdcreq_add_padata (handle, kdcreq, SHISHI_PA_ENC_TIMESTAMP,
1361 : : der, derlen);
1362 : 0 : free (der);
1363 [ # # ]: 0 : if (rc != SHISHI_OK)
1364 : 0 : return rc;
1365 : :
1366 : 0 : return rc;
1367 : : }
1368 : :
1369 : : int
1370 : 0 : shishi_kdcreq_build (Shishi * handle, Shishi_asn1 kdcreq)
1371 : : {
1372 : : int res;
1373 : : size_t n;
1374 : : int msgtype;
1375 : :
1376 : 0 : shishi_verbose (handle, "Building KDC-REQ...");
1377 : :
1378 [ # # ]: 0 : if (shishi_asn1_empty_p (handle, kdcreq, "req-body.rtime"))
1379 : : {
1380 : 0 : res = shishi_asn1_write (handle, kdcreq, "req-body.rtime", NULL, 0);
1381 [ # # ]: 0 : if (res != SHISHI_OK)
1382 : : {
1383 : 0 : shishi_error_printf (handle, "Could not write rtime\n");
1384 : 0 : return res;
1385 : : }
1386 : : }
1387 : :
1388 [ # # ]: 0 : if (shishi_asn1_empty_p (handle, kdcreq, "req-body.from"))
1389 : : {
1390 : 0 : res = shishi_asn1_write (handle, kdcreq, "req-body.from", NULL, 0);
1391 [ # # ]: 0 : if (res != SHISHI_OK)
1392 : : {
1393 : 0 : shishi_error_printf (handle, "Could not write from\n");
1394 : 0 : return res;
1395 : : }
1396 : : }
1397 : :
1398 : 0 : res = shishi_asn1_read_integer (handle, kdcreq, "msg-type", &msgtype);
1399 [ # # ]: 0 : if (res != SHISHI_OK)
1400 : 0 : return res;
1401 [ # # ]: 0 : if (msgtype == SHISHI_MSGTYPE_AS_REQ)
1402 : : {
1403 : 0 : res = shishi_asn1_number_of_elements (handle, kdcreq, "padata", &n);
1404 [ # # # # ]: 0 : if (res == SHISHI_OK && n == 0)
1405 : : {
1406 : 0 : res = shishi_kdcreq_clear_padata (handle, kdcreq);
1407 [ # # ]: 0 : if (res != SHISHI_OK)
1408 : : {
1409 : 0 : shishi_error_printf (handle, "Could not write padata\n");
1410 : 0 : return res;
1411 : : }
1412 : : }
1413 : : }
1414 : :
1415 : 0 : return SHISHI_OK;
1416 : : }
|