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