Fix messages.
[shishi.git] / lib / krberror.c
blob0837bc7a4b8d98e15c45f2577f380f4a8dd85bd7
1 /* krberror.c Functions related to KRB-ERROR packet.
2 * Copyright (C) 2002, 2003 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "internal.h"
24 #define SHISHI_KRB_ERROR_DEFAULT_PVNO "5"
25 #define SHISHI_KRB_ERROR_DEFAULT_PVNO_LEN 0
26 #define SHISHI_KRB_ERROR_DEFAULT_MSG_TYPE "30"
27 #define SHISHI_KRB_ERROR_DEFAULT_MSG_TYPE_LEN 0
29 /**
30 * shishi_krberror:
31 * @handle: shishi handle as allocated by shishi_init().
33 * This function creates a new KRB-ERROR, populated with some default
34 * values.
36 * Return value: Returns the KRB-ERROR or NULL on failure.
37 **/
38 Shishi_asn1
39 shishi_krberror (Shishi * handle)
41 Shishi_asn1 krberror;
42 struct timeval tv;
43 struct timezone tz;
44 int rc;
46 xgettimeofday (&tv, &tz);
48 krberror = shishi_asn1_krberror (handle);
49 if (!krberror)
50 return NULL;
52 rc = shishi_asn1_write (handle, krberror, "pvno",
53 SHISHI_KRB_ERROR_DEFAULT_PVNO,
54 SHISHI_KRB_ERROR_DEFAULT_PVNO_LEN);
56 if (rc == SHISHI_OK)
57 rc = shishi_asn1_write (handle, krberror, "msg-type",
58 SHISHI_KRB_ERROR_DEFAULT_MSG_TYPE,
59 SHISHI_KRB_ERROR_DEFAULT_MSG_TYPE_LEN);
62 if (rc == SHISHI_OK)
63 rc = shishi_krberror_susec_set (handle, krberror, tv.tv_usec % 1000000);
65 if (rc == SHISHI_OK)
66 rc = shishi_asn1_write (handle, krberror, "stime",
67 shishi_generalize_now (handle), 0);
69 if (rc != SHISHI_OK)
71 shishi_error_printf (handle, "shishi_krberror() failed");
72 shishi_asn1_done (handle, krberror);
73 krberror = NULL;
76 return krberror;
79 /**
80 * shishi_krberror_print:
81 * @handle: shishi handle as allocated by shishi_init().
82 * @fh: file handle open for writing.
83 * @krberror: KRB-ERROR to print.
85 * Print ASCII armored DER encoding of KRB-ERROR to file.
87 * Return value: Returns SHISHI_OK iff successful.
88 **/
89 int
90 shishi_krberror_print (Shishi * handle, FILE * fh, Shishi_asn1 krberror)
92 return _shishi_print_armored_data (handle, fh, krberror, "KRB-ERROR", NULL);
95 /**
96 * shishi_krberror_save:
97 * @handle: shishi handle as allocated by shishi_init().
98 * @fh: file handle open for writing.
99 * @krberror: KRB-ERROR to save.
101 * Save DER encoding of KRB-ERROR to file.
103 * Return value: Returns SHISHI_OK iff successful.
106 shishi_krberror_save (Shishi * handle, FILE * fh, Shishi_asn1 krberror)
108 return _shishi_save_data (handle, fh, krberror, "KRB-ERROR");
112 * shishi_krberror_to_file:
113 * @handle: shishi handle as allocated by shishi_init().
114 * @krberror: KRB-ERROR to save.
115 * @filetype: input variable specifying type of file to be written,
116 * see Shishi_filetype.
117 * @filename: input variable with filename to write to.
119 * Write KRB-ERROR to file in specified TYPE. The file will be
120 * truncated if it exists.
122 * Return value: Returns SHISHI_OK iff successful.
125 shishi_krberror_to_file (Shishi * handle, Shishi_asn1 krberror,
126 int filetype, char *filename)
128 FILE *fh;
129 int res;
131 if (VERBOSE (handle))
132 printf (_("Writing KRB-ERROR to %s...\n"), filename);
134 fh = fopen (filename, "w");
135 if (fh == NULL)
136 return SHISHI_FOPEN_ERROR;
138 if (VERBOSE (handle))
139 printf (_("Writing KRB-ERROR in %s format...\n"),
140 filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
142 if (filetype == SHISHI_FILETYPE_TEXT)
143 res = shishi_krberror_print (handle, fh, krberror);
144 else
145 res = shishi_krberror_save (handle, fh, krberror);
146 if (res != SHISHI_OK)
147 return res;
149 res = fclose (fh);
150 if (res != 0)
151 return SHISHI_FCLOSE_ERROR;
153 if (VERBOSE (handle))
154 printf (_("Writing KRB-ERROR to %s...done\n"), filename);
156 return SHISHI_OK;
160 * shishi_krberror_parse:
161 * @handle: shishi handle as allocated by shishi_init().
162 * @fh: file handle open for reading.
163 * @krberror: output variable with newly allocated KRB-ERROR.
165 * Read ASCII armored DER encoded KRB-ERROR from file and populate given
166 * variable.
168 * Return value: Returns SHISHI_OK iff successful.
171 shishi_krberror_parse (Shishi * handle, FILE * fh, Shishi_asn1 * krberror)
173 return _shishi_krberror_input (handle, fh, krberror, 0);
177 * shishi_krberror_read:
178 * @handle: shishi handle as allocated by shishi_init().
179 * @fh: file handle open for reading.
180 * @krberror: output variable with newly allocated KRB-ERROR.
182 * Read DER encoded KRB-ERROR from file and populate given variable.
184 * Return value: Returns SHISHI_OK iff successful.
187 shishi_krberror_read (Shishi * handle, FILE * fh, Shishi_asn1 * krberror)
189 return _shishi_krberror_input (handle, fh, krberror, 1);
193 * shishi_krberror_from_file:
194 * @handle: shishi handle as allocated by shishi_init().
195 * @krberror: output variable with newly allocated KRB-ERROR.
196 * @filetype: input variable specifying type of file to be read,
197 * see Shishi_filetype.
198 * @filename: input variable with filename to read from.
200 * Read KRB-ERROR from file in specified TYPE.
202 * Return value: Returns SHISHI_OK iff successful.
205 shishi_krberror_from_file (Shishi * handle, Shishi_asn1 * krberror,
206 int filetype, char *filename)
208 int res;
209 FILE *fh;
211 if (VERBOSE (handle))
212 printf (_("Reading KRB-ERROR from %s...\n"), filename);
214 fh = fopen (filename, "r");
215 if (fh == NULL)
216 return SHISHI_FOPEN_ERROR;
218 if (VERBOSE (handle))
219 printf (_("Reading KRB-ERROR in %s format...\n"),
220 filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
222 if (filetype == SHISHI_FILETYPE_TEXT)
223 res = shishi_krberror_parse (handle, fh, krberror);
224 else
225 res = shishi_krberror_read (handle, fh, krberror);
226 if (res != SHISHI_OK)
227 return res;
229 res = fclose (fh);
230 if (res != 0)
231 return SHISHI_FCLOSE_ERROR;
233 if (VERBOSE (handle))
234 printf (_("Reading KRB-ERROR from %s...done\n"), filename);
236 return SHISHI_OK;
240 * shishi_krberror_build:
241 * @handle: shishi handle as allocated by shishi_init().
242 * @krberror: krberror as allocated by shishi_krberror().
244 * Finish KRB-ERROR, called before e.g. shishi_krberror_der. This
245 * function removes empty but OPTIONAL fields (such as cname), and
247 * Return value: Returns SHISHI_OK iff successful.
250 shishi_krberror_build (Shishi * handle, Shishi_asn1 krberror)
252 char *time;
253 size_t tmplen = sizeof (time);
254 char *tmp;
255 int32_t errc;
256 int usec;
257 int rc;
259 rc = shishi_krberror_ctime (handle, krberror, &time);
260 if (rc != SHISHI_OK &&
261 rc != SHISHI_ASN1_NO_ELEMENT && rc != SHISHI_ASN1_NO_VALUE)
262 return rc;
263 free (time);
264 if (rc == SHISHI_ASN1_NO_VALUE)
266 rc = shishi_krberror_remove_ctime (handle, krberror);
267 if (rc != SHISHI_OK)
268 return rc;
271 rc = shishi_krberror_cusec (handle, krberror, &usec);
272 if (rc != SHISHI_OK &&
273 rc != SHISHI_ASN1_NO_ELEMENT && rc != SHISHI_ASN1_NO_VALUE)
274 return rc;
275 if (rc == SHISHI_ASN1_NO_VALUE)
277 rc = shishi_krberror_remove_cusec (handle, krberror);
278 if (rc != SHISHI_OK)
279 return rc;
282 rc = shishi_krberror_crealm (handle, krberror, &tmp, &tmplen);
283 if (rc != SHISHI_OK &&
284 rc != SHISHI_ASN1_NO_ELEMENT && rc != SHISHI_ASN1_NO_VALUE)
285 return rc;
286 if (rc == SHISHI_OK)
287 free (tmp);
288 if (rc == SHISHI_ASN1_NO_VALUE)
290 rc = shishi_krberror_remove_crealm (handle, krberror);
291 if (rc != SHISHI_OK)
292 return rc;
295 tmplen = sizeof (time);
296 rc = shishi_krberror_cname (handle, krberror, time, &tmplen);
297 if (rc != SHISHI_OK &&
298 rc != SHISHI_ASN1_NO_ELEMENT && rc != SHISHI_ASN1_NO_VALUE)
299 return rc;
300 if (rc == SHISHI_ASN1_NO_VALUE || (rc == SHISHI_OK && tmplen == 0))
302 rc = shishi_krberror_remove_cname (handle, krberror);
303 if (rc != SHISHI_OK)
304 return rc;
307 rc = shishi_krberror_realm (handle, krberror, &tmp, &tmplen);
308 if (rc != SHISHI_OK && rc != SHISHI_ASN1_NO_VALUE)
309 return rc;
310 if (rc == SHISHI_OK)
311 free (tmp);
312 if (rc == SHISHI_ASN1_NO_VALUE)
314 rc = shishi_krberror_set_realm (handle, krberror, "");
315 if (rc != SHISHI_OK)
316 return rc;
319 tmplen = sizeof (time);
320 rc = shishi_krberror_sname (handle, krberror, time, &tmplen);
321 if (rc != SHISHI_OK && rc != SHISHI_ASN1_NO_VALUE)
322 return rc;
323 if (rc == SHISHI_ASN1_NO_VALUE || tmplen == 0)
325 rc = shishi_krberror_remove_sname (handle, krberror);
326 if (rc != SHISHI_OK)
327 return rc;
330 rc = shishi_krberror_edata (handle, krberror, &tmp, &tmplen);
331 if (rc != SHISHI_OK &&
332 rc != SHISHI_ASN1_NO_ELEMENT && rc != SHISHI_ASN1_NO_VALUE)
333 return rc;
334 if (rc == SHISHI_OK)
335 free (tmp);
336 if (rc == SHISHI_ASN1_NO_VALUE || (rc == SHISHI_OK && tmplen == 0))
338 rc = shishi_krberror_remove_edata (handle, krberror);
339 if (rc != SHISHI_OK)
340 return rc;
343 rc = shishi_krberror_errorcode (handle, krberror, &errc);
344 if (rc != SHISHI_OK && rc != SHISHI_ASN1_NO_VALUE)
345 return rc;
346 if (rc == SHISHI_ASN1_NO_VALUE)
348 rc = shishi_krberror_errorcode_set (handle, krberror,
349 SHISHI_KRB_ERR_GENERIC);
350 if (rc != SHISHI_OK)
351 return rc;
354 rc = shishi_krberror_etext (handle, krberror, &tmp, &tmplen);
355 if (rc != SHISHI_OK &&
356 rc != SHISHI_ASN1_NO_ELEMENT && rc != SHISHI_ASN1_NO_VALUE)
357 return rc;
358 if (rc == SHISHI_OK)
359 free (tmp);
360 if (rc == SHISHI_ASN1_NO_VALUE || (rc == SHISHI_OK && tmplen == 0))
362 if (shishi_krberror_errorcode_fast (handle, krberror) ==
363 SHISHI_KRB_ERR_GENERIC)
364 rc = shishi_krberror_set_etext (handle, krberror,
365 "Uninitialized error");
366 else
367 rc = shishi_krberror_remove_etext (handle, krberror);
368 if (rc != SHISHI_OK)
369 return rc;
372 return SHISHI_OK;
376 * shishi_krberror_der:
377 * @handle: shishi handle as allocated by shishi_init().
378 * @krberror: krberror as allocated by shishi_krberror().
379 * @out: output array with newly allocated DER encoding of KRB-ERROR.
380 * @outlen: length of output array with DER encoding of KRB-ERROR.
382 * DER encode KRB-ERROR. The caller must deallocate the OUT buffer.
384 * Return value: Returns SHISHI_OK iff successful.
387 shishi_krberror_der (Shishi * handle,
388 Shishi_asn1 krberror, char **out, size_t * outlen)
390 int rc;
392 rc = shishi_krberror_build (handle, krberror);
393 if (rc != SHISHI_OK)
394 return rc;
396 rc = shishi_new_a2d (handle, krberror, out, outlen);
397 if (rc != SHISHI_OK)
398 return rc;
400 return SHISHI_OK;
404 * shishi_krberror_crealm:
405 * @handle: shishi handle as allocated by shishi_init().
406 * @krberror: krberror as allocated by shishi_krberror().
407 * @realm: output array with newly allocated name of realm in KRB-ERROR.
408 * @realmlen: size of output array.
410 * Extract client realm from KRB-ERROR.
412 * Return value: Returns SHISHI_OK iff successful.
415 shishi_krberror_crealm (Shishi * handle,
416 Shishi_asn1 krberror, char **realm, size_t * realmlen)
418 return shishi_asn1_read2 (handle, krberror, "crealm", realm, realmlen);
422 * shishi_krberror_remove_crealm:
423 * @handle: shishi handle as allocated by shishi_init().
424 * @krberror: krberror as allocated by shishi_krberror().
426 * Remove client realm field in KRB-ERROR.
428 * Return value: Returns SHISHI_OK iff successful.
431 shishi_krberror_remove_crealm (Shishi * handle, Shishi_asn1 krberror)
433 int res;
435 res = shishi_asn1_write (handle, krberror, "crealm", NULL, 0);
436 if (res != SHISHI_OK)
437 return res;
439 return SHISHI_OK;
443 * shishi_krberror_set_crealm:
444 * @handle: shishi handle as allocated by shishi_init().
445 * @krberror: krberror as allocated by shishi_krberror().
446 * @crealm: input array with realm.
448 * Set realm field in krberror to specified value.
450 * Return value: Returns SHISHI_OK iff successful.
453 shishi_krberror_set_crealm (Shishi * handle,
454 Shishi_asn1 krberror, const char *crealm)
456 int res;
458 res = shishi_asn1_write (handle, krberror, "crealm", crealm, 0);
459 if (res != SHISHI_OK)
460 return res;
462 return SHISHI_OK;
466 * shishi_krberror_cname:
467 * @handle: shishi handle as allocated by shishi_init().
468 * @krberror: krberror as allocated by shishi_krberror().
469 * @out: output buffer that holds client name in KRB-ERROR.
470 * @outlen: on input, maximum size of output buffer,
471 * on output, actual size of output buffer.
473 * Return client principal field in KRB-ERROR.
475 * Return value: Returns SHISHI_OK iff successful.
478 shishi_krberror_cname (Shishi * handle,
479 Shishi_asn1 krberror, char *out, size_t * outlen)
481 int rc;
483 rc = shishi_principal_name_get (handle, krberror, "cname", out, outlen);
484 if (rc != SHISHI_OK)
485 return rc;
487 return SHISHI_OK;
491 * shishi_krberror_set_cname:
492 * @handle: shishi handle as allocated by shishi_init().
493 * @krberror: krberror as allocated by shishi_krberror().
494 * @name_type: type of principial, see Shishi_name_type, usually
495 * SHISHI_NT_UNKNOWN.
496 * @cname: input array with principal name.
498 * Set principal field in krberror to specified value.
500 * Return value: Returns SHISHI_OK iff successful.
503 shishi_krberror_set_cname (Shishi * handle,
504 Shishi_asn1 krberror,
505 Shishi_name_type name_type, const char *cname[])
507 int res;
509 res = shishi_principal_name_set (handle, krberror, "cname",
510 name_type, cname);
511 if (res != SHISHI_OK)
512 return res;
514 return SHISHI_OK;
518 * shishi_krberror_remove_cname:
519 * @handle: shishi handle as allocated by shishi_init().
520 * @krberror: krberror as allocated by shishi_krberror().
522 * Remove client realm field in KRB-ERROR.
524 * Return value: Returns SHISHI_OK iff successful.
527 shishi_krberror_remove_cname (Shishi * handle, Shishi_asn1 krberror)
529 int res;
531 res = shishi_asn1_write (handle, krberror, "cname", NULL, 0);
532 if (res != SHISHI_OK)
533 return res;
535 return SHISHI_OK;
539 * shishi_krberror_client_set:
540 * @handle: shishi handle as allocated by shishi_init().
541 * @krberror: Krberror to set client name field in.
542 * @client: zero-terminated string with principal name on RFC 1964 form.
544 * Set the client name field in the Krberror.
546 * Return value: Returns SHISHI_OK iff successful.
549 shishi_krberror_client_set (Shishi * handle,
550 Shishi_asn1 krberror, const char *client)
552 int res;
554 res = shishi_principal_set (handle, krberror, "cname", client);
555 if (res != SHISHI_OK)
556 return res;
558 return SHISHI_OK;
562 * shishi_krberror_realm:
563 * @handle: shishi handle as allocated by shishi_init().
564 * @krberror: krberror as allocated by shishi_krberror().
565 * @realm: output array with newly allocated name of realm in KRB-ERROR.
566 * @realmlen: size of output array.
568 * Extract (server) realm from KRB-ERROR.
570 * Return value: Returns SHISHI_OK iff successful.
573 shishi_krberror_realm (Shishi * handle,
574 Shishi_asn1 krberror, char **realm, size_t * realmlen)
576 return shishi_asn1_read2 (handle, krberror, "realm", realm, realmlen);
580 * shishi_krberror_set_realm:
581 * @handle: shishi handle as allocated by shishi_init().
582 * @krberror: krberror as allocated by shishi_krberror().
583 * @realm: input array with (server) realm.
585 * Set (server) realm field in krberror to specified value.
587 * Return value: Returns SHISHI_OK iff successful.
590 shishi_krberror_set_realm (Shishi * handle,
591 Shishi_asn1 krberror, const char *realm)
593 int res;
595 res = shishi_asn1_write (handle, krberror, "realm", realm, 0);
596 if (res != SHISHI_OK)
597 return res;
599 return SHISHI_OK;
603 * shishi_krberror_sname:
604 * @handle: shishi handle as allocated by shishi_init().
605 * @krberror: krberror as allocated by shishi_krberror().
606 * @out: output buffer that holds server name in KRB-ERROR.
607 * @outlen: on input, maximum size of output buffer,
608 * on output, actual size of output buffer.
610 * Return server principal field in KRB-ERROR.
612 * Return value: Returns SHISHI_OK iff successful.
615 shishi_krberror_sname (Shishi * handle,
616 Shishi_asn1 krberror, char *out, size_t * outlen)
618 int rc;
620 rc = shishi_principal_name_get (handle, krberror, "sname", out, outlen);
621 if (rc != SHISHI_OK)
622 return rc;
624 return SHISHI_OK;
628 * shishi_krberror_remove_sname:
629 * @handle: shishi handle as allocated by shishi_init().
630 * @krberror: Krberror to set server name field in.
632 * Remove server name field in KRB-ERROR. (Since it is not marked
633 * OPTIONAL in the ASN.1 profile, what is done is to set the name-type
634 * to UNKNOWN and make sure the name-string sequence is empty.)
636 * Return value: Returns SHISHI_OK iff successful.
639 shishi_krberror_remove_sname (Shishi * handle, Shishi_asn1 krberror)
641 int res;
643 res = shishi_asn1_write_int32 (handle, krberror, "sname.name-type",
644 SHISHI_NT_UNKNOWN);
645 if (res != SHISHI_OK)
646 return res;
648 res = shishi_asn1_write (handle, krberror, "sname.name-string", NULL, 0);
649 if (res != SHISHI_OK)
650 return res;
652 return SHISHI_OK;
656 * shishi_krberror_set_sname:
657 * @handle: shishi handle as allocated by shishi_init().
658 * @krberror: krberror as allocated by shishi_krberror().
659 * @name_type: type of principial, see Shishi_name_type, usually
660 * SHISHI_NT_UNKNOWN.
661 * @sname: input array with principal name.
663 * Set principal field in krberror to specified value.
665 * Return value: Returns SHISHI_OK iff successful.
668 shishi_krberror_set_sname (Shishi * handle,
669 Shishi_asn1 krberror,
670 Shishi_name_type name_type, const char *sname[])
672 int res;
674 res = shishi_principal_name_set (handle, krberror, "sname",
675 name_type, sname);
676 if (res != SHISHI_OK)
677 return res;
679 return SHISHI_OK;
683 * shishi_krberror_server_set:
684 * @handle: shishi handle as allocated by shishi_init().
685 * @krberror: Krberror to set server name field in.
686 * @server: zero-terminated string with principal name on RFC 1964 form.
688 * Set the server name field in the Krberror.
690 * Return value: Returns SHISHI_OK iff successful.
693 shishi_krberror_server_set (Shishi * handle,
694 Shishi_asn1 krberror, const char *server)
696 int res;
698 res = shishi_principal_set (handle, krberror, "sname", server);
699 if (res != SHISHI_OK)
700 return res;
702 return SHISHI_OK;
706 * shishi_krberror_ctime:
707 * @handle: shishi handle as allocated by shishi_init().
708 * @krberror: Krberror to set client name field in.
709 * @ctime: newly allocated zero-terminated output array with client time.
711 * Extract client time from KRB-ERROR.
713 * Return value: Returns SHISHI_OK iff successful.
716 shishi_krberror_ctime (Shishi * handle, Shishi_asn1 krberror, char **ctime)
718 return shishi_time (handle, krberror, "ctime", ctime);
722 * shishi_krberror_ctime_set:
723 * @handle: shishi handle as allocated by shishi_init().
724 * @krberror: Krberror as allocated by shishi_krberror().
725 * @ctime: string with generalized time value to store in Krberror.
727 * Store client time in Krberror.
729 * Return value: Returns SHISHI_OK iff successful.
732 shishi_krberror_ctime_set (Shishi * handle,
733 Shishi_asn1 krberror, const char *ctime)
735 int res;
737 if (ctime)
738 res = shishi_asn1_write (handle, krberror, "ctime",
739 ctime, GENERALIZEDTIME_TIME_LEN);
740 else
741 res = shishi_asn1_write (handle, krberror, "ctime", NULL, 0);
742 if (res != SHISHI_OK)
743 return res;
745 return SHISHI_OK;
749 * shishi_krberror_remove_ctime:
750 * @handle: shishi handle as allocated by shishi_init().
751 * @krberror: Krberror as allocated by shishi_krberror().
753 * Remove client time field in Krberror.
755 * Return value: Returns SHISHI_OK iff successful.
758 shishi_krberror_remove_ctime (Shishi * handle, Shishi_asn1 krberror)
760 int res;
762 res = shishi_asn1_write (handle, krberror, "ctime", NULL, 0);
763 if (res != SHISHI_OK)
764 return res;
766 return SHISHI_OK;
770 * shishi_krberror_cusec:
771 * @handle: shishi handle as allocated by shishi_init().
772 * @krberror: Krberror as allocated by shishi_krberror().
773 * @cusec: output integer with client microseconds field.
775 * Extract client microseconds field from Krberror.
777 * Return value: Returns SHISHI_OK iff successful.
780 shishi_krberror_cusec (Shishi * handle, Shishi_asn1 krberror, int *cusec)
782 int res;
784 res = shishi_asn1_read_uint32 (handle, krberror, "cusec", cusec);
785 if (res != SHISHI_OK)
786 return res;
788 return SHISHI_OK;
792 * shishi_krberror_cusec_set:
793 * @handle: shishi handle as allocated by shishi_init().
794 * @krberror: krberror as allocated by shishi_krberror().
795 * @cusec: client microseconds to set in krberror, 0-999999.
797 * Set the cusec field in the Krberror.
799 * Return value: Returns SHISHI_OK iff successful.
802 shishi_krberror_cusec_set (Shishi * handle, Shishi_asn1 krberror, int cusec)
804 int res;
806 res = shishi_asn1_write_uint32 (handle, krberror, "cusec", cusec);
807 if (res != SHISHI_OK)
808 return res;
810 return SHISHI_OK;
814 * shishi_krberror_remove_cusec:
815 * @handle: shishi handle as allocated by shishi_init().
816 * @krberror: Krberror as allocated by shishi_krberror().
818 * Remove client usec field in Krberror.
820 * Return value: Returns SHISHI_OK iff successful.
823 shishi_krberror_remove_cusec (Shishi * handle, Shishi_asn1 krberror)
825 int res;
827 res = shishi_asn1_write (handle, krberror, "cusec", NULL, 0);
828 if (res != SHISHI_OK)
829 return res;
831 return SHISHI_OK;
835 * shishi_krberror_stime:
836 * @handle: shishi handle as allocated by shishi_init().
837 * @krberror: Krberror to set client name field in.
838 * @stime: newly allocated zero-terminated output array with server time.
840 * Extract server time from KRB-ERROR.
842 * Return value: Returns SHISHI_OK iff successful.
845 shishi_krberror_stime (Shishi * handle, Shishi_asn1 krberror, char **stime)
847 return shishi_time (handle, krberror, "stime", stime);
851 * shishi_krberror_stime_set:
852 * @handle: shishi handle as allocated by shishi_init().
853 * @krberror: Krberror as allocated by shishi_krberror().
854 * @stime: string with generalized time value to store in Krberror.
856 * Store server time in Krberror.
858 * Return value: Returns SHISHI_OK iff successful.
861 shishi_krberror_stime_set (Shishi * handle,
862 Shishi_asn1 krberror, const char *stime)
864 int res;
866 res = shishi_asn1_write (handle, krberror, "stime",
867 stime, GENERALIZEDTIME_TIME_LEN);
868 if (res != SHISHI_OK)
869 return res;
871 return SHISHI_OK;
875 * shishi_krberror_susec:
876 * @handle: shishi handle as allocated by shishi_init().
877 * @krberror: Krberror as allocated by shishi_krberror().
878 * @susec: output integer with server microseconds field.
880 * Extract server microseconds field from Krberror.
882 * Return value: Returns SHISHI_OK iff successful.
885 shishi_krberror_susec (Shishi * handle, Shishi_asn1 krberror, int *susec)
887 int res;
889 res = shishi_asn1_read_uint32 (handle, krberror, "susec", susec);
890 if (res != SHISHI_OK)
891 return res;
893 return SHISHI_OK;
897 * shishi_krberror_susec_set:
898 * @handle: shishi handle as allocated by shishi_init().
899 * @krberror: krberror as allocated by shishi_krberror().
900 * @susec: server microseconds to set in krberror, 0-999999.
902 * Set the susec field in the Krberror.
904 * Return value: Returns SHISHI_OK iff successful.
907 shishi_krberror_susec_set (Shishi * handle, Shishi_asn1 krberror, int susec)
909 int res;
911 res = shishi_asn1_write_uint32 (handle, krberror, "susec", susec);
912 if (res != SHISHI_OK)
913 return res;
915 return SHISHI_OK;
919 * shishi_krberror_errorcode:
920 * @handle: shishi handle as allocated by shishi_init().
921 * @krberror: KRB-ERROR structure with error code.
922 * @errorcode: output integer KRB-ERROR error code.
924 * Extract error code from KRB-ERROR.
926 * Return value: Returns SHISHI_OK iff successful.
929 shishi_krberror_errorcode (Shishi * handle,
930 Shishi_asn1 krberror, int32_t * errorcode)
932 return shishi_asn1_read_int32 (handle, krberror, "error-code", errorcode);
936 * shishi_krberror_errorcode_fast:
937 * @handle: shishi handle as allocated by shishi_init().
938 * @krberror: KRB-ERROR structure with error code.
940 * Return value: Return error code (see shishi_krberror_errorcode())
941 * directly, or -1 on error.
944 shishi_krberror_errorcode_fast (Shishi * handle, Shishi_asn1 krberror)
946 int i;
948 if (shishi_krberror_errorcode (handle, krberror, &i) != SHISHI_OK)
949 i = -1;
951 return i;
955 * shishi_krberror_errorcode_set:
956 * @handle: shishi handle as allocated by shishi_init().
957 * @krberror: KRB-ERROR structure with error code to set.
958 * @errorcode: new error code to set in krberror.
960 * Set the error-code field to a new error code.
962 * Return value: Returns SHISHI_OK iff successful.
965 shishi_krberror_errorcode_set (Shishi * handle,
966 Shishi_asn1 krberror, int errorcode)
968 int res;
970 res = shishi_asn1_write_int32 (handle, krberror, "error-code", errorcode);
971 if (res != SHISHI_OK)
972 return res;
974 return SHISHI_OK;
978 * shishi_krberror_etext:
979 * @handle: shishi handle as allocated by shishi_init().
980 * @krberror: KRB-ERROR structure with error code.
981 * @etext: output array with newly allocated error text.
982 * @etextlen: output length of error text.
984 * Extract additional error text from server (possibly empty).
986 * Return value: Returns SHISHI_OK iff successful.
989 shishi_krberror_etext (Shishi * handle, Shishi_asn1 krberror,
990 char **etext, size_t * etextlen)
992 return shishi_asn1_read2 (handle, krberror, "e-text", etext, etextlen);
996 * shishi_krberror_set_etext:
997 * @handle: shishi handle as allocated by shishi_init().
998 * @krberror: krberror as allocated by shishi_krberror().
999 * @etext: input array with error text to set.
1001 * Set error text (e-text) field in KRB-ERROR to specified value.
1003 * Return value: Returns SHISHI_OK iff successful.
1006 shishi_krberror_set_etext (Shishi * handle,
1007 Shishi_asn1 krberror, const char *etext)
1009 int res;
1011 res = shishi_asn1_write (handle, krberror, "e-text", etext, 0);
1012 if (res != SHISHI_OK)
1013 return res;
1015 return SHISHI_OK;
1019 * shishi_krberror_remove_etext:
1020 * @handle: shishi handle as allocated by shishi_init().
1021 * @krberror: krberror as allocated by shishi_krberror().
1023 * Remove error text (e-text) field in KRB-ERROR.
1025 * Return value: Returns SHISHI_OK iff successful.
1028 shishi_krberror_remove_etext (Shishi * handle, Shishi_asn1 krberror)
1030 int res;
1032 res = shishi_asn1_write (handle, krberror, "e-text", NULL, 0);
1033 if (res != SHISHI_OK)
1034 return res;
1036 return SHISHI_OK;
1040 * shishi_krberror_edata:
1041 * @handle: shishi handle as allocated by shishi_init().
1042 * @krberror: KRB-ERROR structure with error code.
1043 * @edata: output array with newly allocated error data.
1044 * @edatalen: output length of error data.
1046 * Extract additional error data from server (possibly empty).
1048 * Return value: Returns SHISHI_OK iff successful.
1051 shishi_krberror_edata (Shishi * handle, Shishi_asn1 krberror,
1052 char **edata, size_t * edatalen)
1054 return shishi_asn1_read2 (handle, krberror, "e-data", edata, edatalen);
1058 * shishi_krberror_set_edata:
1059 * @handle: shishi handle as allocated by shishi_init().
1060 * @krberror: krberror as allocated by shishi_krberror().
1061 * @edata: input array with error text to set.
1063 * Set error text (e-data) field in KRB-ERROR to specified value.
1065 * Return value: Returns SHISHI_OK iff successful.
1068 shishi_krberror_set_edata (Shishi * handle,
1069 Shishi_asn1 krberror, const char *edata)
1071 int res;
1073 res = shishi_asn1_write (handle, krberror, "e-data", edata, 0);
1074 if (res != SHISHI_OK)
1075 return res;
1077 return SHISHI_OK;
1081 * shishi_krberror_remove_edata:
1082 * @handle: shishi handle as allocated by shishi_init().
1083 * @krberror: krberror as allocated by shishi_krberror().
1085 * Remove error text (e-data) field in KRB-ERROR.
1087 * Return value: Returns SHISHI_OK iff successful.
1090 shishi_krberror_remove_edata (Shishi * handle, Shishi_asn1 krberror)
1092 int res;
1094 res = shishi_asn1_write (handle, krberror, "e-data", NULL, 0);
1095 if (res != SHISHI_OK)
1096 return res;
1098 return SHISHI_OK;
1102 * shishi_krberror_pretty_print:
1103 * @handle: shishi handle as allocated by shishi_init().
1104 * @fh: file handle opened for writing.
1105 * @krberror: KRB-ERROR structure with error code.
1107 * Print KRB-ERROR error condition and some explanatory text to file
1108 * descriptor.
1110 * Return value: Returns SHISHI_OK iff successful.
1113 shishi_krberror_pretty_print (Shishi * handle, FILE * fh,
1114 Shishi_asn1 krberror)
1116 char *buf;
1117 size_t len;
1118 int res;
1120 if (VERBOSEASN1 (handle))
1121 shishi_krberror_print (handle, fh, krberror);
1123 if (shishi_krberror_errorcode_fast (handle, krberror) ==
1124 SHISHI_KRB_ERR_GENERIC)
1126 fprintf (fh, "Generic Kerberos error from server:\n");
1128 res = shishi_krberror_etext (handle, krberror, &buf, &len);
1129 buf[len] = '\0';
1130 if (res == SHISHI_OK && len > 0)
1131 fprintf (fh, "%s\n", buf);
1133 else
1135 fprintf (fh, "Kerberos error code from server:\n%s\n",
1136 shishi_krberror_message (handle, krberror));
1138 res = shishi_krberror_etext (handle, krberror, &buf, &len);
1139 if (res == SHISHI_OK && len > 0)
1141 buf[len] = '\0';
1142 fprintf (fh, "Additional Kerberos error message from server:\n%s\n",
1143 buf);
1148 return SHISHI_OK;
1151 struct krb_error_msgs
1153 int errorcode;
1154 char *message;
1157 struct krb_error_msgs _shishi_krberror_messages[SHISHI_LAST_ERROR_CODE] = {
1158 {SHISHI_KDC_ERR_NONE, "No error"},
1159 {SHISHI_KDC_ERR_NAME_EXP, "Client's entry in database has expired"},
1160 {SHISHI_KDC_ERR_SERVICE_EXP, "Server's entry in database has expired"},
1161 {SHISHI_KDC_ERR_BAD_PVNO,
1162 "Requested protocol version number not supported"},
1163 {SHISHI_KDC_ERR_C_OLD_MAST_KVNO,
1164 "Client's key encrypted in old master key"},
1165 {SHISHI_KDC_ERR_S_OLD_MAST_KVNO,
1166 "Server's key encrypted in old master key"},
1167 {SHISHI_KDC_ERR_C_PRINCIPAL_UNKNOWN,
1168 "Client not found in Kerberos database"},
1169 {SHISHI_KDC_ERR_S_PRINCIPAL_UNKNOWN,
1170 "Server not found in Kerberos database"},
1171 {SHISHI_KDC_ERR_PRINCIPAL_NOT_UNIQUE,
1172 "Multiple principal entries in database"},
1173 {SHISHI_KDC_ERR_NULL_KEY, "The client or server has a null key"},
1174 {SHISHI_KDC_ERR_CANNOT_POSTDATE, "Ticket not eligible for postdating"},
1175 {SHISHI_KDC_ERR_NEVER_VALID, "Requested start time is later than end time"},
1176 {SHISHI_KDC_ERR_POLICY, "KDC policy rejects request"},
1177 {SHISHI_KDC_ERR_BADOPTION, "KDC cannot accommodate requested option"},
1178 {SHISHI_KDC_ERR_ETYPE_NOSUPP, "KDC has no support for encryption type"},
1179 {SHISHI_KDC_ERR_SUMTYPE_NOSUPP, "KDC has no support for checksum type"},
1180 {SHISHI_KDC_ERR_PADATA_TYPE_NOSUPP, "KDC has no support for padata type"},
1181 {SHISHI_KDC_ERR_TRTYPE_NOSUPP, "KDC has no support for transited type"},
1182 {SHISHI_KDC_ERR_CLIENT_REVOKED, "Clients credentials have been revoked"},
1183 {SHISHI_KDC_ERR_SERVICE_REVOKED,
1184 "Credentials for server have been revoked"},
1185 {SHISHI_KDC_ERR_TGT_REVOKED, "TGT has been revoked"},
1186 {SHISHI_KDC_ERR_CLIENT_NOTYET, "Client not yet valid - try again later"},
1187 {SHISHI_KDC_ERR_SERVICE_NOTYET, "Server not yet valid - try again later"},
1188 {SHISHI_KDC_ERR_KEY_EXPIRED, "Password has expired "},
1189 {SHISHI_KDC_ERR_PREAUTH_FAILED,
1190 "Pre-authentication information was invalid"},
1191 {SHISHI_KDC_ERR_PREAUTH_REQUIRED,
1192 "Additional pre-authenticationrequired [40]"},
1193 {SHISHI_KDC_ERR_SERVER_NOMATCH, "Requested server and ticket don't match"},
1194 {SHISHI_KDC_ERR_MUST_USE_USER2USER,
1195 "Server principal valid for user2user only"},
1196 {SHISHI_KDC_ERR_PATH_NOT_ACCPETED, "KDC Policy rejects transited path"},
1197 {SHISHI_KDC_ERR_SVC_UNAVAILABLE, "A service is not available"},
1198 {SHISHI_KRB_AP_ERR_BAD_INTEGRITY,
1199 "Integrity check on decrypted field failed"},
1200 {SHISHI_KRB_AP_ERR_TKT_EXPIRED, "Ticket expired"},
1201 {SHISHI_KRB_AP_ERR_TKT_NYV, "Ticket not yet valid"},
1202 {SHISHI_KRB_AP_ERR_REPEAT, "Request is a replay"},
1203 {SHISHI_KRB_AP_ERR_NOT_US, "The ticket isn't for us"},
1204 {SHISHI_KRB_AP_ERR_BADMATCH, "Ticket and authenticator don't match"},
1205 {SHISHI_KRB_AP_ERR_SKEW, "Clock skew too great"},
1206 {SHISHI_KRB_AP_ERR_BADADDR, "Incorrect net address"},
1207 {SHISHI_KRB_AP_ERR_BADVERSION, "Protocol version mismatch"},
1208 {SHISHI_KRB_AP_ERR_MSG_TYPE, "Invalid msg type"},
1209 {SHISHI_KRB_AP_ERR_MODIFIED, "Message stream modified"},
1210 {SHISHI_KRB_AP_ERR_BADORDER, "Message out of order"},
1211 {SHISHI_KRB_AP_ERR_BADKEYVER, "Specified version of key is not available"},
1212 {SHISHI_KRB_AP_ERR_NOKEY, "Service key not available"},
1213 {SHISHI_KRB_AP_ERR_MUT_FAIL, "Mutual authentication failed"},
1214 {SHISHI_KRB_AP_ERR_BADDIRECTION, "Incorrect message direction"},
1215 {SHISHI_KRB_AP_ERR_METHOD, "Alternative authentication method required"},
1216 {SHISHI_KRB_AP_ERR_BADSEQ, "Incorrect sequence number in message"},
1217 {SHISHI_KRB_AP_ERR_INAPP_CKSUM,
1218 "Inappropriate type of checksum in message"},
1219 {SHISHI_KRB_AP_PATH_NOT_ACCEPTED, "Policy rejects transited path"},
1220 {SHISHI_KRB_ERR_RESPONSE_TOO_BIG,
1221 "Response too big for UDP, retry with TCP"},
1222 {SHISHI_KRB_ERR_GENERIC, "Generic error (description in e-text)"},
1223 {SHISHI_KRB_ERR_FIELD_TOOLONG, "Field is too long for this implementation"},
1224 {SHISHI_KDC_ERROR_CLIENT_NOT_TRUSTED, "(pkinit)"},
1225 {SHISHI_KDC_ERROR_KDC_NOT_TRUSTED, "(pkinit)"},
1226 {SHISHI_KDC_ERROR_INVALID_SIG, "(pkinit)"},
1227 {SHISHI_KDC_ERR_KEY_TOO_WEAK, "(pkinit)"},
1228 {SHISHI_KDC_ERR_CERTIFICATE_MISMATCH, "(pkinit)"},
1229 {SHISHI_KRB_AP_ERR_NO_TGT, "(user-to-user)"},
1230 {SHISHI_KDC_ERR_WRONG_REALM, "(user-to-user)"},
1231 {SHISHI_KRB_AP_ERR_USER_TO_USER_REQUIRED, "(user-to-user)"},
1232 {SHISHI_KDC_ERR_CANT_VERIFY_CERTIFICATE, "(pkinit)"},
1233 {SHISHI_KDC_ERR_INVALID_CERTIFICATE, "(pkinit)"},
1234 {SHISHI_KDC_ERR_REVOKED_CERTIFICATE, "(pkinit)"},
1235 {SHISHI_KDC_ERR_REVOCATION_STATUS_UNKNOWN, "(pkinit)"},
1236 {SHISHI_KDC_ERR_REVOCATION_STATUS_UNAVAILABLE, "(pkinit)"},
1237 {SHISHI_KDC_ERR_CLIENT_NAME_MISMATCH, "(pkinit)"},
1238 {SHISHI_KDC_ERR_KDC_NAME_MISMATCH, "(pkinit)"}
1242 * shishi_krberror_errorcode_message:
1243 * @handle: shishi handle as allocated by shishi_init().
1244 * @errorcode: integer KRB-ERROR error code.
1246 * Return value: Return a string describing error code. This function
1247 * will always return a string even if the error code
1248 * isn't known.
1250 const char *
1251 shishi_krberror_errorcode_message (Shishi * handle, int errorcode)
1253 int i;
1254 char *p;
1256 for (i = 0; i < SHISHI_LAST_ERROR_CODE; i++)
1258 if (errorcode == _shishi_krberror_messages[i].errorcode)
1259 return _(_shishi_krberror_messages[i].message);
1262 /* XXX memory leak */
1263 asprintf (&p, _("Unknown KRB-ERROR error code %d."), errorcode);
1264 return p;
1268 * shishi_krberror_message:
1269 * @handle: shishi handle as allocated by shishi_init().
1270 * @krberror: KRB-ERROR structure with error code.
1272 * Extract error code (see shishi_krberror_errorcode_fast()) and
1273 * return error message (see shishi_krberror_errorcode_message()).
1275 * Return value: Return a string describing error code. This function
1276 * will always return a string even if the error code
1277 * isn't known.
1279 const char *
1280 shishi_krberror_message (Shishi * handle, Shishi_asn1 krberror)
1282 return shishi_krberror_errorcode_message
1283 (handle, shishi_krberror_errorcode_fast (handle, krberror));