1 /*	$NetBSD: test_keytab.c,v 1.1.1.1 2011/04/13 18:15:38 elric Exp $	*/
2 
3 /*
4  * Copyright (c) 2005 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 <err.h>
37 #include <krb5/getarg.h>
38 
39 /*
40  * Test that removal entry from of empty keytab doesn't corrupts
41  * memory.
42  */
43 
44 static void
45 test_empty_keytab(krb5_context context, const char *keytab)
46 {
47     krb5_error_code ret;
48     krb5_keytab id;
49     krb5_keytab_entry entry;
50 
51     ret = krb5_kt_resolve(context, keytab, &id);
52     if (ret)
53 	krb5_err(context, 1, ret, "krb5_kt_resolve");
54 
55     memset(&entry, 0, sizeof(entry));
56 
57     krb5_kt_remove_entry(context, id, &entry);
58 
59     ret = krb5_kt_have_content(context, id);
60     if (ret == 0)
61 	krb5_errx(context, 1, "supposed to be empty keytab isn't");
62 
63     ret = krb5_kt_close(context, id);
64     if (ret)
65 	krb5_err(context, 1, ret, "krb5_kt_close");
66 }
67 
68 /*
69  * Test that memory keytab are refcounted.
70  */
71 
72 static void
73 test_memory_keytab(krb5_context context, const char *keytab, const char *keytab2)
74 {
75     krb5_error_code ret;
76     krb5_keytab id, id2, id3;
77     krb5_keytab_entry entry, entry2, entry3;
78 
79     ret = krb5_kt_resolve(context, keytab, &id);
80     if (ret)
81 	krb5_err(context, 1, ret, "krb5_kt_resolve");
82 
83     memset(&entry, 0, sizeof(entry));
84     ret = krb5_parse_name(context, "lha@SU.SE", &entry.principal);
85     if (ret)
86 	krb5_err(context, 1, ret, "krb5_parse_name");
87     entry.vno = 1;
88     ret = krb5_generate_random_keyblock(context,
89 					ETYPE_AES256_CTS_HMAC_SHA1_96,
90 					&entry.keyblock);
91     if (ret)
92 	krb5_err(context, 1, ret, "krb5_generate_random_keyblock");
93 
94     krb5_kt_add_entry(context, id, &entry);
95 
96     ret = krb5_kt_resolve(context, keytab, &id2);
97     if (ret)
98 	krb5_err(context, 1, ret, "krb5_kt_resolve");
99 
100     ret = krb5_kt_get_entry(context, id,
101 			    entry.principal,
102 			    0,
103 			    ETYPE_AES256_CTS_HMAC_SHA1_96,
104 			    &entry2);
105     if (ret)
106 	krb5_err(context, 1, ret, "krb5_kt_get_entry");
107     krb5_kt_free_entry(context, &entry2);
108 
109     ret = krb5_kt_close(context, id);
110     if (ret)
111 	krb5_err(context, 1, ret, "krb5_kt_close");
112 
113     ret = krb5_kt_get_entry(context, id2,
114 			    entry.principal,
115 			    0,
116 			    ETYPE_AES256_CTS_HMAC_SHA1_96,
117 			    &entry2);
118     if (ret)
119 	krb5_err(context, 1, ret, "krb5_kt_get_entry");
120     krb5_kt_free_entry(context, &entry2);
121 
122     ret = krb5_kt_close(context, id2);
123     if (ret)
124 	krb5_err(context, 1, ret, "krb5_kt_close");
125 
126 
127     ret = krb5_kt_resolve(context, keytab2, &id3);
128     if (ret)
129 	krb5_err(context, 1, ret, "krb5_kt_resolve");
130 
131     memset(&entry3, 0, sizeof(entry3));
132     ret = krb5_parse_name(context, "lha3@SU.SE", &entry3.principal);
133     if (ret)
134 	krb5_err(context, 1, ret, "krb5_parse_name");
135     entry3.vno = 1;
136     ret = krb5_generate_random_keyblock(context,
137 					ETYPE_AES256_CTS_HMAC_SHA1_96,
138 					&entry3.keyblock);
139     if (ret)
140 	krb5_err(context, 1, ret, "krb5_generate_random_keyblock");
141 
142     krb5_kt_add_entry(context, id3, &entry3);
143 
144 
145     ret = krb5_kt_resolve(context, keytab, &id);
146     if (ret)
147 	krb5_err(context, 1, ret, "krb5_kt_resolve");
148 
149     ret = krb5_kt_get_entry(context, id,
150 			    entry.principal,
151 			    0,
152 			    ETYPE_AES256_CTS_HMAC_SHA1_96,
153 			    &entry2);
154     if (ret == 0)
155 	krb5_errx(context, 1, "krb5_kt_get_entry when if should fail");
156 
157     krb5_kt_remove_entry(context, id, &entry);
158 
159     ret = krb5_kt_close(context, id);
160     if (ret)
161 	krb5_err(context, 1, ret, "krb5_kt_close");
162 
163     krb5_kt_free_entry(context, &entry);
164 
165     krb5_kt_remove_entry(context, id3, &entry3);
166 
167     ret = krb5_kt_close(context, id3);
168     if (ret)
169 	krb5_err(context, 1, ret, "krb5_kt_close");
170 
171     krb5_free_principal(context, entry3.principal);
172     krb5_free_keyblock_contents(context, &entry3.keyblock);
173 }
174 
175 static void
176 perf_add(krb5_context context, krb5_keytab id, int times)
177 {
178 }
179 
180 static void
181 perf_find(krb5_context context, krb5_keytab id, int times)
182 {
183 }
184 
185 static void
186 perf_delete(krb5_context context, krb5_keytab id, int forward, int times)
187 {
188 }
189 
190 
191 static int version_flag = 0;
192 static int help_flag	= 0;
193 static char *perf_str   = NULL;
194 static int times = 1000;
195 
196 static struct getargs args[] = {
197     {"performance",	0,	arg_string,	&perf_str,
198      "test performance for named keytab", "keytab" },
199     {"times",	0,	arg_integer,	&times,
200      "number of times to run the perforamce test", "number" },
201     {"version",	0,	arg_flag,	&version_flag,
202      "print version", NULL },
203     {"help",	0,	arg_flag,	&help_flag,
204      NULL, NULL }
205 };
206 
207 static void
208 usage (int ret)
209 {
210     arg_printusage (args,
211 		    sizeof(args)/sizeof(*args),
212 		    NULL,
213 		    "");
214     exit (ret);
215 }
216 
217 int
218 main(int argc, char **argv)
219 {
220     krb5_context context;
221     krb5_error_code ret;
222     int optidx = 0;
223 
224     setprogname(argv[0]);
225 
226     if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
227 	usage(1);
228 
229     if (help_flag)
230 	usage (0);
231 
232     if(version_flag){
233 	print_version(NULL);
234 	exit(0);
235     }
236 
237     argc -= optidx;
238     argv += optidx;
239 
240     if (argc != 0)
241 	errx(1, "argc != 0");
242 
243     ret = krb5_init_context(&context);
244     if (ret)
245 	errx (1, "krb5_init_context failed: %d", ret);
246 
247     if (perf_str) {
248 	krb5_keytab id;
249 
250 	ret = krb5_kt_resolve(context, perf_str, &id);
251 	if (ret)
252 	    krb5_err(context, 1, ret, "krb5_kt_resolve: %s", perf_str);
253 
254 	/* add, find, delete on keytab */
255 	perf_add(context, id, times);
256 	perf_find(context, id, times);
257 	perf_delete(context, id, 0, times);
258 
259 	/* add and find again on used keytab */
260 	perf_add(context, id, times);
261 	perf_find(context, id, times);
262 
263 	ret = krb5_kt_destroy(context, id);
264 	if (ret)
265 	    krb5_err(context, 1, ret, "krb5_kt_destroy: %s", perf_str);
266 
267 	ret = krb5_kt_resolve(context, perf_str, &id);
268 	if (ret)
269 	    krb5_err(context, 1, ret, "krb5_kt_resolve: %s", perf_str);
270 
271 	/* try delete backwards */
272 #if 0
273 	perf_add(context, id, times);
274 	perf_delete(context, id, 1, times);
275 #endif
276 
277 	ret = krb5_kt_destroy(context, id);
278 	if (ret)
279 	    krb5_err(context, 1, ret, "krb5_kt_destroy");
280 
281     } else {
282 
283 	test_empty_keytab(context, "MEMORY:foo");
284 	test_empty_keytab(context, "FILE:foo");
285 
286 	test_memory_keytab(context, "MEMORY:foo", "MEMORY:foo2");
287 
288     }
289 
290     krb5_free_context(context);
291 
292     return 0;
293 }
294