Update gnulib files.
[shishi.git] / lib / krberror.c
blob46ecd77f9b5c91f545353a98cade722c7c6acfa8
1 /* krberror.c --- Functions related to KRB-ERROR packet.
2 * Copyright (C) 2002, 2003, 2004, 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_KRB_ERROR_DEFAULT_PVNO "5"
29 #define SHISHI_KRB_ERROR_DEFAULT_PVNO_LEN 0
30 #define SHISHI_KRB_ERROR_DEFAULT_MSG_TYPE "30"
31 #define SHISHI_KRB_ERROR_DEFAULT_MSG_TYPE_LEN 0
33 /**
34 * shishi_krberror:
35 * @handle: shishi handle as allocated by shishi_init().
37 * This function creates a new KRB-ERROR, populated with some default
38 * values.
40 * Return value: Returns the KRB-ERROR or NULL on failure.
41 **/
42 Shishi_asn1
43 shishi_krberror (Shishi * handle)
45 Shishi_asn1 krberror;
46 struct timeval tv;
47 int rc;
49 rc = gettimeofday (&tv, NULL);
50 if (rc != 0)
51 return NULL;
53 krberror = shishi_asn1_krberror (handle);
54 if (!krberror)
55 return NULL;
57 rc = shishi_asn1_write (handle, krberror, "pvno",
58 SHISHI_KRB_ERROR_DEFAULT_PVNO,
59 SHISHI_KRB_ERROR_DEFAULT_PVNO_LEN);
61 if (rc == SHISHI_OK)
62 rc = shishi_asn1_write (handle, krberror, "msg-type",
63 SHISHI_KRB_ERROR_DEFAULT_MSG_TYPE,
64 SHISHI_KRB_ERROR_DEFAULT_MSG_TYPE_LEN);
67 if (rc == SHISHI_OK)
68 rc = shishi_krberror_susec_set (handle, krberror, tv.tv_usec % 1000000);
70 if (rc == SHISHI_OK)
71 rc = shishi_asn1_write (handle, krberror, "stime",
72 shishi_generalize_now (handle), 0);
74 if (rc != SHISHI_OK)
76 shishi_error_printf (handle, "shishi_krberror() failed");
77 shishi_asn1_done (handle, krberror);
78 krberror = NULL;
81 return krberror;
84 /**
85 * shishi_krberror_print:
86 * @handle: shishi handle as allocated by shishi_init().
87 * @fh: file handle open for writing.
88 * @krberror: KRB-ERROR to print.
90 * Print ASCII armored DER encoding of KRB-ERROR to file.
92 * Return value: Returns SHISHI_OK iff successful.
93 **/
94 int
95 shishi_krberror_print (Shishi * handle, FILE * fh, Shishi_asn1 krberror)
97 return _shishi_print_armored_data (handle, fh, krberror, "KRB-ERROR", NULL);
101 * shishi_krberror_save:
102 * @handle: shishi handle as allocated by shishi_init().
103 * @fh: file handle open for writing.
104 * @krberror: KRB-ERROR to save.
106 * Save DER encoding of KRB-ERROR to file.
108 * Return value: Returns SHISHI_OK iff successful.
111 shishi_krberror_save (Shishi * handle, FILE * fh, Shishi_asn1 krberror)
113 return _shishi_save_data (handle, fh, krberror, "KRB-ERROR");
117 * shishi_krberror_to_file:
118 * @handle: shishi handle as allocated by shishi_init().
119 * @krberror: KRB-ERROR to save.
120 * @filetype: input variable specifying type of file to be written,
121 * see Shishi_filetype.
122 * @filename: input variable with filename to write to.
124 * Write KRB-ERROR to file in specified TYPE. The file will be
125 * truncated if it exists.
127 * Return value: Returns SHISHI_OK iff successful.
130 shishi_krberror_to_file (Shishi * handle, Shishi_asn1 krberror,
131 int filetype, const char *filename)
133 FILE *fh;
134 int res;
136 if (VERBOSE (handle))
137 printf (_("Writing KRB-ERROR to %s...\n"), filename);
139 fh = fopen (filename, "w");
140 if (fh == NULL)
141 return SHISHI_FOPEN_ERROR;
143 if (VERBOSE (handle))
144 printf (_("Writing KRB-ERROR in %s format...\n"),
145 filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
147 if (filetype == SHISHI_FILETYPE_TEXT)
148 res = shishi_krberror_print (handle, fh, krberror);
149 else
150 res = shishi_krberror_save (handle, fh, krberror);
151 if (res != SHISHI_OK)
152 return res;
154 res = fclose (fh);
155 if (res != 0)
156 return SHISHI_IO_ERROR;
158 if (VERBOSE (handle))
159 printf (_("Writing KRB-ERROR to %s...done\n"), filename);
161 return SHISHI_OK;
165 * shishi_krberror_parse:
166 * @handle: shishi handle as allocated by shishi_init().
167 * @fh: file handle open for reading.
168 * @krberror: output variable with newly allocated KRB-ERROR.
170 * Read ASCII armored DER encoded KRB-ERROR from file and populate given
171 * variable.
173 * Return value: Returns SHISHI_OK iff successful.
176 shishi_krberror_parse (Shishi * handle, FILE * fh, Shishi_asn1 * krberror)
178 return _shishi_krberror_input (handle, fh, krberror, 0);
182 * shishi_krberror_read:
183 * @handle: shishi handle as allocated by shishi_init().
184 * @fh: file handle open for reading.
185 * @krberror: output variable with newly allocated KRB-ERROR.
187 * Read DER encoded KRB-ERROR from file and populate given variable.
189 * Return value: Returns SHISHI_OK iff successful.
192 shishi_krberror_read (Shishi * handle, FILE * fh, Shishi_asn1 * krberror)
194 return _shishi_krberror_input (handle, fh, krberror, 1);
198 * shishi_krberror_from_file:
199 * @handle: shishi handle as allocated by shishi_init().
200 * @krberror: output variable with newly allocated KRB-ERROR.
201 * @filetype: input variable specifying type of file to be read,
202 * see Shishi_filetype.
203 * @filename: input variable with filename to read from.
205 * Read KRB-ERROR from file in specified TYPE.
207 * Return value: Returns SHISHI_OK iff successful.
210 shishi_krberror_from_file (Shishi * handle, Shishi_asn1 * krberror,
211 int filetype, const char *filename)
213 int res;
214 FILE *fh;
216 if (VERBOSE (handle))
217 printf (_("Reading KRB-ERROR from %s...\n"), filename);
219 fh = fopen (filename, "r");
220 if (fh == NULL)
221 return SHISHI_FOPEN_ERROR;
223 if (VERBOSE (handle))
224 printf (_("Reading KRB-ERROR in %s format...\n"),
225 filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
227 if (filetype == SHISHI_FILETYPE_TEXT)
228 res = shishi_krberror_parse (handle, fh, krberror);
229 else
230 res = shishi_krberror_read (handle, fh, krberror);
231 if (res != SHISHI_OK)
232 return res;
234 res = fclose (fh);
235 if (res != 0)
236 return SHISHI_IO_ERROR;
238 if (VERBOSE (handle))
239 printf (_("Reading KRB-ERROR from %s...done\n"), filename);
241 return SHISHI_OK;
245 * shishi_krberror_build:
246 * @handle: shishi handle as allocated by shishi_init().
247 * @krberror: krberror as allocated by shishi_krberror().
249 * Finish KRB-ERROR, called before e.g. shishi_krberror_der. This
250 * function removes empty but OPTIONAL fields (such as cname), and
252 * Return value: Returns SHISHI_OK iff successful.
255 shishi_krberror_build (Shishi * handle, Shishi_asn1 krberror)
257 char *t;
258 size_t tmplen = sizeof (t);
259 char *tmp;
260 int32_t errc;
261 uint32_t usec;
262 int rc;
264 rc = shishi_krberror_ctime (handle, krberror, &t);
265 if (rc != SHISHI_OK &&
266 rc != SHISHI_ASN1_NO_ELEMENT && rc != SHISHI_ASN1_NO_VALUE)
267 return rc;
268 free (t);
269 if (rc == SHISHI_ASN1_NO_VALUE)
271 rc = shishi_krberror_remove_ctime (handle, krberror);
272 if (rc != SHISHI_OK)
273 return rc;
276 rc = shishi_krberror_cusec (handle, krberror, &usec);
277 if (rc != SHISHI_OK &&
278 rc != SHISHI_ASN1_NO_ELEMENT && rc != SHISHI_ASN1_NO_VALUE)
279 return rc;
280 if (rc == SHISHI_ASN1_NO_VALUE)
282 rc = shishi_krberror_remove_cusec (handle, krberror);
283 if (rc != SHISHI_OK)
284 return rc;
287 rc = shishi_krberror_crealm (handle, krberror, &tmp, &tmplen);
288 if (rc != SHISHI_OK &&
289 rc != SHISHI_ASN1_NO_ELEMENT && rc != SHISHI_ASN1_NO_VALUE)
290 return rc;
291 if (rc == SHISHI_OK)
292 free (tmp);
293 if (rc == SHISHI_ASN1_NO_VALUE)
295 rc = shishi_krberror_remove_crealm (handle, krberror);
296 if (rc != SHISHI_OK)
297 return rc;
300 rc = shishi_krberror_client (handle, krberror, &tmp, &tmplen);
301 if (rc != SHISHI_OK &&
302 rc != SHISHI_ASN1_NO_ELEMENT && rc != SHISHI_ASN1_NO_VALUE)
303 return rc;
304 if (rc == SHISHI_OK)
305 free (tmp);
306 if (rc == SHISHI_ASN1_NO_VALUE || (rc == SHISHI_OK && tmplen == 0))
308 rc = shishi_krberror_remove_cname (handle, krberror);
309 if (rc != SHISHI_OK)
310 return rc;
313 rc = shishi_krberror_realm (handle, krberror, &tmp, &tmplen);
314 if (rc != SHISHI_OK && rc != SHISHI_ASN1_NO_VALUE)
315 return rc;
316 if (rc == SHISHI_OK)
317 free (tmp);
318 if (rc == SHISHI_ASN1_NO_VALUE)
320 rc = shishi_krberror_set_realm (handle, krberror, "");
321 if (rc != SHISHI_OK)
322 return rc;
325 rc = shishi_krberror_server (handle, krberror, &tmp, &tmplen);
326 if (rc != SHISHI_OK && rc != SHISHI_ASN1_NO_VALUE)
327 return rc;
328 if (rc == SHISHI_OK)
329 free (tmp);
330 if (rc == SHISHI_ASN1_NO_VALUE || tmplen == 0)
332 rc = shishi_krberror_remove_sname (handle, krberror);
333 if (rc != SHISHI_OK)
334 return rc;
337 rc = shishi_krberror_edata (handle, krberror, &tmp, &tmplen);
338 if (rc != SHISHI_OK &&
339 rc != SHISHI_ASN1_NO_ELEMENT && rc != SHISHI_ASN1_NO_VALUE)
340 return rc;
341 if (rc == SHISHI_OK)
342 free (tmp);
343 if (rc == SHISHI_ASN1_NO_VALUE || (rc == SHISHI_OK && tmplen == 0))
345 rc = shishi_krberror_remove_edata (handle, krberror);
346 if (rc != SHISHI_OK)
347 return rc;
350 rc = shishi_krberror_errorcode (handle, krberror, &errc);
351 if (rc != SHISHI_OK && rc != SHISHI_ASN1_NO_VALUE)
352 return rc;
353 if (rc == SHISHI_ASN1_NO_VALUE)
355 rc = shishi_krberror_errorcode_set (handle, krberror,
356 SHISHI_KRB_ERR_GENERIC);
357 if (rc != SHISHI_OK)
358 return rc;
361 rc = shishi_krberror_etext (handle, krberror, &tmp, &tmplen);
362 if (rc != SHISHI_OK &&
363 rc != SHISHI_ASN1_NO_ELEMENT && rc != SHISHI_ASN1_NO_VALUE)
364 return rc;
365 if (rc == SHISHI_OK)
366 free (tmp);
367 if (rc == SHISHI_ASN1_NO_VALUE || (rc == SHISHI_OK && tmplen == 0))
369 if (shishi_krberror_errorcode_fast (handle, krberror) ==
370 SHISHI_KRB_ERR_GENERIC)
371 rc = shishi_krberror_set_etext (handle, krberror,
372 "Uninitialized error");
373 else
374 rc = shishi_krberror_remove_etext (handle, krberror);
375 if (rc != SHISHI_OK)
376 return rc;
379 return SHISHI_OK;
383 * shishi_krberror_der:
384 * @handle: shishi handle as allocated by shishi_init().
385 * @krberror: krberror as allocated by shishi_krberror().
386 * @out: output array with newly allocated DER encoding of KRB-ERROR.
387 * @outlen: length of output array with DER encoding of KRB-ERROR.
389 * DER encode KRB-ERROR. The caller must deallocate the OUT buffer.
391 * Return value: Returns SHISHI_OK iff successful.
394 shishi_krberror_der (Shishi * handle,
395 Shishi_asn1 krberror, char **out, size_t * outlen)
397 int rc;
399 rc = shishi_krberror_build (handle, krberror);
400 if (rc != SHISHI_OK)
401 return rc;
403 rc = shishi_asn1_to_der (handle, krberror, out, outlen);
404 if (rc != SHISHI_OK)
405 return rc;
407 return SHISHI_OK;
411 * shishi_krberror_crealm:
412 * @handle: shishi handle as allocated by shishi_init().
413 * @krberror: krberror as allocated by shishi_krberror().
414 * @realm: output array with newly allocated name of realm in KRB-ERROR.
415 * @realmlen: size of output array.
417 * Extract client realm from KRB-ERROR.
419 * Return value: Returns SHISHI_OK iff successful.
422 shishi_krberror_crealm (Shishi * handle,
423 Shishi_asn1 krberror, char **realm, size_t * realmlen)
425 return shishi_asn1_read (handle, krberror, "crealm", realm, realmlen);
429 * shishi_krberror_remove_crealm:
430 * @handle: shishi handle as allocated by shishi_init().
431 * @krberror: krberror as allocated by shishi_krberror().
433 * Remove client realm field in KRB-ERROR.
435 * Return value: Returns SHISHI_OK iff successful.
438 shishi_krberror_remove_crealm (Shishi * handle, Shishi_asn1 krberror)
440 int res;
442 res = shishi_asn1_write (handle, krberror, "crealm", NULL, 0);
443 if (res != SHISHI_OK)
444 return res;
446 return SHISHI_OK;
450 * shishi_krberror_set_crealm:
451 * @handle: shishi handle as allocated by shishi_init().
452 * @krberror: krberror as allocated by shishi_krberror().
453 * @crealm: input array with realm.
455 * Set realm field in krberror to specified value.
457 * Return value: Returns SHISHI_OK iff successful.
460 shishi_krberror_set_crealm (Shishi * handle,
461 Shishi_asn1 krberror, const char *crealm)
463 int res;
465 res = shishi_asn1_write (handle, krberror, "crealm", crealm, 0);
466 if (res != SHISHI_OK)
467 return res;
469 return SHISHI_OK;
473 * shishi_krberror_client:
474 * @handle: shishi handle as allocated by shishi_init().
475 * @krberror: krberror as allocated by shishi_krberror().
476 * @client: pointer to newly allocated zero terminated string containing
477 * principal name. May be %NULL (to only populate @clientlen).
478 * @clientlen: pointer to length of @client on output, excluding terminating
479 * zero. May be %NULL (to only populate @client).
481 * Return client principal name in KRB-ERROR.
483 * Return value: Returns SHISHI_OK iff successful.
486 shishi_krberror_client (Shishi * handle,
487 Shishi_asn1 krberror,
488 char **client, size_t * clientlen)
490 int rc;
492 rc = shishi_principal_name (handle, krberror, "cname", client, clientlen);
493 if (rc != SHISHI_OK)
494 return rc;
496 return SHISHI_OK;
500 * shishi_krberror_set_cname:
501 * @handle: shishi handle as allocated by shishi_init().
502 * @krberror: krberror as allocated by shishi_krberror().
503 * @name_type: type of principial, see Shishi_name_type, usually
504 * SHISHI_NT_UNKNOWN.
505 * @cname: input array with principal name.
507 * Set principal field in krberror to specified value.
509 * Return value: Returns SHISHI_OK iff successful.
512 shishi_krberror_set_cname (Shishi * handle,
513 Shishi_asn1 krberror,
514 Shishi_name_type name_type, const char *cname[])
516 int res;
518 res = shishi_principal_name_set (handle, krberror, "cname",
519 name_type, cname);
520 if (res != SHISHI_OK)
521 return res;
523 return SHISHI_OK;
527 * shishi_krberror_remove_cname:
528 * @handle: shishi handle as allocated by shishi_init().
529 * @krberror: krberror as allocated by shishi_krberror().
531 * Remove client realm field in KRB-ERROR.
533 * Return value: Returns SHISHI_OK iff successful.
536 shishi_krberror_remove_cname (Shishi * handle, Shishi_asn1 krberror)
538 int res;
540 res = shishi_asn1_write (handle, krberror, "cname", NULL, 0);
541 if (res != SHISHI_OK)
542 return res;
544 return SHISHI_OK;
548 * shishi_krberror_client_set:
549 * @handle: shishi handle as allocated by shishi_init().
550 * @krberror: Krberror to set client name field in.
551 * @client: zero-terminated string with principal name on RFC 1964 form.
553 * Set the client name field in the Krberror.
555 * Return value: Returns SHISHI_OK iff successful.
558 shishi_krberror_client_set (Shishi * handle,
559 Shishi_asn1 krberror, const char *client)
561 int res;
563 res = shishi_principal_set (handle, krberror, "cname", client);
564 if (res != SHISHI_OK)
565 return res;
567 return SHISHI_OK;
571 * shishi_krberror_realm:
572 * @handle: shishi handle as allocated by shishi_init().
573 * @krberror: krberror as allocated by shishi_krberror().
574 * @realm: output array with newly allocated name of realm in KRB-ERROR.
575 * @realmlen: size of output array.
577 * Extract (server) realm from KRB-ERROR.
579 * Return value: Returns SHISHI_OK iff successful.
582 shishi_krberror_realm (Shishi * handle,
583 Shishi_asn1 krberror, char **realm, size_t * realmlen)
585 return shishi_asn1_read (handle, krberror, "realm", realm, realmlen);
589 * shishi_krberror_set_realm:
590 * @handle: shishi handle as allocated by shishi_init().
591 * @krberror: krberror as allocated by shishi_krberror().
592 * @realm: input array with (server) realm.
594 * Set (server) realm field in krberror to specified value.
596 * Return value: Returns SHISHI_OK iff successful.
599 shishi_krberror_set_realm (Shishi * handle,
600 Shishi_asn1 krberror, const char *realm)
602 int res;
604 res = shishi_asn1_write (handle, krberror, "realm", realm, 0);
605 if (res != SHISHI_OK)
606 return res;
608 return SHISHI_OK;
612 * shishi_krberror_server:
613 * @handle: shishi handle as allocated by shishi_init().
614 * @krberror: krberror as allocated by shishi_krberror().
615 * @server: pointer to newly allocated zero terminated string containing
616 * server name. May be %NULL (to only populate @serverlen).
617 * @serverlen: pointer to length of @server on output, excluding terminating
618 * zero. May be %NULL (to only populate @server).
620 * Return server principal name in KRB-ERROR.
622 * Return value: Returns SHISHI_OK iff successful.
625 shishi_krberror_server (Shishi * handle,
626 Shishi_asn1 krberror,
627 char **server, size_t * serverlen)
629 int rc;
631 rc = shishi_principal_name (handle, krberror, "sname", server, serverlen);
632 if (rc != SHISHI_OK)
633 return rc;
635 return SHISHI_OK;
639 * shishi_krberror_remove_sname:
640 * @handle: shishi handle as allocated by shishi_init().
641 * @krberror: Krberror to set server name field in.
643 * Remove server name field in KRB-ERROR. (Since it is not marked
644 * OPTIONAL in the ASN.1 profile, what is done is to set the name-type
645 * to UNKNOWN and make sure the name-string sequence is empty.)
647 * Return value: Returns SHISHI_OK iff successful.
650 shishi_krberror_remove_sname (Shishi * handle, Shishi_asn1 krberror)
652 int res;
654 res = shishi_asn1_write_int32 (handle, krberror, "sname.name-type",
655 SHISHI_NT_UNKNOWN);
656 if (res != SHISHI_OK)
657 return res;
659 res = shishi_asn1_write (handle, krberror, "sname.name-string", NULL, 0);
660 if (res != SHISHI_OK)
661 return res;
663 return SHISHI_OK;
667 * shishi_krberror_set_sname:
668 * @handle: shishi handle as allocated by shishi_init().
669 * @krberror: krberror as allocated by shishi_krberror().
670 * @name_type: type of principial, see Shishi_name_type, usually
671 * SHISHI_NT_UNKNOWN.
672 * @sname: input array with principal name.
674 * Set principal field in krberror to specified value.
676 * Return value: Returns SHISHI_OK iff successful.
679 shishi_krberror_set_sname (Shishi * handle,
680 Shishi_asn1 krberror,
681 Shishi_name_type name_type, const char *sname[])
683 int res;
685 res = shishi_principal_name_set (handle, krberror, "sname",
686 name_type, sname);
687 if (res != SHISHI_OK)
688 return res;
690 return SHISHI_OK;
694 * shishi_krberror_server_set:
695 * @handle: shishi handle as allocated by shishi_init().
696 * @krberror: Krberror to set server name field in.
697 * @server: zero-terminated string with principal name on RFC 1964 form.
699 * Set the server name field in the Krberror.
701 * Return value: Returns SHISHI_OK iff successful.
704 shishi_krberror_server_set (Shishi * handle,
705 Shishi_asn1 krberror, const char *server)
707 int res;
709 res = shishi_principal_set (handle, krberror, "sname", server);
710 if (res != SHISHI_OK)
711 return res;
713 return SHISHI_OK;
717 * shishi_krberror_ctime:
718 * @handle: shishi handle as allocated by shishi_init().
719 * @krberror: Krberror to set client name field in.
720 * @t: newly allocated zero-terminated output array with client time.
722 * Extract client time from KRB-ERROR.
724 * Return value: Returns SHISHI_OK iff successful.
727 shishi_krberror_ctime (Shishi * handle, Shishi_asn1 krberror, char **t)
729 return shishi_time (handle, krberror, "ctime", t);
733 * shishi_krberror_ctime_set:
734 * @handle: shishi handle as allocated by shishi_init().
735 * @krberror: Krberror as allocated by shishi_krberror().
736 * @t: string with generalized time value to store in Krberror.
738 * Store client time in Krberror.
740 * Return value: Returns SHISHI_OK iff successful.
743 shishi_krberror_ctime_set (Shishi * handle,
744 Shishi_asn1 krberror, const char *t)
746 int res;
748 if (t)
749 res = shishi_asn1_write (handle, krberror, "ctime",
750 t, SHISHI_GENERALIZEDTIME_LENGTH);
751 else
752 res = shishi_asn1_write (handle, krberror, "ctime", NULL, 0);
753 if (res != SHISHI_OK)
754 return res;
756 return SHISHI_OK;
760 * shishi_krberror_remove_ctime:
761 * @handle: shishi handle as allocated by shishi_init().
762 * @krberror: Krberror as allocated by shishi_krberror().
764 * Remove client time field in Krberror.
766 * Return value: Returns SHISHI_OK iff successful.
769 shishi_krberror_remove_ctime (Shishi * handle, Shishi_asn1 krberror)
771 int res;
773 res = shishi_asn1_write (handle, krberror, "ctime", NULL, 0);
774 if (res != SHISHI_OK)
775 return res;
777 return SHISHI_OK;
781 * shishi_krberror_cusec:
782 * @handle: shishi handle as allocated by shishi_init().
783 * @krberror: Krberror as allocated by shishi_krberror().
784 * @cusec: output integer with client microseconds field.
786 * Extract client microseconds field from Krberror.
788 * Return value: Returns SHISHI_OK iff successful.
791 shishi_krberror_cusec (Shishi * handle, Shishi_asn1 krberror,
792 uint32_t * cusec)
794 int res;
796 res = shishi_asn1_read_uint32 (handle, krberror, "cusec", cusec);
797 if (res != SHISHI_OK)
798 return res;
800 return SHISHI_OK;
804 * shishi_krberror_cusec_set:
805 * @handle: shishi handle as allocated by shishi_init().
806 * @krberror: krberror as allocated by shishi_krberror().
807 * @cusec: client microseconds to set in krberror, 0-999999.
809 * Set the cusec field in the Krberror.
811 * Return value: Returns SHISHI_OK iff successful.
814 shishi_krberror_cusec_set (Shishi * handle,
815 Shishi_asn1 krberror, uint32_t cusec)
817 int res;
819 res = shishi_asn1_write_uint32 (handle, krberror, "cusec", cusec);
820 if (res != SHISHI_OK)
821 return res;
823 return SHISHI_OK;
827 * shishi_krberror_remove_cusec:
828 * @handle: shishi handle as allocated by shishi_init().
829 * @krberror: Krberror as allocated by shishi_krberror().
831 * Remove client usec field in Krberror.
833 * Return value: Returns SHISHI_OK iff successful.
836 shishi_krberror_remove_cusec (Shishi * handle, Shishi_asn1 krberror)
838 int res;
840 res = shishi_asn1_write (handle, krberror, "cusec", NULL, 0);
841 if (res != SHISHI_OK)
842 return res;
844 return SHISHI_OK;
848 * shishi_krberror_stime:
849 * @handle: shishi handle as allocated by shishi_init().
850 * @krberror: Krberror to set client name field in.
851 * @t: newly allocated zero-terminated output array with server time.
853 * Extract server time from KRB-ERROR.
855 * Return value: Returns SHISHI_OK iff successful.
858 shishi_krberror_stime (Shishi * handle, Shishi_asn1 krberror, char **t)
860 return shishi_time (handle, krberror, "stime", t);
864 * shishi_krberror_stime_set:
865 * @handle: shishi handle as allocated by shishi_init().
866 * @krberror: Krberror as allocated by shishi_krberror().
867 * @t: string with generalized time value to store in Krberror.
869 * Store server time in Krberror.
871 * Return value: Returns SHISHI_OK iff successful.
874 shishi_krberror_stime_set (Shishi * handle,
875 Shishi_asn1 krberror, const char *t)
877 int res;
879 res = shishi_asn1_write (handle, krberror, "stime",
880 t, SHISHI_GENERALIZEDTIME_LENGTH);
881 if (res != SHISHI_OK)
882 return res;
884 return SHISHI_OK;
888 * shishi_krberror_susec:
889 * @handle: shishi handle as allocated by shishi_init().
890 * @krberror: Krberror as allocated by shishi_krberror().
891 * @susec: output integer with server microseconds field.
893 * Extract server microseconds field from Krberror.
895 * Return value: Returns SHISHI_OK iff successful.
898 shishi_krberror_susec (Shishi * handle,
899 Shishi_asn1 krberror, uint32_t * susec)
901 int res;
903 res = shishi_asn1_read_uint32 (handle, krberror, "susec", susec);
904 if (res != SHISHI_OK)
905 return res;
907 return SHISHI_OK;
911 * shishi_krberror_susec_set:
912 * @handle: shishi handle as allocated by shishi_init().
913 * @krberror: krberror as allocated by shishi_krberror().
914 * @susec: server microseconds to set in krberror, 0-999999.
916 * Set the susec field in the Krberror.
918 * Return value: Returns SHISHI_OK iff successful.
921 shishi_krberror_susec_set (Shishi * handle,
922 Shishi_asn1 krberror, uint32_t susec)
924 int res;
926 res = shishi_asn1_write_uint32 (handle, krberror, "susec", susec);
927 if (res != SHISHI_OK)
928 return res;
930 return SHISHI_OK;
934 * shishi_krberror_errorcode:
935 * @handle: shishi handle as allocated by shishi_init().
936 * @krberror: KRB-ERROR structure with error code.
937 * @errorcode: output integer KRB-ERROR error code.
939 * Extract error code from KRB-ERROR.
941 * Return value: Returns SHISHI_OK iff successful.
944 shishi_krberror_errorcode (Shishi * handle,
945 Shishi_asn1 krberror, int32_t * errorcode)
947 return shishi_asn1_read_int32 (handle, krberror, "error-code", errorcode);
951 * shishi_krberror_errorcode_fast:
952 * @handle: shishi handle as allocated by shishi_init().
953 * @krberror: KRB-ERROR structure with error code.
955 * Get error code from KRB-ERROR, without error checking.
957 * Return value: Return error code (see shishi_krberror_errorcode())
958 * directly, or -1 on error.
961 shishi_krberror_errorcode_fast (Shishi * handle, Shishi_asn1 krberror)
963 int i;
965 if (shishi_krberror_errorcode (handle, krberror, &i) != SHISHI_OK)
966 i = -1;
968 return i;
972 * shishi_krberror_errorcode_set:
973 * @handle: shishi handle as allocated by shishi_init().
974 * @krberror: KRB-ERROR structure with error code to set.
975 * @errorcode: new error code to set in krberror.
977 * Set the error-code field to a new error code.
979 * Return value: Returns SHISHI_OK iff successful.
982 shishi_krberror_errorcode_set (Shishi * handle,
983 Shishi_asn1 krberror, int errorcode)
985 int res;
987 res = shishi_asn1_write_int32 (handle, krberror, "error-code", errorcode);
988 if (res != SHISHI_OK)
989 return res;
991 return SHISHI_OK;
995 * shishi_krberror_etext:
996 * @handle: shishi handle as allocated by shishi_init().
997 * @krberror: KRB-ERROR structure with error code.
998 * @etext: output array with newly allocated error text.
999 * @etextlen: output length of error text.
1001 * Extract additional error text from server (possibly empty).
1003 * Return value: Returns SHISHI_OK iff successful.
1006 shishi_krberror_etext (Shishi * handle, Shishi_asn1 krberror,
1007 char **etext, size_t * etextlen)
1009 return shishi_asn1_read (handle, krberror, "e-text", etext, etextlen);
1013 * shishi_krberror_set_etext:
1014 * @handle: shishi handle as allocated by shishi_init().
1015 * @krberror: krberror as allocated by shishi_krberror().
1016 * @etext: input array with error text to set.
1018 * Set error text (e-text) field in KRB-ERROR to specified value.
1020 * Return value: Returns SHISHI_OK iff successful.
1023 shishi_krberror_set_etext (Shishi * handle,
1024 Shishi_asn1 krberror, const char *etext)
1026 int res;
1028 res = shishi_asn1_write (handle, krberror, "e-text", etext, 0);
1029 if (res != SHISHI_OK)
1030 return res;
1032 return SHISHI_OK;
1036 * shishi_krberror_remove_etext:
1037 * @handle: shishi handle as allocated by shishi_init().
1038 * @krberror: krberror as allocated by shishi_krberror().
1040 * Remove error text (e-text) field in KRB-ERROR.
1042 * Return value: Returns SHISHI_OK iff successful.
1045 shishi_krberror_remove_etext (Shishi * handle, Shishi_asn1 krberror)
1047 int res;
1049 res = shishi_asn1_write (handle, krberror, "e-text", NULL, 0);
1050 if (res != SHISHI_OK)
1051 return res;
1053 return SHISHI_OK;
1057 * shishi_krberror_edata:
1058 * @handle: shishi handle as allocated by shishi_init().
1059 * @krberror: KRB-ERROR structure with error code.
1060 * @edata: output array with newly allocated error data.
1061 * @edatalen: output length of error data.
1063 * Extract additional error data from server (possibly empty).
1065 * Return value: Returns SHISHI_OK iff successful.
1068 shishi_krberror_edata (Shishi * handle, Shishi_asn1 krberror,
1069 char **edata, size_t * edatalen)
1071 return shishi_asn1_read (handle, krberror, "e-data", edata, edatalen);
1075 * shishi_krberror_methoddata:
1076 * @handle: shishi handle as allocated by shishi_init().
1077 * @krberror: KRB-ERROR structure with error code.
1078 * @methoddata: output ASN.1 METHOD-DATA.
1080 * Extract METHOD-DATA ASN.1 object from the e-data field. The e-data
1081 * field will only contain a METHOD-DATA if the krberror error code is
1082 * %SHISHI_KDC_ERR_PREAUTH_REQUIRED.
1084 * Return value: Returns SHISHI_OK iff successful.
1087 shishi_krberror_methoddata (Shishi * handle, Shishi_asn1 krberror,
1088 Shishi_asn1 *methoddata)
1090 int rc;
1092 *methoddata = NULL;
1094 if (shishi_krberror_errorcode_fast (handle, krberror)
1095 == SHISHI_KDC_ERR_PREAUTH_REQUIRED)
1097 char *buf;
1098 size_t len;
1100 rc = shishi_krberror_edata (handle, krberror, &buf, &len);
1101 if (rc != SHISHI_OK)
1102 return rc;
1104 *methoddata = shishi_der2asn1_methoddata (handle, buf, len);
1105 free (buf);
1106 if (!*methoddata)
1107 return SHISHI_ASN1_ERROR;
1110 return SHISHI_OK;
1114 * shishi_krberror_set_edata:
1115 * @handle: shishi handle as allocated by shishi_init().
1116 * @krberror: krberror as allocated by shishi_krberror().
1117 * @edata: input array with error text to set.
1119 * Set error text (e-data) field in KRB-ERROR to specified value.
1121 * Return value: Returns SHISHI_OK iff successful.
1124 shishi_krberror_set_edata (Shishi * handle,
1125 Shishi_asn1 krberror, const char *edata)
1127 int res;
1129 res = shishi_asn1_write (handle, krberror, "e-data", edata, 0);
1130 if (res != SHISHI_OK)
1131 return res;
1133 return SHISHI_OK;
1137 * shishi_krberror_remove_edata:
1138 * @handle: shishi handle as allocated by shishi_init().
1139 * @krberror: krberror as allocated by shishi_krberror().
1141 * Remove error text (e-data) field in KRB-ERROR.
1143 * Return value: Returns SHISHI_OK iff successful.
1146 shishi_krberror_remove_edata (Shishi * handle, Shishi_asn1 krberror)
1148 int res;
1150 res = shishi_asn1_write (handle, krberror, "e-data", NULL, 0);
1151 if (res != SHISHI_OK)
1152 return res;
1154 return SHISHI_OK;
1158 * shishi_krberror_pretty_print:
1159 * @handle: shishi handle as allocated by shishi_init().
1160 * @fh: file handle opened for writing.
1161 * @krberror: KRB-ERROR structure with error code.
1163 * Print KRB-ERROR error condition and some explanatory text to file
1164 * descriptor.
1166 * Return value: Returns SHISHI_OK iff successful.
1169 shishi_krberror_pretty_print (Shishi * handle, FILE * fh,
1170 Shishi_asn1 krberror)
1172 char *buf;
1173 size_t len;
1174 int res;
1176 if (VERBOSEASN1 (handle))
1177 shishi_krberror_print (handle, fh, krberror);
1179 if (shishi_krberror_errorcode_fast (handle, krberror) ==
1180 SHISHI_KRB_ERR_GENERIC)
1182 fprintf (fh, "Generic error from server:\n");
1184 res = shishi_krberror_etext (handle, krberror, &buf, &len);
1185 if (res == SHISHI_OK && len > 0)
1187 buf[len] = '\0';
1188 fprintf (fh, "%s\n", buf);
1189 free (buf);
1192 else
1194 fprintf (fh, "Error code from server:\n%s\n",
1195 shishi_krberror_message (handle, krberror));
1197 res = shishi_krberror_etext (handle, krberror, &buf, &len);
1198 if (res == SHISHI_OK && len > 0)
1200 buf[len] = '\0';
1201 fprintf (fh, "Additional error message from server:\n%s\n", buf);
1202 free (buf);
1205 if (shishi_krberror_errorcode_fast (handle, krberror) ==
1206 SHISHI_KDC_ERR_PREAUTH_REQUIRED)
1208 Shishi_asn1 pas;
1209 size_t i, n;
1211 res = shishi_krberror_methoddata (handle, krberror, &pas);
1212 if (res != SHISHI_OK)
1213 return res;
1215 if (VERBOSEASN1 (handle))
1216 shishi_methoddata_print (handle, stdout, pas);
1218 res = shishi_asn1_number_of_elements (handle, pas, "", &n);
1219 if (res == SHISHI_OK)
1221 fprintf (fh, "Types of PA-DATA in KRB-ERROR: ");
1223 for (i = 1; i <= n; i++)
1225 char *format = xasprintf ("?%d.padata-type", i);
1226 int32_t padatatype;
1228 if (i > 1)
1229 fprintf (fh, ", ");
1231 res = shishi_asn1_read_int32 (handle, pas, format,
1232 &padatatype);
1233 if (res == SHISHI_OK)
1234 printf ("%d", padatatype);
1236 free (format);
1239 fprintf (fh, ".\n");
1242 shishi_asn1_done (handle, pas);
1247 return SHISHI_OK;
1250 struct krb_error_msgs
1252 int errorcode;
1253 const char *message;
1256 static const struct krb_error_msgs
1257 _shishi_krberror_messages[SHISHI_LAST_ERROR_CODE] = {
1258 {SHISHI_KDC_ERR_NONE,
1259 N_("No error")},
1260 {SHISHI_KDC_ERR_NAME_EXP,
1261 N_("Client's entry in database has expired")},
1262 {SHISHI_KDC_ERR_SERVICE_EXP,
1263 N_("Server's entry in database has expired")},
1264 {SHISHI_KDC_ERR_BAD_PVNO,
1265 N_("Requested protocol version number not supported")},
1266 {SHISHI_KDC_ERR_C_OLD_MAST_KVNO,
1267 N_("Client's key encrypted in old master key")},
1268 {SHISHI_KDC_ERR_S_OLD_MAST_KVNO,
1269 N_("Server's key encrypted in old master key")},
1270 {SHISHI_KDC_ERR_C_PRINCIPAL_UNKNOWN,
1271 N_("Client not found in database")},
1272 {SHISHI_KDC_ERR_S_PRINCIPAL_UNKNOWN,
1273 N_("Server not found in database")},
1274 {SHISHI_KDC_ERR_PRINCIPAL_NOT_UNIQUE,
1275 N_("Multiple principal entries in database")},
1276 {SHISHI_KDC_ERR_NULL_KEY,
1277 N_("The client or server has a null key")},
1278 {SHISHI_KDC_ERR_CANNOT_POSTDATE,
1279 N_("Ticket not eligible for postdating")},
1280 {SHISHI_KDC_ERR_NEVER_VALID,
1281 N_("Requested start time is later than end time")},
1282 {SHISHI_KDC_ERR_POLICY,
1283 N_("KDC policy rejects request")},
1284 {SHISHI_KDC_ERR_BADOPTION,
1285 N_("KDC cannot accommodate requested option")},
1286 {SHISHI_KDC_ERR_ETYPE_NOSUPP,
1287 N_("KDC has no support for encryption type")},
1288 {SHISHI_KDC_ERR_SUMTYPE_NOSUPP,
1289 N_("KDC has no support for checksum type")},
1290 {SHISHI_KDC_ERR_PADATA_TYPE_NOSUPP,
1291 N_("KDC has no support for padata type")},
1292 {SHISHI_KDC_ERR_TRTYPE_NOSUPP,
1293 N_("KDC has no support for transited type")},
1294 {SHISHI_KDC_ERR_CLIENT_REVOKED,
1295 N_("Clients credentials have been revoked")},
1296 {SHISHI_KDC_ERR_SERVICE_REVOKED,
1297 N_("Credentials for server have been revoked")},
1298 {SHISHI_KDC_ERR_TGT_REVOKED,
1299 N_("TGT has been revoked")},
1300 {SHISHI_KDC_ERR_CLIENT_NOTYET,
1301 N_("Client not yet valid - try again later")},
1302 {SHISHI_KDC_ERR_SERVICE_NOTYET,
1303 N_("Server not yet valid - try again later")},
1304 {SHISHI_KDC_ERR_KEY_EXPIRED,
1305 N_("Password has expired ")},
1306 {SHISHI_KDC_ERR_PREAUTH_FAILED,
1307 N_("Pre-authentication information was invalid")},
1308 {SHISHI_KDC_ERR_PREAUTH_REQUIRED,
1309 N_("Additional pre-authentication required")},
1310 {SHISHI_KDC_ERR_SERVER_NOMATCH,
1311 N_("Requested server and ticket don't match")},
1312 {SHISHI_KDC_ERR_MUST_USE_USER2USER,
1313 N_("Server principal valid for user2user only")},
1314 {SHISHI_KDC_ERR_PATH_NOT_ACCPETED,
1315 N_("KDC Policy rejects transited path")},
1316 {SHISHI_KDC_ERR_SVC_UNAVAILABLE,
1317 N_("A service is not available")},
1318 {SHISHI_KRB_AP_ERR_BAD_INTEGRITY,
1319 N_("Integrity check on decrypted field failed")},
1320 {SHISHI_KRB_AP_ERR_TKT_EXPIRED,
1321 N_("Ticket expired")},
1322 {SHISHI_KRB_AP_ERR_TKT_NYV,
1323 N_("Ticket not yet valid")},
1324 {SHISHI_KRB_AP_ERR_REPEAT,
1325 N_("Request is a replay")},
1326 {SHISHI_KRB_AP_ERR_NOT_US,
1327 N_("The ticket isn't for us")},
1328 {SHISHI_KRB_AP_ERR_BADMATCH,
1329 N_("Ticket and authenticator don't match")},
1330 {SHISHI_KRB_AP_ERR_SKEW,
1331 N_("Clock skew too great")},
1332 {SHISHI_KRB_AP_ERR_BADADDR,
1333 N_("Incorrect net address")},
1334 {SHISHI_KRB_AP_ERR_BADVERSION,
1335 N_("Protocol version mismatch")},
1336 {SHISHI_KRB_AP_ERR_MSG_TYPE,
1337 N_("Invalid msg type")},
1338 {SHISHI_KRB_AP_ERR_MODIFIED,
1339 N_("Message stream modified")},
1340 {SHISHI_KRB_AP_ERR_BADORDER,
1341 N_("Message out of order")},
1342 {SHISHI_KRB_AP_ERR_BADKEYVER,
1343 N_("Specified version of key is not available")},
1344 {SHISHI_KRB_AP_ERR_NOKEY,
1345 N_("Service key not available")},
1346 {SHISHI_KRB_AP_ERR_MUT_FAIL,
1347 N_("Mutual authentication failed")},
1348 {SHISHI_KRB_AP_ERR_BADDIRECTION,
1349 N_("Incorrect message direction")},
1350 {SHISHI_KRB_AP_ERR_METHOD,
1351 N_("Alternative authentication method required")},
1352 {SHISHI_KRB_AP_ERR_BADSEQ,
1353 N_("Incorrect sequence number in message")},
1354 {SHISHI_KRB_AP_ERR_INAPP_CKSUM,
1355 N_("Inappropriate type of checksum in message")},
1356 {SHISHI_KRB_AP_PATH_NOT_ACCEPTED,
1357 N_("Policy rejects transited path")},
1358 {SHISHI_KRB_ERR_RESPONSE_TOO_BIG,
1359 N_("Response too big for UDP, retry with TCP")},
1360 {SHISHI_KRB_ERR_GENERIC,
1361 N_("Generic error (description in e-text)")},
1362 {SHISHI_KRB_ERR_FIELD_TOOLONG,
1363 N_("Field is too long for this implementation")},
1364 {SHISHI_KDC_ERROR_CLIENT_NOT_TRUSTED,
1365 N_("(pkinit)")},
1366 {SHISHI_KDC_ERROR_KDC_NOT_TRUSTED,
1367 N_("(pkinit)")},
1368 {SHISHI_KDC_ERROR_INVALID_SIG,
1369 N_("(pkinit)")},
1370 {SHISHI_KDC_ERR_KEY_TOO_WEAK,
1371 N_("(pkinit)")},
1372 {SHISHI_KDC_ERR_CERTIFICATE_MISMATCH,
1373 N_("(pkinit)")},
1374 {SHISHI_KRB_AP_ERR_NO_TGT,
1375 N_("(user-to-user)")},
1376 {SHISHI_KDC_ERR_WRONG_REALM,
1377 N_("(user-to-user)")},
1378 {SHISHI_KRB_AP_ERR_USER_TO_USER_REQUIRED,
1379 N_("(user-to-user)")},
1380 {SHISHI_KDC_ERR_CANT_VERIFY_CERTIFICATE,
1381 N_("(pkinit)")},
1382 {SHISHI_KDC_ERR_INVALID_CERTIFICATE,
1383 N_("(pkinit)")},
1384 {SHISHI_KDC_ERR_REVOKED_CERTIFICATE,
1385 N_("(pkinit)")},
1386 {SHISHI_KDC_ERR_REVOCATION_STATUS_UNKNOWN,
1387 N_("(pkinit)")},
1388 {SHISHI_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE,
1389 N_("(pkinit)")},
1390 {SHISHI_KDC_ERR_CLIENT_NAME_MISMATCH,
1391 N_("(pkinit)")},
1392 {SHISHI_KDC_ERR_KDC_NAME_MISMATCH,
1393 N_("(pkinit)")}
1397 * shishi_krberror_errorcode_message:
1398 * @handle: shishi handle as allocated by shishi_init().
1399 * @errorcode: integer KRB-ERROR error code.
1401 * Get human readable string describing KRB-ERROR code.
1403 * Return value: Return a string describing error code. This function
1404 * will always return a string even if the error code
1405 * isn't known.
1407 const char *
1408 shishi_krberror_errorcode_message (Shishi * handle, int errorcode)
1410 int i;
1411 char *p;
1413 for (i = 0; i < SHISHI_LAST_ERROR_CODE; i++)
1415 if (errorcode == _shishi_krberror_messages[i].errorcode)
1416 return _(_shishi_krberror_messages[i].message);
1419 /* XXX memory leak */
1420 asprintf (&p, _("Unknown KRB-ERROR error code %d."), errorcode);
1421 return p;
1425 * shishi_krberror_message:
1426 * @handle: shishi handle as allocated by shishi_init().
1427 * @krberror: KRB-ERROR structure with error code.
1429 * Extract error code (see shishi_krberror_errorcode_fast()) and
1430 * return error message (see shishi_krberror_errorcode_message()).
1432 * Return value: Return a string describing error code. This function
1433 * will always return a string even if the error code
1434 * isn't known.
1436 const char *
1437 shishi_krberror_message (Shishi * handle, Shishi_asn1 krberror)
1439 return shishi_krberror_errorcode_message
1440 (handle, shishi_krberror_errorcode_fast (handle, krberror));