1/* 2 * Copyright (c) 2000 - 2001, 2009 Kungliga Tekniska H�gskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Portions Copyright (c) 2010 Apple Inc. 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 <getarg.h> 38 39static char *password_str = NULL; 40static char *client_str = NULL; 41static char *fuzzer_mode = NULL; 42static int timer_mode = 0; 43static int debug_flag = 0; 44static int do_lr_flag = 0; 45static int version_flag = 0; 46static int help_flag = 0; 47 48static void 49tvfix(struct timeval *t1) 50{ 51 if (t1->tv_usec < 0) { 52 t1->tv_sec--; 53 t1->tv_usec += 1000000; 54 } 55 if (t1->tv_usec >= 1000000) { 56 t1->tv_sec++; 57 t1->tv_usec -= 1000000; 58 } 59} 60 61/* 62 * t1 -= t2 63 */ 64 65static void 66tvsub(struct timeval *t1, const struct timeval *t2) 67{ 68 t1->tv_sec -= t2->tv_sec; 69 t1->tv_usec -= t2->tv_usec; 70 tvfix(t1); 71} 72 73static krb5_error_code 74lr_proc(krb5_context context, krb5_last_req_entry **e, void *ctx) 75{ 76 while (e && *e) { 77 printf("e type: %d value: %d\n", (*e)->lr_type, (int)(*e)->value); 78 e++; 79 } 80 return 0; 81} 82 83static krb5_error_code 84test_get_init_creds(krb5_context context, 85 krb5_principal client) 86{ 87 krb5_error_code ret; 88 krb5_get_init_creds_opt *opt; 89 krb5_creds cred; 90 91 ret = krb5_get_init_creds_opt_alloc(context, &opt); 92 if (ret) 93 krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc"); 94 95 if (do_lr_flag) { 96 ret = krb5_get_init_creds_opt_set_process_last_req(context, 97 opt, 98 lr_proc, 99 NULL); 100 if (ret) 101 krb5_err(context, 1, ret, 102 "krb5_get_init_creds_opt_set_process_last_req"); 103 } 104 105 ret = krb5_get_init_creds_password(context, 106 &cred, 107 client, 108 password_str, 109 krb5_prompter_posix, 110 NULL, 111 0, 112 NULL, 113 opt); 114 if (ret) 115 krb5_warn(context, ret, "krb5_get_init_creds_password"); 116 117 krb5_get_init_creds_opt_free(context, opt); 118 return ret; 119} 120 121static struct getargs args[] = { 122 {"client", 0, arg_string, &client_str, 123 "client principal to use", NULL }, 124 {"password",0, arg_string, &password_str, 125 "password", NULL }, 126 {"fuzzer",0, arg_string, &fuzzer_mode, 127 "turn on asn1 fuzzer, select mode", NULL }, 128 {"timer",0, arg_flag, &timer_mode, 129 "timer (benchmark) mode", NULL }, 130 {"debug", 'd', arg_flag, &debug_flag, 131 "turn on debuggin", NULL }, 132 {"last-request", 0, arg_flag, &do_lr_flag, 133 "print version", NULL }, 134 {"version", 0, arg_flag, &version_flag, 135 "print version", NULL }, 136 {"help", 0, arg_flag, &help_flag, 137 NULL, NULL } 138}; 139 140static void 141usage (int ret) 142{ 143 arg_printusage (args, sizeof(args)/sizeof(*args), NULL, "hostname ..."); 144 exit (ret); 145} 146 147 148int 149main(int argc, char **argv) 150{ 151 krb5_context context; 152 krb5_error_code ret; 153 int optidx = 0, errors = 0; 154 krb5_principal client; 155 156 setprogname(argv[0]); 157 158 if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) 159 usage(1); 160 161 if (help_flag) 162 usage (0); 163 164 if(version_flag){ 165 print_version(NULL); 166 exit(0); 167 } 168 169 if(client_str == NULL) 170 errx(1, "client is not set"); 171 172 ret = krb5_init_context(&context); 173 if (ret) 174 errx (1, "krb5_init_context failed: %d", ret); 175 176 ret = krb5_parse_name(context, client_str, &client); 177 if (ret) 178 krb5_err(context, 1, ret, "krb5_parse_name: %d", ret); 179 180 if (timer_mode) { 181 unsigned long n; 182 struct timeval tv1, tv2; 183 184 if (password_str == NULL) 185 errx(1, "password-less mode is not support with fuzzer"); 186 187 gettimeofday(&tv1, NULL); 188 189 for (n = 0; n < 1000; n++) { 190 if (test_get_init_creds(context, client)) 191 errors++; 192 } 193 194 gettimeofday(&tv2, NULL); 195 196 tvsub(&tv2, &tv1); 197 198 printf("timing: %ld.%06ld\n", 199 (long)tv2.tv_sec, (long)tv2.tv_usec); 200 201 } else if (fuzzer_mode) { 202 unsigned long u = 0; 203 204 if (password_str == NULL) 205 errx(1, "password-less mode is not support with fuzzer"); 206 207 if (asn1_fuzzer_method(fuzzer_mode)) 208 errx(1, "no fuzzer support"); 209 210 asn1_fuzzer_reset(); 211 212 do { 213 asn1_fuzzer_next(); 214 215 if (debug_flag) 216 printf("request... %lu\n", u++); 217 218 /* ignore failure when we run fuzzer */ 219 (void)test_get_init_creds(context, client); 220 221 } while(!asn1_fuzzer_done()); 222 223 224 } else { 225 if (test_get_init_creds(context, client)) 226 errors++; 227 } 228 229 krb5_free_context(context); 230 231 return errors; 232} 233