xref: /freebsd/crypto/heimdal/lib/gssapi/test_acquire_cred.c (revision 6a068746777241722b2b32c5d0bc443a2a64d80b)
1bbd80c28SJacques Vidrine /*
2*ae771770SStanislav Sedov  * Copyright (c) 2003-2007 Kungliga Tekniska Högskolan
3bbd80c28SJacques Vidrine  * (Royal Institute of Technology, Stockholm, Sweden).
4bbd80c28SJacques Vidrine  * All rights reserved.
5bbd80c28SJacques Vidrine  *
6bbd80c28SJacques Vidrine  * Redistribution and use in source and binary forms, with or without
7bbd80c28SJacques Vidrine  * modification, are permitted provided that the following conditions
8bbd80c28SJacques Vidrine  * are met:
9bbd80c28SJacques Vidrine  *
10bbd80c28SJacques Vidrine  * 1. Redistributions of source code must retain the above copyright
11bbd80c28SJacques Vidrine  *    notice, this list of conditions and the following disclaimer.
12bbd80c28SJacques Vidrine  *
13bbd80c28SJacques Vidrine  * 2. Redistributions in binary form must reproduce the above copyright
14bbd80c28SJacques Vidrine  *    notice, this list of conditions and the following disclaimer in the
15bbd80c28SJacques Vidrine  *    documentation and/or other materials provided with the distribution.
16bbd80c28SJacques Vidrine  *
17bbd80c28SJacques Vidrine  * 3. Neither the name of KTH nor the names of its contributors may be
18bbd80c28SJacques Vidrine  *    used to endorse or promote products derived from this software without
19bbd80c28SJacques Vidrine  *    specific prior written permission.
20bbd80c28SJacques Vidrine  *
21bbd80c28SJacques Vidrine  * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
22bbd80c28SJacques Vidrine  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23bbd80c28SJacques Vidrine  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24bbd80c28SJacques Vidrine  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
25bbd80c28SJacques Vidrine  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26bbd80c28SJacques Vidrine  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27bbd80c28SJacques Vidrine  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28bbd80c28SJacques Vidrine  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29bbd80c28SJacques Vidrine  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30bbd80c28SJacques Vidrine  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31c19800e8SDoug Rabson  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32c19800e8SDoug Rabson  */
33bbd80c28SJacques Vidrine 
34c19800e8SDoug Rabson #ifdef HAVE_CONFIG_H
35c19800e8SDoug Rabson #include <config.h>
36c19800e8SDoug Rabson #endif
37c19800e8SDoug Rabson 
38*ae771770SStanislav Sedov #include <roken.h>
39c19800e8SDoug Rabson #include <stdio.h>
40c19800e8SDoug Rabson #include <stdlib.h>
41c19800e8SDoug Rabson #include <string.h>
42c19800e8SDoug Rabson #include <stdarg.h>
43c19800e8SDoug Rabson #include <gssapi.h>
44*ae771770SStanislav Sedov #include <gssapi_krb5.h>
45*ae771770SStanislav Sedov #include <gssapi_spnego.h>
46bbd80c28SJacques Vidrine #include <err.h>
47c19800e8SDoug Rabson #include <getarg.h>
48bbd80c28SJacques Vidrine 
49c19800e8SDoug Rabson #include "test_common.h"
50c19800e8SDoug Rabson 
51bbd80c28SJacques Vidrine static void
print_time(OM_uint32 time_rec)52bbd80c28SJacques Vidrine print_time(OM_uint32 time_rec)
53bbd80c28SJacques Vidrine {
54bbd80c28SJacques Vidrine     if (time_rec == GSS_C_INDEFINITE) {
55bbd80c28SJacques Vidrine 	printf("cred never expire\n");
56bbd80c28SJacques Vidrine     } else {
57c19800e8SDoug Rabson 	time_t t = time_rec + time(NULL);
58bbd80c28SJacques Vidrine 	printf("expiration time: %s", ctime(&t));
59bbd80c28SJacques Vidrine     }
60bbd80c28SJacques Vidrine }
61bbd80c28SJacques Vidrine 
62c19800e8SDoug Rabson #if 0
63c19800e8SDoug Rabson 
64c19800e8SDoug Rabson static void
65c19800e8SDoug Rabson test_add(gss_cred_id_t cred_handle)
66bbd80c28SJacques Vidrine {
67bbd80c28SJacques Vidrine     OM_uint32 major_status, minor_status;
68c19800e8SDoug Rabson     gss_cred_id_t copy_cred;
69bbd80c28SJacques Vidrine     OM_uint32 time_rec;
70bbd80c28SJacques Vidrine 
71bbd80c28SJacques Vidrine     major_status = gss_add_cred (&minor_status,
72bbd80c28SJacques Vidrine 				 cred_handle,
73bbd80c28SJacques Vidrine 				 GSS_C_NO_NAME,
74bbd80c28SJacques Vidrine 				 GSS_KRB5_MECHANISM,
75bbd80c28SJacques Vidrine 				 GSS_C_INITIATE,
76bbd80c28SJacques Vidrine 				 0,
77bbd80c28SJacques Vidrine 				 0,
78bbd80c28SJacques Vidrine 				 &copy_cred,
79bbd80c28SJacques Vidrine 				 NULL,
80bbd80c28SJacques Vidrine 				 &time_rec,
81bbd80c28SJacques Vidrine 				 NULL);
82bbd80c28SJacques Vidrine 
83bbd80c28SJacques Vidrine     if (GSS_ERROR(major_status))
84bbd80c28SJacques Vidrine 	errx(1, "add_cred failed");
85bbd80c28SJacques Vidrine 
86bbd80c28SJacques Vidrine     print_time(time_rec);
87bbd80c28SJacques Vidrine 
88bbd80c28SJacques Vidrine     major_status = gss_release_cred(&minor_status,
89bbd80c28SJacques Vidrine 				    &copy_cred);
90bbd80c28SJacques Vidrine     if (GSS_ERROR(major_status))
91bbd80c28SJacques Vidrine 	errx(1, "release_cred failed");
92c19800e8SDoug Rabson }
93c19800e8SDoug Rabson 
94c19800e8SDoug Rabson static void
95c19800e8SDoug Rabson copy_cred(void)
96c19800e8SDoug Rabson {
97c19800e8SDoug Rabson     OM_uint32 major_status, minor_status;
98c19800e8SDoug Rabson     gss_cred_id_t cred_handle;
99c19800e8SDoug Rabson     OM_uint32 time_rec;
100c19800e8SDoug Rabson 
101c19800e8SDoug Rabson     major_status = gss_acquire_cred(&minor_status,
102c19800e8SDoug Rabson 				    GSS_C_NO_NAME,
103c19800e8SDoug Rabson 				    0,
104c19800e8SDoug Rabson 				    NULL,
105c19800e8SDoug Rabson 				    GSS_C_INITIATE,
106c19800e8SDoug Rabson 				    &cred_handle,
107c19800e8SDoug Rabson 				    NULL,
108c19800e8SDoug Rabson 				    &time_rec);
109c19800e8SDoug Rabson     if (GSS_ERROR(major_status))
110c19800e8SDoug Rabson 	errx(1, "acquire_cred failed");
111c19800e8SDoug Rabson 
112c19800e8SDoug Rabson     print_time(time_rec);
113c19800e8SDoug Rabson 
114c19800e8SDoug Rabson     test_add(cred_handle);
115c19800e8SDoug Rabson     test_add(cred_handle);
116c19800e8SDoug Rabson     test_add(cred_handle);
117c19800e8SDoug Rabson 
118c19800e8SDoug Rabson     major_status = gss_release_cred(&minor_status,
119c19800e8SDoug Rabson 				    &cred_handle);
120c19800e8SDoug Rabson     if (GSS_ERROR(major_status))
121c19800e8SDoug Rabson 	errx(1, "release_cred failed");
122c19800e8SDoug Rabson }
123c19800e8SDoug Rabson #endif
124c19800e8SDoug Rabson 
125*ae771770SStanislav Sedov static gss_cred_id_t
acquire_cred_service(const char * service,gss_OID nametype,gss_OID_set oidset,int flags)126c19800e8SDoug Rabson acquire_cred_service(const char *service,
127c19800e8SDoug Rabson 		     gss_OID nametype,
128*ae771770SStanislav Sedov 		     gss_OID_set oidset,
129c19800e8SDoug Rabson 		     int flags)
130c19800e8SDoug Rabson {
131c19800e8SDoug Rabson     OM_uint32 major_status, minor_status;
132c19800e8SDoug Rabson     gss_cred_id_t cred_handle;
133c19800e8SDoug Rabson     OM_uint32 time_rec;
134c19800e8SDoug Rabson     gss_buffer_desc name_buffer;
135c19800e8SDoug Rabson     gss_name_t name = GSS_C_NO_NAME;
136c19800e8SDoug Rabson 
137c19800e8SDoug Rabson     if (service) {
138c19800e8SDoug Rabson 	name_buffer.value = rk_UNCONST(service);
139c19800e8SDoug Rabson 	name_buffer.length = strlen(service);
140c19800e8SDoug Rabson 
141c19800e8SDoug Rabson 	major_status = gss_import_name(&minor_status,
142c19800e8SDoug Rabson 				       &name_buffer,
143c19800e8SDoug Rabson 				       nametype,
144c19800e8SDoug Rabson 				       &name);
145c19800e8SDoug Rabson 	if (GSS_ERROR(major_status))
146c19800e8SDoug Rabson 	    errx(1, "import_name failed");
147c19800e8SDoug Rabson     }
148c19800e8SDoug Rabson 
149c19800e8SDoug Rabson     major_status = gss_acquire_cred(&minor_status,
150c19800e8SDoug Rabson 				    name,
151c19800e8SDoug Rabson 				    0,
152*ae771770SStanislav Sedov 				    oidset,
153c19800e8SDoug Rabson 				    flags,
154c19800e8SDoug Rabson 				    &cred_handle,
155c19800e8SDoug Rabson 				    NULL,
156c19800e8SDoug Rabson 				    &time_rec);
157c19800e8SDoug Rabson     if (GSS_ERROR(major_status)) {
158c19800e8SDoug Rabson 	warnx("acquire_cred failed: %s",
159c19800e8SDoug Rabson 	     gssapi_err(major_status, minor_status, GSS_C_NO_OID));
160c19800e8SDoug Rabson     } else {
161c19800e8SDoug Rabson 	print_time(time_rec);
162c19800e8SDoug Rabson 	gss_release_cred(&minor_status, &cred_handle);
163c19800e8SDoug Rabson     }
164c19800e8SDoug Rabson 
165c19800e8SDoug Rabson     if (name != GSS_C_NO_NAME)
166c19800e8SDoug Rabson 	gss_release_name(&minor_status, &name);
167c19800e8SDoug Rabson 
168c19800e8SDoug Rabson     if (GSS_ERROR(major_status))
169c19800e8SDoug Rabson 	exit(1);
170*ae771770SStanislav Sedov 
171*ae771770SStanislav Sedov     return cred_handle;
172c19800e8SDoug Rabson }
173c19800e8SDoug Rabson 
174c19800e8SDoug Rabson static int version_flag = 0;
175c19800e8SDoug Rabson static int help_flag	= 0;
176*ae771770SStanislav Sedov static int kerberos_flag = 0;
177*ae771770SStanislav Sedov static int enctype = 0;
178c19800e8SDoug Rabson static char *acquire_name;
179c19800e8SDoug Rabson static char *acquire_type;
180*ae771770SStanislav Sedov static char *target_name;
181c19800e8SDoug Rabson static char *name_type;
182c19800e8SDoug Rabson static char *ccache;
183*ae771770SStanislav Sedov static int num_loops = 1;
184c19800e8SDoug Rabson 
185c19800e8SDoug Rabson static struct getargs args[] = {
186c19800e8SDoug Rabson     {"acquire-name", 0,	arg_string,	&acquire_name, "name", NULL },
187c19800e8SDoug Rabson     {"acquire-type", 0,	arg_string,	&acquire_type, "type", NULL },
188*ae771770SStanislav Sedov     {"enctype", 0,	arg_integer,	&enctype, "enctype-num", NULL },
189*ae771770SStanislav Sedov     {"loops", 0,	arg_integer,	&num_loops, "enctype-num", NULL },
190*ae771770SStanislav Sedov     {"kerberos", 0,	arg_flag,	&kerberos_flag, "enctype-num", NULL },
191*ae771770SStanislav Sedov     {"target-name", 0,	arg_string,	&target_name, "name", NULL },
192c19800e8SDoug Rabson     {"ccache", 0,	arg_string,	&ccache, "name", NULL },
193c19800e8SDoug Rabson     {"name-type", 0,	arg_string,	&name_type, "type", NULL },
194c19800e8SDoug Rabson     {"version",	0,	arg_flag,	&version_flag, "print version", NULL },
195c19800e8SDoug Rabson     {"help",	0,	arg_flag,	&help_flag,  NULL, NULL }
196c19800e8SDoug Rabson };
197c19800e8SDoug Rabson 
198c19800e8SDoug Rabson static void
usage(int ret)199c19800e8SDoug Rabson usage (int ret)
200c19800e8SDoug Rabson {
201c19800e8SDoug Rabson     arg_printusage (args, sizeof(args)/sizeof(*args), NULL, "");
202c19800e8SDoug Rabson     exit (ret);
203c19800e8SDoug Rabson }
204c19800e8SDoug Rabson 
205c19800e8SDoug Rabson int
main(int argc,char ** argv)206c19800e8SDoug Rabson main(int argc, char **argv)
207c19800e8SDoug Rabson {
208*ae771770SStanislav Sedov     gss_OID_set oidset = GSS_C_NULL_OID_SET;
209*ae771770SStanislav Sedov     gss_OID mechoid = GSS_C_NO_OID;
210*ae771770SStanislav Sedov     OM_uint32 maj_stat, min_stat;
211*ae771770SStanislav Sedov     gss_cred_id_t cred;
212*ae771770SStanislav Sedov     gss_name_t target = GSS_C_NO_NAME;
213*ae771770SStanislav Sedov     int i, optidx = 0;
214c19800e8SDoug Rabson     OM_uint32 flag;
215c19800e8SDoug Rabson     gss_OID type;
216c19800e8SDoug Rabson 
217c19800e8SDoug Rabson     setprogname(argv[0]);
218c19800e8SDoug Rabson     if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
219c19800e8SDoug Rabson 	usage(1);
220c19800e8SDoug Rabson 
221c19800e8SDoug Rabson     if (help_flag)
222c19800e8SDoug Rabson 	usage (0);
223c19800e8SDoug Rabson 
224c19800e8SDoug Rabson     if(version_flag){
225c19800e8SDoug Rabson 	print_version(NULL);
226c19800e8SDoug Rabson 	exit(0);
227c19800e8SDoug Rabson     }
228c19800e8SDoug Rabson 
229c19800e8SDoug Rabson     argc -= optidx;
230c19800e8SDoug Rabson     argv += optidx;
231c19800e8SDoug Rabson 
232c19800e8SDoug Rabson     if (argc != 0)
233c19800e8SDoug Rabson 	usage(1);
234c19800e8SDoug Rabson 
235c19800e8SDoug Rabson     if (acquire_type) {
236c19800e8SDoug Rabson 	if (strcasecmp(acquire_type, "both") == 0)
237c19800e8SDoug Rabson 	    flag = GSS_C_BOTH;
238c19800e8SDoug Rabson 	else if (strcasecmp(acquire_type, "accept") == 0)
239c19800e8SDoug Rabson 	    flag = GSS_C_ACCEPT;
240c19800e8SDoug Rabson 	else if (strcasecmp(acquire_type, "initiate") == 0)
241c19800e8SDoug Rabson 	    flag = GSS_C_INITIATE;
242c19800e8SDoug Rabson 	else
243c19800e8SDoug Rabson 	    errx(1, "unknown type %s", acquire_type);
244c19800e8SDoug Rabson     } else
245c19800e8SDoug Rabson 	flag = GSS_C_ACCEPT;
246c19800e8SDoug Rabson 
247c19800e8SDoug Rabson     if (name_type) {
248c19800e8SDoug Rabson 	if (strcasecmp("hostbased-service", name_type) == 0)
249c19800e8SDoug Rabson 	    type = GSS_C_NT_HOSTBASED_SERVICE;
250c19800e8SDoug Rabson 	else if (strcasecmp("user-name", name_type) == 0)
251c19800e8SDoug Rabson 	    type = GSS_C_NT_USER_NAME;
252c19800e8SDoug Rabson 	else
253c19800e8SDoug Rabson 	    errx(1, "unknown name type %s", name_type);
254c19800e8SDoug Rabson     } else
255c19800e8SDoug Rabson 	type = GSS_C_NT_HOSTBASED_SERVICE;
256c19800e8SDoug Rabson 
257c19800e8SDoug Rabson     if (ccache) {
258*ae771770SStanislav Sedov 	maj_stat = gss_krb5_ccache_name(&min_stat, ccache, NULL);
259*ae771770SStanislav Sedov 	if (GSS_ERROR(maj_stat))
260c19800e8SDoug Rabson 	    errx(1, "gss_krb5_ccache_name %s",
261*ae771770SStanislav Sedov 		 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
262c19800e8SDoug Rabson     }
263c19800e8SDoug Rabson 
264*ae771770SStanislav Sedov     if (kerberos_flag) {
265*ae771770SStanislav Sedov 	mechoid = GSS_KRB5_MECHANISM;
266*ae771770SStanislav Sedov 
267*ae771770SStanislav Sedov 	maj_stat = gss_create_empty_oid_set(&min_stat, &oidset);
268*ae771770SStanislav Sedov 	if (maj_stat != GSS_S_COMPLETE)
269*ae771770SStanislav Sedov 	    errx(1, "gss_create_empty_oid_set: %s",
270*ae771770SStanislav Sedov 		 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
271*ae771770SStanislav Sedov 
272*ae771770SStanislav Sedov 	maj_stat = gss_add_oid_set_member(&min_stat, GSS_KRB5_MECHANISM, &oidset);
273*ae771770SStanislav Sedov 	if (maj_stat != GSS_S_COMPLETE)
274*ae771770SStanislav Sedov 	    errx(1, "gss_add_oid_set_member: %s",
275*ae771770SStanislav Sedov 		 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
276*ae771770SStanislav Sedov     }
277*ae771770SStanislav Sedov 
278*ae771770SStanislav Sedov     if (target_name) {
279*ae771770SStanislav Sedov 	gss_buffer_desc name;
280*ae771770SStanislav Sedov 
281*ae771770SStanislav Sedov 	name.value = target_name;
282*ae771770SStanislav Sedov 	name.length = strlen(target_name);
283*ae771770SStanislav Sedov 	maj_stat = gss_import_name(&min_stat, &name,
284*ae771770SStanislav Sedov 				   GSS_C_NT_HOSTBASED_SERVICE, &target);
285*ae771770SStanislav Sedov 	if (maj_stat != GSS_S_COMPLETE)
286*ae771770SStanislav Sedov 	    errx(1, "gss_import_name: %s",
287*ae771770SStanislav Sedov 		 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
288*ae771770SStanislav Sedov     }
289*ae771770SStanislav Sedov 
290*ae771770SStanislav Sedov     for (i = 0; i < num_loops; i++) {
291*ae771770SStanislav Sedov 
292*ae771770SStanislav Sedov 	cred = acquire_cred_service(acquire_name, type, oidset, flag);
293*ae771770SStanislav Sedov 
294*ae771770SStanislav Sedov 	if (enctype) {
295*ae771770SStanislav Sedov 	    int32_t enctypelist = enctype;
296*ae771770SStanislav Sedov 
297*ae771770SStanislav Sedov 	    maj_stat = gss_krb5_set_allowable_enctypes(&min_stat, cred,
298*ae771770SStanislav Sedov 						       1, &enctypelist);
299*ae771770SStanislav Sedov 	    if (maj_stat)
300*ae771770SStanislav Sedov 		errx(1, "gss_krb5_set_allowable_enctypes: %s",
301*ae771770SStanislav Sedov 		     gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
302*ae771770SStanislav Sedov 	}
303*ae771770SStanislav Sedov 
304*ae771770SStanislav Sedov 	if (target) {
305*ae771770SStanislav Sedov 	    gss_ctx_id_t context = GSS_C_NO_CONTEXT;
306*ae771770SStanislav Sedov 	    gss_buffer_desc out;
307*ae771770SStanislav Sedov 
308*ae771770SStanislav Sedov 	    out.length = 0;
309*ae771770SStanislav Sedov 	    out.value = NULL;
310*ae771770SStanislav Sedov 
311*ae771770SStanislav Sedov 	    maj_stat = gss_init_sec_context(&min_stat,
312*ae771770SStanislav Sedov 					    cred, &context,
313*ae771770SStanislav Sedov 					    target, mechoid,
314*ae771770SStanislav Sedov 					    GSS_C_MUTUAL_FLAG, 0, NULL,
315*ae771770SStanislav Sedov 					    GSS_C_NO_BUFFER, NULL,
316*ae771770SStanislav Sedov 					    &out, NULL, NULL);
317*ae771770SStanislav Sedov 	    if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
318*ae771770SStanislav Sedov 		errx(1, "init_sec_context failed: %s",
319*ae771770SStanislav Sedov 		     gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
320*ae771770SStanislav Sedov 
321*ae771770SStanislav Sedov 	    gss_release_buffer(&min_stat, &out);
322*ae771770SStanislav Sedov 	    gss_delete_sec_context(&min_stat, &context, NULL);
323*ae771770SStanislav Sedov 	}
324*ae771770SStanislav Sedov 	gss_release_cred(&min_stat, &cred);
325*ae771770SStanislav Sedov     }
326*ae771770SStanislav Sedov 
327bbd80c28SJacques Vidrine 
328bbd80c28SJacques Vidrine     return 0;
329bbd80c28SJacques Vidrine }
330