xref: /netbsd-src/crypto/external/bsd/heimdal/dist/lib/krb5/test_store.c (revision afab4e300d3a9fb07dd8c80daf53d0feb3345706)
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