1 /* $NetBSD: test_keytab.c,v 1.1.1.2 2014/04/24 12:45:51 pettai 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, ×, 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