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 52 KRB5_LIB_FUNCTION void KRB5_LIB_CALL 53 krb5_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 67 KRB5_LIB_FUNCTION void KRB5_LIB_CALL 68 krb5_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 85 KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL 86 krb5_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 103 KRB5_LIB_FUNCTION void KRB5_LIB_CALL 104 krb5_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 116 KRB5_LIB_FUNCTION krb5_flags KRB5_LIB_CALL 117 krb5_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 131 KRB5_LIB_FUNCTION void KRB5_LIB_CALL 132 krb5_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 */ 138 static krb5_error_code 139 size_too_large(krb5_storage *sp, size_t size) 140 { 141 if (sp->max_alloc && sp->max_alloc < size) 142 return HEIM_ERR_TOO_BIG; 143 return 0; 144 } 145 146 static krb5_error_code 147 size_too_large_num(krb5_storage *sp, size_t count, size_t size) 148 { 149 if (sp->max_alloc == 0 || size == 0) 150 return 0; 151 size = sp->max_alloc / size; 152 if (size < count) 153 return HEIM_ERR_TOO_BIG; 154 return 0; 155 } 156 157 /** 158 * Seek to a new offset. 159 * 160 * @param sp the storage buffer to seek in. 161 * @param offset the offset to seek 162 * @param whence relateive searching, SEEK_CUR from the current 163 * position, SEEK_END from the end, SEEK_SET absolute from the start. 164 * 165 * @return The new current offset 166 * 167 * @ingroup krb5_storage 168 */ 169 170 KRB5_LIB_FUNCTION off_t KRB5_LIB_CALL 171 krb5_storage_seek(krb5_storage *sp, off_t offset, int whence) 172 { 173 return (*sp->seek)(sp, offset, whence); 174 } 175 176 /** 177 * Truncate the storage buffer in sp to offset. 178 * 179 * @param sp the storage buffer to truncate. 180 * @param offset the offset to truncate too. 181 * 182 * @return An Kerberos 5 error code. 183 * 184 * @ingroup krb5_storage 185 */ 186 187 KRB5_LIB_FUNCTION int KRB5_LIB_CALL 188 krb5_storage_truncate(krb5_storage *sp, off_t offset) 189 { 190 return (*sp->trunc)(sp, offset); 191 } 192 193 /** 194 * Read to the storage buffer. 195 * 196 * @param sp the storage buffer to read from 197 * @param buf the buffer to store the data in 198 * @param len the length to read 199 * 200 * @return The length of data read (can be shorter then len), or negative on error. 201 * 202 * @ingroup krb5_storage 203 */ 204 205 KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL 206 krb5_storage_read(krb5_storage *sp, void *buf, size_t len) 207 { 208 return sp->fetch(sp, buf, len); 209 } 210 211 /** 212 * Write to the storage buffer. 213 * 214 * @param sp the storage buffer to write to 215 * @param buf the buffer to write to the storage buffer 216 * @param len the length to write 217 * 218 * @return The length of data written (can be shorter then len), or negative on error. 219 * 220 * @ingroup krb5_storage 221 */ 222 223 KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL 224 krb5_storage_write(krb5_storage *sp, const void *buf, size_t len) 225 { 226 return sp->store(sp, buf, len); 227 } 228 229 /** 230 * Set the return code that will be used when end of storage is reached. 231 * 232 * @param sp the storage 233 * @param code the error code to return on end of storage 234 * 235 * @ingroup krb5_storage 236 */ 237 238 KRB5_LIB_FUNCTION void KRB5_LIB_CALL 239 krb5_storage_set_eof_code(krb5_storage *sp, int code) 240 { 241 sp->eof_code = code; 242 } 243 244 /** 245 * Get the return code that will be used when end of storage is reached. 246 * 247 * @param sp the storage 248 * 249 * @return storage error code 250 * 251 * @ingroup krb5_storage 252 */ 253 254 KRB5_LIB_FUNCTION int KRB5_LIB_CALL 255 krb5_storage_get_eof_code(krb5_storage *sp) 256 { 257 return sp->eof_code; 258 } 259 260 /** 261 * Free a krb5 storage. 262 * 263 * @param sp the storage to free. 264 * 265 * @return An Kerberos 5 error code. 266 * 267 * @ingroup krb5_storage 268 */ 269 270 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 271 krb5_storage_free(krb5_storage *sp) 272 { 273 if(sp->free) 274 (*sp->free)(sp); 275 free(sp->data); 276 free(sp); 277 return 0; 278 } 279 280 /** 281 * Copy the contnent of storage 282 * 283 * @param sp the storage to copy to a data 284 * @param data the copied data, free with krb5_data_free() 285 * 286 * @return 0 for success, or a Kerberos 5 error code on failure. 287 * 288 * @ingroup krb5_storage 289 */ 290 291 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 292 krb5_storage_to_data(krb5_storage *sp, krb5_data *data) 293 { 294 off_t pos, size; 295 krb5_error_code ret; 296 297 pos = sp->seek(sp, 0, SEEK_CUR); 298 if (pos < 0) 299 return HEIM_ERR_NOT_SEEKABLE; 300 size = sp->seek(sp, 0, SEEK_END); 301 ret = size_too_large(sp, size); 302 if (ret) 303 return ret; 304 ret = krb5_data_alloc(data, size); 305 if (ret) { 306 sp->seek(sp, pos, SEEK_SET); 307 return ret; 308 } 309 if (size) { 310 sp->seek(sp, 0, SEEK_SET); 311 sp->fetch(sp, data->data, data->length); 312 sp->seek(sp, pos, SEEK_SET); 313 } 314 return 0; 315 } 316 317 static krb5_error_code 318 krb5_store_int(krb5_storage *sp, 319 int32_t value, 320 size_t len) 321 { 322 int ret; 323 unsigned char v[16]; 324 325 if(len > sizeof(v)) 326 return EINVAL; 327 _krb5_put_int(v, value, len); 328 ret = sp->store(sp, v, len); 329 if (ret < 0) 330 return errno; 331 if ((size_t)ret != len) 332 return sp->eof_code; 333 return 0; 334 } 335 336 /** 337 * Store a int32 to storage, byte order is controlled by the settings 338 * on the storage, see krb5_storage_set_byteorder(). 339 * 340 * @param sp the storage to write too 341 * @param value the value to store 342 * 343 * @return 0 for success, or a Kerberos 5 error code on failure. 344 * 345 * @ingroup krb5_storage 346 */ 347 348 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 349 krb5_store_int32(krb5_storage *sp, 350 int32_t value) 351 { 352 if(BYTEORDER_IS_HOST(sp)) 353 value = htonl(value); 354 else if(BYTEORDER_IS_LE(sp)) 355 value = bswap32(value); 356 return krb5_store_int(sp, value, 4); 357 } 358 359 /** 360 * Store a uint32 to storage, byte order is controlled by the settings 361 * on the storage, see krb5_storage_set_byteorder(). 362 * 363 * @param sp the storage to write too 364 * @param value the value to store 365 * 366 * @return 0 for success, or a Kerberos 5 error code on failure. 367 * 368 * @ingroup krb5_storage 369 */ 370 371 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 372 krb5_store_uint32(krb5_storage *sp, 373 uint32_t value) 374 { 375 return krb5_store_int32(sp, (int32_t)value); 376 } 377 378 static krb5_error_code 379 krb5_ret_int(krb5_storage *sp, 380 int32_t *value, 381 size_t len) 382 { 383 int ret; 384 unsigned char v[4]; 385 unsigned long w; 386 ret = sp->fetch(sp, v, len); 387 if (ret < 0) 388 return errno; 389 if ((size_t)ret != len) 390 return sp->eof_code; 391 _krb5_get_int(v, &w, len); 392 *value = w; 393 return 0; 394 } 395 396 /** 397 * Read a int32 from storage, byte order is controlled by the settings 398 * on the storage, see krb5_storage_set_byteorder(). 399 * 400 * @param sp the storage to write too 401 * @param value the value read from the buffer 402 * 403 * @return 0 for success, or a Kerberos 5 error code on failure. 404 * 405 * @ingroup krb5_storage 406 */ 407 408 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 409 krb5_ret_int32(krb5_storage *sp, 410 int32_t *value) 411 { 412 krb5_error_code ret = krb5_ret_int(sp, value, 4); 413 if(ret) 414 return ret; 415 if(BYTEORDER_IS_HOST(sp)) 416 *value = htonl(*value); 417 else if(BYTEORDER_IS_LE(sp)) 418 *value = bswap32(*value); 419 return 0; 420 } 421 422 /** 423 * Read a uint32 from storage, byte order is controlled by the settings 424 * on the storage, see krb5_storage_set_byteorder(). 425 * 426 * @param sp the storage to write too 427 * @param value the value read from the buffer 428 * 429 * @return 0 for success, or a Kerberos 5 error code on failure. 430 * 431 * @ingroup krb5_storage 432 */ 433 434 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 435 krb5_ret_uint32(krb5_storage *sp, 436 uint32_t *value) 437 { 438 krb5_error_code ret; 439 int32_t v; 440 441 ret = krb5_ret_int32(sp, &v); 442 if (ret == 0) 443 *value = (uint32_t)v; 444 445 return ret; 446 } 447 448 /** 449 * Store a int16 to storage, byte order is controlled by the settings 450 * on the storage, see krb5_storage_set_byteorder(). 451 * 452 * @param sp the storage to write too 453 * @param value the value to store 454 * 455 * @return 0 for success, or a Kerberos 5 error code on failure. 456 * 457 * @ingroup krb5_storage 458 */ 459 460 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 461 krb5_store_int16(krb5_storage *sp, 462 int16_t value) 463 { 464 if(BYTEORDER_IS_HOST(sp)) 465 value = htons(value); 466 else if(BYTEORDER_IS_LE(sp)) 467 value = bswap16(value); 468 return krb5_store_int(sp, value, 2); 469 } 470 471 /** 472 * Store a uint16 to storage, byte order is controlled by the settings 473 * on the storage, see krb5_storage_set_byteorder(). 474 * 475 * @param sp the storage to write too 476 * @param value the value to store 477 * 478 * @return 0 for success, or a Kerberos 5 error code on failure. 479 * 480 * @ingroup krb5_storage 481 */ 482 483 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 484 krb5_store_uint16(krb5_storage *sp, 485 uint16_t value) 486 { 487 return krb5_store_int16(sp, (int16_t)value); 488 } 489 490 /** 491 * Read a int16 from storage, byte order is controlled by the settings 492 * on the storage, see krb5_storage_set_byteorder(). 493 * 494 * @param sp the storage to write too 495 * @param value the value read from the buffer 496 * 497 * @return 0 for success, or a Kerberos 5 error code on failure. 498 * 499 * @ingroup krb5_storage 500 */ 501 502 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 503 krb5_ret_int16(krb5_storage *sp, 504 int16_t *value) 505 { 506 int32_t v; 507 int ret; 508 ret = krb5_ret_int(sp, &v, 2); 509 if(ret) 510 return ret; 511 *value = v; 512 if(BYTEORDER_IS_HOST(sp)) 513 *value = htons(*value); 514 else if(BYTEORDER_IS_LE(sp)) 515 *value = bswap16(*value); 516 return 0; 517 } 518 519 /** 520 * Read a int16 from storage, byte order is controlled by the settings 521 * on the storage, see krb5_storage_set_byteorder(). 522 * 523 * @param sp the storage to write too 524 * @param value the value read from the buffer 525 * 526 * @return 0 for success, or a Kerberos 5 error code on failure. 527 * 528 * @ingroup krb5_storage 529 */ 530 531 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 532 krb5_ret_uint16(krb5_storage *sp, 533 uint16_t *value) 534 { 535 krb5_error_code ret; 536 int16_t v; 537 538 ret = krb5_ret_int16(sp, &v); 539 if (ret == 0) 540 *value = (uint16_t)v; 541 542 return ret; 543 } 544 545 /** 546 * Store a int8 to storage. 547 * 548 * @param sp the storage to write too 549 * @param value the value to store 550 * 551 * @return 0 for success, or a Kerberos 5 error code on failure. 552 * 553 * @ingroup krb5_storage 554 */ 555 556 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 557 krb5_store_int8(krb5_storage *sp, 558 int8_t value) 559 { 560 int ret; 561 562 ret = sp->store(sp, &value, sizeof(value)); 563 if (ret != sizeof(value)) 564 return (ret<0)?errno:sp->eof_code; 565 return 0; 566 } 567 568 /** 569 * Store a uint8 to storage. 570 * 571 * @param sp the storage to write too 572 * @param value the value to store 573 * 574 * @return 0 for success, or a Kerberos 5 error code on failure. 575 * 576 * @ingroup krb5_storage 577 */ 578 579 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 580 krb5_store_uint8(krb5_storage *sp, 581 uint8_t value) 582 { 583 return krb5_store_int8(sp, (int8_t)value); 584 } 585 586 /** 587 * Read a int8 from storage 588 * 589 * @param sp the storage to write too 590 * @param value the value read from the buffer 591 * 592 * @return 0 for success, or a Kerberos 5 error code on failure. 593 * 594 * @ingroup krb5_storage 595 */ 596 597 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 598 krb5_ret_int8(krb5_storage *sp, 599 int8_t *value) 600 { 601 int ret; 602 603 ret = sp->fetch(sp, value, sizeof(*value)); 604 if (ret != sizeof(*value)) 605 return (ret<0)?errno:sp->eof_code; 606 return 0; 607 } 608 609 /** 610 * Read a uint8 from storage 611 * 612 * @param sp the storage to write too 613 * @param value the value read from the buffer 614 * 615 * @return 0 for success, or a Kerberos 5 error code on failure. 616 * 617 * @ingroup krb5_storage 618 */ 619 620 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 621 krb5_ret_uint8(krb5_storage *sp, 622 uint8_t *value) 623 { 624 krb5_error_code ret; 625 int8_t v; 626 627 ret = krb5_ret_int8(sp, &v); 628 if (ret == 0) 629 *value = (uint8_t)v; 630 631 return ret; 632 } 633 634 /** 635 * Store a data to the storage. The data is stored with an int32 as 636 * lenght plus the data (not padded). 637 * 638 * @param sp the storage buffer to write to 639 * @param data the buffer to store. 640 * 641 * @return 0 on success, a Kerberos 5 error code on failure. 642 * 643 * @ingroup krb5_storage 644 */ 645 646 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 647 krb5_store_data(krb5_storage *sp, 648 krb5_data data) 649 { 650 int ret; 651 ret = krb5_store_int32(sp, data.length); 652 if(ret < 0) 653 return ret; 654 ret = sp->store(sp, data.data, data.length); 655 if(ret < 0) 656 return errno; 657 if((size_t)ret != data.length) 658 return sp->eof_code; 659 return 0; 660 } 661 662 /** 663 * Parse a data from the storage. 664 * 665 * @param sp the storage buffer to read from 666 * @param data the parsed data 667 * 668 * @return 0 on success, a Kerberos 5 error code on failure. 669 * 670 * @ingroup krb5_storage 671 */ 672 673 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 674 krb5_ret_data(krb5_storage *sp, 675 krb5_data *data) 676 { 677 int ret; 678 int32_t size; 679 680 ret = krb5_ret_int32(sp, &size); 681 if(ret) 682 return ret; 683 ret = size_too_large(sp, size); 684 if (ret) 685 return ret; 686 ret = krb5_data_alloc (data, size); 687 if (ret) 688 return ret; 689 if (size) { 690 ret = sp->fetch(sp, data->data, size); 691 if(ret != size) 692 return (ret < 0)? errno : sp->eof_code; 693 } 694 return 0; 695 } 696 697 /** 698 * Store a string to the buffer. The data is formated as an len:uint32 699 * plus the string itself (not padded). 700 * 701 * @param sp the storage buffer to write to 702 * @param s the string to store. 703 * 704 * @return 0 on success, a Kerberos 5 error code on failure. 705 * 706 * @ingroup krb5_storage 707 */ 708 709 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 710 krb5_store_string(krb5_storage *sp, const char *s) 711 { 712 krb5_data data; 713 data.length = strlen(s); 714 data.data = rk_UNCONST(s); 715 return krb5_store_data(sp, data); 716 } 717 718 /** 719 * Parse a string from the storage. 720 * 721 * @param sp the storage buffer to read from 722 * @param string the parsed string 723 * 724 * @return 0 on success, a Kerberos 5 error code on failure. 725 * 726 * @ingroup krb5_storage 727 */ 728 729 730 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 731 krb5_ret_string(krb5_storage *sp, 732 char **string) 733 { 734 int ret; 735 krb5_data data; 736 ret = krb5_ret_data(sp, &data); 737 if(ret) 738 return ret; 739 *string = realloc(data.data, data.length + 1); 740 if(*string == NULL){ 741 free(data.data); 742 return ENOMEM; 743 } 744 (*string)[data.length] = 0; 745 return 0; 746 } 747 748 /** 749 * Store a zero terminated string to the buffer. The data is stored 750 * one character at a time until a NUL is stored. 751 * 752 * @param sp the storage buffer to write to 753 * @param s the string to store. 754 * 755 * @return 0 on success, a Kerberos 5 error code on failure. 756 * 757 * @ingroup krb5_storage 758 */ 759 760 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 761 krb5_store_stringz(krb5_storage *sp, const char *s) 762 { 763 size_t len = strlen(s) + 1; 764 ssize_t ret; 765 766 ret = sp->store(sp, s, len); 767 if(ret < 0) 768 return ret; 769 if((size_t)ret != len) 770 return sp->eof_code; 771 return 0; 772 } 773 774 /** 775 * Parse zero terminated string from the storage. 776 * 777 * @param sp the storage buffer to read from 778 * @param string the parsed string 779 * 780 * @return 0 on success, a Kerberos 5 error code on failure. 781 * 782 * @ingroup krb5_storage 783 */ 784 785 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 786 krb5_ret_stringz(krb5_storage *sp, 787 char **string) 788 { 789 char c; 790 char *s = NULL; 791 size_t len = 0; 792 ssize_t ret; 793 794 while((ret = sp->fetch(sp, &c, 1)) == 1){ 795 char *tmp; 796 797 len++; 798 ret = size_too_large(sp, len); 799 if (ret) 800 break; 801 tmp = realloc (s, len); 802 if (tmp == NULL) { 803 free (s); 804 return ENOMEM; 805 } 806 s = tmp; 807 s[len - 1] = c; 808 if(c == 0) 809 break; 810 } 811 if(ret != 1){ 812 free(s); 813 if(ret == 0) 814 return sp->eof_code; 815 return ret; 816 } 817 *string = s; 818 return 0; 819 } 820 821 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 822 krb5_store_stringnl(krb5_storage *sp, const char *s) 823 { 824 size_t len = strlen(s); 825 ssize_t ret; 826 827 ret = sp->store(sp, s, len); 828 if(ret < 0) 829 return ret; 830 if((size_t)ret != len) 831 return sp->eof_code; 832 ret = sp->store(sp, "\n", 1); 833 if(ret != 1) { 834 if(ret < 0) 835 return ret; 836 else 837 return sp->eof_code; 838 } 839 840 return 0; 841 842 } 843 844 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 845 krb5_ret_stringnl(krb5_storage *sp, 846 char **string) 847 { 848 int expect_nl = 0; 849 char c; 850 char *s = NULL; 851 size_t len = 0; 852 ssize_t ret; 853 854 while((ret = sp->fetch(sp, &c, 1)) == 1){ 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 ret = size_too_large(sp, len); 868 if (ret) 869 break; 870 tmp = realloc (s, len); 871 if (tmp == NULL) { 872 free (s); 873 return ENOMEM; 874 } 875 s = tmp; 876 if(c == '\n') { 877 s[len - 1] = '\0'; 878 break; 879 } 880 s[len - 1] = c; 881 } 882 if(ret != 1){ 883 free(s); 884 if(ret == 0) 885 return sp->eof_code; 886 return ret; 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 903 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 904 krb5_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 940 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 941 krb5_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 1013 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1014 krb5_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 1042 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1043 krb5_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 1072 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1073 krb5_store_times(krb5_storage *sp, krb5_times times) 1074 { 1075 int ret; 1076 ret = krb5_store_int32(sp, times.authtime); 1077 if(ret) return ret; 1078 ret = krb5_store_int32(sp, times.starttime); 1079 if(ret) return ret; 1080 ret = krb5_store_int32(sp, times.endtime); 1081 if(ret) return ret; 1082 ret = krb5_store_int32(sp, 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 1097 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1098 krb5_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 1127 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1128 krb5_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 1148 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1149 krb5_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 1171 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1172 krb5_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 1196 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1197 krb5_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 1229 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1230 krb5_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 1256 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1257 krb5_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 1280 static int32_t 1281 bitswap32(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 1303 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1304 krb5_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 1355 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1356 krb5_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); 1399 cleanup: 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 1427 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1428 krb5_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 1519 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1520 krb5_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 1584 cleanup: 1585 if(ret) { 1586 #if 0 1587 krb5_free_cred_contents(context, creds); /* XXX */ 1588 #endif 1589 } 1590 return ret; 1591 } 1592