Home | History | Annotate | Line # | Download | only in krb5
      1 /*	$NetBSD: test_keytab.c,v 1.2 2017/01/28 21:31:49 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2005 Kungliga Tekniska Hgskolan
      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 (at) 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 (at) 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