LCOV - code coverage report
Current view: top level - source4/heimdal/lib/krb5 - store.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 294 579 50.8 %
Date: 2021-09-23 10:06:22 Functions: 39 55 70.9 %

          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             : 
      43             : /**
      44             :  * Add the flags on a storage buffer by or-ing in the flags to the buffer.
      45             :  *
      46             :  * @param sp the storage buffer to set the flags on
      47             :  * @param flags the flags to set
      48             :  *
      49             :  * @ingroup krb5_storage
      50             :  */
      51             : 
      52             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
      53      562125 : krb5_storage_set_flags(krb5_storage *sp, krb5_flags flags)
      54             : {
      55      562125 :     sp->flags |= flags;
      56      562125 : }
      57             : 
      58             : /**
      59             :  * Clear the flags on a storage buffer
      60             :  *
      61             :  * @param sp the storage buffer to clear the flags on
      62             :  * @param flags the flags to clear
      63             :  *
      64             :  * @ingroup krb5_storage
      65             :  */
      66             : 
      67             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
      68           0 : krb5_storage_clear_flags(krb5_storage *sp, krb5_flags flags)
      69             : {
      70           0 :     sp->flags &= ~flags;
      71           0 : }
      72             : 
      73             : /**
      74             :  * Return true or false depending on if the storage flags is set or
      75             :  * not. NB testing for the flag 0 always return true.
      76             :  *
      77             :  * @param sp the storage buffer to check flags on
      78             :  * @param flags The flags to test for
      79             :  *
      80             :  * @return true if all the flags are set, false if not.
      81             :  *
      82             :  * @ingroup krb5_storage
      83             :  */
      84             : 
      85             : KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
      86     9099933 : krb5_storage_is_flags(krb5_storage *sp, krb5_flags flags)
      87             : {
      88     9099933 :     return (sp->flags & flags) == flags;
      89             : }
      90             : 
      91             : /**
      92             :  * Set the new byte order of the storage buffer.
      93             :  *
      94             :  * @param sp the storage buffer to set the byte order for.
      95             :  * @param byteorder the new byte order.
      96             :  *
      97             :  * The byte order are: KRB5_STORAGE_BYTEORDER_BE,
      98             :  * KRB5_STORAGE_BYTEORDER_LE and KRB5_STORAGE_BYTEORDER_HOST.
      99             :  *
     100             :  * @ingroup krb5_storage
     101             :  */
     102             : 
     103             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
     104           0 : krb5_storage_set_byteorder(krb5_storage *sp, krb5_flags byteorder)
     105             : {
     106           0 :     sp->flags &= ~KRB5_STORAGE_BYTEORDER_MASK;
     107           0 :     sp->flags |= byteorder;
     108           0 : }
     109             : 
     110             : /**
     111             :  * Return the current byteorder for the buffer. See krb5_storage_set_byteorder() for the list or byte order contants.
     112             :  *
     113             :  * @ingroup krb5_storage
     114             :  */
     115             : 
     116             : KRB5_LIB_FUNCTION krb5_flags KRB5_LIB_CALL
     117           0 : krb5_storage_get_byteorder(krb5_storage *sp)
     118             : {
     119           0 :     return sp->flags & KRB5_STORAGE_BYTEORDER_MASK;
     120             : }
     121             : 
     122             : /**
     123             :  * Set the max alloc value
     124             :  *
     125             :  * @param sp the storage buffer set the max allow for
     126             :  * @param size maximum size to allocate, use 0 to remove limit
     127             :  *
     128             :  * @ingroup krb5_storage
     129             :  */
     130             : 
     131             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
     132           0 : krb5_storage_set_max_alloc(krb5_storage *sp, size_t size)
     133             : {
     134           0 :     sp->max_alloc = size;
     135           0 : }
     136             : 
     137             : /* don't allocate unresonable amount of memory */
     138             : static krb5_error_code
     139      896024 : size_too_large(krb5_storage *sp, size_t size)
     140             : {
     141      911030 :     if (sp->max_alloc && sp->max_alloc < size)
     142           0 :         return HEIM_ERR_TOO_BIG;
     143      896024 :     return 0;
     144             : }
     145             : 
     146             : static krb5_error_code
     147      113413 : size_too_large_num(krb5_storage *sp, size_t count, size_t size)
     148             : {
     149      113413 :     if (sp->max_alloc == 0 || size == 0)
     150           0 :         return 0;
     151      113413 :     size = sp->max_alloc / size;
     152      113413 :     if (size < count)
     153           0 :         return HEIM_ERR_TOO_BIG;
     154      113413 :     return 0;
     155             : }
     156             : 
     157             : /**
     158             :  * Seek to a new offset.
     159             :  *
     160             :  * @param sp the storage buffer to seek in.
     161             :  * @param offset the offset to seek
     162             :  * @param whence relateive searching, SEEK_CUR from the current
     163             :  * position, SEEK_END from the end, SEEK_SET absolute from the start.
     164             :  *
     165             :  * @return The new current offset
     166             :  *
     167             :  * @ingroup krb5_storage
     168             :  */
     169             : 
     170             : KRB5_LIB_FUNCTION off_t KRB5_LIB_CALL
     171      636836 : krb5_storage_seek(krb5_storage *sp, off_t offset, int whence)
     172             : {
     173      636836 :     return (*sp->seek)(sp, offset, whence);
     174             : }
     175             : 
     176             : /**
     177             :  * Truncate the storage buffer in sp to offset.
     178             :  *
     179             :  * @param sp the storage buffer to truncate.
     180             :  * @param offset the offset to truncate too.
     181             :  *
     182             :  * @return An Kerberos 5 error code.
     183             :  *
     184             :  * @ingroup krb5_storage
     185             :  */
     186             : 
     187             : KRB5_LIB_FUNCTION int KRB5_LIB_CALL
     188           0 : krb5_storage_truncate(krb5_storage *sp, off_t offset)
     189             : {
     190           0 :     return (*sp->trunc)(sp, offset);
     191             : }
     192             : 
     193             : /**
     194             :  * Read to the storage buffer.
     195             :  *
     196             :  * @param sp the storage buffer to read from
     197             :  * @param buf the buffer to store the data in
     198             :  * @param len the length to read
     199             :  *
     200             :  * @return The length of data read (can be shorter then len), or negative on error.
     201             :  *
     202             :  * @ingroup krb5_storage
     203             :  */
     204             : 
     205             : KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL
     206      823485 : krb5_storage_read(krb5_storage *sp, void *buf, size_t len)
     207             : {
     208      823485 :     return sp->fetch(sp, buf, len);
     209             : }
     210             : 
     211             : /**
     212             :  * Write to the storage buffer.
     213             :  *
     214             :  * @param sp the storage buffer to write to
     215             :  * @param buf the buffer to write to the storage buffer
     216             :  * @param len the length to write
     217             :  *
     218             :  * @return The length of data written (can be shorter then len), or negative on error.
     219             :  *
     220             :  * @ingroup krb5_storage
     221             :  */
     222             : 
     223             : KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL
     224      757354 : krb5_storage_write(krb5_storage *sp, const void *buf, size_t len)
     225             : {
     226      757354 :     return sp->store(sp, buf, len);
     227             : }
     228             : 
     229             : /**
     230             :  * Set the return code that will be used when end of storage is reached.
     231             :  *
     232             :  * @param sp the storage
     233             :  * @param code the error code to return on end of storage
     234             :  *
     235             :  * @ingroup krb5_storage
     236             :  */
     237             : 
     238             : KRB5_LIB_FUNCTION void KRB5_LIB_CALL
     239       56080 : krb5_storage_set_eof_code(krb5_storage *sp, int code)
     240             : {
     241       56080 :     sp->eof_code = code;
     242       56080 : }
     243             : 
     244             : /**
     245             :  * Get the return code that will be used when end of storage is reached.
     246             :  *
     247             :  * @param sp the storage
     248             :  *
     249             :  * @return storage error code
     250             :  *
     251             :  * @ingroup krb5_storage
     252             :  */
     253             : 
     254             : KRB5_LIB_FUNCTION int KRB5_LIB_CALL
     255           0 : krb5_storage_get_eof_code(krb5_storage *sp)
     256             : {
     257           0 :     return sp->eof_code;
     258             : }
     259             : 
     260             : /**
     261             :  * Free a krb5 storage.
     262             :  *
     263             :  * @param sp the storage to free.
     264             :  *
     265             :  * @return An Kerberos 5 error code.
     266             :  *
     267             :  * @ingroup krb5_storage
     268             :  */
     269             : 
     270             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     271      908374 : krb5_storage_free(krb5_storage *sp)
     272             : {
     273      908374 :     if (sp == NULL)
     274           0 :         return 0;
     275      908374 :     if(sp->free)
     276      411255 :         (*sp->free)(sp);
     277      908374 :     free(sp->data);
     278      908374 :     free(sp);
     279      908374 :     return 0;
     280             : }
     281             : 
     282             : /**
     283             :  * Copy the contnent of storage
     284             :  *
     285             :  * @param sp the storage to copy to a data
     286             :  * @param data the copied data, free with krb5_data_free()
     287             :  *
     288             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     289             :  *
     290             :  * @ingroup krb5_storage
     291             :  */
     292             : 
     293             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     294      355856 : krb5_storage_to_data(krb5_storage *sp, krb5_data *data)
     295             : {
     296             :     off_t pos, size;
     297             :     krb5_error_code ret;
     298             : 
     299      355856 :     pos = sp->seek(sp, 0, SEEK_CUR);
     300      355856 :     if (pos < 0)
     301           0 :         return HEIM_ERR_NOT_SEEKABLE;
     302      355856 :     size = sp->seek(sp, 0, SEEK_END);
     303      364191 :     ret = size_too_large(sp, size);
     304      347521 :     if (ret)
     305           0 :         return ret;
     306      355856 :     ret = krb5_data_alloc(data, size);
     307      355856 :     if (ret) {
     308           0 :         sp->seek(sp, pos, SEEK_SET);
     309           0 :         return ret;
     310             :     }
     311      355856 :     if (size) {
     312      355856 :         sp->seek(sp, 0, SEEK_SET);
     313      355856 :         sp->fetch(sp, data->data, data->length);
     314      355856 :         sp->seek(sp, pos, SEEK_SET);
     315             :     }
     316      347521 :     return 0;
     317             : }
     318             : 
     319             : static krb5_error_code
     320     2262188 : krb5_store_int(krb5_storage *sp,
     321             :                int32_t value,
     322             :                size_t len)
     323             : {
     324             :     int ret;
     325             :     unsigned char v[16];
     326             : 
     327     2262188 :     if(len > sizeof(v))
     328           0 :         return EINVAL;
     329     2262188 :     _krb5_put_int(v, value, len);
     330     2262188 :     ret = sp->store(sp, v, len);
     331     2262188 :     if (ret < 0)
     332           0 :         return errno;
     333     2262188 :     if ((size_t)ret != len)
     334           0 :         return sp->eof_code;
     335     2205479 :     return 0;
     336             : }
     337             : 
     338             : /**
     339             :  * Store a int32 to storage, byte order is controlled by the settings
     340             :  * on the storage, see krb5_storage_set_byteorder().
     341             :  *
     342             :  * @param sp the storage to write too
     343             :  * @param value the value to store
     344             :  *
     345             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     346             :  *
     347             :  * @ingroup krb5_storage
     348             :  */
     349             : 
     350             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     351     2117042 : krb5_store_int32(krb5_storage *sp,
     352             :                  int32_t value)
     353             : {
     354     2117042 :     if(BYTEORDER_IS_HOST(sp))
     355           0 :         value = htonl(value);
     356     2117042 :     else if(BYTEORDER_IS_LE(sp))
     357     1740258 :         value = bswap32(value);
     358     2117042 :     return krb5_store_int(sp, value, 4);
     359             : }
     360             : 
     361             : /**
     362             :  * Store a uint32 to storage, byte order is controlled by the settings
     363             :  * on the storage, see krb5_storage_set_byteorder().
     364             :  *
     365             :  * @param sp the storage to write too
     366             :  * @param value the value to store
     367             :  *
     368             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     369             :  *
     370             :  * @ingroup krb5_storage
     371             :  */
     372             : 
     373             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     374     1741915 : krb5_store_uint32(krb5_storage *sp,
     375             :                   uint32_t value)
     376             : {
     377     1741915 :     return krb5_store_int32(sp, (int32_t)value);
     378             : }
     379             : 
     380             : static krb5_error_code
     381     6220185 : krb5_ret_int(krb5_storage *sp,
     382             :              int32_t *value,
     383             :              size_t len)
     384             : {
     385             :     int ret;
     386             :     unsigned char v[4];
     387             :     unsigned long w;
     388     6220185 :     ret = sp->fetch(sp, v, len);
     389     6220185 :     if (ret < 0)
     390           0 :         return errno;
     391     6220185 :     if ((size_t)ret != len)
     392       26208 :         return sp->eof_code;
     393     6193977 :     _krb5_get_int(v, &w, len);
     394     6193977 :     *value = w;
     395     6193977 :     return 0;
     396             : }
     397             : 
     398             : /**
     399             :  * Read a int32 from storage, byte order is controlled by the settings
     400             :  * on the storage, see krb5_storage_set_byteorder().
     401             :  *
     402             :  * @param sp the storage to write too
     403             :  * @param value the value read from the buffer
     404             :  *
     405             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     406             :  *
     407             :  * @ingroup krb5_storage
     408             :  */
     409             : 
     410             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     411     5029544 : krb5_ret_int32(krb5_storage *sp,
     412             :                int32_t *value)
     413             : {
     414     5029544 :     krb5_error_code ret = krb5_ret_int(sp, value, 4);
     415     5029544 :     if(ret)
     416       25982 :         return ret;
     417     5003336 :     if(BYTEORDER_IS_HOST(sp))
     418           0 :         *value = htonl(*value);
     419     5003336 :     else if(BYTEORDER_IS_LE(sp))
     420     3161075 :         *value = bswap32(*value);
     421     4918252 :     return 0;
     422             : }
     423             : 
     424             : /**
     425             :  * Read a uint32 from storage, byte order is controlled by the settings
     426             :  * on the storage, see krb5_storage_set_byteorder().
     427             :  *
     428             :  * @param sp the storage to write too
     429             :  * @param value the value read from the buffer
     430             :  *
     431             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     432             :  *
     433             :  * @ingroup krb5_storage
     434             :  */
     435             : 
     436             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     437     3590283 : krb5_ret_uint32(krb5_storage *sp,
     438             :                 uint32_t *value)
     439             : {
     440             :     krb5_error_code ret;
     441             :     int32_t v;
     442             : 
     443     3590283 :     ret = krb5_ret_int32(sp, &v);
     444     3590283 :     if (ret == 0)
     445     3590283 :         *value = (uint32_t)v;
     446             : 
     447     3590283 :     return ret;
     448             : }
     449             : 
     450             : /**
     451             :  * Store a int16 to storage, byte order is controlled by the settings
     452             :  * on the storage, see krb5_storage_set_byteorder().
     453             :  *
     454             :  * @param sp the storage to write too
     455             :  * @param value the value to store
     456             :  *
     457             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     458             :  *
     459             :  * @ingroup krb5_storage
     460             :  */
     461             : 
     462             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     463      145146 : krb5_store_int16(krb5_storage *sp,
     464             :                  int16_t value)
     465             : {
     466      145146 :     if(BYTEORDER_IS_HOST(sp))
     467           0 :         value = htons(value);
     468      145146 :     else if(BYTEORDER_IS_LE(sp))
     469       66861 :         value = bswap16(value);
     470      145146 :     return krb5_store_int(sp, value, 2);
     471             : }
     472             : 
     473             : /**
     474             :  * Store a uint16 to storage, byte order is controlled by the settings
     475             :  * on the storage, see krb5_storage_set_byteorder().
     476             :  *
     477             :  * @param sp the storage to write too
     478             :  * @param value the value to store
     479             :  *
     480             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     481             :  *
     482             :  * @ingroup krb5_storage
     483             :  */
     484             : 
     485             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     486       66861 : krb5_store_uint16(krb5_storage *sp,
     487             :                   uint16_t value)
     488             : {
     489       66861 :     return krb5_store_int16(sp, (int16_t)value);
     490             : }
     491             : 
     492             : /**
     493             :  * Read a int16 from storage, byte order is controlled by the settings
     494             :  * on the storage, see krb5_storage_set_byteorder().
     495             :  *
     496             :  * @param sp the storage to write too
     497             :  * @param value the value read from the buffer
     498             :  *
     499             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     500             :  *
     501             :  * @ingroup krb5_storage
     502             :  */
     503             : 
     504             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     505     1190641 : krb5_ret_int16(krb5_storage *sp,
     506             :                int16_t *value)
     507             : {
     508     1190641 :     int32_t v = 0;
     509             :     int ret;
     510     1190641 :     ret = krb5_ret_int(sp, &v, 2);
     511     1190641 :     if(ret)
     512           0 :         return ret;
     513     1190641 :     *value = v;
     514     1190641 :     if(BYTEORDER_IS_HOST(sp))
     515           0 :         *value = htons(*value);
     516     1190641 :     else if(BYTEORDER_IS_LE(sp))
     517       86081 :         *value = bswap16(*value);
     518     1172483 :     return 0;
     519             : }
     520             : 
     521             : /**
     522             :  * Read a int16 from storage, byte order is controlled by the settings
     523             :  * on the storage, see krb5_storage_set_byteorder().
     524             :  *
     525             :  * @param sp the storage to write too
     526             :  * @param value the value read from the buffer
     527             :  *
     528             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     529             :  *
     530             :  * @ingroup krb5_storage
     531             :  */
     532             : 
     533             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     534       86081 : krb5_ret_uint16(krb5_storage *sp,
     535             :                 uint16_t *value)
     536             : {
     537             :     krb5_error_code ret;
     538             :     int16_t v;
     539             : 
     540       86081 :     ret = krb5_ret_int16(sp, &v);
     541       86081 :     if (ret == 0)
     542       86081 :         *value = (uint16_t)v;
     543             : 
     544       86081 :     return ret;
     545             : }
     546             : 
     547             : /**
     548             :  * Store a int8 to storage.
     549             :  *
     550             :  * @param sp the storage to write too
     551             :  * @param value the value to store
     552             :  *
     553             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     554             :  *
     555             :  * @ingroup krb5_storage
     556             :  */
     557             : 
     558             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     559        4270 : krb5_store_int8(krb5_storage *sp,
     560             :                 int8_t value)
     561             : {
     562             :     int ret;
     563             : 
     564        4270 :     ret = sp->store(sp, &value, sizeof(value));
     565        4270 :     if (ret != sizeof(value))
     566           0 :         return (ret<0)?errno:sp->eof_code;
     567        4006 :     return 0;
     568             : }
     569             : 
     570             : /**
     571             :  * Store a uint8 to storage.
     572             :  *
     573             :  * @param sp the storage to write too
     574             :  * @param value the value to store
     575             :  *
     576             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     577             :  *
     578             :  * @ingroup krb5_storage
     579             :  */
     580             : 
     581             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     582           0 : krb5_store_uint8(krb5_storage *sp,
     583             :                  uint8_t value)
     584             : {
     585           0 :     return krb5_store_int8(sp, (int8_t)value);
     586             : }
     587             : 
     588             : /**
     589             :  * Read a int8 from storage
     590             :  *
     591             :  * @param sp the storage to write too
     592             :  * @param value the value read from the buffer
     593             :  *
     594             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     595             :  *
     596             :  * @ingroup krb5_storage
     597             :  */
     598             : 
     599             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     600      314411 : krb5_ret_int8(krb5_storage *sp,
     601             :               int8_t *value)
     602             : {
     603             :     int ret;
     604             : 
     605      314411 :     ret = sp->fetch(sp, value, sizeof(*value));
     606      314411 :     if (ret != sizeof(*value))
     607           0 :         return (ret<0)?errno:sp->eof_code;
     608      309681 :     return 0;
     609             : }
     610             : 
     611             : /**
     612             :  * Read a uint8 from storage
     613             :  *
     614             :  * @param sp the storage to write too
     615             :  * @param value the value read from the buffer
     616             :  *
     617             :  * @return 0 for success, or a Kerberos 5 error code on failure.
     618             :  *
     619             :  * @ingroup krb5_storage
     620             :  */
     621             : 
     622             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     623           0 : krb5_ret_uint8(krb5_storage *sp,
     624             :                uint8_t *value)
     625             : {
     626             :     krb5_error_code ret;
     627             :     int8_t v;
     628             : 
     629           0 :     ret = krb5_ret_int8(sp, &v);
     630           0 :     if (ret == 0)
     631           0 :         *value = (uint8_t)v;
     632             : 
     633           0 :     return ret;
     634             : }
     635             : 
     636             : /**
     637             :  * Store a data to the storage. The data is stored with an int32 as
     638             :  * lenght plus the data (not padded).
     639             :  *
     640             :  * @param sp the storage buffer to write to
     641             :  * @param data the buffer to store.
     642             :  *
     643             :  * @return 0 on success, a Kerberos 5 error code on failure.
     644             :  *
     645             :  * @ingroup krb5_storage
     646             :  */
     647             : 
     648             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     649      296736 : krb5_store_data(krb5_storage *sp,
     650             :                 krb5_data data)
     651             : {
     652             :     int ret;
     653      296736 :     ret = krb5_store_int32(sp, data.length);
     654      296736 :     if(ret < 0)
     655           0 :         return ret;
     656      296736 :     ret = sp->store(sp, data.data, data.length);
     657      296736 :     if(ret < 0)
     658           0 :         return errno;
     659      296736 :     if((size_t)ret != data.length)
     660           0 :         return sp->eof_code;
     661      290065 :     return 0;
     662             : }
     663             : 
     664             : /**
     665             :  * Parse a data from the storage.
     666             :  *
     667             :  * @param sp the storage buffer to read from
     668             :  * @param data the parsed data
     669             :  *
     670             :  * @return 0 on success, a Kerberos 5 error code on failure.
     671             :  *
     672             :  * @ingroup krb5_storage
     673             :  */
     674             : 
     675             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     676      577495 : krb5_ret_data(krb5_storage *sp,
     677             :               krb5_data *data)
     678             : {
     679             :     int ret;
     680             :     int32_t size;
     681             : 
     682      577495 :     ret = krb5_ret_int32(sp, &size);
     683      577495 :     if(ret)
     684       22321 :         return ret;
     685      561845 :     ret = size_too_large(sp, size);
     686      548503 :     if (ret)
     687           0 :         return ret;
     688      555174 :     ret = krb5_data_alloc (data, size);
     689      555174 :     if (ret)
     690           0 :         return ret;
     691      555174 :     if (size) {
     692      435172 :         ret = sp->fetch(sp, data->data, size);
     693      435172 :         if(ret != size)
     694           0 :             return (ret < 0)? errno : sp->eof_code;
     695             :     }
     696      548503 :     return 0;
     697             : }
     698             : 
     699             : /**
     700             :  * Store a string to the buffer. The data is formated as an len:uint32
     701             :  * plus the string itself (not padded).
     702             :  *
     703             :  * @param sp the storage buffer to write to
     704             :  * @param s the string to store.
     705             :  *
     706             :  * @return 0 on success, a Kerberos 5 error code on failure.
     707             :  *
     708             :  * @ingroup krb5_storage
     709             :  */
     710             : 
     711             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     712      226299 : krb5_store_string(krb5_storage *sp, const char *s)
     713             : {
     714             :     krb5_data data;
     715      226299 :     data.length = strlen(s);
     716      226299 :     data.data = rk_UNCONST(s);
     717      226299 :     return krb5_store_data(sp, data);
     718             : }
     719             : 
     720             : /**
     721             :  * Parse a string from the storage.
     722             :  *
     723             :  * @param sp the storage buffer to read from
     724             :  * @param string the parsed string
     725             :  *
     726             :  * @return 0 on success, a Kerberos 5 error code on failure.
     727             :  *
     728             :  * @ingroup krb5_storage
     729             :  */
     730             : 
     731             : 
     732             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     733      365411 : krb5_ret_string(krb5_storage *sp,
     734             :                 char **string)
     735             : {
     736             :     int ret;
     737             :     krb5_data data;
     738      365411 :     ret = krb5_ret_data(sp, &data);
     739      365411 :     if(ret)
     740           0 :         return ret;
     741      365411 :     *string = realloc(data.data, data.length + 1);
     742      365411 :     if(*string == NULL){
     743           0 :         free(data.data);
     744           0 :         return ENOMEM;
     745             :     }
     746      365411 :     (*string)[data.length] = 0;
     747      365411 :     return 0;
     748             : }
     749             : 
     750             : /**
     751             :  * Store a zero terminated string to the buffer. The data is stored
     752             :  * one character at a time until a NUL is stored.
     753             :  *
     754             :  * @param sp the storage buffer to write to
     755             :  * @param s the string to store.
     756             :  *
     757             :  * @return 0 on success, a Kerberos 5 error code on failure.
     758             :  *
     759             :  * @ingroup krb5_storage
     760             :  */
     761             : 
     762             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     763           0 : krb5_store_stringz(krb5_storage *sp, const char *s)
     764             : {
     765           0 :     size_t len = strlen(s) + 1;
     766             :     ssize_t ret;
     767             : 
     768           0 :     ret = sp->store(sp, s, len);
     769           0 :     if(ret < 0)
     770           0 :         return ret;
     771           0 :     if((size_t)ret != len)
     772           0 :         return sp->eof_code;
     773           0 :     return 0;
     774             : }
     775             : 
     776             : /**
     777             :  * Parse zero terminated string from the storage.
     778             :  *
     779             :  * @param sp the storage buffer to read from
     780             :  * @param string the parsed string
     781             :  *
     782             :  * @return 0 on success, a Kerberos 5 error code on failure.
     783             :  *
     784             :  * @ingroup krb5_storage
     785             :  */
     786             : 
     787             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     788           0 : krb5_ret_stringz(krb5_storage *sp,
     789             :                 char **string)
     790             : {
     791             :     char c;
     792           0 :     char *s = NULL;
     793           0 :     size_t len = 0;
     794             :     ssize_t ret;
     795             : 
     796           0 :     while((ret = sp->fetch(sp, &c, 1)) == 1){
     797             :         char *tmp;
     798             : 
     799           0 :         len++;
     800           0 :         ret = size_too_large(sp, len);
     801           0 :         if (ret)
     802           0 :             break;
     803           0 :         tmp = realloc (s, len);
     804           0 :         if (tmp == NULL) {
     805           0 :             free (s);
     806           0 :             return ENOMEM;
     807             :         }
     808           0 :         s = tmp;
     809           0 :         s[len - 1] = c;
     810           0 :         if(c == 0)
     811           0 :             break;
     812             :     }
     813           0 :     if(ret != 1){
     814           0 :         free(s);
     815           0 :         if(ret == 0)
     816           0 :             return sp->eof_code;
     817           0 :         return ret;
     818             :     }
     819           0 :     *string = s;
     820           0 :     return 0;
     821             : }
     822             : 
     823             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     824           0 : krb5_store_stringnl(krb5_storage *sp, const char *s)
     825             : {
     826           0 :     size_t len = strlen(s);
     827             :     ssize_t ret;
     828             : 
     829           0 :     ret = sp->store(sp, s, len);
     830           0 :     if(ret < 0)
     831           0 :         return ret;
     832           0 :     if((size_t)ret != len)
     833           0 :         return sp->eof_code;
     834           0 :     ret = sp->store(sp, "\n", 1);
     835           0 :     if(ret != 1) {
     836           0 :         if(ret < 0)
     837           0 :             return ret;
     838             :         else
     839           0 :             return sp->eof_code;
     840             :     }
     841             : 
     842           0 :     return 0;
     843             : 
     844             : }
     845             : 
     846             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     847           0 : krb5_ret_stringnl(krb5_storage *sp,
     848             :                   char **string)
     849             : {
     850           0 :     int expect_nl = 0;
     851             :     char c;
     852           0 :     char *s = NULL;
     853           0 :     size_t len = 0;
     854             :     ssize_t ret;
     855             : 
     856           0 :     while((ret = sp->fetch(sp, &c, 1)) == 1){
     857             :         char *tmp;
     858             : 
     859           0 :         if (c == '\r') {
     860           0 :             expect_nl = 1;
     861           0 :             continue;
     862             :         }
     863           0 :         if (expect_nl && c != '\n') {
     864           0 :             free(s);
     865           0 :             return KRB5_BADMSGTYPE;
     866             :         }
     867             : 
     868           0 :         len++;
     869           0 :         ret = size_too_large(sp, len);
     870           0 :         if (ret)
     871           0 :             break;
     872           0 :         tmp = realloc (s, len);
     873           0 :         if (tmp == NULL) {
     874           0 :             free (s);
     875           0 :             return ENOMEM;
     876             :         }
     877           0 :         s = tmp;
     878           0 :         if(c == '\n') {
     879           0 :             s[len - 1] = '\0';
     880           0 :             break;
     881             :         }
     882           0 :         s[len - 1] = c;
     883             :     }
     884           0 :     if(ret != 1){
     885           0 :         free(s);
     886           0 :         if(ret == 0)
     887           0 :             return sp->eof_code;
     888           0 :         return ret;
     889             :     }
     890           0 :     *string = s;
     891           0 :     return 0;
     892             : }
     893             : 
     894             : /**
     895             :  * Write a principal block to storage.
     896             :  *
     897             :  * @param sp the storage buffer to write to
     898             :  * @param p the principal block to write.
     899             :  *
     900             :  * @return 0 on success, a Kerberos 5 error code on failure.
     901             :  *
     902             :  * @ingroup krb5_storage
     903             :  */
     904             : 
     905             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     906        2926 : krb5_store_principal(krb5_storage *sp,
     907             :                      krb5_const_principal p)
     908             : {
     909             :     size_t i;
     910             :     int ret;
     911             : 
     912        2926 :     if(!krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE)) {
     913        2926 :         ret = krb5_store_int32(sp, p->name.name_type);
     914        2926 :         if(ret) return ret;
     915             :     }
     916        2926 :     if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
     917           0 :         ret = krb5_store_int32(sp, p->name.name_string.len + 1);
     918             :     else
     919        2926 :         ret = krb5_store_int32(sp, p->name.name_string.len);
     920             : 
     921        2926 :     if(ret) return ret;
     922        2926 :     ret = krb5_store_string(sp, p->realm);
     923        2926 :     if(ret) return ret;
     924        7185 :     for(i = 0; i < p->name.name_string.len; i++){
     925        4259 :         ret = krb5_store_string(sp, p->name.name_string.val[i]);
     926        4259 :         if(ret) return ret;
     927             :     }
     928        2926 :     return 0;
     929             : }
     930             : 
     931             : /**
     932             :  * Parse principal from the storage.
     933             :  *
     934             :  * @param sp the storage buffer to read from
     935             :  * @param princ the parsed principal
     936             :  *
     937             :  * @return 0 on success, a Kerberos 5 error code on failure.
     938             :  *
     939             :  * @ingroup krb5_storage
     940             :  */
     941             : 
     942             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     943       60976 : krb5_ret_principal(krb5_storage *sp,
     944             :                    krb5_principal *princ)
     945             : {
     946             :     int i;
     947             :     int ret;
     948             :     krb5_principal p;
     949             :     int32_t type;
     950             :     int32_t ncomp;
     951             : 
     952       60976 :     p = calloc(1, sizeof(*p));
     953       60976 :     if(p == NULL)
     954           0 :         return ENOMEM;
     955             : 
     956       60976 :     if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_NO_NAME_TYPE))
     957           0 :         type = KRB5_NT_UNKNOWN;
     958       60976 :     else if((ret = krb5_ret_int32(sp, &type))){
     959        1245 :         free(p);
     960        1245 :         return ret;
     961             :     }
     962       59731 :     if((ret = krb5_ret_int32(sp, &ncomp))){
     963           0 :         free(p);
     964           0 :         return ret;
     965             :     }
     966       59731 :     if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS))
     967           0 :         ncomp--;
     968       59731 :     if (ncomp < 0) {
     969           0 :         free(p);
     970           0 :         return EINVAL;
     971             :     }
     972       59731 :     ret = size_too_large_num(sp, ncomp, sizeof(p->name.name_string.val[0]));
     973       59731 :     if (ret) {
     974           0 :         free(p);
     975           0 :         return ret;
     976             :     }
     977       59731 :     p->name.name_type = type;
     978       59731 :     p->name.name_string.len = ncomp;
     979       59731 :     ret = krb5_ret_string(sp, &p->realm);
     980       59731 :     if(ret) {
     981           0 :         free(p);
     982           0 :         return ret;
     983             :     }
     984       59731 :     p->name.name_string.val = calloc(ncomp, sizeof(p->name.name_string.val[0]));
     985       59731 :     if(p->name.name_string.val == NULL && ncomp != 0){
     986           0 :         free(p->realm);
     987           0 :         free(p);
     988           0 :         return ENOMEM;
     989             :     }
     990      146297 :     for(i = 0; i < ncomp; i++){
     991       86566 :         ret = krb5_ret_string(sp, &p->name.name_string.val[i]);
     992       86566 :         if(ret) {
     993           0 :             while (i >= 0)
     994           0 :                 free(p->name.name_string.val[i--]);
     995           0 :             free(p->realm);
     996           0 :             free(p);
     997           0 :             return ret;
     998             :         }
     999             :     }
    1000       59731 :     *princ = p;
    1001       59731 :     return 0;
    1002             : }
    1003             : 
    1004             : /**
    1005             :  * Store a keyblock to the storage.
    1006             :  *
    1007             :  * @param sp the storage buffer to write to
    1008             :  * @param p the keyblock to write
    1009             :  *
    1010             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1011             :  *
    1012             :  * @ingroup krb5_storage
    1013             :  */
    1014             : 
    1015             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1016       65947 : krb5_store_keyblock(krb5_storage *sp, krb5_keyblock p)
    1017             : {
    1018             :     int ret;
    1019       65947 :     ret = krb5_store_int16(sp, p.keytype);
    1020       65947 :     if(ret) return ret;
    1021             : 
    1022       65947 :     if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
    1023             :         /* this should really be enctype, but it is the same as
    1024             :            keytype nowadays */
    1025           0 :     ret = krb5_store_int16(sp, p.keytype);
    1026           0 :     if(ret) return ret;
    1027             :     }
    1028             : 
    1029       65947 :     ret = krb5_store_data(sp, p.keyvalue);
    1030       65947 :     return ret;
    1031             : }
    1032             : 
    1033             : /**
    1034             :  * Read a keyblock from the storage.
    1035             :  *
    1036             :  * @param sp the storage buffer to write to
    1037             :  * @param p the keyblock read from storage, free using krb5_free_keyblock()
    1038             :  *
    1039             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1040             :  *
    1041             :  * @ingroup krb5_storage
    1042             :  */
    1043             : 
    1044             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1045       91439 : krb5_ret_keyblock(krb5_storage *sp, krb5_keyblock *p)
    1046             : {
    1047             :     int ret;
    1048             :     int16_t tmp;
    1049             : 
    1050       91439 :     ret = krb5_ret_int16(sp, &tmp);
    1051       91439 :     if(ret) return ret;
    1052       91439 :     p->keytype = tmp;
    1053             : 
    1054       91439 :     if(krb5_storage_is_flags(sp, KRB5_STORAGE_KEYBLOCK_KEYTYPE_TWICE)){
    1055           0 :     ret = krb5_ret_int16(sp, &tmp);
    1056           0 :     if(ret) return ret;
    1057             :     }
    1058             : 
    1059       91439 :     ret = krb5_ret_data(sp, &p->keyvalue);
    1060       91439 :     return ret;
    1061             : }
    1062             : 
    1063             : /**
    1064             :  * Write a times block to storage.
    1065             :  *
    1066             :  * @param sp the storage buffer to write to
    1067             :  * @param times the times block to write.
    1068             :  *
    1069             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1070             :  *
    1071             :  * @ingroup krb5_storage
    1072             :  */
    1073             : 
    1074             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1075        1349 : krb5_store_times(krb5_storage *sp, krb5_times times)
    1076             : {
    1077             :     int ret;
    1078        1349 :     ret = krb5_store_int32(sp, times.authtime);
    1079        1349 :     if(ret) return ret;
    1080        1349 :     ret = krb5_store_int32(sp, times.starttime);
    1081        1349 :     if(ret) return ret;
    1082        1349 :     ret = krb5_store_int32(sp, times.endtime);
    1083        1349 :     if(ret) return ret;
    1084        1349 :     ret = krb5_store_int32(sp, times.renew_till);
    1085        1349 :     return ret;
    1086             : }
    1087             : 
    1088             : /**
    1089             :  * Read a times block from the storage.
    1090             :  *
    1091             :  * @param sp the storage buffer to write to
    1092             :  * @param times the times block read from storage
    1093             :  *
    1094             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1095             :  *
    1096             :  * @ingroup krb5_storage
    1097             :  */
    1098             : 
    1099             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1100       26841 : krb5_ret_times(krb5_storage *sp, krb5_times *times)
    1101             : {
    1102             :     int ret;
    1103             :     int32_t tmp;
    1104       26841 :     ret = krb5_ret_int32(sp, &tmp);
    1105       26841 :     times->authtime = tmp;
    1106       26841 :     if(ret) return ret;
    1107       26841 :     ret = krb5_ret_int32(sp, &tmp);
    1108       26841 :     times->starttime = tmp;
    1109       26841 :     if(ret) return ret;
    1110       26841 :     ret = krb5_ret_int32(sp, &tmp);
    1111       26841 :     times->endtime = tmp;
    1112       26841 :     if(ret) return ret;
    1113       26841 :     ret = krb5_ret_int32(sp, &tmp);
    1114       26841 :     times->renew_till = tmp;
    1115       26841 :     return ret;
    1116             : }
    1117             : 
    1118             : /**
    1119             :  * Write a address block to storage.
    1120             :  *
    1121             :  * @param sp the storage buffer to write to
    1122             :  * @param p the address block to write.
    1123             :  *
    1124             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1125             :  *
    1126             :  * @ingroup krb5_storage
    1127             :  */
    1128             : 
    1129             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1130           0 : krb5_store_address(krb5_storage *sp, krb5_address p)
    1131             : {
    1132             :     int ret;
    1133           0 :     ret = krb5_store_int16(sp, p.addr_type);
    1134           0 :     if(ret) return ret;
    1135           0 :     ret = krb5_store_data(sp, p.address);
    1136           0 :     return ret;
    1137             : }
    1138             : 
    1139             : /**
    1140             :  * Read a address block from the storage.
    1141             :  *
    1142             :  * @param sp the storage buffer to write to
    1143             :  * @param adr the address block read from storage
    1144             :  *
    1145             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1146             :  *
    1147             :  * @ingroup krb5_storage
    1148             :  */
    1149             : 
    1150             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1151           0 : krb5_ret_address(krb5_storage *sp, krb5_address *adr)
    1152             : {
    1153             :     int16_t t;
    1154             :     int ret;
    1155           0 :     ret = krb5_ret_int16(sp, &t);
    1156           0 :     if(ret) return ret;
    1157           0 :     adr->addr_type = t;
    1158           0 :     ret = krb5_ret_data(sp, &adr->address);
    1159           0 :     return ret;
    1160             : }
    1161             : 
    1162             : /**
    1163             :  * Write a addresses block to storage.
    1164             :  *
    1165             :  * @param sp the storage buffer to write to
    1166             :  * @param p the addresses block to write.
    1167             :  *
    1168             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1169             :  *
    1170             :  * @ingroup krb5_storage
    1171             :  */
    1172             : 
    1173             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1174        1349 : krb5_store_addrs(krb5_storage *sp, krb5_addresses p)
    1175             : {
    1176             :     size_t i;
    1177             :     int ret;
    1178        1349 :     ret = krb5_store_int32(sp, p.len);
    1179        1349 :     if(ret) return ret;
    1180        1349 :     for(i = 0; i<p.len; i++){
    1181           0 :         ret = krb5_store_address(sp, p.val[i]);
    1182           0 :         if(ret) break;
    1183             :     }
    1184        1349 :     return ret;
    1185             : }
    1186             : 
    1187             : /**
    1188             :  * Read a addresses block from the storage.
    1189             :  *
    1190             :  * @param sp the storage buffer to write to
    1191             :  * @param adr the addresses block read from storage
    1192             :  *
    1193             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1194             :  *
    1195             :  * @ingroup krb5_storage
    1196             :  */
    1197             : 
    1198             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1199       26841 : krb5_ret_addrs(krb5_storage *sp, krb5_addresses *adr)
    1200             : {
    1201             :     size_t i;
    1202             :     int ret;
    1203             :     int32_t tmp;
    1204             : 
    1205       26841 :     ret = krb5_ret_int32(sp, &tmp);
    1206       26841 :     if(ret) return ret;
    1207       26841 :     ret = size_too_large_num(sp, tmp, sizeof(adr->val[0]));
    1208       26841 :     if (ret) return ret;
    1209       26841 :     adr->len = tmp;
    1210       26841 :     ALLOC(adr->val, adr->len);
    1211       26841 :     if (adr->val == NULL && adr->len != 0)
    1212           0 :         return ENOMEM;
    1213       26841 :     for(i = 0; i < adr->len; i++){
    1214           0 :         ret = krb5_ret_address(sp, &adr->val[i]);
    1215           0 :         if(ret) break;
    1216             :     }
    1217       26841 :     return ret;
    1218             : }
    1219             : 
    1220             : /**
    1221             :  * Write a auth data block to storage.
    1222             :  *
    1223             :  * @param sp the storage buffer to write to
    1224             :  * @param auth the auth data block to write.
    1225             :  *
    1226             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1227             :  *
    1228             :  * @ingroup krb5_storage
    1229             :  */
    1230             : 
    1231             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1232        1349 : krb5_store_authdata(krb5_storage *sp, krb5_authdata auth)
    1233             : {
    1234             :     krb5_error_code ret;
    1235             :     size_t i;
    1236        1349 :     ret = krb5_store_int32(sp, auth.len);
    1237        1349 :     if(ret) return ret;
    1238        1349 :     for(i = 0; i < auth.len; i++){
    1239           0 :         ret = krb5_store_int16(sp, auth.val[i].ad_type);
    1240           0 :         if(ret) break;
    1241           0 :         ret = krb5_store_data(sp, auth.val[i].ad_data);
    1242           0 :         if(ret) break;
    1243             :     }
    1244        1349 :     return 0;
    1245             : }
    1246             : 
    1247             : /**
    1248             :  * Read a auth data from the storage.
    1249             :  *
    1250             :  * @param sp the storage buffer to write to
    1251             :  * @param auth the auth data block read from storage
    1252             :  *
    1253             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1254             :  *
    1255             :  * @ingroup krb5_storage
    1256             :  */
    1257             : 
    1258             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1259       26841 : krb5_ret_authdata(krb5_storage *sp, krb5_authdata *auth)
    1260             : {
    1261             :     krb5_error_code ret;
    1262             :     int32_t tmp;
    1263             :     int16_t tmp2;
    1264             :     int i;
    1265       26841 :     ret = krb5_ret_int32(sp, &tmp);
    1266       26841 :     if(ret) return ret;
    1267       26841 :     ret = size_too_large_num(sp, tmp, sizeof(auth->val[0]));
    1268       26841 :     if (ret) return ret;
    1269       26841 :     ALLOC_SEQ(auth, tmp);
    1270       26841 :     if (auth->val == NULL && tmp != 0)
    1271           0 :         return ENOMEM;
    1272       26841 :     for(i = 0; i < tmp; i++){
    1273           0 :         ret = krb5_ret_int16(sp, &tmp2);
    1274           0 :         if(ret) break;
    1275           0 :         auth->val[i].ad_type = tmp2;
    1276           0 :         ret = krb5_ret_data(sp, &auth->val[i].ad_data);
    1277           0 :         if(ret) break;
    1278             :     }
    1279       26841 :     return ret;
    1280             : }
    1281             : 
    1282             : static int32_t
    1283       28151 : bitswap32(int32_t b)
    1284             : {
    1285       28151 :     int32_t r = 0;
    1286             :     int i;
    1287      928983 :     for (i = 0; i < 32; i++) {
    1288      900832 :         r = r << 1 | (b & 1);
    1289      900832 :         b = b >> 1;
    1290             :     }
    1291       28151 :     return r;
    1292             : }
    1293             : 
    1294             : /**
    1295             :  * Write a credentials block to storage.
    1296             :  *
    1297             :  * @param sp the storage buffer to write to
    1298             :  * @param creds the creds block to write.
    1299             :  *
    1300             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1301             :  *
    1302             :  * @ingroup krb5_storage
    1303             :  */
    1304             : 
    1305             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1306        1349 : krb5_store_creds(krb5_storage *sp, krb5_creds *creds)
    1307             : {
    1308             :     int ret;
    1309             : 
    1310        1349 :     ret = krb5_store_principal(sp, creds->client);
    1311        1349 :     if(ret)
    1312           0 :         return ret;
    1313        1349 :     ret = krb5_store_principal(sp, creds->server);
    1314        1349 :     if(ret)
    1315           0 :         return ret;
    1316        1349 :     ret = krb5_store_keyblock(sp, creds->session);
    1317        1349 :     if(ret)
    1318           0 :         return ret;
    1319        1349 :     ret = krb5_store_times(sp, creds->times);
    1320        1349 :     if(ret)
    1321           0 :         return ret;
    1322        1349 :     ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
    1323        1349 :     if(ret)
    1324           0 :         return ret;
    1325             : 
    1326        1349 :     if(krb5_storage_is_flags(sp, KRB5_STORAGE_CREDS_FLAGS_WRONG_BITORDER))
    1327           0 :         ret = krb5_store_int32(sp, creds->flags.i);
    1328             :     else
    1329        1349 :         ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
    1330        1349 :     if(ret)
    1331           0 :         return ret;
    1332             : 
    1333        1349 :     ret = krb5_store_addrs(sp, creds->addresses);
    1334        1349 :     if(ret)
    1335           0 :         return ret;
    1336        1349 :     ret = krb5_store_authdata(sp, creds->authdata);
    1337        1349 :     if(ret)
    1338           0 :         return ret;
    1339        1349 :     ret = krb5_store_data(sp, creds->ticket);
    1340        1349 :     if(ret)
    1341           0 :         return ret;
    1342        1349 :     ret = krb5_store_data(sp, creds->second_ticket);
    1343        1349 :     return ret;
    1344             : }
    1345             : 
    1346             : /**
    1347             :  * Read a credentials block from the storage.
    1348             :  *
    1349             :  * @param sp the storage buffer to write to
    1350             :  * @param creds the credentials block read from storage
    1351             :  *
    1352             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1353             :  *
    1354             :  * @ingroup krb5_storage
    1355             :  */
    1356             : 
    1357             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1358       28086 : krb5_ret_creds(krb5_storage *sp, krb5_creds *creds)
    1359             : {
    1360             :     krb5_error_code ret;
    1361             :     int8_t dummy8;
    1362             :     int32_t dummy32;
    1363             : 
    1364       28086 :     memset(creds, 0, sizeof(*creds));
    1365       28086 :     ret = krb5_ret_principal (sp,  &creds->client);
    1366       28086 :     if(ret) goto cleanup;
    1367       26841 :     ret = krb5_ret_principal (sp,  &creds->server);
    1368       26841 :     if(ret) goto cleanup;
    1369       26841 :     ret = krb5_ret_keyblock (sp,  &creds->session);
    1370       26841 :     if(ret) goto cleanup;
    1371       26841 :     ret = krb5_ret_times (sp,  &creds->times);
    1372       26841 :     if(ret) goto cleanup;
    1373       26841 :     ret = krb5_ret_int8 (sp,  &dummy8);
    1374       26841 :     if(ret) goto cleanup;
    1375       26841 :     ret = krb5_ret_int32 (sp,  &dummy32);
    1376       26841 :     if(ret) goto cleanup;
    1377             :     /*
    1378             :      * Runtime detect the what is the higher bits of the bitfield. If
    1379             :      * any of the higher bits are set in the input data, it's either a
    1380             :      * new ticket flag (and this code need to be removed), or it's a
    1381             :      * MIT cache (or new Heimdal cache), lets change it to our current
    1382             :      * format.
    1383             :      */
    1384             :     {
    1385       26841 :         uint32_t mask = 0xffff0000;
    1386       26841 :         creds->flags.i = 0;
    1387       26841 :         creds->flags.b.anonymous = 1;
    1388       26841 :         if (creds->flags.i & mask)
    1389           0 :             mask = ~mask;
    1390       26841 :         if (dummy32 & mask)
    1391       26802 :             dummy32 = bitswap32(dummy32);
    1392             :     }
    1393       26841 :     creds->flags.i = dummy32;
    1394       26841 :     ret = krb5_ret_addrs (sp,  &creds->addresses);
    1395       26841 :     if(ret) goto cleanup;
    1396       26841 :     ret = krb5_ret_authdata (sp,  &creds->authdata);
    1397       26841 :     if(ret) goto cleanup;
    1398       26841 :     ret = krb5_ret_data (sp,  &creds->ticket);
    1399       26841 :     if(ret) goto cleanup;
    1400       26841 :     ret = krb5_ret_data (sp,  &creds->second_ticket);
    1401       28086 : cleanup:
    1402             :     if(ret) {
    1403             : #if 0
    1404             :         krb5_free_cred_contents(context, creds); /* XXX */
    1405             : #endif
    1406             :     }
    1407       28086 :     return ret;
    1408             : }
    1409             : 
    1410             : #define SC_CLIENT_PRINCIPAL         0x0001
    1411             : #define SC_SERVER_PRINCIPAL         0x0002
    1412             : #define SC_SESSION_KEY              0x0004
    1413             : #define SC_TICKET                   0x0008
    1414             : #define SC_SECOND_TICKET            0x0010
    1415             : #define SC_AUTHDATA                 0x0020
    1416             : #define SC_ADDRESSES                0x0040
    1417             : 
    1418             : /**
    1419             :  * Write a tagged credentials block to storage.
    1420             :  *
    1421             :  * @param sp the storage buffer to write to
    1422             :  * @param creds the creds block to write.
    1423             :  *
    1424             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1425             :  *
    1426             :  * @ingroup krb5_storage
    1427             :  */
    1428             : 
    1429             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1430           0 : krb5_store_creds_tag(krb5_storage *sp, krb5_creds *creds)
    1431             : {
    1432             :     int ret;
    1433           0 :     int32_t header = 0;
    1434             : 
    1435           0 :     if (creds->client)
    1436           0 :         header |= SC_CLIENT_PRINCIPAL;
    1437           0 :     if (creds->server)
    1438           0 :         header |= SC_SERVER_PRINCIPAL;
    1439           0 :     if (creds->session.keytype != ETYPE_NULL)
    1440           0 :         header |= SC_SESSION_KEY;
    1441           0 :     if (creds->ticket.data)
    1442           0 :         header |= SC_TICKET;
    1443           0 :     if (creds->second_ticket.length)
    1444           0 :         header |= SC_SECOND_TICKET;
    1445           0 :     if (creds->authdata.len)
    1446           0 :         header |= SC_AUTHDATA;
    1447           0 :     if (creds->addresses.len)
    1448           0 :         header |= SC_ADDRESSES;
    1449             : 
    1450           0 :     ret = krb5_store_int32(sp, header);
    1451           0 :     if (ret)
    1452           0 :         return ret;
    1453             : 
    1454           0 :     if (creds->client) {
    1455           0 :         ret = krb5_store_principal(sp, creds->client);
    1456           0 :         if(ret)
    1457           0 :             return ret;
    1458             :     }
    1459             : 
    1460           0 :     if (creds->server) {
    1461           0 :         ret = krb5_store_principal(sp, creds->server);
    1462           0 :         if(ret)
    1463           0 :             return ret;
    1464             :     }
    1465             : 
    1466           0 :     if (creds->session.keytype != ETYPE_NULL) {
    1467           0 :         ret = krb5_store_keyblock(sp, creds->session);
    1468           0 :         if(ret)
    1469           0 :             return ret;
    1470             :     }
    1471             : 
    1472           0 :     ret = krb5_store_times(sp, creds->times);
    1473           0 :     if(ret)
    1474           0 :         return ret;
    1475           0 :     ret = krb5_store_int8(sp, creds->second_ticket.length != 0); /* is_skey */
    1476           0 :     if(ret)
    1477           0 :         return ret;
    1478             : 
    1479           0 :     ret = krb5_store_int32(sp, bitswap32(TicketFlags2int(creds->flags.b)));
    1480           0 :     if(ret)
    1481           0 :         return ret;
    1482             : 
    1483           0 :     if (creds->addresses.len) {
    1484           0 :         ret = krb5_store_addrs(sp, creds->addresses);
    1485           0 :         if(ret)
    1486           0 :             return ret;
    1487             :     }
    1488             : 
    1489           0 :     if (creds->authdata.len) {
    1490           0 :         ret = krb5_store_authdata(sp, creds->authdata);
    1491           0 :         if(ret)
    1492           0 :             return ret;
    1493             :     }
    1494             : 
    1495           0 :     if (creds->ticket.data) {
    1496           0 :         ret = krb5_store_data(sp, creds->ticket);
    1497           0 :         if(ret)
    1498           0 :             return ret;
    1499             :     }
    1500             : 
    1501           0 :     if (creds->second_ticket.data) {
    1502           0 :         ret = krb5_store_data(sp, creds->second_ticket);
    1503           0 :         if (ret)
    1504           0 :             return ret;
    1505             :     }
    1506             : 
    1507           0 :     return ret;
    1508             : }
    1509             : 
    1510             : /**
    1511             :  * Read a tagged credentials block from the storage.
    1512             :  *
    1513             :  * @param sp the storage buffer to write to
    1514             :  * @param creds the credentials block read from storage
    1515             :  *
    1516             :  * @return 0 on success, a Kerberos 5 error code on failure.
    1517             :  *
    1518             :  * @ingroup krb5_storage
    1519             :  */
    1520             : 
    1521             : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    1522           0 : krb5_ret_creds_tag(krb5_storage *sp,
    1523             :                    krb5_creds *creds)
    1524             : {
    1525             :     krb5_error_code ret;
    1526             :     int8_t dummy8;
    1527             :     int32_t dummy32, header;
    1528             : 
    1529           0 :     memset(creds, 0, sizeof(*creds));
    1530             : 
    1531           0 :     ret = krb5_ret_int32 (sp, &header);
    1532           0 :     if (ret) goto cleanup;
    1533             : 
    1534           0 :     if (header & SC_CLIENT_PRINCIPAL) {
    1535           0 :         ret = krb5_ret_principal (sp,  &creds->client);
    1536           0 :         if(ret) goto cleanup;
    1537             :     }
    1538           0 :     if (header & SC_SERVER_PRINCIPAL) {
    1539           0 :         ret = krb5_ret_principal (sp,  &creds->server);
    1540           0 :         if(ret) goto cleanup;
    1541             :     }
    1542           0 :     if (header & SC_SESSION_KEY) {
    1543           0 :         ret = krb5_ret_keyblock (sp,  &creds->session);
    1544           0 :         if(ret) goto cleanup;
    1545             :     }
    1546           0 :     ret = krb5_ret_times (sp,  &creds->times);
    1547           0 :     if(ret) goto cleanup;
    1548           0 :     ret = krb5_ret_int8 (sp,  &dummy8);
    1549           0 :     if(ret) goto cleanup;
    1550           0 :     ret = krb5_ret_int32 (sp,  &dummy32);
    1551           0 :     if(ret) goto cleanup;
    1552             :     /*
    1553             :      * Runtime detect the what is the higher bits of the bitfield. If
    1554             :      * any of the higher bits are set in the input data, it's either a
    1555             :      * new ticket flag (and this code need to be removed), or it's a
    1556             :      * MIT cache (or new Heimdal cache), lets change it to our current
    1557             :      * format.
    1558             :      */
    1559             :     {
    1560           0 :         uint32_t mask = 0xffff0000;
    1561           0 :         creds->flags.i = 0;
    1562           0 :         creds->flags.b.anonymous = 1;
    1563           0 :         if (creds->flags.i & mask)
    1564           0 :             mask = ~mask;
    1565           0 :         if (dummy32 & mask)
    1566           0 :             dummy32 = bitswap32(dummy32);
    1567             :     }
    1568           0 :     creds->flags.i = dummy32;
    1569           0 :     if (header & SC_ADDRESSES) {
    1570           0 :         ret = krb5_ret_addrs (sp,  &creds->addresses);
    1571           0 :         if(ret) goto cleanup;
    1572             :     }
    1573           0 :     if (header & SC_AUTHDATA) {
    1574           0 :         ret = krb5_ret_authdata (sp,  &creds->authdata);
    1575           0 :         if(ret) goto cleanup;
    1576             :     }
    1577           0 :     if (header & SC_TICKET) {
    1578           0 :         ret = krb5_ret_data (sp,  &creds->ticket);
    1579           0 :         if(ret) goto cleanup;
    1580             :     }
    1581           0 :     if (header & SC_SECOND_TICKET) {
    1582           0 :         ret = krb5_ret_data (sp,  &creds->second_ticket);
    1583           0 :         if(ret) goto cleanup;
    1584             :     }
    1585             : 
    1586           0 : cleanup:
    1587             :     if(ret) {
    1588             : #if 0
    1589             :         krb5_free_cred_contents(context, creds); /* XXX */
    1590             : #endif
    1591             :     }
    1592           0 :     return ret;
    1593             : }

Generated by: LCOV version 1.13