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