LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/krb5 - store.c (source / functions) Hit Total Coverage
Test: coverage report for recycleplus df22b230 Lines: 358 781 45.8 %
Date: 2024-02-14 10:14:15 Functions: 47 69 68.1 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 1997-2008 Kungliga Tekniska Högskolan
       3             :  * (Royal Institute of Technology, Stockholm, Sweden).
       4             :  * All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions
       8             :  * are met:
       9             :  *
      10             :  * 1. Redistributions of source code must retain the above copyright
      11             :  *    notice, this list of conditions and the following disclaimer.
      12             :  *
      13             :  * 2. Redistributions in binary form must reproduce the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer in the
      15             :  *    documentation and/or other materials provided with the distribution.
      16             :  *
      17             :  * 3. Neither the name of the Institute nor the names of its contributors
      18             :  *    may be used to endorse or promote products derived from this software
      19             :  *    without specific prior written permission.
      20             :  *
      21             :  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
      22             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
      25             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      27             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      31             :  * SUCH DAMAGE.
      32             :  */
      33             : 
      34             : #include "krb5_locl.h"
      35             : #include "store-int.h"
      36             : 
      37             : #define BYTEORDER_IS(SP, V) (((SP)->flags & KRB5_STORAGE_BYTEORDER_MASK) == (V))
      38             : #define BYTEORDER_IS_LE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_LE)
      39             : #define BYTEORDER_IS_BE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_BE)
      40             : #define BYTEORDER_IS_HOST(SP) (BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_HOST) || \
      41             :                                krb5_storage_is_flags((SP), KRB5_STORAGE_HOST_BYTEORDER))
      42             : #define BYTEORDER_IS_PACKED(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_PACKED)
      43             : 
      44             : /**
      45             :  * Add the flags on a storage buffer by or-ing in the flags to the buffer.
      46             :  *
      47             :  * @param sp the storage buffer to set the flags on
      48             :  * @param flags the flags to set
      49             :  *
      50             :  * @ingroup krb5_storage
      51             :  */
      52             : 
      53             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
      54      631606 : krb5_storage_set_flags(krb5_storage *sp, krb5_flags flags)
      55             : {
      56      631606 :     sp->flags |= flags;
      57      631606 : }
      58             : 
      59             : /**
      60             :  * Clear the flags on a storage buffer
      61             :  *
      62             :  * @param sp the storage buffer to clear the flags on
      63             :  * @param flags the flags to clear
      64             :  *
      65             :  * @ingroup krb5_storage
      66             :  */
      67             : 
      68             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
      69           0 : krb5_storage_clear_flags(krb5_storage *sp, krb5_flags flags)
      70             : {
      71           0 :     sp->flags &= ~flags;
      72           0 : }
      73             : 
      74             : /**
      75             :  * Return true or false depending on if the storage flags is set or
      76             :  * not. NB testing for the flag 0 always return true.
      77             :  *
      78             :  * @param sp the storage buffer to check flags on
      79             :  * @param flags The flags to test for
      80             :  *
      81             :  * @return true if all the flags are set, false if not.
      82             :  *
      83             :  * @ingroup krb5_storage
      84             :  */
      85             : 
      86             : KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
      87     9443336 : krb5_storage_is_flags(krb5_storage *sp, krb5_flags flags)
      88             : {
      89     9443336 :     return (sp->flags & flags) == flags;
      90             : }
      91             : 
      92             : /**
      93             :  * Set the new byte order of the storage buffer.
      94             :  *
      95             :  * @param sp the storage buffer to set the byte order for.
      96             :  * @param byteorder the new byte order.
      97             :  *
      98             :  * The byte order are: KRB5_STORAGE_BYTEORDER_BE,
      99             :  * KRB5_STORAGE_BYTEORDER_LE and KRB5_STORAGE_BYTEORDER_HOST.
     100             :  *
     101             :  * @ingroup krb5_storage
     102             :  */
     103             : 
     104             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
     105           0 : krb5_storage_set_byteorder(krb5_storage *sp, krb5_flags byteorder)
     106             : {
     107           0 :     sp->flags &= ~KRB5_STORAGE_BYTEORDER_MASK;
     108           0 :     sp->flags |= byteorder;
     109           0 : }
     110             : 
     111             : /**
     112             :  * Return the current byteorder for the buffer. See krb5_storage_set_byteorder() for the list or byte order contants.
     113             :  *
     114             :  * @ingroup krb5_storage
     115             :  */
     116             : 
     117             : KRB5_LIB_FUNCTION krb5_flags KRB5_LIB_CALL
     118           0 : krb5_storage_get_byteorder(krb5_storage *sp)
     119             : {
     120           0 :     return sp->flags & KRB5_STORAGE_BYTEORDER_MASK;
     121             : }
     122             : 
     123             : /**
     124             :  * Set the max alloc value
     125             :  *
     126             :  * @param sp the storage buffer set the max allow for
     127             :  * @param size maximum size to allocate, use 0 to remove limit
     128             :  *
     129             :  * @ingroup krb5_storage
     130             :  */
     131             : 
     132             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
     133           0 : krb5_storage_set_max_alloc(krb5_storage *sp, size_t size)
     134             : {
     135           0 :     sp->max_alloc = size;
     136           0 : }
     137             : 
     138             : /* don't allocate unresonable amount of memory */
     139             : static krb5_error_code
     140      860509 : size_too_large(krb5_storage *sp, size_t size)
     141             : {
     142      860509 :     if (sp->max_alloc && sp->max_alloc < size)
     143           0 :         return HEIM_ERR_TOO_BIG;
     144      860509 :     return 0;
     145             : }
     146             : 
     147             : static krb5_error_code
     148      118334 : size_too_large_num(krb5_storage *sp, size_t count, size_t size)
     149             : {
     150      118334 :     if (sp->max_alloc == 0 || size == 0)
     151           0 :         return 0;
     152      118334 :     size = sp->max_alloc / size;
     153      118334 :     if (size < count)
     154           0 :         return HEIM_ERR_TOO_BIG;
     155      118334 :     return 0;
     156             : }
     157             : 
     158             : /**
     159             :  * Seek to a new offset.
     160             :  *
     161             :  * @param sp the storage buffer to seek in.
     162             :  * @param offset the offset to seek
     163             :  * @param whence relateive searching, SEEK_CUR from the current
     164             :  * position, SEEK_END from the end, SEEK_SET absolute from the start.
     165             :  *
     166             :  * @return The new current offset
     167             :  *
     168             :  * @ingroup krb5_storage
     169             :  */
     170             : 
     171             : KRB5_LIB_FUNCTION off_t KRB5_LIB_CALL
     172      602498 : krb5_storage_seek(krb5_storage *sp, off_t offset, int whence)
     173             : {
     174      602498 :     return (*sp->seek)(sp, offset, whence);
     175             : }
     176             : 
     177             : /**
     178             :  * Truncate the storage buffer in sp to offset.
     179             :  *
     180             :  * @param sp the storage buffer to truncate.
     181             :  * @param offset the offset to truncate too.
     182             :  *
     183             :  * @return An Kerberos 5 error code.
     184             :  *
     185             :  * @ingroup krb5_storage
     186             :  */
     187             : 
     188             : KRB5_LIB_FUNCTION int KRB5_LIB_CALL
     189        1247 : krb5_storage_truncate(krb5_storage *sp, off_t offset)
     190             : {
     191        1247 :     return (*sp->trunc)(sp, offset);
     192             : }
     193             : 
     194             : /**
     195             :  * Sync the storage buffer to its backing store.  If there is no
     196             :  * backing store this function will return success.
     197             :  *
     198             :  * @param sp the storage buffer to sync
     199             :  *
     200             :  * @return A Kerberos 5 error code
     201             :  *
     202             :  * @ingroup krb5_storage
     203             :  */
     204             : 
     205             : KRB5_LIB_FUNCTION int KRB5_LIB_CALL
     206        1461 : krb5_storage_fsync(krb5_storage *sp)
     207             : {
     208        1461 :     if (sp->fsync != NULL)
     209        1461 :         return sp->fsync(sp);
     210           0 :     return 0;
     211             : }
     212             : 
     213             : /**
     214             :  * Read to the storage buffer.
     215             :  *
     216             :  * @param sp the storage buffer to read from
     217             :  * @param buf the buffer to store the data in
     218             :  * @param len the length to read
     219             :  *
     220             :  * @return The length of data read (can be shorter then len), or negative on error.
     221             :  *
     222             :  * @ingroup krb5_storage
     223             :  */
     224             : 
     225             : KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL
     226      757150 : krb5_storage_read(krb5_storage *sp, void *buf, size_t len)
     227             : {
     228      757150 :     return sp->fetch(sp, buf, len);
     229             : }
     230             : 
     231             : /**
     232             :  * Write to the storage buffer.
     233             :  *
     234             :  * @param sp the storage buffer to write to
     235             :  * @param buf the buffer to write to the storage buffer
     236             :  * @param len the length to write
     237             :  *
     238             :  * @return The length of data written (can be shorter then len), or negative on error.
     239             :  *
     240             :  * @ingroup krb5_storage
     241             :  */
     242             : 
     243             : KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL
     244      752289 : krb5_storage_write(krb5_storage *sp, const void *buf, size_t len)
     245             : {
     246      752289 :     return sp->store(sp, buf, len);
     247             : }
     248             : 
     249             : /**
     250             :  * Set the return code that will be used when end of storage is reached.
     251             :  *
     252             :  * @param sp the storage
     253             :  * @param code the error code to return on end of storage
     254             :  *
     255             :  * @ingroup krb5_storage
     256             :  */
     257             : 
     258             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
     259       52212 : krb5_storage_set_eof_code(krb5_storage *sp, int code)
     260             : {
     261       52212 :     sp->eof_code = code;
     262       52212 : }
     263             : 
     264             : /**
     265             :  * Get the return code that will be used when end of storage is reached.
     266             :  *
     267             :  * @param sp the storage
     268             :  *
     269             :  * @return storage error code
     270             :  *
     271             :  * @ingroup krb5_storage
     272             :  */
     273             : 
     274             : KRB5_LIB_FUNCTION int KRB5_LIB_CALL
     275           0 : krb5_storage_get_eof_code(krb5_storage *sp)
     276             : {
     277           0 :     return sp->eof_code;
     278             : }
     279             : 
     280             : /**
     281             :  * Free a krb5 storage.
     282             :  *
     283             :  * @param sp the storage to free.
     284             :  *
     285             :  * @return An Kerberos 5 error code.
     286             :  *
     287             :  * @ingroup krb5_storage
     288             :  */
     289             : 
     290             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     291      977458 : krb5_storage_free(krb5_storage *sp)
     292             : {
     293      977458 :     if (sp == NULL)
     294           0 :         return 0;
     295      977458 :     if(sp->free)
     296      381501 :         (*sp->free)(sp);
     297      977458 :     free(sp->data);
     298      977458 :     free(sp);
     299      977458 :     return 0;
     300             : }
     301             : 
     302             : /**
     303             :  * Copy the contnent of storage
     304             :  *
     305             :  * @param sp the storage to copy to a data
     306             :  * @param data the copied data, free with krb5_data_free()
     307             :  *
     308             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     309             :  *
     310             :  * @ingroup krb5_storage
     311             :  */
     312             : 
     313             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     314      329896 : krb5_storage_to_data(krb5_storage *sp, krb5_data *data)
     315             : {
     316             :     off_t pos, size;
     317             :     krb5_error_code ret;
     318             : 
     319      329896 :     pos = sp->seek(sp, 0, SEEK_CUR);
     320      329896 :     if (pos < 0)
     321           0 :         return HEIM_ERR_NOT_SEEKABLE;
     322      329896 :     size = sp->seek(sp, 0, SEEK_END);
     323      329896 :     ret = size_too_large(sp, size);
     324      329896 :     if (ret)
     325           0 :         return ret;
     326      329896 :     ret = krb5_data_alloc(data, size);
     327      329896 :     if (ret) {
     328           0 :         sp->seek(sp, pos, SEEK_SET);
     329           0 :         return ret;
     330             :     }
     331      329896 :     if (size) {
     332      329896 :         sp->seek(sp, 0, SEEK_SET);
     333      329896 :         sp->fetch(sp, data->data, data->length);
     334      329896 :         sp->seek(sp, pos, SEEK_SET);
     335             :     }
     336      329896 :     return 0;
     337             : }
     338             : 
     339             : static size_t
     340           0 : pack_int(uint8_t *p, uint64_t val)
     341             : {
     342           0 :     size_t l = 0;
     343             : 
     344           0 :     if (val < 128) {
     345           0 :         *p = val;
     346             :     } else {
     347           0 :         while (val > 0) {
     348           0 :             *p-- = val % 256;
     349           0 :             val /= 256;
     350           0 :             l++;
     351             :         }
     352           0 :         *p = 0x80 | l;
     353             :     }
     354           0 :     return l + 1;
     355             : }
     356             : 
     357             : static size_t
     358           0 : unpack_int_length(uint8_t *v)
     359             : {
     360             :     size_t size;
     361             : 
     362           0 :     if (*v < 128)
     363           0 :         size = 0;
     364             :     else
     365           0 :         size = *v & 0x7f;
     366             : 
     367           0 :     return size + 1;
     368             : }
     369             : 
     370             : static int
     371           0 : unpack_int(uint8_t *p, size_t len, uint64_t *val, size_t *size)
     372             : {
     373             :     size_t v;
     374             : 
     375           0 :     if (len == 0)
     376           0 :         return EINVAL;
     377           0 :     --len;
     378           0 :     v = *p++;
     379           0 :     if (v < 128) {
     380           0 :         *val = v;
     381           0 :         *size = 1;
     382             :     } else {
     383             :         int e;
     384             :         size_t l;
     385             :         uint64_t tmp;
     386             : 
     387           0 :         if (v == 0x80) {
     388           0 :             *size = 1;
     389           0 :             return EINVAL;
     390             :         }
     391           0 :         v &= 0x7F;
     392           0 :         if (len < v)
     393           0 :             return ERANGE;
     394           0 :         e = der_get_unsigned64(p, v, &tmp, &l);
     395           0 :         if (e)
     396           0 :             return ERANGE;
     397           0 :         *val = tmp;
     398           0 :         *size = l + 1;
     399             :     }
     400           0 :     return 0;
     401             : }
     402             : 
     403             : static krb5_error_code
     404     1986391 : krb5_store_int(krb5_storage *sp,
     405             :                int64_t value,
     406             :                size_t len)
     407             : {
     408             :     int ret;
     409     1986391 :     uint8_t v[9], *p = v;
     410             : 
     411     1986391 :     if (len > sizeof(value))
     412           0 :         return EINVAL;
     413             : 
     414     1986391 :     if (BYTEORDER_IS_PACKED(sp)) {
     415           0 :         uint64_t mask = ~0ULL >> (64 - len * 8);
     416           0 :         value &= mask;
     417           0 :         p += sizeof(v) - 1;
     418           0 :         len = pack_int(p, value);
     419           0 :         p = v + sizeof(v) - len;
     420             :     } else
     421     1986391 :         _krb5_put_int(v, value, len);
     422     1986391 :     ret = sp->store(sp, p, len);
     423     1986391 :     if (ret < 0)
     424           0 :         return errno;
     425     1986391 :     if ((size_t)ret != len)
     426           0 :         return sp->eof_code;
     427     1986391 :     return 0;
     428             : }
     429             : 
     430             : /**
     431             :  * Store a int32 to storage, byte order is controlled by the settings
     432             :  * on the storage, see krb5_storage_set_byteorder().
     433             :  *
     434             :  * @param sp the storage to write too
     435             :  * @param value the value to store
     436             :  *
     437             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     438             :  *
     439             :  * @ingroup krb5_storage
     440             :  */
     441             : 
     442             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     443     1473289 : krb5_store_int32(krb5_storage *sp,
     444             :                  int32_t value)
     445             : {
     446     1473289 :     if(BYTEORDER_IS_HOST(sp))
     447           0 :         value = htonl(value);
     448     1473289 :     else if(BYTEORDER_IS_LE(sp))
     449     1114088 :         value = bswap32(value);
     450     1473289 :     return krb5_store_int(sp, value, 4);
     451             : }
     452             : 
     453             : /**
     454             :  * Store a int64 to storage, byte order is controlled by the settings
     455             :  * on the storage, see krb5_storage_set_byteorder().
     456             :  *
     457             :  * @param sp the storage to write too
     458             :  * @param value the value to store
     459             :  *
     460             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     461             :  *
     462             :  * @ingroup krb5_storage
     463             :  */
     464             : 
     465             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     466      378414 : krb5_store_int64(krb5_storage *sp,
     467             :                  int64_t value)
     468             : {
     469      378414 :     if (BYTEORDER_IS_HOST(sp))
     470             : #ifdef WORDS_BIGENDIAN
     471             :         ;
     472             : #else
     473           0 :         value = bswap64(value); /* There's no ntohll() */
     474             : #endif
     475      378414 :     else if (BYTEORDER_IS_LE(sp))
     476      378414 :         value = bswap64(value);
     477      378414 :     return krb5_store_int(sp, value, 8);
     478             : }
     479             : 
     480             : /**
     481             :  * Store a uint32 to storage, byte order is controlled by the settings
     482             :  * on the storage, see krb5_storage_set_byteorder().
     483             :  *
     484             :  * @param sp the storage to write too
     485             :  * @param value the value to store
     486             :  *
     487             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     488             :  *
     489             :  * @ingroup krb5_storage
     490             :  */
     491             : 
     492             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     493     1114876 : krb5_store_uint32(krb5_storage *sp,
     494             :                   uint32_t value)
     495             : {
     496     1114876 :     return krb5_store_int32(sp, (int32_t)value);
     497             : }
     498             : 
     499             : /**
     500             :  * Store a uint64 to storage, byte order is controlled by the settings
     501             :  * on the storage, see krb5_storage_set_byteorder().
     502             :  *
     503             :  * @param sp the storage to write too
     504             :  * @param value the value to store
     505             :  *
     506             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     507             :  *
     508             :  * @ingroup krb5_storage
     509             :  */
     510             : 
     511             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     512      378414 : krb5_store_uint64(krb5_storage *sp,
     513             :                   uint64_t value)
     514             : {
     515      378414 :     return krb5_store_int64(sp, (int64_t)value);
     516             : }
     517             : 
     518             : static krb5_error_code
     519     6867885 : krb5_ret_int(krb5_storage *sp,
     520             :              int64_t *value,
     521             :              size_t len)
     522             : {
     523             :     int ret;
     524             :     unsigned char v[9];
     525     6867885 :     uint64_t w = 0;
     526     6867885 :     *value = 0; /* quiets warnings */
     527     6867885 :     if (BYTEORDER_IS_PACKED(sp)) {
     528           0 :         ret = sp->fetch(sp, v, 1);
     529           0 :         if (ret < 0)
     530           0 :             return errno;
     531             : 
     532           0 :         len = unpack_int_length(v);
     533           0 :         if (len < 1)
     534           0 :             return ERANGE;
     535           0 :         else if (len > 1) {
     536           0 :             ret = sp->fetch(sp, v + 1, len - 1);
     537           0 :             if (ret < 0)
     538           0 :                 return errno;
     539             :         }
     540           0 :         ret = unpack_int(v, len, &w, &len);
     541           0 :         if (ret)
     542           0 :             return ret;
     543           0 :         *value = w;
     544           0 :         return 0;
     545             :     }
     546     6867885 :     ret = sp->fetch(sp, v, len);
     547     6867885 :     if (ret < 0)
     548           0 :         return errno;
     549     6867885 :     if ((size_t)ret != len)
     550       26610 :         return sp->eof_code;
     551     6841275 :     _krb5_get_int64(v, &w, len);
     552     6841275 :     *value = w;
     553     6841275 :     return 0;
     554             : }
     555             : 
     556             : /**
     557             :  * Read a int64 from storage, byte order is controlled by the settings
     558             :  * on the storage, see krb5_storage_set_byteorder().
     559             :  *
     560             :  * @param sp the storage to write too
     561             :  * @param value the value read from the buffer
     562             :  *
     563             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     564             :  *
     565             :  * @ingroup krb5_storage
     566             :  */
     567             : 
     568             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     569      893009 : krb5_ret_int64(krb5_storage *sp,
     570             :                int64_t *value)
     571             : {
     572      893009 :     krb5_error_code ret = krb5_ret_int(sp, value, 8);
     573      893009 :     if(ret)
     574           0 :         return ret;
     575      893009 :     if(BYTEORDER_IS_HOST(sp))
     576             : #ifdef WORDS_BIGENDIAN
     577             :         ;
     578             : #else
     579           0 :         *value = bswap64(*value); /* There's no ntohll() */
     580             : #endif
     581      893009 :     else if(BYTEORDER_IS_LE(sp))
     582      893009 :         *value = bswap64(*value);
     583      893009 :     return 0;
     584             : }
     585             : 
     586             : /**
     587             :  * Read a uint64 from storage, byte order is controlled by the settings
     588             :  * on the storage, see krb5_storage_set_byteorder().
     589             :  *
     590             :  * @param sp the storage to write too
     591             :  * @param value the value read from the buffer
     592             :  *
     593             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     594             :  *
     595             :  * @ingroup krb5_storage
     596             :  */
     597             : 
     598             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     599      893009 : krb5_ret_uint64(krb5_storage *sp,
     600             :                 uint64_t *value)
     601             : {
     602             :     krb5_error_code ret;
     603             :     int64_t v;
     604             : 
     605      893009 :     ret = krb5_ret_int64(sp, &v);
     606      893009 :     if (ret == 0)
     607      893009 :         *value = (uint64_t)v;
     608             : 
     609      893009 :     return ret;
     610             : }
     611             : 
     612             : /**
     613             :  * Read a int32 from storage, byte order is controlled by the settings
     614             :  * on the storage, see krb5_storage_set_byteorder().
     615             :  *
     616             :  * @param sp the storage to write too
     617             :  * @param value the value read from the buffer
     618             :  *
     619             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     620             :  *
     621             :  * @ingroup krb5_storage
     622             :  */
     623             : 
     624             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     625     4219739 : krb5_ret_int32(krb5_storage *sp,
     626             :                int32_t *value)
     627             : {
     628             :     int64_t v;
     629             : 
     630     4219739 :     krb5_error_code ret = krb5_ret_int(sp, &v, 4);
     631     4219739 :     if (ret)
     632       26610 :         return ret;
     633     4193129 :     *value = v;
     634     4193129 :     if (BYTEORDER_IS_HOST(sp))
     635           0 :         *value = htonl(*value);
     636     4193129 :     else if (BYTEORDER_IS_LE(sp))
     637     2442107 :         *value = bswap32(*value);
     638     4193129 :     return 0;
     639             : }
     640             : 
     641             : /**
     642             :  * Read a uint32 from storage, byte order is controlled by the settings
     643             :  * on the storage, see krb5_storage_set_byteorder().
     644             :  *
     645             :  * @param sp the storage to write too
     646             :  * @param value the value read from the buffer
     647             :  *
     648             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     649             :  *
     650             :  * @ingroup krb5_storage
     651             :  */
     652             : 
     653             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     654     2790288 : krb5_ret_uint32(krb5_storage *sp, uint32_t *value)
     655             : {
     656             :     krb5_error_code ret;
     657             :     int32_t v;
     658             : 
     659     2790288 :     ret = krb5_ret_int32(sp, &v);
     660     2790288 :     if (ret == 0)
     661     2790288 :         *value = (uint32_t)v;
     662             : 
     663     2790288 :     return ret;
     664             : }
     665             : 
     666             : /**
     667             :  * Store a int16 to storage, byte order is controlled by the settings
     668             :  * on the storage, see krb5_storage_set_byteorder().
     669             :  *
     670             :  * @param sp the storage to write too
     671             :  * @param value the value to store
     672             :  *
     673             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     674             :  *
     675             :  * @ingroup krb5_storage
     676             :  */
     677             : 
     678             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     679      134688 : krb5_store_int16(krb5_storage *sp,
     680             :                  int16_t value)
     681             : {
     682      134688 :     if(BYTEORDER_IS_HOST(sp))
     683           0 :         value = htons(value);
     684      134688 :     else if(BYTEORDER_IS_LE(sp))
     685       60401 :         value = bswap16(value);
     686      134688 :     return krb5_store_int(sp, value, 2);
     687             : }
     688             : 
     689             : /**
     690             :  * Store a uint16 to storage, byte order is controlled by the settings
     691             :  * on the storage, see krb5_storage_set_byteorder().
     692             :  *
     693             :  * @param sp the storage to write too
     694             :  * @param value the value to store
     695             :  *
     696             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     697             :  *
     698             :  * @ingroup krb5_storage
     699             :  */
     700             : 
     701             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     702       60401 : krb5_store_uint16(krb5_storage *sp,
     703             :                   uint16_t value)
     704             : {
     705       60401 :     return krb5_store_int16(sp, (int16_t)value);
     706             : }
     707             : 
     708             : /**
     709             :  * Read a int16 from storage, byte order is controlled by the settings
     710             :  * on the storage, see krb5_storage_set_byteorder().
     711             :  *
     712             :  * @param sp the storage to write too
     713             :  * @param value the value read from the buffer
     714             :  *
     715             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     716             :  *
     717             :  * @ingroup krb5_storage
     718             :  */
     719             : 
     720             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     721     1755137 : krb5_ret_int16(krb5_storage *sp,
     722             :                int16_t *value)
     723             : {
     724             :     int64_t v;
     725             :     int ret;
     726     1755137 :     ret = krb5_ret_int(sp, &v, 2);
     727     1755137 :     if(ret)
     728           0 :         return ret;
     729     1755137 :     *value = v;
     730     1755137 :     if(BYTEORDER_IS_HOST(sp))
     731           0 :         *value = htons(*value);
     732     1755137 :     else if(BYTEORDER_IS_LE(sp))
     733      738458 :         *value = bswap16(*value);
     734     1755137 :     return 0;
     735             : }
     736             : 
     737             : /**
     738             :  * Read a int16 from storage, byte order is controlled by the settings
     739             :  * on the storage, see krb5_storage_set_byteorder().
     740             :  *
     741             :  * @param sp the storage to write too
     742             :  * @param value the value read from the buffer
     743             :  *
     744             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     745             :  *
     746             :  * @ingroup krb5_storage
     747             :  */
     748             : 
     749             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     750      738458 : krb5_ret_uint16(krb5_storage *sp,
     751             :                 uint16_t *value)
     752             : {
     753             :     krb5_error_code ret;
     754             :     int16_t v;
     755             : 
     756      738458 :     ret = krb5_ret_int16(sp, &v);
     757      738458 :     if (ret == 0)
     758      738458 :         *value = (uint16_t)v;
     759             : 
     760      738458 :     return ret;
     761             : }
     762             : 
     763             : /**
     764             :  * Store a int8 to storage.
     765             :  *
     766             :  * @param sp the storage to write too
     767             :  * @param value the value to store
     768             :  *
     769             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     770             :  *
     771             :  * @ingroup krb5_storage
     772             :  */
     773             : 
     774             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     775        3307 : krb5_store_int8(krb5_storage *sp,
     776             :                 int8_t value)
     777             : {
     778             :     int ret;
     779             : 
     780        3307 :     ret = sp->store(sp, &value, sizeof(value));
     781        3307 :     if (ret != sizeof(value))
     782           0 :         return (ret<0)?errno:sp->eof_code;
     783        3307 :     return 0;
     784             : }
     785             : 
     786             : /**
     787             :  * Store a uint8 to storage.
     788             :  *
     789             :  * @param sp the storage to write too
     790             :  * @param value the value to store
     791             :  *
     792             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     793             :  *
     794             :  * @ingroup krb5_storage
     795             :  */
     796             : 
     797             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     798           0 : krb5_store_uint8(krb5_storage *sp,
     799             :                  uint8_t value)
     800             : {
     801           0 :     return krb5_store_int8(sp, (int8_t)value);
     802             : }
     803             : 
     804             : /**
     805             :  * Read a int8 from storage
     806             :  *
     807             :  * @param sp the storage to write too
     808             :  * @param value the value read from the buffer
     809             :  *
     810             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     811             :  *
     812             :  * @ingroup krb5_storage
     813             :  */
     814             : 
     815             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     816      293650 : krb5_ret_int8(krb5_storage *sp,
     817             :               int8_t *value)
     818             : {
     819             :     int ret;
     820             : 
     821      293650 :     ret = sp->fetch(sp, value, sizeof(*value));
     822      293650 :     if (ret != sizeof(*value))
     823           0 :         return (ret<0)?errno:sp->eof_code;
     824      293650 :     return 0;
     825             : }
     826             : 
     827             : /**
     828             :  * Read a uint8 from storage
     829             :  *
     830             :  * @param sp the storage to write too
     831             :  * @param value the value read from the buffer
     832             :  *
     833             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     834             :  *
     835             :  * @ingroup krb5_storage
     836             :  */
     837             : 
     838             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     839           0 : krb5_ret_uint8(krb5_storage *sp,
     840             :                uint8_t *value)
     841             : {
     842             :     krb5_error_code ret;
     843             :     int8_t v;
     844             : 
     845           0 :     ret = krb5_ret_int8(sp, &v);
     846           0 :     if (ret == 0)
     847           0 :         *value = (uint8_t)v;
     848             : 
     849           0 :     return ret;
     850             : }
     851             : 
     852             : /**
     853             :  * Store a data to the storage. The data is stored with an int32 as
     854             :  * lenght plus the data (not padded).
     855             :  *
     856             :  * @param sp the storage buffer to write to
     857             :  * @param data the buffer to store.
     858             :  *
     859             :  * @return 0 on success, a Kerberos 5 error code on failure.
     860             :  *
     861             :  * @ingroup krb5_storage
     862             :  */
     863             : 
     864             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     865      285552 : krb5_store_data(krb5_storage *sp,
     866             :                 krb5_data data)
     867             : {
     868             :     int ret;
     869      285552 :     ret = krb5_store_int32(sp, data.length);
     870      285552 :     if(ret < 0)
     871           0 :         return ret;
     872      285552 :     ret = sp->store(sp, data.data, data.length);
     873      285552 :     if(ret < 0)
     874           0 :         return errno;
     875      285552 :     if((size_t)ret != data.length)
     876           0 :         return sp->eof_code;
     877      285552 :     return 0;
     878             : }
     879             : 
     880             : /**
     881             :  * Store a data blob to the storage. The data is stored with an int32 as
     882             :  * length plus the data (not padded).  This function only differs from
     883             :  * krb5_store_data() insofar as it takes a void * and a length as parameters.
     884             :  *
     885             :  * @param sp the storage buffer to write to
     886             :  * @param s the string to store.
     887             :  * @param len length of the string to be stored.
     888             :  *
     889             :  * @return 0 on success, a Kerberos 5 error code on failure.
     890             :  *
     891             :  * @ingroup krb5_storage
     892             :  */
     893             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     894           0 : krb5_store_datalen(krb5_storage *sp, const void *d, size_t len)
     895             : {
     896             :     krb5_data data;
     897           0 :     data.length = len;
     898           0 :     data.data = (void *)d;
     899           0 :     return krb5_store_data(sp, data);
     900             : }
     901             : 
     902             : /**
     903             :  * Store a data blob to the storage. The data is stored without a length.
     904             :  *
     905             :  * @param sp the storage buffer to write to
     906             :  * @param s the string to store.
     907             :  * @param len length of the string to be stored.
     908             :  *
     909             :  * @return 0 on success, a Kerberos 5 error code on failure.
     910             :  *
     911             :  * @ingroup krb5_storage
     912             :  */
     913             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     914           0 : krb5_store_bytes(krb5_storage *sp, const void *d, size_t len)
     915             : {
     916             :     ssize_t ssize;
     917             : 
     918           0 :     ssize = krb5_storage_write(sp, d, len);
     919           0 :     if (ssize != len)
     920           0 :         return ENOMEM;
     921             : 
     922           0 :     return 0;
     923             : }
     924             : 
     925             : /**
     926             :  * Parse a data from the storage.
     927             :  *
     928             :  * @param sp the storage buffer to read from
     929             :  * @param data the parsed data
     930             :  *
     931             :  * @return 0 on success, a Kerberos 5 error code on failure.
     932             :  *
     933             :  * @ingroup krb5_storage
     934             :  */
     935             : 
     936             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     937      554446 : krb5_ret_data(krb5_storage *sp,
     938             :               krb5_data *data)
     939             : {
     940             :     int ret;
     941             :     int32_t size;
     942             : 
     943      554446 :     ret = krb5_ret_int32(sp, &size);
     944      554446 :     if(ret)
     945       23833 :         return ret;
     946      530613 :     ret = size_too_large(sp, size);
     947      530613 :     if (ret)
     948           0 :         return ret;
     949      530613 :     ret = krb5_data_alloc (data, size);
     950      530613 :     if (ret)
     951           0 :         return ret;
     952      530613 :     if (size) {
     953      428966 :         ret = sp->fetch(sp, data->data, size);
     954      428966 :         if(ret != size) {
     955           0 :             krb5_data_free(data);
     956           0 :             return (ret < 0)? errno : sp->eof_code;
     957             :         }
     958             :     }
     959      530613 :     return 0;
     960             : }
     961             : 
     962             : /**
     963             :  * Store a string to the buffer. The data is formated as an len:uint32
     964             :  * plus the string itself (not padded).
     965             :  *
     966             :  * @param sp the storage buffer to write to
     967             :  * @param s the string to store.
     968             :  *
     969             :  * @return 0 on success, a Kerberos 5 error code on failure.
     970             :  *
     971             :  * @ingroup krb5_storage
     972             :  */
     973             : 
     974             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     975      188262 : krb5_store_string(krb5_storage *sp, const char *s)
     976             : {
     977             :     krb5_data data;
     978             : 
     979      188262 :     if (s == NULL)
     980           0 :         return EINVAL;
     981             : 
     982      188262 :     data.length = strlen(s);
     983      188262 :     data.data = rk_UNCONST(s);
     984      188262 :     return krb5_store_data(sp, data);
     985             : }
     986             : 
     987             : /**
     988             :  * Parse a string from the storage.
     989             :  *
     990             :  * @param sp the storage buffer to read from
     991             :  * @param string the parsed string
     992             :  *
     993             :  * @return 0 on success, a Kerberos 5 error code on failure.
     994             :  *
     995             :  * @ingroup krb5_storage
     996             :  */
     997             : 
     998             : 
     999             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1000      332785 : krb5_ret_string(krb5_storage *sp,
    1001             :                 char **string)
    1002             : {
    1003             :     int ret;
    1004             :     krb5_data data;
    1005             : 
    1006      332785 :     *string = NULL;
    1007      332785 :     ret = krb5_ret_data(sp, &data);
    1008      332785 :     if(ret)
    1009           0 :         return ret;
    1010      332785 :     *string = realloc(data.data, data.length + 1);
    1011      332785 :     if(*string == NULL){
    1012           0 :         free(data.data);
    1013           0 :         return ENOMEM;
    1014             :     }
    1015      332785 :     (*string)[data.length] = 0;
    1016      332785 :     return 0;
    1017             : }
    1018             : 
    1019             : /**
    1020             :  * Store a zero terminated string to the buffer. The data is stored
    1021             :  * one character at a time until a NUL is stored.
    1022             :  *
    1023             :  * @param sp the storage buffer to write to
    1024             :  * @param s the string to store.
    1025             :  *
    1026             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1027             :  *
    1028             :  * @ingroup krb5_storage
    1029             :  */
    1030             : 
    1031             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1032           0 : krb5_store_stringz(krb5_storage *sp, const char *s)
    1033             : {
    1034             :     size_t len;
    1035             :     ssize_t ret;
    1036             : 
    1037           0 :     if (s == NULL)
    1038           0 :         return EINVAL;
    1039             : 
    1040           0 :     len = strlen(s) + 1;
    1041           0 :     ret = sp->store(sp, s, len);
    1042           0 :     if(ret < 0)
    1043           0 :         return ret;
    1044           0 :     if((size_t)ret != len)
    1045           0 :         return sp->eof_code;
    1046           0 :     return 0;
    1047             : }
    1048             : 
    1049             : /**
    1050             :  * Parse zero terminated string from the storage.
    1051             :  *
    1052             :  * @param sp the storage buffer to read from
    1053             :  * @param string the parsed string
    1054             :  *
    1055             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1056             :  *
    1057             :  * @ingroup krb5_storage
    1058             :  */
    1059             : 
    1060             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1061           0 : krb5_ret_stringz(krb5_storage *sp,
    1062             :                 char **string)
    1063             : {
    1064             :     char c;
    1065           0 :     char *s = NULL;
    1066           0 :     size_t len = 0;
    1067             :     ssize_t ret;
    1068             : 
    1069           0 :     while((ret = sp->fetch(sp, &c, 1)) == 1){
    1070             :         krb5_error_code eret;
    1071             :         char *tmp;
    1072             : 
    1073           0 :         len++;
    1074           0 :         eret = size_too_large(sp, len);
    1075           0 :         if (eret) {
    1076           0 :             free(s);
    1077           0 :             return eret;
    1078             :         }
    1079           0 :         tmp = realloc (s, len);
    1080           0 :         if (tmp == NULL) {
    1081           0 :             free (s);
    1082           0 :             return ENOMEM;
    1083             :         }
    1084           0 :         s = tmp;
    1085           0 :         s[len - 1] = c;
    1086           0 :         if(c == 0)
    1087           0 :             break;
    1088             :     }
    1089           0 :     if(ret != 1){
    1090           0 :         free(s);
    1091           0 :         if(ret == 0)
    1092           0 :             return sp->eof_code;
    1093           0 :         return ret;
    1094             :     }
    1095           0 :     *string = s;
    1096           0 :     return 0;
    1097             : }
    1098             : 
    1099             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1100           0 : krb5_store_stringnl(krb5_storage *sp, const char *s)
    1101             : {
    1102             :     size_t len;
    1103             :     ssize_t ret;
    1104             : 
    1105           0 :     if (s == NULL)
    1106           0 :         return EINVAL;
    1107             : 
    1108           0 :     len = strlen(s);
    1109           0 :     ret = sp->store(sp, s, len);
    1110           0 :     if(ret < 0)
    1111           0 :         return ret;
    1112           0 :     if((size_t)ret != len)
    1113           0 :         return sp->eof_code;
    1114           0 :     ret = sp->store(sp, "\n", 1);
    1115           0 :     if(ret != 1) {
    1116           0 :         if(ret < 0)
    1117           0 :             return ret;
    1118             :         else
    1119           0 :             return sp->eof_code;
    1120             :     }
    1121             : 
    1122           0 :     return 0;
    1123             : 
    1124             : }
    1125             : 
    1126             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1127           0 : krb5_ret_stringnl(krb5_storage *sp,
    1128             :                   char **string)
    1129             : {
    1130           0 :     int expect_nl = 0;
    1131             :     char c;
    1132           0 :     char *s = NULL;
    1133           0 :     size_t len = 0;
    1134             :     ssize_t ret;
    1135             : 
    1136           0 :     while((ret = sp->fetch(sp, &c, 1)) == 1){
    1137             :         krb5_error_code eret;
    1138             :         char *tmp;
    1139             : 
    1140           0 :         if (c == '\r') {
    1141           0 :             expect_nl = 1;
    1142           0 :             continue;
    1143             :         }
    1144           0 :         if (expect_nl && c != '\n') {
    1145           0 :             free(s);
    1146           0 :             return KRB5_BADMSGTYPE;
    1147             :         }
    1148             : 
    1149           0 :         len++;
    1150           0 :         eret = size_too_large(sp, len);
    1151           0 :         if (eret) {
    1152           0 :             free(s);
    1153           0 :             return eret;
    1154             :         }
    1155           0 :         tmp = realloc (s, len);
    1156           0 :         if (tmp == NULL) {
    1157           0 :             free (s);
    1158           0 :             return ENOMEM;
    1159             :         }
    1160           0 :         s = tmp;
    1161           0 :         if(c == '\n') {
    1162           0 :             s[len - 1] = '\0';
    1163           0 :             break;
    1164             :         }
    1165           0 :         s[len - 1] = c;
    1166             :     }
    1167           0 :     if(ret != 1){
    1168           0 :         free(s);
    1169           0 :         if(ret == 0)
    1170           0 :             return sp->eof_code;
    1171           0 :         return ret;
    1172             :     }
    1173           0 :     *string = s;
    1174           0 :     return 0;
    1175             : }
    1176             : 
    1177             : /**
    1178             :  * Write a principal block to storage.
    1179             :  *
    1180             :  * @param sp the storage buffer to write to
    1181             :  * @param p the principal block to write.
    1182             :  *
    1183             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1184             :  *
    1185             :  * @ingroup krb5_storage
    1186             :  */
    1187             : 
    1188             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1189        2812 : krb5_store_principal(krb5_storage *sp,
    1190             :                      krb5_const_principal p)
    1191             : {
    1192             :     size_t i;
    1193             :     int ret;
    1194             : 
    1195        2812 :     if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) {
    1196        2812 :         ret = krb5_store_int32(sp, p->name.name_type);
    1197        2812 :         if(ret) return ret;
    1198             :     }
    1199        2812 :     if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
    1200           0 :         ret = krb5_store_int32(sp, p->name.name_string.len + 1);
    1201             :     else
    1202        2812 :         ret = krb5_store_int32(sp, p->name.name_string.len);
    1203             : 
    1204        2812 :     if(ret) return ret;
    1205        2812 :     ret = krb5_store_string(sp, p->realm);
    1206        2812 :     if(ret) return ret;
    1207        7041 :     for(i = 0; i < p->name.name_string.len; i++){
    1208        4229 :         ret = krb5_store_string(sp, p->name.name_string.val[i]);
    1209        4229 :         if(ret) return ret;
    1210             :     }
    1211        2812 :     return 0;
    1212             : }
    1213             : 
    1214             : /**
    1215             :  * Parse principal from the storage.
    1216             :  *
    1217             :  * @param sp the storage buffer to read from
    1218             :  * @param princ the parsed principal
    1219             :  *
    1220             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1221             :  *
    1222             :  * @ingroup krb5_storage
    1223             :  */
    1224             : 
    1225             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1226       62414 : krb5_ret_principal(krb5_storage *sp,
    1227             :                    krb5_principal *princ)
    1228             : {
    1229             :     int i;
    1230             :     int ret;
    1231             :     krb5_principal p;
    1232             :     int32_t type;
    1233             :     int32_t ncomp;
    1234             : 
    1235       62414 :     p = calloc(1, sizeof(*p));
    1236       62414 :     if(p == NULL)
    1237           0 :         return ENOMEM;
    1238             : 
    1239       62414 :     if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE))
    1240           0 :         type = KRB5_NT_UNKNOWN;
    1241       62414 :     else if((ret = krb5_ret_int32(sp, &type))){
    1242        1120 :         free(p);
    1243        1120 :         return ret;
    1244             :     }
    1245       61294 :     if((ret = krb5_ret_int32(sp, &ncomp))){
    1246           0 :         free(p);
    1247           0 :         return ret;
    1248             :     }
    1249       61294 :     if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
    1250           0 :         ncomp--;
    1251       61294 :     if (ncomp < 0) {
    1252           0 :         free(p);
    1253           0 :         return EINVAL;
    1254             :     }
    1255       61294 :     ret = size_too_large_num(sp, ncomp, sizeof(p->name.name_string.val[0]));
    1256       61294 :     if (ret) {
    1257           0 :         free(p);
    1258           0 :         return ret;
    1259             :     }
    1260       61294 :     p->name.name_type = type;
    1261       61294 :     p->name.name_string.len = ncomp;
    1262       61294 :     ret = krb5_ret_string(sp, &p->realm);
    1263       61294 :     if(ret) {
    1264           0 :         free(p);
    1265           0 :         return ret;
    1266             :     }
    1267       61294 :     p->name.name_string.val = calloc(ncomp, sizeof(p->name.name_string.val[0]));
    1268       61294 :     if(p->name.name_string.val == NULL && ncomp != 0){
    1269           0 :         free(p->realm);
    1270           0 :         free(p);
    1271           0 :         return ENOMEM;
    1272             :     }
    1273      151564 :     for(i = 0; i < ncomp; i++){
    1274       90270 :         ret = krb5_ret_string(sp, &p->name.name_string.val[i]);
    1275       90270 :         if(ret) {
    1276           0 :             while (i >= 0)
    1277           0 :                 free(p->name.name_string.val[i--]);
    1278           0 :             free(p->realm);
    1279           0 :             free(p);
    1280           0 :             return ret;
    1281             :         }
    1282             :     }
    1283       61294 :     *princ = p;
    1284       61294 :     return 0;
    1285             : }
    1286             : 
    1287             : /**
    1288             :  * Store a keyblock to the storage.
    1289             :  *
    1290             :  * @param sp the storage buffer to write to
    1291             :  * @param p the keyblock to write
    1292             :  *
    1293             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1294             :  *
    1295             :  * @ingroup krb5_storage
    1296             :  */
    1297             : 
    1298             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1299       65946 : krb5_store_keyblock(krb5_storage *sp, krb5_keyblock p)
    1300             : {
    1301             :     int ret;
    1302       65946 :     ret = krb5_store_int16(sp, p.keytype);
    1303       65946 :     if(ret) return ret;
    1304             : 
    1305       65946 :     if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
    1306             :         /* this should really be enctype, but it is the same as
    1307             :            keytype nowadays */
    1308           0 :     ret = krb5_store_int16(sp, p.keytype);
    1309           0 :     if(ret) return ret;
    1310             :     }
    1311             : 
    1312       65946 :     ret = krb5_store_data(sp, p.keyvalue);
    1313       65946 :     return ret;
    1314             : }
    1315             : 
    1316             : /**
    1317             :  * Read a keyblock from the storage.
    1318             :  *
    1319             :  * @param sp the storage buffer to write to
    1320             :  * @param p the keyblock read from storage, free using krb5_free_keyblock()
    1321             :  *
    1322             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1323             :  *
    1324             :  * @ingroup krb5_storage
    1325             :  */
    1326             : 
    1327             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1328       93122 : krb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p)
    1329             : {
    1330             :     int ret;
    1331             :     int16_t tmp;
    1332             : 
    1333       93122 :     ret = krb5_ret_int16(sp, &tmp);
    1334       93122 :     if(ret) return ret;
    1335       93122 :     p->keytype = tmp;
    1336             : 
    1337       93122 :     if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
    1338           0 :     ret = krb5_ret_int16(sp, &tmp);
    1339           0 :     if(ret) return ret;
    1340             :     }
    1341             : 
    1342       93122 :     ret = krb5_ret_data(sp, &p->keyvalue);
    1343       93122 :     return ret;
    1344             : }
    1345             : 
    1346             : /**
    1347             :  * Write a times block to storage.
    1348             :  *
    1349             :  * @param sp the storage buffer to write to
    1350             :  * @param times the times block to write.
    1351             :  *
    1352             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1353             :  *
    1354             :  * @ingroup krb5_storage
    1355             :  */
    1356             : 
    1357             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1358        1344 : krb5_store_times(krb5_storage *sp, krb5_times times)
    1359             : {
    1360             :     int ret;
    1361        1344 :     ret = krb5_store_int32(sp, times.authtime);
    1362        1344 :     if(ret) return ret;
    1363        1344 :     ret = krb5_store_int32(sp, times.starttime);
    1364        1344 :     if(ret) return ret;
    1365        1344 :     ret = krb5_store_int32(sp, times.endtime);
    1366        1344 :     if(ret) return ret;
    1367        1344 :     ret = krb5_store_int32(sp, times.renew_till);
    1368        1344 :     return ret;
    1369             : }
    1370             : 
    1371             : /**
    1372             :  * Read a times block from the storage.
    1373             :  *
    1374             :  * @param sp the storage buffer to write to
    1375             :  * @param times the times block read from storage
    1376             :  *
    1377             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1378             :  *
    1379             :  * @ingroup krb5_storage
    1380             :  */
    1381             : 
    1382             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1383       28520 : krb5_ret_times(krb5_storage *sp, krb5_times *times)
    1384             : {
    1385             :     int ret;
    1386             :     int32_t tmp;
    1387             : 
    1388       28520 :     ret = krb5_ret_int32(sp, &tmp);
    1389       28520 :     if (ret) return ret;
    1390       28520 :     times->authtime = tmp;
    1391       28520 :     ret = krb5_ret_int32(sp, &tmp);
    1392       28520 :     if (ret) return ret;
    1393       28520 :     times->starttime = tmp;
    1394       28520 :     ret = krb5_ret_int32(sp, &tmp);
    1395       28520 :     if (ret) return ret;
    1396       28520 :     times->endtime = tmp;
    1397       28520 :     ret = krb5_ret_int32(sp, &tmp);
    1398       28520 :     if (ret) return ret;
    1399       28520 :     times->renew_till = tmp;
    1400       28520 :     return ret;
    1401             : }
    1402             : 
    1403             : /**
    1404             :  * Write a address block to storage.
    1405             :  *
    1406             :  * @param sp the storage buffer to write to
    1407             :  * @param p the address block to write.
    1408             :  *
    1409             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1410             :  *
    1411             :  * @ingroup krb5_storage
    1412             :  */
    1413             : 
    1414             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1415           0 : krb5_store_address(krb5_storage *sp, krb5_address p)
    1416             : {
    1417             :     int ret;
    1418           0 :     ret = krb5_store_int16(sp, p.addr_type);
    1419           0 :     if(ret) return ret;
    1420           0 :     ret = krb5_store_data(sp, p.address);
    1421           0 :     return ret;
    1422             : }
    1423             : 
    1424             : /**
    1425             :  * Read a address block from the storage.
    1426             :  *
    1427             :  * @param sp the storage buffer to write to
    1428             :  * @param adr the address block read from storage
    1429             :  *
    1430             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1431             :  *
    1432             :  * @ingroup krb5_storage
    1433             :  */
    1434             : 
    1435             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1436           0 : krb5_ret_address(krb5_storage *sp, krb5_address *adr)
    1437             : {
    1438             :     int16_t t;
    1439             :     int ret;
    1440           0 :     ret = krb5_ret_int16(sp, &t);
    1441           0 :     if(ret) return ret;
    1442           0 :     adr->addr_type = t;
    1443           0 :     ret = krb5_ret_data(sp, &adr->address);
    1444           0 :     return ret;
    1445             : }
    1446             : 
    1447             : /**
    1448             :  * Write a addresses block to storage.
    1449             :  *
    1450             :  * @param sp the storage buffer to write to
    1451             :  * @param p the addresses block to write.
    1452             :  *
    1453             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1454             :  *
    1455             :  * @ingroup krb5_storage
    1456             :  */
    1457             : 
    1458             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1459        1344 : krb5_store_addrs(krb5_storage *sp, krb5_addresses p)
    1460             : {
    1461             :     size_t i;
    1462             :     int ret;
    1463        1344 :     ret = krb5_store_int32(sp, p.len);
    1464        1344 :     if(ret) return ret;
    1465        1344 :     for(i = 0; i<p.len; i++){
    1466           0 :         ret = krb5_store_address(sp, p.val[i]);
    1467           0 :         if(ret) break;
    1468             :     }
    1469        1344 :     return ret;
    1470             : }
    1471             : 
    1472             : /**
    1473             :  * Read a addresses block from the storage.
    1474             :  *
    1475             :  * @param sp the storage buffer to write to
    1476             :  * @param adr the addresses block read from storage
    1477             :  *
    1478             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1479             :  *
    1480             :  * @ingroup krb5_storage
    1481             :  */
    1482             : 
    1483             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1484       28520 : krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr)
    1485             : {
    1486             :     size_t i;
    1487             :     int ret;
    1488             :     int32_t tmp;
    1489             : 
    1490       28520 :     ret = krb5_ret_int32(sp, &tmp);
    1491       28520 :     if(ret) return ret;
    1492       28520 :     ret = size_too_large_num(sp, tmp, sizeof(adr->val[0]));
    1493       28520 :     if (ret) return ret;
    1494       28520 :     adr->len = tmp;
    1495       28520 :     ALLOC(adr->val, adr->len);
    1496       28520 :     if (adr->val == NULL && adr->len != 0)
    1497           0 :         return ENOMEM;
    1498       28520 :     for(i = 0; i < adr->len; i++){
    1499           0 :         ret = krb5_ret_address(sp, &adr->val[i]);
    1500           0 :         if(ret) break;
    1501             :     }
    1502       28520 :     return ret;
    1503             : }
    1504             : 
    1505             : /**
    1506             :  * Write a auth data block to storage.
    1507             :  *
    1508             :  * @param sp the storage buffer to write to
    1509             :  * @param auth the auth data block to write.
    1510             :  *
    1511             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1512             :  *
    1513             :  * @ingroup krb5_storage
    1514             :  */
    1515             : 
    1516             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1517        1344 : krb5_store_authdata(krb5_storage *sp, krb5_authdata auth)
    1518             : {
    1519             :     krb5_error_code ret;
    1520             :     size_t i;
    1521        1344 :     ret = krb5_store_int32(sp, auth.len);
    1522        1344 :     if(ret) return ret;
    1523        1344 :     for(i = 0; i < auth.len; i++){
    1524           0 :         ret = krb5_store_int16(sp, auth.val[i].ad_type);
    1525           0 :         if(ret) break;
    1526           0 :         ret = krb5_store_data(sp, auth.val[i].ad_data);
    1527           0 :         if(ret) break;
    1528             :     }
    1529        1344 :     return 0;
    1530             : }
    1531             : 
    1532             : /**
    1533             :  * Read a auth data from the storage.
    1534             :  *
    1535             :  * @param sp the storage buffer to write to
    1536             :  * @param auth the auth data block read from storage
    1537             :  *
    1538             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1539             :  *
    1540             :  * @ingroup krb5_storage
    1541             :  */
    1542             : 
    1543             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1544       28520 : krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth)
    1545             : {
    1546             :     krb5_error_code ret;
    1547             :     int32_t tmp;
    1548             :     int16_t tmp2;
    1549             :     int i;
    1550       28520 :     ret = krb5_ret_int32(sp, &tmp);
    1551       28520 :     if(ret) return ret;
    1552       28520 :     ret = size_too_large_num(sp, tmp, sizeof(auth->val[0]));
    1553       28520 :     if (ret) return ret;
    1554       28520 :     ALLOC_SEQ(auth, tmp);
    1555       28520 :     if (auth->val == NULL && tmp != 0)
    1556           0 :         return ENOMEM;
    1557       28520 :     for(i = 0; i < tmp; i++){
    1558           0 :         ret = krb5_ret_int16(sp, &tmp2);
    1559           0 :         if(ret) break;
    1560           0 :         auth->val[i].ad_type = tmp2;
    1561           0 :         ret = krb5_ret_data(sp, &auth->val[i].ad_data);
    1562           0 :         if(ret) break;
    1563             :     }
    1564       28520 :     return ret;
    1565             : }
    1566             : 
    1567             : static int32_t
    1568       29864 : bitswap32(int32_t b)
    1569             : {
    1570       29864 :     int32_t r = 0;
    1571             :     int i;
    1572      985512 :     for (i = 0; i < 32; i++) {
    1573      955648 :         r = r << 1 | (b & 1);
    1574      955648 :         b = b >> 1;
    1575             :     }
    1576       29864 :     return r;
    1577             : }
    1578             : 
    1579             : /**
    1580             :  * Write a credentials block to storage.
    1581             :  *
    1582             :  * @param sp the storage buffer to write to
    1583             :  * @param creds the creds block to write.
    1584             :  *
    1585             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1586             :  *
    1587             :  * @ingroup krb5_storage
    1588             :  */
    1589             : 
    1590             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1591        1344 : krb5_store_creds(krb5_storage *sp, krb5_creds *creds)
    1592             : {
    1593             :     int ret;
    1594             : 
    1595        1344 :     ret = krb5_store_principal(sp, creds->client);
    1596        1344 :     if(ret)
    1597           0 :         return ret;
    1598        1344 :     ret = krb5_store_principal(sp, creds->server);
    1599        1344 :     if(ret)
    1600           0 :         return ret;
    1601        1344 :     ret = krb5_store_keyblock(sp, creds->session);
    1602        1344 :     if(ret)
    1603           0 :         return ret;
    1604        1344 :     ret = krb5_store_times(sp, creds->times);
    1605        1344 :     if(ret)
    1606           0 :         return ret;
    1607        1344 :     ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
    1608        1344 :     if(ret)
    1609           0 :         return ret;
    1610        1344 :     ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
    1611        1344 :     if(ret)
    1612           0 :         return ret;
    1613        1344 :     ret = krb5_store_addrs(sp, creds->addresses);
    1614        1344 :     if(ret)
    1615           0 :         return ret;
    1616        1344 :     ret = krb5_store_authdata(sp, creds->authdata);
    1617        1344 :     if(ret)
    1618           0 :         return ret;
    1619        1344 :     ret = krb5_store_data(sp, creds->ticket);
    1620        1344 :     if(ret)
    1621           0 :         return ret;
    1622        1344 :     ret = krb5_store_data(sp, creds->second_ticket);
    1623        1344 :     return ret;
    1624             : }
    1625             : 
    1626             : /**
    1627             :  * Read a credentials block from the storage.
    1628             :  *
    1629             :  * @param sp the storage buffer to write to
    1630             :  * @param creds the credentials block read from storage
    1631             :  *
    1632             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1633             :  *
    1634             :  * @ingroup krb5_storage
    1635             :  */
    1636             : 
    1637             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1638       29640 : krb5_ret_creds(krb5_storage *sp, krb5_creds *creds)
    1639             : {
    1640             :     krb5_error_code ret;
    1641             :     int8_t dummy8;
    1642             :     int32_t dummy32;
    1643             : 
    1644       29640 :     memset(creds, 0, sizeof(*creds));
    1645       29640 :     ret = krb5_ret_principal (sp,  &creds->client);
    1646       29640 :     if(ret) goto cleanup;
    1647       28520 :     ret = krb5_ret_principal (sp,  &creds->server);
    1648       28520 :     if(ret) goto cleanup;
    1649       28520 :     ret = krb5_ret_keyblock (sp,  &creds->session);
    1650       28520 :     if(ret) goto cleanup;
    1651       28520 :     ret = krb5_ret_times (sp,  &creds->times);
    1652       28520 :     if(ret) goto cleanup;
    1653       28520 :     ret = krb5_ret_int8 (sp,  &dummy8);
    1654       28520 :     if(ret) goto cleanup;
    1655       28520 :     ret = krb5_ret_int32 (sp,  &dummy32);
    1656       28520 :     if(ret) goto cleanup;
    1657       28520 :     creds->flags.b = int2TicketFlags(bitswap32(dummy32));
    1658       28520 :     ret = krb5_ret_addrs (sp,  &creds->addresses);
    1659       28520 :     if(ret) goto cleanup;
    1660       28520 :     ret = krb5_ret_authdata (sp,  &creds->authdata);
    1661       28520 :     if(ret) goto cleanup;
    1662       28520 :     ret = krb5_ret_data (sp,  &creds->ticket);
    1663       28520 :     if(ret) goto cleanup;
    1664       28520 :     ret = krb5_ret_data (sp,  &creds->second_ticket);
    1665       29640 : cleanup:
    1666             :     if(ret) {
    1667             : #if 0
    1668             :         krb5_free_cred_contents(context, creds); /* XXX */
    1669             : #endif
    1670             :     }
    1671       29640 :     return ret;
    1672             : }
    1673             : 
    1674             : #define SC_CLIENT_PRINCIPAL         0x0001
    1675             : #define SC_SERVER_PRINCIPAL         0x0002
    1676             : #define SC_SESSION_KEY              0x0004
    1677             : #define SC_TICKET                   0x0008
    1678             : #define SC_SECOND_TICKET            0x0010
    1679             : #define SC_AUTHDATA                 0x0020
    1680             : #define SC_ADDRESSES                0x0040
    1681             : 
    1682             : /**
    1683             :  * Write a tagged credentials block to storage.
    1684             :  *
    1685             :  * @param sp the storage buffer to write to
    1686             :  * @param creds the creds block to write.
    1687             :  *
    1688             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1689             :  *
    1690             :  * @ingroup krb5_storage
    1691             :  */
    1692             : 
    1693             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1694           0 : krb5_store_creds_tag(krb5_storage *sp, krb5_creds *creds)
    1695             : {
    1696             :     int ret;
    1697           0 :     int32_t header = 0;
    1698             : 
    1699           0 :     if (creds->client)
    1700           0 :         header |= SC_CLIENT_PRINCIPAL;
    1701           0 :     if (creds->server)
    1702           0 :         header |= SC_SERVER_PRINCIPAL;
    1703           0 :     if (creds->session.keytype != ETYPE_NULL)
    1704           0 :         header |= SC_SESSION_KEY;
    1705           0 :     if (creds->ticket.data)
    1706           0 :         header |= SC_TICKET;
    1707           0 :     if (creds->second_ticket.length)
    1708           0 :         header |= SC_SECOND_TICKET;
    1709           0 :     if (creds->authdata.len)
    1710           0 :         header |= SC_AUTHDATA;
    1711           0 :     if (creds->addresses.len)
    1712           0 :         header |= SC_ADDRESSES;
    1713             : 
    1714           0 :     ret = krb5_store_int32(sp, header);
    1715           0 :     if (ret)
    1716           0 :         return ret;
    1717             : 
    1718           0 :     if (creds->client) {
    1719           0 :         ret = krb5_store_principal(sp, creds->client);
    1720           0 :         if(ret)
    1721           0 :             return ret;
    1722             :     }
    1723             : 
    1724           0 :     if (creds->server) {
    1725           0 :         ret = krb5_store_principal(sp, creds->server);
    1726           0 :         if(ret)
    1727           0 :             return ret;
    1728             :     }
    1729             : 
    1730           0 :     if (creds->session.keytype != ETYPE_NULL) {
    1731           0 :         ret = krb5_store_keyblock(sp, creds->session);
    1732           0 :         if(ret)
    1733           0 :             return ret;
    1734             :     }
    1735             : 
    1736           0 :     ret = krb5_store_times(sp, creds->times);
    1737           0 :     if(ret)
    1738           0 :         return ret;
    1739           0 :     ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
    1740           0 :     if(ret)
    1741           0 :         return ret;
    1742             : 
    1743           0 :     ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
    1744           0 :     if(ret)
    1745           0 :         return ret;
    1746             : 
    1747           0 :     if (creds->addresses.len) {
    1748           0 :         ret = krb5_store_addrs(sp, creds->addresses);
    1749           0 :         if(ret)
    1750           0 :             return ret;
    1751             :     }
    1752             : 
    1753           0 :     if (creds->authdata.len) {
    1754           0 :         ret = krb5_store_authdata(sp, creds->authdata);
    1755           0 :         if(ret)
    1756           0 :             return ret;
    1757             :     }
    1758             : 
    1759           0 :     if (creds->ticket.data) {
    1760           0 :         ret = krb5_store_data(sp, creds->ticket);
    1761           0 :         if(ret)
    1762           0 :             return ret;
    1763             :     }
    1764             : 
    1765           0 :     if (creds->second_ticket.data) {
    1766           0 :         ret = krb5_store_data(sp, creds->second_ticket);
    1767           0 :         if (ret)
    1768           0 :             return ret;
    1769             :     }
    1770             : 
    1771           0 :     return ret;
    1772             : }
    1773             : 
    1774             : /**
    1775             :  * Read a tagged credentials block from the storage.
    1776             :  *
    1777             :  * @param sp the storage buffer to write to
    1778             :  * @param creds the credentials block read from storage
    1779             :  *
    1780             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1781             :  *
    1782             :  * @ingroup krb5_storage
    1783             :  */
    1784             : 
    1785             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1786           0 : krb5_ret_creds_tag(krb5_storage *sp,
    1787             :                    krb5_creds *creds)
    1788             : {
    1789             :     krb5_error_code ret;
    1790             :     int8_t dummy8;
    1791             :     int32_t dummy32, header;
    1792             : 
    1793           0 :     memset(creds, 0, sizeof(*creds));
    1794             : 
    1795           0 :     ret = krb5_ret_int32 (sp, &header);
    1796           0 :     if (ret) goto cleanup;
    1797             : 
    1798           0 :     if (header & SC_CLIENT_PRINCIPAL) {
    1799           0 :         ret = krb5_ret_principal (sp,  &creds->client);
    1800           0 :         if(ret) goto cleanup;
    1801             :     }
    1802           0 :     if (header & SC_SERVER_PRINCIPAL) {
    1803           0 :         ret = krb5_ret_principal (sp,  &creds->server);
    1804           0 :         if(ret) goto cleanup;
    1805             :     }
    1806           0 :     if (header & SC_SESSION_KEY) {
    1807           0 :         ret = krb5_ret_keyblock (sp,  &creds->session);
    1808           0 :         if(ret) goto cleanup;
    1809             :     }
    1810           0 :     ret = krb5_ret_times (sp,  &creds->times);
    1811           0 :     if(ret) goto cleanup;
    1812           0 :     ret = krb5_ret_int8 (sp,  &dummy8);
    1813           0 :     if(ret) goto cleanup;
    1814           0 :     ret = krb5_ret_int32 (sp,  &dummy32);
    1815           0 :     if(ret) goto cleanup;
    1816           0 :     creds->flags.b = int2TicketFlags(bitswap32(dummy32));
    1817           0 :     if (header & SC_ADDRESSES) {
    1818           0 :         ret = krb5_ret_addrs (sp,  &creds->addresses);
    1819           0 :         if(ret) goto cleanup;
    1820             :     }
    1821           0 :     if (header & SC_AUTHDATA) {
    1822           0 :         ret = krb5_ret_authdata (sp,  &creds->authdata);
    1823           0 :         if(ret) goto cleanup;
    1824             :     }
    1825           0 :     if (header & SC_TICKET) {
    1826           0 :         ret = krb5_ret_data (sp,  &creds->ticket);
    1827           0 :         if(ret) goto cleanup;
    1828             :     }
    1829           0 :     if (header & SC_SECOND_TICKET) {
    1830           0 :         ret = krb5_ret_data (sp,  &creds->second_ticket);
    1831           0 :         if(ret) goto cleanup;
    1832             :     }
    1833             : 
    1834           0 : cleanup:
    1835             :     if(ret) {
    1836             : #if 0
    1837             :         krb5_free_cred_contents(context, creds); /* XXX */
    1838             : #endif
    1839             :     }
    1840           0 :     return ret;
    1841             : }
    1842             : 
    1843             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1844      328176 : _krb5_ret_data_at_offset(krb5_storage *sp,
    1845             :                          size_t offset,
    1846             :                          size_t length,
    1847             :                          krb5_data *data)
    1848             : {
    1849             :     krb5_error_code ret;
    1850             :     off_t cur, size;
    1851             : 
    1852      328176 :     krb5_data_zero(data);
    1853             : 
    1854      328176 :     cur = sp->seek(sp, 0, SEEK_CUR);
    1855      328176 :     if (cur < 0)
    1856           0 :         return HEIM_ERR_NOT_SEEKABLE;
    1857             : 
    1858      328176 :     size = sp->seek(sp, 0, SEEK_END);
    1859      328176 :     if (offset + length > size) {
    1860           0 :         ret = ERANGE;
    1861           0 :         goto cleanup;
    1862             :     }
    1863             : 
    1864      328176 :     ret = krb5_data_alloc(data, length);
    1865      328176 :     if (ret)
    1866           0 :         goto cleanup;
    1867             : 
    1868      328176 :     if (length) {
    1869      328176 :         sp->seek(sp, offset, SEEK_SET);
    1870             : 
    1871      328176 :         size = sp->fetch(sp, data->data, length);
    1872      328176 :         heim_assert(size == length, "incomplete buffer fetched");
    1873             :     }
    1874             : 
    1875      328176 : cleanup:
    1876      328176 :     sp->seek(sp, cur, SEEK_SET);
    1877             : 
    1878      328176 :     return ret;
    1879             : }
    1880             : 
    1881             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1882      246132 : _krb5_ret_utf8_from_ucs2le_at_offset(krb5_storage *sp,
    1883             :                                      off_t offset,
    1884             :                                      size_t length,
    1885             :                                      char **utf8)
    1886             : {
    1887             :     krb5_error_code ret;
    1888             :     krb5_data data;
    1889      246132 :     size_t ucs2len = length / 2;
    1890      246132 :     uint16_t *ucs2 = NULL;
    1891             :     size_t u8len;
    1892      246132 :     unsigned int flags = WIND_RW_LE;
    1893             : 
    1894      246132 :     *utf8 = NULL;
    1895             : 
    1896      246132 :     krb5_data_zero(&data);
    1897             : 
    1898      246132 :     ret = _krb5_ret_data_at_offset(sp, offset, length, &data);
    1899      246132 :     if (ret)
    1900           0 :         goto out;
    1901             : 
    1902      246132 :     ucs2 = malloc(sizeof(ucs2[0]) * ucs2len);
    1903      246132 :     if (ucs2 == NULL) {
    1904           0 :         ret = ENOMEM;
    1905           0 :         goto out;
    1906             :     }
    1907             : 
    1908      246132 :     ret = wind_ucs2read(data.data, data.length, &flags, ucs2, &ucs2len);
    1909      246132 :     if (ret)
    1910           0 :         goto out;
    1911             : 
    1912      246132 :     ret = wind_ucs2utf8_length(ucs2, ucs2len, &u8len);
    1913      246132 :     if (ret)
    1914           0 :         goto out;
    1915             : 
    1916      246132 :     u8len += 1; /* Add space for NUL */
    1917             : 
    1918      246132 :     *utf8 = malloc(u8len);
    1919      246132 :     if (*utf8 == NULL) {
    1920           0 :         ret = ENOMEM;
    1921           0 :         goto out;
    1922             :     }
    1923             : 
    1924      246132 :     ret = wind_ucs2utf8(ucs2, ucs2len, *utf8, &u8len);
    1925      246132 :     if (ret)
    1926           0 :         goto out;
    1927             : 
    1928      246132 : out:
    1929      246132 :     if (ret && *utf8) {
    1930           0 :         free(*utf8);
    1931           0 :         *utf8 = NULL;
    1932             :     }
    1933      246132 :     free(ucs2);
    1934      246132 :     krb5_data_free(&data);
    1935             : 
    1936      246132 :     return ret;
    1937             : }
    1938             : 
    1939             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1940           0 : _krb5_store_data_at_offset(krb5_storage *sp,
    1941             :                            size_t offset,
    1942             :                            const krb5_data *data)
    1943             : {
    1944             :     krb5_error_code ret;
    1945             :     krb5_ssize_t nbytes;
    1946             :     off_t pos;
    1947             : 
    1948           0 :     if (offset == (off_t)-1) {
    1949           0 :         if (data == NULL || data->data == NULL) {
    1950           0 :             offset = 0;
    1951             :         } else {
    1952           0 :             pos = sp->seek(sp, 0, SEEK_CUR);
    1953           0 :             offset = sp->seek(sp, 0, SEEK_END);
    1954           0 :             sp->seek(sp, pos, SEEK_SET);
    1955             : 
    1956           0 :             if (offset == (off_t)-1)
    1957           0 :                 return HEIM_ERR_NOT_SEEKABLE;
    1958             :         }
    1959             :     }
    1960             : 
    1961           0 :     if (offset > 0xFFFF)
    1962           0 :         return ERANGE;
    1963           0 :     else if ((offset != 0) != (data && data->data))
    1964           0 :         return EINVAL;
    1965           0 :     else if (data && data->length > 0xFFFF)
    1966           0 :         return ERANGE;
    1967             : 
    1968           0 :     ret = krb5_store_uint16(sp, data ? (uint16_t)data->length : 0);
    1969           0 :     if (ret == 0)
    1970           0 :         ret = krb5_store_uint16(sp, (uint16_t)offset);
    1971           0 :     if (ret == 0 && offset) {
    1972           0 :         pos = sp->seek(sp, 0, SEEK_CUR);
    1973           0 :         sp->seek(sp, offset, SEEK_SET);
    1974           0 :         nbytes = krb5_storage_write(sp, data->data, data->length);
    1975           0 :         if ((size_t)nbytes != data->length)
    1976           0 :             ret = sp->eof_code;
    1977           0 :         sp->seek(sp, pos, SEEK_SET);
    1978             :     }
    1979             : 
    1980           0 :     return ret;
    1981             : }
    1982             : 
    1983             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1984           0 : _krb5_store_utf8_as_ucs2le_at_offset(krb5_storage *sp,
    1985             :                                      off_t offset,
    1986             :                                      const char *utf8)
    1987             : {
    1988             :     krb5_error_code ret;
    1989             :     size_t ucs2_len, ucs2le_size;
    1990             :     uint16_t *ucs2, *ucs2le;
    1991             :     unsigned int flags;
    1992             : 
    1993           0 :     if (utf8) {
    1994           0 :         ret = wind_utf8ucs2_length(utf8, &ucs2_len);
    1995           0 :         if (ret)
    1996           0 :             return ret;
    1997             : 
    1998           0 :         ucs2 = malloc(sizeof(ucs2[0]) * ucs2_len);
    1999           0 :         if (ucs2 == NULL)
    2000           0 :             return ENOMEM;
    2001             : 
    2002           0 :         ret = wind_utf8ucs2(utf8, ucs2, &ucs2_len);
    2003           0 :         if (ret) {
    2004           0 :             free(ucs2);
    2005           0 :             return ret;
    2006             :         }
    2007             : 
    2008           0 :         ucs2le_size = (ucs2_len + 1) * 2;
    2009           0 :         ucs2le = malloc(ucs2le_size);
    2010           0 :             if (ucs2le == NULL) {
    2011           0 :                 free(ucs2);
    2012           0 :                 return ENOMEM;
    2013             :         }
    2014             : 
    2015           0 :         flags = WIND_RW_LE;
    2016           0 :         ret = wind_ucs2write(ucs2, ucs2_len, &flags, ucs2le, &ucs2le_size);
    2017           0 :         free(ucs2);
    2018           0 :         if (ret) {
    2019           0 :             free(ucs2le);
    2020           0 :             return ret;
    2021             :         }
    2022             : 
    2023           0 :         ucs2le_size = ucs2_len * 2;
    2024             :     } else {
    2025           0 :         ucs2le = NULL;
    2026           0 :         ucs2le_size = 0;
    2027           0 :         offset = 0;
    2028           0 :         ret = 0;
    2029             :     }
    2030             : 
    2031             :     {
    2032             :         krb5_data data;
    2033             : 
    2034           0 :         data.data = ucs2le;
    2035           0 :         data.length = ucs2le_size;
    2036             : 
    2037           0 :         ret = _krb5_store_data_at_offset(sp, offset, &data);
    2038             :     }
    2039             : 
    2040           0 :     free(ucs2le);
    2041             : 
    2042           0 :     return ret;
    2043             : }

Generated by: LCOV version 1.14