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 631606 : krb5_storage_set_flags(krb5_storage *sp, krb5_flags flags)
55 : {
56 631606 : sp->flags |= flags;
57 631606 : }
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 9443336 : krb5_storage_is_flags(krb5_storage *sp, krb5_flags flags)
88 : {
89 9443336 : 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 860509 : size_too_large(krb5_storage *sp, size_t size)
141 : {
142 860509 : if (sp->max_alloc && sp->max_alloc < size)
143 0 : return HEIM_ERR_TOO_BIG;
144 860509 : return 0;
145 : }
146 :
147 : static krb5_error_code
148 118334 : size_too_large_num(krb5_storage *sp, size_t count, size_t size)
149 : {
150 118334 : if (sp->max_alloc == 0 || size == 0)
151 0 : return 0;
152 118334 : size = sp->max_alloc / size;
153 118334 : if (size < count)
154 0 : return HEIM_ERR_TOO_BIG;
155 118334 : 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 602498 : krb5_storage_seek(krb5_storage *sp, off_t offset, int whence)
173 : {
174 602498 : 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 1247 : krb5_storage_truncate(krb5_storage *sp, off_t offset)
190 : {
191 1247 : 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 1461 : krb5_storage_fsync(krb5_storage *sp)
207 : {
208 1461 : if (sp->fsync != NULL)
209 1461 : 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 757150 : krb5_storage_read(krb5_storage *sp, void *buf, size_t len)
227 : {
228 757150 : 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 752289 : krb5_storage_write(krb5_storage *sp, const void *buf, size_t len)
245 : {
246 752289 : 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 52212 : krb5_storage_set_eof_code(krb5_storage *sp, int code)
260 : {
261 52212 : sp->eof_code = code;
262 52212 : }
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 977458 : krb5_storage_free(krb5_storage *sp)
292 : {
293 977458 : if (sp == NULL)
294 0 : return 0;
295 977458 : if(sp->free)
296 381501 : (*sp->free)(sp);
297 977458 : free(sp->data);
298 977458 : free(sp);
299 977458 : 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 329896 : krb5_storage_to_data(krb5_storage *sp, krb5_data *data)
315 : {
316 : off_t pos, size;
317 : krb5_error_code ret;
318 :
319 329896 : pos = sp->seek(sp, 0, SEEK_CUR);
320 329896 : if (pos < 0)
321 0 : return HEIM_ERR_NOT_SEEKABLE;
322 329896 : size = sp->seek(sp, 0, SEEK_END);
323 329896 : ret = size_too_large(sp, size);
324 329896 : if (ret)
325 0 : return ret;
326 329896 : ret = krb5_data_alloc(data, size);
327 329896 : if (ret) {
328 0 : sp->seek(sp, pos, SEEK_SET);
329 0 : return ret;
330 : }
331 329896 : if (size) {
332 329896 : sp->seek(sp, 0, SEEK_SET);
333 329896 : sp->fetch(sp, data->data, data->length);
334 329896 : sp->seek(sp, pos, SEEK_SET);
335 : }
336 329896 : 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 1986391 : krb5_store_int(krb5_storage *sp,
405 : int64_t value,
406 : size_t len)
407 : {
408 : int ret;
409 1986391 : uint8_t v[9], *p = v;
410 :
411 1986391 : if (len > sizeof(value))
412 0 : return EINVAL;
413 :
414 1986391 : 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 1986391 : _krb5_put_int(v, value, len);
422 1986391 : ret = sp->store(sp, p, len);
423 1986391 : if (ret < 0)
424 0 : return errno;
425 1986391 : if ((size_t)ret != len)
426 0 : return sp->eof_code;
427 1986391 : 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 1473289 : krb5_store_int32(krb5_storage *sp,
444 : int32_t value)
445 : {
446 1473289 : if(BYTEORDER_IS_HOST(sp))
447 0 : value = htonl(value);
448 1473289 : else if(BYTEORDER_IS_LE(sp))
449 1114088 : value = bswap32(value);
450 1473289 : 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 378414 : krb5_store_int64(krb5_storage *sp,
467 : int64_t value)
468 : {
469 378414 : if (BYTEORDER_IS_HOST(sp))
470 : #ifdef WORDS_BIGENDIAN
471 : ;
472 : #else
473 0 : value = bswap64(value); /* There's no ntohll() */
474 : #endif
475 378414 : else if (BYTEORDER_IS_LE(sp))
476 378414 : value = bswap64(value);
477 378414 : 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 1114876 : krb5_store_uint32(krb5_storage *sp,
494 : uint32_t value)
495 : {
496 1114876 : 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 378414 : krb5_store_uint64(krb5_storage *sp,
513 : uint64_t value)
514 : {
515 378414 : return krb5_store_int64(sp, (int64_t)value);
516 : }
517 :
518 : static krb5_error_code
519 6867885 : krb5_ret_int(krb5_storage *sp,
520 : int64_t *value,
521 : size_t len)
522 : {
523 : int ret;
524 : unsigned char v[9];
525 6867885 : uint64_t w = 0;
526 6867885 : *value = 0; /* quiets warnings */
527 6867885 : 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 6867885 : ret = sp->fetch(sp, v, len);
547 6867885 : if (ret < 0)
548 0 : return errno;
549 6867885 : if ((size_t)ret != len)
550 26610 : return sp->eof_code;
551 6841275 : _krb5_get_int64(v, &w, len);
552 6841275 : *value = w;
553 6841275 : 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 893009 : krb5_ret_int64(krb5_storage *sp,
570 : int64_t *value)
571 : {
572 893009 : krb5_error_code ret = krb5_ret_int(sp, value, 8);
573 893009 : if(ret)
574 0 : return ret;
575 893009 : if(BYTEORDER_IS_HOST(sp))
576 : #ifdef WORDS_BIGENDIAN
577 : ;
578 : #else
579 0 : *value = bswap64(*value); /* There's no ntohll() */
580 : #endif
581 893009 : else if(BYTEORDER_IS_LE(sp))
582 893009 : *value = bswap64(*value);
583 893009 : 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 893009 : krb5_ret_uint64(krb5_storage *sp,
600 : uint64_t *value)
601 : {
602 : krb5_error_code ret;
603 : int64_t v;
604 :
605 893009 : ret = krb5_ret_int64(sp, &v);
606 893009 : if (ret == 0)
607 893009 : *value = (uint64_t)v;
608 :
609 893009 : 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 4219739 : krb5_ret_int32(krb5_storage *sp,
626 : int32_t *value)
627 : {
628 : int64_t v;
629 :
630 4219739 : krb5_error_code ret = krb5_ret_int(sp, &v, 4);
631 4219739 : if (ret)
632 26610 : return ret;
633 4193129 : *value = v;
634 4193129 : if (BYTEORDER_IS_HOST(sp))
635 0 : *value = htonl(*value);
636 4193129 : else if (BYTEORDER_IS_LE(sp))
637 2442107 : *value = bswap32(*value);
638 4193129 : 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 2790288 : krb5_ret_uint32(krb5_storage *sp, uint32_t *value)
655 : {
656 : krb5_error_code ret;
657 : int32_t v;
658 :
659 2790288 : ret = krb5_ret_int32(sp, &v);
660 2790288 : if (ret == 0)
661 2790288 : *value = (uint32_t)v;
662 :
663 2790288 : 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 134688 : krb5_store_int16(krb5_storage *sp,
680 : int16_t value)
681 : {
682 134688 : if(BYTEORDER_IS_HOST(sp))
683 0 : value = htons(value);
684 134688 : else if(BYTEORDER_IS_LE(sp))
685 60401 : value = bswap16(value);
686 134688 : 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 60401 : krb5_store_uint16(krb5_storage *sp,
703 : uint16_t value)
704 : {
705 60401 : 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 1755137 : krb5_ret_int16(krb5_storage *sp,
722 : int16_t *value)
723 : {
724 : int64_t v;
725 : int ret;
726 1755137 : ret = krb5_ret_int(sp, &v, 2);
727 1755137 : if(ret)
728 0 : return ret;
729 1755137 : *value = v;
730 1755137 : if(BYTEORDER_IS_HOST(sp))
731 0 : *value = htons(*value);
732 1755137 : else if(BYTEORDER_IS_LE(sp))
733 738458 : *value = bswap16(*value);
734 1755137 : 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 738458 : krb5_ret_uint16(krb5_storage *sp,
751 : uint16_t *value)
752 : {
753 : krb5_error_code ret;
754 : int16_t v;
755 :
756 738458 : ret = krb5_ret_int16(sp, &v);
757 738458 : if (ret == 0)
758 738458 : *value = (uint16_t)v;
759 :
760 738458 : 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 3307 : krb5_store_int8(krb5_storage *sp,
776 : int8_t value)
777 : {
778 : int ret;
779 :
780 3307 : ret = sp->store(sp, &value, sizeof(value));
781 3307 : if (ret != sizeof(value))
782 0 : return (ret<0)?errno:sp->eof_code;
783 3307 : 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 293650 : krb5_ret_int8(krb5_storage *sp,
817 : int8_t *value)
818 : {
819 : int ret;
820 :
821 293650 : ret = sp->fetch(sp, value, sizeof(*value));
822 293650 : if (ret != sizeof(*value))
823 0 : return (ret<0)?errno:sp->eof_code;
824 293650 : 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 285552 : krb5_store_data(krb5_storage *sp,
866 : krb5_data data)
867 : {
868 : int ret;
869 285552 : ret = krb5_store_int32(sp, data.length);
870 285552 : if(ret < 0)
871 0 : return ret;
872 285552 : ret = sp->store(sp, data.data, data.length);
873 285552 : if(ret < 0)
874 0 : return errno;
875 285552 : if((size_t)ret != data.length)
876 0 : return sp->eof_code;
877 285552 : 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 554446 : krb5_ret_data(krb5_storage *sp,
938 : krb5_data *data)
939 : {
940 : int ret;
941 : int32_t size;
942 :
943 554446 : ret = krb5_ret_int32(sp, &size);
944 554446 : if(ret)
945 23833 : return ret;
946 530613 : ret = size_too_large(sp, size);
947 530613 : if (ret)
948 0 : return ret;
949 530613 : ret = krb5_data_alloc (data, size);
950 530613 : if (ret)
951 0 : return ret;
952 530613 : if (size) {
953 428966 : ret = sp->fetch(sp, data->data, size);
954 428966 : if(ret != size) {
955 0 : krb5_data_free(data);
956 0 : return (ret < 0)? errno : sp->eof_code;
957 : }
958 : }
959 530613 : 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 188262 : krb5_store_string(krb5_storage *sp, const char *s)
976 : {
977 : krb5_data data;
978 :
979 188262 : if (s == NULL)
980 0 : return EINVAL;
981 :
982 188262 : data.length = strlen(s);
983 188262 : data.data = rk_UNCONST(s);
984 188262 : 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 332785 : krb5_ret_string(krb5_storage *sp,
1001 : char **string)
1002 : {
1003 : int ret;
1004 : krb5_data data;
1005 :
1006 332785 : *string = NULL;
1007 332785 : ret = krb5_ret_data(sp, &data);
1008 332785 : if(ret)
1009 0 : return ret;
1010 332785 : *string = realloc(data.data, data.length + 1);
1011 332785 : if(*string == NULL){
1012 0 : free(data.data);
1013 0 : return ENOMEM;
1014 : }
1015 332785 : (*string)[data.length] = 0;
1016 332785 : return 0;
1017 : }
1018 :
1019 : /**
1020 : * Store a zero terminated string to the buffer. The data is stored
1021 : * one character at a time until a NUL is stored.
1022 : *
1023 : * @param sp the storage buffer to write to
1024 : * @param s the string to store.
1025 : *
1026 : * @return 0 on success, a Kerberos 5 error code on failure.
1027 : *
1028 : * @ingroup krb5_storage
1029 : */
1030 :
1031 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1032 0 : krb5_store_stringz(krb5_storage *sp, const char *s)
1033 : {
1034 : size_t len;
1035 : ssize_t ret;
1036 :
1037 0 : if (s == NULL)
1038 0 : return EINVAL;
1039 :
1040 0 : len = strlen(s) + 1;
1041 0 : ret = sp->store(sp, s, len);
1042 0 : if(ret < 0)
1043 0 : return ret;
1044 0 : if((size_t)ret != len)
1045 0 : return sp->eof_code;
1046 0 : return 0;
1047 : }
1048 :
1049 : /**
1050 : * Parse zero terminated string from the storage.
1051 : *
1052 : * @param sp the storage buffer to read from
1053 : * @param string the parsed string
1054 : *
1055 : * @return 0 on success, a Kerberos 5 error code on failure.
1056 : *
1057 : * @ingroup krb5_storage
1058 : */
1059 :
1060 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1061 0 : krb5_ret_stringz(krb5_storage *sp,
1062 : char **string)
1063 : {
1064 : char c;
1065 0 : char *s = NULL;
1066 0 : size_t len = 0;
1067 : ssize_t ret;
1068 :
1069 0 : while((ret = sp->fetch(sp, &c, 1)) == 1){
1070 : krb5_error_code eret;
1071 : char *tmp;
1072 :
1073 0 : len++;
1074 0 : eret = size_too_large(sp, len);
1075 0 : if (eret) {
1076 0 : free(s);
1077 0 : return eret;
1078 : }
1079 0 : tmp = realloc (s, len);
1080 0 : if (tmp == NULL) {
1081 0 : free (s);
1082 0 : return ENOMEM;
1083 : }
1084 0 : s = tmp;
1085 0 : s[len - 1] = c;
1086 0 : if(c == 0)
1087 0 : break;
1088 : }
1089 0 : if(ret != 1){
1090 0 : free(s);
1091 0 : if(ret == 0)
1092 0 : return sp->eof_code;
1093 0 : return ret;
1094 : }
1095 0 : *string = s;
1096 0 : return 0;
1097 : }
1098 :
1099 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1100 0 : krb5_store_stringnl(krb5_storage *sp, const char *s)
1101 : {
1102 : size_t len;
1103 : ssize_t ret;
1104 :
1105 0 : if (s == NULL)
1106 0 : return EINVAL;
1107 :
1108 0 : len = strlen(s);
1109 0 : ret = sp->store(sp, s, len);
1110 0 : if(ret < 0)
1111 0 : return ret;
1112 0 : if((size_t)ret != len)
1113 0 : return sp->eof_code;
1114 0 : ret = sp->store(sp, "\n", 1);
1115 0 : if(ret != 1) {
1116 0 : if(ret < 0)
1117 0 : return ret;
1118 : else
1119 0 : return sp->eof_code;
1120 : }
1121 :
1122 0 : return 0;
1123 :
1124 : }
1125 :
1126 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1127 0 : krb5_ret_stringnl(krb5_storage *sp,
1128 : char **string)
1129 : {
1130 0 : int expect_nl = 0;
1131 : char c;
1132 0 : char *s = NULL;
1133 0 : size_t len = 0;
1134 : ssize_t ret;
1135 :
1136 0 : while((ret = sp->fetch(sp, &c, 1)) == 1){
1137 : krb5_error_code eret;
1138 : char *tmp;
1139 :
1140 0 : if (c == '\r') {
1141 0 : expect_nl = 1;
1142 0 : continue;
1143 : }
1144 0 : if (expect_nl && c != '\n') {
1145 0 : free(s);
1146 0 : return KRB5_BADMSGTYPE;
1147 : }
1148 :
1149 0 : len++;
1150 0 : eret = size_too_large(sp, len);
1151 0 : if (eret) {
1152 0 : free(s);
1153 0 : return eret;
1154 : }
1155 0 : tmp = realloc (s, len);
1156 0 : if (tmp == NULL) {
1157 0 : free (s);
1158 0 : return ENOMEM;
1159 : }
1160 0 : s = tmp;
1161 0 : if(c == '\n') {
1162 0 : s[len - 1] = '\0';
1163 0 : break;
1164 : }
1165 0 : s[len - 1] = c;
1166 : }
1167 0 : if(ret != 1){
1168 0 : free(s);
1169 0 : if(ret == 0)
1170 0 : return sp->eof_code;
1171 0 : return ret;
1172 : }
1173 0 : *string = s;
1174 0 : return 0;
1175 : }
1176 :
1177 : /**
1178 : * Write a principal block to storage.
1179 : *
1180 : * @param sp the storage buffer to write to
1181 : * @param p the principal block to write.
1182 : *
1183 : * @return 0 on success, a Kerberos 5 error code on failure.
1184 : *
1185 : * @ingroup krb5_storage
1186 : */
1187 :
1188 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1189 2812 : krb5_store_principal(krb5_storage *sp,
1190 : krb5_const_principal p)
1191 : {
1192 : size_t i;
1193 : int ret;
1194 :
1195 2812 : if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) {
1196 2812 : ret = krb5_store_int32(sp, p->name.name_type);
1197 2812 : if(ret) return ret;
1198 : }
1199 2812 : if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
1200 0 : ret = krb5_store_int32(sp, p->name.name_string.len + 1);
1201 : else
1202 2812 : ret = krb5_store_int32(sp, p->name.name_string.len);
1203 :
1204 2812 : if(ret) return ret;
1205 2812 : ret = krb5_store_string(sp, p->realm);
1206 2812 : if(ret) return ret;
1207 7041 : for(i = 0; i < p->name.name_string.len; i++){
1208 4229 : ret = krb5_store_string(sp, p->name.name_string.val[i]);
1209 4229 : if(ret) return ret;
1210 : }
1211 2812 : return 0;
1212 : }
1213 :
1214 : /**
1215 : * Parse principal from the storage.
1216 : *
1217 : * @param sp the storage buffer to read from
1218 : * @param princ the parsed principal
1219 : *
1220 : * @return 0 on success, a Kerberos 5 error code on failure.
1221 : *
1222 : * @ingroup krb5_storage
1223 : */
1224 :
1225 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1226 62414 : krb5_ret_principal(krb5_storage *sp,
1227 : krb5_principal *princ)
1228 : {
1229 : int i;
1230 : int ret;
1231 : krb5_principal p;
1232 : int32_t type;
1233 : int32_t ncomp;
1234 :
1235 62414 : p = calloc(1, sizeof(*p));
1236 62414 : if(p == NULL)
1237 0 : return ENOMEM;
1238 :
1239 62414 : if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE))
1240 0 : type = KRB5_NT_UNKNOWN;
1241 62414 : else if((ret = krb5_ret_int32(sp, &type))){
1242 1120 : free(p);
1243 1120 : return ret;
1244 : }
1245 61294 : if((ret = krb5_ret_int32(sp, &ncomp))){
1246 0 : free(p);
1247 0 : return ret;
1248 : }
1249 61294 : if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
1250 0 : ncomp--;
1251 61294 : if (ncomp < 0) {
1252 0 : free(p);
1253 0 : return EINVAL;
1254 : }
1255 61294 : ret = size_too_large_num(sp, ncomp, sizeof(p->name.name_string.val[0]));
1256 61294 : if (ret) {
1257 0 : free(p);
1258 0 : return ret;
1259 : }
1260 61294 : p->name.name_type = type;
1261 61294 : p->name.name_string.len = ncomp;
1262 61294 : ret = krb5_ret_string(sp, &p->realm);
1263 61294 : if(ret) {
1264 0 : free(p);
1265 0 : return ret;
1266 : }
1267 61294 : p->name.name_string.val = calloc(ncomp, sizeof(p->name.name_string.val[0]));
1268 61294 : if(p->name.name_string.val == NULL && ncomp != 0){
1269 0 : free(p->realm);
1270 0 : free(p);
1271 0 : return ENOMEM;
1272 : }
1273 151564 : for(i = 0; i < ncomp; i++){
1274 90270 : ret = krb5_ret_string(sp, &p->name.name_string.val[i]);
1275 90270 : if(ret) {
1276 0 : while (i >= 0)
1277 0 : free(p->name.name_string.val[i--]);
1278 0 : free(p->realm);
1279 0 : free(p);
1280 0 : return ret;
1281 : }
1282 : }
1283 61294 : *princ = p;
1284 61294 : return 0;
1285 : }
1286 :
1287 : /**
1288 : * Store a keyblock to the storage.
1289 : *
1290 : * @param sp the storage buffer to write to
1291 : * @param p the keyblock to write
1292 : *
1293 : * @return 0 on success, a Kerberos 5 error code on failure.
1294 : *
1295 : * @ingroup krb5_storage
1296 : */
1297 :
1298 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1299 65946 : krb5_store_keyblock(krb5_storage *sp, krb5_keyblock p)
1300 : {
1301 : int ret;
1302 65946 : ret = krb5_store_int16(sp, p.keytype);
1303 65946 : if(ret) return ret;
1304 :
1305 65946 : if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
1306 : /* this should really be enctype, but it is the same as
1307 : keytype nowadays */
1308 0 : ret = krb5_store_int16(sp, p.keytype);
1309 0 : if(ret) return ret;
1310 : }
1311 :
1312 65946 : ret = krb5_store_data(sp, p.keyvalue);
1313 65946 : return ret;
1314 : }
1315 :
1316 : /**
1317 : * Read a keyblock from the storage.
1318 : *
1319 : * @param sp the storage buffer to write to
1320 : * @param p the keyblock read from storage, free using krb5_free_keyblock()
1321 : *
1322 : * @return 0 on success, a Kerberos 5 error code on failure.
1323 : *
1324 : * @ingroup krb5_storage
1325 : */
1326 :
1327 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1328 93122 : krb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p)
1329 : {
1330 : int ret;
1331 : int16_t tmp;
1332 :
1333 93122 : ret = krb5_ret_int16(sp, &tmp);
1334 93122 : if(ret) return ret;
1335 93122 : p->keytype = tmp;
1336 :
1337 93122 : if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
1338 0 : ret = krb5_ret_int16(sp, &tmp);
1339 0 : if(ret) return ret;
1340 : }
1341 :
1342 93122 : ret = krb5_ret_data(sp, &p->keyvalue);
1343 93122 : return ret;
1344 : }
1345 :
1346 : /**
1347 : * Write a times block to storage.
1348 : *
1349 : * @param sp the storage buffer to write to
1350 : * @param times the times block to write.
1351 : *
1352 : * @return 0 on success, a Kerberos 5 error code on failure.
1353 : *
1354 : * @ingroup krb5_storage
1355 : */
1356 :
1357 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1358 1344 : krb5_store_times(krb5_storage *sp, krb5_times times)
1359 : {
1360 : int ret;
1361 1344 : ret = krb5_store_int32(sp, times.authtime);
1362 1344 : if(ret) return ret;
1363 1344 : ret = krb5_store_int32(sp, times.starttime);
1364 1344 : if(ret) return ret;
1365 1344 : ret = krb5_store_int32(sp, times.endtime);
1366 1344 : if(ret) return ret;
1367 1344 : ret = krb5_store_int32(sp, times.renew_till);
1368 1344 : return ret;
1369 : }
1370 :
1371 : /**
1372 : * Read a times block from the storage.
1373 : *
1374 : * @param sp the storage buffer to write to
1375 : * @param times the times block read from storage
1376 : *
1377 : * @return 0 on success, a Kerberos 5 error code on failure.
1378 : *
1379 : * @ingroup krb5_storage
1380 : */
1381 :
1382 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1383 28520 : krb5_ret_times(krb5_storage *sp, krb5_times *times)
1384 : {
1385 : int ret;
1386 : int32_t tmp;
1387 :
1388 28520 : ret = krb5_ret_int32(sp, &tmp);
1389 28520 : if (ret) return ret;
1390 28520 : times->authtime = tmp;
1391 28520 : ret = krb5_ret_int32(sp, &tmp);
1392 28520 : if (ret) return ret;
1393 28520 : times->starttime = tmp;
1394 28520 : ret = krb5_ret_int32(sp, &tmp);
1395 28520 : if (ret) return ret;
1396 28520 : times->endtime = tmp;
1397 28520 : ret = krb5_ret_int32(sp, &tmp);
1398 28520 : if (ret) return ret;
1399 28520 : times->renew_till = tmp;
1400 28520 : return ret;
1401 : }
1402 :
1403 : /**
1404 : * Write a address block to storage.
1405 : *
1406 : * @param sp the storage buffer to write to
1407 : * @param p the address block to write.
1408 : *
1409 : * @return 0 on success, a Kerberos 5 error code on failure.
1410 : *
1411 : * @ingroup krb5_storage
1412 : */
1413 :
1414 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1415 0 : krb5_store_address(krb5_storage *sp, krb5_address p)
1416 : {
1417 : int ret;
1418 0 : ret = krb5_store_int16(sp, p.addr_type);
1419 0 : if(ret) return ret;
1420 0 : ret = krb5_store_data(sp, p.address);
1421 0 : return ret;
1422 : }
1423 :
1424 : /**
1425 : * Read a address block from the storage.
1426 : *
1427 : * @param sp the storage buffer to write to
1428 : * @param adr the address block read from storage
1429 : *
1430 : * @return 0 on success, a Kerberos 5 error code on failure.
1431 : *
1432 : * @ingroup krb5_storage
1433 : */
1434 :
1435 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1436 0 : krb5_ret_address(krb5_storage *sp, krb5_address *adr)
1437 : {
1438 : int16_t t;
1439 : int ret;
1440 0 : ret = krb5_ret_int16(sp, &t);
1441 0 : if(ret) return ret;
1442 0 : adr->addr_type = t;
1443 0 : ret = krb5_ret_data(sp, &adr->address);
1444 0 : return ret;
1445 : }
1446 :
1447 : /**
1448 : * Write a addresses block to storage.
1449 : *
1450 : * @param sp the storage buffer to write to
1451 : * @param p the addresses block to write.
1452 : *
1453 : * @return 0 on success, a Kerberos 5 error code on failure.
1454 : *
1455 : * @ingroup krb5_storage
1456 : */
1457 :
1458 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1459 1344 : krb5_store_addrs(krb5_storage *sp, krb5_addresses p)
1460 : {
1461 : size_t i;
1462 : int ret;
1463 1344 : ret = krb5_store_int32(sp, p.len);
1464 1344 : if(ret) return ret;
1465 1344 : for(i = 0; i<p.len; i++){
1466 0 : ret = krb5_store_address(sp, p.val[i]);
1467 0 : if(ret) break;
1468 : }
1469 1344 : return ret;
1470 : }
1471 :
1472 : /**
1473 : * Read a addresses block from the storage.
1474 : *
1475 : * @param sp the storage buffer to write to
1476 : * @param adr the addresses block read from storage
1477 : *
1478 : * @return 0 on success, a Kerberos 5 error code on failure.
1479 : *
1480 : * @ingroup krb5_storage
1481 : */
1482 :
1483 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1484 28520 : krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr)
1485 : {
1486 : size_t i;
1487 : int ret;
1488 : int32_t tmp;
1489 :
1490 28520 : ret = krb5_ret_int32(sp, &tmp);
1491 28520 : if(ret) return ret;
1492 28520 : ret = size_too_large_num(sp, tmp, sizeof(adr->val[0]));
1493 28520 : if (ret) return ret;
1494 28520 : adr->len = tmp;
1495 28520 : ALLOC(adr->val, adr->len);
1496 28520 : if (adr->val == NULL && adr->len != 0)
1497 0 : return ENOMEM;
1498 28520 : for(i = 0; i < adr->len; i++){
1499 0 : ret = krb5_ret_address(sp, &adr->val[i]);
1500 0 : if(ret) break;
1501 : }
1502 28520 : return ret;
1503 : }
1504 :
1505 : /**
1506 : * Write a auth data block to storage.
1507 : *
1508 : * @param sp the storage buffer to write to
1509 : * @param auth the auth data block to write.
1510 : *
1511 : * @return 0 on success, a Kerberos 5 error code on failure.
1512 : *
1513 : * @ingroup krb5_storage
1514 : */
1515 :
1516 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1517 1344 : krb5_store_authdata(krb5_storage *sp, krb5_authdata auth)
1518 : {
1519 : krb5_error_code ret;
1520 : size_t i;
1521 1344 : ret = krb5_store_int32(sp, auth.len);
1522 1344 : if(ret) return ret;
1523 1344 : for(i = 0; i < auth.len; i++){
1524 0 : ret = krb5_store_int16(sp, auth.val[i].ad_type);
1525 0 : if(ret) break;
1526 0 : ret = krb5_store_data(sp, auth.val[i].ad_data);
1527 0 : if(ret) break;
1528 : }
1529 1344 : return 0;
1530 : }
1531 :
1532 : /**
1533 : * Read a auth data from the storage.
1534 : *
1535 : * @param sp the storage buffer to write to
1536 : * @param auth the auth data block read from storage
1537 : *
1538 : * @return 0 on success, a Kerberos 5 error code on failure.
1539 : *
1540 : * @ingroup krb5_storage
1541 : */
1542 :
1543 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1544 28520 : krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth)
1545 : {
1546 : krb5_error_code ret;
1547 : int32_t tmp;
1548 : int16_t tmp2;
1549 : int i;
1550 28520 : ret = krb5_ret_int32(sp, &tmp);
1551 28520 : if(ret) return ret;
1552 28520 : ret = size_too_large_num(sp, tmp, sizeof(auth->val[0]));
1553 28520 : if (ret) return ret;
1554 28520 : ALLOC_SEQ(auth, tmp);
1555 28520 : if (auth->val == NULL && tmp != 0)
1556 0 : return ENOMEM;
1557 28520 : for(i = 0; i < tmp; i++){
1558 0 : ret = krb5_ret_int16(sp, &tmp2);
1559 0 : if(ret) break;
1560 0 : auth->val[i].ad_type = tmp2;
1561 0 : ret = krb5_ret_data(sp, &auth->val[i].ad_data);
1562 0 : if(ret) break;
1563 : }
1564 28520 : return ret;
1565 : }
1566 :
1567 : static int32_t
1568 29864 : bitswap32(int32_t b)
1569 : {
1570 29864 : int32_t r = 0;
1571 : int i;
1572 985512 : for (i = 0; i < 32; i++) {
1573 955648 : r = r << 1 | (b & 1);
1574 955648 : b = b >> 1;
1575 : }
1576 29864 : return r;
1577 : }
1578 :
1579 : /**
1580 : * Write a credentials block to storage.
1581 : *
1582 : * @param sp the storage buffer to write to
1583 : * @param creds the creds block to write.
1584 : *
1585 : * @return 0 on success, a Kerberos 5 error code on failure.
1586 : *
1587 : * @ingroup krb5_storage
1588 : */
1589 :
1590 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1591 1344 : krb5_store_creds(krb5_storage *sp, krb5_creds *creds)
1592 : {
1593 : int ret;
1594 :
1595 1344 : ret = krb5_store_principal(sp, creds->client);
1596 1344 : if(ret)
1597 0 : return ret;
1598 1344 : ret = krb5_store_principal(sp, creds->server);
1599 1344 : if(ret)
1600 0 : return ret;
1601 1344 : ret = krb5_store_keyblock(sp, creds->session);
1602 1344 : if(ret)
1603 0 : return ret;
1604 1344 : ret = krb5_store_times(sp, creds->times);
1605 1344 : if(ret)
1606 0 : return ret;
1607 1344 : ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
1608 1344 : if(ret)
1609 0 : return ret;
1610 1344 : ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
1611 1344 : if(ret)
1612 0 : return ret;
1613 1344 : ret = krb5_store_addrs(sp, creds->addresses);
1614 1344 : if(ret)
1615 0 : return ret;
1616 1344 : ret = krb5_store_authdata(sp, creds->authdata);
1617 1344 : if(ret)
1618 0 : return ret;
1619 1344 : ret = krb5_store_data(sp, creds->ticket);
1620 1344 : if(ret)
1621 0 : return ret;
1622 1344 : ret = krb5_store_data(sp, creds->second_ticket);
1623 1344 : return ret;
1624 : }
1625 :
1626 : /**
1627 : * Read a credentials block from the storage.
1628 : *
1629 : * @param sp the storage buffer to write to
1630 : * @param creds the credentials block read from storage
1631 : *
1632 : * @return 0 on success, a Kerberos 5 error code on failure.
1633 : *
1634 : * @ingroup krb5_storage
1635 : */
1636 :
1637 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1638 29640 : krb5_ret_creds(krb5_storage *sp, krb5_creds *creds)
1639 : {
1640 : krb5_error_code ret;
1641 : int8_t dummy8;
1642 : int32_t dummy32;
1643 :
1644 29640 : memset(creds, 0, sizeof(*creds));
1645 29640 : ret = krb5_ret_principal (sp, &creds->client);
1646 29640 : if(ret) goto cleanup;
1647 28520 : ret = krb5_ret_principal (sp, &creds->server);
1648 28520 : if(ret) goto cleanup;
1649 28520 : ret = krb5_ret_keyblock (sp, &creds->session);
1650 28520 : if(ret) goto cleanup;
1651 28520 : ret = krb5_ret_times (sp, &creds->times);
1652 28520 : if(ret) goto cleanup;
1653 28520 : ret = krb5_ret_int8 (sp, &dummy8);
1654 28520 : if(ret) goto cleanup;
1655 28520 : ret = krb5_ret_int32 (sp, &dummy32);
1656 28520 : if(ret) goto cleanup;
1657 28520 : creds->flags.b = int2TicketFlags(bitswap32(dummy32));
1658 28520 : ret = krb5_ret_addrs (sp, &creds->addresses);
1659 28520 : if(ret) goto cleanup;
1660 28520 : ret = krb5_ret_authdata (sp, &creds->authdata);
1661 28520 : if(ret) goto cleanup;
1662 28520 : ret = krb5_ret_data (sp, &creds->ticket);
1663 28520 : if(ret) goto cleanup;
1664 28520 : ret = krb5_ret_data (sp, &creds->second_ticket);
1665 29640 : cleanup:
1666 : if(ret) {
1667 : #if 0
1668 : krb5_free_cred_contents(context, creds); /* XXX */
1669 : #endif
1670 : }
1671 29640 : return ret;
1672 : }
1673 :
1674 : #define SC_CLIENT_PRINCIPAL 0x0001
1675 : #define SC_SERVER_PRINCIPAL 0x0002
1676 : #define SC_SESSION_KEY 0x0004
1677 : #define SC_TICKET 0x0008
1678 : #define SC_SECOND_TICKET 0x0010
1679 : #define SC_AUTHDATA 0x0020
1680 : #define SC_ADDRESSES 0x0040
1681 :
1682 : /**
1683 : * Write a tagged credentials block to storage.
1684 : *
1685 : * @param sp the storage buffer to write to
1686 : * @param creds the creds block to write.
1687 : *
1688 : * @return 0 on success, a Kerberos 5 error code on failure.
1689 : *
1690 : * @ingroup krb5_storage
1691 : */
1692 :
1693 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1694 0 : krb5_store_creds_tag(krb5_storage *sp, krb5_creds *creds)
1695 : {
1696 : int ret;
1697 0 : int32_t header = 0;
1698 :
1699 0 : if (creds->client)
1700 0 : header |= SC_CLIENT_PRINCIPAL;
1701 0 : if (creds->server)
1702 0 : header |= SC_SERVER_PRINCIPAL;
1703 0 : if (creds->session.keytype != ETYPE_NULL)
1704 0 : header |= SC_SESSION_KEY;
1705 0 : if (creds->ticket.data)
1706 0 : header |= SC_TICKET;
1707 0 : if (creds->second_ticket.length)
1708 0 : header |= SC_SECOND_TICKET;
1709 0 : if (creds->authdata.len)
1710 0 : header |= SC_AUTHDATA;
1711 0 : if (creds->addresses.len)
1712 0 : header |= SC_ADDRESSES;
1713 :
1714 0 : ret = krb5_store_int32(sp, header);
1715 0 : if (ret)
1716 0 : return ret;
1717 :
1718 0 : if (creds->client) {
1719 0 : ret = krb5_store_principal(sp, creds->client);
1720 0 : if(ret)
1721 0 : return ret;
1722 : }
1723 :
1724 0 : if (creds->server) {
1725 0 : ret = krb5_store_principal(sp, creds->server);
1726 0 : if(ret)
1727 0 : return ret;
1728 : }
1729 :
1730 0 : if (creds->session.keytype != ETYPE_NULL) {
1731 0 : ret = krb5_store_keyblock(sp, creds->session);
1732 0 : if(ret)
1733 0 : return ret;
1734 : }
1735 :
1736 0 : ret = krb5_store_times(sp, creds->times);
1737 0 : if(ret)
1738 0 : return ret;
1739 0 : ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
1740 0 : if(ret)
1741 0 : return ret;
1742 :
1743 0 : ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
1744 0 : if(ret)
1745 0 : return ret;
1746 :
1747 0 : if (creds->addresses.len) {
1748 0 : ret = krb5_store_addrs(sp, creds->addresses);
1749 0 : if(ret)
1750 0 : return ret;
1751 : }
1752 :
1753 0 : if (creds->authdata.len) {
1754 0 : ret = krb5_store_authdata(sp, creds->authdata);
1755 0 : if(ret)
1756 0 : return ret;
1757 : }
1758 :
1759 0 : if (creds->ticket.data) {
1760 0 : ret = krb5_store_data(sp, creds->ticket);
1761 0 : if(ret)
1762 0 : return ret;
1763 : }
1764 :
1765 0 : if (creds->second_ticket.data) {
1766 0 : ret = krb5_store_data(sp, creds->second_ticket);
1767 0 : if (ret)
1768 0 : return ret;
1769 : }
1770 :
1771 0 : return ret;
1772 : }
1773 :
1774 : /**
1775 : * Read a tagged credentials block from the storage.
1776 : *
1777 : * @param sp the storage buffer to write to
1778 : * @param creds the credentials block read from storage
1779 : *
1780 : * @return 0 on success, a Kerberos 5 error code on failure.
1781 : *
1782 : * @ingroup krb5_storage
1783 : */
1784 :
1785 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1786 0 : krb5_ret_creds_tag(krb5_storage *sp,
1787 : krb5_creds *creds)
1788 : {
1789 : krb5_error_code ret;
1790 : int8_t dummy8;
1791 : int32_t dummy32, header;
1792 :
1793 0 : memset(creds, 0, sizeof(*creds));
1794 :
1795 0 : ret = krb5_ret_int32 (sp, &header);
1796 0 : if (ret) goto cleanup;
1797 :
1798 0 : if (header & SC_CLIENT_PRINCIPAL) {
1799 0 : ret = krb5_ret_principal (sp, &creds->client);
1800 0 : if(ret) goto cleanup;
1801 : }
1802 0 : if (header & SC_SERVER_PRINCIPAL) {
1803 0 : ret = krb5_ret_principal (sp, &creds->server);
1804 0 : if(ret) goto cleanup;
1805 : }
1806 0 : if (header & SC_SESSION_KEY) {
1807 0 : ret = krb5_ret_keyblock (sp, &creds->session);
1808 0 : if(ret) goto cleanup;
1809 : }
1810 0 : ret = krb5_ret_times (sp, &creds->times);
1811 0 : if(ret) goto cleanup;
1812 0 : ret = krb5_ret_int8 (sp, &dummy8);
1813 0 : if(ret) goto cleanup;
1814 0 : ret = krb5_ret_int32 (sp, &dummy32);
1815 0 : if(ret) goto cleanup;
1816 0 : creds->flags.b = int2TicketFlags(bitswap32(dummy32));
1817 0 : if (header & SC_ADDRESSES) {
1818 0 : ret = krb5_ret_addrs (sp, &creds->addresses);
1819 0 : if(ret) goto cleanup;
1820 : }
1821 0 : if (header & SC_AUTHDATA) {
1822 0 : ret = krb5_ret_authdata (sp, &creds->authdata);
1823 0 : if(ret) goto cleanup;
1824 : }
1825 0 : if (header & SC_TICKET) {
1826 0 : ret = krb5_ret_data (sp, &creds->ticket);
1827 0 : if(ret) goto cleanup;
1828 : }
1829 0 : if (header & SC_SECOND_TICKET) {
1830 0 : ret = krb5_ret_data (sp, &creds->second_ticket);
1831 0 : if(ret) goto cleanup;
1832 : }
1833 :
1834 0 : cleanup:
1835 : if(ret) {
1836 : #if 0
1837 : krb5_free_cred_contents(context, creds); /* XXX */
1838 : #endif
1839 : }
1840 0 : return ret;
1841 : }
1842 :
1843 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1844 328176 : _krb5_ret_data_at_offset(krb5_storage *sp,
1845 : size_t offset,
1846 : size_t length,
1847 : krb5_data *data)
1848 : {
1849 : krb5_error_code ret;
1850 : off_t cur, size;
1851 :
1852 328176 : krb5_data_zero(data);
1853 :
1854 328176 : cur = sp->seek(sp, 0, SEEK_CUR);
1855 328176 : if (cur < 0)
1856 0 : return HEIM_ERR_NOT_SEEKABLE;
1857 :
1858 328176 : size = sp->seek(sp, 0, SEEK_END);
1859 328176 : if (offset + length > size) {
1860 0 : ret = ERANGE;
1861 0 : goto cleanup;
1862 : }
1863 :
1864 328176 : ret = krb5_data_alloc(data, length);
1865 328176 : if (ret)
1866 0 : goto cleanup;
1867 :
1868 328176 : if (length) {
1869 328176 : sp->seek(sp, offset, SEEK_SET);
1870 :
1871 328176 : size = sp->fetch(sp, data->data, length);
1872 328176 : heim_assert(size == length, "incomplete buffer fetched");
1873 : }
1874 :
1875 328176 : cleanup:
1876 328176 : sp->seek(sp, cur, SEEK_SET);
1877 :
1878 328176 : return ret;
1879 : }
1880 :
1881 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1882 246132 : _krb5_ret_utf8_from_ucs2le_at_offset(krb5_storage *sp,
1883 : off_t offset,
1884 : size_t length,
1885 : char **utf8)
1886 : {
1887 : krb5_error_code ret;
1888 : krb5_data data;
1889 246132 : size_t ucs2len = length / 2;
1890 246132 : uint16_t *ucs2 = NULL;
1891 : size_t u8len;
1892 246132 : unsigned int flags = WIND_RW_LE;
1893 :
1894 246132 : *utf8 = NULL;
1895 :
1896 246132 : krb5_data_zero(&data);
1897 :
1898 246132 : ret = _krb5_ret_data_at_offset(sp, offset, length, &data);
1899 246132 : if (ret)
1900 0 : goto out;
1901 :
1902 246132 : ucs2 = malloc(sizeof(ucs2[0]) * ucs2len);
1903 246132 : if (ucs2 == NULL) {
1904 0 : ret = ENOMEM;
1905 0 : goto out;
1906 : }
1907 :
1908 246132 : ret = wind_ucs2read(data.data, data.length, &flags, ucs2, &ucs2len);
1909 246132 : if (ret)
1910 0 : goto out;
1911 :
1912 246132 : ret = wind_ucs2utf8_length(ucs2, ucs2len, &u8len);
1913 246132 : if (ret)
1914 0 : goto out;
1915 :
1916 246132 : u8len += 1; /* Add space for NUL */
1917 :
1918 246132 : *utf8 = malloc(u8len);
1919 246132 : if (*utf8 == NULL) {
1920 0 : ret = ENOMEM;
1921 0 : goto out;
1922 : }
1923 :
1924 246132 : ret = wind_ucs2utf8(ucs2, ucs2len, *utf8, &u8len);
1925 246132 : if (ret)
1926 0 : goto out;
1927 :
1928 246132 : out:
1929 246132 : if (ret && *utf8) {
1930 0 : free(*utf8);
1931 0 : *utf8 = NULL;
1932 : }
1933 246132 : free(ucs2);
1934 246132 : krb5_data_free(&data);
1935 :
1936 246132 : return ret;
1937 : }
1938 :
1939 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1940 0 : _krb5_store_data_at_offset(krb5_storage *sp,
1941 : size_t offset,
1942 : const krb5_data *data)
1943 : {
1944 : krb5_error_code ret;
1945 : krb5_ssize_t nbytes;
1946 : off_t pos;
1947 :
1948 0 : if (offset == (off_t)-1) {
1949 0 : if (data == NULL || data->data == NULL) {
1950 0 : offset = 0;
1951 : } else {
1952 0 : pos = sp->seek(sp, 0, SEEK_CUR);
1953 0 : offset = sp->seek(sp, 0, SEEK_END);
1954 0 : sp->seek(sp, pos, SEEK_SET);
1955 :
1956 0 : if (offset == (off_t)-1)
1957 0 : return HEIM_ERR_NOT_SEEKABLE;
1958 : }
1959 : }
1960 :
1961 0 : if (offset > 0xFFFF)
1962 0 : return ERANGE;
1963 0 : else if ((offset != 0) != (data && data->data))
1964 0 : return EINVAL;
1965 0 : else if (data && data->length > 0xFFFF)
1966 0 : return ERANGE;
1967 :
1968 0 : ret = krb5_store_uint16(sp, data ? (uint16_t)data->length : 0);
1969 0 : if (ret == 0)
1970 0 : ret = krb5_store_uint16(sp, (uint16_t)offset);
1971 0 : if (ret == 0 && offset) {
1972 0 : pos = sp->seek(sp, 0, SEEK_CUR);
1973 0 : sp->seek(sp, offset, SEEK_SET);
1974 0 : nbytes = krb5_storage_write(sp, data->data, data->length);
1975 0 : if ((size_t)nbytes != data->length)
1976 0 : ret = sp->eof_code;
1977 0 : sp->seek(sp, pos, SEEK_SET);
1978 : }
1979 :
1980 0 : return ret;
1981 : }
1982 :
1983 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
1984 0 : _krb5_store_utf8_as_ucs2le_at_offset(krb5_storage *sp,
1985 : off_t offset,
1986 : const char *utf8)
1987 : {
1988 : krb5_error_code ret;
1989 : size_t ucs2_len, ucs2le_size;
1990 : uint16_t *ucs2, *ucs2le;
1991 : unsigned int flags;
1992 :
1993 0 : if (utf8) {
1994 0 : ret = wind_utf8ucs2_length(utf8, &ucs2_len);
1995 0 : if (ret)
1996 0 : return ret;
1997 :
1998 0 : ucs2 = malloc(sizeof(ucs2[0]) * ucs2_len);
1999 0 : if (ucs2 == NULL)
2000 0 : return ENOMEM;
2001 :
2002 0 : ret = wind_utf8ucs2(utf8, ucs2, &ucs2_len);
2003 0 : if (ret) {
2004 0 : free(ucs2);
2005 0 : return ret;
2006 : }
2007 :
2008 0 : ucs2le_size = (ucs2_len + 1) * 2;
2009 0 : ucs2le = malloc(ucs2le_size);
2010 0 : if (ucs2le == NULL) {
2011 0 : free(ucs2);
2012 0 : return ENOMEM;
2013 : }
2014 :
2015 0 : flags = WIND_RW_LE;
2016 0 : ret = wind_ucs2write(ucs2, ucs2_len, &flags, ucs2le, &ucs2le_size);
2017 0 : free(ucs2);
2018 0 : if (ret) {
2019 0 : free(ucs2le);
2020 0 : return ret;
2021 : }
2022 :
2023 0 : ucs2le_size = ucs2_len * 2;
2024 : } else {
2025 0 : ucs2le = NULL;
2026 0 : ucs2le_size = 0;
2027 0 : offset = 0;
2028 0 : ret = 0;
2029 : }
2030 :
2031 : {
2032 : krb5_data data;
2033 :
2034 0 : data.data = ucs2le;
2035 0 : data.length = ucs2le_size;
2036 :
2037 0 : ret = _krb5_store_data_at_offset(sp, offset, &data);
2038 : }
2039 :
2040 0 : free(ucs2le);
2041 :
2042 0 : return ret;
2043 : }
|