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