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