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 : #define BYTEORDER_IS_PACKED(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_PACKED)
43 :
44 : /**
45 : * Add the flags on a storage buffer by or-ing in the flags to the buffer.
46 : *
47 : * @param sp the storage buffer to set the flags on
48 : * @param flags the flags to set
49 : *
50 : * @ingroup krb5_storage
51 : */
52 :
53 : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
54 831291 : krb5_storage_set_flags(krb5_storage *sp, krb5_flags flags)
55 : {
56 831291 : sp->flags |= flags;
57 831291 : }
58 :
59 : /**
60 : * Clear the flags on a storage buffer
61 : *
62 : * @param sp the storage buffer to clear the flags on
63 : * @param flags the flags to clear
64 : *
65 : * @ingroup krb5_storage
66 : */
67 :
68 : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
69 0 : krb5_storage_clear_flags(krb5_storage *sp, krb5_flags flags)
70 : {
71 0 : sp->flags &= ~flags;
72 0 : }
73 :
74 : /**
75 : * Return true or false depending on if the storage flags is set or
76 : * not. NB testing for the flag 0 always return true.
77 : *
78 : * @param sp the storage buffer to check flags on
79 : * @param flags The flags to test for
80 : *
81 : * @return true if all the flags are set, false if not.
82 : *
83 : * @ingroup krb5_storage
84 : */
85 :
86 : KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
87 12831446 : krb5_storage_is_flags(krb5_storage *sp, krb5_flags flags)
88 : {
89 12831446 : return (sp->flags & flags) == flags;
90 : }
91 :
92 : /**
93 : * Set the new byte order of the storage buffer.
94 : *
95 : * @param sp the storage buffer to set the byte order for.
96 : * @param byteorder the new byte order.
97 : *
98 : * The byte order are: KRB5_STORAGE_BYTEORDER_BE,
99 : * KRB5_STORAGE_BYTEORDER_LE and KRB5_STORAGE_BYTEORDER_HOST.
100 : *
101 : * @ingroup krb5_storage
102 : */
103 :
104 : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
105 0 : krb5_storage_set_byteorder(krb5_storage *sp, krb5_flags byteorder)
106 : {
107 0 : sp->flags &= ~KRB5_STORAGE_BYTEORDER_MASK;
108 0 : sp->flags |= byteorder;
109 0 : }
110 :
111 : /**
112 : * Return the current byteorder for the buffer. See krb5_storage_set_byteorder() for the list or byte order contants.
113 : *
114 : * @ingroup krb5_storage
115 : */
116 :
117 : KRB5_LIB_FUNCTION krb5_flags KRB5_LIB_CALL
118 0 : krb5_storage_get_byteorder(krb5_storage *sp)
119 : {
120 0 : return sp->flags & KRB5_STORAGE_BYTEORDER_MASK;
121 : }
122 :
123 : /**
124 : * Set the max alloc value
125 : *
126 : * @param sp the storage buffer set the max allow for
127 : * @param size maximum size to allocate, use 0 to remove limit
128 : *
129 : * @ingroup krb5_storage
130 : */
131 :
132 : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
133 0 : krb5_storage_set_max_alloc(krb5_storage *sp, size_t size)
134 : {
135 0 : sp->max_alloc = size;
136 0 : }
137 :
138 : /* don't allocate unresonable amount of memory */
139 : static krb5_error_code
140 1081274 : size_too_large(krb5_storage *sp, size_t size)
141 : {
142 1081274 : if (sp->max_alloc && sp->max_alloc < size)
143 0 : return HEIM_ERR_TOO_BIG;
144 1057392 : return 0;
145 : }
146 :
147 : static krb5_error_code
148 125909 : size_too_large_num(krb5_storage *sp, size_t count, size_t size)
149 : {
150 125909 : if (sp->max_alloc == 0 || size == 0)
151 0 : return 0;
152 125909 : size = sp->max_alloc / size;
153 125909 : if (size < count)
154 0 : return HEIM_ERR_TOO_BIG;
155 125909 : return 0;
156 : }
157 :
158 : /**
159 : * Seek to a new offset.
160 : *
161 : * @param sp the storage buffer to seek in.
162 : * @param offset the offset to seek
163 : * @param whence relateive searching, SEEK_CUR from the current
164 : * position, SEEK_END from the end, SEEK_SET absolute from the start.
165 : *
166 : * @return The new current offset
167 : *
168 : * @ingroup krb5_storage
169 : */
170 :
171 : KRB5_LIB_FUNCTION off_t KRB5_LIB_CALL
172 800607 : krb5_storage_seek(krb5_storage *sp, off_t offset, int whence)
173 : {
174 800607 : return (*sp->seek)(sp, offset, whence);
175 : }
176 :
177 : /**
178 : * Truncate the storage buffer in sp to offset.
179 : *
180 : * @param sp the storage buffer to truncate.
181 : * @param offset the offset to truncate to.
182 : *
183 : * @return An Kerberos 5 error code.
184 : *
185 : * @ingroup krb5_storage
186 : */
187 :
188 : KRB5_LIB_FUNCTION int KRB5_LIB_CALL
189 1816 : krb5_storage_truncate(krb5_storage *sp, off_t offset)
190 : {
191 1816 : return (*sp->trunc)(sp, offset);
192 : }
193 :
194 : /**
195 : * Sync the storage buffer to its backing store. If there is no
196 : * backing store this function will return success.
197 : *
198 : * @param sp the storage buffer to sync
199 : *
200 : * @return A Kerberos 5 error code
201 : *
202 : * @ingroup krb5_storage
203 : */
204 :
205 : KRB5_LIB_FUNCTION int KRB5_LIB_CALL
206 2282 : krb5_storage_fsync(krb5_storage *sp)
207 : {
208 2282 : if (sp->fsync != NULL)
209 2282 : return sp->fsync(sp);
210 0 : return 0;
211 : }
212 :
213 : /**
214 : * Read to the storage buffer.
215 : *
216 : * @param sp the storage buffer to read from
217 : * @param buf the buffer to store the data in
218 : * @param len the length to read
219 : *
220 : * @return The length of data read (can be shorter then len), or negative on error.
221 : *
222 : * @ingroup krb5_storage
223 : */
224 :
225 : KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL
226 988387 : krb5_storage_read(krb5_storage *sp, void *buf, size_t len)
227 : {
228 988387 : return sp->fetch(sp, buf, len);
229 : }
230 :
231 : /**
232 : * Write to the storage buffer.
233 : *
234 : * @param sp the storage buffer to write to
235 : * @param buf the buffer to write to the storage buffer
236 : * @param len the length to write
237 : *
238 : * @return The length of data written (can be shorter then len), or negative on error.
239 : *
240 : * @ingroup krb5_storage
241 : */
242 :
243 : KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL
244 1165974 : krb5_storage_write(krb5_storage *sp, const void *buf, size_t len)
245 : {
246 1165974 : return sp->store(sp, buf, len);
247 : }
248 :
249 : /**
250 : * Set the return code that will be used when end of storage is reached.
251 : *
252 : * @param sp the storage
253 : * @param code the error code to return on end of storage
254 : *
255 : * @ingroup krb5_storage
256 : */
257 :
258 : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
259 66527 : krb5_storage_set_eof_code(krb5_storage *sp, int code)
260 : {
261 66527 : sp->eof_code = code;
262 66527 : }
263 :
264 : /**
265 : * Get the return code that will be used when end of storage is reached.
266 : *
267 : * @param sp the storage
268 : *
269 : * @return storage error code
270 : *
271 : * @ingroup krb5_storage
272 : */
273 :
274 : KRB5_LIB_FUNCTION int KRB5_LIB_CALL
275 0 : krb5_storage_get_eof_code(krb5_storage *sp)
276 : {
277 0 : return sp->eof_code;
278 : }
279 :
280 : /**
281 : * Free a krb5 storage.
282 : *
283 : * @param sp the storage to free.
284 : *
285 : * @return An Kerberos 5 error code.
286 : *
287 : * @ingroup krb5_storage
288 : */
289 :
290 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
291 1260566 : krb5_storage_free(krb5_storage *sp)
292 : {
293 1260566 : if (sp == NULL)
294 0 : return 0;
295 1260566 : if(sp->free)
296 519791 : (*sp->free)(sp);
297 1260566 : free(sp->data);
298 1260566 : free(sp);
299 1260566 : return 0;
300 : }
301 :
302 : /**
303 : * Copy the content of storage to a krb5_data.
304 : *
305 : * @param sp the storage to copy to a data
306 : * @param data the copied data, free with krb5_data_free()
307 : *
308 : * @return 0 for success, or a Kerberos 5 error code on failure.
309 : *
310 : * @ingroup krb5_storage
311 : */
312 :
313 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
314 454837 : krb5_storage_to_data(krb5_storage *sp, krb5_data *data)
315 : {
316 14678 : off_t pos, size;
317 14678 : krb5_error_code ret;
318 :
319 454837 : pos = sp->seek(sp, 0, SEEK_CUR);
320 454837 : if (pos < 0)
321 0 : return HEIM_ERR_NOT_SEEKABLE;
322 454837 : size = sp->seek(sp, 0, SEEK_END);
323 454837 : ret = size_too_large(sp, size);
324 440159 : if (ret)
325 0 : return ret;
326 454837 : ret = krb5_data_alloc(data, size);
327 454837 : if (ret) {
328 0 : sp->seek(sp, pos, SEEK_SET);
329 0 : return ret;
330 : }
331 454837 : if (size) {
332 14678 : ssize_t bytes;
333 :
334 454837 : sp->seek(sp, 0, SEEK_SET);
335 454837 : bytes = sp->fetch(sp, data->data, data->length);
336 454837 : sp->seek(sp, pos, SEEK_SET);
337 :
338 : /* sp->fetch() really shouldn't fail */
339 454837 : if (bytes < 0)
340 0 : return sp->eof_code;
341 :
342 : /* Maybe the underlying file (or whatever) got truncated? */
343 454837 : data->length = bytes;
344 : }
345 440159 : return 0;
346 : }
347 :
348 : static size_t
349 0 : pack_int(uint8_t *p, uint64_t val)
350 : {
351 0 : size_t l = 0;
352 :
353 0 : if (val < 128) {
354 0 : *p = val;
355 : } else {
356 0 : while (val > 0) {
357 0 : *p-- = val % 256;
358 0 : val /= 256;
359 0 : l++;
360 : }
361 0 : *p = 0x80 | l;
362 : }
363 0 : return l + 1;
364 : }
365 :
366 : static size_t
367 0 : unpack_int_length(uint8_t *v)
368 : {
369 0 : size_t size;
370 :
371 0 : if (*v < 128)
372 0 : size = 0;
373 : else
374 0 : size = *v & 0x7f;
375 :
376 0 : return size + 1;
377 : }
378 :
379 : static int
380 0 : unpack_int(uint8_t *p, size_t len, uint64_t *val, size_t *size)
381 : {
382 0 : size_t v;
383 :
384 0 : if (len == 0)
385 0 : return EINVAL;
386 0 : --len;
387 0 : v = *p++;
388 0 : if (v < 128) {
389 0 : *val = v;
390 0 : *size = 1;
391 : } else {
392 0 : int e;
393 0 : size_t l;
394 0 : uint64_t tmp;
395 :
396 0 : if (v == 0x80) {
397 0 : *size = 1;
398 0 : return EINVAL;
399 : }
400 0 : v &= 0x7F;
401 0 : if (len < v)
402 0 : return ERANGE;
403 0 : e = der_get_unsigned64(p, v, &tmp, &l);
404 0 : if (e)
405 0 : return ERANGE;
406 0 : *val = tmp;
407 0 : *size = l + 1;
408 : }
409 0 : return 0;
410 : }
411 :
412 : static krb5_error_code
413 3083240 : krb5_store_int(krb5_storage *sp,
414 : int64_t value,
415 : size_t len)
416 : {
417 106754 : int ret;
418 3083240 : uint8_t v[9], *p = v;
419 :
420 3083240 : if (len > sizeof(value))
421 0 : return EINVAL;
422 :
423 3083240 : if (BYTEORDER_IS_PACKED(sp)) {
424 0 : uint64_t mask = ~0ULL >> (64 - len * 8);
425 0 : value &= mask;
426 0 : p += sizeof(v) - 1;
427 0 : len = pack_int(p, value);
428 0 : p = v + sizeof(v) - len;
429 : } else
430 3083240 : _krb5_put_int(v, value, len);
431 3083240 : ret = sp->store(sp, p, len);
432 3083240 : if (ret < 0)
433 0 : return errno;
434 3083240 : if ((size_t)ret != len)
435 0 : return sp->eof_code;
436 2976486 : return 0;
437 : }
438 :
439 : /**
440 : * Store a int32 to storage, byte order is controlled by the settings
441 : * on the storage, see krb5_storage_set_byteorder().
442 : *
443 : * @param sp the storage to write to
444 : * @param value the value to store
445 : *
446 : * @return 0 for success, or a Kerberos 5 error code on failure.
447 : *
448 : * @ingroup krb5_storage
449 : */
450 :
451 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
452 2277997 : krb5_store_int32(krb5_storage *sp,
453 : int32_t value)
454 : {
455 2277997 : if(BYTEORDER_IS_HOST(sp))
456 0 : value = htonl(value);
457 2277997 : else if(BYTEORDER_IS_LE(sp))
458 1785304 : value = bswap32(value);
459 2277997 : return krb5_store_int(sp, value, 4);
460 : }
461 :
462 : /**
463 : * Store a int64 to storage, byte order is controlled by the settings
464 : * on the storage, see krb5_storage_set_byteorder().
465 : *
466 : * @param sp the storage to write to
467 : * @param value the value to store
468 : *
469 : * @return 0 for success, or a Kerberos 5 error code on failure.
470 : *
471 : * @ingroup krb5_storage
472 : */
473 :
474 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
475 631897 : krb5_store_int64(krb5_storage *sp,
476 : int64_t value)
477 : {
478 631897 : if (BYTEORDER_IS_HOST(sp))
479 : #ifdef WORDS_BIGENDIAN
480 : ;
481 : #else
482 0 : value = bswap64(value); /* There's no ntohll() */
483 : #endif
484 631897 : else if (BYTEORDER_IS_LE(sp))
485 631897 : value = bswap64(value);
486 631897 : return krb5_store_int(sp, value, 8);
487 : }
488 :
489 : /**
490 : * Store a uint32 to storage, byte order is controlled by the settings
491 : * on the storage, see krb5_storage_set_byteorder().
492 : *
493 : * @param sp the storage to write to
494 : * @param value the value to store
495 : *
496 : * @return 0 for success, or a Kerberos 5 error code on failure.
497 : *
498 : * @ingroup krb5_storage
499 : */
500 :
501 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
502 1786818 : krb5_store_uint32(krb5_storage *sp,
503 : uint32_t value)
504 : {
505 1786818 : return krb5_store_int32(sp, (int32_t)value);
506 : }
507 :
508 : /**
509 : * Store a uint64 to storage, byte order is controlled by the settings
510 : * on the storage, see krb5_storage_set_byteorder().
511 : *
512 : * @param sp the storage to write to
513 : * @param value the value to store
514 : *
515 : * @return 0 for success, or a Kerberos 5 error code on failure.
516 : *
517 : * @ingroup krb5_storage
518 : */
519 :
520 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
521 631897 : krb5_store_uint64(krb5_storage *sp,
522 : uint64_t value)
523 : {
524 631897 : return krb5_store_int64(sp, (int64_t)value);
525 : }
526 :
527 : static krb5_error_code
528 9028938 : krb5_ret_int(krb5_storage *sp,
529 : int64_t *value,
530 : size_t len)
531 : {
532 187930 : int ret;
533 187930 : unsigned char v[9];
534 9028938 : uint64_t w = 0;
535 9028938 : *value = 0; /* quiets warnings */
536 9028938 : if (BYTEORDER_IS_PACKED(sp)) {
537 0 : ret = sp->fetch(sp, v, 1);
538 0 : if (ret < 0)
539 0 : return errno;
540 0 : if (ret != 1)
541 0 : return sp->eof_code;
542 :
543 0 : len = unpack_int_length(v);
544 0 : if (len < 1)
545 0 : return ERANGE;
546 0 : else if (len > 1) {
547 0 : ret = sp->fetch(sp, v + 1, len - 1);
548 0 : if (ret < 0)
549 0 : return errno;
550 0 : if (ret != len - 1)
551 0 : return sp->eof_code;
552 : }
553 0 : ret = unpack_int(v, len, &w, &len);
554 0 : if (ret)
555 0 : return ret;
556 0 : *value = w;
557 0 : return 0;
558 : }
559 9028938 : ret = sp->fetch(sp, v, len);
560 9028938 : if (ret < 0)
561 0 : return errno;
562 9028938 : if ((size_t)ret != len)
563 29594 : return sp->eof_code;
564 8999344 : _krb5_get_int64(v, &w, len);
565 8999344 : *value = w;
566 8999344 : return 0;
567 : }
568 :
569 : /**
570 : * Read a int64 from storage, byte order is controlled by the settings
571 : * on the storage, see krb5_storage_set_byteorder().
572 : *
573 : * @param sp the storage to write to
574 : * @param value the value read from the buffer
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 1255391 : krb5_ret_int64(krb5_storage *sp,
583 : int64_t *value)
584 : {
585 1255391 : krb5_error_code ret = krb5_ret_int(sp, value, 8);
586 1255391 : if(ret)
587 0 : return ret;
588 1255391 : if(BYTEORDER_IS_HOST(sp))
589 : #ifdef WORDS_BIGENDIAN
590 : ;
591 : #else
592 0 : *value = bswap64(*value); /* There's no ntohll() */
593 : #endif
594 1255391 : else if(BYTEORDER_IS_LE(sp))
595 1255391 : *value = bswap64(*value);
596 1228023 : return 0;
597 : }
598 :
599 : /**
600 : * Read a uint64 from storage, byte order is controlled by the settings
601 : * on the storage, see krb5_storage_set_byteorder().
602 : *
603 : * @param sp the storage to write to
604 : * @param value the value read from the buffer
605 : *
606 : * @return 0 for success, or a Kerberos 5 error code on failure.
607 : *
608 : * @ingroup krb5_storage
609 : */
610 :
611 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
612 1255391 : krb5_ret_uint64(krb5_storage *sp,
613 : uint64_t *value)
614 : {
615 27368 : krb5_error_code ret;
616 27368 : int64_t v;
617 :
618 1255391 : ret = krb5_ret_int64(sp, &v);
619 1255391 : if (ret == 0)
620 1255391 : *value = (uint64_t)v;
621 :
622 1255391 : return ret;
623 : }
624 :
625 : /**
626 : * Read a int32 from storage, byte order is controlled by the settings
627 : * on the storage, see krb5_storage_set_byteorder().
628 : *
629 : * @param sp the storage to write to
630 : * @param value the value read from the buffer
631 : *
632 : * @return 0 for success, or a Kerberos 5 error code on failure.
633 : *
634 : * @ingroup krb5_storage
635 : */
636 :
637 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
638 5522056 : krb5_ret_int32(krb5_storage *sp,
639 : int32_t *value)
640 : {
641 111712 : int64_t v;
642 :
643 5522056 : krb5_error_code ret = krb5_ret_int(sp, &v, 4);
644 5522056 : if (ret)
645 29150 : return ret;
646 5492462 : *value = v;
647 5492462 : if (BYTEORDER_IS_HOST(sp))
648 0 : *value = htonl(*value);
649 5492462 : else if (BYTEORDER_IS_LE(sp))
650 3342119 : *value = bswap32(*value);
651 5381194 : return 0;
652 : }
653 :
654 : /**
655 : * Read a uint32 from storage, byte order is controlled by the settings
656 : * on the storage, see krb5_storage_set_byteorder().
657 : *
658 : * @param sp the storage to write to
659 : * @param value the value read from the buffer
660 : *
661 : * @return 0 for success, or a Kerberos 5 error code on failure.
662 : *
663 : * @ingroup krb5_storage
664 : */
665 :
666 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
667 3789820 : krb5_ret_uint32(krb5_storage *sp, uint32_t *value)
668 : {
669 83860 : krb5_error_code ret;
670 83860 : int32_t v;
671 :
672 3789820 : ret = krb5_ret_int32(sp, &v);
673 3789820 : if (ret == 0)
674 3789820 : *value = (uint32_t)v;
675 :
676 3789820 : return ret;
677 : }
678 :
679 : /**
680 : * Store a int16 to storage, byte order is controlled by the settings
681 : * on the storage, see krb5_storage_set_byteorder().
682 : *
683 : * @param sp the storage to write to
684 : * @param value the value to store
685 : *
686 : * @return 0 for success, or a Kerberos 5 error code on failure.
687 : *
688 : * @ingroup krb5_storage
689 : */
690 :
691 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
692 173346 : krb5_store_int16(krb5_storage *sp,
693 : int16_t value)
694 : {
695 173346 : if(BYTEORDER_IS_HOST(sp))
696 0 : value = htons(value);
697 173346 : else if(BYTEORDER_IS_LE(sp))
698 85596 : value = bswap16(value);
699 173346 : return krb5_store_int(sp, value, 2);
700 : }
701 :
702 : /**
703 : * Store a uint16 to storage, byte order is controlled by the settings
704 : * on the storage, see krb5_storage_set_byteorder().
705 : *
706 : * @param sp the storage to write to
707 : * @param value the value to store
708 : *
709 : * @return 0 for success, or a Kerberos 5 error code on failure.
710 : *
711 : * @ingroup krb5_storage
712 : */
713 :
714 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
715 85596 : krb5_store_uint16(krb5_storage *sp,
716 : uint16_t value)
717 : {
718 85596 : return krb5_store_int16(sp, (int16_t)value);
719 : }
720 :
721 : /**
722 : * Read a int16 from storage, byte order is controlled by the settings
723 : * on the storage, see krb5_storage_set_byteorder().
724 : *
725 : * @param sp the storage to write to
726 : * @param value the value read from the buffer
727 : *
728 : * @return 0 for success, or a Kerberos 5 error code on failure.
729 : *
730 : * @ingroup krb5_storage
731 : */
732 :
733 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
734 2251491 : krb5_ret_int16(krb5_storage *sp,
735 : int16_t *value)
736 : {
737 48850 : int64_t v;
738 48850 : int ret;
739 2251491 : ret = krb5_ret_int(sp, &v, 2);
740 2251491 : if(ret)
741 0 : return ret;
742 2251491 : *value = v;
743 2251491 : if(BYTEORDER_IS_HOST(sp))
744 0 : *value = htons(*value);
745 2251491 : else if(BYTEORDER_IS_LE(sp))
746 935634 : *value = bswap16(*value);
747 2202641 : return 0;
748 : }
749 :
750 : /**
751 : * Read a int16 from storage, byte order is controlled by the settings
752 : * on the storage, see krb5_storage_set_byteorder().
753 : *
754 : * @param sp the storage to write to
755 : * @param value the value read from the buffer
756 : *
757 : * @return 0 for success, or 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 935634 : krb5_ret_uint16(krb5_storage *sp,
764 : uint16_t *value)
765 : {
766 22851 : krb5_error_code ret;
767 22851 : int16_t v;
768 :
769 935634 : ret = krb5_ret_int16(sp, &v);
770 935634 : if (ret == 0)
771 935634 : *value = (uint16_t)v;
772 :
773 935634 : return ret;
774 : }
775 :
776 : /**
777 : * Store a int8 to storage.
778 : *
779 : * @param sp the storage to write to
780 : * @param value the value to store
781 : *
782 : * @return 0 for success, or 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 5471 : krb5_store_int8(krb5_storage *sp,
789 : int8_t value)
790 : {
791 275 : int ret;
792 :
793 5471 : ret = sp->store(sp, &value, sizeof(value));
794 5471 : if (ret != sizeof(value))
795 0 : return (ret<0)?errno:sp->eof_code;
796 5196 : return 0;
797 : }
798 :
799 : /**
800 : * Store a uint8 to storage.
801 : *
802 : * @param sp the storage to write to
803 : * @param value the value to store
804 : *
805 : * @return 0 for success, or a Kerberos 5 error code on failure.
806 : *
807 : * @ingroup krb5_storage
808 : */
809 :
810 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
811 0 : krb5_store_uint8(krb5_storage *sp,
812 : uint8_t value)
813 : {
814 0 : return krb5_store_int8(sp, (int8_t)value);
815 : }
816 :
817 : /**
818 : * Read a int8 from storage
819 : *
820 : * @param sp the storage to write to
821 : * @param value the value read from the buffer
822 : *
823 : * @return 0 for success, or a Kerberos 5 error code on failure.
824 : *
825 : * @ingroup krb5_storage
826 : */
827 :
828 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
829 371655 : krb5_ret_int8(krb5_storage *sp,
830 : int8_t *value)
831 : {
832 7118 : ssize_t ret;
833 :
834 371655 : ret = sp->fetch(sp, value, sizeof(*value));
835 371655 : if (ret < 0 || (size_t)ret != sizeof(*value))
836 0 : return (ret<0)?errno:sp->eof_code;
837 364537 : return 0;
838 : }
839 :
840 : /**
841 : * Read a uint8 from storage
842 : *
843 : * @param sp the storage to write to
844 : * @param value the value read from the buffer
845 : *
846 : * @return 0 for success, or a Kerberos 5 error code on failure.
847 : *
848 : * @ingroup krb5_storage
849 : */
850 :
851 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
852 0 : krb5_ret_uint8(krb5_storage *sp,
853 : uint8_t *value)
854 : {
855 0 : krb5_error_code ret;
856 0 : int8_t v;
857 :
858 0 : ret = krb5_ret_int8(sp, &v);
859 0 : if (ret == 0)
860 0 : *value = (uint8_t)v;
861 :
862 0 : return ret;
863 : }
864 :
865 : /**
866 : * Store a data to the storage. The data is stored with an int32 as
867 : * lenght plus the data (not padded).
868 : *
869 : * @param sp the storage buffer to write to
870 : * @param data the buffer to store.
871 : *
872 : * @return 0 on success, a Kerberos 5 error code on failure.
873 : *
874 : * @ingroup krb5_storage
875 : */
876 :
877 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
878 383460 : krb5_store_data(krb5_storage *sp,
879 : krb5_data data)
880 : {
881 10862 : int ret;
882 383460 : ret = krb5_store_int32(sp, data.length);
883 383460 : if(ret < 0)
884 0 : return ret;
885 383460 : ret = sp->store(sp, data.data, data.length);
886 383460 : if(ret < 0)
887 0 : return errno;
888 383460 : if((size_t)ret != data.length)
889 0 : return sp->eof_code;
890 372598 : return 0;
891 : }
892 :
893 : /**
894 : * Store a data blob to the storage. The data is stored with an int32 as
895 : * length plus the data (not padded). This function only differs from
896 : * krb5_store_data() insofar as it takes a void * and a length as parameters.
897 : *
898 : * @param sp the storage buffer to write to
899 : * @param s the string to store.
900 : * @param len length of the string to be stored.
901 : *
902 : * @return 0 on success, a Kerberos 5 error code on failure.
903 : *
904 : * @ingroup krb5_storage
905 : */
906 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
907 0 : krb5_store_datalen(krb5_storage *sp, const void *d, size_t len)
908 : {
909 0 : krb5_data data;
910 0 : data.length = len;
911 0 : data.data = (void *)d;
912 0 : return krb5_store_data(sp, data);
913 : }
914 :
915 : /**
916 : * Store a data blob to the storage. The data is stored without a length.
917 : *
918 : * @param sp the storage buffer to write to
919 : * @param s the string to store.
920 : * @param len length of the string to be stored.
921 : *
922 : * @return 0 on success, a Kerberos 5 error code on failure.
923 : *
924 : * @ingroup krb5_storage
925 : */
926 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
927 0 : krb5_store_bytes(krb5_storage *sp, const void *d, size_t len)
928 : {
929 0 : ssize_t ssize;
930 :
931 0 : ssize = krb5_storage_write(sp, d, len);
932 0 : if (ssize != len)
933 0 : return ENOMEM;
934 :
935 0 : return 0;
936 : }
937 :
938 : /**
939 : * Parse a data from the storage.
940 : *
941 : * @param sp the storage buffer to read from
942 : * @param data the parsed data
943 : *
944 : * @return 0 on success, a Kerberos 5 error code on failure.
945 : *
946 : * @ingroup krb5_storage
947 : */
948 :
949 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
950 649544 : krb5_ret_data(krb5_storage *sp,
951 : krb5_data *data)
952 : {
953 9204 : krb5_error_code ret;
954 9204 : int32_t size;
955 :
956 649544 : ret = krb5_ret_int32(sp, &size);
957 649544 : if(ret)
958 23107 : return ret;
959 626437 : ret = size_too_large(sp, size);
960 617233 : if (ret)
961 0 : return ret;
962 626437 : ret = krb5_data_alloc (data, size);
963 626437 : if (ret)
964 0 : return ret;
965 626437 : if (size) {
966 5877 : ssize_t bytes;
967 :
968 485928 : bytes = sp->fetch(sp, data->data, size);
969 485928 : if (bytes < 0 || bytes != size) {
970 0 : krb5_data_free(data);
971 0 : return (bytes < 0)? errno : sp->eof_code;
972 : }
973 : }
974 617233 : return 0;
975 : }
976 :
977 : /**
978 : * Store a string to the buffer. The data is formated as an len:uint32
979 : * plus the string itself (not padded).
980 : *
981 : * @param sp the storage buffer to write to
982 : * @param s the string to store.
983 : *
984 : * @return 0 on success, a Kerberos 5 error code on failure.
985 : *
986 : * @ingroup krb5_storage
987 : */
988 :
989 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
990 265500 : krb5_store_string(krb5_storage *sp, const char *s)
991 : {
992 8226 : krb5_data data;
993 :
994 265500 : if (s == NULL)
995 0 : return EINVAL;
996 :
997 265500 : data.length = strlen(s);
998 265500 : data.data = rk_UNCONST(s);
999 265500 : return krb5_store_data(sp, data);
1000 : }
1001 :
1002 : /**
1003 : * Parse a string from the storage.
1004 : *
1005 : * @param sp the storage buffer to read from
1006 : * @param string the parsed string
1007 : *
1008 : * @return 0 on success, a Kerberos 5 error code on failure.
1009 : *
1010 : * @ingroup krb5_storage
1011 : */
1012 :
1013 :
1014 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1015 418281 : krb5_ret_string(krb5_storage *sp,
1016 : char **string)
1017 : {
1018 8226 : int ret;
1019 8226 : krb5_data data;
1020 :
1021 418281 : *string = NULL;
1022 418281 : ret = krb5_ret_data(sp, &data);
1023 418281 : if(ret)
1024 0 : return ret;
1025 418281 : *string = realloc(data.data, data.length + 1);
1026 418281 : if(*string == NULL){
1027 0 : free(data.data);
1028 0 : return ENOMEM;
1029 : }
1030 418281 : (*string)[data.length] = 0;
1031 418281 : return 0;
1032 : }
1033 :
1034 : /**
1035 : * Store a zero terminated string to the buffer. The data is stored
1036 : * one character at a time until a NUL is stored.
1037 : *
1038 : * @param sp the storage buffer to write to
1039 : * @param s the string to store.
1040 : *
1041 : * @return 0 on success, a Kerberos 5 error code on failure.
1042 : *
1043 : * @ingroup krb5_storage
1044 : */
1045 :
1046 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1047 0 : krb5_store_stringz(krb5_storage *sp, const char *s)
1048 : {
1049 0 : size_t len;
1050 0 : ssize_t ret;
1051 :
1052 0 : if (s == NULL)
1053 0 : return EINVAL;
1054 :
1055 0 : len = strlen(s) + 1;
1056 0 : ret = sp->store(sp, s, len);
1057 0 : if(ret < 0)
1058 0 : return ret;
1059 0 : if((size_t)ret != len)
1060 0 : return sp->eof_code;
1061 0 : return 0;
1062 : }
1063 :
1064 : /**
1065 : * Parse zero terminated string from the storage.
1066 : *
1067 : * @param sp the storage buffer to read from
1068 : * @param string the parsed string
1069 : *
1070 : * @return 0 on success, a Kerberos 5 error code on failure.
1071 : *
1072 : * @ingroup krb5_storage
1073 : */
1074 :
1075 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1076 0 : krb5_ret_stringz(krb5_storage *sp,
1077 : char **string)
1078 : {
1079 0 : char c;
1080 0 : char *s = NULL;
1081 0 : size_t len = 0;
1082 0 : ssize_t ret;
1083 :
1084 0 : while((ret = sp->fetch(sp, &c, 1)) == 1){
1085 0 : krb5_error_code eret;
1086 0 : char *tmp;
1087 :
1088 0 : len++;
1089 0 : eret = size_too_large(sp, len);
1090 0 : if (eret) {
1091 0 : free(s);
1092 0 : return eret;
1093 : }
1094 0 : tmp = realloc (s, len);
1095 0 : if (tmp == NULL) {
1096 0 : free (s);
1097 0 : return ENOMEM;
1098 : }
1099 0 : s = tmp;
1100 0 : s[len - 1] = c;
1101 0 : if(c == 0)
1102 0 : break;
1103 : }
1104 0 : if(ret != 1){
1105 0 : free(s);
1106 0 : if(ret == 0)
1107 0 : return sp->eof_code;
1108 0 : return ret;
1109 : }
1110 0 : *string = s;
1111 0 : return 0;
1112 : }
1113 :
1114 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1115 0 : krb5_store_stringnl(krb5_storage *sp, const char *s)
1116 : {
1117 0 : size_t len;
1118 0 : ssize_t ret;
1119 :
1120 0 : if (s == NULL)
1121 0 : return EINVAL;
1122 :
1123 0 : len = strlen(s);
1124 0 : ret = sp->store(sp, s, len);
1125 0 : if(ret < 0)
1126 0 : return ret;
1127 0 : if((size_t)ret != len)
1128 0 : return sp->eof_code;
1129 0 : ret = sp->store(sp, "\n", 1);
1130 0 : if(ret != 1) {
1131 0 : if(ret < 0)
1132 0 : return ret;
1133 : else
1134 0 : return sp->eof_code;
1135 : }
1136 :
1137 0 : return 0;
1138 :
1139 : }
1140 :
1141 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1142 0 : krb5_ret_stringnl(krb5_storage *sp,
1143 : char **string)
1144 : {
1145 0 : int expect_nl = 0;
1146 0 : char c;
1147 0 : char *s = NULL;
1148 0 : size_t len = 0;
1149 0 : ssize_t ret;
1150 :
1151 0 : while((ret = sp->fetch(sp, &c, 1)) == 1){
1152 0 : krb5_error_code eret;
1153 0 : char *tmp;
1154 :
1155 0 : if (c == '\r') {
1156 0 : expect_nl = 1;
1157 0 : continue;
1158 : }
1159 0 : if (expect_nl && c != '\n') {
1160 0 : free(s);
1161 0 : return KRB5_BADMSGTYPE;
1162 : }
1163 :
1164 0 : len++;
1165 0 : eret = size_too_large(sp, len);
1166 0 : if (eret) {
1167 0 : free(s);
1168 0 : return eret;
1169 : }
1170 0 : tmp = realloc (s, len);
1171 0 : if (tmp == NULL) {
1172 0 : free (s);
1173 0 : return ENOMEM;
1174 : }
1175 0 : s = tmp;
1176 0 : if(c == '\n') {
1177 0 : s[len - 1] = '\0';
1178 0 : break;
1179 : }
1180 0 : s[len - 1] = c;
1181 : }
1182 0 : if(ret != 1){
1183 0 : free(s);
1184 0 : if(ret == 0)
1185 0 : return sp->eof_code;
1186 0 : return ret;
1187 : }
1188 0 : *string = s;
1189 0 : return 0;
1190 : }
1191 :
1192 : /**
1193 : * Write a principal block to storage.
1194 : *
1195 : * @param sp the storage buffer to write to
1196 : * @param p the principal block to write.
1197 : *
1198 : * @return 0 on success, a Kerberos 5 error code on failure.
1199 : *
1200 : * @ingroup krb5_storage
1201 : */
1202 :
1203 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1204 4258 : krb5_store_principal(krb5_storage *sp,
1205 : krb5_const_principal p)
1206 : {
1207 0 : size_t i;
1208 0 : int ret;
1209 :
1210 4258 : if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) {
1211 4258 : ret = krb5_store_int32(sp, p->name.name_type);
1212 4258 : if(ret) return ret;
1213 : }
1214 4258 : if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
1215 0 : ret = krb5_store_int32(sp, p->name.name_string.len + 1);
1216 : else
1217 4258 : ret = krb5_store_int32(sp, p->name.name_string.len);
1218 :
1219 4258 : if(ret) return ret;
1220 4258 : ret = krb5_store_string(sp, p->realm);
1221 4258 : if(ret) return ret;
1222 10710 : for(i = 0; i < p->name.name_string.len; i++){
1223 6452 : ret = krb5_store_string(sp, p->name.name_string.val[i]);
1224 6452 : if(ret) return ret;
1225 : }
1226 4258 : return 0;
1227 : }
1228 :
1229 : /**
1230 : * Parse principal from the storage.
1231 : *
1232 : * @param sp the storage buffer to read from
1233 : * @param princ the parsed principal
1234 : *
1235 : * @return 0 on success, a Kerberos 5 error code on failure.
1236 : *
1237 : * @ingroup krb5_storage
1238 : */
1239 :
1240 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1241 68196 : krb5_ret_principal(krb5_storage *sp,
1242 : krb5_principal *princ)
1243 : {
1244 0 : int i;
1245 0 : int ret;
1246 0 : krb5_principal p;
1247 0 : int32_t type;
1248 0 : int32_t ncomp;
1249 :
1250 68196 : p = calloc(1, sizeof(*p));
1251 68196 : if(p == NULL)
1252 0 : return ENOMEM;
1253 :
1254 68196 : if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE))
1255 0 : type = KRB5_NT_UNKNOWN;
1256 68196 : else if((ret = krb5_ret_int32(sp, &type))){
1257 1915 : free(p);
1258 1915 : return ret;
1259 : }
1260 66281 : if((ret = krb5_ret_int32(sp, &ncomp))){
1261 0 : free(p);
1262 0 : return ret;
1263 : }
1264 66281 : if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
1265 0 : ncomp--;
1266 66281 : if (ncomp < 0) {
1267 0 : free(p);
1268 0 : return EINVAL;
1269 : }
1270 66281 : ret = size_too_large_num(sp, ncomp, sizeof(p->name.name_string.val[0]));
1271 66281 : if (ret) {
1272 0 : free(p);
1273 0 : return ret;
1274 : }
1275 66281 : p->name.name_type = type;
1276 66281 : p->name.name_string.len = ncomp;
1277 66281 : ret = krb5_ret_string(sp, &p->realm);
1278 66281 : if(ret) {
1279 0 : free(p);
1280 0 : return ret;
1281 : }
1282 66281 : p->name.name_string.val = calloc(ncomp, sizeof(p->name.name_string.val[0]));
1283 66281 : if(p->name.name_string.val == NULL && ncomp != 0){
1284 0 : free(p->realm);
1285 0 : free(p);
1286 0 : return ENOMEM;
1287 : }
1288 163491 : for(i = 0; i < ncomp; i++){
1289 97210 : ret = krb5_ret_string(sp, &p->name.name_string.val[i]);
1290 97210 : if(ret) {
1291 0 : while (i >= 0)
1292 0 : free(p->name.name_string.val[i--]);
1293 0 : free(p->realm);
1294 0 : free(p);
1295 0 : return ret;
1296 : }
1297 : }
1298 66281 : *princ = p;
1299 66281 : return 0;
1300 : }
1301 :
1302 : /**
1303 : * Store a keyblock to the storage.
1304 : *
1305 : * @param sp the storage buffer to write to
1306 : * @param p the keyblock to write
1307 : *
1308 : * @return 0 on success, a Kerberos 5 error code on failure.
1309 : *
1310 : * @ingroup krb5_storage
1311 : */
1312 :
1313 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1314 74397 : krb5_store_keyblock(krb5_storage *sp, krb5_keyblock p)
1315 : {
1316 978 : int ret;
1317 74397 : ret = krb5_store_int16(sp, p.keytype);
1318 74397 : if(ret) return ret;
1319 :
1320 74397 : if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
1321 : /* this should really be enctype, but it is the same as
1322 : keytype nowadays */
1323 0 : ret = krb5_store_int16(sp, p.keytype);
1324 0 : if(ret) return ret;
1325 : }
1326 :
1327 74397 : ret = krb5_store_data(sp, p.keyvalue);
1328 74397 : return ret;
1329 : }
1330 :
1331 : /**
1332 : * Read a keyblock from the storage.
1333 : *
1334 : * @param sp the storage buffer to write to
1335 : * @param p the keyblock read from storage, free using krb5_free_keyblock()
1336 : *
1337 : * @return 0 on success, a Kerberos 5 error code on failure.
1338 : *
1339 : * @ingroup krb5_storage
1340 : */
1341 :
1342 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1343 102314 : krb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p)
1344 : {
1345 978 : int ret;
1346 978 : int16_t tmp;
1347 :
1348 102314 : ret = krb5_ret_int16(sp, &tmp);
1349 102314 : if(ret) return ret;
1350 102314 : p->keytype = tmp;
1351 :
1352 102314 : if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
1353 0 : ret = krb5_ret_int16(sp, &tmp);
1354 0 : if(ret) return ret;
1355 : }
1356 :
1357 102314 : ret = krb5_ret_data(sp, &p->keyvalue);
1358 102314 : return ret;
1359 : }
1360 :
1361 : /**
1362 : * Write a times block to storage.
1363 : *
1364 : * @param sp the storage buffer to write to
1365 : * @param times the times block to write.
1366 : *
1367 : * @return 0 on success, a Kerberos 5 error code on failure.
1368 : *
1369 : * @ingroup krb5_storage
1370 : */
1371 :
1372 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1373 1897 : krb5_store_times(krb5_storage *sp, krb5_times times)
1374 : {
1375 0 : int ret;
1376 1897 : ret = krb5_store_int32(sp, times.authtime);
1377 1897 : if(ret) return ret;
1378 1897 : ret = krb5_store_int32(sp, times.starttime);
1379 1897 : if(ret) return ret;
1380 1897 : ret = krb5_store_int32(sp, times.endtime);
1381 1897 : if(ret) return ret;
1382 1897 : ret = krb5_store_int32(sp, times.renew_till);
1383 1897 : return ret;
1384 : }
1385 :
1386 : /**
1387 : * Read a times block from the storage.
1388 : *
1389 : * @param sp the storage buffer to write to
1390 : * @param times the times block read from storage
1391 : *
1392 : * @return 0 on success, a Kerberos 5 error code on failure.
1393 : *
1394 : * @ingroup krb5_storage
1395 : */
1396 :
1397 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1398 29814 : krb5_ret_times(krb5_storage *sp, krb5_times *times)
1399 : {
1400 0 : int ret;
1401 0 : int32_t tmp;
1402 :
1403 29814 : ret = krb5_ret_int32(sp, &tmp);
1404 29814 : if (ret) return ret;
1405 29814 : times->authtime = tmp;
1406 29814 : ret = krb5_ret_int32(sp, &tmp);
1407 29814 : if (ret) return ret;
1408 29814 : times->starttime = tmp;
1409 29814 : ret = krb5_ret_int32(sp, &tmp);
1410 29814 : if (ret) return ret;
1411 29814 : times->endtime = tmp;
1412 29814 : ret = krb5_ret_int32(sp, &tmp);
1413 29814 : if (ret) return ret;
1414 29814 : times->renew_till = tmp;
1415 29814 : return ret;
1416 : }
1417 :
1418 : /**
1419 : * Write a address block to storage.
1420 : *
1421 : * @param sp the storage buffer to write to
1422 : * @param p the address 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_address(krb5_storage *sp, krb5_address p)
1431 : {
1432 0 : int ret;
1433 0 : ret = krb5_store_int16(sp, p.addr_type);
1434 0 : if(ret) return ret;
1435 0 : ret = krb5_store_data(sp, p.address);
1436 0 : return ret;
1437 : }
1438 :
1439 : /**
1440 : * Read a address block from the storage.
1441 : *
1442 : * @param sp the storage buffer to write to
1443 : * @param adr the address block read from storage
1444 : *
1445 : * @return 0 on success, a Kerberos 5 error code on failure.
1446 : *
1447 : * @ingroup krb5_storage
1448 : */
1449 :
1450 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1451 0 : krb5_ret_address(krb5_storage *sp, krb5_address *adr)
1452 : {
1453 0 : int16_t t;
1454 0 : int ret;
1455 0 : ret = krb5_ret_int16(sp, &t);
1456 0 : if(ret) return ret;
1457 0 : adr->addr_type = t;
1458 0 : ret = krb5_ret_data(sp, &adr->address);
1459 0 : return ret;
1460 : }
1461 :
1462 : /**
1463 : * Write a addresses block to storage.
1464 : *
1465 : * @param sp the storage buffer to write to
1466 : * @param p the addresses block to write.
1467 : *
1468 : * @return 0 on success, a Kerberos 5 error code on failure.
1469 : *
1470 : * @ingroup krb5_storage
1471 : */
1472 :
1473 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1474 1897 : krb5_store_addrs(krb5_storage *sp, krb5_addresses p)
1475 : {
1476 0 : size_t i;
1477 0 : int ret;
1478 1897 : ret = krb5_store_int32(sp, p.len);
1479 1897 : if(ret) return ret;
1480 1897 : for(i = 0; i<p.len; i++){
1481 0 : ret = krb5_store_address(sp, p.val[i]);
1482 0 : if(ret) break;
1483 : }
1484 1897 : return ret;
1485 : }
1486 :
1487 : /**
1488 : * Read a addresses block from the storage.
1489 : *
1490 : * @param sp the storage buffer to write to
1491 : * @param adr the addresses block read from storage
1492 : *
1493 : * @return 0 on success, a Kerberos 5 error code on failure.
1494 : *
1495 : * @ingroup krb5_storage
1496 : */
1497 :
1498 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1499 29814 : krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr)
1500 : {
1501 0 : size_t i;
1502 0 : int ret;
1503 0 : int32_t tmp;
1504 :
1505 29814 : ret = krb5_ret_int32(sp, &tmp);
1506 29814 : if(ret) return ret;
1507 29814 : ret = size_too_large_num(sp, tmp, sizeof(adr->val[0]));
1508 29814 : if (ret) return ret;
1509 29814 : adr->len = tmp;
1510 29814 : ALLOC(adr->val, adr->len);
1511 29814 : if (adr->val == NULL && adr->len != 0)
1512 0 : return ENOMEM;
1513 29814 : for(i = 0; i < adr->len; i++){
1514 0 : ret = krb5_ret_address(sp, &adr->val[i]);
1515 0 : if(ret) break;
1516 : }
1517 29814 : return ret;
1518 : }
1519 :
1520 : /**
1521 : * Write a auth data block to storage.
1522 : *
1523 : * @param sp the storage buffer to write to
1524 : * @param auth the auth data block to write.
1525 : *
1526 : * @return 0 on success, a Kerberos 5 error code on failure.
1527 : *
1528 : * @ingroup krb5_storage
1529 : */
1530 :
1531 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1532 1897 : krb5_store_authdata(krb5_storage *sp, krb5_authdata auth)
1533 : {
1534 0 : krb5_error_code ret;
1535 0 : size_t i;
1536 1897 : ret = krb5_store_int32(sp, auth.len);
1537 1897 : if(ret) return ret;
1538 1897 : for(i = 0; i < auth.len; i++){
1539 0 : ret = krb5_store_int16(sp, auth.val[i].ad_type);
1540 0 : if(ret) break;
1541 0 : ret = krb5_store_data(sp, auth.val[i].ad_data);
1542 0 : if(ret) break;
1543 : }
1544 1897 : return 0;
1545 : }
1546 :
1547 : /**
1548 : * Read a auth data from the storage.
1549 : *
1550 : * @param sp the storage buffer to write to
1551 : * @param auth the auth data block read from storage
1552 : *
1553 : * @return 0 on success, a Kerberos 5 error code on failure.
1554 : *
1555 : * @ingroup krb5_storage
1556 : */
1557 :
1558 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1559 29814 : krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth)
1560 : {
1561 0 : krb5_error_code ret;
1562 0 : int32_t tmp;
1563 0 : int16_t tmp2;
1564 0 : int i;
1565 29814 : ret = krb5_ret_int32(sp, &tmp);
1566 29814 : if(ret) return ret;
1567 29814 : ret = size_too_large_num(sp, tmp, sizeof(auth->val[0]));
1568 29814 : if (ret) return ret;
1569 29814 : ALLOC_SEQ(auth, tmp);
1570 29814 : if (auth->val == NULL && tmp != 0)
1571 0 : return ENOMEM;
1572 29814 : for(i = 0; i < tmp; i++){
1573 0 : ret = krb5_ret_int16(sp, &tmp2);
1574 0 : if(ret) break;
1575 0 : auth->val[i].ad_type = tmp2;
1576 0 : ret = krb5_ret_data(sp, &auth->val[i].ad_data);
1577 0 : if(ret) break;
1578 : }
1579 29814 : return ret;
1580 : }
1581 :
1582 : static int32_t
1583 31711 : bitswap32(int32_t b)
1584 : {
1585 31711 : int32_t r = 0;
1586 0 : int i;
1587 1046463 : for (i = 0; i < 32; i++) {
1588 1014752 : r = r << 1 | (b & 1);
1589 1014752 : b = b >> 1;
1590 : }
1591 31711 : return r;
1592 : }
1593 :
1594 : /**
1595 : * Write a credentials block to storage.
1596 : *
1597 : * @param sp the storage buffer to write to
1598 : * @param creds the creds block to write.
1599 : *
1600 : * @return 0 on success, a Kerberos 5 error code on failure.
1601 : *
1602 : * @ingroup krb5_storage
1603 : */
1604 :
1605 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1606 1897 : krb5_store_creds(krb5_storage *sp, krb5_creds *creds)
1607 : {
1608 0 : int ret;
1609 :
1610 1897 : ret = krb5_store_principal(sp, creds->client);
1611 1897 : if(ret)
1612 0 : return ret;
1613 1897 : ret = krb5_store_principal(sp, creds->server);
1614 1897 : if(ret)
1615 0 : return ret;
1616 1897 : ret = krb5_store_keyblock(sp, creds->session);
1617 1897 : if(ret)
1618 0 : return ret;
1619 1897 : ret = krb5_store_times(sp, creds->times);
1620 1897 : if(ret)
1621 0 : return ret;
1622 1897 : ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
1623 1897 : if(ret)
1624 0 : return ret;
1625 1897 : ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
1626 1897 : if(ret)
1627 0 : return ret;
1628 1897 : ret = krb5_store_addrs(sp, creds->addresses);
1629 1897 : if(ret)
1630 0 : return ret;
1631 1897 : ret = krb5_store_authdata(sp, creds->authdata);
1632 1897 : if(ret)
1633 0 : return ret;
1634 1897 : ret = krb5_store_data(sp, creds->ticket);
1635 1897 : if(ret)
1636 0 : return ret;
1637 1897 : ret = krb5_store_data(sp, creds->second_ticket);
1638 1897 : return ret;
1639 : }
1640 :
1641 : /**
1642 : * Read a credentials block from the storage.
1643 : *
1644 : * @param sp the storage buffer to write to
1645 : * @param creds the credentials block read from storage
1646 : *
1647 : * @return 0 on success, a Kerberos 5 error code on failure.
1648 : *
1649 : * @ingroup krb5_storage
1650 : */
1651 :
1652 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1653 31729 : krb5_ret_creds(krb5_storage *sp, krb5_creds *creds)
1654 : {
1655 0 : krb5_error_code ret;
1656 0 : int8_t dummy8;
1657 0 : int32_t dummy32;
1658 :
1659 31729 : memset(creds, 0, sizeof(*creds));
1660 31729 : ret = krb5_ret_principal (sp, &creds->client);
1661 31729 : if(ret) goto cleanup;
1662 29814 : ret = krb5_ret_principal (sp, &creds->server);
1663 29814 : if(ret) goto cleanup;
1664 29814 : ret = krb5_ret_keyblock (sp, &creds->session);
1665 29814 : if(ret) goto cleanup;
1666 29814 : ret = krb5_ret_times (sp, &creds->times);
1667 29814 : if(ret) goto cleanup;
1668 29814 : ret = krb5_ret_int8 (sp, &dummy8);
1669 29814 : if(ret) goto cleanup;
1670 29814 : ret = krb5_ret_int32 (sp, &dummy32);
1671 29814 : if(ret) goto cleanup;
1672 29814 : creds->flags.b = int2TicketFlags(bitswap32(dummy32));
1673 29814 : ret = krb5_ret_addrs (sp, &creds->addresses);
1674 29814 : if(ret) goto cleanup;
1675 29814 : ret = krb5_ret_authdata (sp, &creds->authdata);
1676 29814 : if(ret) goto cleanup;
1677 29814 : ret = krb5_ret_data (sp, &creds->ticket);
1678 29814 : if(ret) goto cleanup;
1679 29814 : ret = krb5_ret_data (sp, &creds->second_ticket);
1680 31729 : cleanup:
1681 0 : if(ret) {
1682 : #if 0
1683 : krb5_free_cred_contents(context, creds); /* XXX */
1684 : #endif
1685 0 : }
1686 31729 : return ret;
1687 : }
1688 :
1689 : #define SC_CLIENT_PRINCIPAL 0x0001
1690 : #define SC_SERVER_PRINCIPAL 0x0002
1691 : #define SC_SESSION_KEY 0x0004
1692 : #define SC_TICKET 0x0008
1693 : #define SC_SECOND_TICKET 0x0010
1694 : #define SC_AUTHDATA 0x0020
1695 : #define SC_ADDRESSES 0x0040
1696 :
1697 : /**
1698 : * Write a tagged credentials block to storage.
1699 : *
1700 : * @param sp the storage buffer to write to
1701 : * @param creds the creds block to write.
1702 : *
1703 : * @return 0 on success, a Kerberos 5 error code on failure.
1704 : *
1705 : * @ingroup krb5_storage
1706 : */
1707 :
1708 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1709 0 : krb5_store_creds_tag(krb5_storage *sp, krb5_creds *creds)
1710 : {
1711 0 : int ret;
1712 0 : int32_t header = 0;
1713 :
1714 0 : if (creds->client)
1715 0 : header |= SC_CLIENT_PRINCIPAL;
1716 0 : if (creds->server)
1717 0 : header |= SC_SERVER_PRINCIPAL;
1718 0 : if (creds->session.keytype != ETYPE_NULL)
1719 0 : header |= SC_SESSION_KEY;
1720 0 : if (creds->ticket.data)
1721 0 : header |= SC_TICKET;
1722 0 : if (creds->second_ticket.length)
1723 0 : header |= SC_SECOND_TICKET;
1724 0 : if (creds->authdata.len)
1725 0 : header |= SC_AUTHDATA;
1726 0 : if (creds->addresses.len)
1727 0 : header |= SC_ADDRESSES;
1728 :
1729 0 : ret = krb5_store_int32(sp, header);
1730 0 : if (ret)
1731 0 : return ret;
1732 :
1733 0 : if (creds->client) {
1734 0 : ret = krb5_store_principal(sp, creds->client);
1735 0 : if(ret)
1736 0 : return ret;
1737 : }
1738 :
1739 0 : if (creds->server) {
1740 0 : ret = krb5_store_principal(sp, creds->server);
1741 0 : if(ret)
1742 0 : return ret;
1743 : }
1744 :
1745 0 : if (creds->session.keytype != ETYPE_NULL) {
1746 0 : ret = krb5_store_keyblock(sp, creds->session);
1747 0 : if(ret)
1748 0 : return ret;
1749 : }
1750 :
1751 0 : ret = krb5_store_times(sp, creds->times);
1752 0 : if(ret)
1753 0 : return ret;
1754 0 : ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
1755 0 : if(ret)
1756 0 : return ret;
1757 :
1758 0 : ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
1759 0 : if(ret)
1760 0 : return ret;
1761 :
1762 0 : if (creds->addresses.len) {
1763 0 : ret = krb5_store_addrs(sp, creds->addresses);
1764 0 : if(ret)
1765 0 : return ret;
1766 : }
1767 :
1768 0 : if (creds->authdata.len) {
1769 0 : ret = krb5_store_authdata(sp, creds->authdata);
1770 0 : if(ret)
1771 0 : return ret;
1772 : }
1773 :
1774 0 : if (creds->ticket.data) {
1775 0 : ret = krb5_store_data(sp, creds->ticket);
1776 0 : if(ret)
1777 0 : return ret;
1778 : }
1779 :
1780 0 : if (creds->second_ticket.data) {
1781 0 : ret = krb5_store_data(sp, creds->second_ticket);
1782 0 : if (ret)
1783 0 : return ret;
1784 : }
1785 :
1786 0 : return ret;
1787 : }
1788 :
1789 : /**
1790 : * Read a tagged credentials block from the storage.
1791 : *
1792 : * @param sp the storage buffer to write to
1793 : * @param creds the credentials block read from storage
1794 : *
1795 : * @return 0 on success, a Kerberos 5 error code on failure.
1796 : *
1797 : * @ingroup krb5_storage
1798 : */
1799 :
1800 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1801 0 : krb5_ret_creds_tag(krb5_storage *sp,
1802 : krb5_creds *creds)
1803 : {
1804 0 : krb5_error_code ret;
1805 0 : int8_t dummy8;
1806 0 : int32_t dummy32, header;
1807 :
1808 0 : memset(creds, 0, sizeof(*creds));
1809 :
1810 0 : ret = krb5_ret_int32 (sp, &header);
1811 0 : if (ret) goto cleanup;
1812 :
1813 0 : if (header & SC_CLIENT_PRINCIPAL) {
1814 0 : ret = krb5_ret_principal (sp, &creds->client);
1815 0 : if(ret) goto cleanup;
1816 : }
1817 0 : if (header & SC_SERVER_PRINCIPAL) {
1818 0 : ret = krb5_ret_principal (sp, &creds->server);
1819 0 : if(ret) goto cleanup;
1820 : }
1821 0 : if (header & SC_SESSION_KEY) {
1822 0 : ret = krb5_ret_keyblock (sp, &creds->session);
1823 0 : if(ret) goto cleanup;
1824 : }
1825 0 : ret = krb5_ret_times (sp, &creds->times);
1826 0 : if(ret) goto cleanup;
1827 0 : ret = krb5_ret_int8 (sp, &dummy8);
1828 0 : if(ret) goto cleanup;
1829 0 : ret = krb5_ret_int32 (sp, &dummy32);
1830 0 : if(ret) goto cleanup;
1831 0 : creds->flags.b = int2TicketFlags(bitswap32(dummy32));
1832 0 : if (header & SC_ADDRESSES) {
1833 0 : ret = krb5_ret_addrs (sp, &creds->addresses);
1834 0 : if(ret) goto cleanup;
1835 : }
1836 0 : if (header & SC_AUTHDATA) {
1837 0 : ret = krb5_ret_authdata (sp, &creds->authdata);
1838 0 : if(ret) goto cleanup;
1839 : }
1840 0 : if (header & SC_TICKET) {
1841 0 : ret = krb5_ret_data (sp, &creds->ticket);
1842 0 : if(ret) goto cleanup;
1843 : }
1844 0 : if (header & SC_SECOND_TICKET) {
1845 0 : ret = krb5_ret_data (sp, &creds->second_ticket);
1846 0 : if(ret) goto cleanup;
1847 : }
1848 :
1849 0 : cleanup:
1850 0 : if(ret) {
1851 : #if 0
1852 : krb5_free_cred_contents(context, creds); /* XXX */
1853 : #endif
1854 0 : }
1855 0 : return ret;
1856 : }
1857 :
1858 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1859 415804 : _krb5_ret_data_at_offset(krb5_storage *sp,
1860 : size_t offset,
1861 : size_t length,
1862 : krb5_data *data)
1863 : {
1864 10156 : krb5_error_code ret;
1865 10156 : off_t cur, size;
1866 :
1867 415804 : krb5_data_zero(data);
1868 :
1869 415804 : cur = sp->seek(sp, 0, SEEK_CUR);
1870 415804 : if (cur < 0)
1871 0 : return HEIM_ERR_NOT_SEEKABLE;
1872 :
1873 415804 : size = sp->seek(sp, 0, SEEK_END);
1874 415804 : if (offset + length > size) {
1875 0 : ret = ERANGE;
1876 0 : goto cleanup;
1877 : }
1878 :
1879 415804 : ret = krb5_data_alloc(data, length);
1880 415804 : if (ret)
1881 0 : goto cleanup;
1882 :
1883 415804 : if (length) {
1884 415804 : sp->seek(sp, offset, SEEK_SET);
1885 :
1886 415804 : size = sp->fetch(sp, data->data, length);
1887 415804 : if (size < 0 || (size_t)size != length)
1888 0 : return sp->eof_code;
1889 : }
1890 :
1891 415804 : cleanup:
1892 415804 : sp->seek(sp, cur, SEEK_SET);
1893 :
1894 415804 : return ret;
1895 : }
1896 :
1897 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1898 311853 : _krb5_ret_utf8_from_ucs2le_at_offset(krb5_storage *sp,
1899 : off_t offset,
1900 : size_t length,
1901 : char **utf8)
1902 : {
1903 7617 : krb5_error_code ret;
1904 7617 : krb5_data data;
1905 311853 : size_t ucs2len = length / 2;
1906 311853 : uint16_t *ucs2 = NULL;
1907 7617 : size_t u8len;
1908 311853 : unsigned int flags = WIND_RW_LE;
1909 :
1910 311853 : *utf8 = NULL;
1911 :
1912 311853 : krb5_data_zero(&data);
1913 :
1914 311853 : ret = _krb5_ret_data_at_offset(sp, offset, length, &data);
1915 311853 : if (ret)
1916 0 : goto out;
1917 :
1918 311853 : ucs2 = malloc(sizeof(ucs2[0]) * ucs2len);
1919 311853 : if (ucs2 == NULL) {
1920 0 : ret = ENOMEM;
1921 0 : goto out;
1922 : }
1923 :
1924 311853 : ret = wind_ucs2read(data.data, data.length, &flags, ucs2, &ucs2len);
1925 311853 : if (ret)
1926 0 : goto out;
1927 :
1928 311853 : ret = wind_ucs2utf8_length(ucs2, ucs2len, &u8len);
1929 311853 : if (ret)
1930 0 : goto out;
1931 :
1932 311853 : u8len += 1; /* Add space for NUL */
1933 :
1934 311853 : *utf8 = malloc(u8len);
1935 311853 : if (*utf8 == NULL) {
1936 0 : ret = ENOMEM;
1937 0 : goto out;
1938 : }
1939 :
1940 311853 : ret = wind_ucs2utf8(ucs2, ucs2len, *utf8, &u8len);
1941 311853 : if (ret)
1942 0 : goto out;
1943 :
1944 311853 : out:
1945 311853 : if (ret && *utf8) {
1946 0 : free(*utf8);
1947 0 : *utf8 = NULL;
1948 : }
1949 311853 : free(ucs2);
1950 311853 : krb5_data_free(&data);
1951 :
1952 311853 : return ret;
1953 : }
1954 :
1955 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1956 0 : _krb5_store_data_at_offset(krb5_storage *sp,
1957 : size_t offset,
1958 : const krb5_data *data)
1959 : {
1960 0 : krb5_error_code ret;
1961 0 : krb5_ssize_t nbytes;
1962 0 : off_t pos;
1963 :
1964 0 : if (offset == (size_t)-1) {
1965 0 : if (data == NULL || data->data == NULL) {
1966 0 : offset = 0;
1967 : } else {
1968 0 : pos = sp->seek(sp, 0, SEEK_CUR);
1969 0 : offset = sp->seek(sp, 0, SEEK_END);
1970 0 : sp->seek(sp, pos, SEEK_SET);
1971 :
1972 0 : if (offset == (size_t)-1)
1973 0 : return HEIM_ERR_NOT_SEEKABLE;
1974 : }
1975 : }
1976 :
1977 0 : if (offset > 0xFFFF)
1978 0 : return ERANGE;
1979 0 : else if ((offset != 0) != (data && data->data))
1980 0 : return EINVAL;
1981 0 : else if (data && data->length > 0xFFFF)
1982 0 : return ERANGE;
1983 :
1984 0 : ret = krb5_store_uint16(sp, data ? (uint16_t)data->length : 0);
1985 0 : if (ret == 0)
1986 0 : ret = krb5_store_uint16(sp, (uint16_t)offset);
1987 0 : if (ret == 0 && offset) {
1988 0 : pos = sp->seek(sp, 0, SEEK_CUR);
1989 0 : sp->seek(sp, offset, SEEK_SET);
1990 0 : nbytes = krb5_storage_write(sp, data->data, data->length);
1991 0 : if ((size_t)nbytes != data->length)
1992 0 : ret = sp->eof_code;
1993 0 : sp->seek(sp, pos, SEEK_SET);
1994 : }
1995 :
1996 0 : return ret;
1997 : }
1998 :
1999 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
2000 0 : _krb5_store_utf8_as_ucs2le_at_offset(krb5_storage *sp,
2001 : off_t offset,
2002 : const char *utf8)
2003 : {
2004 0 : krb5_error_code ret;
2005 0 : size_t ucs2_len, ucs2le_size;
2006 0 : uint16_t *ucs2, *ucs2le;
2007 0 : unsigned int flags;
2008 :
2009 0 : if (utf8) {
2010 0 : ret = wind_utf8ucs2_length(utf8, &ucs2_len);
2011 0 : if (ret)
2012 0 : return ret;
2013 :
2014 0 : ucs2 = malloc(sizeof(ucs2[0]) * ucs2_len);
2015 0 : if (ucs2 == NULL)
2016 0 : return ENOMEM;
2017 :
2018 0 : ret = wind_utf8ucs2(utf8, ucs2, &ucs2_len);
2019 0 : if (ret) {
2020 0 : free(ucs2);
2021 0 : return ret;
2022 : }
2023 :
2024 0 : ucs2le_size = (ucs2_len + 1) * 2;
2025 0 : ucs2le = malloc(ucs2le_size);
2026 0 : if (ucs2le == NULL) {
2027 0 : free(ucs2);
2028 0 : return ENOMEM;
2029 : }
2030 :
2031 0 : flags = WIND_RW_LE;
2032 0 : ret = wind_ucs2write(ucs2, ucs2_len, &flags, ucs2le, &ucs2le_size);
2033 0 : free(ucs2);
2034 0 : if (ret) {
2035 0 : free(ucs2le);
2036 0 : return ret;
2037 : }
2038 :
2039 0 : ucs2le_size = ucs2_len * 2;
2040 : } else {
2041 0 : ucs2le = NULL;
2042 0 : ucs2le_size = 0;
2043 0 : offset = 0;
2044 : }
2045 :
2046 : {
2047 0 : krb5_data data;
2048 :
2049 0 : data.data = ucs2le;
2050 0 : data.length = ucs2le_size;
2051 :
2052 0 : ret = _krb5_store_data_at_offset(sp, offset, &data);
2053 : }
2054 :
2055 0 : free(ucs2le);
2056 :
2057 0 : return ret;
2058 : }
|