No empty .Rs/.Re
[netbsd-mini2440.git] / crypto / dist / heimdal / lib / krb5 / store.c
blobe0c8cce7b30945cc989fd40a1bf4f3b5561a1de1
1 /*
2 * Copyright (c) 1997-2006 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 #include "krb5_locl.h"
35 #include "store-int.h"
37 __RCSID("$Heimdal: store.c 22071 2007-11-14 20:04:50Z lha $"
38 "$NetBSD$");
40 #define BYTEORDER_IS(SP, V) (((SP)->flags & KRB5_STORAGE_BYTEORDER_MASK) == (V))
41 #define BYTEORDER_IS_LE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_LE)
42 #define BYTEORDER_IS_BE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_BE)
43 #define BYTEORDER_IS_HOST(SP) (BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_HOST) || \
44 krb5_storage_is_flags((SP), KRB5_STORAGE_HOST_BYTEORDER))
46 void KRB5_LIB_FUNCTION
47 krb5_storage_set_flags(krb5_storage *sp, krb5_flags flags)
49 sp->flags |= flags;
52 void KRB5_LIB_FUNCTION
53 krb5_storage_clear_flags(krb5_storage *sp, krb5_flags flags)
55 sp->flags &= ~flags;
58 krb5_boolean KRB5_LIB_FUNCTION
59 krb5_storage_is_flags(krb5_storage *sp, krb5_flags flags)
61 return (sp->flags & flags) == flags;
64 void KRB5_LIB_FUNCTION
65 krb5_storage_set_byteorder(krb5_storage *sp, krb5_flags byteorder)
67 sp->flags &= ~KRB5_STORAGE_BYTEORDER_MASK;
68 sp->flags |= byteorder;
71 krb5_flags KRB5_LIB_FUNCTION
72 krb5_storage_get_byteorder(krb5_storage *sp, krb5_flags byteorder)
74 return sp->flags & KRB5_STORAGE_BYTEORDER_MASK;
77 off_t KRB5_LIB_FUNCTION
78 krb5_storage_seek(krb5_storage *sp, off_t offset, int whence)
80 return (*sp->seek)(sp, offset, whence);
83 krb5_ssize_t KRB5_LIB_FUNCTION
84 krb5_storage_read(krb5_storage *sp, void *buf, size_t len)
86 return sp->fetch(sp, buf, len);
89 krb5_ssize_t KRB5_LIB_FUNCTION
90 krb5_storage_write(krb5_storage *sp, const void *buf, size_t len)
92 return sp->store(sp, buf, len);
95 void KRB5_LIB_FUNCTION
96 krb5_storage_set_eof_code(krb5_storage *sp, int code)
98 sp->eof_code = code;
101 krb5_ssize_t KRB5_LIB_FUNCTION
102 _krb5_put_int(void *buffer, unsigned long value, size_t size)
104 unsigned char *p = buffer;
105 int i;
106 for (i = size - 1; i >= 0; i--) {
107 p[i] = value & 0xff;
108 value >>= 8;
110 return size;
113 krb5_ssize_t KRB5_LIB_FUNCTION
114 _krb5_get_int(void *buffer, unsigned long *value, size_t size)
116 unsigned char *p = buffer;
117 unsigned long v = 0;
118 int i;
119 for (i = 0; i < size; i++)
120 v = (v << 8) + p[i];
121 *value = v;
122 return size;
125 krb5_error_code KRB5_LIB_FUNCTION
126 krb5_storage_free(krb5_storage *sp)
128 if(sp->free)
129 (*sp->free)(sp);
130 free(sp->data);
131 free(sp);
132 return 0;
135 krb5_error_code KRB5_LIB_FUNCTION
136 krb5_storage_to_data(krb5_storage *sp, krb5_data *data)
138 off_t pos;
139 size_t size;
140 krb5_error_code ret;
142 pos = sp->seek(sp, 0, SEEK_CUR);
143 size = (size_t)sp->seek(sp, 0, SEEK_END);
144 ret = krb5_data_alloc (data, size);
145 if (ret) {
146 sp->seek(sp, pos, SEEK_SET);
147 return ret;
149 if (size) {
150 sp->seek(sp, 0, SEEK_SET);
151 sp->fetch(sp, data->data, data->length);
152 sp->seek(sp, pos, SEEK_SET);
154 return 0;
157 static krb5_error_code
158 krb5_store_int(krb5_storage *sp,
159 int32_t value,
160 size_t len)
162 int ret;
163 unsigned char v[16];
165 if(len > sizeof(v))
166 return EINVAL;
167 _krb5_put_int(v, value, len);
168 ret = sp->store(sp, v, len);
169 if (ret != len)
170 return (ret<0)?errno:sp->eof_code;
171 return 0;
174 krb5_error_code KRB5_LIB_FUNCTION
175 krb5_store_int32(krb5_storage *sp,
176 int32_t value)
178 if(BYTEORDER_IS_HOST(sp))
179 value = htonl(value);
180 else if(BYTEORDER_IS_LE(sp))
181 value = bswap32(value);
182 return krb5_store_int(sp, value, 4);
185 krb5_error_code KRB5_LIB_FUNCTION
186 krb5_store_uint32(krb5_storage *sp,
187 uint32_t value)
189 return krb5_store_int32(sp, (int32_t)value);
192 static krb5_error_code
193 krb5_ret_int(krb5_storage *sp,
194 int32_t *value,
195 size_t len)
197 int ret;
198 unsigned char v[4];
199 unsigned long w;
200 ret = sp->fetch(sp, v, len);
201 if(ret != len)
202 return (ret<0)?errno:sp->eof_code;
203 _krb5_get_int(v, &w, len);
204 *value = w;
205 return 0;
208 krb5_error_code KRB5_LIB_FUNCTION
209 krb5_ret_int32(krb5_storage *sp,
210 int32_t *value)
212 krb5_error_code ret = krb5_ret_int(sp, value, 4);
213 if(ret)
214 return ret;
215 if(BYTEORDER_IS_HOST(sp))
216 *value = htonl(*value);
217 else if(BYTEORDER_IS_LE(sp))
218 *value = bswap32(*value);
219 return 0;
222 krb5_error_code KRB5_LIB_FUNCTION
223 krb5_ret_uint32(krb5_storage *sp,
224 uint32_t *value)
226 krb5_error_code ret;
227 int32_t v;
229 ret = krb5_ret_int32(sp, &v);
230 if (ret == 0)
231 *value = (uint32_t)v;
233 return ret;
236 krb5_error_code KRB5_LIB_FUNCTION
237 krb5_store_int16(krb5_storage *sp,
238 int16_t value)
240 if(BYTEORDER_IS_HOST(sp))
241 value = htons(value);
242 else if(BYTEORDER_IS_LE(sp))
243 value = bswap16(value);
244 return krb5_store_int(sp, value, 2);
247 krb5_error_code KRB5_LIB_FUNCTION
248 krb5_store_uint16(krb5_storage *sp,
249 uint16_t value)
251 return krb5_store_int16(sp, (int16_t)value);
254 krb5_error_code KRB5_LIB_FUNCTION
255 krb5_ret_int16(krb5_storage *sp,
256 int16_t *value)
258 int32_t v;
259 int ret;
260 ret = krb5_ret_int(sp, &v, 2);
261 if(ret)
262 return ret;
263 *value = v;
264 if(BYTEORDER_IS_HOST(sp))
265 *value = htons(*value);
266 else if(BYTEORDER_IS_LE(sp))
267 *value = bswap16(*value);
268 return 0;
271 krb5_error_code KRB5_LIB_FUNCTION
272 krb5_ret_uint16(krb5_storage *sp,
273 uint16_t *value)
275 krb5_error_code ret;
276 int16_t v;
278 ret = krb5_ret_int16(sp, &v);
279 if (ret == 0)
280 *value = (uint16_t)v;
282 return ret;
285 krb5_error_code KRB5_LIB_FUNCTION
286 krb5_store_int8(krb5_storage *sp,
287 int8_t value)
289 int ret;
291 ret = sp->store(sp, &value, sizeof(value));
292 if (ret != sizeof(value))
293 return (ret<0)?errno:sp->eof_code;
294 return 0;
297 krb5_error_code KRB5_LIB_FUNCTION
298 krb5_store_uint8(krb5_storage *sp,
299 uint8_t value)
301 return krb5_store_int8(sp, (int8_t)value);
304 krb5_error_code KRB5_LIB_FUNCTION
305 krb5_ret_int8(krb5_storage *sp,
306 int8_t *value)
308 int ret;
310 ret = sp->fetch(sp, value, sizeof(*value));
311 if (ret != sizeof(*value))
312 return (ret<0)?errno:sp->eof_code;
313 return 0;
316 krb5_error_code KRB5_LIB_FUNCTION
317 krb5_ret_uint8(krb5_storage *sp,
318 uint8_t *value)
320 krb5_error_code ret;
321 int8_t v;
323 ret = krb5_ret_int8(sp, &v);
324 if (ret == 0)
325 *value = (uint8_t)v;
327 return ret;
330 krb5_error_code KRB5_LIB_FUNCTION
331 krb5_store_data(krb5_storage *sp,
332 krb5_data data)
334 int ret;
335 ret = krb5_store_int32(sp, data.length);
336 if(ret < 0)
337 return ret;
338 ret = sp->store(sp, data.data, data.length);
339 if(ret != data.length){
340 if(ret < 0)
341 return errno;
342 return sp->eof_code;
344 return 0;
347 krb5_error_code KRB5_LIB_FUNCTION
348 krb5_ret_data(krb5_storage *sp,
349 krb5_data *data)
351 int ret;
352 int32_t size;
354 ret = krb5_ret_int32(sp, &size);
355 if(ret)
356 return ret;
357 ret = krb5_data_alloc (data, size);
358 if (ret)
359 return ret;
360 if (size) {
361 ret = sp->fetch(sp, data->data, size);
362 if(ret != size)
363 return (ret < 0)? errno : sp->eof_code;
365 return 0;
368 krb5_error_code KRB5_LIB_FUNCTION
369 krb5_store_string(krb5_storage *sp, const char *s)
371 krb5_data data;
372 data.length = strlen(s);
373 data.data = rk_UNCONST(s);
374 return krb5_store_data(sp, data);
377 krb5_error_code KRB5_LIB_FUNCTION
378 krb5_ret_string(krb5_storage *sp,
379 char **string)
381 int ret;
382 krb5_data data;
383 ret = krb5_ret_data(sp, &data);
384 if(ret)
385 return ret;
386 *string = realloc(data.data, data.length + 1);
387 if(*string == NULL){
388 free(data.data);
389 return ENOMEM;
391 (*string)[data.length] = 0;
392 return 0;
395 krb5_error_code KRB5_LIB_FUNCTION
396 krb5_store_stringz(krb5_storage *sp, const char *s)
398 size_t len = strlen(s) + 1;
399 ssize_t ret;
401 ret = sp->store(sp, s, len);
402 if(ret != len) {
403 if(ret < 0)
404 return ret;
405 else
406 return sp->eof_code;
408 return 0;
411 krb5_error_code KRB5_LIB_FUNCTION
412 krb5_ret_stringz(krb5_storage *sp,
413 char **string)
415 char c;
416 char *s = NULL;
417 size_t len = 0;
418 ssize_t ret;
420 while((ret = sp->fetch(sp, &c, 1)) == 1){
421 char *tmp;
423 len++;
424 tmp = realloc (s, len);
425 if (tmp == NULL) {
426 free (s);
427 return ENOMEM;
429 s = tmp;
430 s[len - 1] = c;
431 if(c == 0)
432 break;
434 if(ret != 1){
435 free(s);
436 if(ret == 0)
437 return sp->eof_code;
438 return ret;
440 *string = s;
441 return 0;
444 krb5_error_code KRB5_LIB_FUNCTION
445 krb5_store_stringnl(krb5_storage *sp, const char *s)
447 size_t len = strlen(s);
448 ssize_t ret;
450 ret = sp->store(sp, s, len);
451 if(ret != len) {
452 if(ret < 0)
453 return ret;
454 else
455 return sp->eof_code;
457 ret = sp->store(sp, "\n", 1);
458 if(ret != 1) {
459 if(ret < 0)
460 return ret;
461 else
462 return sp->eof_code;
465 return 0;
469 krb5_error_code KRB5_LIB_FUNCTION
470 krb5_ret_stringnl(krb5_storage *sp,
471 char **string)
473 int expect_nl = 0;
474 char c;
475 char *s = NULL;
476 size_t len = 0;
477 ssize_t ret;
479 while((ret = sp->fetch(sp, &c, 1)) == 1){
480 char *tmp;
482 if (c == '\r') {
483 expect_nl = 1;
484 continue;
486 if (expect_nl && c != '\n') {
487 free(s);
488 return KRB5_BADMSGTYPE;
491 len++;
492 tmp = realloc (s, len);
493 if (tmp == NULL) {
494 free (s);
495 return ENOMEM;
497 s = tmp;
498 if(c == '\n') {
499 s[len - 1] = '\0';
500 break;
502 s[len - 1] = c;
504 if(ret != 1){
505 free(s);
506 if(ret == 0)
507 return sp->eof_code;
508 return ret;
510 *string = s;
511 return 0;
515 krb5_error_code KRB5_LIB_FUNCTION
516 krb5_store_principal(krb5_storage *sp,
517 krb5_const_principal p)
519 int i;
520 int ret;
522 if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) {
523 ret = krb5_store_int32(sp, p->name.name_type);
524 if(ret) return ret;
526 if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
527 ret = krb5_store_int32(sp, p->name.name_string.len + 1);
528 else
529 ret = krb5_store_int32(sp, p->name.name_string.len);
531 if(ret) return ret;
532 ret = krb5_store_string(sp, p->realm);
533 if(ret) return ret;
534 for(i = 0; i < p->name.name_string.len; i++){
535 ret = krb5_store_string(sp, p->name.name_string.val[i]);
536 if(ret) return ret;
538 return 0;
541 krb5_error_code KRB5_LIB_FUNCTION
542 krb5_ret_principal(krb5_storage *sp,
543 krb5_principal *princ)
545 int i;
546 int ret;
547 krb5_principal p;
548 int32_t type;
549 int32_t ncomp;
551 p = calloc(1, sizeof(*p));
552 if(p == NULL)
553 return ENOMEM;
555 if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE))
556 type = KRB5_NT_UNKNOWN;
557 else if((ret = krb5_ret_int32(sp, &type))){
558 free(p);
559 return ret;
561 if((ret = krb5_ret_int32(sp, &ncomp))){
562 free(p);
563 return ret;
565 if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
566 ncomp--;
567 if (ncomp < 0) {
568 free(p);
569 return EINVAL;
571 p->name.name_type = type;
572 p->name.name_string.len = ncomp;
573 ret = krb5_ret_string(sp, &p->realm);
574 if(ret) {
575 free(p);
576 return ret;
578 p->name.name_string.val = calloc(ncomp, sizeof(*p->name.name_string.val));
579 if(p->name.name_string.val == NULL && ncomp != 0){
580 free(p->realm);
581 free(p);
582 return ENOMEM;
584 for(i = 0; i < ncomp; i++){
585 ret = krb5_ret_string(sp, &p->name.name_string.val[i]);
586 if(ret) {
587 while (i >= 0)
588 free(p->name.name_string.val[i--]);
589 free(p->realm);
590 free(p);
591 return ret;
594 *princ = p;
595 return 0;
598 krb5_error_code KRB5_LIB_FUNCTION
599 krb5_store_keyblock(krb5_storage *sp, krb5_keyblock p)
601 int ret;
602 ret = krb5_store_int16(sp, p.keytype);
603 if(ret) return ret;
605 if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
606 /* this should really be enctype, but it is the same as
607 keytype nowadays */
608 ret = krb5_store_int16(sp, p.keytype);
609 if(ret) return ret;
612 ret = krb5_store_data(sp, p.keyvalue);
613 return ret;
616 krb5_error_code KRB5_LIB_FUNCTION
617 krb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p)
619 int ret;
620 int16_t tmp;
622 ret = krb5_ret_int16(sp, &tmp);
623 if(ret) return ret;
624 p->keytype = tmp;
626 if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
627 ret = krb5_ret_int16(sp, &tmp);
628 if(ret) return ret;
631 ret = krb5_ret_data(sp, &p->keyvalue);
632 return ret;
635 krb5_error_code KRB5_LIB_FUNCTION
636 krb5_store_times(krb5_storage *sp, krb5_times times)
638 int ret;
639 ret = krb5_store_int32(sp, times.authtime);
640 if(ret) return ret;
641 ret = krb5_store_int32(sp, times.starttime);
642 if(ret) return ret;
643 ret = krb5_store_int32(sp, times.endtime);
644 if(ret) return ret;
645 ret = krb5_store_int32(sp, times.renew_till);
646 return ret;
649 krb5_error_code KRB5_LIB_FUNCTION
650 krb5_ret_times(krb5_storage *sp, krb5_times *times)
652 int ret;
653 int32_t tmp;
654 ret = krb5_ret_int32(sp, &tmp);
655 times->authtime = tmp;
656 if(ret) return ret;
657 ret = krb5_ret_int32(sp, &tmp);
658 times->starttime = tmp;
659 if(ret) return ret;
660 ret = krb5_ret_int32(sp, &tmp);
661 times->endtime = tmp;
662 if(ret) return ret;
663 ret = krb5_ret_int32(sp, &tmp);
664 times->renew_till = tmp;
665 return ret;
668 krb5_error_code KRB5_LIB_FUNCTION
669 krb5_store_address(krb5_storage *sp, krb5_address p)
671 int ret;
672 ret = krb5_store_int16(sp, p.addr_type);
673 if(ret) return ret;
674 ret = krb5_store_data(sp, p.address);
675 return ret;
678 krb5_error_code KRB5_LIB_FUNCTION
679 krb5_ret_address(krb5_storage *sp, krb5_address *adr)
681 int16_t t;
682 int ret;
683 ret = krb5_ret_int16(sp, &t);
684 if(ret) return ret;
685 adr->addr_type = t;
686 ret = krb5_ret_data(sp, &adr->address);
687 return ret;
690 krb5_error_code KRB5_LIB_FUNCTION
691 krb5_store_addrs(krb5_storage *sp, krb5_addresses p)
693 int i;
694 int ret;
695 ret = krb5_store_int32(sp, p.len);
696 if(ret) return ret;
697 for(i = 0; i<p.len; i++){
698 ret = krb5_store_address(sp, p.val[i]);
699 if(ret) break;
701 return ret;
704 krb5_error_code KRB5_LIB_FUNCTION
705 krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr)
707 int i;
708 int ret;
709 int32_t tmp;
711 ret = krb5_ret_int32(sp, &tmp);
712 if(ret) return ret;
713 adr->len = tmp;
714 ALLOC(adr->val, adr->len);
715 if (adr->val == NULL && adr->len != 0)
716 return ENOMEM;
717 for(i = 0; i < adr->len; i++){
718 ret = krb5_ret_address(sp, &adr->val[i]);
719 if(ret) break;
721 return ret;
724 krb5_error_code KRB5_LIB_FUNCTION
725 krb5_store_authdata(krb5_storage *sp, krb5_authdata auth)
727 krb5_error_code ret;
728 int i;
729 ret = krb5_store_int32(sp, auth.len);
730 if(ret) return ret;
731 for(i = 0; i < auth.len; i++){
732 ret = krb5_store_int16(sp, auth.val[i].ad_type);
733 if(ret) break;
734 ret = krb5_store_data(sp, auth.val[i].ad_data);
735 if(ret) break;
737 return 0;
740 krb5_error_code KRB5_LIB_FUNCTION
741 krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth)
743 krb5_error_code ret;
744 int32_t tmp;
745 int16_t tmp2;
746 int i;
747 ret = krb5_ret_int32(sp, &tmp);
748 if(ret) return ret;
749 ALLOC_SEQ(auth, tmp);
750 if (auth->val == NULL && tmp != 0)
751 return ENOMEM;
752 for(i = 0; i < tmp; i++){
753 ret = krb5_ret_int16(sp, &tmp2);
754 if(ret) break;
755 auth->val[i].ad_type = tmp2;
756 ret = krb5_ret_data(sp, &auth->val[i].ad_data);
757 if(ret) break;
759 return ret;
762 static int32_t
763 bitswap32(int32_t b)
765 int32_t r = 0;
766 int i;
767 for (i = 0; i < 32; i++) {
768 r = r << 1 | (b & 1);
769 b = b >> 1;
771 return r;
779 krb5_error_code KRB5_LIB_FUNCTION
780 krb5_store_creds(krb5_storage *sp, krb5_creds *creds)
782 int ret;
784 ret = krb5_store_principal(sp, creds->client);
785 if(ret)
786 return ret;
787 ret = krb5_store_principal(sp, creds->server);
788 if(ret)
789 return ret;
790 ret = krb5_store_keyblock(sp, creds->session);
791 if(ret)
792 return ret;
793 ret = krb5_store_times(sp, creds->times);
794 if(ret)
795 return ret;
796 ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
797 if(ret)
798 return ret;
800 if(krb5_storage_is_flags(sp, KRB5_STORAGE_CREDS_FLAGS_WRONG_BITORDER))
801 ret = krb5_store_int32(sp, creds->flags.i);
802 else
803 ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
804 if(ret)
805 return ret;
807 ret = krb5_store_addrs(sp, creds->addresses);
808 if(ret)
809 return ret;
810 ret = krb5_store_authdata(sp, creds->authdata);
811 if(ret)
812 return ret;
813 ret = krb5_store_data(sp, creds->ticket);
814 if(ret)
815 return ret;
816 ret = krb5_store_data(sp, creds->second_ticket);
817 return ret;
820 krb5_error_code KRB5_LIB_FUNCTION
821 krb5_ret_creds(krb5_storage *sp, krb5_creds *creds)
823 krb5_error_code ret;
824 int8_t dummy8;
825 int32_t dummy32;
827 memset(creds, 0, sizeof(*creds));
828 ret = krb5_ret_principal (sp, &creds->client);
829 if(ret) goto cleanup;
830 ret = krb5_ret_principal (sp, &creds->server);
831 if(ret) goto cleanup;
832 ret = krb5_ret_keyblock (sp, &creds->session);
833 if(ret) goto cleanup;
834 ret = krb5_ret_times (sp, &creds->times);
835 if(ret) goto cleanup;
836 ret = krb5_ret_int8 (sp, &dummy8);
837 if(ret) goto cleanup;
838 ret = krb5_ret_int32 (sp, &dummy32);
839 if(ret) goto cleanup;
841 * Runtime detect the what is the higher bits of the bitfield. If
842 * any of the higher bits are set in the input data, it's either a
843 * new ticket flag (and this code need to be removed), or it's a
844 * MIT cache (or new Heimdal cache), lets change it to our current
845 * format.
848 uint32_t mask = 0xffff0000;
849 creds->flags.i = 0;
850 creds->flags.b.anonymous = 1;
851 if (creds->flags.i & mask)
852 mask = ~mask;
853 if (dummy32 & mask)
854 dummy32 = bitswap32(dummy32);
856 creds->flags.i = dummy32;
857 ret = krb5_ret_addrs (sp, &creds->addresses);
858 if(ret) goto cleanup;
859 ret = krb5_ret_authdata (sp, &creds->authdata);
860 if(ret) goto cleanup;
861 ret = krb5_ret_data (sp, &creds->ticket);
862 if(ret) goto cleanup;
863 ret = krb5_ret_data (sp, &creds->second_ticket);
864 cleanup:
865 if(ret) {
866 #if 0
867 krb5_free_cred_contents(context, creds); /* XXX */
868 #endif
870 return ret;
873 #define SC_CLIENT_PRINCIPAL 0x0001
874 #define SC_SERVER_PRINCIPAL 0x0002
875 #define SC_SESSION_KEY 0x0004
876 #define SC_TICKET 0x0008
877 #define SC_SECOND_TICKET 0x0010
878 #define SC_AUTHDATA 0x0020
879 #define SC_ADDRESSES 0x0040
885 krb5_error_code KRB5_LIB_FUNCTION
886 krb5_store_creds_tag(krb5_storage *sp, krb5_creds *creds)
888 int ret;
889 int32_t header = 0;
891 if (creds->client)
892 header |= SC_CLIENT_PRINCIPAL;
893 if (creds->server)
894 header |= SC_SERVER_PRINCIPAL;
895 if (creds->session.keytype != ETYPE_NULL)
896 header |= SC_SESSION_KEY;
897 if (creds->ticket.data)
898 header |= SC_TICKET;
899 if (creds->second_ticket.length)
900 header |= SC_SECOND_TICKET;
901 if (creds->authdata.len)
902 header |= SC_AUTHDATA;
903 if (creds->addresses.len)
904 header |= SC_ADDRESSES;
906 ret = krb5_store_int32(sp, header);
908 if (creds->client) {
909 ret = krb5_store_principal(sp, creds->client);
910 if(ret)
911 return ret;
914 if (creds->server) {
915 ret = krb5_store_principal(sp, creds->server);
916 if(ret)
917 return ret;
920 if (creds->session.keytype != ETYPE_NULL) {
921 ret = krb5_store_keyblock(sp, creds->session);
922 if(ret)
923 return ret;
926 ret = krb5_store_times(sp, creds->times);
927 if(ret)
928 return ret;
929 ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
930 if(ret)
931 return ret;
933 ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
934 if(ret)
935 return ret;
937 if (creds->addresses.len) {
938 ret = krb5_store_addrs(sp, creds->addresses);
939 if(ret)
940 return ret;
943 if (creds->authdata.len) {
944 ret = krb5_store_authdata(sp, creds->authdata);
945 if(ret)
946 return ret;
949 if (creds->ticket.data) {
950 ret = krb5_store_data(sp, creds->ticket);
951 if(ret)
952 return ret;
955 if (creds->second_ticket.data) {
956 ret = krb5_store_data(sp, creds->second_ticket);
957 if (ret)
958 return ret;
961 return ret;
964 krb5_error_code KRB5_LIB_FUNCTION
965 krb5_ret_creds_tag(krb5_storage *sp,
966 krb5_creds *creds)
968 krb5_error_code ret;
969 int8_t dummy8;
970 int32_t dummy32, header;
972 memset(creds, 0, sizeof(*creds));
974 ret = krb5_ret_int32 (sp, &header);
975 if (ret) goto cleanup;
977 if (header & SC_CLIENT_PRINCIPAL) {
978 ret = krb5_ret_principal (sp, &creds->client);
979 if(ret) goto cleanup;
981 if (header & SC_SERVER_PRINCIPAL) {
982 ret = krb5_ret_principal (sp, &creds->server);
983 if(ret) goto cleanup;
985 if (header & SC_SESSION_KEY) {
986 ret = krb5_ret_keyblock (sp, &creds->session);
987 if(ret) goto cleanup;
989 ret = krb5_ret_times (sp, &creds->times);
990 if(ret) goto cleanup;
991 ret = krb5_ret_int8 (sp, &dummy8);
992 if(ret) goto cleanup;
993 ret = krb5_ret_int32 (sp, &dummy32);
994 if(ret) goto cleanup;
996 * Runtime detect the what is the higher bits of the bitfield. If
997 * any of the higher bits are set in the input data, it's either a
998 * new ticket flag (and this code need to be removed), or it's a
999 * MIT cache (or new Heimdal cache), lets change it to our current
1000 * format.
1003 uint32_t mask = 0xffff0000;
1004 creds->flags.i = 0;
1005 creds->flags.b.anonymous = 1;
1006 if (creds->flags.i & mask)
1007 mask = ~mask;
1008 if (dummy32 & mask)
1009 dummy32 = bitswap32(dummy32);
1011 creds->flags.i = dummy32;
1012 if (header & SC_ADDRESSES) {
1013 ret = krb5_ret_addrs (sp, &creds->addresses);
1014 if(ret) goto cleanup;
1016 if (header & SC_AUTHDATA) {
1017 ret = krb5_ret_authdata (sp, &creds->authdata);
1018 if(ret) goto cleanup;
1020 if (header & SC_TICKET) {
1021 ret = krb5_ret_data (sp, &creds->ticket);
1022 if(ret) goto cleanup;
1024 if (header & SC_SECOND_TICKET) {
1025 ret = krb5_ret_data (sp, &creds->second_ticket);
1026 if(ret) goto cleanup;
1029 cleanup:
1030 if(ret) {
1031 #if 0
1032 krb5_free_cred_contents(context, creds); /* XXX */
1033 #endif
1035 return ret;