1178825Sdfr/*
2233294Sstas * Copyright (c) 2005 Kungliga Tekniska H��gskolan
3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4233294Sstas * All rights reserved.
5178825Sdfr *
6233294Sstas * Redistribution and use in source and binary forms, with or without
7233294Sstas * modification, are permitted provided that the following conditions
8233294Sstas * are met:
9178825Sdfr *
10233294Sstas * 1. Redistributions of source code must retain the above copyright
11233294Sstas *    notice, this list of conditions and the following disclaimer.
12178825Sdfr *
13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright
14233294Sstas *    notice, this list of conditions and the following disclaimer in the
15233294Sstas *    documentation and/or other materials provided with the distribution.
16178825Sdfr *
17178825Sdfr * 3. Neither the name of KTH nor the names of its contributors may be
18178825Sdfr *    used to endorse or promote products derived from this software without
19178825Sdfr *    specific prior written permission.
20178825Sdfr *
21178825Sdfr * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
22178825Sdfr * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23178825Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24178825Sdfr * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
25178825Sdfr * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26178825Sdfr * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27178825Sdfr * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28178825Sdfr * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29178825Sdfr * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30178825Sdfr * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31178825Sdfr * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
32178825Sdfr
33178825Sdfr#include "krb5_locl.h"
34178825Sdfr#include <err.h>
35233294Sstas#include <getarg.h>
36178825Sdfr
37178825Sdfr/*
38178825Sdfr * Test that removal entry from of empty keytab doesn't corrupts
39178825Sdfr * memory.
40178825Sdfr */
41178825Sdfr
42178825Sdfrstatic void
43178825Sdfrtest_empty_keytab(krb5_context context, const char *keytab)
44178825Sdfr{
45178825Sdfr    krb5_error_code ret;
46178825Sdfr    krb5_keytab id;
47178825Sdfr    krb5_keytab_entry entry;
48178825Sdfr
49178825Sdfr    ret = krb5_kt_resolve(context, keytab, &id);
50178825Sdfr    if (ret)
51178825Sdfr	krb5_err(context, 1, ret, "krb5_kt_resolve");
52178825Sdfr
53178825Sdfr    memset(&entry, 0, sizeof(entry));
54178825Sdfr
55178825Sdfr    krb5_kt_remove_entry(context, id, &entry);
56178825Sdfr
57233294Sstas    ret = krb5_kt_have_content(context, id);
58233294Sstas    if (ret == 0)
59233294Sstas	krb5_errx(context, 1, "supposed to be empty keytab isn't");
60233294Sstas
61178825Sdfr    ret = krb5_kt_close(context, id);
62178825Sdfr    if (ret)
63178825Sdfr	krb5_err(context, 1, ret, "krb5_kt_close");
64178825Sdfr}
65178825Sdfr
66178825Sdfr/*
67178825Sdfr * Test that memory keytab are refcounted.
68178825Sdfr */
69178825Sdfr
70178825Sdfrstatic void
71178825Sdfrtest_memory_keytab(krb5_context context, const char *keytab, const char *keytab2)
72178825Sdfr{
73178825Sdfr    krb5_error_code ret;
74178825Sdfr    krb5_keytab id, id2, id3;
75178825Sdfr    krb5_keytab_entry entry, entry2, entry3;
76178825Sdfr
77178825Sdfr    ret = krb5_kt_resolve(context, keytab, &id);
78178825Sdfr    if (ret)
79178825Sdfr	krb5_err(context, 1, ret, "krb5_kt_resolve");
80178825Sdfr
81178825Sdfr    memset(&entry, 0, sizeof(entry));
82178825Sdfr    ret = krb5_parse_name(context, "lha@SU.SE", &entry.principal);
83178825Sdfr    if (ret)
84178825Sdfr	krb5_err(context, 1, ret, "krb5_parse_name");
85178825Sdfr    entry.vno = 1;
86178825Sdfr    ret = krb5_generate_random_keyblock(context,
87178825Sdfr					ETYPE_AES256_CTS_HMAC_SHA1_96,
88178825Sdfr					&entry.keyblock);
89178825Sdfr    if (ret)
90178825Sdfr	krb5_err(context, 1, ret, "krb5_generate_random_keyblock");
91178825Sdfr
92178825Sdfr    krb5_kt_add_entry(context, id, &entry);
93178825Sdfr
94178825Sdfr    ret = krb5_kt_resolve(context, keytab, &id2);
95178825Sdfr    if (ret)
96178825Sdfr	krb5_err(context, 1, ret, "krb5_kt_resolve");
97178825Sdfr
98178825Sdfr    ret = krb5_kt_get_entry(context, id,
99178825Sdfr			    entry.principal,
100178825Sdfr			    0,
101178825Sdfr			    ETYPE_AES256_CTS_HMAC_SHA1_96,
102178825Sdfr			    &entry2);
103178825Sdfr    if (ret)
104178825Sdfr	krb5_err(context, 1, ret, "krb5_kt_get_entry");
105178825Sdfr    krb5_kt_free_entry(context, &entry2);
106178825Sdfr
107178825Sdfr    ret = krb5_kt_close(context, id);
108178825Sdfr    if (ret)
109178825Sdfr	krb5_err(context, 1, ret, "krb5_kt_close");
110178825Sdfr
111178825Sdfr    ret = krb5_kt_get_entry(context, id2,
112178825Sdfr			    entry.principal,
113178825Sdfr			    0,
114178825Sdfr			    ETYPE_AES256_CTS_HMAC_SHA1_96,
115178825Sdfr			    &entry2);
116178825Sdfr    if (ret)
117178825Sdfr	krb5_err(context, 1, ret, "krb5_kt_get_entry");
118178825Sdfr    krb5_kt_free_entry(context, &entry2);
119178825Sdfr
120178825Sdfr    ret = krb5_kt_close(context, id2);
121178825Sdfr    if (ret)
122178825Sdfr	krb5_err(context, 1, ret, "krb5_kt_close");
123178825Sdfr
124178825Sdfr
125178825Sdfr    ret = krb5_kt_resolve(context, keytab2, &id3);
126178825Sdfr    if (ret)
127178825Sdfr	krb5_err(context, 1, ret, "krb5_kt_resolve");
128178825Sdfr
129178825Sdfr    memset(&entry3, 0, sizeof(entry3));
130178825Sdfr    ret = krb5_parse_name(context, "lha3@SU.SE", &entry3.principal);
131178825Sdfr    if (ret)
132178825Sdfr	krb5_err(context, 1, ret, "krb5_parse_name");
133178825Sdfr    entry3.vno = 1;
134178825Sdfr    ret = krb5_generate_random_keyblock(context,
135178825Sdfr					ETYPE_AES256_CTS_HMAC_SHA1_96,
136178825Sdfr					&entry3.keyblock);
137178825Sdfr    if (ret)
138178825Sdfr	krb5_err(context, 1, ret, "krb5_generate_random_keyblock");
139178825Sdfr
140178825Sdfr    krb5_kt_add_entry(context, id3, &entry3);
141178825Sdfr
142178825Sdfr
143178825Sdfr    ret = krb5_kt_resolve(context, keytab, &id);
144178825Sdfr    if (ret)
145178825Sdfr	krb5_err(context, 1, ret, "krb5_kt_resolve");
146178825Sdfr
147178825Sdfr    ret = krb5_kt_get_entry(context, id,
148178825Sdfr			    entry.principal,
149178825Sdfr			    0,
150178825Sdfr			    ETYPE_AES256_CTS_HMAC_SHA1_96,
151178825Sdfr			    &entry2);
152178825Sdfr    if (ret == 0)
153178825Sdfr	krb5_errx(context, 1, "krb5_kt_get_entry when if should fail");
154178825Sdfr
155178825Sdfr    krb5_kt_remove_entry(context, id, &entry);
156178825Sdfr
157178825Sdfr    ret = krb5_kt_close(context, id);
158178825Sdfr    if (ret)
159178825Sdfr	krb5_err(context, 1, ret, "krb5_kt_close");
160178825Sdfr
161178825Sdfr    krb5_kt_free_entry(context, &entry);
162178825Sdfr
163178825Sdfr    krb5_kt_remove_entry(context, id3, &entry3);
164178825Sdfr
165178825Sdfr    ret = krb5_kt_close(context, id3);
166178825Sdfr    if (ret)
167178825Sdfr	krb5_err(context, 1, ret, "krb5_kt_close");
168178825Sdfr
169178825Sdfr    krb5_free_principal(context, entry3.principal);
170178825Sdfr    krb5_free_keyblock_contents(context, &entry3.keyblock);
171178825Sdfr}
172178825Sdfr
173233294Sstasstatic void
174233294Sstasperf_add(krb5_context context, krb5_keytab id, int times)
175233294Sstas{
176233294Sstas}
177233294Sstas
178233294Sstasstatic void
179233294Sstasperf_find(krb5_context context, krb5_keytab id, int times)
180233294Sstas{
181233294Sstas}
182233294Sstas
183233294Sstasstatic void
184233294Sstasperf_delete(krb5_context context, krb5_keytab id, int forward, int times)
185233294Sstas{
186233294Sstas}
187233294Sstas
188233294Sstas
189233294Sstasstatic int version_flag = 0;
190233294Sstasstatic int help_flag	= 0;
191233294Sstasstatic char *perf_str   = NULL;
192233294Sstasstatic int times = 1000;
193233294Sstas
194233294Sstasstatic struct getargs args[] = {
195233294Sstas    {"performance",	0,	arg_string,	&perf_str,
196233294Sstas     "test performance for named keytab", "keytab" },
197233294Sstas    {"times",	0,	arg_integer,	&times,
198233294Sstas     "number of times to run the perforamce test", "number" },
199233294Sstas    {"version",	0,	arg_flag,	&version_flag,
200233294Sstas     "print version", NULL },
201233294Sstas    {"help",	0,	arg_flag,	&help_flag,
202233294Sstas     NULL, NULL }
203233294Sstas};
204233294Sstas
205233294Sstasstatic void
206233294Sstasusage (int ret)
207233294Sstas{
208233294Sstas    arg_printusage (args,
209233294Sstas		    sizeof(args)/sizeof(*args),
210233294Sstas		    NULL,
211233294Sstas		    "");
212233294Sstas    exit (ret);
213233294Sstas}
214233294Sstas
215178825Sdfrint
216178825Sdfrmain(int argc, char **argv)
217178825Sdfr{
218178825Sdfr    krb5_context context;
219178825Sdfr    krb5_error_code ret;
220233294Sstas    int optidx = 0;
221178825Sdfr
222178825Sdfr    setprogname(argv[0]);
223178825Sdfr
224233294Sstas    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
225233294Sstas	usage(1);
226233294Sstas
227233294Sstas    if (help_flag)
228233294Sstas	usage (0);
229233294Sstas
230233294Sstas    if(version_flag){
231233294Sstas	print_version(NULL);
232233294Sstas	exit(0);
233233294Sstas    }
234233294Sstas
235233294Sstas    argc -= optidx;
236233294Sstas    argv += optidx;
237233294Sstas
238233294Sstas    if (argc != 0)
239233294Sstas	errx(1, "argc != 0");
240233294Sstas
241178825Sdfr    ret = krb5_init_context(&context);
242178825Sdfr    if (ret)
243178825Sdfr	errx (1, "krb5_init_context failed: %d", ret);
244178825Sdfr
245233294Sstas    if (perf_str) {
246233294Sstas	krb5_keytab id;
247178825Sdfr
248233294Sstas	ret = krb5_kt_resolve(context, perf_str, &id);
249233294Sstas	if (ret)
250233294Sstas	    krb5_err(context, 1, ret, "krb5_kt_resolve: %s", perf_str);
251178825Sdfr
252233294Sstas	/* add, find, delete on keytab */
253233294Sstas	perf_add(context, id, times);
254233294Sstas	perf_find(context, id, times);
255233294Sstas	perf_delete(context, id, 0, times);
256233294Sstas
257233294Sstas	/* add and find again on used keytab */
258233294Sstas	perf_add(context, id, times);
259233294Sstas	perf_find(context, id, times);
260233294Sstas
261233294Sstas	ret = krb5_kt_destroy(context, id);
262233294Sstas	if (ret)
263233294Sstas	    krb5_err(context, 1, ret, "krb5_kt_destroy: %s", perf_str);
264233294Sstas
265233294Sstas	ret = krb5_kt_resolve(context, perf_str, &id);
266233294Sstas	if (ret)
267233294Sstas	    krb5_err(context, 1, ret, "krb5_kt_resolve: %s", perf_str);
268233294Sstas
269233294Sstas	/* try delete backwards */
270233294Sstas#if 0
271233294Sstas	perf_add(context, id, times);
272233294Sstas	perf_delete(context, id, 1, times);
273233294Sstas#endif
274233294Sstas
275233294Sstas	ret = krb5_kt_destroy(context, id);
276233294Sstas	if (ret)
277233294Sstas	    krb5_err(context, 1, ret, "krb5_kt_destroy");
278233294Sstas
279233294Sstas    } else {
280233294Sstas
281233294Sstas	test_empty_keytab(context, "MEMORY:foo");
282233294Sstas	test_empty_keytab(context, "FILE:foo");
283233294Sstas
284233294Sstas	test_memory_keytab(context, "MEMORY:foo", "MEMORY:foo2");
285233294Sstas
286233294Sstas    }
287233294Sstas
288178825Sdfr    krb5_free_context(context);
289178825Sdfr
290178825Sdfr    return 0;
291178825Sdfr}
292