root/source4/heimdal/lib/krb5/store.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. krb5_storage_set_flags
  2. krb5_storage_clear_flags
  3. krb5_storage_is_flags
  4. krb5_storage_set_byteorder
  5. krb5_storage_get_byteorder
  6. krb5_storage_seek
  7. krb5_storage_read
  8. krb5_storage_write
  9. krb5_storage_set_eof_code
  10. _krb5_put_int
  11. _krb5_get_int
  12. krb5_storage_free
  13. krb5_storage_to_data
  14. krb5_store_int
  15. krb5_store_int32
  16. krb5_store_uint32
  17. krb5_ret_int
  18. krb5_ret_int32
  19. krb5_ret_uint32
  20. krb5_store_int16
  21. krb5_store_uint16
  22. krb5_ret_int16
  23. krb5_ret_uint16
  24. krb5_store_int8
  25. krb5_store_uint8
  26. krb5_ret_int8
  27. krb5_ret_uint8
  28. krb5_store_data
  29. krb5_ret_data
  30. krb5_store_string
  31. krb5_ret_string
  32. krb5_store_stringz
  33. krb5_ret_stringz
  34. krb5_store_stringnl
  35. krb5_ret_stringnl
  36. krb5_store_principal
  37. krb5_ret_principal
  38. krb5_store_keyblock
  39. krb5_ret_keyblock
  40. krb5_store_times
  41. krb5_ret_times
  42. krb5_store_address
  43. krb5_ret_address
  44. krb5_store_addrs
  45. krb5_ret_addrs
  46. krb5_store_authdata
  47. krb5_ret_authdata
  48. bitswap32
  49. krb5_store_creds
  50. krb5_ret_creds
  51. krb5_store_creds_tag
  52. krb5_ret_creds_tag

   1 /*
   2  * Copyright (c) 1997-2006 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 RCSID("$Id$");
  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 void KRB5_LIB_FUNCTION
  46 krb5_storage_set_flags(krb5_storage *sp, krb5_flags flags)
     /* [<][>][^][v][top][bottom][index][help] */
  47 {
  48     sp->flags |= flags;
  49 }
  50 
  51 void KRB5_LIB_FUNCTION
  52 krb5_storage_clear_flags(krb5_storage *sp, krb5_flags flags)
     /* [<][>][^][v][top][bottom][index][help] */
  53 {
  54     sp->flags &= ~flags;
  55 }
  56 
  57 krb5_boolean KRB5_LIB_FUNCTION
  58 krb5_storage_is_flags(krb5_storage *sp, krb5_flags flags)
     /* [<][>][^][v][top][bottom][index][help] */
  59 {
  60     return (sp->flags & flags) == flags;
  61 }
  62 
  63 void KRB5_LIB_FUNCTION
  64 krb5_storage_set_byteorder(krb5_storage *sp, krb5_flags byteorder)
     /* [<][>][^][v][top][bottom][index][help] */
  65 {
  66     sp->flags &= ~KRB5_STORAGE_BYTEORDER_MASK;
  67     sp->flags |= byteorder;
  68 }
  69 
  70 krb5_flags KRB5_LIB_FUNCTION
  71 krb5_storage_get_byteorder(krb5_storage *sp, krb5_flags byteorder)
     /* [<][>][^][v][top][bottom][index][help] */
  72 {
  73     return sp->flags & KRB5_STORAGE_BYTEORDER_MASK;
  74 }
  75 
  76 off_t KRB5_LIB_FUNCTION
  77 krb5_storage_seek(krb5_storage *sp, off_t offset, int whence)
     /* [<][>][^][v][top][bottom][index][help] */
  78 {
  79     return (*sp->seek)(sp, offset, whence);
  80 }
  81 
  82 krb5_ssize_t KRB5_LIB_FUNCTION
  83 krb5_storage_read(krb5_storage *sp, void *buf, size_t len)
     /* [<][>][^][v][top][bottom][index][help] */
  84 {
  85     return sp->fetch(sp, buf, len);
  86 }
  87 
  88 krb5_ssize_t KRB5_LIB_FUNCTION
  89 krb5_storage_write(krb5_storage *sp, const void *buf, size_t len)
     /* [<][>][^][v][top][bottom][index][help] */
  90 {
  91     return sp->store(sp, buf, len);
  92 }
  93 
  94 void KRB5_LIB_FUNCTION
  95 krb5_storage_set_eof_code(krb5_storage *sp, int code)
     /* [<][>][^][v][top][bottom][index][help] */
  96 {
  97     sp->eof_code = code;
  98 }
  99 
 100 krb5_ssize_t KRB5_LIB_FUNCTION
 101 _krb5_put_int(void *buffer, unsigned long value, size_t size)
     /* [<][>][^][v][top][bottom][index][help] */
 102 {
 103     unsigned char *p = buffer;
 104     int i;
 105     for (i = size - 1; i >= 0; i--) {
 106         p[i] = value & 0xff;
 107         value >>= 8;
 108     }
 109     return size;
 110 }
 111 
 112 krb5_ssize_t KRB5_LIB_FUNCTION
 113 _krb5_get_int(void *buffer, unsigned long *value, size_t size)
     /* [<][>][^][v][top][bottom][index][help] */
 114 {
 115     unsigned char *p = buffer;
 116     unsigned long v = 0;
 117     int i;
 118     for (i = 0; i < size; i++)
 119         v = (v << 8) + p[i];
 120     *value = v;
 121     return size;
 122 }
 123 
 124 krb5_error_code KRB5_LIB_FUNCTION
 125 krb5_storage_free(krb5_storage *sp)
     /* [<][>][^][v][top][bottom][index][help] */
 126 {
 127     if(sp->free)
 128         (*sp->free)(sp);
 129     free(sp->data);
 130     free(sp);
 131     return 0;
 132 }
 133 
 134 krb5_error_code KRB5_LIB_FUNCTION
 135 krb5_storage_to_data(krb5_storage *sp, krb5_data *data)
     /* [<][>][^][v][top][bottom][index][help] */
 136 {
 137     off_t pos;
 138     size_t size;
 139     krb5_error_code ret;
 140 
 141     pos = sp->seek(sp, 0, SEEK_CUR);
 142     size = (size_t)sp->seek(sp, 0, SEEK_END);
 143     ret = krb5_data_alloc (data, size);
 144     if (ret) {
 145         sp->seek(sp, pos, SEEK_SET);
 146         return ret;
 147     }
 148     if (size) {
 149         sp->seek(sp, 0, SEEK_SET);
 150         sp->fetch(sp, data->data, data->length);
 151         sp->seek(sp, pos, SEEK_SET);
 152     }
 153     return 0;
 154 }
 155 
 156 static krb5_error_code
 157 krb5_store_int(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 158                int32_t value,
 159                size_t len)
 160 {
 161     int ret;
 162     unsigned char v[16];
 163 
 164     if(len > sizeof(v))
 165         return EINVAL;
 166     _krb5_put_int(v, value, len);
 167     ret = sp->store(sp, v, len);
 168     if (ret != len)
 169         return (ret<0)?errno:sp->eof_code;
 170     return 0;
 171 }
 172 
 173 krb5_error_code KRB5_LIB_FUNCTION
 174 krb5_store_int32(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 175                  int32_t value)
 176 {
 177     if(BYTEORDER_IS_HOST(sp))
 178         value = htonl(value);
 179     else if(BYTEORDER_IS_LE(sp))
 180         value = bswap32(value);
 181     return krb5_store_int(sp, value, 4);
 182 }
 183 
 184 krb5_error_code KRB5_LIB_FUNCTION
 185 krb5_store_uint32(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 186                   uint32_t value)
 187 {
 188     return krb5_store_int32(sp, (int32_t)value);
 189 }
 190 
 191 static krb5_error_code
 192 krb5_ret_int(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 193              int32_t *value,
 194              size_t len)
 195 {
 196     int ret;
 197     unsigned char v[4];
 198     unsigned long w;
 199     ret = sp->fetch(sp, v, len);
 200     if(ret != len)
 201         return (ret<0)?errno:sp->eof_code;
 202     _krb5_get_int(v, &w, len);
 203     *value = w;
 204     return 0;
 205 }
 206 
 207 krb5_error_code KRB5_LIB_FUNCTION
 208 krb5_ret_int32(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 209                int32_t *value)
 210 {
 211     krb5_error_code ret = krb5_ret_int(sp, value, 4);
 212     if(ret)
 213         return ret;
 214     if(BYTEORDER_IS_HOST(sp))
 215         *value = htonl(*value);
 216     else if(BYTEORDER_IS_LE(sp))
 217         *value = bswap32(*value);
 218     return 0;
 219 }
 220 
 221 krb5_error_code KRB5_LIB_FUNCTION
 222 krb5_ret_uint32(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 223                 uint32_t *value)
 224 {
 225     krb5_error_code ret;
 226     int32_t v;
 227 
 228     ret = krb5_ret_int32(sp, &v);
 229     if (ret == 0)
 230         *value = (uint32_t)v;
 231 
 232     return ret;
 233 }
 234 
 235 krb5_error_code KRB5_LIB_FUNCTION
 236 krb5_store_int16(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 237                  int16_t value)
 238 {
 239     if(BYTEORDER_IS_HOST(sp))
 240         value = htons(value);
 241     else if(BYTEORDER_IS_LE(sp))
 242         value = bswap16(value);
 243     return krb5_store_int(sp, value, 2);
 244 }
 245 
 246 krb5_error_code KRB5_LIB_FUNCTION
 247 krb5_store_uint16(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 248                   uint16_t value)
 249 {
 250     return krb5_store_int16(sp, (int16_t)value);
 251 }
 252 
 253 krb5_error_code KRB5_LIB_FUNCTION
 254 krb5_ret_int16(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 255                int16_t *value)
 256 {
 257     int32_t v;
 258     int ret;
 259     ret = krb5_ret_int(sp, &v, 2);
 260     if(ret)
 261         return ret;
 262     *value = v;
 263     if(BYTEORDER_IS_HOST(sp))
 264         *value = htons(*value);
 265     else if(BYTEORDER_IS_LE(sp))
 266         *value = bswap16(*value);
 267     return 0;
 268 }
 269 
 270 krb5_error_code KRB5_LIB_FUNCTION
 271 krb5_ret_uint16(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 272                 uint16_t *value)
 273 {
 274     krb5_error_code ret;
 275     int16_t v;
 276 
 277     ret = krb5_ret_int16(sp, &v);
 278     if (ret == 0)
 279         *value = (uint16_t)v;
 280 
 281     return ret;
 282 }
 283 
 284 krb5_error_code KRB5_LIB_FUNCTION
 285 krb5_store_int8(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 286                 int8_t value)
 287 {
 288     int ret;
 289 
 290     ret = sp->store(sp, &value, sizeof(value));
 291     if (ret != sizeof(value))
 292         return (ret<0)?errno:sp->eof_code;
 293     return 0;
 294 }
 295 
 296 krb5_error_code KRB5_LIB_FUNCTION
 297 krb5_store_uint8(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 298                  uint8_t value)
 299 {
 300     return krb5_store_int8(sp, (int8_t)value);
 301 }
 302 
 303 krb5_error_code KRB5_LIB_FUNCTION
 304 krb5_ret_int8(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 305               int8_t *value)
 306 {
 307     int ret;
 308 
 309     ret = sp->fetch(sp, value, sizeof(*value));
 310     if (ret != sizeof(*value))
 311         return (ret<0)?errno:sp->eof_code;
 312     return 0;
 313 }
 314 
 315 krb5_error_code KRB5_LIB_FUNCTION
 316 krb5_ret_uint8(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 317                uint8_t *value)
 318 {
 319     krb5_error_code ret;
 320     int8_t v;
 321 
 322     ret = krb5_ret_int8(sp, &v);
 323     if (ret == 0)
 324         *value = (uint8_t)v;
 325 
 326     return ret;
 327 }
 328 
 329 krb5_error_code KRB5_LIB_FUNCTION
 330 krb5_store_data(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 331                 krb5_data data)
 332 {
 333     int ret;
 334     ret = krb5_store_int32(sp, data.length);
 335     if(ret < 0)
 336         return ret;
 337     ret = sp->store(sp, data.data, data.length);
 338     if(ret != data.length){
 339         if(ret < 0)
 340             return errno;
 341         return sp->eof_code;
 342     }
 343     return 0;
 344 }
 345 
 346 krb5_error_code KRB5_LIB_FUNCTION
 347 krb5_ret_data(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 348               krb5_data *data)
 349 {
 350     int ret;
 351     int32_t size;
 352 
 353     ret = krb5_ret_int32(sp, &size);
 354     if(ret)
 355         return ret;
 356     ret = krb5_data_alloc (data, size);
 357     if (ret)
 358         return ret;
 359     if (size) {
 360         ret = sp->fetch(sp, data->data, size);
 361         if(ret != size)
 362             return (ret < 0)? errno : sp->eof_code;
 363     }
 364     return 0;
 365 }
 366 
 367 krb5_error_code KRB5_LIB_FUNCTION
 368 krb5_store_string(krb5_storage *sp, const char *s)
     /* [<][>][^][v][top][bottom][index][help] */
 369 {
 370     krb5_data data;
 371     data.length = strlen(s);
 372     data.data = rk_UNCONST(s);
 373     return krb5_store_data(sp, data);
 374 }
 375 
 376 krb5_error_code KRB5_LIB_FUNCTION
 377 krb5_ret_string(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 378                 char **string)
 379 {
 380     int ret;
 381     krb5_data data;
 382     ret = krb5_ret_data(sp, &data);
 383     if(ret)
 384         return ret;
 385     *string = realloc(data.data, data.length + 1);
 386     if(*string == NULL){
 387         free(data.data);
 388         return ENOMEM;
 389     }
 390     (*string)[data.length] = 0;
 391     return 0;
 392 }
 393 
 394 krb5_error_code KRB5_LIB_FUNCTION
 395 krb5_store_stringz(krb5_storage *sp, const char *s)
     /* [<][>][^][v][top][bottom][index][help] */
 396 {
 397     size_t len = strlen(s) + 1;
 398     ssize_t ret;
 399 
 400     ret = sp->store(sp, s, len);
 401     if(ret != len) {
 402         if(ret < 0)
 403             return ret;
 404         else
 405             return sp->eof_code;
 406     }
 407     return 0;
 408 }
 409 
 410 krb5_error_code KRB5_LIB_FUNCTION
 411 krb5_ret_stringz(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 412                 char **string)
 413 {
 414     char c;
 415     char *s = NULL;
 416     size_t len = 0;
 417     ssize_t ret;
 418 
 419     while((ret = sp->fetch(sp, &c, 1)) == 1){
 420         char *tmp;
 421 
 422         len++;
 423         tmp = realloc (s, len);
 424         if (tmp == NULL) {
 425             free (s);
 426             return ENOMEM;
 427         }
 428         s = tmp;
 429         s[len - 1] = c;
 430         if(c == 0)
 431             break;
 432     }
 433     if(ret != 1){
 434         free(s);
 435         if(ret == 0)
 436             return sp->eof_code;
 437         return ret;
 438     }
 439     *string = s;
 440     return 0;
 441 }
 442 
 443 krb5_error_code KRB5_LIB_FUNCTION
 444 krb5_store_stringnl(krb5_storage *sp, const char *s)
     /* [<][>][^][v][top][bottom][index][help] */
 445 {
 446     size_t len = strlen(s);
 447     ssize_t ret;
 448 
 449     ret = sp->store(sp, s, len);
 450     if(ret != len) {
 451         if(ret < 0)
 452             return ret;
 453         else
 454             return sp->eof_code;
 455     }
 456     ret = sp->store(sp, "\n", 1);
 457     if(ret != 1) {
 458         if(ret < 0)
 459             return ret;
 460         else
 461             return sp->eof_code;
 462     }
 463 
 464     return 0;
 465 
 466 }
 467 
 468 krb5_error_code KRB5_LIB_FUNCTION
 469 krb5_ret_stringnl(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 470                   char **string)
 471 {
 472     int expect_nl = 0;
 473     char c;
 474     char *s = NULL;
 475     size_t len = 0;
 476     ssize_t ret;
 477 
 478     while((ret = sp->fetch(sp, &c, 1)) == 1){
 479         char *tmp;
 480 
 481         if (c == '\r') {
 482             expect_nl = 1;
 483             continue;
 484         }
 485         if (expect_nl && c != '\n') {
 486             free(s);
 487             return KRB5_BADMSGTYPE;
 488         }
 489 
 490         len++;
 491         tmp = realloc (s, len);
 492         if (tmp == NULL) {
 493             free (s);
 494             return ENOMEM;
 495         }
 496         s = tmp;
 497         if(c == '\n') {
 498             s[len - 1] = '\0';
 499             break;
 500         }
 501         s[len - 1] = c;
 502     }
 503     if(ret != 1){
 504         free(s);
 505         if(ret == 0)
 506             return sp->eof_code;
 507         return ret;
 508     }
 509     *string = s;
 510     return 0;
 511 }
 512 
 513 
 514 krb5_error_code KRB5_LIB_FUNCTION
 515 krb5_store_principal(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 516                      krb5_const_principal p)
 517 {
 518     int i;
 519     int ret;
 520 
 521     if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) {
 522         ret = krb5_store_int32(sp, p->name.name_type);
 523         if(ret) return ret;
 524     }
 525     if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
 526         ret = krb5_store_int32(sp, p->name.name_string.len + 1);
 527     else
 528         ret = krb5_store_int32(sp, p->name.name_string.len);
 529 
 530     if(ret) return ret;
 531     ret = krb5_store_string(sp, p->realm);
 532     if(ret) return ret;
 533     for(i = 0; i < p->name.name_string.len; i++){
 534         ret = krb5_store_string(sp, p->name.name_string.val[i]);
 535         if(ret) return ret;
 536     }
 537     return 0;
 538 }
 539 
 540 krb5_error_code KRB5_LIB_FUNCTION
 541 krb5_ret_principal(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 542                    krb5_principal *princ)
 543 {
 544     int i;
 545     int ret;
 546     krb5_principal p;
 547     int32_t type;
 548     int32_t ncomp;
 549 
 550     p = calloc(1, sizeof(*p));
 551     if(p == NULL)
 552         return ENOMEM;
 553 
 554     if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE))
 555         type = KRB5_NT_UNKNOWN;
 556     else if((ret = krb5_ret_int32(sp, &type))){
 557         free(p);
 558         return ret;
 559     }
 560     if((ret = krb5_ret_int32(sp, &ncomp))){
 561         free(p);
 562         return ret;
 563     }
 564     if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
 565         ncomp--;
 566     if (ncomp < 0) {
 567         free(p);
 568         return EINVAL;
 569     }
 570     p->name.name_type = type;
 571     p->name.name_string.len = ncomp;
 572     ret = krb5_ret_string(sp, &p->realm);
 573     if(ret) {
 574         free(p);
 575         return ret;
 576     }
 577     p->name.name_string.val = calloc(ncomp, sizeof(*p->name.name_string.val));
 578     if(p->name.name_string.val == NULL && ncomp != 0){
 579         free(p->realm);
 580         free(p);
 581         return ENOMEM;
 582     }
 583     for(i = 0; i < ncomp; i++){
 584         ret = krb5_ret_string(sp, &p->name.name_string.val[i]);
 585         if(ret) {
 586             while (i >= 0)
 587                 free(p->name.name_string.val[i--]);
 588             free(p->realm);
 589             free(p);
 590             return ret;
 591         }
 592     }
 593     *princ = p;
 594     return 0;
 595 }
 596 
 597 krb5_error_code KRB5_LIB_FUNCTION
 598 krb5_store_keyblock(krb5_storage *sp, krb5_keyblock p)
     /* [<][>][^][v][top][bottom][index][help] */
 599 {
 600     int ret;
 601     ret = krb5_store_int16(sp, p.keytype);
 602     if(ret) return ret;
 603 
 604     if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
 605         /* this should really be enctype, but it is the same as
 606            keytype nowadays */
 607     ret = krb5_store_int16(sp, p.keytype);
 608     if(ret) return ret;
 609     }
 610 
 611     ret = krb5_store_data(sp, p.keyvalue);
 612     return ret;
 613 }
 614 
 615 krb5_error_code KRB5_LIB_FUNCTION
 616 krb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p)
     /* [<][>][^][v][top][bottom][index][help] */
 617 {
 618     int ret;
 619     int16_t tmp;
 620 
 621     ret = krb5_ret_int16(sp, &tmp);
 622     if(ret) return ret;
 623     p->keytype = tmp;
 624 
 625     if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
 626     ret = krb5_ret_int16(sp, &tmp);
 627     if(ret) return ret;
 628     }
 629 
 630     ret = krb5_ret_data(sp, &p->keyvalue);
 631     return ret;
 632 }
 633 
 634 krb5_error_code KRB5_LIB_FUNCTION
 635 krb5_store_times(krb5_storage *sp, krb5_times times)
     /* [<][>][^][v][top][bottom][index][help] */
 636 {
 637     int ret;
 638     ret = krb5_store_int32(sp, times.authtime);
 639     if(ret) return ret;
 640     ret = krb5_store_int32(sp, times.starttime);
 641     if(ret) return ret;
 642     ret = krb5_store_int32(sp, times.endtime);
 643     if(ret) return ret;
 644     ret = krb5_store_int32(sp, times.renew_till);
 645     return ret;
 646 }
 647 
 648 krb5_error_code KRB5_LIB_FUNCTION
 649 krb5_ret_times(krb5_storage *sp, krb5_times *times)
     /* [<][>][^][v][top][bottom][index][help] */
 650 {
 651     int ret;
 652     int32_t tmp;
 653     ret = krb5_ret_int32(sp, &tmp);
 654     times->authtime = tmp;
 655     if(ret) return ret;
 656     ret = krb5_ret_int32(sp, &tmp);
 657     times->starttime = tmp;
 658     if(ret) return ret;
 659     ret = krb5_ret_int32(sp, &tmp);
 660     times->endtime = tmp;
 661     if(ret) return ret;
 662     ret = krb5_ret_int32(sp, &tmp);
 663     times->renew_till = tmp;
 664     return ret;
 665 }
 666 
 667 krb5_error_code KRB5_LIB_FUNCTION
 668 krb5_store_address(krb5_storage *sp, krb5_address p)
     /* [<][>][^][v][top][bottom][index][help] */
 669 {
 670     int ret;
 671     ret = krb5_store_int16(sp, p.addr_type);
 672     if(ret) return ret;
 673     ret = krb5_store_data(sp, p.address);
 674     return ret;
 675 }
 676 
 677 krb5_error_code KRB5_LIB_FUNCTION
 678 krb5_ret_address(krb5_storage *sp, krb5_address *adr)
     /* [<][>][^][v][top][bottom][index][help] */
 679 {
 680     int16_t t;
 681     int ret;
 682     ret = krb5_ret_int16(sp, &t);
 683     if(ret) return ret;
 684     adr->addr_type = t;
 685     ret = krb5_ret_data(sp, &adr->address);
 686     return ret;
 687 }
 688 
 689 krb5_error_code KRB5_LIB_FUNCTION
 690 krb5_store_addrs(krb5_storage *sp, krb5_addresses p)
     /* [<][>][^][v][top][bottom][index][help] */
 691 {
 692     int i;
 693     int ret;
 694     ret = krb5_store_int32(sp, p.len);
 695     if(ret) return ret;
 696     for(i = 0; i<p.len; i++){
 697         ret = krb5_store_address(sp, p.val[i]);
 698         if(ret) break;
 699     }
 700     return ret;
 701 }
 702 
 703 krb5_error_code KRB5_LIB_FUNCTION
 704 krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr)
     /* [<][>][^][v][top][bottom][index][help] */
 705 {
 706     int i;
 707     int ret;
 708     int32_t tmp;
 709 
 710     ret = krb5_ret_int32(sp, &tmp);
 711     if(ret) return ret;
 712     adr->len = tmp;
 713     ALLOC(adr->val, adr->len);
 714     if (adr->val == NULL && adr->len != 0)
 715         return ENOMEM;
 716     for(i = 0; i < adr->len; i++){
 717         ret = krb5_ret_address(sp, &adr->val[i]);
 718         if(ret) break;
 719     }
 720     return ret;
 721 }
 722 
 723 krb5_error_code KRB5_LIB_FUNCTION
 724 krb5_store_authdata(krb5_storage *sp, krb5_authdata auth)
     /* [<][>][^][v][top][bottom][index][help] */
 725 {
 726     krb5_error_code ret;
 727     int i;
 728     ret = krb5_store_int32(sp, auth.len);
 729     if(ret) return ret;
 730     for(i = 0; i < auth.len; i++){
 731         ret = krb5_store_int16(sp, auth.val[i].ad_type);
 732         if(ret) break;
 733         ret = krb5_store_data(sp, auth.val[i].ad_data);
 734         if(ret) break;
 735     }
 736     return 0;
 737 }
 738 
 739 krb5_error_code KRB5_LIB_FUNCTION
 740 krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth)
     /* [<][>][^][v][top][bottom][index][help] */
 741 {
 742     krb5_error_code ret;
 743     int32_t tmp;
 744     int16_t tmp2;
 745     int i;
 746     ret = krb5_ret_int32(sp, &tmp);
 747     if(ret) return ret;
 748     ALLOC_SEQ(auth, tmp);
 749     if (auth->val == NULL && tmp != 0)
 750         return ENOMEM;
 751     for(i = 0; i < tmp; i++){
 752         ret = krb5_ret_int16(sp, &tmp2);
 753         if(ret) break;
 754         auth->val[i].ad_type = tmp2;
 755         ret = krb5_ret_data(sp, &auth->val[i].ad_data);
 756         if(ret) break;
 757     }
 758     return ret;
 759 }
 760 
 761 static int32_t
 762 bitswap32(int32_t b)
     /* [<][>][^][v][top][bottom][index][help] */
 763 {
 764     int32_t r = 0;
 765     int i;
 766     for (i = 0; i < 32; i++) {
 767         r = r << 1 | (b & 1);
 768         b = b >> 1;
 769     }
 770     return r;
 771 }
 772 
 773 
 774 /*
 775  *
 776  */
 777 
 778 krb5_error_code KRB5_LIB_FUNCTION
 779 krb5_store_creds(krb5_storage *sp, krb5_creds *creds)
     /* [<][>][^][v][top][bottom][index][help] */
 780 {
 781     int ret;
 782 
 783     ret = krb5_store_principal(sp, creds->client);
 784     if(ret)
 785         return ret;
 786     ret = krb5_store_principal(sp, creds->server);
 787     if(ret)
 788         return ret;
 789     ret = krb5_store_keyblock(sp, creds->session);
 790     if(ret)
 791         return ret;
 792     ret = krb5_store_times(sp, creds->times);
 793     if(ret)
 794         return ret;
 795     ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
 796     if(ret)
 797         return ret;
 798 
 799     if(krb5_storage_is_flags(sp, KRB5_STORAGE_CREDS_FLAGS_WRONG_BITORDER))
 800         ret = krb5_store_int32(sp, creds->flags.i);
 801     else
 802         ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
 803     if(ret)
 804         return ret;
 805 
 806     ret = krb5_store_addrs(sp, creds->addresses);
 807     if(ret)
 808         return ret;
 809     ret = krb5_store_authdata(sp, creds->authdata);
 810     if(ret)
 811         return ret;
 812     ret = krb5_store_data(sp, creds->ticket);
 813     if(ret)
 814         return ret;
 815     ret = krb5_store_data(sp, creds->second_ticket);
 816     return ret;
 817 }
 818 
 819 krb5_error_code KRB5_LIB_FUNCTION
 820 krb5_ret_creds(krb5_storage *sp, krb5_creds *creds)
     /* [<][>][^][v][top][bottom][index][help] */
 821 {
 822     krb5_error_code ret;
 823     int8_t dummy8;
 824     int32_t dummy32;
 825 
 826     memset(creds, 0, sizeof(*creds));
 827     ret = krb5_ret_principal (sp,  &creds->client);
 828     if(ret) goto cleanup;
 829     ret = krb5_ret_principal (sp,  &creds->server);
 830     if(ret) goto cleanup;
 831     ret = krb5_ret_keyblock (sp,  &creds->session);
 832     if(ret) goto cleanup;
 833     ret = krb5_ret_times (sp,  &creds->times);
 834     if(ret) goto cleanup;
 835     ret = krb5_ret_int8 (sp,  &dummy8);
 836     if(ret) goto cleanup;
 837     ret = krb5_ret_int32 (sp,  &dummy32);
 838     if(ret) goto cleanup;
 839     /*
 840      * Runtime detect the what is the higher bits of the bitfield. If
 841      * any of the higher bits are set in the input data, it's either a
 842      * new ticket flag (and this code need to be removed), or it's a
 843      * MIT cache (or new Heimdal cache), lets change it to our current
 844      * format.
 845      */
 846     {
 847         uint32_t mask = 0xffff0000;
 848         creds->flags.i = 0;
 849         creds->flags.b.anonymous = 1;
 850         if (creds->flags.i & mask)
 851             mask = ~mask;
 852         if (dummy32 & mask)
 853             dummy32 = bitswap32(dummy32);
 854     }
 855     creds->flags.i = dummy32;
 856     ret = krb5_ret_addrs (sp,  &creds->addresses);
 857     if(ret) goto cleanup;
 858     ret = krb5_ret_authdata (sp,  &creds->authdata);
 859     if(ret) goto cleanup;
 860     ret = krb5_ret_data (sp,  &creds->ticket);
 861     if(ret) goto cleanup;
 862     ret = krb5_ret_data (sp,  &creds->second_ticket);
 863 cleanup:
 864     if(ret) {
 865 #if 0   
 866         krb5_free_cred_contents(context, creds); /* XXX */
 867 #endif
 868     }
 869     return ret;
 870 }
 871 
 872 #define SC_CLIENT_PRINCIPAL         0x0001
 873 #define SC_SERVER_PRINCIPAL         0x0002
 874 #define SC_SESSION_KEY              0x0004
 875 #define SC_TICKET                   0x0008
 876 #define SC_SECOND_TICKET            0x0010
 877 #define SC_AUTHDATA                 0x0020
 878 #define SC_ADDRESSES                0x0040
 879 
 880 /*
 881  *
 882  */
 883 
 884 krb5_error_code KRB5_LIB_FUNCTION
 885 krb5_store_creds_tag(krb5_storage *sp, krb5_creds *creds)
     /* [<][>][^][v][top][bottom][index][help] */
 886 {
 887     int ret;
 888     int32_t header = 0;
 889 
 890     if (creds->client)
 891         header |= SC_CLIENT_PRINCIPAL;
 892     if (creds->server)
 893         header |= SC_SERVER_PRINCIPAL;
 894     if (creds->session.keytype != ETYPE_NULL)
 895         header |= SC_SESSION_KEY;
 896     if (creds->ticket.data)
 897         header |= SC_TICKET;
 898     if (creds->second_ticket.length)
 899         header |= SC_SECOND_TICKET;
 900     if (creds->authdata.len)
 901         header |= SC_AUTHDATA;
 902     if (creds->addresses.len)
 903         header |= SC_ADDRESSES;
 904 
 905     ret = krb5_store_int32(sp, header);
 906 
 907     if (creds->client) {
 908         ret = krb5_store_principal(sp, creds->client);
 909         if(ret)
 910             return ret;
 911     }
 912 
 913     if (creds->server) {
 914         ret = krb5_store_principal(sp, creds->server);
 915         if(ret)
 916             return ret;
 917     }
 918 
 919     if (creds->session.keytype != ETYPE_NULL) {
 920         ret = krb5_store_keyblock(sp, creds->session);
 921         if(ret)
 922             return ret;
 923     }
 924 
 925     ret = krb5_store_times(sp, creds->times);
 926     if(ret)
 927         return ret;
 928     ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
 929     if(ret)
 930         return ret;
 931 
 932     ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
 933     if(ret)
 934         return ret;
 935 
 936     if (creds->addresses.len) {
 937         ret = krb5_store_addrs(sp, creds->addresses);
 938         if(ret)
 939             return ret;
 940     }
 941 
 942     if (creds->authdata.len) {
 943         ret = krb5_store_authdata(sp, creds->authdata);
 944         if(ret)
 945             return ret;
 946     }
 947 
 948     if (creds->ticket.data) {
 949         ret = krb5_store_data(sp, creds->ticket);
 950         if(ret)
 951             return ret;
 952     }
 953 
 954     if (creds->second_ticket.data) {
 955         ret = krb5_store_data(sp, creds->second_ticket);
 956         if (ret)
 957             return ret;
 958     }
 959 
 960     return ret;
 961 }
 962 
 963 krb5_error_code KRB5_LIB_FUNCTION
 964 krb5_ret_creds_tag(krb5_storage *sp,
     /* [<][>][^][v][top][bottom][index][help] */
 965                    krb5_creds *creds)
 966 {
 967     krb5_error_code ret;
 968     int8_t dummy8;
 969     int32_t dummy32, header;
 970 
 971     memset(creds, 0, sizeof(*creds));
 972 
 973     ret = krb5_ret_int32 (sp, &header);
 974     if (ret) goto cleanup;
 975 
 976     if (header & SC_CLIENT_PRINCIPAL) {
 977         ret = krb5_ret_principal (sp,  &creds->client);
 978         if(ret) goto cleanup;
 979     }
 980     if (header & SC_SERVER_PRINCIPAL) {
 981         ret = krb5_ret_principal (sp,  &creds->server);
 982         if(ret) goto cleanup;
 983     }
 984     if (header & SC_SESSION_KEY) {
 985         ret = krb5_ret_keyblock (sp,  &creds->session);
 986         if(ret) goto cleanup;
 987     }
 988     ret = krb5_ret_times (sp,  &creds->times);
 989     if(ret) goto cleanup;
 990     ret = krb5_ret_int8 (sp,  &dummy8);
 991     if(ret) goto cleanup;
 992     ret = krb5_ret_int32 (sp,  &dummy32);
 993     if(ret) goto cleanup;
 994     /*
 995      * Runtime detect the what is the higher bits of the bitfield. If
 996      * any of the higher bits are set in the input data, it's either a
 997      * new ticket flag (and this code need to be removed), or it's a
 998      * MIT cache (or new Heimdal cache), lets change it to our current
 999      * format.
1000      */
1001     {
1002         uint32_t mask = 0xffff0000;
1003         creds->flags.i = 0;
1004         creds->flags.b.anonymous = 1;
1005         if (creds->flags.i & mask)
1006             mask = ~mask;
1007         if (dummy32 & mask)
1008             dummy32 = bitswap32(dummy32);
1009     }
1010     creds->flags.i = dummy32;
1011     if (header & SC_ADDRESSES) {
1012         ret = krb5_ret_addrs (sp,  &creds->addresses);
1013         if(ret) goto cleanup;
1014     }
1015     if (header & SC_AUTHDATA) {
1016         ret = krb5_ret_authdata (sp,  &creds->authdata);
1017         if(ret) goto cleanup;
1018     }
1019     if (header & SC_TICKET) {
1020         ret = krb5_ret_data (sp,  &creds->ticket);
1021         if(ret) goto cleanup;
1022     }
1023     if (header & SC_SECOND_TICKET) {
1024         ret = krb5_ret_data (sp,  &creds->second_ticket);
1025         if(ret) goto cleanup;
1026     }
1027 
1028 cleanup:
1029     if(ret) {
1030 #if 0   
1031         krb5_free_cred_contents(context, creds); /* XXX */
1032 #endif
1033     }
1034     return ret;
1035 }

/* [<][>][^][v][top][bottom][index][help] */