LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/krb5 - store.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 357 780 45.8 %
Date: 2024-06-13 04:01:37 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      630022 : krb5_storage_set_flags(krb5_storage *sp, krb5_flags flags)
      55             : {
      56      630022 :     sp->flags |= flags;
      57      630022 : }
      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     9443193 : krb5_storage_is_flags(krb5_storage *sp, krb5_flags flags)
      88             : {
      89     9443193 :     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      871755 : size_too_large(krb5_storage *sp, size_t size)
     141             : {
     142      871755 :     if (sp->max_alloc && sp->max_alloc < size)
     143           0 :         return HEIM_ERR_TOO_BIG;
     144      871755 :     return 0;
     145             : }
     146             : 
     147             : static krb5_error_code
     148      125741 : size_too_large_num(krb5_storage *sp, size_t count, size_t size)
     149             : {
     150      125741 :     if (sp->max_alloc == 0 || size == 0)
     151           0 :         return 0;
     152      125741 :     size = sp->max_alloc / size;
     153      125741 :     if (size < count)
     154           0 :         return HEIM_ERR_TOO_BIG;
     155      125741 :     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      602201 : krb5_storage_seek(krb5_storage *sp, off_t offset, int whence)
     173             : {
     174      602201 :     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        1238 : krb5_storage_truncate(krb5_storage *sp, off_t offset)
     190             : {
     191        1238 :     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        1452 : krb5_storage_fsync(krb5_storage *sp)
     207             : {
     208        1452 :     if (sp->fsync != NULL)
     209        1452 :         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      752320 : krb5_storage_read(krb5_storage *sp, void *buf, size_t len)
     227             : {
     228      752320 :     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      747666 : krb5_storage_write(krb5_storage *sp, const void *buf, size_t len)
     245             : {
     246      747666 :     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       53635 : krb5_storage_set_eof_code(krb5_storage *sp, int code)
     260             : {
     261       53635 :     sp->eof_code = code;
     262       53635 : }
     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      973991 : krb5_storage_free(krb5_storage *sp)
     292             : {
     293      973991 :     if (sp == NULL)
     294           0 :         return 0;
     295      973991 :     if(sp->free)
     296      380946 :         (*sp->free)(sp);
     297      973991 :     free(sp->data);
     298      973991 :     free(sp);
     299      973991 :     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      327974 : krb5_storage_to_data(krb5_storage *sp, krb5_data *data)
     315             : {
     316             :     off_t pos, size;
     317             :     krb5_error_code ret;
     318             : 
     319      327974 :     pos = sp->seek(sp, 0, SEEK_CUR);
     320      327974 :     if (pos < 0)
     321           0 :         return HEIM_ERR_NOT_SEEKABLE;
     322      327974 :     size = sp->seek(sp, 0, SEEK_END);
     323      327974 :     ret = size_too_large(sp, size);
     324      327974 :     if (ret)
     325           0 :         return ret;
     326      327974 :     ret = krb5_data_alloc(data, size);
     327      327974 :     if (ret) {
     328           0 :         sp->seek(sp, pos, SEEK_SET);
     329           0 :         return ret;
     330             :     }
     331      327974 :     if (size) {
     332      327974 :         sp->seek(sp, 0, SEEK_SET);
     333      327974 :         sp->fetch(sp, data->data, data->length);
     334      327974 :         sp->seek(sp, pos, SEEK_SET);
     335             :     }
     336      327974 :     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     1975457 : krb5_store_int(krb5_storage *sp,
     405             :                int64_t value,
     406             :                size_t len)
     407             : {
     408             :     int ret;
     409     1975457 :     uint8_t v[9], *p = v;
     410             : 
     411     1975457 :     if (len > sizeof(value))
     412           0 :         return EINVAL;
     413             : 
     414     1975457 :     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     1975457 :         _krb5_put_int(v, value, len);
     422     1975457 :     ret = sp->store(sp, p, len);
     423     1975457 :     if (ret < 0)
     424           0 :         return errno;
     425     1975457 :     if ((size_t)ret != len)
     426           0 :         return sp->eof_code;
     427     1975457 :     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     1465421 : krb5_store_int32(krb5_storage *sp,
     444             :                  int32_t value)
     445             : {
     446     1465421 :     if(BYTEORDER_IS_HOST(sp))
     447           0 :         value = htonl(value);
     448     1465421 :     else if(BYTEORDER_IS_LE(sp))
     449     1107352 :         value = bswap32(value);
     450     1465421 :     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      376062 : krb5_store_int64(krb5_storage *sp,
     467             :                  int64_t value)
     468             : {
     469      376062 :     if (BYTEORDER_IS_HOST(sp))
     470             : #ifdef WORDS_BIGENDIAN
     471             :         ;
     472             : #else
     473           0 :         value = bswap64(value); /* There's no ntohll() */
     474             : #endif
     475      376062 :     else if (BYTEORDER_IS_LE(sp))
     476      376062 :         value = bswap64(value);
     477      376062 :     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     1108121 : krb5_store_uint32(krb5_storage *sp,
     494             :                   uint32_t value)
     495             : {
     496     1108121 :     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      376062 : krb5_store_uint64(krb5_storage *sp,
     513             :                   uint64_t value)
     514             : {
     515      376062 :     return krb5_store_int64(sp, (int64_t)value);
     516             : }
     517             : 
     518             : static krb5_error_code
     519     6870936 : krb5_ret_int(krb5_storage *sp,
     520             :              int64_t *value,
     521             :              size_t len)
     522             : {
     523             :     int ret;
     524             :     unsigned char v[9];
     525     6870936 :     uint64_t w = 0;
     526     6870936 :     *value = 0; /* quiets warnings */
     527     6870936 :     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     6870936 :     ret = sp->fetch(sp, v, len);
     547     6870936 :     if (ret < 0)
     548           0 :         return errno;
     549     6870936 :     if ((size_t)ret != len)
     550       26734 :         return sp->eof_code;
     551     6844202 :     _krb5_get_int64(v, &w, len);
     552     6844202 :     *value = w;
     553     6844202 :     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      888550 : krb5_ret_int64(krb5_storage *sp,
     570             :                int64_t *value)
     571             : {
     572      888550 :     krb5_error_code ret = krb5_ret_int(sp, value, 8);
     573      888550 :     if(ret)
     574           0 :         return ret;
     575      888550 :     if(BYTEORDER_IS_HOST(sp))
     576             : #ifdef WORDS_BIGENDIAN
     577             :         ;
     578             : #else
     579           0 :         *value = bswap64(*value); /* There's no ntohll() */
     580             : #endif
     581      888550 :     else if(BYTEORDER_IS_LE(sp))
     582      888550 :         *value = bswap64(*value);
     583      888550 :     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      888550 : krb5_ret_uint64(krb5_storage *sp,
     600             :                 uint64_t *value)
     601             : {
     602             :     krb5_error_code ret;
     603             :     int64_t v;
     604             : 
     605      888550 :     ret = krb5_ret_int64(sp, &v);
     606      888550 :     if (ret == 0)
     607      888550 :         *value = (uint64_t)v;
     608             : 
     609      888550 :     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     4234417 : krb5_ret_int32(krb5_storage *sp,
     626             :                int32_t *value)
     627             : {
     628             :     int64_t v;
     629             : 
     630     4234417 :     krb5_error_code ret = krb5_ret_int(sp, &v, 4);
     631     4234417 :     if (ret)
     632       26734 :         return ret;
     633     4207683 :     *value = v;
     634     4207683 :     if (BYTEORDER_IS_HOST(sp))
     635           0 :         *value = htonl(*value);
     636     4207683 :     else if (BYTEORDER_IS_LE(sp))
     637     2429973 :         *value = bswap32(*value);
     638     4207683 :     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     2775882 : krb5_ret_uint32(krb5_storage *sp, uint32_t *value)
     655             : {
     656             :     krb5_error_code ret;
     657             :     int32_t v;
     658             : 
     659     2775882 :     ret = krb5_ret_int32(sp, &v);
     660     2775882 :     if (ret == 0)
     661     2775882 :         *value = (uint32_t)v;
     662             : 
     663     2775882 :     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      133974 : krb5_store_int16(krb5_storage *sp,
     680             :                  int16_t value)
     681             : {
     682      133974 :     if(BYTEORDER_IS_HOST(sp))
     683           0 :         value = htons(value);
     684      133974 :     else if(BYTEORDER_IS_LE(sp))
     685       60076 :         value = bswap16(value);
     686      133974 :     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       60076 : krb5_store_uint16(krb5_storage *sp,
     703             :                   uint16_t value)
     704             : {
     705       60076 :     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     1747969 : krb5_ret_int16(krb5_storage *sp,
     722             :                int16_t *value)
     723             : {
     724             :     int64_t v;
     725             :     int ret;
     726     1747969 :     ret = krb5_ret_int(sp, &v, 2);
     727     1747969 :     if(ret)
     728           0 :         return ret;
     729     1747969 :     *value = v;
     730     1747969 :     if(BYTEORDER_IS_HOST(sp))
     731           0 :         *value = htons(*value);
     732     1747969 :     else if(BYTEORDER_IS_LE(sp))
     733      734840 :         *value = bswap16(*value);
     734     1747969 :     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      734840 : krb5_ret_uint16(krb5_storage *sp,
     751             :                 uint16_t *value)
     752             : {
     753             :     krb5_error_code ret;
     754             :     int16_t v;
     755             : 
     756      734840 :     ret = krb5_ret_int16(sp, &v);
     757      734840 :     if (ret == 0)
     758      734840 :         *value = (uint16_t)v;
     759             : 
     760      734840 :     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        3356 : krb5_store_int8(krb5_storage *sp,
     776             :                 int8_t value)
     777             : {
     778             :     int ret;
     779             : 
     780        3356 :     ret = sp->store(sp, &value, sizeof(value));
     781        3356 :     if (ret != sizeof(value))
     782           0 :         return (ret<0)?errno:sp->eof_code;
     783        3356 :     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      296743 : krb5_ret_int8(krb5_storage *sp,
     817             :               int8_t *value)
     818             : {
     819             :     int ret;
     820             : 
     821      296743 :     ret = sp->fetch(sp, value, sizeof(*value));
     822      296743 :     if (ret != sizeof(*value))
     823           0 :         return (ret<0)?errno:sp->eof_code;
     824      296743 :     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      284152 : krb5_store_data(krb5_storage *sp,
     866             :                 krb5_data data)
     867             : {
     868             :     int ret;
     869      284152 :     ret = krb5_store_int32(sp, data.length);
     870      284152 :     if(ret < 0)
     871           0 :         return ret;
     872      284152 :     ret = sp->store(sp, data.data, data.length);
     873      284152 :     if(ret < 0)
     874           0 :         return errno;
     875      284152 :     if((size_t)ret != data.length)
     876           0 :         return sp->eof_code;
     877      284152 :     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      567538 : krb5_ret_data(krb5_storage *sp,
     938             :               krb5_data *data)
     939             : {
     940             :     int ret;
     941             :     int32_t size;
     942             : 
     943      567538 :     ret = krb5_ret_int32(sp, &size);
     944      567538 :     if(ret)
     945       23757 :         return ret;
     946      543781 :     ret = size_too_large(sp, size);
     947      543781 :     if (ret)
     948           0 :         return ret;
     949      543781 :     ret = krb5_data_alloc (data, size);
     950      543781 :     if (ret)
     951           0 :         return ret;
     952      543781 :     if (size) {
     953      440697 :         ret = sp->fetch(sp, data->data, size);
     954      440697 :         if(ret != size) {
     955           0 :             krb5_data_free(data);
     956           0 :             return (ret < 0)? errno : sp->eof_code;
     957             :         }
     958             :     }
     959      543781 :     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      187340 : krb5_store_string(krb5_storage *sp, const char *s)
     976             : {
     977             :     krb5_data data;
     978             : 
     979      187340 :     if (s == NULL)
     980           0 :         return EINVAL;
     981             : 
     982      187340 :     data.length = strlen(s);
     983      187340 :     data.data = rk_UNCONST(s);
     984      187340 :     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      342124 : krb5_ret_string(krb5_storage *sp,
    1001             :                 char **string)
    1002             : {
    1003             :     int ret;
    1004             :     krb5_data data;
    1005      342124 :     ret = krb5_ret_data(sp, &data);
    1006      342124 :     if(ret)
    1007           0 :         return ret;
    1008      342124 :     *string = realloc(data.data, data.length + 1);
    1009      342124 :     if(*string == NULL){
    1010           0 :         free(data.data);
    1011           0 :         return ENOMEM;
    1012             :     }
    1013      342124 :     (*string)[data.length] = 0;
    1014      342124 :     return 0;
    1015             : }
    1016             : 
    1017             : /**
    1018             :  * Store a zero terminated string to the buffer. The data is stored
    1019             :  * one character at a time until a NUL is stored.
    1020             :  *
    1021             :  * @param sp the storage buffer to write to
    1022             :  * @param s the string to store.
    1023             :  *
    1024             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1025             :  *
    1026             :  * @ingroup krb5_storage
    1027             :  */
    1028             : 
    1029             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1030           0 : krb5_store_stringz(krb5_storage *sp, const char *s)
    1031             : {
    1032             :     size_t len;
    1033             :     ssize_t ret;
    1034             : 
    1035           0 :     if (s == NULL)
    1036           0 :         return EINVAL;
    1037             : 
    1038           0 :     len = strlen(s) + 1;
    1039           0 :     ret = sp->store(sp, s, len);
    1040           0 :     if(ret < 0)
    1041           0 :         return ret;
    1042           0 :     if((size_t)ret != len)
    1043           0 :         return sp->eof_code;
    1044           0 :     return 0;
    1045             : }
    1046             : 
    1047             : /**
    1048             :  * Parse zero terminated string from the storage.
    1049             :  *
    1050             :  * @param sp the storage buffer to read from
    1051             :  * @param string the parsed string
    1052             :  *
    1053             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1054             :  *
    1055             :  * @ingroup krb5_storage
    1056             :  */
    1057             : 
    1058             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1059           0 : krb5_ret_stringz(krb5_storage *sp,
    1060             :                 char **string)
    1061             : {
    1062             :     char c;
    1063           0 :     char *s = NULL;
    1064           0 :     size_t len = 0;
    1065             :     ssize_t ret;
    1066             : 
    1067           0 :     while((ret = sp->fetch(sp, &c, 1)) == 1){
    1068             :         krb5_error_code eret;
    1069             :         char *tmp;
    1070             : 
    1071           0 :         len++;
    1072           0 :         eret = size_too_large(sp, len);
    1073           0 :         if (eret) {
    1074           0 :             free(s);
    1075           0 :             return eret;
    1076             :         }
    1077           0 :         tmp = realloc (s, len);
    1078           0 :         if (tmp == NULL) {
    1079           0 :             free (s);
    1080           0 :             return ENOMEM;
    1081             :         }
    1082           0 :         s = tmp;
    1083           0 :         s[len - 1] = c;
    1084           0 :         if(c == 0)
    1085           0 :             break;
    1086             :     }
    1087           0 :     if(ret != 1){
    1088           0 :         free(s);
    1089           0 :         if(ret == 0)
    1090           0 :             return sp->eof_code;
    1091           0 :         return ret;
    1092             :     }
    1093           0 :     *string = s;
    1094           0 :     return 0;
    1095             : }
    1096             : 
    1097             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1098           0 : krb5_store_stringnl(krb5_storage *sp, const char *s)
    1099             : {
    1100             :     size_t len;
    1101             :     ssize_t ret;
    1102             : 
    1103           0 :     if (s == NULL)
    1104           0 :         return EINVAL;
    1105             : 
    1106           0 :     len = strlen(s);
    1107           0 :     ret = sp->store(sp, s, len);
    1108           0 :     if(ret < 0)
    1109           0 :         return ret;
    1110           0 :     if((size_t)ret != len)
    1111           0 :         return sp->eof_code;
    1112           0 :     ret = sp->store(sp, "\n", 1);
    1113           0 :     if(ret != 1) {
    1114           0 :         if(ret < 0)
    1115           0 :             return ret;
    1116             :         else
    1117           0 :             return sp->eof_code;
    1118             :     }
    1119             : 
    1120           0 :     return 0;
    1121             : 
    1122             : }
    1123             : 
    1124             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1125           0 : krb5_ret_stringnl(krb5_storage *sp,
    1126             :                   char **string)
    1127             : {
    1128           0 :     int expect_nl = 0;
    1129             :     char c;
    1130           0 :     char *s = NULL;
    1131           0 :     size_t len = 0;
    1132             :     ssize_t ret;
    1133             : 
    1134           0 :     while((ret = sp->fetch(sp, &c, 1)) == 1){
    1135             :         krb5_error_code eret;
    1136             :         char *tmp;
    1137             : 
    1138           0 :         if (c == '\r') {
    1139           0 :             expect_nl = 1;
    1140           0 :             continue;
    1141             :         }
    1142           0 :         if (expect_nl && c != '\n') {
    1143           0 :             free(s);
    1144           0 :             return KRB5_BADMSGTYPE;
    1145             :         }
    1146             : 
    1147           0 :         len++;
    1148           0 :         eret = size_too_large(sp, len);
    1149           0 :         if (eret) {
    1150           0 :             free(s);
    1151           0 :             return eret;
    1152             :         }
    1153           0 :         tmp = realloc (s, len);
    1154           0 :         if (tmp == NULL) {
    1155           0 :             free (s);
    1156           0 :             return ENOMEM;
    1157             :         }
    1158           0 :         s = tmp;
    1159           0 :         if(c == '\n') {
    1160           0 :             s[len - 1] = '\0';
    1161           0 :             break;
    1162             :         }
    1163           0 :         s[len - 1] = c;
    1164             :     }
    1165           0 :     if(ret != 1){
    1166           0 :         free(s);
    1167           0 :         if(ret == 0)
    1168           0 :             return sp->eof_code;
    1169           0 :         return ret;
    1170             :     }
    1171           0 :     *string = s;
    1172           0 :     return 0;
    1173             : }
    1174             : 
    1175             : /**
    1176             :  * Write a principal block to storage.
    1177             :  *
    1178             :  * @param sp the storage buffer to write to
    1179             :  * @param p the principal block to write.
    1180             :  *
    1181             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1182             :  *
    1183             :  * @ingroup krb5_storage
    1184             :  */
    1185             : 
    1186             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1187        2890 : krb5_store_principal(krb5_storage *sp,
    1188             :                      krb5_const_principal p)
    1189             : {
    1190             :     size_t i;
    1191             :     int ret;
    1192             : 
    1193        2890 :     if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) {
    1194        2890 :         ret = krb5_store_int32(sp, p->name.name_type);
    1195        2890 :         if(ret) return ret;
    1196             :     }
    1197        2890 :     if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
    1198           0 :         ret = krb5_store_int32(sp, p->name.name_string.len + 1);
    1199             :     else
    1200        2890 :         ret = krb5_store_int32(sp, p->name.name_string.len);
    1201             : 
    1202        2890 :     if(ret) return ret;
    1203        2890 :     ret = krb5_store_string(sp, p->realm);
    1204        2890 :     if(ret) return ret;
    1205        7229 :     for(i = 0; i < p->name.name_string.len; i++){
    1206        4339 :         ret = krb5_store_string(sp, p->name.name_string.val[i]);
    1207        4339 :         if(ret) return ret;
    1208             :     }
    1209        2890 :     return 0;
    1210             : }
    1211             : 
    1212             : /**
    1213             :  * Parse principal from the storage.
    1214             :  *
    1215             :  * @param sp the storage buffer to read from
    1216             :  * @param princ the parsed principal
    1217             :  *
    1218             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1219             :  *
    1220             :  * @ingroup krb5_storage
    1221             :  */
    1222             : 
    1223             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1224       67120 : krb5_ret_principal(krb5_storage *sp,
    1225             :                    krb5_principal *princ)
    1226             : {
    1227             :     int i;
    1228             :     int ret;
    1229             :     krb5_principal p;
    1230             :     int32_t type;
    1231             :     int32_t ncomp;
    1232             : 
    1233       67120 :     p = calloc(1, sizeof(*p));
    1234       67120 :     if(p == NULL)
    1235           0 :         return ENOMEM;
    1236             : 
    1237       67120 :     if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE))
    1238           0 :         type = KRB5_NT_UNKNOWN;
    1239       67120 :     else if((ret = krb5_ret_int32(sp, &type))){
    1240        1329 :         free(p);
    1241        1329 :         return ret;
    1242             :     }
    1243       65791 :     if((ret = krb5_ret_int32(sp, &ncomp))){
    1244           0 :         free(p);
    1245           0 :         return ret;
    1246             :     }
    1247       65791 :     if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
    1248           0 :         ncomp--;
    1249       65791 :     if (ncomp < 0) {
    1250           0 :         free(p);
    1251           0 :         return EINVAL;
    1252             :     }
    1253       65791 :     ret = size_too_large_num(sp, ncomp, sizeof(p->name.name_string.val[0]));
    1254       65791 :     if (ret) {
    1255           0 :         free(p);
    1256           0 :         return ret;
    1257             :     }
    1258       65791 :     p->name.name_type = type;
    1259       65791 :     p->name.name_string.len = ncomp;
    1260       65791 :     ret = krb5_ret_string(sp, &p->realm);
    1261       65791 :     if(ret) {
    1262           0 :         free(p);
    1263           0 :         return ret;
    1264             :     }
    1265       65791 :     p->name.name_string.val = calloc(ncomp, sizeof(p->name.name_string.val[0]));
    1266       65791 :     if(p->name.name_string.val == NULL && ncomp != 0){
    1267           0 :         free(p->realm);
    1268           0 :         free(p);
    1269           0 :         return ENOMEM;
    1270             :     }
    1271      162013 :     for(i = 0; i < ncomp; i++){
    1272       96222 :         ret = krb5_ret_string(sp, &p->name.name_string.val[i]);
    1273       96222 :         if(ret) {
    1274           0 :             while (i >= 0)
    1275           0 :                 free(p->name.name_string.val[i--]);
    1276           0 :             free(p->realm);
    1277           0 :             free(p);
    1278           0 :             return ret;
    1279             :         }
    1280             :     }
    1281       65791 :     *princ = p;
    1282       65791 :     return 0;
    1283             : }
    1284             : 
    1285             : /**
    1286             :  * Store a keyblock to the storage.
    1287             :  *
    1288             :  * @param sp the storage buffer to write to
    1289             :  * @param p the keyblock to write
    1290             :  *
    1291             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1292             :  *
    1293             :  * @ingroup krb5_storage
    1294             :  */
    1295             : 
    1296             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1297       65594 : krb5_store_keyblock(krb5_storage *sp, krb5_keyblock p)
    1298             : {
    1299             :     int ret;
    1300       65594 :     ret = krb5_store_int16(sp, p.keytype);
    1301       65594 :     if(ret) return ret;
    1302             : 
    1303       65594 :     if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
    1304             :         /* this should really be enctype, but it is the same as
    1305             :            keytype nowadays */
    1306           0 :     ret = krb5_store_int16(sp, p.keytype);
    1307           0 :     if(ret) return ret;
    1308             :     }
    1309             : 
    1310       65594 :     ret = krb5_store_data(sp, p.keyvalue);
    1311       65594 :     return ret;
    1312             : }
    1313             : 
    1314             : /**
    1315             :  * Read a keyblock from the storage.
    1316             :  *
    1317             :  * @param sp the storage buffer to write to
    1318             :  * @param p the keyblock read from storage, free using krb5_free_keyblock()
    1319             :  *
    1320             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1321             :  *
    1322             :  * @ingroup krb5_storage
    1323             :  */
    1324             : 
    1325             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1326       94193 : krb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p)
    1327             : {
    1328             :     int ret;
    1329             :     int16_t tmp;
    1330             : 
    1331       94193 :     ret = krb5_ret_int16(sp, &tmp);
    1332       94193 :     if(ret) return ret;
    1333       94193 :     p->keytype = tmp;
    1334             : 
    1335       94193 :     if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
    1336           0 :     ret = krb5_ret_int16(sp, &tmp);
    1337           0 :     if(ret) return ret;
    1338             :     }
    1339             : 
    1340       94193 :     ret = krb5_ret_data(sp, &p->keyvalue);
    1341       94193 :     return ret;
    1342             : }
    1343             : 
    1344             : /**
    1345             :  * Write a times block to storage.
    1346             :  *
    1347             :  * @param sp the storage buffer to write to
    1348             :  * @param times the times block to write.
    1349             :  *
    1350             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1351             :  *
    1352             :  * @ingroup krb5_storage
    1353             :  */
    1354             : 
    1355             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1356        1376 : krb5_store_times(krb5_storage *sp, krb5_times times)
    1357             : {
    1358             :     int ret;
    1359        1376 :     ret = krb5_store_int32(sp, times.authtime);
    1360        1376 :     if(ret) return ret;
    1361        1376 :     ret = krb5_store_int32(sp, times.starttime);
    1362        1376 :     if(ret) return ret;
    1363        1376 :     ret = krb5_store_int32(sp, times.endtime);
    1364        1376 :     if(ret) return ret;
    1365        1376 :     ret = krb5_store_int32(sp, times.renew_till);
    1366        1376 :     return ret;
    1367             : }
    1368             : 
    1369             : /**
    1370             :  * Read a times block from the storage.
    1371             :  *
    1372             :  * @param sp the storage buffer to write to
    1373             :  * @param times the times block read from storage
    1374             :  *
    1375             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1376             :  *
    1377             :  * @ingroup krb5_storage
    1378             :  */
    1379             : 
    1380             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1381       29975 : krb5_ret_times(krb5_storage *sp, krb5_times *times)
    1382             : {
    1383             :     int ret;
    1384             :     int32_t tmp;
    1385             : 
    1386       29975 :     ret = krb5_ret_int32(sp, &tmp);
    1387       29975 :     if (ret) return ret;
    1388       29975 :     times->authtime = tmp;
    1389       29975 :     ret = krb5_ret_int32(sp, &tmp);
    1390       29975 :     if (ret) return ret;
    1391       29975 :     times->starttime = tmp;
    1392       29975 :     ret = krb5_ret_int32(sp, &tmp);
    1393       29975 :     if (ret) return ret;
    1394       29975 :     times->endtime = tmp;
    1395       29975 :     ret = krb5_ret_int32(sp, &tmp);
    1396       29975 :     if (ret) return ret;
    1397       29975 :     times->renew_till = tmp;
    1398       29975 :     return ret;
    1399             : }
    1400             : 
    1401             : /**
    1402             :  * Write a address block to storage.
    1403             :  *
    1404             :  * @param sp the storage buffer to write to
    1405             :  * @param p the address block to write.
    1406             :  *
    1407             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1408             :  *
    1409             :  * @ingroup krb5_storage
    1410             :  */
    1411             : 
    1412             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1413           0 : krb5_store_address(krb5_storage *sp, krb5_address p)
    1414             : {
    1415             :     int ret;
    1416           0 :     ret = krb5_store_int16(sp, p.addr_type);
    1417           0 :     if(ret) return ret;
    1418           0 :     ret = krb5_store_data(sp, p.address);
    1419           0 :     return ret;
    1420             : }
    1421             : 
    1422             : /**
    1423             :  * Read a address block from the storage.
    1424             :  *
    1425             :  * @param sp the storage buffer to write to
    1426             :  * @param adr the address block read from storage
    1427             :  *
    1428             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1429             :  *
    1430             :  * @ingroup krb5_storage
    1431             :  */
    1432             : 
    1433             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1434           0 : krb5_ret_address(krb5_storage *sp, krb5_address *adr)
    1435             : {
    1436             :     int16_t t;
    1437             :     int ret;
    1438           0 :     ret = krb5_ret_int16(sp, &t);
    1439           0 :     if(ret) return ret;
    1440           0 :     adr->addr_type = t;
    1441           0 :     ret = krb5_ret_data(sp, &adr->address);
    1442           0 :     return ret;
    1443             : }
    1444             : 
    1445             : /**
    1446             :  * Write a addresses block to storage.
    1447             :  *
    1448             :  * @param sp the storage buffer to write to
    1449             :  * @param p the addresses block to write.
    1450             :  *
    1451             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1452             :  *
    1453             :  * @ingroup krb5_storage
    1454             :  */
    1455             : 
    1456             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1457        1376 : krb5_store_addrs(krb5_storage *sp, krb5_addresses p)
    1458             : {
    1459             :     size_t i;
    1460             :     int ret;
    1461        1376 :     ret = krb5_store_int32(sp, p.len);
    1462        1376 :     if(ret) return ret;
    1463        1376 :     for(i = 0; i<p.len; i++){
    1464           0 :         ret = krb5_store_address(sp, p.val[i]);
    1465           0 :         if(ret) break;
    1466             :     }
    1467        1376 :     return ret;
    1468             : }
    1469             : 
    1470             : /**
    1471             :  * Read a addresses block from the storage.
    1472             :  *
    1473             :  * @param sp the storage buffer to write to
    1474             :  * @param adr the addresses block read from storage
    1475             :  *
    1476             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1477             :  *
    1478             :  * @ingroup krb5_storage
    1479             :  */
    1480             : 
    1481             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1482       29975 : krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr)
    1483             : {
    1484             :     size_t i;
    1485             :     int ret;
    1486             :     int32_t tmp;
    1487             : 
    1488       29975 :     ret = krb5_ret_int32(sp, &tmp);
    1489       29975 :     if(ret) return ret;
    1490       29975 :     ret = size_too_large_num(sp, tmp, sizeof(adr->val[0]));
    1491       29975 :     if (ret) return ret;
    1492       29975 :     adr->len = tmp;
    1493       29975 :     ALLOC(adr->val, adr->len);
    1494       29975 :     if (adr->val == NULL && adr->len != 0)
    1495           0 :         return ENOMEM;
    1496       29975 :     for(i = 0; i < adr->len; i++){
    1497           0 :         ret = krb5_ret_address(sp, &adr->val[i]);
    1498           0 :         if(ret) break;
    1499             :     }
    1500       29975 :     return ret;
    1501             : }
    1502             : 
    1503             : /**
    1504             :  * Write a auth data block to storage.
    1505             :  *
    1506             :  * @param sp the storage buffer to write to
    1507             :  * @param auth the auth data block to write.
    1508             :  *
    1509             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1510             :  *
    1511             :  * @ingroup krb5_storage
    1512             :  */
    1513             : 
    1514             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1515        1376 : krb5_store_authdata(krb5_storage *sp, krb5_authdata auth)
    1516             : {
    1517             :     krb5_error_code ret;
    1518             :     size_t i;
    1519        1376 :     ret = krb5_store_int32(sp, auth.len);
    1520        1376 :     if(ret) return ret;
    1521        1376 :     for(i = 0; i < auth.len; i++){
    1522           0 :         ret = krb5_store_int16(sp, auth.val[i].ad_type);
    1523           0 :         if(ret) break;
    1524           0 :         ret = krb5_store_data(sp, auth.val[i].ad_data);
    1525           0 :         if(ret) break;
    1526             :     }
    1527        1376 :     return 0;
    1528             : }
    1529             : 
    1530             : /**
    1531             :  * Read a auth data from the storage.
    1532             :  *
    1533             :  * @param sp the storage buffer to write to
    1534             :  * @param auth the auth data block read from storage
    1535             :  *
    1536             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1537             :  *
    1538             :  * @ingroup krb5_storage
    1539             :  */
    1540             : 
    1541             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1542       29975 : krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth)
    1543             : {
    1544             :     krb5_error_code ret;
    1545             :     int32_t tmp;
    1546             :     int16_t tmp2;
    1547             :     int i;
    1548       29975 :     ret = krb5_ret_int32(sp, &tmp);
    1549       29975 :     if(ret) return ret;
    1550       29975 :     ret = size_too_large_num(sp, tmp, sizeof(auth->val[0]));
    1551       29975 :     if (ret) return ret;
    1552       29975 :     ALLOC_SEQ(auth, tmp);
    1553       29975 :     if (auth->val == NULL && tmp != 0)
    1554           0 :         return ENOMEM;
    1555       29975 :     for(i = 0; i < tmp; i++){
    1556           0 :         ret = krb5_ret_int16(sp, &tmp2);
    1557           0 :         if(ret) break;
    1558           0 :         auth->val[i].ad_type = tmp2;
    1559           0 :         ret = krb5_ret_data(sp, &auth->val[i].ad_data);
    1560           0 :         if(ret) break;
    1561             :     }
    1562       29975 :     return ret;
    1563             : }
    1564             : 
    1565             : static int32_t
    1566       31351 : bitswap32(int32_t b)
    1567             : {
    1568       31351 :     int32_t r = 0;
    1569             :     int i;
    1570     1034583 :     for (i = 0; i < 32; i++) {
    1571     1003232 :         r = r << 1 | (b & 1);
    1572     1003232 :         b = b >> 1;
    1573             :     }
    1574       31351 :     return r;
    1575             : }
    1576             : 
    1577             : /**
    1578             :  * Write a credentials block to storage.
    1579             :  *
    1580             :  * @param sp the storage buffer to write to
    1581             :  * @param creds the creds block to write.
    1582             :  *
    1583             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1584             :  *
    1585             :  * @ingroup krb5_storage
    1586             :  */
    1587             : 
    1588             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1589        1376 : krb5_store_creds(krb5_storage *sp, krb5_creds *creds)
    1590             : {
    1591             :     int ret;
    1592             : 
    1593        1376 :     ret = krb5_store_principal(sp, creds->client);
    1594        1376 :     if(ret)
    1595           0 :         return ret;
    1596        1376 :     ret = krb5_store_principal(sp, creds->server);
    1597        1376 :     if(ret)
    1598           0 :         return ret;
    1599        1376 :     ret = krb5_store_keyblock(sp, creds->session);
    1600        1376 :     if(ret)
    1601           0 :         return ret;
    1602        1376 :     ret = krb5_store_times(sp, creds->times);
    1603        1376 :     if(ret)
    1604           0 :         return ret;
    1605        1376 :     ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
    1606        1376 :     if(ret)
    1607           0 :         return ret;
    1608        1376 :     ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
    1609        1376 :     if(ret)
    1610           0 :         return ret;
    1611        1376 :     ret = krb5_store_addrs(sp, creds->addresses);
    1612        1376 :     if(ret)
    1613           0 :         return ret;
    1614        1376 :     ret = krb5_store_authdata(sp, creds->authdata);
    1615        1376 :     if(ret)
    1616           0 :         return ret;
    1617        1376 :     ret = krb5_store_data(sp, creds->ticket);
    1618        1376 :     if(ret)
    1619           0 :         return ret;
    1620        1376 :     ret = krb5_store_data(sp, creds->second_ticket);
    1621        1376 :     return ret;
    1622             : }
    1623             : 
    1624             : /**
    1625             :  * Read a credentials block from the storage.
    1626             :  *
    1627             :  * @param sp the storage buffer to write to
    1628             :  * @param creds the credentials block read from storage
    1629             :  *
    1630             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1631             :  *
    1632             :  * @ingroup krb5_storage
    1633             :  */
    1634             : 
    1635             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1636       31304 : krb5_ret_creds(krb5_storage *sp, krb5_creds *creds)
    1637             : {
    1638             :     krb5_error_code ret;
    1639             :     int8_t dummy8;
    1640             :     int32_t dummy32;
    1641             : 
    1642       31304 :     memset(creds, 0, sizeof(*creds));
    1643       31304 :     ret = krb5_ret_principal (sp,  &creds->client);
    1644       31304 :     if(ret) goto cleanup;
    1645       29975 :     ret = krb5_ret_principal (sp,  &creds->server);
    1646       29975 :     if(ret) goto cleanup;
    1647       29975 :     ret = krb5_ret_keyblock (sp,  &creds->session);
    1648       29975 :     if(ret) goto cleanup;
    1649       29975 :     ret = krb5_ret_times (sp,  &creds->times);
    1650       29975 :     if(ret) goto cleanup;
    1651       29975 :     ret = krb5_ret_int8 (sp,  &dummy8);
    1652       29975 :     if(ret) goto cleanup;
    1653       29975 :     ret = krb5_ret_int32 (sp,  &dummy32);
    1654       29975 :     if(ret) goto cleanup;
    1655       29975 :     creds->flags.b = int2TicketFlags(bitswap32(dummy32));
    1656       29975 :     ret = krb5_ret_addrs (sp,  &creds->addresses);
    1657       29975 :     if(ret) goto cleanup;
    1658       29975 :     ret = krb5_ret_authdata (sp,  &creds->authdata);
    1659       29975 :     if(ret) goto cleanup;
    1660       29975 :     ret = krb5_ret_data (sp,  &creds->ticket);
    1661       29975 :     if(ret) goto cleanup;
    1662       29975 :     ret = krb5_ret_data (sp,  &creds->second_ticket);
    1663       31304 : cleanup:
    1664             :     if(ret) {
    1665             : #if 0
    1666             :         krb5_free_cred_contents(context, creds); /* XXX */
    1667             : #endif
    1668             :     }
    1669       31304 :     return ret;
    1670             : }
    1671             : 
    1672             : #define SC_CLIENT_PRINCIPAL         0x0001
    1673             : #define SC_SERVER_PRINCIPAL         0x0002
    1674             : #define SC_SESSION_KEY              0x0004
    1675             : #define SC_TICKET                   0x0008
    1676             : #define SC_SECOND_TICKET            0x0010
    1677             : #define SC_AUTHDATA                 0x0020
    1678             : #define SC_ADDRESSES                0x0040
    1679             : 
    1680             : /**
    1681             :  * Write a tagged credentials block to storage.
    1682             :  *
    1683             :  * @param sp the storage buffer to write to
    1684             :  * @param creds the creds block to write.
    1685             :  *
    1686             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1687             :  *
    1688             :  * @ingroup krb5_storage
    1689             :  */
    1690             : 
    1691             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1692           0 : krb5_store_creds_tag(krb5_storage *sp, krb5_creds *creds)
    1693             : {
    1694             :     int ret;
    1695           0 :     int32_t header = 0;
    1696             : 
    1697           0 :     if (creds->client)
    1698           0 :         header |= SC_CLIENT_PRINCIPAL;
    1699           0 :     if (creds->server)
    1700           0 :         header |= SC_SERVER_PRINCIPAL;
    1701           0 :     if (creds->session.keytype != ETYPE_NULL)
    1702           0 :         header |= SC_SESSION_KEY;
    1703           0 :     if (creds->ticket.data)
    1704           0 :         header |= SC_TICKET;
    1705           0 :     if (creds->second_ticket.length)
    1706           0 :         header |= SC_SECOND_TICKET;
    1707           0 :     if (creds->authdata.len)
    1708           0 :         header |= SC_AUTHDATA;
    1709           0 :     if (creds->addresses.len)
    1710           0 :         header |= SC_ADDRESSES;
    1711             : 
    1712           0 :     ret = krb5_store_int32(sp, header);
    1713           0 :     if (ret)
    1714           0 :         return ret;
    1715             : 
    1716           0 :     if (creds->client) {
    1717           0 :         ret = krb5_store_principal(sp, creds->client);
    1718           0 :         if(ret)
    1719           0 :             return ret;
    1720             :     }
    1721             : 
    1722           0 :     if (creds->server) {
    1723           0 :         ret = krb5_store_principal(sp, creds->server);
    1724           0 :         if(ret)
    1725           0 :             return ret;
    1726             :     }
    1727             : 
    1728           0 :     if (creds->session.keytype != ETYPE_NULL) {
    1729           0 :         ret = krb5_store_keyblock(sp, creds->session);
    1730           0 :         if(ret)
    1731           0 :             return ret;
    1732             :     }
    1733             : 
    1734           0 :     ret = krb5_store_times(sp, creds->times);
    1735           0 :     if(ret)
    1736           0 :         return ret;
    1737           0 :     ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
    1738           0 :     if(ret)
    1739           0 :         return ret;
    1740             : 
    1741           0 :     ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
    1742           0 :     if(ret)
    1743           0 :         return ret;
    1744             : 
    1745           0 :     if (creds->addresses.len) {
    1746           0 :         ret = krb5_store_addrs(sp, creds->addresses);
    1747           0 :         if(ret)
    1748           0 :             return ret;
    1749             :     }
    1750             : 
    1751           0 :     if (creds->authdata.len) {
    1752           0 :         ret = krb5_store_authdata(sp, creds->authdata);
    1753           0 :         if(ret)
    1754           0 :             return ret;
    1755             :     }
    1756             : 
    1757           0 :     if (creds->ticket.data) {
    1758           0 :         ret = krb5_store_data(sp, creds->ticket);
    1759           0 :         if(ret)
    1760           0 :             return ret;
    1761             :     }
    1762             : 
    1763           0 :     if (creds->second_ticket.data) {
    1764           0 :         ret = krb5_store_data(sp, creds->second_ticket);
    1765           0 :         if (ret)
    1766           0 :             return ret;
    1767             :     }
    1768             : 
    1769           0 :     return ret;
    1770             : }
    1771             : 
    1772             : /**
    1773             :  * Read a tagged credentials block from the storage.
    1774             :  *
    1775             :  * @param sp the storage buffer to write to
    1776             :  * @param creds the credentials block read from storage
    1777             :  *
    1778             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1779             :  *
    1780             :  * @ingroup krb5_storage
    1781             :  */
    1782             : 
    1783             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1784           0 : krb5_ret_creds_tag(krb5_storage *sp,
    1785             :                    krb5_creds *creds)
    1786             : {
    1787             :     krb5_error_code ret;
    1788             :     int8_t dummy8;
    1789             :     int32_t dummy32, header;
    1790             : 
    1791           0 :     memset(creds, 0, sizeof(*creds));
    1792             : 
    1793           0 :     ret = krb5_ret_int32 (sp, &header);
    1794           0 :     if (ret) goto cleanup;
    1795             : 
    1796           0 :     if (header & SC_CLIENT_PRINCIPAL) {
    1797           0 :         ret = krb5_ret_principal (sp,  &creds->client);
    1798           0 :         if(ret) goto cleanup;
    1799             :     }
    1800           0 :     if (header & SC_SERVER_PRINCIPAL) {
    1801           0 :         ret = krb5_ret_principal (sp,  &creds->server);
    1802           0 :         if(ret) goto cleanup;
    1803             :     }
    1804           0 :     if (header & SC_SESSION_KEY) {
    1805           0 :         ret = krb5_ret_keyblock (sp,  &creds->session);
    1806           0 :         if(ret) goto cleanup;
    1807             :     }
    1808           0 :     ret = krb5_ret_times (sp,  &creds->times);
    1809           0 :     if(ret) goto cleanup;
    1810           0 :     ret = krb5_ret_int8 (sp,  &dummy8);
    1811           0 :     if(ret) goto cleanup;
    1812           0 :     ret = krb5_ret_int32 (sp,  &dummy32);
    1813           0 :     if(ret) goto cleanup;
    1814           0 :     creds->flags.b = int2TicketFlags(bitswap32(dummy32));
    1815           0 :     if (header & SC_ADDRESSES) {
    1816           0 :         ret = krb5_ret_addrs (sp,  &creds->addresses);
    1817           0 :         if(ret) goto cleanup;
    1818             :     }
    1819           0 :     if (header & SC_AUTHDATA) {
    1820           0 :         ret = krb5_ret_authdata (sp,  &creds->authdata);
    1821           0 :         if(ret) goto cleanup;
    1822             :     }
    1823           0 :     if (header & SC_TICKET) {
    1824           0 :         ret = krb5_ret_data (sp,  &creds->ticket);
    1825           0 :         if(ret) goto cleanup;
    1826             :     }
    1827           0 :     if (header & SC_SECOND_TICKET) {
    1828           0 :         ret = krb5_ret_data (sp,  &creds->second_ticket);
    1829           0 :         if(ret) goto cleanup;
    1830             :     }
    1831             : 
    1832           0 : cleanup:
    1833             :     if(ret) {
    1834             : #if 0
    1835             :         krb5_free_cred_contents(context, creds); /* XXX */
    1836             : #endif
    1837             :     }
    1838           0 :     return ret;
    1839             : }
    1840             : 
    1841             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1842      326568 : _krb5_ret_data_at_offset(krb5_storage *sp,
    1843             :                          size_t offset,
    1844             :                          size_t length,
    1845             :                          krb5_data *data)
    1846             : {
    1847             :     krb5_error_code ret;
    1848             :     off_t cur, size;
    1849             : 
    1850      326568 :     krb5_data_zero(data);
    1851             : 
    1852      326568 :     cur = sp->seek(sp, 0, SEEK_CUR);
    1853      326568 :     if (cur < 0)
    1854           0 :         return HEIM_ERR_NOT_SEEKABLE;
    1855             : 
    1856      326568 :     size = sp->seek(sp, 0, SEEK_END);
    1857      326568 :     if (offset + length > size) {
    1858           0 :         ret = ERANGE;
    1859           0 :         goto cleanup;
    1860             :     }
    1861             : 
    1862      326568 :     ret = krb5_data_alloc(data, length);
    1863      326568 :     if (ret)
    1864           0 :         goto cleanup;
    1865             : 
    1866      326568 :     if (length) {
    1867      326568 :         sp->seek(sp, offset, SEEK_SET);
    1868             : 
    1869      326568 :         size = sp->fetch(sp, data->data, length);
    1870      326568 :         heim_assert(size == length, "incomplete buffer fetched");
    1871             :     }
    1872             : 
    1873      326568 : cleanup:
    1874      326568 :     sp->seek(sp, cur, SEEK_SET);
    1875             : 
    1876      326568 :     return ret;
    1877             : }
    1878             : 
    1879             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1880      244926 : _krb5_ret_utf8_from_ucs2le_at_offset(krb5_storage *sp,
    1881             :                                      off_t offset,
    1882             :                                      size_t length,
    1883             :                                      char **utf8)
    1884             : {
    1885             :     krb5_error_code ret;
    1886             :     krb5_data data;
    1887      244926 :     size_t ucs2len = length / 2;
    1888      244926 :     uint16_t *ucs2 = NULL;
    1889             :     size_t u8len;
    1890      244926 :     unsigned int flags = WIND_RW_LE;
    1891             : 
    1892      244926 :     *utf8 = NULL;
    1893             : 
    1894      244926 :     krb5_data_zero(&data);
    1895             : 
    1896      244926 :     ret = _krb5_ret_data_at_offset(sp, offset, length, &data);
    1897      244926 :     if (ret)
    1898           0 :         goto out;
    1899             : 
    1900      244926 :     ucs2 = malloc(sizeof(ucs2[0]) * ucs2len);
    1901      244926 :     if (ucs2 == NULL) {
    1902           0 :         ret = ENOMEM;
    1903           0 :         goto out;
    1904             :     }
    1905             : 
    1906      244926 :     ret = wind_ucs2read(data.data, data.length, &flags, ucs2, &ucs2len);
    1907      244926 :     if (ret)
    1908           0 :         goto out;
    1909             : 
    1910      244926 :     ret = wind_ucs2utf8_length(ucs2, ucs2len, &u8len);
    1911      244926 :     if (ret)
    1912           0 :         goto out;
    1913             : 
    1914      244926 :     u8len += 1; /* Add space for NUL */
    1915             : 
    1916      244926 :     *utf8 = malloc(u8len);
    1917      244926 :     if (*utf8 == NULL) {
    1918           0 :         ret = ENOMEM;
    1919           0 :         goto out;
    1920             :     }
    1921             : 
    1922      244926 :     ret = wind_ucs2utf8(ucs2, ucs2len, *utf8, &u8len);
    1923      244926 :     if (ret)
    1924           0 :         goto out;
    1925             : 
    1926      489852 : out:
    1927      244926 :     if (ret && *utf8) {
    1928           0 :         free(*utf8);
    1929           0 :         *utf8 = NULL;
    1930             :     }
    1931      244926 :     free(ucs2);
    1932      244926 :     krb5_data_free(&data);
    1933             : 
    1934      244926 :     return ret;
    1935             : }
    1936             : 
    1937             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1938           0 : _krb5_store_data_at_offset(krb5_storage *sp,
    1939             :                            size_t offset,
    1940             :                            const krb5_data *data)
    1941             : {
    1942             :     krb5_error_code ret;
    1943             :     krb5_ssize_t nbytes;
    1944             :     off_t pos;
    1945             : 
    1946           0 :     if (offset == (off_t)-1) {
    1947           0 :         if (data == NULL || data->data == NULL) {
    1948           0 :             offset = 0;
    1949             :         } else {
    1950           0 :             pos = sp->seek(sp, 0, SEEK_CUR);
    1951           0 :             offset = sp->seek(sp, 0, SEEK_END);
    1952           0 :             sp->seek(sp, pos, SEEK_SET);
    1953             : 
    1954           0 :             if (offset == (off_t)-1)
    1955           0 :                 return HEIM_ERR_NOT_SEEKABLE;
    1956             :         }
    1957             :     }
    1958             : 
    1959           0 :     if (offset > 0xFFFF)
    1960           0 :         return ERANGE;
    1961           0 :     else if ((offset != 0) != (data && data->data))
    1962           0 :         return EINVAL;
    1963           0 :     else if (data && data->length > 0xFFFF)
    1964           0 :         return ERANGE;
    1965             : 
    1966           0 :     ret = krb5_store_uint16(sp, data ? (uint16_t)data->length : 0);
    1967           0 :     if (ret == 0)
    1968           0 :         ret = krb5_store_uint16(sp, (uint16_t)offset);
    1969           0 :     if (ret == 0 && offset) {
    1970           0 :         pos = sp->seek(sp, 0, SEEK_CUR);
    1971           0 :         sp->seek(sp, offset, SEEK_SET);
    1972           0 :         nbytes = krb5_storage_write(sp, data->data, data->length);
    1973           0 :         if ((size_t)nbytes != data->length)
    1974           0 :             ret = sp->eof_code;
    1975           0 :         sp->seek(sp, pos, SEEK_SET);
    1976             :     }
    1977             : 
    1978           0 :     return ret;
    1979             : }
    1980             : 
    1981             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1982           0 : _krb5_store_utf8_as_ucs2le_at_offset(krb5_storage *sp,
    1983             :                                      off_t offset,
    1984             :                                      const char *utf8)
    1985             : {
    1986             :     krb5_error_code ret;
    1987             :     size_t ucs2_len, ucs2le_size;
    1988             :     uint16_t *ucs2, *ucs2le;
    1989             :     unsigned int flags;
    1990             : 
    1991           0 :     if (utf8) {
    1992           0 :         ret = wind_utf8ucs2_length(utf8, &ucs2_len);
    1993           0 :         if (ret)
    1994           0 :             return ret;
    1995             : 
    1996           0 :         ucs2 = malloc(sizeof(ucs2[0]) * ucs2_len);
    1997           0 :         if (ucs2 == NULL)
    1998           0 :             return ENOMEM;
    1999             : 
    2000           0 :         ret = wind_utf8ucs2(utf8, ucs2, &ucs2_len);
    2001           0 :         if (ret) {
    2002           0 :             free(ucs2);
    2003           0 :             return ret;
    2004             :         }
    2005             : 
    2006           0 :         ucs2le_size = (ucs2_len + 1) * 2;
    2007           0 :         ucs2le = malloc(ucs2le_size);
    2008           0 :             if (ucs2le == NULL) {
    2009           0 :                 free(ucs2);
    2010           0 :                 return ENOMEM;
    2011             :         }
    2012             : 
    2013           0 :         flags = WIND_RW_LE;
    2014           0 :         ret = wind_ucs2write(ucs2, ucs2_len, &flags, ucs2le, &ucs2le_size);
    2015           0 :         free(ucs2);
    2016           0 :         if (ret) {
    2017           0 :             free(ucs2le);
    2018           0 :             return ret;
    2019             :         }
    2020             : 
    2021           0 :         ucs2le_size = ucs2_len * 2;
    2022             :     } else {
    2023           0 :         ucs2le = NULL;
    2024           0 :         ucs2le_size = 0;
    2025           0 :         offset = 0;
    2026           0 :         ret = 0;
    2027             :     }
    2028             : 
    2029             :     {
    2030             :         krb5_data data;
    2031             : 
    2032           0 :         data.data = ucs2le;
    2033           0 :         data.length = ucs2le_size;
    2034             : 
    2035           0 :         ret = _krb5_store_data_at_offset(sp, offset, &data);
    2036             :     }
    2037             : 
    2038           0 :     free(ucs2le);
    2039             : 
    2040           0 :     return ret;
    2041             : }

Generated by: LCOV version 1.13