xref: /freebsd/crypto/heimdal/lib/krb5/store.c (revision 6a068746777241722b2b32c5d0bc443a2a64d80b)
1b528cefcSMark Murray /*
2*ae771770SStanislav Sedov  * Copyright (c) 1997-2008 Kungliga Tekniska Högskolan
3b528cefcSMark Murray  * (Royal Institute of Technology, Stockholm, Sweden).
4b528cefcSMark Murray  * All rights reserved.
5b528cefcSMark Murray  *
6b528cefcSMark Murray  * Redistribution and use in source and binary forms, with or without
7b528cefcSMark Murray  * modification, are permitted provided that the following conditions
8b528cefcSMark Murray  * are met:
9b528cefcSMark Murray  *
10b528cefcSMark Murray  * 1. Redistributions of source code must retain the above copyright
11b528cefcSMark Murray  *    notice, this list of conditions and the following disclaimer.
12b528cefcSMark Murray  *
13b528cefcSMark Murray  * 2. Redistributions in binary form must reproduce the above copyright
14b528cefcSMark Murray  *    notice, this list of conditions and the following disclaimer in the
15b528cefcSMark Murray  *    documentation and/or other materials provided with the distribution.
16b528cefcSMark Murray  *
17b528cefcSMark Murray  * 3. Neither the name of the Institute nor the names of its contributors
18b528cefcSMark Murray  *    may be used to endorse or promote products derived from this software
19b528cefcSMark Murray  *    without specific prior written permission.
20b528cefcSMark Murray  *
21b528cefcSMark Murray  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22b528cefcSMark Murray  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23b528cefcSMark Murray  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24b528cefcSMark Murray  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25b528cefcSMark Murray  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26b528cefcSMark Murray  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27b528cefcSMark Murray  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28b528cefcSMark Murray  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29b528cefcSMark Murray  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30b528cefcSMark Murray  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31b528cefcSMark Murray  * SUCH DAMAGE.
32b528cefcSMark Murray  */
33b528cefcSMark Murray 
34b528cefcSMark Murray #include "krb5_locl.h"
358373020dSJacques Vidrine #include "store-int.h"
36b528cefcSMark Murray 
37adb0ddaeSAssar Westerlund #define BYTEORDER_IS(SP, V) (((SP)->flags & KRB5_STORAGE_BYTEORDER_MASK) == (V))
38adb0ddaeSAssar Westerlund #define BYTEORDER_IS_LE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_LE)
39adb0ddaeSAssar Westerlund #define BYTEORDER_IS_BE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_BE)
40adb0ddaeSAssar Westerlund #define BYTEORDER_IS_HOST(SP) (BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_HOST) || \
41adb0ddaeSAssar Westerlund 			       krb5_storage_is_flags((SP), KRB5_STORAGE_HOST_BYTEORDER))
42b528cefcSMark Murray 
43*ae771770SStanislav Sedov /**
44*ae771770SStanislav Sedov  * Add the flags on a storage buffer by or-ing in the flags to the buffer.
45*ae771770SStanislav Sedov  *
46*ae771770SStanislav Sedov  * @param sp the storage buffer to set the flags on
47*ae771770SStanislav Sedov  * @param flags the flags to set
48*ae771770SStanislav Sedov  *
49*ae771770SStanislav Sedov  * @ingroup krb5_storage
50*ae771770SStanislav Sedov  */
51*ae771770SStanislav Sedov 
52*ae771770SStanislav Sedov KRB5_LIB_FUNCTION void KRB5_LIB_CALL
krb5_storage_set_flags(krb5_storage * sp,krb5_flags flags)53b528cefcSMark Murray krb5_storage_set_flags(krb5_storage *sp, krb5_flags flags)
54b528cefcSMark Murray {
55b528cefcSMark Murray     sp->flags |= flags;
56b528cefcSMark Murray }
57b528cefcSMark Murray 
58*ae771770SStanislav Sedov /**
59*ae771770SStanislav Sedov  * Clear the flags on a storage buffer
60*ae771770SStanislav Sedov  *
61*ae771770SStanislav Sedov  * @param sp the storage buffer to clear the flags on
62*ae771770SStanislav Sedov  * @param flags the flags to clear
63*ae771770SStanislav Sedov  *
64*ae771770SStanislav Sedov  * @ingroup krb5_storage
65*ae771770SStanislav Sedov  */
66*ae771770SStanislav Sedov 
67*ae771770SStanislav Sedov KRB5_LIB_FUNCTION void KRB5_LIB_CALL
krb5_storage_clear_flags(krb5_storage * sp,krb5_flags flags)68b528cefcSMark Murray krb5_storage_clear_flags(krb5_storage *sp, krb5_flags flags)
69b528cefcSMark Murray {
70b528cefcSMark Murray     sp->flags &= ~flags;
71b528cefcSMark Murray }
72b528cefcSMark Murray 
73*ae771770SStanislav Sedov /**
74*ae771770SStanislav Sedov  * Return true or false depending on if the storage flags is set or
75*ae771770SStanislav Sedov  * not. NB testing for the flag 0 always return true.
76*ae771770SStanislav Sedov  *
77*ae771770SStanislav Sedov  * @param sp the storage buffer to check flags on
78*ae771770SStanislav Sedov  * @param flags The flags to test for
79*ae771770SStanislav Sedov  *
80*ae771770SStanislav Sedov  * @return true if all the flags are set, false if not.
81*ae771770SStanislav Sedov  *
82*ae771770SStanislav Sedov  * @ingroup krb5_storage
83*ae771770SStanislav Sedov  */
84*ae771770SStanislav Sedov 
85*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
krb5_storage_is_flags(krb5_storage * sp,krb5_flags flags)86b528cefcSMark Murray krb5_storage_is_flags(krb5_storage *sp, krb5_flags flags)
87b528cefcSMark Murray {
88b528cefcSMark Murray     return (sp->flags & flags) == flags;
89b528cefcSMark Murray }
90b528cefcSMark Murray 
91*ae771770SStanislav Sedov /**
92*ae771770SStanislav Sedov  * Set the new byte order of the storage buffer.
93*ae771770SStanislav Sedov  *
94*ae771770SStanislav Sedov  * @param sp the storage buffer to set the byte order for.
95*ae771770SStanislav Sedov  * @param byteorder the new byte order.
96*ae771770SStanislav Sedov  *
97*ae771770SStanislav Sedov  * The byte order are: KRB5_STORAGE_BYTEORDER_BE,
98*ae771770SStanislav Sedov  * KRB5_STORAGE_BYTEORDER_LE and KRB5_STORAGE_BYTEORDER_HOST.
99*ae771770SStanislav Sedov  *
100*ae771770SStanislav Sedov  * @ingroup krb5_storage
101*ae771770SStanislav Sedov  */
102*ae771770SStanislav Sedov 
103*ae771770SStanislav Sedov KRB5_LIB_FUNCTION void KRB5_LIB_CALL
krb5_storage_set_byteorder(krb5_storage * sp,krb5_flags byteorder)104adb0ddaeSAssar Westerlund krb5_storage_set_byteorder(krb5_storage *sp, krb5_flags byteorder)
105adb0ddaeSAssar Westerlund {
106adb0ddaeSAssar Westerlund     sp->flags &= ~KRB5_STORAGE_BYTEORDER_MASK;
107adb0ddaeSAssar Westerlund     sp->flags |= byteorder;
108adb0ddaeSAssar Westerlund }
109adb0ddaeSAssar Westerlund 
110*ae771770SStanislav Sedov /**
111*ae771770SStanislav Sedov  * Return the current byteorder for the buffer. See krb5_storage_set_byteorder() for the list or byte order contants.
112*ae771770SStanislav Sedov  *
113*ae771770SStanislav Sedov  * @ingroup krb5_storage
114*ae771770SStanislav Sedov  */
115*ae771770SStanislav Sedov 
116*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_flags KRB5_LIB_CALL
krb5_storage_get_byteorder(krb5_storage * sp)117*ae771770SStanislav Sedov krb5_storage_get_byteorder(krb5_storage *sp)
118adb0ddaeSAssar Westerlund {
119adb0ddaeSAssar Westerlund     return sp->flags & KRB5_STORAGE_BYTEORDER_MASK;
120adb0ddaeSAssar Westerlund }
121adb0ddaeSAssar Westerlund 
122*ae771770SStanislav Sedov /**
123*ae771770SStanislav Sedov  * Set the max alloc value
124*ae771770SStanislav Sedov  *
125*ae771770SStanislav Sedov  * @param sp the storage buffer set the max allow for
126*ae771770SStanislav Sedov  * @param size maximum size to allocate, use 0 to remove limit
127*ae771770SStanislav Sedov  *
128*ae771770SStanislav Sedov  * @ingroup krb5_storage
129*ae771770SStanislav Sedov  */
130*ae771770SStanislav Sedov 
131*ae771770SStanislav Sedov KRB5_LIB_FUNCTION void KRB5_LIB_CALL
krb5_storage_set_max_alloc(krb5_storage * sp,size_t size)132*ae771770SStanislav Sedov krb5_storage_set_max_alloc(krb5_storage *sp, size_t size)
133*ae771770SStanislav Sedov {
134*ae771770SStanislav Sedov     sp->max_alloc = size;
135*ae771770SStanislav Sedov }
136*ae771770SStanislav Sedov 
137*ae771770SStanislav Sedov /* don't allocate unresonable amount of memory */
138*ae771770SStanislav Sedov static krb5_error_code
size_too_large(krb5_storage * sp,size_t size)139*ae771770SStanislav Sedov size_too_large(krb5_storage *sp, size_t size)
140*ae771770SStanislav Sedov {
141*ae771770SStanislav Sedov     if (sp->max_alloc && sp->max_alloc < size)
142*ae771770SStanislav Sedov 	return HEIM_ERR_TOO_BIG;
143*ae771770SStanislav Sedov     return 0;
144*ae771770SStanislav Sedov }
145*ae771770SStanislav Sedov 
146*ae771770SStanislav Sedov static krb5_error_code
size_too_large_num(krb5_storage * sp,size_t count,size_t size)147*ae771770SStanislav Sedov size_too_large_num(krb5_storage *sp, size_t count, size_t size)
148*ae771770SStanislav Sedov {
149*ae771770SStanislav Sedov     if (sp->max_alloc == 0 || size == 0)
150*ae771770SStanislav Sedov 	return 0;
151*ae771770SStanislav Sedov     size = sp->max_alloc / size;
152*ae771770SStanislav Sedov     if (size < count)
153*ae771770SStanislav Sedov 	return HEIM_ERR_TOO_BIG;
154*ae771770SStanislav Sedov     return 0;
155*ae771770SStanislav Sedov }
156*ae771770SStanislav Sedov 
157*ae771770SStanislav Sedov /**
158*ae771770SStanislav Sedov  * Seek to a new offset.
159*ae771770SStanislav Sedov  *
160*ae771770SStanislav Sedov  * @param sp the storage buffer to seek in.
161*ae771770SStanislav Sedov  * @param offset the offset to seek
162*ae771770SStanislav Sedov  * @param whence relateive searching, SEEK_CUR from the current
163*ae771770SStanislav Sedov  * position, SEEK_END from the end, SEEK_SET absolute from the start.
164*ae771770SStanislav Sedov  *
165*ae771770SStanislav Sedov  * @return The new current offset
166*ae771770SStanislav Sedov  *
167*ae771770SStanislav Sedov  * @ingroup krb5_storage
168*ae771770SStanislav Sedov  */
169*ae771770SStanislav Sedov 
170*ae771770SStanislav Sedov KRB5_LIB_FUNCTION off_t KRB5_LIB_CALL
krb5_storage_seek(krb5_storage * sp,off_t offset,int whence)1718373020dSJacques Vidrine krb5_storage_seek(krb5_storage *sp, off_t offset, int whence)
1728373020dSJacques Vidrine {
1738373020dSJacques Vidrine     return (*sp->seek)(sp, offset, whence);
1748373020dSJacques Vidrine }
175adb0ddaeSAssar Westerlund 
176*ae771770SStanislav Sedov /**
177*ae771770SStanislav Sedov  * Truncate the storage buffer in sp to offset.
178*ae771770SStanislav Sedov  *
179*ae771770SStanislav Sedov  * @param sp the storage buffer to truncate.
180*ae771770SStanislav Sedov  * @param offset the offset to truncate too.
181*ae771770SStanislav Sedov  *
182*ae771770SStanislav Sedov  * @return An Kerberos 5 error code.
183*ae771770SStanislav Sedov  *
184*ae771770SStanislav Sedov  * @ingroup krb5_storage
185*ae771770SStanislav Sedov  */
186*ae771770SStanislav Sedov 
187*ae771770SStanislav Sedov KRB5_LIB_FUNCTION int KRB5_LIB_CALL
krb5_storage_truncate(krb5_storage * sp,off_t offset)188*ae771770SStanislav Sedov krb5_storage_truncate(krb5_storage *sp, off_t offset)
189*ae771770SStanislav Sedov {
190*ae771770SStanislav Sedov     return (*sp->trunc)(sp, offset);
191*ae771770SStanislav Sedov }
192*ae771770SStanislav Sedov 
193*ae771770SStanislav Sedov /**
194*ae771770SStanislav Sedov  * Read to the storage buffer.
195*ae771770SStanislav Sedov  *
196*ae771770SStanislav Sedov  * @param sp the storage buffer to read from
197*ae771770SStanislav Sedov  * @param buf the buffer to store the data in
198*ae771770SStanislav Sedov  * @param len the length to read
199*ae771770SStanislav Sedov  *
200*ae771770SStanislav Sedov  * @return The length of data read (can be shorter then len), or negative on error.
201*ae771770SStanislav Sedov  *
202*ae771770SStanislav Sedov  * @ingroup krb5_storage
203*ae771770SStanislav Sedov  */
204*ae771770SStanislav Sedov 
205*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL
krb5_storage_read(krb5_storage * sp,void * buf,size_t len)2068373020dSJacques Vidrine krb5_storage_read(krb5_storage *sp, void *buf, size_t len)
2078373020dSJacques Vidrine {
2088373020dSJacques Vidrine     return sp->fetch(sp, buf, len);
2098373020dSJacques Vidrine }
2108373020dSJacques Vidrine 
211*ae771770SStanislav Sedov /**
212*ae771770SStanislav Sedov  * Write to the storage buffer.
213*ae771770SStanislav Sedov  *
214*ae771770SStanislav Sedov  * @param sp the storage buffer to write to
215*ae771770SStanislav Sedov  * @param buf the buffer to write to the storage buffer
216*ae771770SStanislav Sedov  * @param len the length to write
217*ae771770SStanislav Sedov  *
218*ae771770SStanislav Sedov  * @return The length of data written (can be shorter then len), or negative on error.
219*ae771770SStanislav Sedov  *
220*ae771770SStanislav Sedov  * @ingroup krb5_storage
221*ae771770SStanislav Sedov  */
222*ae771770SStanislav Sedov 
223*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL
krb5_storage_write(krb5_storage * sp,const void * buf,size_t len)2248373020dSJacques Vidrine krb5_storage_write(krb5_storage *sp, const void *buf, size_t len)
2258373020dSJacques Vidrine {
2268373020dSJacques Vidrine     return sp->store(sp, buf, len);
2278373020dSJacques Vidrine }
2288373020dSJacques Vidrine 
229*ae771770SStanislav Sedov /**
230*ae771770SStanislav Sedov  * Set the return code that will be used when end of storage is reached.
231*ae771770SStanislav Sedov  *
232*ae771770SStanislav Sedov  * @param sp the storage
233*ae771770SStanislav Sedov  * @param code the error code to return on end of storage
234*ae771770SStanislav Sedov  *
235*ae771770SStanislav Sedov  * @ingroup krb5_storage
236*ae771770SStanislav Sedov  */
237*ae771770SStanislav Sedov 
238*ae771770SStanislav Sedov KRB5_LIB_FUNCTION void KRB5_LIB_CALL
krb5_storage_set_eof_code(krb5_storage * sp,int code)2398373020dSJacques Vidrine krb5_storage_set_eof_code(krb5_storage *sp, int code)
2408373020dSJacques Vidrine {
2418373020dSJacques Vidrine     sp->eof_code = code;
2428373020dSJacques Vidrine }
2438373020dSJacques Vidrine 
244*ae771770SStanislav Sedov /**
245*ae771770SStanislav Sedov  * Get the return code that will be used when end of storage is reached.
246*ae771770SStanislav Sedov  *
247*ae771770SStanislav Sedov  * @param sp the storage
248*ae771770SStanislav Sedov  *
249*ae771770SStanislav Sedov  * @return storage error code
250*ae771770SStanislav Sedov  *
251*ae771770SStanislav Sedov  * @ingroup krb5_storage
252*ae771770SStanislav Sedov  */
253*ae771770SStanislav Sedov 
254*ae771770SStanislav Sedov KRB5_LIB_FUNCTION int KRB5_LIB_CALL
krb5_storage_get_eof_code(krb5_storage * sp)255*ae771770SStanislav Sedov krb5_storage_get_eof_code(krb5_storage *sp)
256b528cefcSMark Murray {
257*ae771770SStanislav Sedov     return sp->eof_code;
258b528cefcSMark Murray }
259b528cefcSMark Murray 
260*ae771770SStanislav Sedov /**
261*ae771770SStanislav Sedov  * Free a krb5 storage.
262*ae771770SStanislav Sedov  *
263*ae771770SStanislav Sedov  * @param sp the storage to free.
264*ae771770SStanislav Sedov  *
265*ae771770SStanislav Sedov  * @return An Kerberos 5 error code.
266*ae771770SStanislav Sedov  *
267*ae771770SStanislav Sedov  * @ingroup krb5_storage
268*ae771770SStanislav Sedov  */
269b528cefcSMark Murray 
270*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_storage_free(krb5_storage * sp)271b528cefcSMark Murray krb5_storage_free(krb5_storage *sp)
272b528cefcSMark Murray {
273b528cefcSMark Murray     if(sp->free)
274b528cefcSMark Murray 	(*sp->free)(sp);
275b528cefcSMark Murray     free(sp->data);
276b528cefcSMark Murray     free(sp);
277b528cefcSMark Murray     return 0;
278b528cefcSMark Murray }
279b528cefcSMark Murray 
280*ae771770SStanislav Sedov /**
281*ae771770SStanislav Sedov  * Copy the contnent of storage
282*ae771770SStanislav Sedov  *
283*ae771770SStanislav Sedov  * @param sp the storage to copy to a data
284*ae771770SStanislav Sedov  * @param data the copied data, free with krb5_data_free()
285*ae771770SStanislav Sedov  *
286*ae771770SStanislav Sedov  * @return 0 for success, or a Kerberos 5 error code on failure.
287*ae771770SStanislav Sedov  *
288*ae771770SStanislav Sedov  * @ingroup krb5_storage
289*ae771770SStanislav Sedov  */
290*ae771770SStanislav Sedov 
291*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_storage_to_data(krb5_storage * sp,krb5_data * data)292b528cefcSMark Murray krb5_storage_to_data(krb5_storage *sp, krb5_data *data)
293b528cefcSMark Murray {
294*ae771770SStanislav Sedov     off_t pos, size;
295b528cefcSMark Murray     krb5_error_code ret;
296b528cefcSMark Murray 
297b528cefcSMark Murray     pos = sp->seek(sp, 0, SEEK_CUR);
298*ae771770SStanislav Sedov     if (pos < 0)
299*ae771770SStanislav Sedov 	return HEIM_ERR_NOT_SEEKABLE;
300*ae771770SStanislav Sedov     size = sp->seek(sp, 0, SEEK_END);
301*ae771770SStanislav Sedov     ret = size_too_large(sp, size);
302*ae771770SStanislav Sedov     if (ret)
303*ae771770SStanislav Sedov 	return ret;
304b528cefcSMark Murray     ret = krb5_data_alloc(data, size);
305b528cefcSMark Murray     if (ret) {
306b528cefcSMark Murray 	sp->seek(sp, pos, SEEK_SET);
307b528cefcSMark Murray 	return ret;
308b528cefcSMark Murray     }
309b528cefcSMark Murray     if (size) {
310b528cefcSMark Murray 	sp->seek(sp, 0, SEEK_SET);
311b528cefcSMark Murray 	sp->fetch(sp, data->data, data->length);
312b528cefcSMark Murray 	sp->seek(sp, pos, SEEK_SET);
313b528cefcSMark Murray     }
314b528cefcSMark Murray     return 0;
315b528cefcSMark Murray }
316b528cefcSMark Murray 
317b528cefcSMark Murray static krb5_error_code
krb5_store_int(krb5_storage * sp,int32_t value,size_t len)318b528cefcSMark Murray krb5_store_int(krb5_storage *sp,
319b528cefcSMark Murray 	       int32_t value,
320b528cefcSMark Murray 	       size_t len)
321b528cefcSMark Murray {
322b528cefcSMark Murray     int ret;
323adb0ddaeSAssar Westerlund     unsigned char v[16];
324b528cefcSMark Murray 
325adb0ddaeSAssar Westerlund     if(len > sizeof(v))
326adb0ddaeSAssar Westerlund 	return EINVAL;
327b528cefcSMark Murray     _krb5_put_int(v, value, len);
328b528cefcSMark Murray     ret = sp->store(sp, v, len);
329*ae771770SStanislav Sedov     if (ret < 0)
330*ae771770SStanislav Sedov 	return errno;
331*ae771770SStanislav Sedov     if ((size_t)ret != len)
332*ae771770SStanislav Sedov 	return sp->eof_code;
333b528cefcSMark Murray     return 0;
334b528cefcSMark Murray }
335b528cefcSMark Murray 
336*ae771770SStanislav Sedov /**
337*ae771770SStanislav Sedov  * Store a int32 to storage, byte order is controlled by the settings
338*ae771770SStanislav Sedov  * on the storage, see krb5_storage_set_byteorder().
339*ae771770SStanislav Sedov  *
340*ae771770SStanislav Sedov  * @param sp the storage to write too
341*ae771770SStanislav Sedov  * @param value the value to store
342*ae771770SStanislav Sedov  *
343*ae771770SStanislav Sedov  * @return 0 for success, or a Kerberos 5 error code on failure.
344*ae771770SStanislav Sedov  *
345*ae771770SStanislav Sedov  * @ingroup krb5_storage
346*ae771770SStanislav Sedov  */
347*ae771770SStanislav Sedov 
348*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_store_int32(krb5_storage * sp,int32_t value)349b528cefcSMark Murray krb5_store_int32(krb5_storage *sp,
350b528cefcSMark Murray 		 int32_t value)
351b528cefcSMark Murray {
352adb0ddaeSAssar Westerlund     if(BYTEORDER_IS_HOST(sp))
353b528cefcSMark Murray 	value = htonl(value);
354adb0ddaeSAssar Westerlund     else if(BYTEORDER_IS_LE(sp))
355adb0ddaeSAssar Westerlund 	value = bswap32(value);
356b528cefcSMark Murray     return krb5_store_int(sp, value, 4);
357b528cefcSMark Murray }
358b528cefcSMark Murray 
359*ae771770SStanislav Sedov /**
360*ae771770SStanislav Sedov  * Store a uint32 to storage, byte order is controlled by the settings
361*ae771770SStanislav Sedov  * on the storage, see krb5_storage_set_byteorder().
362*ae771770SStanislav Sedov  *
363*ae771770SStanislav Sedov  * @param sp the storage to write too
364*ae771770SStanislav Sedov  * @param value the value to store
365*ae771770SStanislav Sedov  *
366*ae771770SStanislav Sedov  * @return 0 for success, or a Kerberos 5 error code on failure.
367*ae771770SStanislav Sedov  *
368*ae771770SStanislav Sedov  * @ingroup krb5_storage
369*ae771770SStanislav Sedov  */
370*ae771770SStanislav Sedov 
371*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_store_uint32(krb5_storage * sp,uint32_t value)372c19800e8SDoug Rabson krb5_store_uint32(krb5_storage *sp,
373c19800e8SDoug Rabson 		  uint32_t value)
374c19800e8SDoug Rabson {
375c19800e8SDoug Rabson     return krb5_store_int32(sp, (int32_t)value);
376c19800e8SDoug Rabson }
377c19800e8SDoug Rabson 
378b528cefcSMark Murray static krb5_error_code
krb5_ret_int(krb5_storage * sp,int32_t * value,size_t len)379b528cefcSMark Murray krb5_ret_int(krb5_storage *sp,
380b528cefcSMark Murray 	     int32_t *value,
381b528cefcSMark Murray 	     size_t len)
382b528cefcSMark Murray {
383b528cefcSMark Murray     int ret;
384b528cefcSMark Murray     unsigned char v[4];
385b528cefcSMark Murray     unsigned long w;
386b528cefcSMark Murray     ret = sp->fetch(sp, v, len);
387*ae771770SStanislav Sedov     if (ret < 0)
388*ae771770SStanislav Sedov 	return errno;
389*ae771770SStanislav Sedov     if ((size_t)ret != len)
390*ae771770SStanislav Sedov 	return sp->eof_code;
391b528cefcSMark Murray     _krb5_get_int(v, &w, len);
392b528cefcSMark Murray     *value = w;
393b528cefcSMark Murray     return 0;
394b528cefcSMark Murray }
395b528cefcSMark Murray 
396*ae771770SStanislav Sedov /**
397*ae771770SStanislav Sedov  * Read a int32 from storage, byte order is controlled by the settings
398*ae771770SStanislav Sedov  * on the storage, see krb5_storage_set_byteorder().
399*ae771770SStanislav Sedov  *
400*ae771770SStanislav Sedov  * @param sp the storage to write too
401*ae771770SStanislav Sedov  * @param value the value read from the buffer
402*ae771770SStanislav Sedov  *
403*ae771770SStanislav Sedov  * @return 0 for success, or a Kerberos 5 error code on failure.
404*ae771770SStanislav Sedov  *
405*ae771770SStanislav Sedov  * @ingroup krb5_storage
406*ae771770SStanislav Sedov  */
407*ae771770SStanislav Sedov 
408*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_int32(krb5_storage * sp,int32_t * value)409b528cefcSMark Murray krb5_ret_int32(krb5_storage *sp,
410b528cefcSMark Murray 	       int32_t *value)
411b528cefcSMark Murray {
412b528cefcSMark Murray     krb5_error_code ret = krb5_ret_int(sp, value, 4);
413b528cefcSMark Murray     if(ret)
414b528cefcSMark Murray 	return ret;
415adb0ddaeSAssar Westerlund     if(BYTEORDER_IS_HOST(sp))
416adb0ddaeSAssar Westerlund 	*value = htonl(*value);
417adb0ddaeSAssar Westerlund     else if(BYTEORDER_IS_LE(sp))
418adb0ddaeSAssar Westerlund 	*value = bswap32(*value);
419b528cefcSMark Murray     return 0;
420b528cefcSMark Murray }
421b528cefcSMark Murray 
422*ae771770SStanislav Sedov /**
423*ae771770SStanislav Sedov  * Read a uint32 from storage, byte order is controlled by the settings
424*ae771770SStanislav Sedov  * on the storage, see krb5_storage_set_byteorder().
425*ae771770SStanislav Sedov  *
426*ae771770SStanislav Sedov  * @param sp the storage to write too
427*ae771770SStanislav Sedov  * @param value the value read from the buffer
428*ae771770SStanislav Sedov  *
429*ae771770SStanislav Sedov  * @return 0 for success, or a Kerberos 5 error code on failure.
430*ae771770SStanislav Sedov  *
431*ae771770SStanislav Sedov  * @ingroup krb5_storage
432*ae771770SStanislav Sedov  */
433*ae771770SStanislav Sedov 
434*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_uint32(krb5_storage * sp,uint32_t * value)435c19800e8SDoug Rabson krb5_ret_uint32(krb5_storage *sp,
436c19800e8SDoug Rabson 		uint32_t *value)
437c19800e8SDoug Rabson {
438c19800e8SDoug Rabson     krb5_error_code ret;
439c19800e8SDoug Rabson     int32_t v;
440c19800e8SDoug Rabson 
441c19800e8SDoug Rabson     ret = krb5_ret_int32(sp, &v);
442c19800e8SDoug Rabson     if (ret == 0)
443c19800e8SDoug Rabson 	*value = (uint32_t)v;
444c19800e8SDoug Rabson 
445c19800e8SDoug Rabson     return ret;
446c19800e8SDoug Rabson }
447c19800e8SDoug Rabson 
448*ae771770SStanislav Sedov /**
449*ae771770SStanislav Sedov  * Store a int16 to storage, byte order is controlled by the settings
450*ae771770SStanislav Sedov  * on the storage, see krb5_storage_set_byteorder().
451*ae771770SStanislav Sedov  *
452*ae771770SStanislav Sedov  * @param sp the storage to write too
453*ae771770SStanislav Sedov  * @param value the value to store
454*ae771770SStanislav Sedov  *
455*ae771770SStanislav Sedov  * @return 0 for success, or a Kerberos 5 error code on failure.
456*ae771770SStanislav Sedov  *
457*ae771770SStanislav Sedov  * @ingroup krb5_storage
458*ae771770SStanislav Sedov  */
459*ae771770SStanislav Sedov 
460*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_store_int16(krb5_storage * sp,int16_t value)461b528cefcSMark Murray krb5_store_int16(krb5_storage *sp,
462b528cefcSMark Murray 		 int16_t value)
463b528cefcSMark Murray {
464adb0ddaeSAssar Westerlund     if(BYTEORDER_IS_HOST(sp))
465b528cefcSMark Murray 	value = htons(value);
466adb0ddaeSAssar Westerlund     else if(BYTEORDER_IS_LE(sp))
467adb0ddaeSAssar Westerlund 	value = bswap16(value);
468b528cefcSMark Murray     return krb5_store_int(sp, value, 2);
469b528cefcSMark Murray }
470b528cefcSMark Murray 
471*ae771770SStanislav Sedov /**
472*ae771770SStanislav Sedov  * Store a uint16 to storage, byte order is controlled by the settings
473*ae771770SStanislav Sedov  * on the storage, see krb5_storage_set_byteorder().
474*ae771770SStanislav Sedov  *
475*ae771770SStanislav Sedov  * @param sp the storage to write too
476*ae771770SStanislav Sedov  * @param value the value to store
477*ae771770SStanislav Sedov  *
478*ae771770SStanislav Sedov  * @return 0 for success, or a Kerberos 5 error code on failure.
479*ae771770SStanislav Sedov  *
480*ae771770SStanislav Sedov  * @ingroup krb5_storage
481*ae771770SStanislav Sedov  */
482*ae771770SStanislav Sedov 
483*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_store_uint16(krb5_storage * sp,uint16_t value)484c19800e8SDoug Rabson krb5_store_uint16(krb5_storage *sp,
485c19800e8SDoug Rabson 		  uint16_t value)
486c19800e8SDoug Rabson {
487c19800e8SDoug Rabson     return krb5_store_int16(sp, (int16_t)value);
488c19800e8SDoug Rabson }
489c19800e8SDoug Rabson 
490*ae771770SStanislav Sedov /**
491*ae771770SStanislav Sedov  * Read a int16 from storage, byte order is controlled by the settings
492*ae771770SStanislav Sedov  * on the storage, see krb5_storage_set_byteorder().
493*ae771770SStanislav Sedov  *
494*ae771770SStanislav Sedov  * @param sp the storage to write too
495*ae771770SStanislav Sedov  * @param value the value read from the buffer
496*ae771770SStanislav Sedov  *
497*ae771770SStanislav Sedov  * @return 0 for success, or a Kerberos 5 error code on failure.
498*ae771770SStanislav Sedov  *
499*ae771770SStanislav Sedov  * @ingroup krb5_storage
500*ae771770SStanislav Sedov  */
501*ae771770SStanislav Sedov 
502*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_int16(krb5_storage * sp,int16_t * value)503b528cefcSMark Murray krb5_ret_int16(krb5_storage *sp,
504b528cefcSMark Murray 	       int16_t *value)
505b528cefcSMark Murray {
506b528cefcSMark Murray     int32_t v;
507b528cefcSMark Murray     int ret;
508b528cefcSMark Murray     ret = krb5_ret_int(sp, &v, 2);
509b528cefcSMark Murray     if(ret)
510b528cefcSMark Murray 	return ret;
511b528cefcSMark Murray     *value = v;
512adb0ddaeSAssar Westerlund     if(BYTEORDER_IS_HOST(sp))
513adb0ddaeSAssar Westerlund 	*value = htons(*value);
514adb0ddaeSAssar Westerlund     else if(BYTEORDER_IS_LE(sp))
515adb0ddaeSAssar Westerlund 	*value = bswap16(*value);
516b528cefcSMark Murray     return 0;
517b528cefcSMark Murray }
518b528cefcSMark Murray 
519*ae771770SStanislav Sedov /**
520*ae771770SStanislav Sedov  * Read a int16 from storage, byte order is controlled by the settings
521*ae771770SStanislav Sedov  * on the storage, see krb5_storage_set_byteorder().
522*ae771770SStanislav Sedov  *
523*ae771770SStanislav Sedov  * @param sp the storage to write too
524*ae771770SStanislav Sedov  * @param value the value read from the buffer
525*ae771770SStanislav Sedov  *
526*ae771770SStanislav Sedov  * @return 0 for success, or a Kerberos 5 error code on failure.
527*ae771770SStanislav Sedov  *
528*ae771770SStanislav Sedov  * @ingroup krb5_storage
529*ae771770SStanislav Sedov  */
530*ae771770SStanislav Sedov 
531*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_uint16(krb5_storage * sp,uint16_t * value)532c19800e8SDoug Rabson krb5_ret_uint16(krb5_storage *sp,
533c19800e8SDoug Rabson 		uint16_t *value)
534c19800e8SDoug Rabson {
535c19800e8SDoug Rabson     krb5_error_code ret;
536c19800e8SDoug Rabson     int16_t v;
537c19800e8SDoug Rabson 
538c19800e8SDoug Rabson     ret = krb5_ret_int16(sp, &v);
539c19800e8SDoug Rabson     if (ret == 0)
540c19800e8SDoug Rabson 	*value = (uint16_t)v;
541c19800e8SDoug Rabson 
542c19800e8SDoug Rabson     return ret;
543c19800e8SDoug Rabson }
544c19800e8SDoug Rabson 
545*ae771770SStanislav Sedov /**
546*ae771770SStanislav Sedov  * Store a int8 to storage.
547*ae771770SStanislav Sedov  *
548*ae771770SStanislav Sedov  * @param sp the storage to write too
549*ae771770SStanislav Sedov  * @param value the value to store
550*ae771770SStanislav Sedov  *
551*ae771770SStanislav Sedov  * @return 0 for success, or a Kerberos 5 error code on failure.
552*ae771770SStanislav Sedov  *
553*ae771770SStanislav Sedov  * @ingroup krb5_storage
554*ae771770SStanislav Sedov  */
555*ae771770SStanislav Sedov 
556*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_store_int8(krb5_storage * sp,int8_t value)557b528cefcSMark Murray krb5_store_int8(krb5_storage *sp,
558b528cefcSMark Murray 		int8_t value)
559b528cefcSMark Murray {
560b528cefcSMark Murray     int ret;
561b528cefcSMark Murray 
562b528cefcSMark Murray     ret = sp->store(sp, &value, sizeof(value));
563b528cefcSMark Murray     if (ret != sizeof(value))
5648373020dSJacques Vidrine 	return (ret<0)?errno:sp->eof_code;
565b528cefcSMark Murray     return 0;
566b528cefcSMark Murray }
567b528cefcSMark Murray 
568*ae771770SStanislav Sedov /**
569*ae771770SStanislav Sedov  * Store a uint8 to storage.
570*ae771770SStanislav Sedov  *
571*ae771770SStanislav Sedov  * @param sp the storage to write too
572*ae771770SStanislav Sedov  * @param value the value to store
573*ae771770SStanislav Sedov  *
574*ae771770SStanislav Sedov  * @return 0 for success, or a Kerberos 5 error code on failure.
575*ae771770SStanislav Sedov  *
576*ae771770SStanislav Sedov  * @ingroup krb5_storage
577*ae771770SStanislav Sedov  */
578*ae771770SStanislav Sedov 
579*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_store_uint8(krb5_storage * sp,uint8_t value)580c19800e8SDoug Rabson krb5_store_uint8(krb5_storage *sp,
581c19800e8SDoug Rabson 		 uint8_t value)
582c19800e8SDoug Rabson {
583c19800e8SDoug Rabson     return krb5_store_int8(sp, (int8_t)value);
584c19800e8SDoug Rabson }
585c19800e8SDoug Rabson 
586*ae771770SStanislav Sedov /**
587*ae771770SStanislav Sedov  * Read a int8 from storage
588*ae771770SStanislav Sedov  *
589*ae771770SStanislav Sedov  * @param sp the storage to write too
590*ae771770SStanislav Sedov  * @param value the value read from the buffer
591*ae771770SStanislav Sedov  *
592*ae771770SStanislav Sedov  * @return 0 for success, or a Kerberos 5 error code on failure.
593*ae771770SStanislav Sedov  *
594*ae771770SStanislav Sedov  * @ingroup krb5_storage
595*ae771770SStanislav Sedov  */
596*ae771770SStanislav Sedov 
597*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_int8(krb5_storage * sp,int8_t * value)598b528cefcSMark Murray krb5_ret_int8(krb5_storage *sp,
599b528cefcSMark Murray 	      int8_t *value)
600b528cefcSMark Murray {
601b528cefcSMark Murray     int ret;
602b528cefcSMark Murray 
603b528cefcSMark Murray     ret = sp->fetch(sp, value, sizeof(*value));
604b528cefcSMark Murray     if (ret != sizeof(*value))
6058373020dSJacques Vidrine 	return (ret<0)?errno:sp->eof_code;
606b528cefcSMark Murray     return 0;
607b528cefcSMark Murray }
608b528cefcSMark Murray 
609*ae771770SStanislav Sedov /**
610*ae771770SStanislav Sedov  * Read a uint8 from storage
611*ae771770SStanislav Sedov  *
612*ae771770SStanislav Sedov  * @param sp the storage to write too
613*ae771770SStanislav Sedov  * @param value the value read from the buffer
614*ae771770SStanislav Sedov  *
615*ae771770SStanislav Sedov  * @return 0 for success, or a Kerberos 5 error code on failure.
616*ae771770SStanislav Sedov  *
617*ae771770SStanislav Sedov  * @ingroup krb5_storage
618*ae771770SStanislav Sedov  */
619*ae771770SStanislav Sedov 
620*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_uint8(krb5_storage * sp,uint8_t * value)621c19800e8SDoug Rabson krb5_ret_uint8(krb5_storage *sp,
622c19800e8SDoug Rabson 	       uint8_t *value)
623c19800e8SDoug Rabson {
624c19800e8SDoug Rabson     krb5_error_code ret;
625c19800e8SDoug Rabson     int8_t v;
626c19800e8SDoug Rabson 
627c19800e8SDoug Rabson     ret = krb5_ret_int8(sp, &v);
628c19800e8SDoug Rabson     if (ret == 0)
629c19800e8SDoug Rabson 	*value = (uint8_t)v;
630c19800e8SDoug Rabson 
631c19800e8SDoug Rabson     return ret;
632c19800e8SDoug Rabson }
633c19800e8SDoug Rabson 
634*ae771770SStanislav Sedov /**
635*ae771770SStanislav Sedov  * Store a data to the storage. The data is stored with an int32 as
636*ae771770SStanislav Sedov  * lenght plus the data (not padded).
637*ae771770SStanislav Sedov  *
638*ae771770SStanislav Sedov  * @param sp the storage buffer to write to
639*ae771770SStanislav Sedov  * @param data the buffer to store.
640*ae771770SStanislav Sedov  *
641*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
642*ae771770SStanislav Sedov  *
643*ae771770SStanislav Sedov  * @ingroup krb5_storage
644*ae771770SStanislav Sedov  */
645*ae771770SStanislav Sedov 
646*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_store_data(krb5_storage * sp,krb5_data data)647b528cefcSMark Murray krb5_store_data(krb5_storage *sp,
648b528cefcSMark Murray 		krb5_data data)
649b528cefcSMark Murray {
650b528cefcSMark Murray     int ret;
651b528cefcSMark Murray     ret = krb5_store_int32(sp, data.length);
652b528cefcSMark Murray     if(ret < 0)
653b528cefcSMark Murray 	return ret;
654b528cefcSMark Murray     ret = sp->store(sp, data.data, data.length);
655b528cefcSMark Murray     if(ret < 0)
656b528cefcSMark Murray 	return errno;
657*ae771770SStanislav Sedov     if((size_t)ret != data.length)
6588373020dSJacques Vidrine 	return sp->eof_code;
659b528cefcSMark Murray     return 0;
660b528cefcSMark Murray }
661b528cefcSMark Murray 
662*ae771770SStanislav Sedov /**
663*ae771770SStanislav Sedov  * Parse a data from the storage.
664*ae771770SStanislav Sedov  *
665*ae771770SStanislav Sedov  * @param sp the storage buffer to read from
666*ae771770SStanislav Sedov  * @param data the parsed data
667*ae771770SStanislav Sedov  *
668*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
669*ae771770SStanislav Sedov  *
670*ae771770SStanislav Sedov  * @ingroup krb5_storage
671*ae771770SStanislav Sedov  */
672*ae771770SStanislav Sedov 
673*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_data(krb5_storage * sp,krb5_data * data)674b528cefcSMark Murray krb5_ret_data(krb5_storage *sp,
675b528cefcSMark Murray 	      krb5_data *data)
676b528cefcSMark Murray {
677b528cefcSMark Murray     int ret;
678b528cefcSMark Murray     int32_t size;
679b528cefcSMark Murray 
680b528cefcSMark Murray     ret = krb5_ret_int32(sp, &size);
681b528cefcSMark Murray     if(ret)
682b528cefcSMark Murray 	return ret;
683*ae771770SStanislav Sedov     ret = size_too_large(sp, size);
684*ae771770SStanislav Sedov     if (ret)
685*ae771770SStanislav Sedov 	return ret;
686b528cefcSMark Murray     ret = krb5_data_alloc (data, size);
687b528cefcSMark Murray     if (ret)
688b528cefcSMark Murray 	return ret;
689b528cefcSMark Murray     if (size) {
690b528cefcSMark Murray 	ret = sp->fetch(sp, data->data, size);
691b528cefcSMark Murray 	if(ret != size)
6928373020dSJacques Vidrine 	    return (ret < 0)? errno : sp->eof_code;
693b528cefcSMark Murray     }
694b528cefcSMark Murray     return 0;
695b528cefcSMark Murray }
696b528cefcSMark Murray 
697*ae771770SStanislav Sedov /**
698*ae771770SStanislav Sedov  * Store a string to the buffer. The data is formated as an len:uint32
699*ae771770SStanislav Sedov  * plus the string itself (not padded).
700*ae771770SStanislav Sedov  *
701*ae771770SStanislav Sedov  * @param sp the storage buffer to write to
702*ae771770SStanislav Sedov  * @param s the string to store.
703*ae771770SStanislav Sedov  *
704*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
705*ae771770SStanislav Sedov  *
706*ae771770SStanislav Sedov  * @ingroup krb5_storage
707*ae771770SStanislav Sedov  */
708*ae771770SStanislav Sedov 
709*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_store_string(krb5_storage * sp,const char * s)710b528cefcSMark Murray krb5_store_string(krb5_storage *sp, const char *s)
711b528cefcSMark Murray {
712b528cefcSMark Murray     krb5_data data;
713b528cefcSMark Murray     data.length = strlen(s);
714c19800e8SDoug Rabson     data.data = rk_UNCONST(s);
715b528cefcSMark Murray     return krb5_store_data(sp, data);
716b528cefcSMark Murray }
717b528cefcSMark Murray 
718*ae771770SStanislav Sedov /**
719*ae771770SStanislav Sedov  * Parse a string from the storage.
720*ae771770SStanislav Sedov  *
721*ae771770SStanislav Sedov  * @param sp the storage buffer to read from
722*ae771770SStanislav Sedov  * @param string the parsed string
723*ae771770SStanislav Sedov  *
724*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
725*ae771770SStanislav Sedov  *
726*ae771770SStanislav Sedov  * @ingroup krb5_storage
727*ae771770SStanislav Sedov  */
728*ae771770SStanislav Sedov 
729*ae771770SStanislav Sedov 
730*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_string(krb5_storage * sp,char ** string)731b528cefcSMark Murray krb5_ret_string(krb5_storage *sp,
732b528cefcSMark Murray 		char **string)
733b528cefcSMark Murray {
734b528cefcSMark Murray     int ret;
735b528cefcSMark Murray     krb5_data data;
736b528cefcSMark Murray     ret = krb5_ret_data(sp, &data);
737b528cefcSMark Murray     if(ret)
738b528cefcSMark Murray 	return ret;
739b528cefcSMark Murray     *string = realloc(data.data, data.length + 1);
740b528cefcSMark Murray     if(*string == NULL){
741b528cefcSMark Murray 	free(data.data);
742b528cefcSMark Murray 	return ENOMEM;
743b528cefcSMark Murray     }
744b528cefcSMark Murray     (*string)[data.length] = 0;
745b528cefcSMark Murray     return 0;
746b528cefcSMark Murray }
747b528cefcSMark Murray 
748*ae771770SStanislav Sedov /**
749*ae771770SStanislav Sedov  * Store a zero terminated string to the buffer. The data is stored
750*ae771770SStanislav Sedov  * one character at a time until a NUL is stored.
751*ae771770SStanislav Sedov  *
752*ae771770SStanislav Sedov  * @param sp the storage buffer to write to
753*ae771770SStanislav Sedov  * @param s the string to store.
754*ae771770SStanislav Sedov  *
755*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
756*ae771770SStanislav Sedov  *
757*ae771770SStanislav Sedov  * @ingroup krb5_storage
758*ae771770SStanislav Sedov  */
759*ae771770SStanislav Sedov 
760*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_store_stringz(krb5_storage * sp,const char * s)7615e9cd1aeSAssar Westerlund krb5_store_stringz(krb5_storage *sp, const char *s)
762b528cefcSMark Murray {
763b528cefcSMark Murray     size_t len = strlen(s) + 1;
764b528cefcSMark Murray     ssize_t ret;
765b528cefcSMark Murray 
766b528cefcSMark Murray     ret = sp->store(sp, s, len);
767b528cefcSMark Murray     if(ret < 0)
768b528cefcSMark Murray 	return ret;
769*ae771770SStanislav Sedov     if((size_t)ret != len)
7708373020dSJacques Vidrine 	return sp->eof_code;
771b528cefcSMark Murray     return 0;
772b528cefcSMark Murray }
773b528cefcSMark Murray 
774*ae771770SStanislav Sedov /**
775*ae771770SStanislav Sedov  * Parse zero terminated string from the storage.
776*ae771770SStanislav Sedov  *
777*ae771770SStanislav Sedov  * @param sp the storage buffer to read from
778*ae771770SStanislav Sedov  * @param string the parsed string
779*ae771770SStanislav Sedov  *
780*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
781*ae771770SStanislav Sedov  *
782*ae771770SStanislav Sedov  * @ingroup krb5_storage
783*ae771770SStanislav Sedov  */
784*ae771770SStanislav Sedov 
785*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_stringz(krb5_storage * sp,char ** string)786b528cefcSMark Murray krb5_ret_stringz(krb5_storage *sp,
787b528cefcSMark Murray 		char **string)
788b528cefcSMark Murray {
789b528cefcSMark Murray     char c;
790b528cefcSMark Murray     char *s = NULL;
791b528cefcSMark Murray     size_t len = 0;
792b528cefcSMark Murray     ssize_t ret;
793b528cefcSMark Murray 
794b528cefcSMark Murray     while((ret = sp->fetch(sp, &c, 1)) == 1){
795b528cefcSMark Murray 	char *tmp;
796b528cefcSMark Murray 
797b528cefcSMark Murray 	len++;
798*ae771770SStanislav Sedov 	ret = size_too_large(sp, len);
799*ae771770SStanislav Sedov 	if (ret)
800*ae771770SStanislav Sedov 	    break;
801b528cefcSMark Murray 	tmp = realloc (s, len);
802b528cefcSMark Murray 	if (tmp == NULL) {
803b528cefcSMark Murray 	    free (s);
804b528cefcSMark Murray 	    return ENOMEM;
805b528cefcSMark Murray 	}
806b528cefcSMark Murray 	s = tmp;
807b528cefcSMark Murray 	s[len - 1] = c;
808b528cefcSMark Murray 	if(c == 0)
809b528cefcSMark Murray 	    break;
810b528cefcSMark Murray     }
811b528cefcSMark Murray     if(ret != 1){
812b528cefcSMark Murray 	free(s);
813b528cefcSMark Murray 	if(ret == 0)
8148373020dSJacques Vidrine 	    return sp->eof_code;
815b528cefcSMark Murray 	return ret;
816b528cefcSMark Murray     }
817b528cefcSMark Murray     *string = s;
818b528cefcSMark Murray     return 0;
819b528cefcSMark Murray }
820b528cefcSMark Murray 
821*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_store_stringnl(krb5_storage * sp,const char * s)822c19800e8SDoug Rabson krb5_store_stringnl(krb5_storage *sp, const char *s)
823c19800e8SDoug Rabson {
824c19800e8SDoug Rabson     size_t len = strlen(s);
825c19800e8SDoug Rabson     ssize_t ret;
826b528cefcSMark Murray 
827c19800e8SDoug Rabson     ret = sp->store(sp, s, len);
828c19800e8SDoug Rabson     if(ret < 0)
829c19800e8SDoug Rabson 	return ret;
830*ae771770SStanislav Sedov     if((size_t)ret != len)
831c19800e8SDoug Rabson 	return sp->eof_code;
832c19800e8SDoug Rabson     ret = sp->store(sp, "\n", 1);
833c19800e8SDoug Rabson     if(ret != 1) {
834c19800e8SDoug Rabson 	if(ret < 0)
835c19800e8SDoug Rabson 	    return ret;
836c19800e8SDoug Rabson 	else
837c19800e8SDoug Rabson 	    return sp->eof_code;
838c19800e8SDoug Rabson     }
839c19800e8SDoug Rabson 
840c19800e8SDoug Rabson     return 0;
841c19800e8SDoug Rabson 
842c19800e8SDoug Rabson }
843c19800e8SDoug Rabson 
844*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_stringnl(krb5_storage * sp,char ** string)845c19800e8SDoug Rabson krb5_ret_stringnl(krb5_storage *sp,
846c19800e8SDoug Rabson 		  char **string)
847c19800e8SDoug Rabson {
848c19800e8SDoug Rabson     int expect_nl = 0;
849c19800e8SDoug Rabson     char c;
850c19800e8SDoug Rabson     char *s = NULL;
851c19800e8SDoug Rabson     size_t len = 0;
852c19800e8SDoug Rabson     ssize_t ret;
853c19800e8SDoug Rabson 
854c19800e8SDoug Rabson     while((ret = sp->fetch(sp, &c, 1)) == 1){
855c19800e8SDoug Rabson 	char *tmp;
856c19800e8SDoug Rabson 
857c19800e8SDoug Rabson 	if (c == '\r') {
858c19800e8SDoug Rabson 	    expect_nl = 1;
859c19800e8SDoug Rabson 	    continue;
860c19800e8SDoug Rabson 	}
861c19800e8SDoug Rabson 	if (expect_nl && c != '\n') {
862c19800e8SDoug Rabson 	    free(s);
863c19800e8SDoug Rabson 	    return KRB5_BADMSGTYPE;
864c19800e8SDoug Rabson 	}
865c19800e8SDoug Rabson 
866c19800e8SDoug Rabson 	len++;
867*ae771770SStanislav Sedov 	ret = size_too_large(sp, len);
868*ae771770SStanislav Sedov 	if (ret)
869*ae771770SStanislav Sedov 	    break;
870c19800e8SDoug Rabson 	tmp = realloc (s, len);
871c19800e8SDoug Rabson 	if (tmp == NULL) {
872c19800e8SDoug Rabson 	    free (s);
873c19800e8SDoug Rabson 	    return ENOMEM;
874c19800e8SDoug Rabson 	}
875c19800e8SDoug Rabson 	s = tmp;
876c19800e8SDoug Rabson 	if(c == '\n') {
877c19800e8SDoug Rabson 	    s[len - 1] = '\0';
878c19800e8SDoug Rabson 	    break;
879c19800e8SDoug Rabson 	}
880c19800e8SDoug Rabson 	s[len - 1] = c;
881c19800e8SDoug Rabson     }
882c19800e8SDoug Rabson     if(ret != 1){
883c19800e8SDoug Rabson 	free(s);
884c19800e8SDoug Rabson 	if(ret == 0)
885c19800e8SDoug Rabson 	    return sp->eof_code;
886c19800e8SDoug Rabson 	return ret;
887c19800e8SDoug Rabson     }
888c19800e8SDoug Rabson     *string = s;
889c19800e8SDoug Rabson     return 0;
890c19800e8SDoug Rabson }
891c19800e8SDoug Rabson 
892*ae771770SStanislav Sedov /**
893*ae771770SStanislav Sedov  * Write a principal block to storage.
894*ae771770SStanislav Sedov  *
895*ae771770SStanislav Sedov  * @param sp the storage buffer to write to
896*ae771770SStanislav Sedov  * @param p the principal block to write.
897*ae771770SStanislav Sedov  *
898*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
899*ae771770SStanislav Sedov  *
900*ae771770SStanislav Sedov  * @ingroup krb5_storage
901*ae771770SStanislav Sedov  */
902c19800e8SDoug Rabson 
903*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_store_principal(krb5_storage * sp,krb5_const_principal p)904b528cefcSMark Murray krb5_store_principal(krb5_storage *sp,
905c19800e8SDoug Rabson 		     krb5_const_principal p)
906b528cefcSMark Murray {
907*ae771770SStanislav Sedov     size_t i;
908b528cefcSMark Murray     int ret;
909b528cefcSMark Murray 
910b528cefcSMark Murray     if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) {
911b528cefcSMark Murray 	ret = krb5_store_int32(sp, p->name.name_type);
912b528cefcSMark Murray 	if(ret) return ret;
913b528cefcSMark Murray     }
914b528cefcSMark Murray     if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
915b528cefcSMark Murray 	ret = krb5_store_int32(sp, p->name.name_string.len + 1);
916b528cefcSMark Murray     else
917b528cefcSMark Murray 	ret = krb5_store_int32(sp, p->name.name_string.len);
918b528cefcSMark Murray 
919b528cefcSMark Murray     if(ret) return ret;
920b528cefcSMark Murray     ret = krb5_store_string(sp, p->realm);
921b528cefcSMark Murray     if(ret) return ret;
922b528cefcSMark Murray     for(i = 0; i < p->name.name_string.len; i++){
923b528cefcSMark Murray 	ret = krb5_store_string(sp, p->name.name_string.val[i]);
924b528cefcSMark Murray 	if(ret) return ret;
925b528cefcSMark Murray     }
926b528cefcSMark Murray     return 0;
927b528cefcSMark Murray }
928b528cefcSMark Murray 
929*ae771770SStanislav Sedov /**
930*ae771770SStanislav Sedov  * Parse principal from the storage.
931*ae771770SStanislav Sedov  *
932*ae771770SStanislav Sedov  * @param sp the storage buffer to read from
933*ae771770SStanislav Sedov  * @param princ the parsed principal
934*ae771770SStanislav Sedov  *
935*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
936*ae771770SStanislav Sedov  *
937*ae771770SStanislav Sedov  * @ingroup krb5_storage
938*ae771770SStanislav Sedov  */
939*ae771770SStanislav Sedov 
940*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_principal(krb5_storage * sp,krb5_principal * princ)941b528cefcSMark Murray krb5_ret_principal(krb5_storage *sp,
942b528cefcSMark Murray 		   krb5_principal *princ)
943b528cefcSMark Murray {
944b528cefcSMark Murray     int i;
945b528cefcSMark Murray     int ret;
946b528cefcSMark Murray     krb5_principal p;
947b528cefcSMark Murray     int32_t type;
948b528cefcSMark Murray     int32_t ncomp;
949b528cefcSMark Murray 
950b528cefcSMark Murray     p = calloc(1, sizeof(*p));
951b528cefcSMark Murray     if(p == NULL)
952b528cefcSMark Murray 	return ENOMEM;
953b528cefcSMark Murray 
954b528cefcSMark Murray     if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE))
955b528cefcSMark Murray 	type = KRB5_NT_UNKNOWN;
956b528cefcSMark Murray     else if((ret = krb5_ret_int32(sp, &type))){
957b528cefcSMark Murray 	free(p);
958b528cefcSMark Murray 	return ret;
959b528cefcSMark Murray     }
960b528cefcSMark Murray     if((ret = krb5_ret_int32(sp, &ncomp))){
961b528cefcSMark Murray 	free(p);
962b528cefcSMark Murray 	return ret;
963b528cefcSMark Murray     }
964b528cefcSMark Murray     if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
965b528cefcSMark Murray 	ncomp--;
966c19800e8SDoug Rabson     if (ncomp < 0) {
967c19800e8SDoug Rabson 	free(p);
968c19800e8SDoug Rabson 	return EINVAL;
969c19800e8SDoug Rabson     }
970*ae771770SStanislav Sedov     ret = size_too_large_num(sp, ncomp, sizeof(p->name.name_string.val[0]));
971*ae771770SStanislav Sedov     if (ret) {
972*ae771770SStanislav Sedov 	free(p);
973*ae771770SStanislav Sedov 	return ret;
974*ae771770SStanislav Sedov     }
975b528cefcSMark Murray     p->name.name_type = type;
976b528cefcSMark Murray     p->name.name_string.len = ncomp;
977b528cefcSMark Murray     ret = krb5_ret_string(sp, &p->realm);
978c19800e8SDoug Rabson     if(ret) {
979c19800e8SDoug Rabson 	free(p);
980c19800e8SDoug Rabson 	return ret;
981c19800e8SDoug Rabson     }
982*ae771770SStanislav Sedov     p->name.name_string.val = calloc(ncomp, sizeof(p->name.name_string.val[0]));
983c19800e8SDoug Rabson     if(p->name.name_string.val == NULL && ncomp != 0){
984b528cefcSMark Murray 	free(p->realm);
985c19800e8SDoug Rabson 	free(p);
986b528cefcSMark Murray 	return ENOMEM;
987b528cefcSMark Murray     }
988b528cefcSMark Murray     for(i = 0; i < ncomp; i++){
989b528cefcSMark Murray 	ret = krb5_ret_string(sp, &p->name.name_string.val[i]);
990c19800e8SDoug Rabson 	if(ret) {
991c19800e8SDoug Rabson 	    while (i >= 0)
992c19800e8SDoug Rabson 		free(p->name.name_string.val[i--]);
993c19800e8SDoug Rabson 	    free(p->realm);
994c19800e8SDoug Rabson 	    free(p);
995c19800e8SDoug Rabson 	    return ret;
996c19800e8SDoug Rabson 	}
997b528cefcSMark Murray     }
998b528cefcSMark Murray     *princ = p;
999b528cefcSMark Murray     return 0;
1000b528cefcSMark Murray }
1001b528cefcSMark Murray 
1002*ae771770SStanislav Sedov /**
1003*ae771770SStanislav Sedov  * Store a keyblock to the storage.
1004*ae771770SStanislav Sedov  *
1005*ae771770SStanislav Sedov  * @param sp the storage buffer to write to
1006*ae771770SStanislav Sedov  * @param p the keyblock to write
1007*ae771770SStanislav Sedov  *
1008*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
1009*ae771770SStanislav Sedov  *
1010*ae771770SStanislav Sedov  * @ingroup krb5_storage
1011*ae771770SStanislav Sedov  */
1012*ae771770SStanislav Sedov 
1013*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_store_keyblock(krb5_storage * sp,krb5_keyblock p)1014b528cefcSMark Murray krb5_store_keyblock(krb5_storage *sp, krb5_keyblock p)
1015b528cefcSMark Murray {
1016b528cefcSMark Murray     int ret;
1017b528cefcSMark Murray     ret = krb5_store_int16(sp, p.keytype);
1018b528cefcSMark Murray     if(ret) return ret;
1019b528cefcSMark Murray 
1020b528cefcSMark Murray     if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
1021b528cefcSMark Murray 	/* this should really be enctype, but it is the same as
1022b528cefcSMark Murray            keytype nowadays */
1023b528cefcSMark Murray     ret = krb5_store_int16(sp, p.keytype);
1024b528cefcSMark Murray     if(ret) return ret;
1025b528cefcSMark Murray     }
1026b528cefcSMark Murray 
1027b528cefcSMark Murray     ret = krb5_store_data(sp, p.keyvalue);
1028b528cefcSMark Murray     return ret;
1029b528cefcSMark Murray }
1030b528cefcSMark Murray 
1031*ae771770SStanislav Sedov /**
1032*ae771770SStanislav Sedov  * Read a keyblock from the storage.
1033*ae771770SStanislav Sedov  *
1034*ae771770SStanislav Sedov  * @param sp the storage buffer to write to
1035*ae771770SStanislav Sedov  * @param p the keyblock read from storage, free using krb5_free_keyblock()
1036*ae771770SStanislav Sedov  *
1037*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
1038*ae771770SStanislav Sedov  *
1039*ae771770SStanislav Sedov  * @ingroup krb5_storage
1040*ae771770SStanislav Sedov  */
1041*ae771770SStanislav Sedov 
1042*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_keyblock(krb5_storage * sp,krb5_keyblock * p)1043b528cefcSMark Murray krb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p)
1044b528cefcSMark Murray {
1045b528cefcSMark Murray     int ret;
1046b528cefcSMark Murray     int16_t tmp;
1047b528cefcSMark Murray 
1048b528cefcSMark Murray     ret = krb5_ret_int16(sp, &tmp);
1049b528cefcSMark Murray     if(ret) return ret;
1050b528cefcSMark Murray     p->keytype = tmp;
1051b528cefcSMark Murray 
1052b528cefcSMark Murray     if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
1053b528cefcSMark Murray     ret = krb5_ret_int16(sp, &tmp);
1054b528cefcSMark Murray     if(ret) return ret;
1055b528cefcSMark Murray     }
1056b528cefcSMark Murray 
1057b528cefcSMark Murray     ret = krb5_ret_data(sp, &p->keyvalue);
1058b528cefcSMark Murray     return ret;
1059b528cefcSMark Murray }
1060b528cefcSMark Murray 
1061*ae771770SStanislav Sedov /**
1062*ae771770SStanislav Sedov  * Write a times block to storage.
1063*ae771770SStanislav Sedov  *
1064*ae771770SStanislav Sedov  * @param sp the storage buffer to write to
1065*ae771770SStanislav Sedov  * @param times the times block to write.
1066*ae771770SStanislav Sedov  *
1067*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
1068*ae771770SStanislav Sedov  *
1069*ae771770SStanislav Sedov  * @ingroup krb5_storage
1070*ae771770SStanislav Sedov  */
1071*ae771770SStanislav Sedov 
1072*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_store_times(krb5_storage * sp,krb5_times times)1073b528cefcSMark Murray krb5_store_times(krb5_storage *sp, krb5_times times)
1074b528cefcSMark Murray {
1075b528cefcSMark Murray     int ret;
1076b528cefcSMark Murray     ret = krb5_store_int32(sp, times.authtime);
1077b528cefcSMark Murray     if(ret) return ret;
1078b528cefcSMark Murray     ret = krb5_store_int32(sp, times.starttime);
1079b528cefcSMark Murray     if(ret) return ret;
1080b528cefcSMark Murray     ret = krb5_store_int32(sp, times.endtime);
1081b528cefcSMark Murray     if(ret) return ret;
1082b528cefcSMark Murray     ret = krb5_store_int32(sp, times.renew_till);
1083b528cefcSMark Murray     return ret;
1084b528cefcSMark Murray }
1085b528cefcSMark Murray 
1086*ae771770SStanislav Sedov /**
1087*ae771770SStanislav Sedov  * Read a times block from the storage.
1088*ae771770SStanislav Sedov  *
1089*ae771770SStanislav Sedov  * @param sp the storage buffer to write to
1090*ae771770SStanislav Sedov  * @param times the times block read from storage
1091*ae771770SStanislav Sedov  *
1092*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
1093*ae771770SStanislav Sedov  *
1094*ae771770SStanislav Sedov  * @ingroup krb5_storage
1095*ae771770SStanislav Sedov  */
1096*ae771770SStanislav Sedov 
1097*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_times(krb5_storage * sp,krb5_times * times)1098b528cefcSMark Murray krb5_ret_times(krb5_storage *sp, krb5_times *times)
1099b528cefcSMark Murray {
1100b528cefcSMark Murray     int ret;
1101b528cefcSMark Murray     int32_t tmp;
1102b528cefcSMark Murray     ret = krb5_ret_int32(sp, &tmp);
1103b528cefcSMark Murray     times->authtime = tmp;
1104b528cefcSMark Murray     if(ret) return ret;
1105b528cefcSMark Murray     ret = krb5_ret_int32(sp, &tmp);
1106b528cefcSMark Murray     times->starttime = tmp;
1107b528cefcSMark Murray     if(ret) return ret;
1108b528cefcSMark Murray     ret = krb5_ret_int32(sp, &tmp);
1109b528cefcSMark Murray     times->endtime = tmp;
1110b528cefcSMark Murray     if(ret) return ret;
1111b528cefcSMark Murray     ret = krb5_ret_int32(sp, &tmp);
1112b528cefcSMark Murray     times->renew_till = tmp;
1113b528cefcSMark Murray     return ret;
1114b528cefcSMark Murray }
1115b528cefcSMark Murray 
1116*ae771770SStanislav Sedov /**
1117*ae771770SStanislav Sedov  * Write a address block to storage.
1118*ae771770SStanislav Sedov  *
1119*ae771770SStanislav Sedov  * @param sp the storage buffer to write to
1120*ae771770SStanislav Sedov  * @param p the address block to write.
1121*ae771770SStanislav Sedov  *
1122*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
1123*ae771770SStanislav Sedov  *
1124*ae771770SStanislav Sedov  * @ingroup krb5_storage
1125*ae771770SStanislav Sedov  */
1126*ae771770SStanislav Sedov 
1127*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_store_address(krb5_storage * sp,krb5_address p)1128b528cefcSMark Murray krb5_store_address(krb5_storage *sp, krb5_address p)
1129b528cefcSMark Murray {
1130b528cefcSMark Murray     int ret;
1131b528cefcSMark Murray     ret = krb5_store_int16(sp, p.addr_type);
1132b528cefcSMark Murray     if(ret) return ret;
1133b528cefcSMark Murray     ret = krb5_store_data(sp, p.address);
1134b528cefcSMark Murray     return ret;
1135b528cefcSMark Murray }
1136b528cefcSMark Murray 
1137*ae771770SStanislav Sedov /**
1138*ae771770SStanislav Sedov  * Read a address block from the storage.
1139*ae771770SStanislav Sedov  *
1140*ae771770SStanislav Sedov  * @param sp the storage buffer to write to
1141*ae771770SStanislav Sedov  * @param adr the address block read from storage
1142*ae771770SStanislav Sedov  *
1143*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
1144*ae771770SStanislav Sedov  *
1145*ae771770SStanislav Sedov  * @ingroup krb5_storage
1146*ae771770SStanislav Sedov  */
1147*ae771770SStanislav Sedov 
1148*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_address(krb5_storage * sp,krb5_address * adr)1149b528cefcSMark Murray krb5_ret_address(krb5_storage *sp, krb5_address *adr)
1150b528cefcSMark Murray {
1151b528cefcSMark Murray     int16_t t;
1152b528cefcSMark Murray     int ret;
1153b528cefcSMark Murray     ret = krb5_ret_int16(sp, &t);
1154b528cefcSMark Murray     if(ret) return ret;
1155b528cefcSMark Murray     adr->addr_type = t;
1156b528cefcSMark Murray     ret = krb5_ret_data(sp, &adr->address);
1157b528cefcSMark Murray     return ret;
1158b528cefcSMark Murray }
1159b528cefcSMark Murray 
1160*ae771770SStanislav Sedov /**
1161*ae771770SStanislav Sedov  * Write a addresses block to storage.
1162*ae771770SStanislav Sedov  *
1163*ae771770SStanislav Sedov  * @param sp the storage buffer to write to
1164*ae771770SStanislav Sedov  * @param p the addresses block to write.
1165*ae771770SStanislav Sedov  *
1166*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
1167*ae771770SStanislav Sedov  *
1168*ae771770SStanislav Sedov  * @ingroup krb5_storage
1169*ae771770SStanislav Sedov  */
1170*ae771770SStanislav Sedov 
1171*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_store_addrs(krb5_storage * sp,krb5_addresses p)1172b528cefcSMark Murray krb5_store_addrs(krb5_storage *sp, krb5_addresses p)
1173b528cefcSMark Murray {
1174*ae771770SStanislav Sedov     size_t i;
1175b528cefcSMark Murray     int ret;
1176b528cefcSMark Murray     ret = krb5_store_int32(sp, p.len);
1177b528cefcSMark Murray     if(ret) return ret;
1178b528cefcSMark Murray     for(i = 0; i<p.len; i++){
1179b528cefcSMark Murray 	ret = krb5_store_address(sp, p.val[i]);
1180b528cefcSMark Murray 	if(ret) break;
1181b528cefcSMark Murray     }
1182b528cefcSMark Murray     return ret;
1183b528cefcSMark Murray }
1184b528cefcSMark Murray 
1185*ae771770SStanislav Sedov /**
1186*ae771770SStanislav Sedov  * Read a addresses block from the storage.
1187*ae771770SStanislav Sedov  *
1188*ae771770SStanislav Sedov  * @param sp the storage buffer to write to
1189*ae771770SStanislav Sedov  * @param adr the addresses block read from storage
1190*ae771770SStanislav Sedov  *
1191*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
1192*ae771770SStanislav Sedov  *
1193*ae771770SStanislav Sedov  * @ingroup krb5_storage
1194*ae771770SStanislav Sedov  */
1195*ae771770SStanislav Sedov 
1196*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_addrs(krb5_storage * sp,krb5_addresses * adr)1197b528cefcSMark Murray krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr)
1198b528cefcSMark Murray {
1199*ae771770SStanislav Sedov     size_t i;
1200b528cefcSMark Murray     int ret;
1201b528cefcSMark Murray     int32_t tmp;
1202b528cefcSMark Murray 
1203b528cefcSMark Murray     ret = krb5_ret_int32(sp, &tmp);
1204b528cefcSMark Murray     if(ret) return ret;
1205*ae771770SStanislav Sedov     ret = size_too_large_num(sp, tmp, sizeof(adr->val[0]));
1206*ae771770SStanislav Sedov     if (ret) return ret;
1207b528cefcSMark Murray     adr->len = tmp;
1208b528cefcSMark Murray     ALLOC(adr->val, adr->len);
1209c19800e8SDoug Rabson     if (adr->val == NULL && adr->len != 0)
1210c19800e8SDoug Rabson 	return ENOMEM;
1211b528cefcSMark Murray     for(i = 0; i < adr->len; i++){
1212b528cefcSMark Murray 	ret = krb5_ret_address(sp, &adr->val[i]);
1213b528cefcSMark Murray 	if(ret) break;
1214b528cefcSMark Murray     }
1215b528cefcSMark Murray     return ret;
1216b528cefcSMark Murray }
1217b528cefcSMark Murray 
1218*ae771770SStanislav Sedov /**
1219*ae771770SStanislav Sedov  * Write a auth data block to storage.
1220*ae771770SStanislav Sedov  *
1221*ae771770SStanislav Sedov  * @param sp the storage buffer to write to
1222*ae771770SStanislav Sedov  * @param auth the auth data block to write.
1223*ae771770SStanislav Sedov  *
1224*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
1225*ae771770SStanislav Sedov  *
1226*ae771770SStanislav Sedov  * @ingroup krb5_storage
1227*ae771770SStanislav Sedov  */
1228*ae771770SStanislav Sedov 
1229*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_store_authdata(krb5_storage * sp,krb5_authdata auth)1230b528cefcSMark Murray krb5_store_authdata(krb5_storage *sp, krb5_authdata auth)
1231b528cefcSMark Murray {
1232b528cefcSMark Murray     krb5_error_code ret;
1233*ae771770SStanislav Sedov     size_t i;
1234b528cefcSMark Murray     ret = krb5_store_int32(sp, auth.len);
1235b528cefcSMark Murray     if(ret) return ret;
1236b528cefcSMark Murray     for(i = 0; i < auth.len; i++){
1237b528cefcSMark Murray 	ret = krb5_store_int16(sp, auth.val[i].ad_type);
1238b528cefcSMark Murray 	if(ret) break;
1239b528cefcSMark Murray 	ret = krb5_store_data(sp, auth.val[i].ad_data);
1240b528cefcSMark Murray 	if(ret) break;
1241b528cefcSMark Murray     }
1242b528cefcSMark Murray     return 0;
1243b528cefcSMark Murray }
1244b528cefcSMark Murray 
1245*ae771770SStanislav Sedov /**
1246*ae771770SStanislav Sedov  * Read a auth data from the storage.
1247*ae771770SStanislav Sedov  *
1248*ae771770SStanislav Sedov  * @param sp the storage buffer to write to
1249*ae771770SStanislav Sedov  * @param auth the auth data block read from storage
1250*ae771770SStanislav Sedov  *
1251*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
1252*ae771770SStanislav Sedov  *
1253*ae771770SStanislav Sedov  * @ingroup krb5_storage
1254*ae771770SStanislav Sedov  */
1255*ae771770SStanislav Sedov 
1256*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_authdata(krb5_storage * sp,krb5_authdata * auth)1257b528cefcSMark Murray krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth)
1258b528cefcSMark Murray {
1259b528cefcSMark Murray     krb5_error_code ret;
1260b528cefcSMark Murray     int32_t tmp;
1261b528cefcSMark Murray     int16_t tmp2;
1262b528cefcSMark Murray     int i;
1263b528cefcSMark Murray     ret = krb5_ret_int32(sp, &tmp);
1264b528cefcSMark Murray     if(ret) return ret;
1265*ae771770SStanislav Sedov     ret = size_too_large_num(sp, tmp, sizeof(auth->val[0]));
1266*ae771770SStanislav Sedov     if (ret) return ret;
1267b528cefcSMark Murray     ALLOC_SEQ(auth, tmp);
1268c19800e8SDoug Rabson     if (auth->val == NULL && tmp != 0)
1269c19800e8SDoug Rabson 	return ENOMEM;
1270b528cefcSMark Murray     for(i = 0; i < tmp; i++){
1271b528cefcSMark Murray 	ret = krb5_ret_int16(sp, &tmp2);
1272b528cefcSMark Murray 	if(ret) break;
1273b528cefcSMark Murray 	auth->val[i].ad_type = tmp2;
1274b528cefcSMark Murray 	ret = krb5_ret_data(sp, &auth->val[i].ad_data);
1275b528cefcSMark Murray 	if(ret) break;
1276b528cefcSMark Murray     }
1277b528cefcSMark Murray     return ret;
1278b528cefcSMark Murray }
1279b528cefcSMark Murray 
12801c43270aSJacques Vidrine static int32_t
bitswap32(int32_t b)12811c43270aSJacques Vidrine bitswap32(int32_t b)
12821c43270aSJacques Vidrine {
12831c43270aSJacques Vidrine     int32_t r = 0;
12841c43270aSJacques Vidrine     int i;
12851c43270aSJacques Vidrine     for (i = 0; i < 32; i++) {
12861c43270aSJacques Vidrine 	r = r << 1 | (b & 1);
12871c43270aSJacques Vidrine 	b = b >> 1;
12881c43270aSJacques Vidrine     }
12891c43270aSJacques Vidrine     return r;
12901c43270aSJacques Vidrine }
12911c43270aSJacques Vidrine 
1292*ae771770SStanislav Sedov /**
1293*ae771770SStanislav Sedov  * Write a credentials block to storage.
12941c43270aSJacques Vidrine  *
1295*ae771770SStanislav Sedov  * @param sp the storage buffer to write to
1296*ae771770SStanislav Sedov  * @param creds the creds block to write.
1297*ae771770SStanislav Sedov  *
1298*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
1299*ae771770SStanislav Sedov  *
1300*ae771770SStanislav Sedov  * @ingroup krb5_storage
13015e9cd1aeSAssar Westerlund  */
13025e9cd1aeSAssar Westerlund 
1303*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_store_creds(krb5_storage * sp,krb5_creds * creds)1304c19800e8SDoug Rabson krb5_store_creds(krb5_storage *sp, krb5_creds *creds)
1305b528cefcSMark Murray {
13065e9cd1aeSAssar Westerlund     int ret;
13075e9cd1aeSAssar Westerlund 
13085e9cd1aeSAssar Westerlund     ret = krb5_store_principal(sp, creds->client);
13095e9cd1aeSAssar Westerlund     if(ret)
13105e9cd1aeSAssar Westerlund 	return ret;
13115e9cd1aeSAssar Westerlund     ret = krb5_store_principal(sp, creds->server);
13125e9cd1aeSAssar Westerlund     if(ret)
13135e9cd1aeSAssar Westerlund 	return ret;
13145e9cd1aeSAssar Westerlund     ret = krb5_store_keyblock(sp, creds->session);
13155e9cd1aeSAssar Westerlund     if(ret)
13165e9cd1aeSAssar Westerlund 	return ret;
13175e9cd1aeSAssar Westerlund     ret = krb5_store_times(sp, creds->times);
13185e9cd1aeSAssar Westerlund     if(ret)
13195e9cd1aeSAssar Westerlund 	return ret;
1320c19800e8SDoug Rabson     ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
13215e9cd1aeSAssar Westerlund     if(ret)
13225e9cd1aeSAssar Westerlund 	return ret;
1323c19800e8SDoug Rabson 
1324c19800e8SDoug Rabson     if(krb5_storage_is_flags(sp, KRB5_STORAGE_CREDS_FLAGS_WRONG_BITORDER))
13255e9cd1aeSAssar Westerlund 	ret = krb5_store_int32(sp, creds->flags.i);
1326c19800e8SDoug Rabson     else
13271c43270aSJacques Vidrine 	ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
13281c43270aSJacques Vidrine     if(ret)
13291c43270aSJacques Vidrine 	return ret;
1330c19800e8SDoug Rabson 
13315e9cd1aeSAssar Westerlund     ret = krb5_store_addrs(sp, creds->addresses);
13325e9cd1aeSAssar Westerlund     if(ret)
13335e9cd1aeSAssar Westerlund 	return ret;
13345e9cd1aeSAssar Westerlund     ret = krb5_store_authdata(sp, creds->authdata);
13355e9cd1aeSAssar Westerlund     if(ret)
13365e9cd1aeSAssar Westerlund 	return ret;
13375e9cd1aeSAssar Westerlund     ret = krb5_store_data(sp, creds->ticket);
13385e9cd1aeSAssar Westerlund     if(ret)
13395e9cd1aeSAssar Westerlund 	return ret;
13405e9cd1aeSAssar Westerlund     ret = krb5_store_data(sp, creds->second_ticket);
13415e9cd1aeSAssar Westerlund     return ret;
1342b528cefcSMark Murray }
1343b528cefcSMark Murray 
1344*ae771770SStanislav Sedov /**
1345*ae771770SStanislav Sedov  * Read a credentials block from the storage.
1346*ae771770SStanislav Sedov  *
1347*ae771770SStanislav Sedov  * @param sp the storage buffer to write to
1348*ae771770SStanislav Sedov  * @param creds the credentials block read from storage
1349*ae771770SStanislav Sedov  *
1350*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
1351*ae771770SStanislav Sedov  *
1352*ae771770SStanislav Sedov  * @ingroup krb5_storage
1353*ae771770SStanislav Sedov  */
1354*ae771770SStanislav Sedov 
1355*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_creds(krb5_storage * sp,krb5_creds * creds)1356b528cefcSMark Murray krb5_ret_creds(krb5_storage *sp, krb5_creds *creds)
1357b528cefcSMark Murray {
1358b528cefcSMark Murray     krb5_error_code ret;
1359b528cefcSMark Murray     int8_t dummy8;
1360b528cefcSMark Murray     int32_t dummy32;
1361b528cefcSMark Murray 
1362b528cefcSMark Murray     memset(creds, 0, sizeof(*creds));
1363b528cefcSMark Murray     ret = krb5_ret_principal (sp,  &creds->client);
1364b528cefcSMark Murray     if(ret) goto cleanup;
1365b528cefcSMark Murray     ret = krb5_ret_principal (sp,  &creds->server);
1366b528cefcSMark Murray     if(ret) goto cleanup;
1367b528cefcSMark Murray     ret = krb5_ret_keyblock (sp,  &creds->session);
1368b528cefcSMark Murray     if(ret) goto cleanup;
1369b528cefcSMark Murray     ret = krb5_ret_times (sp,  &creds->times);
1370b528cefcSMark Murray     if(ret) goto cleanup;
1371b528cefcSMark Murray     ret = krb5_ret_int8 (sp,  &dummy8);
1372b528cefcSMark Murray     if(ret) goto cleanup;
1373b528cefcSMark Murray     ret = krb5_ret_int32 (sp,  &dummy32);
1374b528cefcSMark Murray     if(ret) goto cleanup;
13751c43270aSJacques Vidrine     /*
13761c43270aSJacques Vidrine      * Runtime detect the what is the higher bits of the bitfield. If
1377c19800e8SDoug Rabson      * any of the higher bits are set in the input data, it's either a
1378c19800e8SDoug Rabson      * new ticket flag (and this code need to be removed), or it's a
13791c43270aSJacques Vidrine      * MIT cache (or new Heimdal cache), lets change it to our current
13801c43270aSJacques Vidrine      * format.
13811c43270aSJacques Vidrine      */
13821c43270aSJacques Vidrine     {
1383c19800e8SDoug Rabson 	uint32_t mask = 0xffff0000;
13841c43270aSJacques Vidrine 	creds->flags.i = 0;
13851c43270aSJacques Vidrine 	creds->flags.b.anonymous = 1;
13861c43270aSJacques Vidrine 	if (creds->flags.i & mask)
13871c43270aSJacques Vidrine 	    mask = ~mask;
13881c43270aSJacques Vidrine 	if (dummy32 & mask)
13891c43270aSJacques Vidrine 	    dummy32 = bitswap32(dummy32);
13901c43270aSJacques Vidrine     }
1391b528cefcSMark Murray     creds->flags.i = dummy32;
1392b528cefcSMark Murray     ret = krb5_ret_addrs (sp,  &creds->addresses);
1393b528cefcSMark Murray     if(ret) goto cleanup;
1394b528cefcSMark Murray     ret = krb5_ret_authdata (sp,  &creds->authdata);
1395b528cefcSMark Murray     if(ret) goto cleanup;
1396b528cefcSMark Murray     ret = krb5_ret_data (sp,  &creds->ticket);
1397b528cefcSMark Murray     if(ret) goto cleanup;
1398b528cefcSMark Murray     ret = krb5_ret_data (sp,  &creds->second_ticket);
1399b528cefcSMark Murray cleanup:
14008373020dSJacques Vidrine     if(ret) {
1401b528cefcSMark Murray #if 0
1402c19800e8SDoug Rabson 	krb5_free_cred_contents(context, creds); /* XXX */
1403c19800e8SDoug Rabson #endif
1404c19800e8SDoug Rabson     }
1405c19800e8SDoug Rabson     return ret;
1406c19800e8SDoug Rabson }
1407c19800e8SDoug Rabson 
1408c19800e8SDoug Rabson #define SC_CLIENT_PRINCIPAL	    0x0001
1409c19800e8SDoug Rabson #define SC_SERVER_PRINCIPAL	    0x0002
1410c19800e8SDoug Rabson #define SC_SESSION_KEY		    0x0004
1411c19800e8SDoug Rabson #define SC_TICKET		    0x0008
1412c19800e8SDoug Rabson #define SC_SECOND_TICKET	    0x0010
1413c19800e8SDoug Rabson #define SC_AUTHDATA		    0x0020
1414c19800e8SDoug Rabson #define SC_ADDRESSES		    0x0040
1415c19800e8SDoug Rabson 
1416*ae771770SStanislav Sedov /**
1417*ae771770SStanislav Sedov  * Write a tagged credentials block to storage.
1418c19800e8SDoug Rabson  *
1419*ae771770SStanislav Sedov  * @param sp the storage buffer to write to
1420*ae771770SStanislav Sedov  * @param creds the creds block to write.
1421*ae771770SStanislav Sedov  *
1422*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
1423*ae771770SStanislav Sedov  *
1424*ae771770SStanislav Sedov  * @ingroup krb5_storage
1425c19800e8SDoug Rabson  */
1426c19800e8SDoug Rabson 
1427*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_store_creds_tag(krb5_storage * sp,krb5_creds * creds)1428c19800e8SDoug Rabson krb5_store_creds_tag(krb5_storage *sp, krb5_creds *creds)
1429c19800e8SDoug Rabson {
1430c19800e8SDoug Rabson     int ret;
1431c19800e8SDoug Rabson     int32_t header = 0;
1432c19800e8SDoug Rabson 
1433c19800e8SDoug Rabson     if (creds->client)
1434c19800e8SDoug Rabson 	header |= SC_CLIENT_PRINCIPAL;
1435c19800e8SDoug Rabson     if (creds->server)
1436c19800e8SDoug Rabson 	header |= SC_SERVER_PRINCIPAL;
1437c19800e8SDoug Rabson     if (creds->session.keytype != ETYPE_NULL)
1438c19800e8SDoug Rabson 	header |= SC_SESSION_KEY;
1439c19800e8SDoug Rabson     if (creds->ticket.data)
1440c19800e8SDoug Rabson 	header |= SC_TICKET;
1441c19800e8SDoug Rabson     if (creds->second_ticket.length)
1442c19800e8SDoug Rabson 	header |= SC_SECOND_TICKET;
1443c19800e8SDoug Rabson     if (creds->authdata.len)
1444c19800e8SDoug Rabson 	header |= SC_AUTHDATA;
1445c19800e8SDoug Rabson     if (creds->addresses.len)
1446c19800e8SDoug Rabson 	header |= SC_ADDRESSES;
1447c19800e8SDoug Rabson 
1448c19800e8SDoug Rabson     ret = krb5_store_int32(sp, header);
1449*ae771770SStanislav Sedov     if (ret)
1450*ae771770SStanislav Sedov 	return ret;
1451c19800e8SDoug Rabson 
1452c19800e8SDoug Rabson     if (creds->client) {
1453c19800e8SDoug Rabson 	ret = krb5_store_principal(sp, creds->client);
1454c19800e8SDoug Rabson 	if(ret)
1455c19800e8SDoug Rabson 	    return ret;
1456c19800e8SDoug Rabson     }
1457c19800e8SDoug Rabson 
1458c19800e8SDoug Rabson     if (creds->server) {
1459c19800e8SDoug Rabson 	ret = krb5_store_principal(sp, creds->server);
1460c19800e8SDoug Rabson 	if(ret)
1461c19800e8SDoug Rabson 	    return ret;
1462c19800e8SDoug Rabson     }
1463c19800e8SDoug Rabson 
1464c19800e8SDoug Rabson     if (creds->session.keytype != ETYPE_NULL) {
1465c19800e8SDoug Rabson 	ret = krb5_store_keyblock(sp, creds->session);
1466c19800e8SDoug Rabson 	if(ret)
1467c19800e8SDoug Rabson 	    return ret;
1468c19800e8SDoug Rabson     }
1469c19800e8SDoug Rabson 
1470c19800e8SDoug Rabson     ret = krb5_store_times(sp, creds->times);
1471c19800e8SDoug Rabson     if(ret)
1472c19800e8SDoug Rabson 	return ret;
1473c19800e8SDoug Rabson     ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
1474c19800e8SDoug Rabson     if(ret)
1475c19800e8SDoug Rabson 	return ret;
1476c19800e8SDoug Rabson 
1477c19800e8SDoug Rabson     ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
1478c19800e8SDoug Rabson     if(ret)
1479c19800e8SDoug Rabson 	return ret;
1480c19800e8SDoug Rabson 
1481c19800e8SDoug Rabson     if (creds->addresses.len) {
1482c19800e8SDoug Rabson 	ret = krb5_store_addrs(sp, creds->addresses);
1483c19800e8SDoug Rabson 	if(ret)
1484c19800e8SDoug Rabson 	    return ret;
1485c19800e8SDoug Rabson     }
1486c19800e8SDoug Rabson 
1487c19800e8SDoug Rabson     if (creds->authdata.len) {
1488c19800e8SDoug Rabson 	ret = krb5_store_authdata(sp, creds->authdata);
1489c19800e8SDoug Rabson 	if(ret)
1490c19800e8SDoug Rabson 	    return ret;
1491c19800e8SDoug Rabson     }
1492c19800e8SDoug Rabson 
1493c19800e8SDoug Rabson     if (creds->ticket.data) {
1494c19800e8SDoug Rabson 	ret = krb5_store_data(sp, creds->ticket);
1495c19800e8SDoug Rabson 	if(ret)
1496c19800e8SDoug Rabson 	    return ret;
1497c19800e8SDoug Rabson     }
1498c19800e8SDoug Rabson 
1499c19800e8SDoug Rabson     if (creds->second_ticket.data) {
1500c19800e8SDoug Rabson 	ret = krb5_store_data(sp, creds->second_ticket);
1501c19800e8SDoug Rabson 	if (ret)
1502c19800e8SDoug Rabson 	    return ret;
1503c19800e8SDoug Rabson     }
1504c19800e8SDoug Rabson 
1505c19800e8SDoug Rabson     return ret;
1506c19800e8SDoug Rabson }
1507c19800e8SDoug Rabson 
1508*ae771770SStanislav Sedov /**
1509*ae771770SStanislav Sedov  * Read a tagged credentials block from the storage.
1510*ae771770SStanislav Sedov  *
1511*ae771770SStanislav Sedov  * @param sp the storage buffer to write to
1512*ae771770SStanislav Sedov  * @param creds the credentials block read from storage
1513*ae771770SStanislav Sedov  *
1514*ae771770SStanislav Sedov  * @return 0 on success, a Kerberos 5 error code on failure.
1515*ae771770SStanislav Sedov  *
1516*ae771770SStanislav Sedov  * @ingroup krb5_storage
1517*ae771770SStanislav Sedov  */
1518*ae771770SStanislav Sedov 
1519*ae771770SStanislav Sedov KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_creds_tag(krb5_storage * sp,krb5_creds * creds)1520c19800e8SDoug Rabson krb5_ret_creds_tag(krb5_storage *sp,
1521c19800e8SDoug Rabson 		   krb5_creds *creds)
1522c19800e8SDoug Rabson {
1523c19800e8SDoug Rabson     krb5_error_code ret;
1524c19800e8SDoug Rabson     int8_t dummy8;
1525c19800e8SDoug Rabson     int32_t dummy32, header;
1526c19800e8SDoug Rabson 
1527c19800e8SDoug Rabson     memset(creds, 0, sizeof(*creds));
1528c19800e8SDoug Rabson 
1529c19800e8SDoug Rabson     ret = krb5_ret_int32 (sp, &header);
1530c19800e8SDoug Rabson     if (ret) goto cleanup;
1531c19800e8SDoug Rabson 
1532c19800e8SDoug Rabson     if (header & SC_CLIENT_PRINCIPAL) {
1533c19800e8SDoug Rabson 	ret = krb5_ret_principal (sp,  &creds->client);
1534c19800e8SDoug Rabson 	if(ret) goto cleanup;
1535c19800e8SDoug Rabson     }
1536c19800e8SDoug Rabson     if (header & SC_SERVER_PRINCIPAL) {
1537c19800e8SDoug Rabson 	ret = krb5_ret_principal (sp,  &creds->server);
1538c19800e8SDoug Rabson 	if(ret) goto cleanup;
1539c19800e8SDoug Rabson     }
1540c19800e8SDoug Rabson     if (header & SC_SESSION_KEY) {
1541c19800e8SDoug Rabson 	ret = krb5_ret_keyblock (sp,  &creds->session);
1542c19800e8SDoug Rabson 	if(ret) goto cleanup;
1543c19800e8SDoug Rabson     }
1544c19800e8SDoug Rabson     ret = krb5_ret_times (sp,  &creds->times);
1545c19800e8SDoug Rabson     if(ret) goto cleanup;
1546c19800e8SDoug Rabson     ret = krb5_ret_int8 (sp,  &dummy8);
1547c19800e8SDoug Rabson     if(ret) goto cleanup;
1548c19800e8SDoug Rabson     ret = krb5_ret_int32 (sp,  &dummy32);
1549c19800e8SDoug Rabson     if(ret) goto cleanup;
1550c19800e8SDoug Rabson     /*
1551c19800e8SDoug Rabson      * Runtime detect the what is the higher bits of the bitfield. If
1552c19800e8SDoug Rabson      * any of the higher bits are set in the input data, it's either a
1553c19800e8SDoug Rabson      * new ticket flag (and this code need to be removed), or it's a
1554c19800e8SDoug Rabson      * MIT cache (or new Heimdal cache), lets change it to our current
1555c19800e8SDoug Rabson      * format.
1556c19800e8SDoug Rabson      */
1557c19800e8SDoug Rabson     {
1558c19800e8SDoug Rabson 	uint32_t mask = 0xffff0000;
1559c19800e8SDoug Rabson 	creds->flags.i = 0;
1560c19800e8SDoug Rabson 	creds->flags.b.anonymous = 1;
1561c19800e8SDoug Rabson 	if (creds->flags.i & mask)
1562c19800e8SDoug Rabson 	    mask = ~mask;
1563c19800e8SDoug Rabson 	if (dummy32 & mask)
1564c19800e8SDoug Rabson 	    dummy32 = bitswap32(dummy32);
1565c19800e8SDoug Rabson     }
1566c19800e8SDoug Rabson     creds->flags.i = dummy32;
1567c19800e8SDoug Rabson     if (header & SC_ADDRESSES) {
1568c19800e8SDoug Rabson 	ret = krb5_ret_addrs (sp,  &creds->addresses);
1569c19800e8SDoug Rabson 	if(ret) goto cleanup;
1570c19800e8SDoug Rabson     }
1571c19800e8SDoug Rabson     if (header & SC_AUTHDATA) {
1572c19800e8SDoug Rabson 	ret = krb5_ret_authdata (sp,  &creds->authdata);
1573c19800e8SDoug Rabson 	if(ret) goto cleanup;
1574c19800e8SDoug Rabson     }
1575c19800e8SDoug Rabson     if (header & SC_TICKET) {
1576c19800e8SDoug Rabson 	ret = krb5_ret_data (sp,  &creds->ticket);
1577c19800e8SDoug Rabson 	if(ret) goto cleanup;
1578c19800e8SDoug Rabson     }
1579c19800e8SDoug Rabson     if (header & SC_SECOND_TICKET) {
1580c19800e8SDoug Rabson 	ret = krb5_ret_data (sp,  &creds->second_ticket);
1581c19800e8SDoug Rabson 	if(ret) goto cleanup;
1582c19800e8SDoug Rabson     }
1583c19800e8SDoug Rabson 
1584c19800e8SDoug Rabson cleanup:
1585c19800e8SDoug Rabson     if(ret) {
1586c19800e8SDoug Rabson #if 0
1587c19800e8SDoug Rabson 	krb5_free_cred_contents(context, creds); /* XXX */
1588b528cefcSMark Murray #endif
15898373020dSJacques Vidrine     }
1590b528cefcSMark Murray     return ret;
1591b528cefcSMark Murray }
1592