1*7f2fe78bSCy Schubert /* tests/hammer/kdc5_hammer.c */
2*7f2fe78bSCy Schubert /*
3*7f2fe78bSCy Schubert * Copyright 1990,1991 by the Massachusetts Institute of Technology.
4*7f2fe78bSCy Schubert * All Rights Reserved.
5*7f2fe78bSCy Schubert *
6*7f2fe78bSCy Schubert * Export of this software from the United States of America may
7*7f2fe78bSCy Schubert * require a specific license from the United States Government.
8*7f2fe78bSCy Schubert * It is the responsibility of any person or organization contemplating
9*7f2fe78bSCy Schubert * export to obtain such a license before exporting.
10*7f2fe78bSCy Schubert *
11*7f2fe78bSCy Schubert * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
12*7f2fe78bSCy Schubert * distribute this software and its documentation for any purpose and
13*7f2fe78bSCy Schubert * without fee is hereby granted, provided that the above copyright
14*7f2fe78bSCy Schubert * notice appear in all copies and that both that copyright notice and
15*7f2fe78bSCy Schubert * this permission notice appear in supporting documentation, and that
16*7f2fe78bSCy Schubert * the name of M.I.T. not be used in advertising or publicity pertaining
17*7f2fe78bSCy Schubert * to distribution of the software without specific, written prior
18*7f2fe78bSCy Schubert * permission. Furthermore if you modify this software you must label
19*7f2fe78bSCy Schubert * your software as modified software and not distribute it in such a
20*7f2fe78bSCy Schubert * fashion that it might be confused with the original M.I.T. software.
21*7f2fe78bSCy Schubert * M.I.T. makes no representations about the suitability of
22*7f2fe78bSCy Schubert * this software for any purpose. It is provided "as is" without express
23*7f2fe78bSCy Schubert * or implied warranty.
24*7f2fe78bSCy Schubert */
25*7f2fe78bSCy Schubert
26*7f2fe78bSCy Schubert #include "k5-int.h"
27*7f2fe78bSCy Schubert #include "com_err.h"
28*7f2fe78bSCy Schubert #include <sys/time.h>
29*7f2fe78bSCy Schubert
30*7f2fe78bSCy Schubert #define KRB5_DEFAULT_OPTIONS 0
31*7f2fe78bSCy Schubert #define KRB5_DEFAULT_LIFE 60*60*8 /* 8 hours */
32*7f2fe78bSCy Schubert #define KRB5_RENEWABLE_LIFE 60*60*2 /* 2 hours */
33*7f2fe78bSCy Schubert
34*7f2fe78bSCy Schubert struct h_timer {
35*7f2fe78bSCy Schubert float ht_cumulative;
36*7f2fe78bSCy Schubert float ht_min;
37*7f2fe78bSCy Schubert float ht_max;
38*7f2fe78bSCy Schubert krb5_int32 ht_observations;
39*7f2fe78bSCy Schubert };
40*7f2fe78bSCy Schubert
41*7f2fe78bSCy Schubert extern int optind;
42*7f2fe78bSCy Schubert extern char *optarg;
43*7f2fe78bSCy Schubert char *prog;
44*7f2fe78bSCy Schubert
45*7f2fe78bSCy Schubert static int brief;
46*7f2fe78bSCy Schubert static char *cur_realm = 0;
47*7f2fe78bSCy Schubert static int do_timer = 0;
48*7f2fe78bSCy Schubert
49*7f2fe78bSCy Schubert krb5_data tgtname = {
50*7f2fe78bSCy Schubert 0,
51*7f2fe78bSCy Schubert KRB5_TGS_NAME_SIZE,
52*7f2fe78bSCy Schubert KRB5_TGS_NAME
53*7f2fe78bSCy Schubert };
54*7f2fe78bSCy Schubert
55*7f2fe78bSCy Schubert int verify_cs_pair
56*7f2fe78bSCy Schubert (krb5_context,
57*7f2fe78bSCy Schubert char *,
58*7f2fe78bSCy Schubert krb5_principal,
59*7f2fe78bSCy Schubert char *,
60*7f2fe78bSCy Schubert char *,
61*7f2fe78bSCy Schubert int, int, int,
62*7f2fe78bSCy Schubert krb5_ccache);
63*7f2fe78bSCy Schubert
64*7f2fe78bSCy Schubert int get_tgt
65*7f2fe78bSCy Schubert (krb5_context,
66*7f2fe78bSCy Schubert char *,
67*7f2fe78bSCy Schubert krb5_principal *,
68*7f2fe78bSCy Schubert krb5_ccache);
69*7f2fe78bSCy Schubert
70*7f2fe78bSCy Schubert static void
usage(who,status)71*7f2fe78bSCy Schubert usage(who, status)
72*7f2fe78bSCy Schubert char *who;
73*7f2fe78bSCy Schubert int status;
74*7f2fe78bSCy Schubert {
75*7f2fe78bSCy Schubert fprintf(stderr,
76*7f2fe78bSCy Schubert "usage: %s -p prefix -n num_to_check [-c cachename] [-r realmname]\n",
77*7f2fe78bSCy Schubert who);
78*7f2fe78bSCy Schubert fprintf(stderr, "\t [-D depth]\n");
79*7f2fe78bSCy Schubert fprintf(stderr, "\t [-P preauth type] [-R repeat_count] [-t] [-b] [-v] \n");
80*7f2fe78bSCy Schubert
81*7f2fe78bSCy Schubert exit(status);
82*7f2fe78bSCy Schubert }
83*7f2fe78bSCy Schubert
84*7f2fe78bSCy Schubert static krb5_preauthtype * patype = NULL, patypedata[2] = { 0, -1 };
85*7f2fe78bSCy Schubert static krb5_context test_context;
86*7f2fe78bSCy Schubert
87*7f2fe78bSCy Schubert struct timeval tstart_time, tend_time;
88*7f2fe78bSCy Schubert struct timezone dontcare;
89*7f2fe78bSCy Schubert
90*7f2fe78bSCy Schubert struct h_timer in_tkt_times = { 0.0, 1000000.0, -1.0, 0 };
91*7f2fe78bSCy Schubert struct h_timer tgs_req_times = { 0.0, 1000000.0, -1.0, 0 };
92*7f2fe78bSCy Schubert /*
93*7f2fe78bSCy Schubert * Timer macros.
94*7f2fe78bSCy Schubert */
95*7f2fe78bSCy Schubert #define swatch_on() ((void) gettimeofday(&tstart_time, &dontcare))
96*7f2fe78bSCy Schubert #define swatch_eltime() ((gettimeofday(&tend_time, &dontcare)) ? -1.0 : \
97*7f2fe78bSCy Schubert (((float) (tend_time.tv_sec - \
98*7f2fe78bSCy Schubert tstart_time.tv_sec)) + \
99*7f2fe78bSCy Schubert (((float) (tend_time.tv_usec - \
100*7f2fe78bSCy Schubert tstart_time.tv_usec))/1000000.0)))
101*7f2fe78bSCy Schubert
102*7f2fe78bSCy Schubert int
main(argc,argv)103*7f2fe78bSCy Schubert main(argc, argv)
104*7f2fe78bSCy Schubert int argc;
105*7f2fe78bSCy Schubert char **argv;
106*7f2fe78bSCy Schubert {
107*7f2fe78bSCy Schubert krb5_ccache ccache = NULL;
108*7f2fe78bSCy Schubert char *cache_name = NULL; /* -f option */
109*7f2fe78bSCy Schubert int option;
110*7f2fe78bSCy Schubert int errflg = 0;
111*7f2fe78bSCy Schubert krb5_error_code code;
112*7f2fe78bSCy Schubert int num_to_check, n, i, j, repeat_count, counter;
113*7f2fe78bSCy Schubert int n_tried, errors;
114*7f2fe78bSCy Schubert char prefix[BUFSIZ], client[4096], server[4096];
115*7f2fe78bSCy Schubert int depth;
116*7f2fe78bSCy Schubert char ctmp[4096], ctmp2[BUFSIZ], stmp[4096], stmp2[BUFSIZ];
117*7f2fe78bSCy Schubert krb5_principal client_princ;
118*7f2fe78bSCy Schubert krb5_error_code retval;
119*7f2fe78bSCy Schubert
120*7f2fe78bSCy Schubert krb5_init_context(&test_context);
121*7f2fe78bSCy Schubert
122*7f2fe78bSCy Schubert if (strrchr(argv[0], '/'))
123*7f2fe78bSCy Schubert prog = strrchr(argv[0], '/')+1;
124*7f2fe78bSCy Schubert else
125*7f2fe78bSCy Schubert prog = argv[0];
126*7f2fe78bSCy Schubert
127*7f2fe78bSCy Schubert num_to_check = 0;
128*7f2fe78bSCy Schubert depth = 1;
129*7f2fe78bSCy Schubert repeat_count = 1;
130*7f2fe78bSCy Schubert brief = 0;
131*7f2fe78bSCy Schubert n_tried = 0;
132*7f2fe78bSCy Schubert errors = 0;
133*7f2fe78bSCy Schubert
134*7f2fe78bSCy Schubert while ((option = getopt(argc, argv, "D:p:n:c:R:P:e:bvr:t")) != -1) {
135*7f2fe78bSCy Schubert switch (option) {
136*7f2fe78bSCy Schubert case 't':
137*7f2fe78bSCy Schubert do_timer = 1;
138*7f2fe78bSCy Schubert break;
139*7f2fe78bSCy Schubert case 'b':
140*7f2fe78bSCy Schubert brief = 1;
141*7f2fe78bSCy Schubert break;
142*7f2fe78bSCy Schubert case 'v':
143*7f2fe78bSCy Schubert brief = 0;
144*7f2fe78bSCy Schubert break;
145*7f2fe78bSCy Schubert case 'R':
146*7f2fe78bSCy Schubert repeat_count = atoi(optarg); /* how many times? */
147*7f2fe78bSCy Schubert break;
148*7f2fe78bSCy Schubert case 'r':
149*7f2fe78bSCy Schubert cur_realm = optarg;
150*7f2fe78bSCy Schubert break;
151*7f2fe78bSCy Schubert case 'D':
152*7f2fe78bSCy Schubert depth = atoi(optarg); /* how deep to go */
153*7f2fe78bSCy Schubert break;
154*7f2fe78bSCy Schubert case 'p': /* prefix name to check */
155*7f2fe78bSCy Schubert strncpy(prefix, optarg, sizeof(prefix) - 1);
156*7f2fe78bSCy Schubert prefix[sizeof(prefix) - 1] = '\0';
157*7f2fe78bSCy Schubert break;
158*7f2fe78bSCy Schubert case 'n': /* how many to check */
159*7f2fe78bSCy Schubert num_to_check = atoi(optarg);
160*7f2fe78bSCy Schubert break;
161*7f2fe78bSCy Schubert case 'P':
162*7f2fe78bSCy Schubert patypedata[0] = atoi(optarg);
163*7f2fe78bSCy Schubert patype = patypedata;
164*7f2fe78bSCy Schubert break;
165*7f2fe78bSCy Schubert case 'c':
166*7f2fe78bSCy Schubert if (ccache == NULL) {
167*7f2fe78bSCy Schubert cache_name = optarg;
168*7f2fe78bSCy Schubert
169*7f2fe78bSCy Schubert code = krb5_cc_resolve (test_context, cache_name, &ccache);
170*7f2fe78bSCy Schubert if (code != 0) {
171*7f2fe78bSCy Schubert com_err (prog, code, "resolving %s", cache_name);
172*7f2fe78bSCy Schubert errflg++;
173*7f2fe78bSCy Schubert }
174*7f2fe78bSCy Schubert } else {
175*7f2fe78bSCy Schubert fprintf(stderr, "Only one -c option allowed\n");
176*7f2fe78bSCy Schubert errflg++;
177*7f2fe78bSCy Schubert }
178*7f2fe78bSCy Schubert break;
179*7f2fe78bSCy Schubert case '?':
180*7f2fe78bSCy Schubert default:
181*7f2fe78bSCy Schubert errflg++;
182*7f2fe78bSCy Schubert break;
183*7f2fe78bSCy Schubert }
184*7f2fe78bSCy Schubert }
185*7f2fe78bSCy Schubert
186*7f2fe78bSCy Schubert if (!(num_to_check && prefix[0])) usage(prog, 1);
187*7f2fe78bSCy Schubert
188*7f2fe78bSCy Schubert if (!cur_realm) {
189*7f2fe78bSCy Schubert if ((retval = krb5_get_default_realm(test_context, &cur_realm))) {
190*7f2fe78bSCy Schubert com_err(prog, retval, "while retrieving default realm name");
191*7f2fe78bSCy Schubert exit(1);
192*7f2fe78bSCy Schubert }
193*7f2fe78bSCy Schubert }
194*7f2fe78bSCy Schubert
195*7f2fe78bSCy Schubert if (ccache == NULL) {
196*7f2fe78bSCy Schubert if ((code = krb5_cc_default(test_context, &ccache))) {
197*7f2fe78bSCy Schubert com_err(prog, code, "while getting default ccache");
198*7f2fe78bSCy Schubert exit(1);
199*7f2fe78bSCy Schubert }
200*7f2fe78bSCy Schubert }
201*7f2fe78bSCy Schubert
202*7f2fe78bSCy Schubert memset(ctmp, 0, sizeof(ctmp));
203*7f2fe78bSCy Schubert memset(stmp, 0, sizeof(stmp));
204*7f2fe78bSCy Schubert
205*7f2fe78bSCy Schubert for (counter = 0; counter < repeat_count; counter++) {
206*7f2fe78bSCy Schubert fprintf(stderr, "\nRound %d\n", counter);
207*7f2fe78bSCy Schubert
208*7f2fe78bSCy Schubert for (n = 1; n <= num_to_check; n++) {
209*7f2fe78bSCy Schubert /* build the new principal name */
210*7f2fe78bSCy Schubert /* we can't pick random names because we need to generate all the names
211*7f2fe78bSCy Schubert again given a prefix and count to test the db lib and kdb */
212*7f2fe78bSCy Schubert ctmp[0] = '\0';
213*7f2fe78bSCy Schubert for (i = 1; i <= depth; i++) {
214*7f2fe78bSCy Schubert (void) snprintf(ctmp2, sizeof(ctmp2), "%s%s%d-DEPTH-%d",
215*7f2fe78bSCy Schubert (i != 1) ? "/" : "", prefix, n, i);
216*7f2fe78bSCy Schubert ctmp2[sizeof(ctmp2) - 1] = '\0';
217*7f2fe78bSCy Schubert strncat(ctmp, ctmp2, sizeof(ctmp) - 1 - strlen(ctmp));
218*7f2fe78bSCy Schubert ctmp[sizeof(ctmp) - 1] = '\0';
219*7f2fe78bSCy Schubert snprintf(client, sizeof(client), "%s@%s", ctmp, cur_realm);
220*7f2fe78bSCy Schubert
221*7f2fe78bSCy Schubert if (get_tgt (test_context, client, &client_princ, ccache)) {
222*7f2fe78bSCy Schubert errors++;
223*7f2fe78bSCy Schubert n_tried++;
224*7f2fe78bSCy Schubert continue;
225*7f2fe78bSCy Schubert }
226*7f2fe78bSCy Schubert n_tried++;
227*7f2fe78bSCy Schubert
228*7f2fe78bSCy Schubert stmp[0] = '\0';
229*7f2fe78bSCy Schubert for (j = 1; j <= depth; j++) {
230*7f2fe78bSCy Schubert (void) snprintf(stmp2, sizeof(stmp2), "%s%s%d-DEPTH-%d",
231*7f2fe78bSCy Schubert (j != 1) ? "/" : "", prefix, n, j);
232*7f2fe78bSCy Schubert stmp2[sizeof (stmp2) - 1] = '\0';
233*7f2fe78bSCy Schubert strncat(stmp, stmp2, sizeof(stmp) - 1 - strlen(stmp));
234*7f2fe78bSCy Schubert stmp[sizeof(stmp) - 1] = '\0';
235*7f2fe78bSCy Schubert snprintf(server, sizeof(server), "%s@%s", stmp, cur_realm);
236*7f2fe78bSCy Schubert if (verify_cs_pair(test_context, client, client_princ,
237*7f2fe78bSCy Schubert stmp, cur_realm, n, i, j, ccache))
238*7f2fe78bSCy Schubert errors++;
239*7f2fe78bSCy Schubert n_tried++;
240*7f2fe78bSCy Schubert }
241*7f2fe78bSCy Schubert krb5_free_principal(test_context, client_princ);
242*7f2fe78bSCy Schubert }
243*7f2fe78bSCy Schubert }
244*7f2fe78bSCy Schubert }
245*7f2fe78bSCy Schubert fprintf (stderr, "\nTried %d. Got %d errors.\n", n_tried, errors);
246*7f2fe78bSCy Schubert if (do_timer) {
247*7f2fe78bSCy Schubert if (in_tkt_times.ht_observations)
248*7f2fe78bSCy Schubert fprintf(stderr,
249*7f2fe78bSCy Schubert "%8d AS_REQ requests: %9.6f average (min: %9.6f, max:%9.6f)\n",
250*7f2fe78bSCy Schubert in_tkt_times.ht_observations,
251*7f2fe78bSCy Schubert in_tkt_times.ht_cumulative /
252*7f2fe78bSCy Schubert (float) in_tkt_times.ht_observations,
253*7f2fe78bSCy Schubert in_tkt_times.ht_min,
254*7f2fe78bSCy Schubert in_tkt_times.ht_max);
255*7f2fe78bSCy Schubert if (tgs_req_times.ht_observations)
256*7f2fe78bSCy Schubert fprintf(stderr,
257*7f2fe78bSCy Schubert "%8d TGS_REQ requests: %9.6f average (min: %9.6f, max:%9.6f)\n",
258*7f2fe78bSCy Schubert tgs_req_times.ht_observations,
259*7f2fe78bSCy Schubert tgs_req_times.ht_cumulative /
260*7f2fe78bSCy Schubert (float) tgs_req_times.ht_observations,
261*7f2fe78bSCy Schubert tgs_req_times.ht_min,
262*7f2fe78bSCy Schubert tgs_req_times.ht_max);
263*7f2fe78bSCy Schubert }
264*7f2fe78bSCy Schubert
265*7f2fe78bSCy Schubert (void) krb5_cc_close(test_context, ccache);
266*7f2fe78bSCy Schubert
267*7f2fe78bSCy Schubert krb5_free_context(test_context);
268*7f2fe78bSCy Schubert
269*7f2fe78bSCy Schubert exit(errors);
270*7f2fe78bSCy Schubert }
271*7f2fe78bSCy Schubert
272*7f2fe78bSCy Schubert
273*7f2fe78bSCy Schubert static krb5_error_code
get_server_key(context,server,enctype,key)274*7f2fe78bSCy Schubert get_server_key(context, server, enctype, key)
275*7f2fe78bSCy Schubert krb5_context context;
276*7f2fe78bSCy Schubert krb5_principal server;
277*7f2fe78bSCy Schubert krb5_enctype enctype;
278*7f2fe78bSCy Schubert krb5_keyblock ** key;
279*7f2fe78bSCy Schubert {
280*7f2fe78bSCy Schubert krb5_error_code retval;
281*7f2fe78bSCy Schubert krb5_encrypt_block eblock;
282*7f2fe78bSCy Schubert char * string;
283*7f2fe78bSCy Schubert krb5_data salt;
284*7f2fe78bSCy Schubert krb5_data pwd;
285*7f2fe78bSCy Schubert
286*7f2fe78bSCy Schubert *key = NULL;
287*7f2fe78bSCy Schubert
288*7f2fe78bSCy Schubert if ((retval = krb5_principal2salt(context, server, &salt)))
289*7f2fe78bSCy Schubert return retval;
290*7f2fe78bSCy Schubert
291*7f2fe78bSCy Schubert if ((retval = krb5_unparse_name(context, server, &string)))
292*7f2fe78bSCy Schubert goto cleanup_salt;
293*7f2fe78bSCy Schubert
294*7f2fe78bSCy Schubert pwd.data = string;
295*7f2fe78bSCy Schubert pwd.length = strlen(string);
296*7f2fe78bSCy Schubert
297*7f2fe78bSCy Schubert if ((*key = (krb5_keyblock *)malloc(sizeof(krb5_keyblock)))) {
298*7f2fe78bSCy Schubert krb5_use_enctype(context, &eblock, enctype);
299*7f2fe78bSCy Schubert retval = krb5_string_to_key(context, &eblock, *key, &pwd, &salt);
300*7f2fe78bSCy Schubert if (retval) {
301*7f2fe78bSCy Schubert free(*key);
302*7f2fe78bSCy Schubert *key = NULL;
303*7f2fe78bSCy Schubert }
304*7f2fe78bSCy Schubert } else
305*7f2fe78bSCy Schubert retval = ENOMEM;
306*7f2fe78bSCy Schubert
307*7f2fe78bSCy Schubert free(string);
308*7f2fe78bSCy Schubert
309*7f2fe78bSCy Schubert cleanup_salt:
310*7f2fe78bSCy Schubert free(salt.data);
311*7f2fe78bSCy Schubert return retval;
312*7f2fe78bSCy Schubert }
313*7f2fe78bSCy Schubert
verify_cs_pair(context,p_client_str,p_client,service,hostname,p_num,c_depth,s_depth,ccache)314*7f2fe78bSCy Schubert int verify_cs_pair(context, p_client_str, p_client, service, hostname,
315*7f2fe78bSCy Schubert p_num, c_depth, s_depth, ccache)
316*7f2fe78bSCy Schubert krb5_context context;
317*7f2fe78bSCy Schubert char *p_client_str;
318*7f2fe78bSCy Schubert krb5_principal p_client;
319*7f2fe78bSCy Schubert char * service;
320*7f2fe78bSCy Schubert char * hostname;
321*7f2fe78bSCy Schubert int p_num, c_depth, s_depth;
322*7f2fe78bSCy Schubert krb5_ccache ccache;
323*7f2fe78bSCy Schubert {
324*7f2fe78bSCy Schubert krb5_error_code retval;
325*7f2fe78bSCy Schubert krb5_creds creds;
326*7f2fe78bSCy Schubert krb5_creds * credsp = NULL;
327*7f2fe78bSCy Schubert krb5_ticket * ticket = NULL;
328*7f2fe78bSCy Schubert krb5_keyblock * keyblock = NULL;
329*7f2fe78bSCy Schubert krb5_auth_context auth_context = NULL;
330*7f2fe78bSCy Schubert krb5_data request_data = empty_data();
331*7f2fe78bSCy Schubert char * sname;
332*7f2fe78bSCy Schubert float dt;
333*7f2fe78bSCy Schubert
334*7f2fe78bSCy Schubert if (brief)
335*7f2fe78bSCy Schubert fprintf(stderr, "\tprinc (%d) client (%d) for server (%d)\n",
336*7f2fe78bSCy Schubert p_num, c_depth, s_depth);
337*7f2fe78bSCy Schubert else
338*7f2fe78bSCy Schubert fprintf(stderr, "\tclient %s for server %s\n", p_client_str,
339*7f2fe78bSCy Schubert service);
340*7f2fe78bSCy Schubert
341*7f2fe78bSCy Schubert /* Initialize variables */
342*7f2fe78bSCy Schubert memset(&creds, 0, sizeof(creds));
343*7f2fe78bSCy Schubert
344*7f2fe78bSCy Schubert /* Do client side */
345*7f2fe78bSCy Schubert if (asprintf(&sname, "%s@%s", service, hostname) >= 0) {
346*7f2fe78bSCy Schubert retval = krb5_parse_name(context, sname, &creds.server);
347*7f2fe78bSCy Schubert free(sname);
348*7f2fe78bSCy Schubert }
349*7f2fe78bSCy Schubert else
350*7f2fe78bSCy Schubert retval = ENOMEM;
351*7f2fe78bSCy Schubert if (retval)
352*7f2fe78bSCy Schubert return(retval);
353*7f2fe78bSCy Schubert
354*7f2fe78bSCy Schubert /* obtain ticket & session key */
355*7f2fe78bSCy Schubert if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) {
356*7f2fe78bSCy Schubert com_err(prog, retval, "while getting client princ for %s", hostname);
357*7f2fe78bSCy Schubert return retval;
358*7f2fe78bSCy Schubert }
359*7f2fe78bSCy Schubert
360*7f2fe78bSCy Schubert if ((retval = krb5_get_credentials(context, 0,
361*7f2fe78bSCy Schubert ccache, &creds, &credsp))) {
362*7f2fe78bSCy Schubert com_err(prog, retval, "while getting creds for %s", hostname);
363*7f2fe78bSCy Schubert return retval;
364*7f2fe78bSCy Schubert }
365*7f2fe78bSCy Schubert
366*7f2fe78bSCy Schubert if (do_timer)
367*7f2fe78bSCy Schubert swatch_on();
368*7f2fe78bSCy Schubert
369*7f2fe78bSCy Schubert if ((retval = krb5_mk_req_extended(context, &auth_context, 0, NULL,
370*7f2fe78bSCy Schubert credsp, &request_data))) {
371*7f2fe78bSCy Schubert com_err(prog, retval, "while preparing AP_REQ for %s", hostname);
372*7f2fe78bSCy Schubert goto cleanup;
373*7f2fe78bSCy Schubert }
374*7f2fe78bSCy Schubert
375*7f2fe78bSCy Schubert krb5_auth_con_free(context, auth_context);
376*7f2fe78bSCy Schubert auth_context = NULL;
377*7f2fe78bSCy Schubert
378*7f2fe78bSCy Schubert /* Do server side now */
379*7f2fe78bSCy Schubert if ((retval = get_server_key(context, credsp->server,
380*7f2fe78bSCy Schubert credsp->keyblock.enctype, &keyblock))) {
381*7f2fe78bSCy Schubert com_err(prog, retval, "while getting server key for %s", hostname);
382*7f2fe78bSCy Schubert goto cleanup;
383*7f2fe78bSCy Schubert }
384*7f2fe78bSCy Schubert
385*7f2fe78bSCy Schubert if (krb5_auth_con_init(context, &auth_context)) {
386*7f2fe78bSCy Schubert com_err(prog, retval, "while creating auth_context for %s", hostname);
387*7f2fe78bSCy Schubert goto cleanup;
388*7f2fe78bSCy Schubert }
389*7f2fe78bSCy Schubert
390*7f2fe78bSCy Schubert if (krb5_auth_con_setuseruserkey(context, auth_context, keyblock)) {
391*7f2fe78bSCy Schubert com_err(prog, retval, "while setting auth_context key %s", hostname);
392*7f2fe78bSCy Schubert goto cleanup;
393*7f2fe78bSCy Schubert }
394*7f2fe78bSCy Schubert
395*7f2fe78bSCy Schubert if ((retval = krb5_rd_req(context, &auth_context, &request_data,
396*7f2fe78bSCy Schubert NULL /* server */, 0, NULL, &ticket))) {
397*7f2fe78bSCy Schubert com_err(prog, retval, "while decoding AP_REQ for %s", hostname);
398*7f2fe78bSCy Schubert goto cleanup;
399*7f2fe78bSCy Schubert }
400*7f2fe78bSCy Schubert
401*7f2fe78bSCy Schubert if (do_timer) {
402*7f2fe78bSCy Schubert dt = swatch_eltime();
403*7f2fe78bSCy Schubert tgs_req_times.ht_cumulative += dt;
404*7f2fe78bSCy Schubert tgs_req_times.ht_observations++;
405*7f2fe78bSCy Schubert if (dt > tgs_req_times.ht_max)
406*7f2fe78bSCy Schubert tgs_req_times.ht_max = dt;
407*7f2fe78bSCy Schubert if (dt < tgs_req_times.ht_min)
408*7f2fe78bSCy Schubert tgs_req_times.ht_min = dt;
409*7f2fe78bSCy Schubert }
410*7f2fe78bSCy Schubert
411*7f2fe78bSCy Schubert if (!(krb5_principal_compare(context,ticket->enc_part2->client,p_client))){
412*7f2fe78bSCy Schubert char *returned_client;
413*7f2fe78bSCy Schubert if ((retval = krb5_unparse_name(context, ticket->enc_part2->client,
414*7f2fe78bSCy Schubert &returned_client)))
415*7f2fe78bSCy Schubert com_err (prog, retval,
416*7f2fe78bSCy Schubert "Client not as expected, but cannot unparse client name");
417*7f2fe78bSCy Schubert else
418*7f2fe78bSCy Schubert com_err (prog, 0, "Client not as expected (%s).", returned_client);
419*7f2fe78bSCy Schubert retval = KRB5_PRINC_NOMATCH;
420*7f2fe78bSCy Schubert free(returned_client);
421*7f2fe78bSCy Schubert } else {
422*7f2fe78bSCy Schubert retval = 0;
423*7f2fe78bSCy Schubert }
424*7f2fe78bSCy Schubert
425*7f2fe78bSCy Schubert cleanup:
426*7f2fe78bSCy Schubert krb5_free_cred_contents(context, &creds);
427*7f2fe78bSCy Schubert krb5_free_ticket(context, ticket);
428*7f2fe78bSCy Schubert krb5_auth_con_free(context, auth_context);
429*7f2fe78bSCy Schubert krb5_free_keyblock(context, keyblock);
430*7f2fe78bSCy Schubert krb5_free_data_contents(context, &request_data);
431*7f2fe78bSCy Schubert krb5_free_creds(context, credsp);
432*7f2fe78bSCy Schubert
433*7f2fe78bSCy Schubert return retval;
434*7f2fe78bSCy Schubert }
435*7f2fe78bSCy Schubert
get_tgt(context,p_client_str,p_client,ccache)436*7f2fe78bSCy Schubert int get_tgt (context, p_client_str, p_client, ccache)
437*7f2fe78bSCy Schubert krb5_context context;
438*7f2fe78bSCy Schubert char *p_client_str;
439*7f2fe78bSCy Schubert krb5_principal *p_client;
440*7f2fe78bSCy Schubert krb5_ccache ccache;
441*7f2fe78bSCy Schubert {
442*7f2fe78bSCy Schubert long lifetime = KRB5_DEFAULT_LIFE; /* -l option */
443*7f2fe78bSCy Schubert krb5_error_code code;
444*7f2fe78bSCy Schubert krb5_creds my_creds;
445*7f2fe78bSCy Schubert krb5_timestamp start;
446*7f2fe78bSCy Schubert float dt;
447*7f2fe78bSCy Schubert krb5_get_init_creds_opt *options;
448*7f2fe78bSCy Schubert
449*7f2fe78bSCy Schubert if (!brief)
450*7f2fe78bSCy Schubert fprintf(stderr, "\tgetting TGT for %s\n", p_client_str);
451*7f2fe78bSCy Schubert
452*7f2fe78bSCy Schubert if ((code = krb5_timeofday(context, &start))) {
453*7f2fe78bSCy Schubert com_err(prog, code, "while getting time of day");
454*7f2fe78bSCy Schubert return(-1);
455*7f2fe78bSCy Schubert }
456*7f2fe78bSCy Schubert
457*7f2fe78bSCy Schubert memset(&my_creds, 0, sizeof(my_creds));
458*7f2fe78bSCy Schubert
459*7f2fe78bSCy Schubert if ((code = krb5_parse_name (context, p_client_str, p_client))) {
460*7f2fe78bSCy Schubert com_err (prog, code, "when parsing name %s", p_client_str);
461*7f2fe78bSCy Schubert return(-1);
462*7f2fe78bSCy Schubert }
463*7f2fe78bSCy Schubert
464*7f2fe78bSCy Schubert code = krb5_cc_initialize (context, ccache, *p_client);
465*7f2fe78bSCy Schubert if (code != 0) {
466*7f2fe78bSCy Schubert com_err (prog, code, "when initializing cache");
467*7f2fe78bSCy Schubert return(-1);
468*7f2fe78bSCy Schubert }
469*7f2fe78bSCy Schubert
470*7f2fe78bSCy Schubert if (do_timer)
471*7f2fe78bSCy Schubert swatch_on();
472*7f2fe78bSCy Schubert
473*7f2fe78bSCy Schubert code = krb5_get_init_creds_opt_alloc(context, &options);
474*7f2fe78bSCy Schubert if (code != 0) {
475*7f2fe78bSCy Schubert com_err(prog, code, "when allocating init cred options");
476*7f2fe78bSCy Schubert return(-1);
477*7f2fe78bSCy Schubert }
478*7f2fe78bSCy Schubert
479*7f2fe78bSCy Schubert krb5_get_init_creds_opt_set_tkt_life(options, lifetime);
480*7f2fe78bSCy Schubert
481*7f2fe78bSCy Schubert code = krb5_get_init_creds_opt_set_out_ccache(context, options, ccache);
482*7f2fe78bSCy Schubert if (code != 0) {
483*7f2fe78bSCy Schubert com_err(prog, code, "when setting init cred output ccache");
484*7f2fe78bSCy Schubert return(-1);
485*7f2fe78bSCy Schubert }
486*7f2fe78bSCy Schubert
487*7f2fe78bSCy Schubert code = krb5_get_init_creds_password(context, &my_creds, *p_client,
488*7f2fe78bSCy Schubert p_client_str, NULL, NULL, 0, NULL,
489*7f2fe78bSCy Schubert options);
490*7f2fe78bSCy Schubert if (do_timer) {
491*7f2fe78bSCy Schubert dt = swatch_eltime();
492*7f2fe78bSCy Schubert in_tkt_times.ht_cumulative += dt;
493*7f2fe78bSCy Schubert in_tkt_times.ht_observations++;
494*7f2fe78bSCy Schubert if (dt > in_tkt_times.ht_max)
495*7f2fe78bSCy Schubert in_tkt_times.ht_max = dt;
496*7f2fe78bSCy Schubert if (dt < in_tkt_times.ht_min)
497*7f2fe78bSCy Schubert in_tkt_times.ht_min = dt;
498*7f2fe78bSCy Schubert }
499*7f2fe78bSCy Schubert krb5_get_init_creds_opt_free(context, options);
500*7f2fe78bSCy Schubert krb5_free_cred_contents(context, &my_creds);
501*7f2fe78bSCy Schubert if (code != 0) {
502*7f2fe78bSCy Schubert com_err (prog, code, "while getting initial credentials");
503*7f2fe78bSCy Schubert return(-1);
504*7f2fe78bSCy Schubert }
505*7f2fe78bSCy Schubert
506*7f2fe78bSCy Schubert return(0);
507*7f2fe78bSCy Schubert }
508