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