1b528cefcSMark Murray /* 28373020dSJacques Vidrine * Copyright (c) 1997-2002 Kungliga Tekniska H�gskolan 3b528cefcSMark Murray * (Royal Institute of Technology, Stockholm, Sweden). 4b528cefcSMark Murray * All rights reserved. 5b528cefcSMark Murray * 6b528cefcSMark Murray * Redistribution and use in source and binary forms, with or without 7b528cefcSMark Murray * modification, are permitted provided that the following conditions 8b528cefcSMark Murray * are met: 9b528cefcSMark Murray * 10b528cefcSMark Murray * 1. Redistributions of source code must retain the above copyright 11b528cefcSMark Murray * notice, this list of conditions and the following disclaimer. 12b528cefcSMark Murray * 13b528cefcSMark Murray * 2. Redistributions in binary form must reproduce the above copyright 14b528cefcSMark Murray * notice, this list of conditions and the following disclaimer in the 15b528cefcSMark Murray * documentation and/or other materials provided with the distribution. 16b528cefcSMark Murray * 17b528cefcSMark Murray * 3. Neither the name of the Institute nor the names of its contributors 18b528cefcSMark Murray * may be used to endorse or promote products derived from this software 19b528cefcSMark Murray * without specific prior written permission. 20b528cefcSMark Murray * 21b528cefcSMark Murray * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22b528cefcSMark Murray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23b528cefcSMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24b528cefcSMark Murray * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25b528cefcSMark Murray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26b528cefcSMark Murray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27b528cefcSMark Murray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28b528cefcSMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29b528cefcSMark Murray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30b528cefcSMark Murray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31b528cefcSMark Murray * SUCH DAMAGE. 32b528cefcSMark Murray */ 33b528cefcSMark Murray 34b528cefcSMark Murray #include "krb5_locl.h" 358373020dSJacques Vidrine #include "store-int.h" 36b528cefcSMark Murray 371c43270aSJacques Vidrine RCSID("$Id: store.c,v 1.38.4.1 2004/03/09 19:32:14 lha Exp $"); 38adb0ddaeSAssar Westerlund 39adb0ddaeSAssar Westerlund #define BYTEORDER_IS(SP, V) (((SP)->flags & KRB5_STORAGE_BYTEORDER_MASK) == (V)) 40adb0ddaeSAssar Westerlund #define BYTEORDER_IS_LE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_LE) 41adb0ddaeSAssar Westerlund #define BYTEORDER_IS_BE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_BE) 42adb0ddaeSAssar Westerlund #define BYTEORDER_IS_HOST(SP) (BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_HOST) || \ 43adb0ddaeSAssar Westerlund krb5_storage_is_flags((SP), KRB5_STORAGE_HOST_BYTEORDER)) 44b528cefcSMark Murray 45b528cefcSMark Murray void 46b528cefcSMark Murray krb5_storage_set_flags(krb5_storage *sp, krb5_flags flags) 47b528cefcSMark Murray { 48b528cefcSMark Murray sp->flags |= flags; 49b528cefcSMark Murray } 50b528cefcSMark Murray 51b528cefcSMark Murray void 52b528cefcSMark Murray krb5_storage_clear_flags(krb5_storage *sp, krb5_flags flags) 53b528cefcSMark Murray { 54b528cefcSMark Murray sp->flags &= ~flags; 55b528cefcSMark Murray } 56b528cefcSMark Murray 57b528cefcSMark Murray krb5_boolean 58b528cefcSMark Murray krb5_storage_is_flags(krb5_storage *sp, krb5_flags flags) 59b528cefcSMark Murray { 60b528cefcSMark Murray return (sp->flags & flags) == flags; 61b528cefcSMark Murray } 62b528cefcSMark Murray 63adb0ddaeSAssar Westerlund void 64adb0ddaeSAssar Westerlund krb5_storage_set_byteorder(krb5_storage *sp, krb5_flags byteorder) 65adb0ddaeSAssar Westerlund { 66adb0ddaeSAssar Westerlund sp->flags &= ~KRB5_STORAGE_BYTEORDER_MASK; 67adb0ddaeSAssar Westerlund sp->flags |= byteorder; 68adb0ddaeSAssar Westerlund } 69adb0ddaeSAssar Westerlund 70adb0ddaeSAssar Westerlund krb5_flags 71adb0ddaeSAssar Westerlund krb5_storage_get_byteorder(krb5_storage *sp, krb5_flags byteorder) 72adb0ddaeSAssar Westerlund { 73adb0ddaeSAssar Westerlund return sp->flags & KRB5_STORAGE_BYTEORDER_MASK; 74adb0ddaeSAssar Westerlund } 75adb0ddaeSAssar Westerlund 768373020dSJacques Vidrine off_t 778373020dSJacques Vidrine krb5_storage_seek(krb5_storage *sp, off_t offset, int whence) 788373020dSJacques Vidrine { 798373020dSJacques Vidrine return (*sp->seek)(sp, offset, whence); 808373020dSJacques Vidrine } 81adb0ddaeSAssar Westerlund 828373020dSJacques Vidrine krb5_ssize_t 838373020dSJacques Vidrine krb5_storage_read(krb5_storage *sp, void *buf, size_t len) 848373020dSJacques Vidrine { 858373020dSJacques Vidrine return sp->fetch(sp, buf, len); 868373020dSJacques Vidrine } 878373020dSJacques Vidrine 888373020dSJacques Vidrine krb5_ssize_t 898373020dSJacques Vidrine krb5_storage_write(krb5_storage *sp, const void *buf, size_t len) 908373020dSJacques Vidrine { 918373020dSJacques Vidrine return sp->store(sp, buf, len); 928373020dSJacques Vidrine } 938373020dSJacques Vidrine 948373020dSJacques Vidrine void 958373020dSJacques Vidrine krb5_storage_set_eof_code(krb5_storage *sp, int code) 968373020dSJacques Vidrine { 978373020dSJacques Vidrine sp->eof_code = code; 988373020dSJacques Vidrine } 998373020dSJacques Vidrine 1008373020dSJacques Vidrine krb5_ssize_t 101b528cefcSMark Murray _krb5_put_int(void *buffer, unsigned long value, size_t size) 102b528cefcSMark Murray { 103b528cefcSMark Murray unsigned char *p = buffer; 104b528cefcSMark Murray int i; 105b528cefcSMark Murray for (i = size - 1; i >= 0; i--) { 106b528cefcSMark Murray p[i] = value & 0xff; 107b528cefcSMark Murray value >>= 8; 108b528cefcSMark Murray } 109b528cefcSMark Murray return size; 110b528cefcSMark Murray } 111b528cefcSMark Murray 1128373020dSJacques Vidrine krb5_ssize_t 113b528cefcSMark Murray _krb5_get_int(void *buffer, unsigned long *value, size_t size) 114b528cefcSMark Murray { 115b528cefcSMark Murray unsigned char *p = buffer; 116b528cefcSMark Murray unsigned long v = 0; 117b528cefcSMark Murray int i; 118b528cefcSMark Murray for (i = 0; i < size; i++) 119b528cefcSMark Murray v = (v << 8) + p[i]; 120b528cefcSMark Murray *value = v; 121b528cefcSMark Murray return size; 122b528cefcSMark Murray } 123b528cefcSMark Murray 124b528cefcSMark Murray krb5_error_code 125b528cefcSMark Murray krb5_storage_free(krb5_storage *sp) 126b528cefcSMark Murray { 127b528cefcSMark Murray if(sp->free) 128b528cefcSMark Murray (*sp->free)(sp); 129b528cefcSMark Murray free(sp->data); 130b528cefcSMark Murray free(sp); 131b528cefcSMark Murray return 0; 132b528cefcSMark Murray } 133b528cefcSMark Murray 134b528cefcSMark Murray krb5_error_code 135b528cefcSMark Murray krb5_storage_to_data(krb5_storage *sp, krb5_data *data) 136b528cefcSMark Murray { 137b528cefcSMark Murray off_t pos; 138b528cefcSMark Murray size_t size; 139b528cefcSMark Murray krb5_error_code ret; 140b528cefcSMark Murray 141b528cefcSMark Murray pos = sp->seek(sp, 0, SEEK_CUR); 142b528cefcSMark Murray size = (size_t)sp->seek(sp, 0, SEEK_END); 143b528cefcSMark Murray ret = krb5_data_alloc (data, size); 144b528cefcSMark Murray if (ret) { 145b528cefcSMark Murray sp->seek(sp, pos, SEEK_SET); 146b528cefcSMark Murray return ret; 147b528cefcSMark Murray } 148b528cefcSMark Murray if (size) { 149b528cefcSMark Murray sp->seek(sp, 0, SEEK_SET); 150b528cefcSMark Murray sp->fetch(sp, data->data, data->length); 151b528cefcSMark Murray sp->seek(sp, pos, SEEK_SET); 152b528cefcSMark Murray } 153b528cefcSMark Murray return 0; 154b528cefcSMark Murray } 155b528cefcSMark Murray 156b528cefcSMark Murray static krb5_error_code 157b528cefcSMark Murray krb5_store_int(krb5_storage *sp, 158b528cefcSMark Murray int32_t value, 159b528cefcSMark Murray size_t len) 160b528cefcSMark Murray { 161b528cefcSMark Murray int ret; 162adb0ddaeSAssar Westerlund unsigned char v[16]; 163b528cefcSMark Murray 164adb0ddaeSAssar Westerlund if(len > sizeof(v)) 165adb0ddaeSAssar Westerlund return EINVAL; 166b528cefcSMark Murray _krb5_put_int(v, value, len); 167b528cefcSMark Murray ret = sp->store(sp, v, len); 168b528cefcSMark Murray if (ret != len) 1698373020dSJacques Vidrine return (ret<0)?errno:sp->eof_code; 170b528cefcSMark Murray return 0; 171b528cefcSMark Murray } 172b528cefcSMark Murray 173b528cefcSMark Murray krb5_error_code 174b528cefcSMark Murray krb5_store_int32(krb5_storage *sp, 175b528cefcSMark Murray int32_t value) 176b528cefcSMark Murray { 177adb0ddaeSAssar Westerlund if(BYTEORDER_IS_HOST(sp)) 178b528cefcSMark Murray value = htonl(value); 179adb0ddaeSAssar Westerlund else if(BYTEORDER_IS_LE(sp)) 180adb0ddaeSAssar Westerlund value = bswap32(value); 181b528cefcSMark Murray return krb5_store_int(sp, value, 4); 182b528cefcSMark Murray } 183b528cefcSMark Murray 184b528cefcSMark Murray static krb5_error_code 185b528cefcSMark Murray krb5_ret_int(krb5_storage *sp, 186b528cefcSMark Murray int32_t *value, 187b528cefcSMark Murray size_t len) 188b528cefcSMark Murray { 189b528cefcSMark Murray int ret; 190b528cefcSMark Murray unsigned char v[4]; 191b528cefcSMark Murray unsigned long w; 192b528cefcSMark Murray ret = sp->fetch(sp, v, len); 193b528cefcSMark Murray if(ret != len) 1948373020dSJacques Vidrine return (ret<0)?errno:sp->eof_code; 195b528cefcSMark Murray _krb5_get_int(v, &w, len); 196b528cefcSMark Murray *value = w; 197b528cefcSMark Murray return 0; 198b528cefcSMark Murray } 199b528cefcSMark Murray 200b528cefcSMark Murray krb5_error_code 201b528cefcSMark Murray krb5_ret_int32(krb5_storage *sp, 202b528cefcSMark Murray int32_t *value) 203b528cefcSMark Murray { 204b528cefcSMark Murray krb5_error_code ret = krb5_ret_int(sp, value, 4); 205b528cefcSMark Murray if(ret) 206b528cefcSMark Murray return ret; 207adb0ddaeSAssar Westerlund if(BYTEORDER_IS_HOST(sp)) 208adb0ddaeSAssar Westerlund *value = htonl(*value); 209adb0ddaeSAssar Westerlund else if(BYTEORDER_IS_LE(sp)) 210adb0ddaeSAssar Westerlund *value = bswap32(*value); 211b528cefcSMark Murray return 0; 212b528cefcSMark Murray } 213b528cefcSMark Murray 214b528cefcSMark Murray krb5_error_code 215b528cefcSMark Murray krb5_store_int16(krb5_storage *sp, 216b528cefcSMark Murray int16_t value) 217b528cefcSMark Murray { 218adb0ddaeSAssar Westerlund if(BYTEORDER_IS_HOST(sp)) 219b528cefcSMark Murray value = htons(value); 220adb0ddaeSAssar Westerlund else if(BYTEORDER_IS_LE(sp)) 221adb0ddaeSAssar Westerlund value = bswap16(value); 222b528cefcSMark Murray return krb5_store_int(sp, value, 2); 223b528cefcSMark Murray } 224b528cefcSMark Murray 225b528cefcSMark Murray krb5_error_code 226b528cefcSMark Murray krb5_ret_int16(krb5_storage *sp, 227b528cefcSMark Murray int16_t *value) 228b528cefcSMark Murray { 229b528cefcSMark Murray int32_t v; 230b528cefcSMark Murray int ret; 231b528cefcSMark Murray ret = krb5_ret_int(sp, &v, 2); 232b528cefcSMark Murray if(ret) 233b528cefcSMark Murray return ret; 234b528cefcSMark Murray *value = v; 235adb0ddaeSAssar Westerlund if(BYTEORDER_IS_HOST(sp)) 236adb0ddaeSAssar Westerlund *value = htons(*value); 237adb0ddaeSAssar Westerlund else if(BYTEORDER_IS_LE(sp)) 238adb0ddaeSAssar Westerlund *value = bswap16(*value); 239b528cefcSMark Murray return 0; 240b528cefcSMark Murray } 241b528cefcSMark Murray 242b528cefcSMark Murray krb5_error_code 243b528cefcSMark Murray krb5_store_int8(krb5_storage *sp, 244b528cefcSMark Murray int8_t value) 245b528cefcSMark Murray { 246b528cefcSMark Murray int ret; 247b528cefcSMark Murray 248b528cefcSMark Murray ret = sp->store(sp, &value, sizeof(value)); 249b528cefcSMark Murray if (ret != sizeof(value)) 2508373020dSJacques Vidrine return (ret<0)?errno:sp->eof_code; 251b528cefcSMark Murray return 0; 252b528cefcSMark Murray } 253b528cefcSMark Murray 254b528cefcSMark Murray krb5_error_code 255b528cefcSMark Murray krb5_ret_int8(krb5_storage *sp, 256b528cefcSMark Murray int8_t *value) 257b528cefcSMark Murray { 258b528cefcSMark Murray int ret; 259b528cefcSMark Murray 260b528cefcSMark Murray ret = sp->fetch(sp, value, sizeof(*value)); 261b528cefcSMark Murray if (ret != sizeof(*value)) 2628373020dSJacques Vidrine return (ret<0)?errno:sp->eof_code; 263b528cefcSMark Murray return 0; 264b528cefcSMark Murray } 265b528cefcSMark Murray 266b528cefcSMark Murray krb5_error_code 267b528cefcSMark Murray krb5_store_data(krb5_storage *sp, 268b528cefcSMark Murray krb5_data data) 269b528cefcSMark Murray { 270b528cefcSMark Murray int ret; 271b528cefcSMark Murray ret = krb5_store_int32(sp, data.length); 272b528cefcSMark Murray if(ret < 0) 273b528cefcSMark Murray return ret; 274b528cefcSMark Murray ret = sp->store(sp, data.data, data.length); 275b528cefcSMark Murray if(ret != data.length){ 276b528cefcSMark Murray if(ret < 0) 277b528cefcSMark Murray return errno; 2788373020dSJacques Vidrine return sp->eof_code; 279b528cefcSMark Murray } 280b528cefcSMark Murray return 0; 281b528cefcSMark Murray } 282b528cefcSMark Murray 283b528cefcSMark Murray krb5_error_code 284b528cefcSMark Murray krb5_ret_data(krb5_storage *sp, 285b528cefcSMark Murray krb5_data *data) 286b528cefcSMark Murray { 287b528cefcSMark Murray int ret; 288b528cefcSMark Murray int32_t size; 289b528cefcSMark Murray 290b528cefcSMark Murray ret = krb5_ret_int32(sp, &size); 291b528cefcSMark Murray if(ret) 292b528cefcSMark Murray return ret; 293b528cefcSMark Murray ret = krb5_data_alloc (data, size); 294b528cefcSMark Murray if (ret) 295b528cefcSMark Murray return ret; 296b528cefcSMark Murray if (size) { 297b528cefcSMark Murray ret = sp->fetch(sp, data->data, size); 298b528cefcSMark Murray if(ret != size) 2998373020dSJacques Vidrine return (ret < 0)? errno : sp->eof_code; 300b528cefcSMark Murray } 301b528cefcSMark Murray return 0; 302b528cefcSMark Murray } 303b528cefcSMark Murray 304b528cefcSMark Murray krb5_error_code 305b528cefcSMark Murray krb5_store_string(krb5_storage *sp, const char *s) 306b528cefcSMark Murray { 307b528cefcSMark Murray krb5_data data; 308b528cefcSMark Murray data.length = strlen(s); 309b528cefcSMark Murray data.data = (void*)s; 310b528cefcSMark Murray return krb5_store_data(sp, data); 311b528cefcSMark Murray } 312b528cefcSMark Murray 313b528cefcSMark Murray krb5_error_code 314b528cefcSMark Murray krb5_ret_string(krb5_storage *sp, 315b528cefcSMark Murray char **string) 316b528cefcSMark Murray { 317b528cefcSMark Murray int ret; 318b528cefcSMark Murray krb5_data data; 319b528cefcSMark Murray ret = krb5_ret_data(sp, &data); 320b528cefcSMark Murray if(ret) 321b528cefcSMark Murray return ret; 322b528cefcSMark Murray *string = realloc(data.data, data.length + 1); 323b528cefcSMark Murray if(*string == NULL){ 324b528cefcSMark Murray free(data.data); 325b528cefcSMark Murray return ENOMEM; 326b528cefcSMark Murray } 327b528cefcSMark Murray (*string)[data.length] = 0; 328b528cefcSMark Murray return 0; 329b528cefcSMark Murray } 330b528cefcSMark Murray 331b528cefcSMark Murray krb5_error_code 3325e9cd1aeSAssar Westerlund krb5_store_stringz(krb5_storage *sp, const char *s) 333b528cefcSMark Murray { 334b528cefcSMark Murray size_t len = strlen(s) + 1; 335b528cefcSMark Murray ssize_t ret; 336b528cefcSMark Murray 337b528cefcSMark Murray ret = sp->store(sp, s, len); 338b528cefcSMark Murray if(ret != len) { 339b528cefcSMark Murray if(ret < 0) 340b528cefcSMark Murray return ret; 341b528cefcSMark Murray else 3428373020dSJacques Vidrine return sp->eof_code; 343b528cefcSMark Murray } 344b528cefcSMark Murray return 0; 345b528cefcSMark Murray } 346b528cefcSMark Murray 347b528cefcSMark Murray krb5_error_code 348b528cefcSMark Murray krb5_ret_stringz(krb5_storage *sp, 349b528cefcSMark Murray char **string) 350b528cefcSMark Murray { 351b528cefcSMark Murray char c; 352b528cefcSMark Murray char *s = NULL; 353b528cefcSMark Murray size_t len = 0; 354b528cefcSMark Murray ssize_t ret; 355b528cefcSMark Murray 356b528cefcSMark Murray while((ret = sp->fetch(sp, &c, 1)) == 1){ 357b528cefcSMark Murray char *tmp; 358b528cefcSMark Murray 359b528cefcSMark Murray len++; 360b528cefcSMark Murray tmp = realloc (s, len); 361b528cefcSMark Murray if (tmp == NULL) { 362b528cefcSMark Murray free (s); 363b528cefcSMark Murray return ENOMEM; 364b528cefcSMark Murray } 365b528cefcSMark Murray s = tmp; 366b528cefcSMark Murray s[len - 1] = c; 367b528cefcSMark Murray if(c == 0) 368b528cefcSMark Murray break; 369b528cefcSMark Murray } 370b528cefcSMark Murray if(ret != 1){ 371b528cefcSMark Murray free(s); 372b528cefcSMark Murray if(ret == 0) 3738373020dSJacques Vidrine return sp->eof_code; 374b528cefcSMark Murray return ret; 375b528cefcSMark Murray } 376b528cefcSMark Murray *string = s; 377b528cefcSMark Murray return 0; 378b528cefcSMark Murray } 379b528cefcSMark Murray 380b528cefcSMark Murray 381b528cefcSMark Murray krb5_error_code 382b528cefcSMark Murray krb5_store_principal(krb5_storage *sp, 383b528cefcSMark Murray krb5_principal p) 384b528cefcSMark Murray { 385b528cefcSMark Murray int i; 386b528cefcSMark Murray int ret; 387b528cefcSMark Murray 388b528cefcSMark Murray if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) { 389b528cefcSMark Murray ret = krb5_store_int32(sp, p->name.name_type); 390b528cefcSMark Murray if(ret) return ret; 391b528cefcSMark Murray } 392b528cefcSMark Murray if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS)) 393b528cefcSMark Murray ret = krb5_store_int32(sp, p->name.name_string.len + 1); 394b528cefcSMark Murray else 395b528cefcSMark Murray ret = krb5_store_int32(sp, p->name.name_string.len); 396b528cefcSMark Murray 397b528cefcSMark Murray if(ret) return ret; 398b528cefcSMark Murray ret = krb5_store_string(sp, p->realm); 399b528cefcSMark Murray if(ret) return ret; 400b528cefcSMark Murray for(i = 0; i < p->name.name_string.len; i++){ 401b528cefcSMark Murray ret = krb5_store_string(sp, p->name.name_string.val[i]); 402b528cefcSMark Murray if(ret) return ret; 403b528cefcSMark Murray } 404b528cefcSMark Murray return 0; 405b528cefcSMark Murray } 406b528cefcSMark Murray 407b528cefcSMark Murray krb5_error_code 408b528cefcSMark Murray krb5_ret_principal(krb5_storage *sp, 409b528cefcSMark Murray krb5_principal *princ) 410b528cefcSMark Murray { 411b528cefcSMark Murray int i; 412b528cefcSMark Murray int ret; 413b528cefcSMark Murray krb5_principal p; 414b528cefcSMark Murray int32_t type; 415b528cefcSMark Murray int32_t ncomp; 416b528cefcSMark Murray 417b528cefcSMark Murray p = calloc(1, sizeof(*p)); 418b528cefcSMark Murray if(p == NULL) 419b528cefcSMark Murray return ENOMEM; 420b528cefcSMark Murray 421b528cefcSMark Murray if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) 422b528cefcSMark Murray type = KRB5_NT_UNKNOWN; 423b528cefcSMark Murray else if((ret = krb5_ret_int32(sp, &type))){ 424b528cefcSMark Murray free(p); 425b528cefcSMark Murray return ret; 426b528cefcSMark Murray } 427b528cefcSMark Murray if((ret = krb5_ret_int32(sp, &ncomp))){ 428b528cefcSMark Murray free(p); 429b528cefcSMark Murray return ret; 430b528cefcSMark Murray } 431b528cefcSMark Murray if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS)) 432b528cefcSMark Murray ncomp--; 433b528cefcSMark Murray p->name.name_type = type; 434b528cefcSMark Murray p->name.name_string.len = ncomp; 435b528cefcSMark Murray ret = krb5_ret_string(sp, &p->realm); 436b528cefcSMark Murray if(ret) return ret; 437b528cefcSMark Murray p->name.name_string.val = calloc(ncomp, sizeof(*p->name.name_string.val)); 438b528cefcSMark Murray if(p->name.name_string.val == NULL){ 439b528cefcSMark Murray free(p->realm); 440b528cefcSMark Murray return ENOMEM; 441b528cefcSMark Murray } 442b528cefcSMark Murray for(i = 0; i < ncomp; i++){ 443b528cefcSMark Murray ret = krb5_ret_string(sp, &p->name.name_string.val[i]); 444b528cefcSMark Murray if(ret) return ret; /* XXX */ 445b528cefcSMark Murray } 446b528cefcSMark Murray *princ = p; 447b528cefcSMark Murray return 0; 448b528cefcSMark Murray } 449b528cefcSMark Murray 450b528cefcSMark Murray krb5_error_code 451b528cefcSMark Murray krb5_store_keyblock(krb5_storage *sp, krb5_keyblock p) 452b528cefcSMark Murray { 453b528cefcSMark Murray int ret; 454b528cefcSMark Murray ret = krb5_store_int16(sp, p.keytype); 455b528cefcSMark Murray if(ret) return ret; 456b528cefcSMark Murray 457b528cefcSMark Murray if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){ 458b528cefcSMark Murray /* this should really be enctype, but it is the same as 459b528cefcSMark Murray keytype nowadays */ 460b528cefcSMark Murray ret = krb5_store_int16(sp, p.keytype); 461b528cefcSMark Murray if(ret) return ret; 462b528cefcSMark Murray } 463b528cefcSMark Murray 464b528cefcSMark Murray ret = krb5_store_data(sp, p.keyvalue); 465b528cefcSMark Murray return ret; 466b528cefcSMark Murray } 467b528cefcSMark Murray 468b528cefcSMark Murray krb5_error_code 469b528cefcSMark Murray krb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p) 470b528cefcSMark Murray { 471b528cefcSMark Murray int ret; 472b528cefcSMark Murray int16_t tmp; 473b528cefcSMark Murray 474b528cefcSMark Murray ret = krb5_ret_int16(sp, &tmp); 475b528cefcSMark Murray if(ret) return ret; 476b528cefcSMark Murray p->keytype = tmp; 477b528cefcSMark Murray 478b528cefcSMark Murray if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){ 479b528cefcSMark Murray ret = krb5_ret_int16(sp, &tmp); 480b528cefcSMark Murray if(ret) return ret; 481b528cefcSMark Murray } 482b528cefcSMark Murray 483b528cefcSMark Murray ret = krb5_ret_data(sp, &p->keyvalue); 484b528cefcSMark Murray return ret; 485b528cefcSMark Murray } 486b528cefcSMark Murray 487b528cefcSMark Murray krb5_error_code 488b528cefcSMark Murray krb5_store_times(krb5_storage *sp, krb5_times times) 489b528cefcSMark Murray { 490b528cefcSMark Murray int ret; 491b528cefcSMark Murray ret = krb5_store_int32(sp, times.authtime); 492b528cefcSMark Murray if(ret) return ret; 493b528cefcSMark Murray ret = krb5_store_int32(sp, times.starttime); 494b528cefcSMark Murray if(ret) return ret; 495b528cefcSMark Murray ret = krb5_store_int32(sp, times.endtime); 496b528cefcSMark Murray if(ret) return ret; 497b528cefcSMark Murray ret = krb5_store_int32(sp, times.renew_till); 498b528cefcSMark Murray return ret; 499b528cefcSMark Murray } 500b528cefcSMark Murray 501b528cefcSMark Murray krb5_error_code 502b528cefcSMark Murray krb5_ret_times(krb5_storage *sp, krb5_times *times) 503b528cefcSMark Murray { 504b528cefcSMark Murray int ret; 505b528cefcSMark Murray int32_t tmp; 506b528cefcSMark Murray ret = krb5_ret_int32(sp, &tmp); 507b528cefcSMark Murray times->authtime = tmp; 508b528cefcSMark Murray if(ret) return ret; 509b528cefcSMark Murray ret = krb5_ret_int32(sp, &tmp); 510b528cefcSMark Murray times->starttime = tmp; 511b528cefcSMark Murray if(ret) return ret; 512b528cefcSMark Murray ret = krb5_ret_int32(sp, &tmp); 513b528cefcSMark Murray times->endtime = tmp; 514b528cefcSMark Murray if(ret) return ret; 515b528cefcSMark Murray ret = krb5_ret_int32(sp, &tmp); 516b528cefcSMark Murray times->renew_till = tmp; 517b528cefcSMark Murray return ret; 518b528cefcSMark Murray } 519b528cefcSMark Murray 520b528cefcSMark Murray krb5_error_code 521b528cefcSMark Murray krb5_store_address(krb5_storage *sp, krb5_address p) 522b528cefcSMark Murray { 523b528cefcSMark Murray int ret; 524b528cefcSMark Murray ret = krb5_store_int16(sp, p.addr_type); 525b528cefcSMark Murray if(ret) return ret; 526b528cefcSMark Murray ret = krb5_store_data(sp, p.address); 527b528cefcSMark Murray return ret; 528b528cefcSMark Murray } 529b528cefcSMark Murray 530b528cefcSMark Murray krb5_error_code 531b528cefcSMark Murray krb5_ret_address(krb5_storage *sp, krb5_address *adr) 532b528cefcSMark Murray { 533b528cefcSMark Murray int16_t t; 534b528cefcSMark Murray int ret; 535b528cefcSMark Murray ret = krb5_ret_int16(sp, &t); 536b528cefcSMark Murray if(ret) return ret; 537b528cefcSMark Murray adr->addr_type = t; 538b528cefcSMark Murray ret = krb5_ret_data(sp, &adr->address); 539b528cefcSMark Murray return ret; 540b528cefcSMark Murray } 541b528cefcSMark Murray 542b528cefcSMark Murray krb5_error_code 543b528cefcSMark Murray krb5_store_addrs(krb5_storage *sp, krb5_addresses p) 544b528cefcSMark Murray { 545b528cefcSMark Murray int i; 546b528cefcSMark Murray int ret; 547b528cefcSMark Murray ret = krb5_store_int32(sp, p.len); 548b528cefcSMark Murray if(ret) return ret; 549b528cefcSMark Murray for(i = 0; i<p.len; i++){ 550b528cefcSMark Murray ret = krb5_store_address(sp, p.val[i]); 551b528cefcSMark Murray if(ret) break; 552b528cefcSMark Murray } 553b528cefcSMark Murray return ret; 554b528cefcSMark Murray } 555b528cefcSMark Murray 556b528cefcSMark Murray krb5_error_code 557b528cefcSMark Murray krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr) 558b528cefcSMark Murray { 559b528cefcSMark Murray int i; 560b528cefcSMark Murray int ret; 561b528cefcSMark Murray int32_t tmp; 562b528cefcSMark Murray 563b528cefcSMark Murray ret = krb5_ret_int32(sp, &tmp); 564b528cefcSMark Murray if(ret) return ret; 565b528cefcSMark Murray adr->len = tmp; 566b528cefcSMark Murray ALLOC(adr->val, adr->len); 567b528cefcSMark Murray for(i = 0; i < adr->len; i++){ 568b528cefcSMark Murray ret = krb5_ret_address(sp, &adr->val[i]); 569b528cefcSMark Murray if(ret) break; 570b528cefcSMark Murray } 571b528cefcSMark Murray return ret; 572b528cefcSMark Murray } 573b528cefcSMark Murray 574b528cefcSMark Murray krb5_error_code 575b528cefcSMark Murray krb5_store_authdata(krb5_storage *sp, krb5_authdata auth) 576b528cefcSMark Murray { 577b528cefcSMark Murray krb5_error_code ret; 578b528cefcSMark Murray int i; 579b528cefcSMark Murray ret = krb5_store_int32(sp, auth.len); 580b528cefcSMark Murray if(ret) return ret; 581b528cefcSMark Murray for(i = 0; i < auth.len; i++){ 582b528cefcSMark Murray ret = krb5_store_int16(sp, auth.val[i].ad_type); 583b528cefcSMark Murray if(ret) break; 584b528cefcSMark Murray ret = krb5_store_data(sp, auth.val[i].ad_data); 585b528cefcSMark Murray if(ret) break; 586b528cefcSMark Murray } 587b528cefcSMark Murray return 0; 588b528cefcSMark Murray } 589b528cefcSMark Murray 590b528cefcSMark Murray krb5_error_code 591b528cefcSMark Murray krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth) 592b528cefcSMark Murray { 593b528cefcSMark Murray krb5_error_code ret; 594b528cefcSMark Murray int32_t tmp; 595b528cefcSMark Murray int16_t tmp2; 596b528cefcSMark Murray int i; 597b528cefcSMark Murray ret = krb5_ret_int32(sp, &tmp); 598b528cefcSMark Murray if(ret) return ret; 599b528cefcSMark Murray ALLOC_SEQ(auth, tmp); 600b528cefcSMark Murray for(i = 0; i < tmp; i++){ 601b528cefcSMark Murray ret = krb5_ret_int16(sp, &tmp2); 602b528cefcSMark Murray if(ret) break; 603b528cefcSMark Murray auth->val[i].ad_type = tmp2; 604b528cefcSMark Murray ret = krb5_ret_data(sp, &auth->val[i].ad_data); 605b528cefcSMark Murray if(ret) break; 606b528cefcSMark Murray } 607b528cefcSMark Murray return ret; 608b528cefcSMark Murray } 609b528cefcSMark Murray 6101c43270aSJacques Vidrine static int32_t 6111c43270aSJacques Vidrine bitswap32(int32_t b) 6121c43270aSJacques Vidrine { 6131c43270aSJacques Vidrine int32_t r = 0; 6141c43270aSJacques Vidrine int i; 6151c43270aSJacques Vidrine for (i = 0; i < 32; i++) { 6161c43270aSJacques Vidrine r = r << 1 | (b & 1); 6171c43270aSJacques Vidrine b = b >> 1; 6181c43270aSJacques Vidrine } 6191c43270aSJacques Vidrine return r; 6201c43270aSJacques Vidrine } 6211c43270aSJacques Vidrine 6221c43270aSJacques Vidrine 6235e9cd1aeSAssar Westerlund /* 6241c43270aSJacques Vidrine * 6255e9cd1aeSAssar Westerlund */ 6265e9cd1aeSAssar Westerlund 627b528cefcSMark Murray krb5_error_code 6281c43270aSJacques Vidrine _krb5_store_creds_internal(krb5_storage *sp, krb5_creds *creds, int v0_6) 629b528cefcSMark Murray { 6305e9cd1aeSAssar Westerlund int ret; 6315e9cd1aeSAssar Westerlund 6325e9cd1aeSAssar Westerlund ret = krb5_store_principal(sp, creds->client); 6335e9cd1aeSAssar Westerlund if(ret) 6345e9cd1aeSAssar Westerlund return ret; 6355e9cd1aeSAssar Westerlund ret = krb5_store_principal(sp, creds->server); 6365e9cd1aeSAssar Westerlund if(ret) 6375e9cd1aeSAssar Westerlund return ret; 6385e9cd1aeSAssar Westerlund ret = krb5_store_keyblock(sp, creds->session); 6395e9cd1aeSAssar Westerlund if(ret) 6405e9cd1aeSAssar Westerlund return ret; 6415e9cd1aeSAssar Westerlund ret = krb5_store_times(sp, creds->times); 6425e9cd1aeSAssar Westerlund if(ret) 6435e9cd1aeSAssar Westerlund return ret; 6445e9cd1aeSAssar Westerlund ret = krb5_store_int8(sp, 0); /* this is probably the 645b528cefcSMark Murray enc-tkt-in-skey bit from KDCOptions */ 6465e9cd1aeSAssar Westerlund if(ret) 6475e9cd1aeSAssar Westerlund return ret; 6481c43270aSJacques Vidrine if (v0_6) { 6495e9cd1aeSAssar Westerlund ret = krb5_store_int32(sp, creds->flags.i); 6505e9cd1aeSAssar Westerlund if(ret) 6515e9cd1aeSAssar Westerlund return ret; 6521c43270aSJacques Vidrine } else { 6531c43270aSJacques Vidrine ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b))); 6541c43270aSJacques Vidrine if(ret) 6551c43270aSJacques Vidrine return ret; 6561c43270aSJacques Vidrine } 6575e9cd1aeSAssar Westerlund ret = krb5_store_addrs(sp, creds->addresses); 6585e9cd1aeSAssar Westerlund if(ret) 6595e9cd1aeSAssar Westerlund return ret; 6605e9cd1aeSAssar Westerlund ret = krb5_store_authdata(sp, creds->authdata); 6615e9cd1aeSAssar Westerlund if(ret) 6625e9cd1aeSAssar Westerlund return ret; 6635e9cd1aeSAssar Westerlund ret = krb5_store_data(sp, creds->ticket); 6645e9cd1aeSAssar Westerlund if(ret) 6655e9cd1aeSAssar Westerlund return ret; 6665e9cd1aeSAssar Westerlund ret = krb5_store_data(sp, creds->second_ticket); 6675e9cd1aeSAssar Westerlund return ret; 668b528cefcSMark Murray } 669b528cefcSMark Murray 6701c43270aSJacques Vidrine /* 6711c43270aSJacques Vidrine * store `creds' on `sp' returning error or zero 6721c43270aSJacques Vidrine */ 6731c43270aSJacques Vidrine 6741c43270aSJacques Vidrine krb5_error_code 6751c43270aSJacques Vidrine krb5_store_creds(krb5_storage *sp, krb5_creds *creds) 6761c43270aSJacques Vidrine { 6771c43270aSJacques Vidrine return _krb5_store_creds_internal(sp, creds, 1); 6781c43270aSJacques Vidrine } 6791c43270aSJacques Vidrine 6801c43270aSJacques Vidrine krb5_error_code 6811c43270aSJacques Vidrine _krb5_store_creds_heimdal_0_7(krb5_storage *sp, krb5_creds *creds) 6821c43270aSJacques Vidrine { 6831c43270aSJacques Vidrine return _krb5_store_creds_internal(sp, creds, 0); 6841c43270aSJacques Vidrine } 6851c43270aSJacques Vidrine 6861c43270aSJacques Vidrine krb5_error_code 6871c43270aSJacques Vidrine _krb5_store_creds_heimdal_pre_0_7(krb5_storage *sp, krb5_creds *creds) 6881c43270aSJacques Vidrine { 6891c43270aSJacques Vidrine return _krb5_store_creds_internal(sp, creds, 1); 6901c43270aSJacques Vidrine } 6911c43270aSJacques Vidrine 692b528cefcSMark Murray krb5_error_code 693b528cefcSMark Murray krb5_ret_creds(krb5_storage *sp, krb5_creds *creds) 694b528cefcSMark Murray { 695b528cefcSMark Murray krb5_error_code ret; 696b528cefcSMark Murray int8_t dummy8; 697b528cefcSMark Murray int32_t dummy32; 698b528cefcSMark Murray 699b528cefcSMark Murray memset(creds, 0, sizeof(*creds)); 700b528cefcSMark Murray ret = krb5_ret_principal (sp, &creds->client); 701b528cefcSMark Murray if(ret) goto cleanup; 702b528cefcSMark Murray ret = krb5_ret_principal (sp, &creds->server); 703b528cefcSMark Murray if(ret) goto cleanup; 704b528cefcSMark Murray ret = krb5_ret_keyblock (sp, &creds->session); 705b528cefcSMark Murray if(ret) goto cleanup; 706b528cefcSMark Murray ret = krb5_ret_times (sp, &creds->times); 707b528cefcSMark Murray if(ret) goto cleanup; 708b528cefcSMark Murray ret = krb5_ret_int8 (sp, &dummy8); 709b528cefcSMark Murray if(ret) goto cleanup; 710b528cefcSMark Murray ret = krb5_ret_int32 (sp, &dummy32); 711b528cefcSMark Murray if(ret) goto cleanup; 7121c43270aSJacques Vidrine /* 7131c43270aSJacques Vidrine * Runtime detect the what is the higher bits of the bitfield. If 7141c43270aSJacques Vidrine * any of the higher bits are set in the input data, its either a 7151c43270aSJacques Vidrine * new ticket flag (and this code need to be removed), or its a 7161c43270aSJacques Vidrine * MIT cache (or new Heimdal cache), lets change it to our current 7171c43270aSJacques Vidrine * format. 7181c43270aSJacques Vidrine */ 7191c43270aSJacques Vidrine { 7201c43270aSJacques Vidrine u_int32_t mask = 0xffff0000; 7211c43270aSJacques Vidrine creds->flags.i = 0; 7221c43270aSJacques Vidrine creds->flags.b.anonymous = 1; 7231c43270aSJacques Vidrine if (creds->flags.i & mask) 7241c43270aSJacques Vidrine mask = ~mask; 7251c43270aSJacques Vidrine if (dummy32 & mask) 7261c43270aSJacques Vidrine dummy32 = bitswap32(dummy32); 7271c43270aSJacques Vidrine } 728b528cefcSMark Murray creds->flags.i = dummy32; 729b528cefcSMark Murray ret = krb5_ret_addrs (sp, &creds->addresses); 730b528cefcSMark Murray if(ret) goto cleanup; 731b528cefcSMark Murray ret = krb5_ret_authdata (sp, &creds->authdata); 732b528cefcSMark Murray if(ret) goto cleanup; 733b528cefcSMark Murray ret = krb5_ret_data (sp, &creds->ticket); 734b528cefcSMark Murray if(ret) goto cleanup; 735b528cefcSMark Murray ret = krb5_ret_data (sp, &creds->second_ticket); 736b528cefcSMark Murray cleanup: 7378373020dSJacques Vidrine if(ret) { 738b528cefcSMark Murray #if 0 7398373020dSJacques Vidrine krb5_free_creds_contents(context, creds); /* XXX */ 740b528cefcSMark Murray #endif 7418373020dSJacques Vidrine } 742b528cefcSMark Murray return ret; 743b528cefcSMark Murray } 744