1 /* 2 * Copyright (c) 1997 - 2000, 2002 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 typedef struct mem_storage{ 38 unsigned char *base; 39 size_t size; 40 unsigned char *ptr; 41 }mem_storage; 42 43 static ssize_t 44 mem_fetch(krb5_storage *sp, void *data, size_t size) 45 { 46 mem_storage *s = (mem_storage*)sp->data; 47 if(size > (size_t)(s->base + s->size - s->ptr)) 48 size = s->base + s->size - s->ptr; 49 memmove(data, s->ptr, size); 50 sp->seek(sp, size, SEEK_CUR); 51 return size; 52 } 53 54 static ssize_t 55 mem_store(krb5_storage *sp, const void *data, size_t size) 56 { 57 mem_storage *s = (mem_storage*)sp->data; 58 if(size > (size_t)(s->base + s->size - s->ptr)) 59 size = s->base + s->size - s->ptr; 60 memmove(s->ptr, data, size); 61 sp->seek(sp, size, SEEK_CUR); 62 return size; 63 } 64 65 static ssize_t 66 mem_no_store(krb5_storage *sp, const void *data, size_t size) 67 { 68 return -1; 69 } 70 71 static off_t 72 mem_seek(krb5_storage *sp, off_t offset, int whence) 73 { 74 mem_storage *s = (mem_storage*)sp->data; 75 switch(whence){ 76 case SEEK_SET: 77 if((size_t)offset > s->size) 78 offset = s->size; 79 if(offset < 0) 80 offset = 0; 81 s->ptr = s->base + offset; 82 break; 83 case SEEK_CUR: 84 return sp->seek(sp, s->ptr - s->base + offset, SEEK_SET); 85 case SEEK_END: 86 return sp->seek(sp, s->size + offset, SEEK_SET); 87 default: 88 errno = EINVAL; 89 return -1; 90 } 91 return s->ptr - s->base; 92 } 93 94 static int 95 mem_trunc(krb5_storage *sp, off_t offset) 96 { 97 mem_storage *s = (mem_storage*)sp->data; 98 if((size_t)offset > s->size) 99 return ERANGE; 100 s->size = offset; 101 if ((s->ptr - s->base) > offset) 102 s->ptr = s->base + offset; 103 return 0; 104 } 105 106 static int 107 mem_no_trunc(krb5_storage *sp, off_t offset) 108 { 109 return EINVAL; 110 } 111 112 /** 113 * Create a fixed size memory storage block 114 * 115 * @return A krb5_storage on success, or NULL on out of memory error. 116 * 117 * @ingroup krb5_storage 118 * 119 * @sa krb5_storage_mem() 120 * @sa krb5_storage_from_readonly_mem() 121 * @sa krb5_storage_from_data() 122 * @sa krb5_storage_from_fd() 123 */ 124 125 KRB5_LIB_FUNCTION krb5_storage * KRB5_LIB_CALL 126 krb5_storage_from_mem(void *buf, size_t len) 127 { 128 krb5_storage *sp = malloc(sizeof(krb5_storage)); 129 mem_storage *s; 130 if(sp == NULL) 131 return NULL; 132 s = malloc(sizeof(*s)); 133 if(s == NULL) { 134 free(sp); 135 return NULL; 136 } 137 sp->data = s; 138 sp->flags = 0; 139 sp->eof_code = HEIM_ERR_EOF; 140 s->base = buf; 141 s->size = len; 142 s->ptr = buf; 143 sp->fetch = mem_fetch; 144 sp->store = mem_store; 145 sp->seek = mem_seek; 146 sp->trunc = mem_trunc; 147 sp->free = NULL; 148 sp->max_alloc = UINT_MAX/8; 149 return sp; 150 } 151 152 /** 153 * Create a fixed size memory storage block 154 * 155 * @return A krb5_storage on success, or NULL on out of memory error. 156 * 157 * @ingroup krb5_storage 158 * 159 * @sa krb5_storage_mem() 160 * @sa krb5_storage_from_mem() 161 * @sa krb5_storage_from_readonly_mem() 162 * @sa krb5_storage_from_fd() 163 */ 164 165 KRB5_LIB_FUNCTION krb5_storage * KRB5_LIB_CALL 166 krb5_storage_from_data(krb5_data *data) 167 { 168 return krb5_storage_from_mem(data->data, data->length); 169 } 170 171 /** 172 * Create a fixed size memory storage block that is read only 173 * 174 * @return A krb5_storage on success, or NULL on out of memory error. 175 * 176 * @ingroup krb5_storage 177 * 178 * @sa krb5_storage_mem() 179 * @sa krb5_storage_from_mem() 180 * @sa krb5_storage_from_data() 181 * @sa krb5_storage_from_fd() 182 */ 183 184 KRB5_LIB_FUNCTION krb5_storage * KRB5_LIB_CALL 185 krb5_storage_from_readonly_mem(const void *buf, size_t len) 186 { 187 krb5_storage *sp = malloc(sizeof(krb5_storage)); 188 mem_storage *s; 189 if(sp == NULL) 190 return NULL; 191 s = malloc(sizeof(*s)); 192 if(s == NULL) { 193 free(sp); 194 return NULL; 195 } 196 sp->data = s; 197 sp->flags = 0; 198 sp->eof_code = HEIM_ERR_EOF; 199 s->base = rk_UNCONST(buf); 200 s->size = len; 201 s->ptr = rk_UNCONST(buf); 202 sp->fetch = mem_fetch; 203 sp->store = mem_no_store; 204 sp->seek = mem_seek; 205 sp->trunc = mem_no_trunc; 206 sp->free = NULL; 207 sp->max_alloc = UINT_MAX/8; 208 return sp; 209 } 210