xref: /freebsd/crypto/krb5/src/tests/hammer/kdc5_hammer.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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