1 /* $NetBSD: store.c,v 1.1.1.2 2014/04/24 12:45:51 pettai Exp $ */ 2 3 /* 4 * Copyright (c) 1997-2008 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include "krb5_locl.h" 37 #include "store-int.h" 38 39 #define BYTEORDER_IS(SP, V) (((SP)->flags & KRB5_STORAGE_BYTEORDER_MASK) == (V)) 40 #define BYTEORDER_IS_LE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_LE) 41 #define BYTEORDER_IS_BE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_BE) 42 #define BYTEORDER_IS_HOST(SP) (BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_HOST) || \ 43 krb5_storage_is_flags((SP), KRB5_STORAGE_HOST_BYTEORDER)) 44 45 /** 46 * Add the flags on a storage buffer by or-ing in the flags to the buffer. 47 * 48 * @param sp the storage buffer to set the flags on 49 * @param flags the flags to set 50 * 51 * @ingroup krb5_storage 52 */ 53 54 KRB5_LIB_FUNCTION void KRB5_LIB_CALL 55 krb5_storage_set_flags(krb5_storage *sp, krb5_flags flags) 56 { 57 sp->flags |= flags; 58 } 59 60 /** 61 * Clear the flags on a storage buffer 62 * 63 * @param sp the storage buffer to clear the flags on 64 * @param flags the flags to clear 65 * 66 * @ingroup krb5_storage 67 */ 68 69 KRB5_LIB_FUNCTION void KRB5_LIB_CALL 70 krb5_storage_clear_flags(krb5_storage *sp, krb5_flags flags) 71 { 72 sp->flags &= ~flags; 73 } 74 75 /** 76 * Return true or false depending on if the storage flags is set or 77 * not. NB testing for the flag 0 always return true. 78 * 79 * @param sp the storage buffer to check flags on 80 * @param flags The flags to test for 81 * 82 * @return true if all the flags are set, false if not. 83 * 84 * @ingroup krb5_storage 85 */ 86 87 KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL 88 krb5_storage_is_flags(krb5_storage *sp, krb5_flags flags) 89 { 90 return (sp->flags & flags) == flags; 91 } 92 93 /** 94 * Set the new byte order of the storage buffer. 95 * 96 * @param sp the storage buffer to set the byte order for. 97 * @param byteorder the new byte order. 98 * 99 * The byte order are: KRB5_STORAGE_BYTEORDER_BE, 100 * KRB5_STORAGE_BYTEORDER_LE and KRB5_STORAGE_BYTEORDER_HOST. 101 * 102 * @ingroup krb5_storage 103 */ 104 105 KRB5_LIB_FUNCTION void KRB5_LIB_CALL 106 krb5_storage_set_byteorder(krb5_storage *sp, krb5_flags byteorder) 107 { 108 sp->flags &= ~KRB5_STORAGE_BYTEORDER_MASK; 109 sp->flags |= byteorder; 110 } 111 112 /** 113 * Return the current byteorder for the buffer. See krb5_storage_set_byteorder() for the list or byte order contants. 114 * 115 * @ingroup krb5_storage 116 */ 117 118 KRB5_LIB_FUNCTION krb5_flags KRB5_LIB_CALL 119 krb5_storage_get_byteorder(krb5_storage *sp) 120 { 121 return sp->flags & KRB5_STORAGE_BYTEORDER_MASK; 122 } 123 124 /** 125 * Set the max alloc value 126 * 127 * @param sp the storage buffer set the max allow for 128 * @param size maximum size to allocate, use 0 to remove limit 129 * 130 * @ingroup krb5_storage 131 */ 132 133 KRB5_LIB_FUNCTION void KRB5_LIB_CALL 134 krb5_storage_set_max_alloc(krb5_storage *sp, size_t size) 135 { 136 sp->max_alloc = size; 137 } 138 139 /* don't allocate unresonable amount of memory */ 140 static krb5_error_code 141 size_too_large(krb5_storage *sp, size_t size) 142 { 143 if (sp->max_alloc && sp->max_alloc < size) 144 return HEIM_ERR_TOO_BIG; 145 return 0; 146 } 147 148 static krb5_error_code 149 size_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 172 KRB5_LIB_FUNCTION off_t KRB5_LIB_CALL 173 krb5_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 189 KRB5_LIB_FUNCTION int KRB5_LIB_CALL 190 krb5_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 207 KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL 208 krb5_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 225 KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL 226 krb5_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 240 KRB5_LIB_FUNCTION void KRB5_LIB_CALL 241 krb5_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 256 KRB5_LIB_FUNCTION int KRB5_LIB_CALL 257 krb5_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 272 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 273 krb5_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 293 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 294 krb5_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); 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 319 static krb5_error_code 320 krb5_store_int(krb5_storage *sp, 321 int32_t value, 322 size_t len) 323 { 324 int ret; 325 unsigned char v[16]; 326 327 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 350 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 351 krb5_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 373 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 374 krb5_store_uint32(krb5_storage *sp, 375 uint32_t value) 376 { 377 return krb5_store_int32(sp, (int32_t)value); 378 } 379 380 static krb5_error_code 381 krb5_ret_int(krb5_storage *sp, 382 int32_t *value, 383 size_t len) 384 { 385 int ret; 386 unsigned char v[4]; 387 unsigned long w; 388 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 = 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 410 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 411 krb5_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 436 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 437 krb5_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 462 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 463 krb5_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 485 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 486 krb5_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 504 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 505 krb5_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 533 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 534 krb5_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 558 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 559 krb5_store_int8(krb5_storage *sp, 560 int8_t value) 561 { 562 int 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 581 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 582 krb5_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 599 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 600 krb5_ret_int8(krb5_storage *sp, 601 int8_t *value) 602 { 603 int 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 622 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 623 krb5_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 648 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 649 krb5_store_data(krb5_storage *sp, 650 krb5_data data) 651 { 652 int ret; 653 ret = krb5_store_int32(sp, data.length); 654 if(ret < 0) 655 return ret; 656 ret = sp->store(sp, data.data, data.length); 657 if(ret < 0) 658 return errno; 659 if((size_t)ret != data.length) 660 return sp->eof_code; 661 return 0; 662 } 663 664 /** 665 * Parse a data from the storage. 666 * 667 * @param sp the storage buffer to read from 668 * @param data the parsed data 669 * 670 * @return 0 on success, a Kerberos 5 error code on failure. 671 * 672 * @ingroup krb5_storage 673 */ 674 675 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 676 krb5_ret_data(krb5_storage *sp, 677 krb5_data *data) 678 { 679 int ret; 680 int32_t size; 681 682 ret = krb5_ret_int32(sp, &size); 683 if(ret) 684 return ret; 685 ret = size_too_large(sp, size); 686 if (ret) 687 return ret; 688 ret = krb5_data_alloc (data, size); 689 if (ret) 690 return ret; 691 if (size) { 692 ret = sp->fetch(sp, data->data, size); 693 if(ret != size) 694 return (ret < 0)? errno : sp->eof_code; 695 } 696 return 0; 697 } 698 699 /** 700 * Store a string to the buffer. The data is formated as an len:uint32 701 * plus the string itself (not padded). 702 * 703 * @param sp the storage buffer to write to 704 * @param s the string to store. 705 * 706 * @return 0 on success, a Kerberos 5 error code on failure. 707 * 708 * @ingroup krb5_storage 709 */ 710 711 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 712 krb5_store_string(krb5_storage *sp, const char *s) 713 { 714 krb5_data data; 715 data.length = strlen(s); 716 data.data = rk_UNCONST(s); 717 return krb5_store_data(sp, data); 718 } 719 720 /** 721 * Parse a string from the storage. 722 * 723 * @param sp the storage buffer to read from 724 * @param string the parsed string 725 * 726 * @return 0 on success, a Kerberos 5 error code on failure. 727 * 728 * @ingroup krb5_storage 729 */ 730 731 732 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 733 krb5_ret_string(krb5_storage *sp, 734 char **string) 735 { 736 int ret; 737 krb5_data data; 738 ret = krb5_ret_data(sp, &data); 739 if(ret) 740 return ret; 741 *string = realloc(data.data, data.length + 1); 742 if(*string == NULL){ 743 free(data.data); 744 return ENOMEM; 745 } 746 (*string)[data.length] = 0; 747 return 0; 748 } 749 750 /** 751 * Store a zero terminated string to the buffer. The data is stored 752 * one character at a time until a NUL is stored. 753 * 754 * @param sp the storage buffer to write to 755 * @param s the string to store. 756 * 757 * @return 0 on success, a Kerberos 5 error code on failure. 758 * 759 * @ingroup krb5_storage 760 */ 761 762 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 763 krb5_store_stringz(krb5_storage *sp, const char *s) 764 { 765 size_t len = strlen(s) + 1; 766 ssize_t ret; 767 768 ret = sp->store(sp, s, len); 769 if(ret < 0) 770 return ret; 771 if((size_t)ret != len) 772 return sp->eof_code; 773 return 0; 774 } 775 776 /** 777 * Parse zero terminated string from the storage. 778 * 779 * @param sp the storage buffer to read from 780 * @param string the parsed string 781 * 782 * @return 0 on success, a Kerberos 5 error code on failure. 783 * 784 * @ingroup krb5_storage 785 */ 786 787 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 788 krb5_ret_stringz(krb5_storage *sp, 789 char **string) 790 { 791 char c; 792 char *s = NULL; 793 size_t len = 0; 794 ssize_t ret; 795 796 while((ret = sp->fetch(sp, &c, 1)) == 1){ 797 char *tmp; 798 799 len++; 800 ret = size_too_large(sp, len); 801 if (ret) 802 break; 803 tmp = realloc (s, len); 804 if (tmp == NULL) { 805 free (s); 806 return ENOMEM; 807 } 808 s = tmp; 809 s[len - 1] = c; 810 if(c == 0) 811 break; 812 } 813 if(ret != 1){ 814 free(s); 815 if(ret == 0) 816 return sp->eof_code; 817 return ret; 818 } 819 *string = s; 820 return 0; 821 } 822 823 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 824 krb5_store_stringnl(krb5_storage *sp, const char *s) 825 { 826 size_t len = strlen(s); 827 ssize_t ret; 828 829 ret = sp->store(sp, s, len); 830 if(ret < 0) 831 return ret; 832 if((size_t)ret != len) 833 return sp->eof_code; 834 ret = sp->store(sp, "\n", 1); 835 if(ret != 1) { 836 if(ret < 0) 837 return ret; 838 else 839 return sp->eof_code; 840 } 841 842 return 0; 843 844 } 845 846 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 847 krb5_ret_stringnl(krb5_storage *sp, 848 char **string) 849 { 850 int expect_nl = 0; 851 char c; 852 char *s = NULL; 853 size_t len = 0; 854 ssize_t ret; 855 856 while((ret = sp->fetch(sp, &c, 1)) == 1){ 857 char *tmp; 858 859 if (c == '\r') { 860 expect_nl = 1; 861 continue; 862 } 863 if (expect_nl && c != '\n') { 864 free(s); 865 return KRB5_BADMSGTYPE; 866 } 867 868 len++; 869 ret = size_too_large(sp, len); 870 if (ret) 871 break; 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 if(ret == 0) 887 return sp->eof_code; 888 return ret; 889 } 890 *string = s; 891 return 0; 892 } 893 894 /** 895 * Write a principal block to storage. 896 * 897 * @param sp the storage buffer to write to 898 * @param p the principal block to write. 899 * 900 * @return 0 on success, a Kerberos 5 error code on failure. 901 * 902 * @ingroup krb5_storage 903 */ 904 905 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 906 krb5_store_principal(krb5_storage *sp, 907 krb5_const_principal p) 908 { 909 size_t i; 910 int ret; 911 912 if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) { 913 ret = krb5_store_int32(sp, p->name.name_type); 914 if(ret) return ret; 915 } 916 if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS)) 917 ret = krb5_store_int32(sp, p->name.name_string.len + 1); 918 else 919 ret = krb5_store_int32(sp, p->name.name_string.len); 920 921 if(ret) return ret; 922 ret = krb5_store_string(sp, p->realm); 923 if(ret) return ret; 924 for(i = 0; i < p->name.name_string.len; i++){ 925 ret = krb5_store_string(sp, p->name.name_string.val[i]); 926 if(ret) return ret; 927 } 928 return 0; 929 } 930 931 /** 932 * Parse principal from the storage. 933 * 934 * @param sp the storage buffer to read from 935 * @param princ the parsed principal 936 * 937 * @return 0 on success, a Kerberos 5 error code on failure. 938 * 939 * @ingroup krb5_storage 940 */ 941 942 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 943 krb5_ret_principal(krb5_storage *sp, 944 krb5_principal *princ) 945 { 946 int i; 947 int ret; 948 krb5_principal p; 949 int32_t type; 950 int32_t ncomp; 951 952 p = calloc(1, sizeof(*p)); 953 if(p == NULL) 954 return ENOMEM; 955 956 if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) 957 type = KRB5_NT_UNKNOWN; 958 else if((ret = krb5_ret_int32(sp, &type))){ 959 free(p); 960 return ret; 961 } 962 if((ret = krb5_ret_int32(sp, &ncomp))){ 963 free(p); 964 return ret; 965 } 966 if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS)) 967 ncomp--; 968 if (ncomp < 0) { 969 free(p); 970 return EINVAL; 971 } 972 ret = size_too_large_num(sp, ncomp, sizeof(p->name.name_string.val[0])); 973 if (ret) { 974 free(p); 975 return ret; 976 } 977 p->name.name_type = type; 978 p->name.name_string.len = ncomp; 979 ret = krb5_ret_string(sp, &p->realm); 980 if(ret) { 981 free(p); 982 return ret; 983 } 984 p->name.name_string.val = calloc(ncomp, sizeof(p->name.name_string.val[0])); 985 if(p->name.name_string.val == NULL && ncomp != 0){ 986 free(p->realm); 987 free(p); 988 return ENOMEM; 989 } 990 for(i = 0; i < ncomp; i++){ 991 ret = krb5_ret_string(sp, &p->name.name_string.val[i]); 992 if(ret) { 993 while (i >= 0) 994 free(p->name.name_string.val[i--]); 995 free(p->realm); 996 free(p); 997 return ret; 998 } 999 } 1000 *princ = p; 1001 return 0; 1002 } 1003 1004 /** 1005 * Store a keyblock to the storage. 1006 * 1007 * @param sp the storage buffer to write to 1008 * @param p the keyblock to write 1009 * 1010 * @return 0 on success, a Kerberos 5 error code on failure. 1011 * 1012 * @ingroup krb5_storage 1013 */ 1014 1015 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1016 krb5_store_keyblock(krb5_storage *sp, krb5_keyblock p) 1017 { 1018 int ret; 1019 ret = krb5_store_int16(sp, p.keytype); 1020 if(ret) return ret; 1021 1022 if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){ 1023 /* this should really be enctype, but it is the same as 1024 keytype nowadays */ 1025 ret = krb5_store_int16(sp, p.keytype); 1026 if(ret) return ret; 1027 } 1028 1029 ret = krb5_store_data(sp, p.keyvalue); 1030 return ret; 1031 } 1032 1033 /** 1034 * Read a keyblock from the storage. 1035 * 1036 * @param sp the storage buffer to write to 1037 * @param p the keyblock read from storage, free using krb5_free_keyblock() 1038 * 1039 * @return 0 on success, a Kerberos 5 error code on failure. 1040 * 1041 * @ingroup krb5_storage 1042 */ 1043 1044 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1045 krb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p) 1046 { 1047 int ret; 1048 int16_t tmp; 1049 1050 ret = krb5_ret_int16(sp, &tmp); 1051 if(ret) return ret; 1052 p->keytype = tmp; 1053 1054 if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){ 1055 ret = krb5_ret_int16(sp, &tmp); 1056 if(ret) return ret; 1057 } 1058 1059 ret = krb5_ret_data(sp, &p->keyvalue); 1060 return ret; 1061 } 1062 1063 /** 1064 * Write a times block to storage. 1065 * 1066 * @param sp the storage buffer to write to 1067 * @param times the times block to write. 1068 * 1069 * @return 0 on success, a Kerberos 5 error code on failure. 1070 * 1071 * @ingroup krb5_storage 1072 */ 1073 1074 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1075 krb5_store_times(krb5_storage *sp, krb5_times times) 1076 { 1077 int ret; 1078 ret = krb5_store_int32(sp, times.authtime); 1079 if(ret) return ret; 1080 ret = krb5_store_int32(sp, times.starttime); 1081 if(ret) return ret; 1082 ret = krb5_store_int32(sp, times.endtime); 1083 if(ret) return ret; 1084 ret = krb5_store_int32(sp, times.renew_till); 1085 return ret; 1086 } 1087 1088 /** 1089 * Read a times block from the storage. 1090 * 1091 * @param sp the storage buffer to write to 1092 * @param times the times block read from storage 1093 * 1094 * @return 0 on success, a Kerberos 5 error code on failure. 1095 * 1096 * @ingroup krb5_storage 1097 */ 1098 1099 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1100 krb5_ret_times(krb5_storage *sp, krb5_times *times) 1101 { 1102 int ret; 1103 int32_t tmp; 1104 ret = krb5_ret_int32(sp, &tmp); 1105 times->authtime = tmp; 1106 if(ret) return ret; 1107 ret = krb5_ret_int32(sp, &tmp); 1108 times->starttime = tmp; 1109 if(ret) return ret; 1110 ret = krb5_ret_int32(sp, &tmp); 1111 times->endtime = tmp; 1112 if(ret) return ret; 1113 ret = krb5_ret_int32(sp, &tmp); 1114 times->renew_till = tmp; 1115 return ret; 1116 } 1117 1118 /** 1119 * Write a address block to storage. 1120 * 1121 * @param sp the storage buffer to write to 1122 * @param p the address block to write. 1123 * 1124 * @return 0 on success, a Kerberos 5 error code on failure. 1125 * 1126 * @ingroup krb5_storage 1127 */ 1128 1129 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1130 krb5_store_address(krb5_storage *sp, krb5_address p) 1131 { 1132 int ret; 1133 ret = krb5_store_int16(sp, p.addr_type); 1134 if(ret) return ret; 1135 ret = krb5_store_data(sp, p.address); 1136 return ret; 1137 } 1138 1139 /** 1140 * Read a address block from the storage. 1141 * 1142 * @param sp the storage buffer to write to 1143 * @param adr the address block read from storage 1144 * 1145 * @return 0 on success, a Kerberos 5 error code on failure. 1146 * 1147 * @ingroup krb5_storage 1148 */ 1149 1150 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1151 krb5_ret_address(krb5_storage *sp, krb5_address *adr) 1152 { 1153 int16_t t; 1154 int ret; 1155 ret = krb5_ret_int16(sp, &t); 1156 if(ret) return ret; 1157 adr->addr_type = t; 1158 ret = krb5_ret_data(sp, &adr->address); 1159 return ret; 1160 } 1161 1162 /** 1163 * Write a addresses block to storage. 1164 * 1165 * @param sp the storage buffer to write to 1166 * @param p the addresses block to write. 1167 * 1168 * @return 0 on success, a Kerberos 5 error code on failure. 1169 * 1170 * @ingroup krb5_storage 1171 */ 1172 1173 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1174 krb5_store_addrs(krb5_storage *sp, krb5_addresses p) 1175 { 1176 size_t i; 1177 int ret; 1178 ret = krb5_store_int32(sp, p.len); 1179 if(ret) return ret; 1180 for(i = 0; i<p.len; i++){ 1181 ret = krb5_store_address(sp, p.val[i]); 1182 if(ret) break; 1183 } 1184 return ret; 1185 } 1186 1187 /** 1188 * Read a addresses block from the storage. 1189 * 1190 * @param sp the storage buffer to write to 1191 * @param adr the addresses block read from storage 1192 * 1193 * @return 0 on success, a Kerberos 5 error code on failure. 1194 * 1195 * @ingroup krb5_storage 1196 */ 1197 1198 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1199 krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr) 1200 { 1201 size_t i; 1202 int ret; 1203 int32_t tmp; 1204 1205 ret = krb5_ret_int32(sp, &tmp); 1206 if(ret) return ret; 1207 ret = size_too_large_num(sp, tmp, sizeof(adr->val[0])); 1208 if (ret) return ret; 1209 adr->len = tmp; 1210 ALLOC(adr->val, adr->len); 1211 if (adr->val == NULL && adr->len != 0) 1212 return ENOMEM; 1213 for(i = 0; i < adr->len; i++){ 1214 ret = krb5_ret_address(sp, &adr->val[i]); 1215 if(ret) break; 1216 } 1217 return ret; 1218 } 1219 1220 /** 1221 * Write a auth data block to storage. 1222 * 1223 * @param sp the storage buffer to write to 1224 * @param auth the auth data block to write. 1225 * 1226 * @return 0 on success, a Kerberos 5 error code on failure. 1227 * 1228 * @ingroup krb5_storage 1229 */ 1230 1231 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1232 krb5_store_authdata(krb5_storage *sp, krb5_authdata auth) 1233 { 1234 krb5_error_code ret; 1235 size_t i; 1236 ret = krb5_store_int32(sp, auth.len); 1237 if(ret) return ret; 1238 for(i = 0; i < auth.len; i++){ 1239 ret = krb5_store_int16(sp, auth.val[i].ad_type); 1240 if(ret) break; 1241 ret = krb5_store_data(sp, auth.val[i].ad_data); 1242 if(ret) break; 1243 } 1244 return 0; 1245 } 1246 1247 /** 1248 * Read a auth data from the storage. 1249 * 1250 * @param sp the storage buffer to write to 1251 * @param auth the auth data block read from storage 1252 * 1253 * @return 0 on success, a Kerberos 5 error code on failure. 1254 * 1255 * @ingroup krb5_storage 1256 */ 1257 1258 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1259 krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth) 1260 { 1261 krb5_error_code ret; 1262 int32_t tmp; 1263 int16_t tmp2; 1264 int i; 1265 ret = krb5_ret_int32(sp, &tmp); 1266 if(ret) return ret; 1267 ret = size_too_large_num(sp, tmp, sizeof(auth->val[0])); 1268 if (ret) return ret; 1269 ALLOC_SEQ(auth, tmp); 1270 if (auth->val == NULL && tmp != 0) 1271 return ENOMEM; 1272 for(i = 0; i < tmp; i++){ 1273 ret = krb5_ret_int16(sp, &tmp2); 1274 if(ret) break; 1275 auth->val[i].ad_type = tmp2; 1276 ret = krb5_ret_data(sp, &auth->val[i].ad_data); 1277 if(ret) break; 1278 } 1279 return ret; 1280 } 1281 1282 static int32_t 1283 bitswap32(int32_t b) 1284 { 1285 int32_t r = 0; 1286 int i; 1287 for (i = 0; i < 32; i++) { 1288 r = r << 1 | (b & 1); 1289 b = b >> 1; 1290 } 1291 return r; 1292 } 1293 1294 /** 1295 * Write a credentials block to storage. 1296 * 1297 * @param sp the storage buffer to write to 1298 * @param creds the creds block to write. 1299 * 1300 * @return 0 on success, a Kerberos 5 error code on failure. 1301 * 1302 * @ingroup krb5_storage 1303 */ 1304 1305 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1306 krb5_store_creds(krb5_storage *sp, krb5_creds *creds) 1307 { 1308 int ret; 1309 1310 ret = krb5_store_principal(sp, creds->client); 1311 if(ret) 1312 return ret; 1313 ret = krb5_store_principal(sp, creds->server); 1314 if(ret) 1315 return ret; 1316 ret = krb5_store_keyblock(sp, creds->session); 1317 if(ret) 1318 return ret; 1319 ret = krb5_store_times(sp, creds->times); 1320 if(ret) 1321 return ret; 1322 ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */ 1323 if(ret) 1324 return ret; 1325 1326 if(krb5_storage_is_flags(sp, KRB5_STORAGE_CREDS_FLAGS_WRONG_BITORDER)) 1327 ret = krb5_store_int32(sp, creds->flags.i); 1328 else 1329 ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b))); 1330 if(ret) 1331 return ret; 1332 1333 ret = krb5_store_addrs(sp, creds->addresses); 1334 if(ret) 1335 return ret; 1336 ret = krb5_store_authdata(sp, creds->authdata); 1337 if(ret) 1338 return ret; 1339 ret = krb5_store_data(sp, creds->ticket); 1340 if(ret) 1341 return ret; 1342 ret = krb5_store_data(sp, creds->second_ticket); 1343 return ret; 1344 } 1345 1346 /** 1347 * Read a credentials block from the storage. 1348 * 1349 * @param sp the storage buffer to write to 1350 * @param creds the credentials block read from storage 1351 * 1352 * @return 0 on success, a Kerberos 5 error code on failure. 1353 * 1354 * @ingroup krb5_storage 1355 */ 1356 1357 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1358 krb5_ret_creds(krb5_storage *sp, krb5_creds *creds) 1359 { 1360 krb5_error_code ret; 1361 int8_t dummy8; 1362 int32_t dummy32; 1363 1364 memset(creds, 0, sizeof(*creds)); 1365 ret = krb5_ret_principal (sp, &creds->client); 1366 if(ret) goto cleanup; 1367 ret = krb5_ret_principal (sp, &creds->server); 1368 if(ret) goto cleanup; 1369 ret = krb5_ret_keyblock (sp, &creds->session); 1370 if(ret) goto cleanup; 1371 ret = krb5_ret_times (sp, &creds->times); 1372 if(ret) goto cleanup; 1373 ret = krb5_ret_int8 (sp, &dummy8); 1374 if(ret) goto cleanup; 1375 ret = krb5_ret_int32 (sp, &dummy32); 1376 if(ret) goto cleanup; 1377 /* 1378 * Runtime detect the what is the higher bits of the bitfield. If 1379 * any of the higher bits are set in the input data, it's either a 1380 * new ticket flag (and this code need to be removed), or it's a 1381 * MIT cache (or new Heimdal cache), lets change it to our current 1382 * format. 1383 */ 1384 { 1385 uint32_t mask = 0xffff0000; 1386 creds->flags.i = 0; 1387 creds->flags.b.anonymous = 1; 1388 if (creds->flags.i & mask) 1389 mask = ~mask; 1390 if (dummy32 & mask) 1391 dummy32 = bitswap32(dummy32); 1392 } 1393 creds->flags.i = dummy32; 1394 ret = krb5_ret_addrs (sp, &creds->addresses); 1395 if(ret) goto cleanup; 1396 ret = krb5_ret_authdata (sp, &creds->authdata); 1397 if(ret) goto cleanup; 1398 ret = krb5_ret_data (sp, &creds->ticket); 1399 if(ret) goto cleanup; 1400 ret = krb5_ret_data (sp, &creds->second_ticket); 1401 cleanup: 1402 if(ret) { 1403 #if 0 1404 krb5_free_cred_contents(context, creds); /* XXX */ 1405 #endif 1406 } 1407 return ret; 1408 } 1409 1410 #define SC_CLIENT_PRINCIPAL 0x0001 1411 #define SC_SERVER_PRINCIPAL 0x0002 1412 #define SC_SESSION_KEY 0x0004 1413 #define SC_TICKET 0x0008 1414 #define SC_SECOND_TICKET 0x0010 1415 #define SC_AUTHDATA 0x0020 1416 #define SC_ADDRESSES 0x0040 1417 1418 /** 1419 * Write a tagged credentials block to storage. 1420 * 1421 * @param sp the storage buffer to write to 1422 * @param creds the creds block to write. 1423 * 1424 * @return 0 on success, a Kerberos 5 error code on failure. 1425 * 1426 * @ingroup krb5_storage 1427 */ 1428 1429 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1430 krb5_store_creds_tag(krb5_storage *sp, krb5_creds *creds) 1431 { 1432 int ret; 1433 int32_t header = 0; 1434 1435 if (creds->client) 1436 header |= SC_CLIENT_PRINCIPAL; 1437 if (creds->server) 1438 header |= SC_SERVER_PRINCIPAL; 1439 if (creds->session.keytype != ETYPE_NULL) 1440 header |= SC_SESSION_KEY; 1441 if (creds->ticket.data) 1442 header |= SC_TICKET; 1443 if (creds->second_ticket.length) 1444 header |= SC_SECOND_TICKET; 1445 if (creds->authdata.len) 1446 header |= SC_AUTHDATA; 1447 if (creds->addresses.len) 1448 header |= SC_ADDRESSES; 1449 1450 ret = krb5_store_int32(sp, header); 1451 if (ret) 1452 return ret; 1453 1454 if (creds->client) { 1455 ret = krb5_store_principal(sp, creds->client); 1456 if(ret) 1457 return ret; 1458 } 1459 1460 if (creds->server) { 1461 ret = krb5_store_principal(sp, creds->server); 1462 if(ret) 1463 return ret; 1464 } 1465 1466 if (creds->session.keytype != ETYPE_NULL) { 1467 ret = krb5_store_keyblock(sp, creds->session); 1468 if(ret) 1469 return ret; 1470 } 1471 1472 ret = krb5_store_times(sp, creds->times); 1473 if(ret) 1474 return ret; 1475 ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */ 1476 if(ret) 1477 return ret; 1478 1479 ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b))); 1480 if(ret) 1481 return ret; 1482 1483 if (creds->addresses.len) { 1484 ret = krb5_store_addrs(sp, creds->addresses); 1485 if(ret) 1486 return ret; 1487 } 1488 1489 if (creds->authdata.len) { 1490 ret = krb5_store_authdata(sp, creds->authdata); 1491 if(ret) 1492 return ret; 1493 } 1494 1495 if (creds->ticket.data) { 1496 ret = krb5_store_data(sp, creds->ticket); 1497 if(ret) 1498 return ret; 1499 } 1500 1501 if (creds->second_ticket.data) { 1502 ret = krb5_store_data(sp, creds->second_ticket); 1503 if (ret) 1504 return ret; 1505 } 1506 1507 return ret; 1508 } 1509 1510 /** 1511 * Read a tagged credentials block from the storage. 1512 * 1513 * @param sp the storage buffer to write to 1514 * @param creds the credentials block read from storage 1515 * 1516 * @return 0 on success, a Kerberos 5 error code on failure. 1517 * 1518 * @ingroup krb5_storage 1519 */ 1520 1521 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1522 krb5_ret_creds_tag(krb5_storage *sp, 1523 krb5_creds *creds) 1524 { 1525 krb5_error_code ret; 1526 int8_t dummy8; 1527 int32_t dummy32, header; 1528 1529 memset(creds, 0, sizeof(*creds)); 1530 1531 ret = krb5_ret_int32 (sp, &header); 1532 if (ret) goto cleanup; 1533 1534 if (header & SC_CLIENT_PRINCIPAL) { 1535 ret = krb5_ret_principal (sp, &creds->client); 1536 if(ret) goto cleanup; 1537 } 1538 if (header & SC_SERVER_PRINCIPAL) { 1539 ret = krb5_ret_principal (sp, &creds->server); 1540 if(ret) goto cleanup; 1541 } 1542 if (header & SC_SESSION_KEY) { 1543 ret = krb5_ret_keyblock (sp, &creds->session); 1544 if(ret) goto cleanup; 1545 } 1546 ret = krb5_ret_times (sp, &creds->times); 1547 if(ret) goto cleanup; 1548 ret = krb5_ret_int8 (sp, &dummy8); 1549 if(ret) goto cleanup; 1550 ret = krb5_ret_int32 (sp, &dummy32); 1551 if(ret) goto cleanup; 1552 /* 1553 * Runtime detect the what is the higher bits of the bitfield. If 1554 * any of the higher bits are set in the input data, it's either a 1555 * new ticket flag (and this code need to be removed), or it's a 1556 * MIT cache (or new Heimdal cache), lets change it to our current 1557 * format. 1558 */ 1559 { 1560 uint32_t mask = 0xffff0000; 1561 creds->flags.i = 0; 1562 creds->flags.b.anonymous = 1; 1563 if (creds->flags.i & mask) 1564 mask = ~mask; 1565 if (dummy32 & mask) 1566 dummy32 = bitswap32(dummy32); 1567 } 1568 creds->flags.i = dummy32; 1569 if (header & SC_ADDRESSES) { 1570 ret = krb5_ret_addrs (sp, &creds->addresses); 1571 if(ret) goto cleanup; 1572 } 1573 if (header & SC_AUTHDATA) { 1574 ret = krb5_ret_authdata (sp, &creds->authdata); 1575 if(ret) goto cleanup; 1576 } 1577 if (header & SC_TICKET) { 1578 ret = krb5_ret_data (sp, &creds->ticket); 1579 if(ret) goto cleanup; 1580 } 1581 if (header & SC_SECOND_TICKET) { 1582 ret = krb5_ret_data (sp, &creds->second_ticket); 1583 if(ret) goto cleanup; 1584 } 1585 1586 cleanup: 1587 if(ret) { 1588 #if 0 1589 krb5_free_cred_contents(context, creds); /* XXX */ 1590 #endif 1591 } 1592 return ret; 1593 } 1594