2 * Copyright (c) 1997-2008 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
34 #include "krb5_locl.h"
35 #include "store-int.h"
37 #define BYTEORDER_IS(SP, V) (((SP)->flags & KRB5_STORAGE_BYTEORDER_MASK) == (V))
38 #define BYTEORDER_IS_LE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_LE)
39 #define BYTEORDER_IS_BE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_BE)
40 #define BYTEORDER_IS_HOST(SP) (BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_HOST) || \
41 krb5_storage_is_flags((SP), KRB5_STORAGE_HOST_BYTEORDER))
44 * Add the flags on a storage buffer by or-ing in the flags to the buffer.
46 * @param sp the storage buffer to set the flags on
47 * @param flags the flags to set
49 * @ingroup krb5_storage
52 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
53 krb5_storage_set_flags(krb5_storage *sp, krb5_flags flags)
59 * Clear the flags on a storage buffer
61 * @param sp the storage buffer to clear the flags on
62 * @param flags the flags to clear
64 * @ingroup krb5_storage
67 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
68 krb5_storage_clear_flags(krb5_storage *sp, krb5_flags flags)
74 * Return true or false depending on if the storage flags is set or
75 * not. NB testing for the flag 0 always return true.
77 * @param sp the storage buffer to check flags on
78 * @param flags The flags to test for
80 * @return true if all the flags are set, false if not.
82 * @ingroup krb5_storage
85 KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
86 krb5_storage_is_flags(krb5_storage *sp, krb5_flags flags)
88 return (sp->flags & flags) == flags;
92 * Set the new byte order of the storage buffer.
94 * @param sp the storage buffer to set the byte order for.
95 * @param byteorder the new byte order.
97 * The byte order are: KRB5_STORAGE_BYTEORDER_BE,
98 * KRB5_STORAGE_BYTEORDER_LE and KRB5_STORAGE_BYTEORDER_HOST.
100 * @ingroup krb5_storage
103 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
104 krb5_storage_set_byteorder(krb5_storage *sp, krb5_flags byteorder)
106 sp->flags &= ~KRB5_STORAGE_BYTEORDER_MASK;
107 sp->flags |= byteorder;
111 * Return the current byteorder for the buffer. See krb5_storage_set_byteorder() for the list or byte order contants.
113 * @ingroup krb5_storage
116 KRB5_LIB_FUNCTION krb5_flags KRB5_LIB_CALL
117 krb5_storage_get_byteorder(krb5_storage *sp)
119 return sp->flags & KRB5_STORAGE_BYTEORDER_MASK;
123 * Seek to a new offset.
125 * @param sp the storage buffer to seek in.
126 * @param offset the offset to seek
127 * @param whence relateive searching, SEEK_CUR from the current
128 * position, SEEK_END from the end, SEEK_SET absolute from the start.
130 * @return The new current offset
132 * @ingroup krb5_storage
135 KRB5_LIB_FUNCTION off_t KRB5_LIB_CALL
136 krb5_storage_seek(krb5_storage *sp, off_t offset, int whence)
138 return (*sp->seek)(sp, offset, whence);
142 * Truncate the storage buffer in sp to offset.
144 * @param sp the storage buffer to truncate.
145 * @param offset the offset to truncate too.
147 * @return An Kerberos 5 error code.
149 * @ingroup krb5_storage
152 KRB5_LIB_FUNCTION int KRB5_LIB_CALL
153 krb5_storage_truncate(krb5_storage *sp, off_t offset)
155 return (*sp->trunc)(sp, offset);
159 * Read to the storage buffer.
161 * @param sp the storage buffer to read from
162 * @param buf the buffer to store the data in
163 * @param len the length to read
165 * @return The length of data read (can be shorter then len), or negative on error.
167 * @ingroup krb5_storage
170 KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL
171 krb5_storage_read(krb5_storage *sp, void *buf, size_t len)
173 return sp->fetch(sp, buf, len);
177 * Write to the storage buffer.
179 * @param sp the storage buffer to write to
180 * @param buf the buffer to write to the storage buffer
181 * @param len the length to write
183 * @return The length of data written (can be shorter then len), or negative on error.
185 * @ingroup krb5_storage
188 KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL
189 krb5_storage_write(krb5_storage *sp, const void *buf, size_t len)
191 return sp->store(sp, buf, len);
195 * Set the return code that will be used when end of storage is reached.
197 * @param sp the storage
198 * @param code the error code to return on end of storage
200 * @ingroup krb5_storage
203 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
204 krb5_storage_set_eof_code(krb5_storage *sp, int code)
210 * Get the return code that will be used when end of storage is reached.
212 * @param sp the storage
214 * @return storage error code
216 * @ingroup krb5_storage
219 KRB5_LIB_FUNCTION int KRB5_LIB_CALL
220 krb5_storage_get_eof_code(krb5_storage *sp)
226 * Free a krb5 storage.
228 * @param sp the storage to free.
230 * @return An Kerberos 5 error code.
232 * @ingroup krb5_storage
235 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
236 krb5_storage_free(krb5_storage *sp)
246 * Copy the contnent of storage
248 * @param sp the storage to copy to a data
249 * @param data the copied data, free with krb5_data_free()
251 * @return 0 for success, or a Kerberos 5 error code on failure.
253 * @ingroup krb5_storage
256 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
257 krb5_storage_to_data(krb5_storage *sp, krb5_data *data)
262 pos = sp->seek(sp, 0, SEEK_CUR);
264 return HEIM_ERR_NOT_SEEKABLE;
265 size = (size_t)sp->seek(sp, 0, SEEK_END);
266 if (size > (size_t)-1)
267 return HEIM_ERR_TOO_BIG;
268 ret = krb5_data_alloc (data, size);
270 sp->seek(sp, pos, SEEK_SET);
274 sp->seek(sp, 0, SEEK_SET);
275 sp->fetch(sp, data->data, data->length);
276 sp->seek(sp, pos, SEEK_SET);
281 static krb5_error_code
282 krb5_store_int(krb5_storage *sp,
291 _krb5_put_int(v, value, len);
292 ret = sp->store(sp, v, len);
294 return (ret<0)?errno:sp->eof_code;
299 * Store a int32 to storage, byte order is controlled by the settings
300 * on the storage, see krb5_storage_set_byteorder().
302 * @param sp the storage to write too
303 * @param value the value to store
305 * @return 0 for success, or a Kerberos 5 error code on failure.
307 * @ingroup krb5_storage
310 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
311 krb5_store_int32(krb5_storage *sp,
314 if(BYTEORDER_IS_HOST(sp))
315 value = htonl(value);
316 else if(BYTEORDER_IS_LE(sp))
317 value = bswap32(value);
318 return krb5_store_int(sp, value, 4);
322 * Store a uint32 to storage, byte order is controlled by the settings
323 * on the storage, see krb5_storage_set_byteorder().
325 * @param sp the storage to write too
326 * @param value the value to store
328 * @return 0 for success, or a Kerberos 5 error code on failure.
330 * @ingroup krb5_storage
333 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
334 krb5_store_uint32(krb5_storage *sp,
337 return krb5_store_int32(sp, (int32_t)value);
340 static krb5_error_code
341 krb5_ret_int(krb5_storage *sp,
348 ret = sp->fetch(sp, v, len);
350 return (ret<0)?errno:sp->eof_code;
351 _krb5_get_int(v, &w, len);
357 * Read a int32 from storage, byte order is controlled by the settings
358 * on the storage, see krb5_storage_set_byteorder().
360 * @param sp the storage to write too
361 * @param value the value read from the buffer
363 * @return 0 for success, or a Kerberos 5 error code on failure.
365 * @ingroup krb5_storage
368 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
369 krb5_ret_int32(krb5_storage *sp,
372 krb5_error_code ret = krb5_ret_int(sp, value, 4);
375 if(BYTEORDER_IS_HOST(sp))
376 *value = htonl(*value);
377 else if(BYTEORDER_IS_LE(sp))
378 *value = bswap32(*value);
383 * Read a uint32 from storage, byte order is controlled by the settings
384 * on the storage, see krb5_storage_set_byteorder().
386 * @param sp the storage to write too
387 * @param value the value read from the buffer
389 * @return 0 for success, or a Kerberos 5 error code on failure.
391 * @ingroup krb5_storage
394 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
395 krb5_ret_uint32(krb5_storage *sp,
401 ret = krb5_ret_int32(sp, &v);
403 *value = (uint32_t)v;
409 * Store a int16 to storage, byte order is controlled by the settings
410 * on the storage, see krb5_storage_set_byteorder().
412 * @param sp the storage to write too
413 * @param value the value to store
415 * @return 0 for success, or a Kerberos 5 error code on failure.
417 * @ingroup krb5_storage
420 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
421 krb5_store_int16(krb5_storage *sp,
424 if(BYTEORDER_IS_HOST(sp))
425 value = htons(value);
426 else if(BYTEORDER_IS_LE(sp))
427 value = bswap16(value);
428 return krb5_store_int(sp, value, 2);
432 * Store a uint16 to storage, byte order is controlled by the settings
433 * on the storage, see krb5_storage_set_byteorder().
435 * @param sp the storage to write too
436 * @param value the value to store
438 * @return 0 for success, or a Kerberos 5 error code on failure.
440 * @ingroup krb5_storage
443 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
444 krb5_store_uint16(krb5_storage *sp,
447 return krb5_store_int16(sp, (int16_t)value);
451 * Read a int16 from storage, byte order is controlled by the settings
452 * on the storage, see krb5_storage_set_byteorder().
454 * @param sp the storage to write too
455 * @param value the value read from the buffer
457 * @return 0 for success, or a Kerberos 5 error code on failure.
459 * @ingroup krb5_storage
462 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
463 krb5_ret_int16(krb5_storage *sp,
468 ret = krb5_ret_int(sp, &v, 2);
472 if(BYTEORDER_IS_HOST(sp))
473 *value = htons(*value);
474 else if(BYTEORDER_IS_LE(sp))
475 *value = bswap16(*value);
480 * Read a int16 from storage, byte order is controlled by the settings
481 * on the storage, see krb5_storage_set_byteorder().
483 * @param sp the storage to write too
484 * @param value the value read from the buffer
486 * @return 0 for success, or a Kerberos 5 error code on failure.
488 * @ingroup krb5_storage
491 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
492 krb5_ret_uint16(krb5_storage *sp,
498 ret = krb5_ret_int16(sp, &v);
500 *value = (uint16_t)v;
506 * Store a int8 to storage.
508 * @param sp the storage to write too
509 * @param value the value to store
511 * @return 0 for success, or a Kerberos 5 error code on failure.
513 * @ingroup krb5_storage
516 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
517 krb5_store_int8(krb5_storage *sp,
522 ret = sp->store(sp, &value, sizeof(value));
523 if (ret != sizeof(value))
524 return (ret<0)?errno:sp->eof_code;
529 * Store a uint8 to storage.
531 * @param sp the storage to write too
532 * @param value the value to store
534 * @return 0 for success, or a Kerberos 5 error code on failure.
536 * @ingroup krb5_storage
539 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
540 krb5_store_uint8(krb5_storage *sp,
543 return krb5_store_int8(sp, (int8_t)value);
547 * Read a int8 from storage
549 * @param sp the storage to write too
550 * @param value the value read from the buffer
552 * @return 0 for success, or a Kerberos 5 error code on failure.
554 * @ingroup krb5_storage
557 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
558 krb5_ret_int8(krb5_storage *sp,
563 ret = sp->fetch(sp, value, sizeof(*value));
564 if (ret != sizeof(*value))
565 return (ret<0)?errno:sp->eof_code;
570 * Read a uint8 from storage
572 * @param sp the storage to write too
573 * @param value the value read from the buffer
575 * @return 0 for success, or a Kerberos 5 error code on failure.
577 * @ingroup krb5_storage
580 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
581 krb5_ret_uint8(krb5_storage *sp,
587 ret = krb5_ret_int8(sp, &v);
595 * Store a data to the storage. The data is stored with an int32 as
596 * lenght plus the data (not padded).
598 * @param sp the storage buffer to write to
599 * @param data the buffer to store.
601 * @return 0 on success, a Kerberos 5 error code on failure.
603 * @ingroup krb5_storage
606 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
607 krb5_store_data(krb5_storage *sp,
611 ret = krb5_store_int32(sp, data.length);
614 ret = sp->store(sp, data.data, data.length);
615 if(ret != data.length){
624 * Parse a data from the storage.
626 * @param sp the storage buffer to read from
627 * @param data the parsed data
629 * @return 0 on success, a Kerberos 5 error code on failure.
631 * @ingroup krb5_storage
634 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
635 krb5_ret_data(krb5_storage *sp,
641 ret = krb5_ret_int32(sp, &size);
644 ret = krb5_data_alloc (data, size);
648 ret = sp->fetch(sp, data->data, size);
650 return (ret < 0)? errno : sp->eof_code;
656 * Store a string to the buffer. The data is formated as an len:uint32
657 * plus the string itself (not padded).
659 * @param sp the storage buffer to write to
660 * @param s the string to store.
662 * @return 0 on success, a Kerberos 5 error code on failure.
664 * @ingroup krb5_storage
667 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
668 krb5_store_string(krb5_storage *sp, const char *s)
671 data.length = strlen(s);
672 data.data = rk_UNCONST(s);
673 return krb5_store_data(sp, data);
677 * Parse a string from the storage.
679 * @param sp the storage buffer to read from
680 * @param string the parsed string
682 * @return 0 on success, a Kerberos 5 error code on failure.
684 * @ingroup krb5_storage
688 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
689 krb5_ret_string(krb5_storage *sp,
694 ret = krb5_ret_data(sp, &data);
697 *string = realloc(data.data, data.length + 1);
702 (*string)[data.length] = 0;
707 * Store a zero terminated string to the buffer. The data is stored
708 * one character at a time until a NUL is stored.
710 * @param sp the storage buffer to write to
711 * @param s the string to store.
713 * @return 0 on success, a Kerberos 5 error code on failure.
715 * @ingroup krb5_storage
718 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
719 krb5_store_stringz(krb5_storage *sp, const char *s)
721 size_t len = strlen(s) + 1;
724 ret = sp->store(sp, s, len);
735 * Parse zero terminated string from the storage.
737 * @param sp the storage buffer to read from
738 * @param string the parsed string
740 * @return 0 on success, a Kerberos 5 error code on failure.
742 * @ingroup krb5_storage
745 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
746 krb5_ret_stringz(krb5_storage *sp,
754 while((ret = sp->fetch(sp, &c, 1)) == 1){
758 tmp = realloc (s, len);
778 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
779 krb5_store_stringnl(krb5_storage *sp, const char *s)
781 size_t len = strlen(s);
784 ret = sp->store(sp, s, len);
791 ret = sp->store(sp, "\n", 1);
803 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
804 krb5_ret_stringnl(krb5_storage *sp,
813 while((ret = sp->fetch(sp, &c, 1)) == 1){
820 if (expect_nl && c != '\n') {
822 return KRB5_BADMSGTYPE;
826 tmp = realloc (s, len);
849 * Write a principal block to storage.
851 * @param sp the storage buffer to write to
852 * @param p the principal block to write.
854 * @return 0 on success, a Kerberos 5 error code on failure.
856 * @ingroup krb5_storage
859 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
860 krb5_store_principal(krb5_storage *sp,
861 krb5_const_principal p)
866 if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) {
867 ret = krb5_store_int32(sp, p->name.name_type);
870 if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
871 ret = krb5_store_int32(sp, p->name.name_string.len + 1);
873 ret = krb5_store_int32(sp, p->name.name_string.len);
876 ret = krb5_store_string(sp, p->realm);
878 for(i = 0; i < p->name.name_string.len; i++){
879 ret = krb5_store_string(sp, p->name.name_string.val[i]);
886 * Parse principal from the storage.
888 * @param sp the storage buffer to read from
889 * @param princ the parsed principal
891 * @return 0 on success, a Kerberos 5 error code on failure.
893 * @ingroup krb5_storage
896 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
897 krb5_ret_principal(krb5_storage *sp,
898 krb5_principal *princ)
906 p = calloc(1, sizeof(*p));
910 if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE))
911 type = KRB5_NT_UNKNOWN;
912 else if((ret = krb5_ret_int32(sp, &type))){
916 if((ret = krb5_ret_int32(sp, &ncomp))){
920 if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
926 p->name.name_type = type;
927 p->name.name_string.len = ncomp;
928 ret = krb5_ret_string(sp, &p->realm);
933 p->name.name_string.val = calloc(ncomp, sizeof(*p->name.name_string.val));
934 if(p->name.name_string.val == NULL && ncomp != 0){
939 for(i = 0; i < ncomp; i++){
940 ret = krb5_ret_string(sp, &p->name.name_string.val[i]);
943 free(p->name.name_string.val[i--]);
954 * Store a keyblock to the storage.
956 * @param sp the storage buffer to write to
957 * @param p the keyblock to write
959 * @return 0 on success, a Kerberos 5 error code on failure.
961 * @ingroup krb5_storage
964 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
965 krb5_store_keyblock(krb5_storage *sp, krb5_keyblock p)
968 ret = krb5_store_int16(sp, p.keytype);
971 if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
972 /* this should really be enctype, but it is the same as
974 ret = krb5_store_int16(sp, p.keytype);
978 ret = krb5_store_data(sp, p.keyvalue);
983 * Read a keyblock from the storage.
985 * @param sp the storage buffer to write to
986 * @param p the keyblock read from storage, free using krb5_free_keyblock()
988 * @return 0 on success, a Kerberos 5 error code on failure.
990 * @ingroup krb5_storage
993 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
994 krb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p)
999 ret = krb5_ret_int16(sp, &tmp);
1003 if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
1004 ret = krb5_ret_int16(sp, &tmp);
1008 ret = krb5_ret_data(sp, &p->keyvalue);
1013 * Write a times block to storage.
1015 * @param sp the storage buffer to write to
1016 * @param times the times block to write.
1018 * @return 0 on success, a Kerberos 5 error code on failure.
1020 * @ingroup krb5_storage
1023 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1024 krb5_store_times(krb5_storage *sp, krb5_times times)
1027 ret = krb5_store_int32(sp, times.authtime);
1029 ret = krb5_store_int32(sp, times.starttime);
1031 ret = krb5_store_int32(sp, times.endtime);
1033 ret = krb5_store_int32(sp, times.renew_till);
1038 * Read a times block from the storage.
1040 * @param sp the storage buffer to write to
1041 * @param times the times block read from storage
1043 * @return 0 on success, a Kerberos 5 error code on failure.
1045 * @ingroup krb5_storage
1048 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1049 krb5_ret_times(krb5_storage *sp, krb5_times *times)
1053 ret = krb5_ret_int32(sp, &tmp);
1054 times->authtime = tmp;
1056 ret = krb5_ret_int32(sp, &tmp);
1057 times->starttime = tmp;
1059 ret = krb5_ret_int32(sp, &tmp);
1060 times->endtime = tmp;
1062 ret = krb5_ret_int32(sp, &tmp);
1063 times->renew_till = tmp;
1068 * Write a address block to storage.
1070 * @param sp the storage buffer to write to
1071 * @param p the address block to write.
1073 * @return 0 on success, a Kerberos 5 error code on failure.
1075 * @ingroup krb5_storage
1078 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1079 krb5_store_address(krb5_storage *sp, krb5_address p)
1082 ret = krb5_store_int16(sp, p.addr_type);
1084 ret = krb5_store_data(sp, p.address);
1089 * Read a address block from the storage.
1091 * @param sp the storage buffer to write to
1092 * @param adr the address block read from storage
1094 * @return 0 on success, a Kerberos 5 error code on failure.
1096 * @ingroup krb5_storage
1099 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1100 krb5_ret_address(krb5_storage *sp, krb5_address *adr)
1104 ret = krb5_ret_int16(sp, &t);
1107 ret = krb5_ret_data(sp, &adr->address);
1112 * Write a addresses block to storage.
1114 * @param sp the storage buffer to write to
1115 * @param p the addresses block to write.
1117 * @return 0 on success, a Kerberos 5 error code on failure.
1119 * @ingroup krb5_storage
1122 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1123 krb5_store_addrs(krb5_storage *sp, krb5_addresses p)
1127 ret = krb5_store_int32(sp, p.len);
1129 for(i = 0; i<p.len; i++){
1130 ret = krb5_store_address(sp, p.val[i]);
1137 * Read a addresses block from the storage.
1139 * @param sp the storage buffer to write to
1140 * @param adr the addresses block read from storage
1142 * @return 0 on success, a Kerberos 5 error code on failure.
1144 * @ingroup krb5_storage
1147 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1148 krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr)
1154 ret = krb5_ret_int32(sp, &tmp);
1157 ALLOC(adr->val, adr->len);
1158 if (adr->val == NULL && adr->len != 0)
1160 for(i = 0; i < adr->len; i++){
1161 ret = krb5_ret_address(sp, &adr->val[i]);
1168 * Write a auth data block to storage.
1170 * @param sp the storage buffer to write to
1171 * @param auth the auth data block to write.
1173 * @return 0 on success, a Kerberos 5 error code on failure.
1175 * @ingroup krb5_storage
1178 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1179 krb5_store_authdata(krb5_storage *sp, krb5_authdata auth)
1181 krb5_error_code ret;
1183 ret = krb5_store_int32(sp, auth.len);
1185 for(i = 0; i < auth.len; i++){
1186 ret = krb5_store_int16(sp, auth.val[i].ad_type);
1188 ret = krb5_store_data(sp, auth.val[i].ad_data);
1195 * Read a auth data from the storage.
1197 * @param sp the storage buffer to write to
1198 * @param auth the auth data block read from storage
1200 * @return 0 on success, a Kerberos 5 error code on failure.
1202 * @ingroup krb5_storage
1205 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1206 krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth)
1208 krb5_error_code ret;
1212 ret = krb5_ret_int32(sp, &tmp);
1214 ALLOC_SEQ(auth, tmp);
1215 if (auth->val == NULL && tmp != 0)
1217 for(i = 0; i < tmp; i++){
1218 ret = krb5_ret_int16(sp, &tmp2);
1220 auth->val[i].ad_type = tmp2;
1221 ret = krb5_ret_data(sp, &auth->val[i].ad_data);
1228 bitswap32(int32_t b)
1232 for (i = 0; i < 32; i++) {
1233 r = r << 1 | (b & 1);
1240 * Write a credentials block to storage.
1242 * @param sp the storage buffer to write to
1243 * @param creds the creds block to write.
1245 * @return 0 on success, a Kerberos 5 error code on failure.
1247 * @ingroup krb5_storage
1250 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1251 krb5_store_creds(krb5_storage *sp, krb5_creds *creds)
1255 ret = krb5_store_principal(sp, creds->client);
1258 ret = krb5_store_principal(sp, creds->server);
1261 ret = krb5_store_keyblock(sp, creds->session);
1264 ret = krb5_store_times(sp, creds->times);
1267 ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
1271 if(krb5_storage_is_flags(sp, KRB5_STORAGE_CREDS_FLAGS_WRONG_BITORDER))
1272 ret = krb5_store_int32(sp, creds->flags.i);
1274 ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
1278 ret = krb5_store_addrs(sp, creds->addresses);
1281 ret = krb5_store_authdata(sp, creds->authdata);
1284 ret = krb5_store_data(sp, creds->ticket);
1287 ret = krb5_store_data(sp, creds->second_ticket);
1292 * Read a credentials block from the storage.
1294 * @param sp the storage buffer to write to
1295 * @param creds the credentials block read from storage
1297 * @return 0 on success, a Kerberos 5 error code on failure.
1299 * @ingroup krb5_storage
1302 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1303 krb5_ret_creds(krb5_storage *sp, krb5_creds *creds)
1305 krb5_error_code ret;
1309 memset(creds, 0, sizeof(*creds));
1310 ret = krb5_ret_principal (sp, &creds->client);
1311 if(ret) goto cleanup;
1312 ret = krb5_ret_principal (sp, &creds->server);
1313 if(ret) goto cleanup;
1314 ret = krb5_ret_keyblock (sp, &creds->session);
1315 if(ret) goto cleanup;
1316 ret = krb5_ret_times (sp, &creds->times);
1317 if(ret) goto cleanup;
1318 ret = krb5_ret_int8 (sp, &dummy8);
1319 if(ret) goto cleanup;
1320 ret = krb5_ret_int32 (sp, &dummy32);
1321 if(ret) goto cleanup;
1323 * Runtime detect the what is the higher bits of the bitfield. If
1324 * any of the higher bits are set in the input data, it's either a
1325 * new ticket flag (and this code need to be removed), or it's a
1326 * MIT cache (or new Heimdal cache), lets change it to our current
1330 uint32_t mask = 0xffff0000;
1332 creds->flags.b.anonymous = 1;
1333 if (creds->flags.i & mask)
1336 dummy32 = bitswap32(dummy32);
1338 creds->flags.i = dummy32;
1339 ret = krb5_ret_addrs (sp, &creds->addresses);
1340 if(ret) goto cleanup;
1341 ret = krb5_ret_authdata (sp, &creds->authdata);
1342 if(ret) goto cleanup;
1343 ret = krb5_ret_data (sp, &creds->ticket);
1344 if(ret) goto cleanup;
1345 ret = krb5_ret_data (sp, &creds->second_ticket);
1349 krb5_free_cred_contents(context, creds); /* XXX */
1355 #define SC_CLIENT_PRINCIPAL 0x0001
1356 #define SC_SERVER_PRINCIPAL 0x0002
1357 #define SC_SESSION_KEY 0x0004
1358 #define SC_TICKET 0x0008
1359 #define SC_SECOND_TICKET 0x0010
1360 #define SC_AUTHDATA 0x0020
1361 #define SC_ADDRESSES 0x0040
1364 * Write a tagged credentials block to storage.
1366 * @param sp the storage buffer to write to
1367 * @param creds the creds block to write.
1369 * @return 0 on success, a Kerberos 5 error code on failure.
1371 * @ingroup krb5_storage
1374 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1375 krb5_store_creds_tag(krb5_storage *sp, krb5_creds *creds)
1381 header |= SC_CLIENT_PRINCIPAL;
1383 header |= SC_SERVER_PRINCIPAL;
1384 if (creds->session.keytype != ETYPE_NULL)
1385 header |= SC_SESSION_KEY;
1386 if (creds->ticket.data)
1387 header |= SC_TICKET;
1388 if (creds->second_ticket.length)
1389 header |= SC_SECOND_TICKET;
1390 if (creds->authdata.len)
1391 header |= SC_AUTHDATA;
1392 if (creds->addresses.len)
1393 header |= SC_ADDRESSES;
1395 ret = krb5_store_int32(sp, header);
1399 if (creds->client) {
1400 ret = krb5_store_principal(sp, creds->client);
1405 if (creds->server) {
1406 ret = krb5_store_principal(sp, creds->server);
1411 if (creds->session.keytype != ETYPE_NULL) {
1412 ret = krb5_store_keyblock(sp, creds->session);
1417 ret = krb5_store_times(sp, creds->times);
1420 ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
1424 ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
1428 if (creds->addresses.len) {
1429 ret = krb5_store_addrs(sp, creds->addresses);
1434 if (creds->authdata.len) {
1435 ret = krb5_store_authdata(sp, creds->authdata);
1440 if (creds->ticket.data) {
1441 ret = krb5_store_data(sp, creds->ticket);
1446 if (creds->second_ticket.data) {
1447 ret = krb5_store_data(sp, creds->second_ticket);
1456 * Read a tagged credentials block from the storage.
1458 * @param sp the storage buffer to write to
1459 * @param creds the credentials block read from storage
1461 * @return 0 on success, a Kerberos 5 error code on failure.
1463 * @ingroup krb5_storage
1466 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1467 krb5_ret_creds_tag(krb5_storage *sp,
1470 krb5_error_code ret;
1472 int32_t dummy32, header;
1474 memset(creds, 0, sizeof(*creds));
1476 ret = krb5_ret_int32 (sp, &header);
1477 if (ret) goto cleanup;
1479 if (header & SC_CLIENT_PRINCIPAL) {
1480 ret = krb5_ret_principal (sp, &creds->client);
1481 if(ret) goto cleanup;
1483 if (header & SC_SERVER_PRINCIPAL) {
1484 ret = krb5_ret_principal (sp, &creds->server);
1485 if(ret) goto cleanup;
1487 if (header & SC_SESSION_KEY) {
1488 ret = krb5_ret_keyblock (sp, &creds->session);
1489 if(ret) goto cleanup;
1491 ret = krb5_ret_times (sp, &creds->times);
1492 if(ret) goto cleanup;
1493 ret = krb5_ret_int8 (sp, &dummy8);
1494 if(ret) goto cleanup;
1495 ret = krb5_ret_int32 (sp, &dummy32);
1496 if(ret) goto cleanup;
1498 * Runtime detect the what is the higher bits of the bitfield. If
1499 * any of the higher bits are set in the input data, it's either a
1500 * new ticket flag (and this code need to be removed), or it's a
1501 * MIT cache (or new Heimdal cache), lets change it to our current
1505 uint32_t mask = 0xffff0000;
1507 creds->flags.b.anonymous = 1;
1508 if (creds->flags.i & mask)
1511 dummy32 = bitswap32(dummy32);
1513 creds->flags.i = dummy32;
1514 if (header & SC_ADDRESSES) {
1515 ret = krb5_ret_addrs (sp, &creds->addresses);
1516 if(ret) goto cleanup;
1518 if (header & SC_AUTHDATA) {
1519 ret = krb5_ret_authdata (sp, &creds->authdata);
1520 if(ret) goto cleanup;
1522 if (header & SC_TICKET) {
1523 ret = krb5_ret_data (sp, &creds->ticket);
1524 if(ret) goto cleanup;
1526 if (header & SC_SECOND_TICKET) {
1527 ret = krb5_ret_data (sp, &creds->second_ticket);
1528 if(ret) goto cleanup;
1534 krb5_free_cred_contents(context, creds); /* XXX */