1/* $NetBSD: store.c,v 1.2 2017/01/28 21:31:49 christos 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 54KRB5_LIB_FUNCTION void KRB5_LIB_CALL 55krb5_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 69KRB5_LIB_FUNCTION void KRB5_LIB_CALL 70krb5_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 87KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL 88krb5_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 105KRB5_LIB_FUNCTION void KRB5_LIB_CALL 106krb5_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 118KRB5_LIB_FUNCTION krb5_flags KRB5_LIB_CALL 119krb5_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 133KRB5_LIB_FUNCTION void KRB5_LIB_CALL 134krb5_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 */ 140static krb5_error_code 141size_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 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 * Sync the storage buffer to its backing store. If there is no 197 * backing store this function will return success. 198 * 199 * @param sp the storage buffer to sync 200 * 201 * @return A Kerberos 5 error code 202 * 203 * @ingroup krb5_storage 204 */ 205 206KRB5_LIB_FUNCTION int KRB5_LIB_CALL 207krb5_storage_fsync(krb5_storage *sp) 208{ 209 if (sp->fsync != NULL) 210 return sp->fsync(sp); 211 return 0; 212} 213 214/** 215 * Read to the storage buffer. 216 * 217 * @param sp the storage buffer to read from 218 * @param buf the buffer to store the data in 219 * @param len the length to read 220 * 221 * @return The length of data read (can be shorter then len), or negative on error. 222 * 223 * @ingroup krb5_storage 224 */ 225 226KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL 227krb5_storage_read(krb5_storage *sp, void *buf, size_t len) 228{ 229 return sp->fetch(sp, buf, len); 230} 231 232/** 233 * Write to the storage buffer. 234 * 235 * @param sp the storage buffer to write to 236 * @param buf the buffer to write to the storage buffer 237 * @param len the length to write 238 * 239 * @return The length of data written (can be shorter then len), or negative on error. 240 * 241 * @ingroup krb5_storage 242 */ 243 244KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL 245krb5_storage_write(krb5_storage *sp, const void *buf, size_t len) 246{ 247 return sp->store(sp, buf, len); 248} 249 250/** 251 * Set the return code that will be used when end of storage is reached. 252 * 253 * @param sp the storage 254 * @param code the error code to return on end of storage 255 * 256 * @ingroup krb5_storage 257 */ 258 259KRB5_LIB_FUNCTION void KRB5_LIB_CALL 260krb5_storage_set_eof_code(krb5_storage *sp, int code) 261{ 262 sp->eof_code = code; 263} 264 265/** 266 * Get the return code that will be used when end of storage is reached. 267 * 268 * @param sp the storage 269 * 270 * @return storage error code 271 * 272 * @ingroup krb5_storage 273 */ 274 275KRB5_LIB_FUNCTION int KRB5_LIB_CALL 276krb5_storage_get_eof_code(krb5_storage *sp) 277{ 278 return sp->eof_code; 279} 280 281/** 282 * Free a krb5 storage. 283 * 284 * @param sp the storage to free. 285 * 286 * @return An Kerberos 5 error code. 287 * 288 * @ingroup krb5_storage 289 */ 290 291KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 292krb5_storage_free(krb5_storage *sp) 293{ 294 if (sp == NULL) 295 return 0; 296 if(sp->free) 297 (*sp->free)(sp); 298 free(sp->data); 299 free(sp); 300 return 0; 301} 302 303/** 304 * Copy the contnent of storage 305 * 306 * @param sp the storage to copy to a data 307 * @param data the copied data, free with krb5_data_free() 308 * 309 * @return 0 for success, or a Kerberos 5 error code on failure. 310 * 311 * @ingroup krb5_storage 312 */ 313 314KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 315krb5_storage_to_data(krb5_storage *sp, krb5_data *data) 316{ 317 off_t pos, size; 318 krb5_error_code ret; 319 320 pos = sp->seek(sp, 0, SEEK_CUR); 321 if (pos < 0) 322 return HEIM_ERR_NOT_SEEKABLE; 323 size = sp->seek(sp, 0, SEEK_END); 324 ret = size_too_large(sp, size); 325 if (ret) 326 return ret; 327 ret = krb5_data_alloc(data, size); 328 if (ret) { 329 sp->seek(sp, pos, SEEK_SET); 330 return ret; 331 } 332 if (size) { 333 sp->seek(sp, 0, SEEK_SET); 334 sp->fetch(sp, data->data, data->length); 335 sp->seek(sp, pos, SEEK_SET); 336 } 337 return 0; 338} 339 340static krb5_error_code 341krb5_store_int(krb5_storage *sp, 342 int64_t value, 343 size_t len) 344{ 345 int ret; 346 unsigned char v[8]; 347 348 if (len > sizeof(v)) 349 return EINVAL; 350 _krb5_put_int(v, value, len); 351 ret = sp->store(sp, v, len); 352 if (ret < 0) 353 return errno; 354 if ((size_t)ret != len) 355 return sp->eof_code; 356 return 0; 357} 358 359/** 360 * Store a int32 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 371KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 372krb5_store_int32(krb5_storage *sp, 373 int32_t value) 374{ 375 if(BYTEORDER_IS_HOST(sp)) 376 value = htonl(value); 377 else if(BYTEORDER_IS_LE(sp)) 378 value = bswap32(value); 379 return krb5_store_int(sp, value, 4); 380} 381 382/** 383 * Store a int64 to storage, byte order is controlled by the settings 384 * on the storage, see krb5_storage_set_byteorder(). 385 * 386 * @param sp the storage to write too 387 * @param value the value to store 388 * 389 * @return 0 for success, or a Kerberos 5 error code on failure. 390 * 391 * @ingroup krb5_storage 392 */ 393 394KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 395krb5_store_int64(krb5_storage *sp, 396 int64_t value) 397{ 398 if (BYTEORDER_IS_HOST(sp)) 399#ifdef WORDS_BIGENDIAN 400 ; 401#else 402 value = bswap64(value); /* There's no ntohll() */ 403#endif 404 else if (BYTEORDER_IS_LE(sp)) 405 value = bswap64(value); 406 return krb5_store_int(sp, value, 8); 407} 408 409/** 410 * Store a uint32 to storage, byte order is controlled by the settings 411 * on the storage, see krb5_storage_set_byteorder(). 412 * 413 * @param sp the storage to write too 414 * @param value the value to store 415 * 416 * @return 0 for success, or a Kerberos 5 error code on failure. 417 * 418 * @ingroup krb5_storage 419 */ 420 421KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 422krb5_store_uint32(krb5_storage *sp, 423 uint32_t value) 424{ 425 return krb5_store_int32(sp, (int32_t)value); 426} 427 428/** 429 * Store a uint64 to storage, byte order is controlled by the settings 430 * on the storage, see krb5_storage_set_byteorder(). 431 * 432 * @param sp the storage to write too 433 * @param value the value to store 434 * 435 * @return 0 for success, or a Kerberos 5 error code on failure. 436 * 437 * @ingroup krb5_storage 438 */ 439 440KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 441krb5_store_uint64(krb5_storage *sp, 442 uint64_t value) 443{ 444 return krb5_store_int64(sp, (int64_t)value); 445} 446 447static krb5_error_code 448krb5_ret_int(krb5_storage *sp, 449 int64_t *value, 450 size_t len) 451{ 452 int ret; 453 unsigned char v[8]; 454 uint64_t w; 455 *value = 0; /* quiets warnings */ 456 ret = sp->fetch(sp, v, len); 457 if (ret < 0) 458 return errno; 459 if ((size_t)ret != len) 460 return sp->eof_code; 461 _krb5_get_int64(v, &w, len); 462 *value = w; 463 return 0; 464} 465 466/** 467 * Read a int64 from storage, byte order is controlled by the settings 468 * on the storage, see krb5_storage_set_byteorder(). 469 * 470 * @param sp the storage to write too 471 * @param value the value read from the buffer 472 * 473 * @return 0 for success, or a Kerberos 5 error code on failure. 474 * 475 * @ingroup krb5_storage 476 */ 477 478KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 479krb5_ret_int64(krb5_storage *sp, 480 int64_t *value) 481{ 482 krb5_error_code ret = krb5_ret_int(sp, value, 8); 483 if(ret) 484 return ret; 485 if(BYTEORDER_IS_HOST(sp)) 486#ifdef WORDS_BIGENDIAN 487 ; 488#else 489 *value = bswap64(*value); /* There's no ntohll() */ 490#endif 491 else if(BYTEORDER_IS_LE(sp)) 492 *value = bswap64(*value); 493 return 0; 494} 495 496/** 497 * Read a uint64 from storage, byte order is controlled by the settings 498 * on the storage, see krb5_storage_set_byteorder(). 499 * 500 * @param sp the storage to write too 501 * @param value the value read from the buffer 502 * 503 * @return 0 for success, or a Kerberos 5 error code on failure. 504 * 505 * @ingroup krb5_storage 506 */ 507 508KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 509krb5_ret_uint64(krb5_storage *sp, 510 uint64_t *value) 511{ 512 krb5_error_code ret; 513 int64_t v; 514 515 ret = krb5_ret_int64(sp, &v); 516 if (ret == 0) 517 *value = (uint64_t)v; 518 519 return ret; 520} 521 522/** 523 * Read a int32 from storage, byte order is controlled by the settings 524 * on the storage, see krb5_storage_set_byteorder(). 525 * 526 * @param sp the storage to write too 527 * @param value the value read from the buffer 528 * 529 * @return 0 for success, or a Kerberos 5 error code on failure. 530 * 531 * @ingroup krb5_storage 532 */ 533 534KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 535krb5_ret_int32(krb5_storage *sp, 536 int32_t *value) 537{ 538 int64_t v; 539 540 krb5_error_code ret = krb5_ret_int(sp, &v, 4); 541 if (ret) 542 return ret; 543 *value = v; 544 if (BYTEORDER_IS_HOST(sp)) 545 *value = htonl(*value); 546 else if (BYTEORDER_IS_LE(sp)) 547 *value = bswap32(*value); 548 return 0; 549} 550 551/** 552 * Read a uint32 from storage, byte order is controlled by the settings 553 * on the storage, see krb5_storage_set_byteorder(). 554 * 555 * @param sp the storage to write too 556 * @param value the value read from the buffer 557 * 558 * @return 0 for success, or a Kerberos 5 error code on failure. 559 * 560 * @ingroup krb5_storage 561 */ 562 563KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 564krb5_ret_uint32(krb5_storage *sp, uint32_t *value) 565{ 566 krb5_error_code ret; 567 int32_t v; 568 569 ret = krb5_ret_int32(sp, &v); 570 if (ret == 0) 571 *value = (uint32_t)v; 572 573 return ret; 574} 575 576/** 577 * Store a int16 to storage, byte order is controlled by the settings 578 * on the storage, see krb5_storage_set_byteorder(). 579 * 580 * @param sp the storage to write too 581 * @param value the value to store 582 * 583 * @return 0 for success, or a Kerberos 5 error code on failure. 584 * 585 * @ingroup krb5_storage 586 */ 587 588KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 589krb5_store_int16(krb5_storage *sp, 590 int16_t value) 591{ 592 if(BYTEORDER_IS_HOST(sp)) 593 value = htons(value); 594 else if(BYTEORDER_IS_LE(sp)) 595 value = bswap16(value); 596 return krb5_store_int(sp, value, 2); 597} 598 599/** 600 * Store a uint16 to storage, byte order is controlled by the settings 601 * on the storage, see krb5_storage_set_byteorder(). 602 * 603 * @param sp the storage to write too 604 * @param value the value to store 605 * 606 * @return 0 for success, or a Kerberos 5 error code on failure. 607 * 608 * @ingroup krb5_storage 609 */ 610 611KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 612krb5_store_uint16(krb5_storage *sp, 613 uint16_t value) 614{ 615 return krb5_store_int16(sp, (int16_t)value); 616} 617 618/** 619 * Read a int16 from storage, byte order is controlled by the settings 620 * on the storage, see krb5_storage_set_byteorder(). 621 * 622 * @param sp the storage to write too 623 * @param value the value read from the buffer 624 * 625 * @return 0 for success, or a Kerberos 5 error code on failure. 626 * 627 * @ingroup krb5_storage 628 */ 629 630KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 631krb5_ret_int16(krb5_storage *sp, 632 int16_t *value) 633{ 634 int64_t v; 635 int ret; 636 ret = krb5_ret_int(sp, &v, 2); 637 if(ret) 638 return ret; 639 *value = v; 640 if(BYTEORDER_IS_HOST(sp)) 641 *value = htons(*value); 642 else if(BYTEORDER_IS_LE(sp)) 643 *value = bswap16(*value); 644 return 0; 645} 646 647/** 648 * Read a int16 from storage, byte order is controlled by the settings 649 * on the storage, see krb5_storage_set_byteorder(). 650 * 651 * @param sp the storage to write too 652 * @param value the value read from the buffer 653 * 654 * @return 0 for success, or a Kerberos 5 error code on failure. 655 * 656 * @ingroup krb5_storage 657 */ 658 659KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 660krb5_ret_uint16(krb5_storage *sp, 661 uint16_t *value) 662{ 663 krb5_error_code ret; 664 int16_t v; 665 666 ret = krb5_ret_int16(sp, &v); 667 if (ret == 0) 668 *value = (uint16_t)v; 669 670 return ret; 671} 672 673/** 674 * Store a int8 to storage. 675 * 676 * @param sp the storage to write too 677 * @param value the value to store 678 * 679 * @return 0 for success, or a Kerberos 5 error code on failure. 680 * 681 * @ingroup krb5_storage 682 */ 683 684KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 685krb5_store_int8(krb5_storage *sp, 686 int8_t value) 687{ 688 int ret; 689 690 ret = sp->store(sp, &value, sizeof(value)); 691 if (ret != sizeof(value)) 692 return (ret<0)?errno:sp->eof_code; 693 return 0; 694} 695 696/** 697 * Store a uint8 to storage. 698 * 699 * @param sp the storage to write too 700 * @param value the value to store 701 * 702 * @return 0 for success, or a Kerberos 5 error code on failure. 703 * 704 * @ingroup krb5_storage 705 */ 706 707KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 708krb5_store_uint8(krb5_storage *sp, 709 uint8_t value) 710{ 711 return krb5_store_int8(sp, (int8_t)value); 712} 713 714/** 715 * Read a int8 from storage 716 * 717 * @param sp the storage to write too 718 * @param value the value read from the buffer 719 * 720 * @return 0 for success, or a Kerberos 5 error code on failure. 721 * 722 * @ingroup krb5_storage 723 */ 724 725KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 726krb5_ret_int8(krb5_storage *sp, 727 int8_t *value) 728{ 729 int ret; 730 731 ret = sp->fetch(sp, value, sizeof(*value)); 732 if (ret != sizeof(*value)) 733 return (ret<0)?errno:sp->eof_code; 734 return 0; 735} 736 737/** 738 * Read a uint8 from storage 739 * 740 * @param sp the storage to write too 741 * @param value the value read from the buffer 742 * 743 * @return 0 for success, or a Kerberos 5 error code on failure. 744 * 745 * @ingroup krb5_storage 746 */ 747 748KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 749krb5_ret_uint8(krb5_storage *sp, 750 uint8_t *value) 751{ 752 krb5_error_code ret; 753 int8_t v; 754 755 ret = krb5_ret_int8(sp, &v); 756 if (ret == 0) 757 *value = (uint8_t)v; 758 759 return ret; 760} 761 762/** 763 * Store a data to the storage. The data is stored with an int32 as 764 * lenght plus the data (not padded). 765 * 766 * @param sp the storage buffer to write to 767 * @param data the buffer to store. 768 * 769 * @return 0 on success, a Kerberos 5 error code on failure. 770 * 771 * @ingroup krb5_storage 772 */ 773 774KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 775krb5_store_data(krb5_storage *sp, 776 krb5_data data) 777{ 778 int ret; 779 ret = krb5_store_int32(sp, data.length); 780 if(ret < 0) 781 return ret; 782 ret = sp->store(sp, data.data, data.length); 783 if(ret < 0) 784 return errno; 785 if((size_t)ret != data.length) 786 return sp->eof_code; 787 return 0; 788} 789 790/** 791 * Parse a data from the storage. 792 * 793 * @param sp the storage buffer to read from 794 * @param data the parsed data 795 * 796 * @return 0 on success, a Kerberos 5 error code on failure. 797 * 798 * @ingroup krb5_storage 799 */ 800 801KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 802krb5_ret_data(krb5_storage *sp, 803 krb5_data *data) 804{ 805 int ret; 806 int32_t size; 807 808 ret = krb5_ret_int32(sp, &size); 809 if(ret) 810 return ret; 811 ret = size_too_large(sp, size); 812 if (ret) 813 return ret; 814 ret = krb5_data_alloc (data, size); 815 if (ret) 816 return ret; 817 if (size) { 818 ret = sp->fetch(sp, data->data, size); 819 if(ret != size) { 820 krb5_data_free(data); 821 return (ret < 0)? errno : sp->eof_code; 822 } 823 } 824 return 0; 825} 826 827/** 828 * Store a string to the buffer. The data is formated as an len:uint32 829 * plus the string itself (not padded). 830 * 831 * @param sp the storage buffer to write to 832 * @param s the string to store. 833 * 834 * @return 0 on success, a Kerberos 5 error code on failure. 835 * 836 * @ingroup krb5_storage 837 */ 838 839KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 840krb5_store_string(krb5_storage *sp, const char *s) 841{ 842 krb5_data data; 843 data.length = strlen(s); 844 data.data = rk_UNCONST(s); 845 return krb5_store_data(sp, data); 846} 847 848/** 849 * Parse a string from the storage. 850 * 851 * @param sp the storage buffer to read from 852 * @param string the parsed string 853 * 854 * @return 0 on success, a Kerberos 5 error code on failure. 855 * 856 * @ingroup krb5_storage 857 */ 858 859 860KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 861krb5_ret_string(krb5_storage *sp, 862 char **string) 863{ 864 int ret; 865 krb5_data data; 866 ret = krb5_ret_data(sp, &data); 867 if(ret) 868 return ret; 869 *string = realloc(data.data, data.length + 1); 870 if(*string == NULL){ 871 free(data.data); 872 return ENOMEM; 873 } 874 (*string)[data.length] = 0; 875 return 0; 876} 877 878/** 879 * Store a zero terminated string to the buffer. The data is stored 880 * one character at a time until a NUL is stored. 881 * 882 * @param sp the storage buffer to write to 883 * @param s the string to store. 884 * 885 * @return 0 on success, a Kerberos 5 error code on failure. 886 * 887 * @ingroup krb5_storage 888 */ 889 890KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 891krb5_store_stringz(krb5_storage *sp, const char *s) 892{ 893 size_t len = strlen(s) + 1; 894 ssize_t ret; 895 896 ret = sp->store(sp, s, len); 897 if(ret < 0) 898 return ret; 899 if((size_t)ret != len) 900 return sp->eof_code; 901 return 0; 902} 903 904/** 905 * Parse zero terminated string from the storage. 906 * 907 * @param sp the storage buffer to read from 908 * @param string the parsed string 909 * 910 * @return 0 on success, a Kerberos 5 error code on failure. 911 * 912 * @ingroup krb5_storage 913 */ 914 915KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 916krb5_ret_stringz(krb5_storage *sp, 917 char **string) 918{ 919 char c; 920 char *s = NULL; 921 size_t len = 0; 922 ssize_t ret; 923 924 while((ret = sp->fetch(sp, &c, 1)) == 1){ 925 krb5_error_code eret; 926 char *tmp; 927 928 len++; 929 eret = size_too_large(sp, len); 930 if (eret) { 931 free(s); 932 return eret; 933 } 934 tmp = realloc (s, len); 935 if (tmp == NULL) { 936 free (s); 937 return ENOMEM; 938 } 939 s = tmp; 940 s[len - 1] = c; 941 if(c == 0) 942 break; 943 } 944 if(ret != 1){ 945 free(s); 946 if(ret == 0) 947 return sp->eof_code; 948 return ret; 949 } 950 *string = s; 951 return 0; 952} 953 954KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 955krb5_store_stringnl(krb5_storage *sp, const char *s) 956{ 957 size_t len = strlen(s); 958 ssize_t ret; 959 960 ret = sp->store(sp, s, len); 961 if(ret < 0) 962 return ret; 963 if((size_t)ret != len) 964 return sp->eof_code; 965 ret = sp->store(sp, "\n", 1); 966 if(ret != 1) { 967 if(ret < 0) 968 return ret; 969 else 970 return sp->eof_code; 971 } 972 973 return 0; 974 975} 976 977KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 978krb5_ret_stringnl(krb5_storage *sp, 979 char **string) 980{ 981 int expect_nl = 0; 982 char c; 983 char *s = NULL; 984 size_t len = 0; 985 ssize_t ret; 986 987 while((ret = sp->fetch(sp, &c, 1)) == 1){ 988 krb5_error_code eret; 989 char *tmp; 990 991 if (c == '\r') { 992 expect_nl = 1; 993 continue; 994 } 995 if (expect_nl && c != '\n') { 996 free(s); 997 return KRB5_BADMSGTYPE; 998 } 999 1000 len++; 1001 eret = size_too_large(sp, len); 1002 if (eret) { 1003 free(s); 1004 return eret; 1005 } 1006 tmp = realloc (s, len); 1007 if (tmp == NULL) { 1008 free (s); 1009 return ENOMEM; 1010 } 1011 s = tmp; 1012 if(c == '\n') { 1013 s[len - 1] = '\0'; 1014 break; 1015 } 1016 s[len - 1] = c; 1017 } 1018 if(ret != 1){ 1019 free(s); 1020 if(ret == 0) 1021 return sp->eof_code; 1022 return ret; 1023 } 1024 *string = s; 1025 return 0; 1026} 1027 1028/** 1029 * Write a principal block to storage. 1030 * 1031 * @param sp the storage buffer to write to 1032 * @param p the principal block to write. 1033 * 1034 * @return 0 on success, a Kerberos 5 error code on failure. 1035 * 1036 * @ingroup krb5_storage 1037 */ 1038 1039KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1040krb5_store_principal(krb5_storage *sp, 1041 krb5_const_principal p) 1042{ 1043 size_t i; 1044 int ret; 1045 1046 if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) { 1047 ret = krb5_store_int32(sp, p->name.name_type); 1048 if(ret) return ret; 1049 } 1050 if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS)) 1051 ret = krb5_store_int32(sp, p->name.name_string.len + 1); 1052 else 1053 ret = krb5_store_int32(sp, p->name.name_string.len); 1054 1055 if(ret) return ret; 1056 ret = krb5_store_string(sp, p->realm); 1057 if(ret) return ret; 1058 for(i = 0; i < p->name.name_string.len; i++){ 1059 ret = krb5_store_string(sp, p->name.name_string.val[i]); 1060 if(ret) return ret; 1061 } 1062 return 0; 1063} 1064 1065/** 1066 * Parse principal from the storage. 1067 * 1068 * @param sp the storage buffer to read from 1069 * @param princ the parsed principal 1070 * 1071 * @return 0 on success, a Kerberos 5 error code on failure. 1072 * 1073 * @ingroup krb5_storage 1074 */ 1075 1076KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1077krb5_ret_principal(krb5_storage *sp, 1078 krb5_principal *princ) 1079{ 1080 int i; 1081 int ret; 1082 krb5_principal p; 1083 int32_t type; 1084 int32_t ncomp; 1085 1086 p = calloc(1, sizeof(*p)); 1087 if(p == NULL) 1088 return ENOMEM; 1089 1090 if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) 1091 type = KRB5_NT_UNKNOWN; 1092 else if((ret = krb5_ret_int32(sp, &type))){ 1093 free(p); 1094 return ret; 1095 } 1096 if((ret = krb5_ret_int32(sp, &ncomp))){ 1097 free(p); 1098 return ret; 1099 } 1100 if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS)) 1101 ncomp--; 1102 if (ncomp < 0) { 1103 free(p); 1104 return EINVAL; 1105 } 1106 ret = size_too_large_num(sp, ncomp, sizeof(p->name.name_string.val[0])); 1107 if (ret) { 1108 free(p); 1109 return ret; 1110 } 1111 p->name.name_type = type; 1112 p->name.name_string.len = ncomp; 1113 ret = krb5_ret_string(sp, &p->realm); 1114 if(ret) { 1115 free(p); 1116 return ret; 1117 } 1118 p->name.name_string.val = calloc(ncomp, sizeof(p->name.name_string.val[0])); 1119 if(p->name.name_string.val == NULL && ncomp != 0){ 1120 free(p->realm); 1121 free(p); 1122 return ENOMEM; 1123 } 1124 for(i = 0; i < ncomp; i++){ 1125 ret = krb5_ret_string(sp, &p->name.name_string.val[i]); 1126 if(ret) { 1127 while (i >= 0) 1128 free(p->name.name_string.val[i--]); 1129 free(p->realm); 1130 free(p); 1131 return ret; 1132 } 1133 } 1134 *princ = p; 1135 return 0; 1136} 1137 1138/** 1139 * Store a keyblock to the storage. 1140 * 1141 * @param sp the storage buffer to write to 1142 * @param p the keyblock to write 1143 * 1144 * @return 0 on success, a Kerberos 5 error code on failure. 1145 * 1146 * @ingroup krb5_storage 1147 */ 1148 1149KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1150krb5_store_keyblock(krb5_storage *sp, krb5_keyblock p) 1151{ 1152 int ret; 1153 ret = krb5_store_int16(sp, p.keytype); 1154 if(ret) return ret; 1155 1156 if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){ 1157 /* this should really be enctype, but it is the same as 1158 keytype nowadays */ 1159 ret = krb5_store_int16(sp, p.keytype); 1160 if(ret) return ret; 1161 } 1162 1163 ret = krb5_store_data(sp, p.keyvalue); 1164 return ret; 1165} 1166 1167/** 1168 * Read a keyblock from the storage. 1169 * 1170 * @param sp the storage buffer to write to 1171 * @param p the keyblock read from storage, free using krb5_free_keyblock() 1172 * 1173 * @return 0 on success, a Kerberos 5 error code on failure. 1174 * 1175 * @ingroup krb5_storage 1176 */ 1177 1178KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1179krb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p) 1180{ 1181 int ret; 1182 int16_t tmp; 1183 1184 ret = krb5_ret_int16(sp, &tmp); 1185 if(ret) return ret; 1186 p->keytype = tmp; 1187 1188 if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){ 1189 ret = krb5_ret_int16(sp, &tmp); 1190 if(ret) return ret; 1191 } 1192 1193 ret = krb5_ret_data(sp, &p->keyvalue); 1194 return ret; 1195} 1196 1197/** 1198 * Write a times block to storage. 1199 * 1200 * @param sp the storage buffer to write to 1201 * @param times the times block to write. 1202 * 1203 * @return 0 on success, a Kerberos 5 error code on failure. 1204 * 1205 * @ingroup krb5_storage 1206 */ 1207 1208KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1209krb5_store_times(krb5_storage *sp, krb5_times times) 1210{ 1211 int ret; 1212 ret = krb5_store_int32(sp, times.authtime); 1213 if(ret) return ret; 1214 ret = krb5_store_int32(sp, times.starttime); 1215 if(ret) return ret; 1216 ret = krb5_store_int32(sp, times.endtime); 1217 if(ret) return ret; 1218 ret = krb5_store_int32(sp, times.renew_till); 1219 return ret; 1220} 1221 1222/** 1223 * Read a times block from the storage. 1224 * 1225 * @param sp the storage buffer to write to 1226 * @param times the times block read from storage 1227 * 1228 * @return 0 on success, a Kerberos 5 error code on failure. 1229 * 1230 * @ingroup krb5_storage 1231 */ 1232 1233KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1234krb5_ret_times(krb5_storage *sp, krb5_times *times) 1235{ 1236 int ret; 1237 int32_t tmp; 1238 ret = krb5_ret_int32(sp, &tmp); 1239 times->authtime = tmp; 1240 if(ret) return ret; 1241 ret = krb5_ret_int32(sp, &tmp); 1242 times->starttime = tmp; 1243 if(ret) return ret; 1244 ret = krb5_ret_int32(sp, &tmp); 1245 times->endtime = tmp; 1246 if(ret) return ret; 1247 ret = krb5_ret_int32(sp, &tmp); 1248 times->renew_till = tmp; 1249 return ret; 1250} 1251 1252/** 1253 * Write a address block to storage. 1254 * 1255 * @param sp the storage buffer to write to 1256 * @param p the address block to write. 1257 * 1258 * @return 0 on success, a Kerberos 5 error code on failure. 1259 * 1260 * @ingroup krb5_storage 1261 */ 1262 1263KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1264krb5_store_address(krb5_storage *sp, krb5_address p) 1265{ 1266 int ret; 1267 ret = krb5_store_int16(sp, p.addr_type); 1268 if(ret) return ret; 1269 ret = krb5_store_data(sp, p.address); 1270 return ret; 1271} 1272 1273/** 1274 * Read a address block from the storage. 1275 * 1276 * @param sp the storage buffer to write to 1277 * @param adr the address block read from storage 1278 * 1279 * @return 0 on success, a Kerberos 5 error code on failure. 1280 * 1281 * @ingroup krb5_storage 1282 */ 1283 1284KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1285krb5_ret_address(krb5_storage *sp, krb5_address *adr) 1286{ 1287 int16_t t; 1288 int ret; 1289 ret = krb5_ret_int16(sp, &t); 1290 if(ret) return ret; 1291 adr->addr_type = t; 1292 ret = krb5_ret_data(sp, &adr->address); 1293 return ret; 1294} 1295 1296/** 1297 * Write a addresses block to storage. 1298 * 1299 * @param sp the storage buffer to write to 1300 * @param p the addresses block to write. 1301 * 1302 * @return 0 on success, a Kerberos 5 error code on failure. 1303 * 1304 * @ingroup krb5_storage 1305 */ 1306 1307KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1308krb5_store_addrs(krb5_storage *sp, krb5_addresses p) 1309{ 1310 size_t i; 1311 int ret; 1312 ret = krb5_store_int32(sp, p.len); 1313 if(ret) return ret; 1314 for(i = 0; i<p.len; i++){ 1315 ret = krb5_store_address(sp, p.val[i]); 1316 if(ret) break; 1317 } 1318 return ret; 1319} 1320 1321/** 1322 * Read a addresses block from the storage. 1323 * 1324 * @param sp the storage buffer to write to 1325 * @param adr the addresses block read from storage 1326 * 1327 * @return 0 on success, a Kerberos 5 error code on failure. 1328 * 1329 * @ingroup krb5_storage 1330 */ 1331 1332KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1333krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr) 1334{ 1335 size_t i; 1336 int ret; 1337 int32_t tmp; 1338 1339 ret = krb5_ret_int32(sp, &tmp); 1340 if(ret) return ret; 1341 ret = size_too_large_num(sp, tmp, sizeof(adr->val[0])); 1342 if (ret) return ret; 1343 adr->len = tmp; 1344 ALLOC(adr->val, adr->len); 1345 if (adr->val == NULL && adr->len != 0) 1346 return ENOMEM; 1347 for(i = 0; i < adr->len; i++){ 1348 ret = krb5_ret_address(sp, &adr->val[i]); 1349 if(ret) break; 1350 } 1351 return ret; 1352} 1353 1354/** 1355 * Write a auth data block to storage. 1356 * 1357 * @param sp the storage buffer to write to 1358 * @param auth the auth data block to write. 1359 * 1360 * @return 0 on success, a Kerberos 5 error code on failure. 1361 * 1362 * @ingroup krb5_storage 1363 */ 1364 1365KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1366krb5_store_authdata(krb5_storage *sp, krb5_authdata auth) 1367{ 1368 krb5_error_code ret; 1369 size_t i; 1370 ret = krb5_store_int32(sp, auth.len); 1371 if(ret) return ret; 1372 for(i = 0; i < auth.len; i++){ 1373 ret = krb5_store_int16(sp, auth.val[i].ad_type); 1374 if(ret) break; 1375 ret = krb5_store_data(sp, auth.val[i].ad_data); 1376 if(ret) break; 1377 } 1378 return 0; 1379} 1380 1381/** 1382 * Read a auth data from the storage. 1383 * 1384 * @param sp the storage buffer to write to 1385 * @param auth the auth data block read from storage 1386 * 1387 * @return 0 on success, a Kerberos 5 error code on failure. 1388 * 1389 * @ingroup krb5_storage 1390 */ 1391 1392KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1393krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth) 1394{ 1395 krb5_error_code ret; 1396 int32_t tmp; 1397 int16_t tmp2; 1398 int i; 1399 ret = krb5_ret_int32(sp, &tmp); 1400 if(ret) return ret; 1401 ret = size_too_large_num(sp, tmp, sizeof(auth->val[0])); 1402 if (ret) return ret; 1403 ALLOC_SEQ(auth, tmp); 1404 if (auth->val == NULL && tmp != 0) 1405 return ENOMEM; 1406 for(i = 0; i < tmp; i++){ 1407 ret = krb5_ret_int16(sp, &tmp2); 1408 if(ret) break; 1409 auth->val[i].ad_type = tmp2; 1410 ret = krb5_ret_data(sp, &auth->val[i].ad_data); 1411 if(ret) break; 1412 } 1413 return ret; 1414} 1415 1416static int32_t 1417bitswap32(int32_t b) 1418{ 1419 int32_t r = 0; 1420 int i; 1421 for (i = 0; i < 32; i++) { 1422 r = r << 1 | (b & 1); 1423 b = b >> 1; 1424 } 1425 return r; 1426} 1427 1428/** 1429 * Write a credentials block to storage. 1430 * 1431 * @param sp the storage buffer to write to 1432 * @param creds the creds block to write. 1433 * 1434 * @return 0 on success, a Kerberos 5 error code on failure. 1435 * 1436 * @ingroup krb5_storage 1437 */ 1438 1439KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1440krb5_store_creds(krb5_storage *sp, krb5_creds *creds) 1441{ 1442 int ret; 1443 1444 ret = krb5_store_principal(sp, creds->client); 1445 if(ret) 1446 return ret; 1447 ret = krb5_store_principal(sp, creds->server); 1448 if(ret) 1449 return ret; 1450 ret = krb5_store_keyblock(sp, creds->session); 1451 if(ret) 1452 return ret; 1453 ret = krb5_store_times(sp, creds->times); 1454 if(ret) 1455 return ret; 1456 ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */ 1457 if(ret) 1458 return ret; 1459 ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b))); 1460 if(ret) 1461 return ret; 1462 ret = krb5_store_addrs(sp, creds->addresses); 1463 if(ret) 1464 return ret; 1465 ret = krb5_store_authdata(sp, creds->authdata); 1466 if(ret) 1467 return ret; 1468 ret = krb5_store_data(sp, creds->ticket); 1469 if(ret) 1470 return ret; 1471 ret = krb5_store_data(sp, creds->second_ticket); 1472 return ret; 1473} 1474 1475/** 1476 * Read a credentials block from the storage. 1477 * 1478 * @param sp the storage buffer to write to 1479 * @param creds the credentials block read from storage 1480 * 1481 * @return 0 on success, a Kerberos 5 error code on failure. 1482 * 1483 * @ingroup krb5_storage 1484 */ 1485 1486KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1487krb5_ret_creds(krb5_storage *sp, krb5_creds *creds) 1488{ 1489 krb5_error_code ret; 1490 int8_t dummy8; 1491 int32_t dummy32; 1492 1493 memset(creds, 0, sizeof(*creds)); 1494 ret = krb5_ret_principal (sp, &creds->client); 1495 if(ret) goto cleanup; 1496 ret = krb5_ret_principal (sp, &creds->server); 1497 if(ret) goto cleanup; 1498 ret = krb5_ret_keyblock (sp, &creds->session); 1499 if(ret) goto cleanup; 1500 ret = krb5_ret_times (sp, &creds->times); 1501 if(ret) goto cleanup; 1502 ret = krb5_ret_int8 (sp, &dummy8); 1503 if(ret) goto cleanup; 1504 ret = krb5_ret_int32 (sp, &dummy32); 1505 if(ret) goto cleanup; 1506 creds->flags.b = int2TicketFlags(bitswap32(dummy32)); 1507 ret = krb5_ret_addrs (sp, &creds->addresses); 1508 if(ret) goto cleanup; 1509 ret = krb5_ret_authdata (sp, &creds->authdata); 1510 if(ret) goto cleanup; 1511 ret = krb5_ret_data (sp, &creds->ticket); 1512 if(ret) goto cleanup; 1513 ret = krb5_ret_data (sp, &creds->second_ticket); 1514cleanup: 1515 if(ret) { 1516#if 0 1517 krb5_free_cred_contents(context, creds); /* XXX */ 1518#endif 1519 } 1520 return ret; 1521} 1522 1523#define SC_CLIENT_PRINCIPAL 0x0001 1524#define SC_SERVER_PRINCIPAL 0x0002 1525#define SC_SESSION_KEY 0x0004 1526#define SC_TICKET 0x0008 1527#define SC_SECOND_TICKET 0x0010 1528#define SC_AUTHDATA 0x0020 1529#define SC_ADDRESSES 0x0040 1530 1531/** 1532 * Write a tagged credentials block to storage. 1533 * 1534 * @param sp the storage buffer to write to 1535 * @param creds the creds block to write. 1536 * 1537 * @return 0 on success, a Kerberos 5 error code on failure. 1538 * 1539 * @ingroup krb5_storage 1540 */ 1541 1542KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1543krb5_store_creds_tag(krb5_storage *sp, krb5_creds *creds) 1544{ 1545 int ret; 1546 int32_t header = 0; 1547 1548 if (creds->client) 1549 header |= SC_CLIENT_PRINCIPAL; 1550 if (creds->server) 1551 header |= SC_SERVER_PRINCIPAL; 1552 if (creds->session.keytype != ETYPE_NULL) 1553 header |= SC_SESSION_KEY; 1554 if (creds->ticket.data) 1555 header |= SC_TICKET; 1556 if (creds->second_ticket.length) 1557 header |= SC_SECOND_TICKET; 1558 if (creds->authdata.len) 1559 header |= SC_AUTHDATA; 1560 if (creds->addresses.len) 1561 header |= SC_ADDRESSES; 1562 1563 ret = krb5_store_int32(sp, header); 1564 if (ret) 1565 return ret; 1566 1567 if (creds->client) { 1568 ret = krb5_store_principal(sp, creds->client); 1569 if(ret) 1570 return ret; 1571 } 1572 1573 if (creds->server) { 1574 ret = krb5_store_principal(sp, creds->server); 1575 if(ret) 1576 return ret; 1577 } 1578 1579 if (creds->session.keytype != ETYPE_NULL) { 1580 ret = krb5_store_keyblock(sp, creds->session); 1581 if(ret) 1582 return ret; 1583 } 1584 1585 ret = krb5_store_times(sp, creds->times); 1586 if(ret) 1587 return ret; 1588 ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */ 1589 if(ret) 1590 return ret; 1591 1592 ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b))); 1593 if(ret) 1594 return ret; 1595 1596 if (creds->addresses.len) { 1597 ret = krb5_store_addrs(sp, creds->addresses); 1598 if(ret) 1599 return ret; 1600 } 1601 1602 if (creds->authdata.len) { 1603 ret = krb5_store_authdata(sp, creds->authdata); 1604 if(ret) 1605 return ret; 1606 } 1607 1608 if (creds->ticket.data) { 1609 ret = krb5_store_data(sp, creds->ticket); 1610 if(ret) 1611 return ret; 1612 } 1613 1614 if (creds->second_ticket.data) { 1615 ret = krb5_store_data(sp, creds->second_ticket); 1616 if (ret) 1617 return ret; 1618 } 1619 1620 return ret; 1621} 1622 1623/** 1624 * Read a tagged credentials block from the storage. 1625 * 1626 * @param sp the storage buffer to write to 1627 * @param creds the credentials block read from storage 1628 * 1629 * @return 0 on success, a Kerberos 5 error code on failure. 1630 * 1631 * @ingroup krb5_storage 1632 */ 1633 1634KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 1635krb5_ret_creds_tag(krb5_storage *sp, 1636 krb5_creds *creds) 1637{ 1638 krb5_error_code ret; 1639 int8_t dummy8; 1640 int32_t dummy32, header; 1641 1642 memset(creds, 0, sizeof(*creds)); 1643 1644 ret = krb5_ret_int32 (sp, &header); 1645 if (ret) goto cleanup; 1646 1647 if (header & SC_CLIENT_PRINCIPAL) { 1648 ret = krb5_ret_principal (sp, &creds->client); 1649 if(ret) goto cleanup; 1650 } 1651 if (header & SC_SERVER_PRINCIPAL) { 1652 ret = krb5_ret_principal (sp, &creds->server); 1653 if(ret) goto cleanup; 1654 } 1655 if (header & SC_SESSION_KEY) { 1656 ret = krb5_ret_keyblock (sp, &creds->session); 1657 if(ret) goto cleanup; 1658 } 1659 ret = krb5_ret_times (sp, &creds->times); 1660 if(ret) goto cleanup; 1661 ret = krb5_ret_int8 (sp, &dummy8); 1662 if(ret) goto cleanup; 1663 ret = krb5_ret_int32 (sp, &dummy32); 1664 if(ret) goto cleanup; 1665 creds->flags.b = int2TicketFlags(bitswap32(dummy32)); 1666 if (header & SC_ADDRESSES) { 1667 ret = krb5_ret_addrs (sp, &creds->addresses); 1668 if(ret) goto cleanup; 1669 } 1670 if (header & SC_AUTHDATA) { 1671 ret = krb5_ret_authdata (sp, &creds->authdata); 1672 if(ret) goto cleanup; 1673 } 1674 if (header & SC_TICKET) { 1675 ret = krb5_ret_data (sp, &creds->ticket); 1676 if(ret) goto cleanup; 1677 } 1678 if (header & SC_SECOND_TICKET) { 1679 ret = krb5_ret_data (sp, &creds->second_ticket); 1680 if(ret) goto cleanup; 1681 } 1682 1683cleanup: 1684 if(ret) { 1685#if 0 1686 krb5_free_cred_contents(context, creds); /* XXX */ 1687#endif 1688 } 1689 return ret; 1690} 1691