Home | History | Annotate | Line # | Download | only in gssapi
      1 /*	$NetBSD: test_acquire_cred.c,v 1.2 2017/01/28 21:31:46 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2003-2007 Kungliga Tekniska Hgskolan
      5  * (Royal Institute of Technology, Stockholm, Sweden).
      6  * 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 
     36 #ifdef HAVE_CONFIG_H
     37 #include <config.h>
     38 #endif
     39 
     40 #include <krb5/roken.h>
     41 #include <stdio.h>
     42 #include <stdlib.h>
     43 #include <string.h>
     44 #include <stdarg.h>
     45 #include <gssapi/gssapi.h>
     46 #include <gssapi/gssapi_krb5.h>
     47 #include <gssapi/gssapi_spnego.h>
     48 #include <err.h>
     49 #include <krb5/getarg.h>
     50 
     51 #include "test_common.h"
     52 
     53 static void
     54 print_time(OM_uint32 time_rec)
     55 {
     56     if (time_rec == GSS_C_INDEFINITE) {
     57 	printf("cred never expire\n");
     58     } else {
     59 	time_t t = time_rec + time(NULL);
     60 	printf("expiration time: %s", ctime(&t));
     61     }
     62 }
     63 
     64 #if 0
     65 
     66 static void
     67 test_add(gss_cred_id_t cred_handle)
     68 {
     69     OM_uint32 major_status, minor_status;
     70     gss_cred_id_t copy_cred;
     71     OM_uint32 time_rec;
     72 
     73     major_status = gss_add_cred (&minor_status,
     74 				 cred_handle,
     75 				 GSS_C_NO_NAME,
     76 				 GSS_KRB5_MECHANISM,
     77 				 GSS_C_INITIATE,
     78 				 0,
     79 				 0,
     80 				 &copy_cred,
     81 				 NULL,
     82 				 &time_rec,
     83 				 NULL);
     84 
     85     if (GSS_ERROR(major_status))
     86 	errx(1, "add_cred failed");
     87 
     88     print_time(time_rec);
     89 
     90     major_status = gss_release_cred(&minor_status,
     91 				    &copy_cred);
     92     if (GSS_ERROR(major_status))
     93 	errx(1, "release_cred failed");
     94 }
     95 
     96 static void
     97 copy_cred(void)
     98 {
     99     OM_uint32 major_status, minor_status;
    100     gss_cred_id_t cred_handle;
    101     OM_uint32 time_rec;
    102 
    103     major_status = gss_acquire_cred(&minor_status,
    104 				    GSS_C_NO_NAME,
    105 				    0,
    106 				    NULL,
    107 				    GSS_C_INITIATE,
    108 				    &cred_handle,
    109 				    NULL,
    110 				    &time_rec);
    111     if (GSS_ERROR(major_status))
    112 	errx(1, "acquire_cred failed");
    113 
    114     print_time(time_rec);
    115 
    116     test_add(cred_handle);
    117     test_add(cred_handle);
    118     test_add(cred_handle);
    119 
    120     major_status = gss_release_cred(&minor_status,
    121 				    &cred_handle);
    122     if (GSS_ERROR(major_status))
    123 	errx(1, "release_cred failed");
    124 }
    125 #endif
    126 
    127 static gss_cred_id_t
    128 acquire_cred_service(const char *service,
    129 		     gss_OID nametype,
    130 		     gss_OID_set oidset,
    131 		     int flags)
    132 {
    133     OM_uint32 major_status, minor_status;
    134     gss_cred_id_t cred_handle;
    135     OM_uint32 time_rec;
    136     gss_buffer_desc name_buffer;
    137     gss_name_t name = GSS_C_NO_NAME;
    138 
    139     if (service) {
    140 	name_buffer.value = rk_UNCONST(service);
    141 	name_buffer.length = strlen(service);
    142 
    143 	major_status = gss_import_name(&minor_status,
    144 				       &name_buffer,
    145 				       nametype,
    146 				       &name);
    147 	if (GSS_ERROR(major_status))
    148 	    errx(1, "import_name failed");
    149     }
    150 
    151     major_status = gss_acquire_cred(&minor_status,
    152 				    name,
    153 				    0,
    154 				    oidset,
    155 				    flags,
    156 				    &cred_handle,
    157 				    NULL,
    158 				    &time_rec);
    159     if (GSS_ERROR(major_status)) {
    160 	warnx("acquire_cred failed: %s",
    161 	     gssapi_err(major_status, minor_status, GSS_C_NO_OID));
    162     } else {
    163 	print_time(time_rec);
    164 	gss_release_cred(&minor_status, &cred_handle);
    165     }
    166 
    167     if (name != GSS_C_NO_NAME)
    168 	gss_release_name(&minor_status, &name);
    169 
    170     if (GSS_ERROR(major_status))
    171 	exit(1);
    172 
    173     return cred_handle;
    174 }
    175 
    176 static int version_flag = 0;
    177 static int help_flag	= 0;
    178 static int kerberos_flag = 0;
    179 static int enctype = 0;
    180 static char *acquire_name;
    181 static char *acquire_type;
    182 static char *target_name;
    183 static char *name_type;
    184 static char *ccache;
    185 static int num_loops = 1;
    186 
    187 static struct getargs args[] = {
    188     {"acquire-name", 0,	arg_string,	&acquire_name, "name", NULL },
    189     {"acquire-type", 0,	arg_string,	&acquire_type, "type", NULL },
    190     {"enctype", 0,	arg_integer,	&enctype, "enctype-num", NULL },
    191     {"loops", 0,	arg_integer,	&num_loops, "enctype-num", NULL },
    192     {"kerberos", 0,	arg_flag,	&kerberos_flag, "enctype-num", NULL },
    193     {"target-name", 0,	arg_string,	&target_name, "name", NULL },
    194     {"ccache", 0,	arg_string,	&ccache, "name", NULL },
    195     {"name-type", 0,	arg_string,	&name_type, "type", NULL },
    196     {"version",	0,	arg_flag,	&version_flag, "print version", NULL },
    197     {"help",	0,	arg_flag,	&help_flag,  NULL, NULL }
    198 };
    199 
    200 static void
    201 usage (int ret)
    202 {
    203     arg_printusage (args, sizeof(args)/sizeof(*args), NULL, "");
    204     exit (ret);
    205 }
    206 
    207 int
    208 main(int argc, char **argv)
    209 {
    210     gss_OID_set oidset = GSS_C_NULL_OID_SET;
    211     gss_OID mechoid = GSS_C_NO_OID;
    212     OM_uint32 maj_stat, min_stat;
    213     gss_cred_id_t cred;
    214     gss_name_t target = GSS_C_NO_NAME;
    215     int i, optidx = 0;
    216     OM_uint32 flag;
    217     gss_OID type;
    218 
    219     setprogname(argv[0]);
    220     if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
    221 	usage(1);
    222 
    223     if (help_flag)
    224 	usage (0);
    225 
    226     if(version_flag){
    227 	print_version(NULL);
    228 	exit(0);
    229     }
    230 
    231     argc -= optidx;
    232     argv += optidx;
    233 
    234     if (argc != 0)
    235 	usage(1);
    236 
    237     if (acquire_type) {
    238 	if (strcasecmp(acquire_type, "both") == 0)
    239 	    flag = GSS_C_BOTH;
    240 	else if (strcasecmp(acquire_type, "accept") == 0)
    241 	    flag = GSS_C_ACCEPT;
    242 	else if (strcasecmp(acquire_type, "initiate") == 0)
    243 	    flag = GSS_C_INITIATE;
    244 	else
    245 	    errx(1, "unknown type %s", acquire_type);
    246     } else
    247 	flag = GSS_C_ACCEPT;
    248 
    249     if (name_type) {
    250 	if (strcasecmp("hostbased-service", name_type) == 0)
    251 	    type = GSS_C_NT_HOSTBASED_SERVICE;
    252 	else if (strcasecmp("user-name", name_type) == 0)
    253 	    type = GSS_C_NT_USER_NAME;
    254 	else
    255 	    errx(1, "unknown name type %s", name_type);
    256     } else
    257 	type = GSS_C_NT_HOSTBASED_SERVICE;
    258 
    259     if (ccache) {
    260 	maj_stat = gss_krb5_ccache_name(&min_stat, ccache, NULL);
    261 	if (GSS_ERROR(maj_stat))
    262 	    errx(1, "gss_krb5_ccache_name %s",
    263 		 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
    264     }
    265 
    266     if (kerberos_flag) {
    267 	mechoid = GSS_KRB5_MECHANISM;
    268 
    269 	maj_stat = gss_create_empty_oid_set(&min_stat, &oidset);
    270 	if (maj_stat != GSS_S_COMPLETE)
    271 	    errx(1, "gss_create_empty_oid_set: %s",
    272 		 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
    273 
    274 	maj_stat = gss_add_oid_set_member(&min_stat, GSS_KRB5_MECHANISM, &oidset);
    275 	if (maj_stat != GSS_S_COMPLETE)
    276 	    errx(1, "gss_add_oid_set_member: %s",
    277 		 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
    278     }
    279 
    280     if (target_name) {
    281 	gss_buffer_desc name;
    282 
    283 	name.value = target_name;
    284 	name.length = strlen(target_name);
    285 	maj_stat = gss_import_name(&min_stat, &name,
    286 				   GSS_C_NT_HOSTBASED_SERVICE, &target);
    287 	if (maj_stat != GSS_S_COMPLETE)
    288 	    errx(1, "gss_import_name: %s",
    289 		 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
    290     }
    291 
    292     for (i = 0; i < num_loops; i++) {
    293 
    294 	cred = acquire_cred_service(acquire_name, type, oidset, flag);
    295 
    296 	if (enctype) {
    297 	    int32_t enctypelist = enctype;
    298 
    299 	    maj_stat = gss_krb5_set_allowable_enctypes(&min_stat, cred,
    300 						       1, &enctypelist);
    301 	    if (maj_stat)
    302 		errx(1, "gss_krb5_set_allowable_enctypes: %s",
    303 		     gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
    304 	}
    305 
    306 	if (target) {
    307 	    gss_ctx_id_t context = GSS_C_NO_CONTEXT;
    308 	    gss_buffer_desc out;
    309 
    310 	    out.length = 0;
    311 	    out.value = NULL;
    312 
    313 	    maj_stat = gss_init_sec_context(&min_stat,
    314 					    cred, &context,
    315 					    target, mechoid,
    316 					    GSS_C_MUTUAL_FLAG, 0, NULL,
    317 					    GSS_C_NO_BUFFER, NULL,
    318 					    &out, NULL, NULL);
    319 	    if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
    320 		errx(1, "init_sec_context failed: %s",
    321 		     gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
    322 
    323 	    gss_release_buffer(&min_stat, &out);
    324 	    gss_delete_sec_context(&min_stat, &context, NULL);
    325 	}
    326 	gss_release_cred(&min_stat, &cred);
    327     }
    328 
    329 
    330     return 0;
    331 }
    332