1 /* 2 * Copyright (c) 2006 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 KTH nor the names of its contributors may be 18 * used to endorse or promote products derived from this software without 19 * specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY 22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE 25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 32 33 #include "krb5_locl.h" 34 #include <getarg.h> 35 36 static void 37 test_int8(krb5_context context, krb5_storage *sp) 38 { 39 krb5_error_code ret; 40 int i; 41 int8_t val[] = { 42 0, 1, -1, 128, -127 43 }, v; 44 45 krb5_storage_truncate(sp, 0); 46 47 for (i = 0; i < sizeof(val[0])/sizeof(val); i++) { 48 49 ret = krb5_store_int8(sp, val[i]); 50 if (ret) 51 krb5_err(context, 1, ret, "krb5_store_int8"); 52 krb5_storage_seek(sp, 0, SEEK_SET); 53 ret = krb5_ret_int8(sp, &v); 54 if (ret) 55 krb5_err(context, 1, ret, "krb5_ret_int8"); 56 if (v != val[i]) 57 krb5_errx(context, 1, "store and ret mismatch"); 58 } 59 } 60 61 static void 62 test_int16(krb5_context context, krb5_storage *sp) 63 { 64 krb5_error_code ret; 65 int i; 66 int16_t val[] = { 67 0, 1, -1, 32768, -32767 68 }, v; 69 70 krb5_storage_truncate(sp, 0); 71 72 for (i = 0; i < sizeof(val[0])/sizeof(val); i++) { 73 74 ret = krb5_store_int16(sp, val[i]); 75 if (ret) 76 krb5_err(context, 1, ret, "krb5_store_int16"); 77 krb5_storage_seek(sp, 0, SEEK_SET); 78 ret = krb5_ret_int16(sp, &v); 79 if (ret) 80 krb5_err(context, 1, ret, "krb5_ret_int16"); 81 if (v != val[i]) 82 krb5_errx(context, 1, "store and ret mismatch"); 83 } 84 } 85 86 static void 87 test_int32(krb5_context context, krb5_storage *sp) 88 { 89 krb5_error_code ret; 90 int i; 91 int32_t val[] = { 92 0, 1, -1, 2147483647, -2147483646 93 }, v; 94 95 krb5_storage_truncate(sp, 0); 96 97 for (i = 0; i < sizeof(val[0])/sizeof(val); i++) { 98 99 ret = krb5_store_int32(sp, val[i]); 100 if (ret) 101 krb5_err(context, 1, ret, "krb5_store_int32"); 102 krb5_storage_seek(sp, 0, SEEK_SET); 103 ret = krb5_ret_int32(sp, &v); 104 if (ret) 105 krb5_err(context, 1, ret, "krb5_ret_int32"); 106 if (v != val[i]) 107 krb5_errx(context, 1, "store and ret mismatch"); 108 } 109 } 110 111 static void 112 test_uint8(krb5_context context, krb5_storage *sp) 113 { 114 krb5_error_code ret; 115 int i; 116 uint8_t val[] = { 117 0, 1, 255 118 }, v; 119 120 krb5_storage_truncate(sp, 0); 121 122 for (i = 0; i < sizeof(val[0])/sizeof(val); i++) { 123 124 ret = krb5_store_uint8(sp, val[i]); 125 if (ret) 126 krb5_err(context, 1, ret, "krb5_store_uint8"); 127 krb5_storage_seek(sp, 0, SEEK_SET); 128 ret = krb5_ret_uint8(sp, &v); 129 if (ret) 130 krb5_err(context, 1, ret, "krb5_ret_uint8"); 131 if (v != val[i]) 132 krb5_errx(context, 1, "store and ret mismatch"); 133 } 134 } 135 136 static void 137 test_uint16(krb5_context context, krb5_storage *sp) 138 { 139 krb5_error_code ret; 140 int i; 141 uint16_t val[] = { 142 0, 1, 65535 143 }, v; 144 145 krb5_storage_truncate(sp, 0); 146 147 for (i = 0; i < sizeof(val[0])/sizeof(val); i++) { 148 149 ret = krb5_store_uint16(sp, val[i]); 150 if (ret) 151 krb5_err(context, 1, ret, "krb5_store_uint16"); 152 krb5_storage_seek(sp, 0, SEEK_SET); 153 ret = krb5_ret_uint16(sp, &v); 154 if (ret) 155 krb5_err(context, 1, ret, "krb5_ret_uint16"); 156 if (v != val[i]) 157 krb5_errx(context, 1, "store and ret mismatch"); 158 } 159 } 160 161 static void 162 test_uint32(krb5_context context, krb5_storage *sp) 163 { 164 krb5_error_code ret; 165 int i; 166 uint32_t val[] = { 167 0, 1, 4294967295UL 168 }, v; 169 170 krb5_storage_truncate(sp, 0); 171 172 for (i = 0; i < sizeof(val[0])/sizeof(val); i++) { 173 174 ret = krb5_store_uint32(sp, val[i]); 175 if (ret) 176 krb5_err(context, 1, ret, "krb5_store_uint32"); 177 krb5_storage_seek(sp, 0, SEEK_SET); 178 ret = krb5_ret_uint32(sp, &v); 179 if (ret) 180 krb5_err(context, 1, ret, "krb5_ret_uint32"); 181 if (v != val[i]) 182 krb5_errx(context, 1, "store and ret mismatch"); 183 } 184 } 185 186 187 static void 188 test_storage(krb5_context context, krb5_storage *sp) 189 { 190 test_int8(context, sp); 191 test_int16(context, sp); 192 test_int32(context, sp); 193 test_uint8(context, sp); 194 test_uint16(context, sp); 195 test_uint32(context, sp); 196 } 197 198 199 static void 200 test_truncate(krb5_context context, krb5_storage *sp, int fd) 201 { 202 struct stat sb; 203 204 krb5_store_string(sp, "hej"); 205 krb5_storage_truncate(sp, 2); 206 207 if (fstat(fd, &sb) != 0) 208 krb5_err(context, 1, errno, "fstat"); 209 if (sb.st_size != 2) 210 krb5_errx(context, 1, "length not 2"); 211 212 krb5_storage_truncate(sp, 1024); 213 214 if (fstat(fd, &sb) != 0) 215 krb5_err(context, 1, errno, "fstat"); 216 if (sb.st_size != 1024) 217 krb5_errx(context, 1, "length not 2"); 218 } 219 220 static void 221 check_too_large(krb5_context context, krb5_storage *sp) 222 { 223 uint32_t too_big_sizes[] = { INT_MAX, INT_MAX / 2, INT_MAX / 4, INT_MAX / 8 + 1}; 224 krb5_error_code ret; 225 krb5_data data; 226 size_t n; 227 228 for (n = 0; n < sizeof(too_big_sizes) / sizeof(too_big_sizes); n++) { 229 krb5_storage_truncate(sp, 0); 230 krb5_store_uint32(sp, too_big_sizes[n]); 231 krb5_storage_seek(sp, 0, SEEK_SET); 232 ret = krb5_ret_data(sp, &data); 233 if (ret != HEIM_ERR_TOO_BIG) 234 errx(1, "not too big: %lu", (unsigned long)n); 235 } 236 } 237 238 /* 239 * 240 */ 241 242 static int version_flag = 0; 243 static int help_flag = 0; 244 245 static struct getargs args[] = { 246 {"version", 0, arg_flag, &version_flag, 247 "print version", NULL }, 248 {"help", 0, arg_flag, &help_flag, 249 NULL, NULL } 250 }; 251 252 static void 253 usage (int ret) 254 { 255 arg_printusage (args, 256 sizeof(args)/sizeof(*args), 257 NULL, 258 ""); 259 exit (ret); 260 } 261 262 int 263 main(int argc, char **argv) 264 { 265 krb5_context context; 266 krb5_error_code ret; 267 int fd, optidx = 0; 268 krb5_storage *sp; 269 const char *fn = "test-store-data"; 270 271 setprogname(argv[0]); 272 273 if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) 274 usage(1); 275 276 if (help_flag) 277 usage (0); 278 279 if(version_flag){ 280 print_version(NULL); 281 exit(0); 282 } 283 284 argc -= optidx; 285 argv += optidx; 286 287 ret = krb5_init_context (&context); 288 if (ret) 289 errx (1, "krb5_init_context failed: %d", ret); 290 291 /* 292 * Test encoding/decoding of primotive types on diffrent backends 293 */ 294 295 sp = krb5_storage_emem(); 296 if (sp == NULL) 297 krb5_errx(context, 1, "krb5_storage_emem: no mem"); 298 299 test_storage(context, sp); 300 check_too_large(context, sp); 301 krb5_storage_free(sp); 302 303 304 fd = open(fn, O_RDWR|O_CREAT|O_TRUNC, 0600); 305 if (fd < 0) 306 krb5_err(context, 1, errno, "open(%s)", fn); 307 308 sp = krb5_storage_from_fd(fd); 309 close(fd); 310 if (sp == NULL) 311 krb5_errx(context, 1, "krb5_storage_from_fd: %s no mem", fn); 312 313 test_storage(context, sp); 314 krb5_storage_free(sp); 315 unlink(fn); 316 317 /* 318 * test truncate behavior 319 */ 320 321 fd = open(fn, O_RDWR|O_CREAT|O_TRUNC, 0600); 322 if (fd < 0) 323 krb5_err(context, 1, errno, "open(%s)", fn); 324 325 sp = krb5_storage_from_fd(fd); 326 if (sp == NULL) 327 krb5_errx(context, 1, "krb5_storage_from_fd: %s no mem", fn); 328 329 test_truncate(context, sp, fd); 330 krb5_storage_free(sp); 331 close(fd); 332 unlink(fn); 333 334 krb5_free_context(context); 335 336 return 0; 337 } 338