1 /* 2 * Copyright (c) 2005 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of KTH nor the names of its contributors may be 18 * used to endorse or promote products derived from this software without 19 * specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY 22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE 25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 32 33 #include "krb5_locl.h" 34 #include <err.h> 35 #include <getarg.h> 36 37 /* 38 * Test that removal entry from of empty keytab doesn't corrupts 39 * memory. 40 */ 41 42 static void 43 test_empty_keytab(krb5_context context, const char *keytab) 44 { 45 krb5_error_code ret; 46 krb5_keytab id; 47 krb5_keytab_entry entry; 48 49 ret = krb5_kt_resolve(context, keytab, &id); 50 if (ret) 51 krb5_err(context, 1, ret, "krb5_kt_resolve"); 52 53 memset(&entry, 0, sizeof(entry)); 54 55 krb5_kt_remove_entry(context, id, &entry); 56 57 ret = krb5_kt_have_content(context, id); 58 if (ret == 0) 59 krb5_errx(context, 1, "supposed to be empty keytab isn't"); 60 61 ret = krb5_kt_close(context, id); 62 if (ret) 63 krb5_err(context, 1, ret, "krb5_kt_close"); 64 } 65 66 /* 67 * Test that memory keytab are refcounted. 68 */ 69 70 static void 71 test_memory_keytab(krb5_context context, const char *keytab, const char *keytab2) 72 { 73 krb5_error_code ret; 74 krb5_keytab id, id2, id3; 75 krb5_keytab_entry entry, entry2, entry3; 76 77 ret = krb5_kt_resolve(context, keytab, &id); 78 if (ret) 79 krb5_err(context, 1, ret, "krb5_kt_resolve"); 80 81 memset(&entry, 0, sizeof(entry)); 82 ret = krb5_parse_name(context, "lha@SU.SE", &entry.principal); 83 if (ret) 84 krb5_err(context, 1, ret, "krb5_parse_name"); 85 entry.vno = 1; 86 ret = krb5_generate_random_keyblock(context, 87 ETYPE_AES256_CTS_HMAC_SHA1_96, 88 &entry.keyblock); 89 if (ret) 90 krb5_err(context, 1, ret, "krb5_generate_random_keyblock"); 91 92 krb5_kt_add_entry(context, id, &entry); 93 94 ret = krb5_kt_resolve(context, keytab, &id2); 95 if (ret) 96 krb5_err(context, 1, ret, "krb5_kt_resolve"); 97 98 ret = krb5_kt_get_entry(context, id, 99 entry.principal, 100 0, 101 ETYPE_AES256_CTS_HMAC_SHA1_96, 102 &entry2); 103 if (ret) 104 krb5_err(context, 1, ret, "krb5_kt_get_entry"); 105 krb5_kt_free_entry(context, &entry2); 106 107 ret = krb5_kt_close(context, id); 108 if (ret) 109 krb5_err(context, 1, ret, "krb5_kt_close"); 110 111 ret = krb5_kt_get_entry(context, id2, 112 entry.principal, 113 0, 114 ETYPE_AES256_CTS_HMAC_SHA1_96, 115 &entry2); 116 if (ret) 117 krb5_err(context, 1, ret, "krb5_kt_get_entry"); 118 krb5_kt_free_entry(context, &entry2); 119 120 ret = krb5_kt_close(context, id2); 121 if (ret) 122 krb5_err(context, 1, ret, "krb5_kt_close"); 123 124 125 ret = krb5_kt_resolve(context, keytab2, &id3); 126 if (ret) 127 krb5_err(context, 1, ret, "krb5_kt_resolve"); 128 129 memset(&entry3, 0, sizeof(entry3)); 130 ret = krb5_parse_name(context, "lha3@SU.SE", &entry3.principal); 131 if (ret) 132 krb5_err(context, 1, ret, "krb5_parse_name"); 133 entry3.vno = 1; 134 ret = krb5_generate_random_keyblock(context, 135 ETYPE_AES256_CTS_HMAC_SHA1_96, 136 &entry3.keyblock); 137 if (ret) 138 krb5_err(context, 1, ret, "krb5_generate_random_keyblock"); 139 140 krb5_kt_add_entry(context, id3, &entry3); 141 142 143 ret = krb5_kt_resolve(context, keytab, &id); 144 if (ret) 145 krb5_err(context, 1, ret, "krb5_kt_resolve"); 146 147 ret = krb5_kt_get_entry(context, id, 148 entry.principal, 149 0, 150 ETYPE_AES256_CTS_HMAC_SHA1_96, 151 &entry2); 152 if (ret == 0) 153 krb5_errx(context, 1, "krb5_kt_get_entry when if should fail"); 154 155 krb5_kt_remove_entry(context, id, &entry); 156 157 ret = krb5_kt_close(context, id); 158 if (ret) 159 krb5_err(context, 1, ret, "krb5_kt_close"); 160 161 krb5_kt_free_entry(context, &entry); 162 163 krb5_kt_remove_entry(context, id3, &entry3); 164 165 ret = krb5_kt_close(context, id3); 166 if (ret) 167 krb5_err(context, 1, ret, "krb5_kt_close"); 168 169 krb5_free_principal(context, entry3.principal); 170 krb5_free_keyblock_contents(context, &entry3.keyblock); 171 } 172 173 static void 174 perf_add(krb5_context context, krb5_keytab id, int times) 175 { 176 } 177 178 static void 179 perf_find(krb5_context context, krb5_keytab id, int times) 180 { 181 } 182 183 static void 184 perf_delete(krb5_context context, krb5_keytab id, int forward, int times) 185 { 186 } 187 188 189 static int version_flag = 0; 190 static int help_flag = 0; 191 static char *perf_str = NULL; 192 static int times = 1000; 193 194 static struct getargs args[] = { 195 {"performance", 0, arg_string, &perf_str, 196 "test performance for named keytab", "keytab" }, 197 {"times", 0, arg_integer, ×, 198 "number of times to run the perforamce test", "number" }, 199 {"version", 0, arg_flag, &version_flag, 200 "print version", NULL }, 201 {"help", 0, arg_flag, &help_flag, 202 NULL, NULL } 203 }; 204 205 static void 206 usage (int ret) 207 { 208 arg_printusage (args, 209 sizeof(args)/sizeof(*args), 210 NULL, 211 ""); 212 exit (ret); 213 } 214 215 int 216 main(int argc, char **argv) 217 { 218 krb5_context context; 219 krb5_error_code ret; 220 int optidx = 0; 221 222 setprogname(argv[0]); 223 224 if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) 225 usage(1); 226 227 if (help_flag) 228 usage (0); 229 230 if(version_flag){ 231 print_version(NULL); 232 exit(0); 233 } 234 235 argc -= optidx; 236 argv += optidx; 237 238 if (argc != 0) 239 errx(1, "argc != 0"); 240 241 ret = krb5_init_context(&context); 242 if (ret) 243 errx (1, "krb5_init_context failed: %d", ret); 244 245 if (perf_str) { 246 krb5_keytab id; 247 248 ret = krb5_kt_resolve(context, perf_str, &id); 249 if (ret) 250 krb5_err(context, 1, ret, "krb5_kt_resolve: %s", perf_str); 251 252 /* add, find, delete on keytab */ 253 perf_add(context, id, times); 254 perf_find(context, id, times); 255 perf_delete(context, id, 0, times); 256 257 /* add and find again on used keytab */ 258 perf_add(context, id, times); 259 perf_find(context, id, times); 260 261 ret = krb5_kt_destroy(context, id); 262 if (ret) 263 krb5_err(context, 1, ret, "krb5_kt_destroy: %s", perf_str); 264 265 ret = krb5_kt_resolve(context, perf_str, &id); 266 if (ret) 267 krb5_err(context, 1, ret, "krb5_kt_resolve: %s", perf_str); 268 269 /* try delete backwards */ 270 #if 0 271 perf_add(context, id, times); 272 perf_delete(context, id, 1, times); 273 #endif 274 275 ret = krb5_kt_destroy(context, id); 276 if (ret) 277 krb5_err(context, 1, ret, "krb5_kt_destroy"); 278 279 } else { 280 281 test_empty_keytab(context, "MEMORY:foo"); 282 test_empty_keytab(context, "FILE:foo"); 283 284 test_memory_keytab(context, "MEMORY:foo", "MEMORY:foo2"); 285 286 } 287 288 krb5_free_context(context); 289 290 return 0; 291 } 292