1c19800e8SDoug Rabson /* 2c19800e8SDoug Rabson * Copyright (c) 2006 Kungliga Tekniska H�gskolan 3c19800e8SDoug Rabson * (Royal Institute of Technology, Stockholm, Sweden). 4c19800e8SDoug Rabson * All rights reserved. 5c19800e8SDoug Rabson * 6c19800e8SDoug Rabson * Redistribution and use in source and binary forms, with or without 7c19800e8SDoug Rabson * modification, are permitted provided that the following conditions 8c19800e8SDoug Rabson * are met: 9c19800e8SDoug Rabson * 10c19800e8SDoug Rabson * 1. Redistributions of source code must retain the above copyright 11c19800e8SDoug Rabson * notice, this list of conditions and the following disclaimer. 12c19800e8SDoug Rabson * 13c19800e8SDoug Rabson * 2. Redistributions in binary form must reproduce the above copyright 14c19800e8SDoug Rabson * notice, this list of conditions and the following disclaimer in the 15c19800e8SDoug Rabson * documentation and/or other materials provided with the distribution. 16c19800e8SDoug Rabson * 17c19800e8SDoug Rabson * 3. Neither the name of KTH nor the names of its contributors may be 18c19800e8SDoug Rabson * used to endorse or promote products derived from this software without 19c19800e8SDoug Rabson * specific prior written permission. 20c19800e8SDoug Rabson * 21c19800e8SDoug Rabson * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY 22c19800e8SDoug Rabson * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23c19800e8SDoug Rabson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24c19800e8SDoug Rabson * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE 25c19800e8SDoug Rabson * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26c19800e8SDoug Rabson * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27c19800e8SDoug Rabson * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 28c19800e8SDoug Rabson * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29c19800e8SDoug Rabson * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 30c19800e8SDoug Rabson * 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 */ 33c19800e8SDoug Rabson 34c19800e8SDoug Rabson #include "krb5/gsskrb5_locl.h" 35c19800e8SDoug Rabson #include <err.h> 36c19800e8SDoug Rabson #include <getarg.h> 37c19800e8SDoug Rabson #include "test_common.h" 38c19800e8SDoug Rabson 39c19800e8SDoug Rabson RCSID("$Id: test_context.c 20075 2007-01-31 06:05:19Z lha $"); 40c19800e8SDoug Rabson 41c19800e8SDoug Rabson static char *type_string; 42c19800e8SDoug Rabson static char *mech_string; 43c19800e8SDoug Rabson static char *ret_mech_string; 44c19800e8SDoug Rabson static int dns_canon_flag = -1; 45c19800e8SDoug Rabson static int mutual_auth_flag = 0; 46c19800e8SDoug Rabson static int dce_style_flag = 0; 47c19800e8SDoug Rabson static int wrapunwrap_flag = 0; 48c19800e8SDoug Rabson static int getverifymic_flag = 0; 49c19800e8SDoug Rabson static int deleg_flag = 0; 50c19800e8SDoug Rabson static int version_flag = 0; 51c19800e8SDoug Rabson static int verbose_flag = 0; 52c19800e8SDoug Rabson static int help_flag = 0; 53c19800e8SDoug Rabson 54c19800e8SDoug Rabson static struct { 55c19800e8SDoug Rabson const char *name; 56c19800e8SDoug Rabson gss_OID *oid; 57c19800e8SDoug Rabson } o2n[] = { 58c19800e8SDoug Rabson { "krb5", &GSS_KRB5_MECHANISM }, 59c19800e8SDoug Rabson { "spnego", &GSS_SPNEGO_MECHANISM }, 60c19800e8SDoug Rabson { "ntlm", &GSS_NTLM_MECHANISM }, 61c19800e8SDoug Rabson { "sasl-digest-md5", &GSS_SASL_DIGEST_MD5_MECHANISM } 62c19800e8SDoug Rabson }; 63c19800e8SDoug Rabson 64c19800e8SDoug Rabson static gss_OID 65c19800e8SDoug Rabson string_to_oid(const char *name) 66c19800e8SDoug Rabson { 67c19800e8SDoug Rabson int i; 68c19800e8SDoug Rabson for (i = 0; i < sizeof(o2n)/sizeof(o2n[0]); i++) 69c19800e8SDoug Rabson if (strcasecmp(name, o2n[i].name) == 0) 70c19800e8SDoug Rabson return *o2n[i].oid; 71c19800e8SDoug Rabson errx(1, "name %s not unknown", name); 72c19800e8SDoug Rabson } 73c19800e8SDoug Rabson 74c19800e8SDoug Rabson static const char * 75c19800e8SDoug Rabson oid_to_string(const gss_OID oid) 76c19800e8SDoug Rabson { 77c19800e8SDoug Rabson int i; 78c19800e8SDoug Rabson for (i = 0; i < sizeof(o2n)/sizeof(o2n[0]); i++) 79c19800e8SDoug Rabson if (gss_oid_equal(oid, *o2n[i].oid)) 80c19800e8SDoug Rabson return o2n[i].name; 81c19800e8SDoug Rabson return "unknown oid"; 82c19800e8SDoug Rabson } 83c19800e8SDoug Rabson 84c19800e8SDoug Rabson static void 85c19800e8SDoug Rabson loop(gss_OID mechoid, 86c19800e8SDoug Rabson gss_OID nameoid, const char *target, 87c19800e8SDoug Rabson gss_cred_id_t init_cred, 88c19800e8SDoug Rabson gss_ctx_id_t *sctx, gss_ctx_id_t *cctx, 89c19800e8SDoug Rabson gss_OID *actual_mech, 90c19800e8SDoug Rabson gss_cred_id_t *deleg_cred) 91c19800e8SDoug Rabson { 92c19800e8SDoug Rabson int server_done = 0, client_done = 0; 93c19800e8SDoug Rabson OM_uint32 maj_stat, min_stat; 94c19800e8SDoug Rabson gss_name_t gss_target_name; 95c19800e8SDoug Rabson gss_buffer_desc input_token, output_token; 96c19800e8SDoug Rabson OM_uint32 flags = 0, ret_cflags, ret_sflags; 97c19800e8SDoug Rabson gss_OID actual_mech_client; 98c19800e8SDoug Rabson gss_OID actual_mech_server; 99c19800e8SDoug Rabson 100c19800e8SDoug Rabson *actual_mech = GSS_C_NO_OID; 101c19800e8SDoug Rabson 102c19800e8SDoug Rabson flags |= GSS_C_INTEG_FLAG; 103c19800e8SDoug Rabson flags |= GSS_C_CONF_FLAG; 104c19800e8SDoug Rabson 105c19800e8SDoug Rabson if (mutual_auth_flag) 106c19800e8SDoug Rabson flags |= GSS_C_MUTUAL_FLAG; 107c19800e8SDoug Rabson if (dce_style_flag) 108c19800e8SDoug Rabson flags |= GSS_C_DCE_STYLE; 109c19800e8SDoug Rabson if (deleg_flag) 110c19800e8SDoug Rabson flags |= GSS_C_DELEG_FLAG; 111c19800e8SDoug Rabson 112c19800e8SDoug Rabson input_token.value = rk_UNCONST(target); 113c19800e8SDoug Rabson input_token.length = strlen(target); 114c19800e8SDoug Rabson 115c19800e8SDoug Rabson maj_stat = gss_import_name(&min_stat, 116c19800e8SDoug Rabson &input_token, 117c19800e8SDoug Rabson nameoid, 118c19800e8SDoug Rabson &gss_target_name); 119c19800e8SDoug Rabson if (GSS_ERROR(maj_stat)) 120c19800e8SDoug Rabson err(1, "import name creds failed with: %d", maj_stat); 121c19800e8SDoug Rabson 122c19800e8SDoug Rabson input_token.length = 0; 123c19800e8SDoug Rabson input_token.value = NULL; 124c19800e8SDoug Rabson 125c19800e8SDoug Rabson while (!server_done || !client_done) { 126c19800e8SDoug Rabson 127c19800e8SDoug Rabson maj_stat = gss_init_sec_context(&min_stat, 128c19800e8SDoug Rabson init_cred, 129c19800e8SDoug Rabson cctx, 130c19800e8SDoug Rabson gss_target_name, 131c19800e8SDoug Rabson mechoid, 132c19800e8SDoug Rabson flags, 133c19800e8SDoug Rabson 0, 134c19800e8SDoug Rabson NULL, 135c19800e8SDoug Rabson &input_token, 136c19800e8SDoug Rabson &actual_mech_client, 137c19800e8SDoug Rabson &output_token, 138c19800e8SDoug Rabson &ret_cflags, 139c19800e8SDoug Rabson NULL); 140c19800e8SDoug Rabson if (GSS_ERROR(maj_stat)) 141c19800e8SDoug Rabson errx(1, "init_sec_context: %s", 142c19800e8SDoug Rabson gssapi_err(maj_stat, min_stat, mechoid)); 143c19800e8SDoug Rabson if (maj_stat & GSS_S_CONTINUE_NEEDED) 144c19800e8SDoug Rabson ; 145c19800e8SDoug Rabson else 146c19800e8SDoug Rabson client_done = 1; 147c19800e8SDoug Rabson 148c19800e8SDoug Rabson if (client_done && server_done) 149c19800e8SDoug Rabson break; 150c19800e8SDoug Rabson 151c19800e8SDoug Rabson if (input_token.length != 0) 152c19800e8SDoug Rabson gss_release_buffer(&min_stat, &input_token); 153c19800e8SDoug Rabson 154c19800e8SDoug Rabson maj_stat = gss_accept_sec_context(&min_stat, 155c19800e8SDoug Rabson sctx, 156c19800e8SDoug Rabson GSS_C_NO_CREDENTIAL, 157c19800e8SDoug Rabson &output_token, 158c19800e8SDoug Rabson GSS_C_NO_CHANNEL_BINDINGS, 159c19800e8SDoug Rabson NULL, 160c19800e8SDoug Rabson &actual_mech_server, 161c19800e8SDoug Rabson &input_token, 162c19800e8SDoug Rabson &ret_sflags, 163c19800e8SDoug Rabson NULL, 164c19800e8SDoug Rabson deleg_cred); 165c19800e8SDoug Rabson if (GSS_ERROR(maj_stat)) 166c19800e8SDoug Rabson errx(1, "accept_sec_context: %s", 167c19800e8SDoug Rabson gssapi_err(maj_stat, min_stat, actual_mech_server)); 168c19800e8SDoug Rabson 169c19800e8SDoug Rabson if (verbose_flag) 170c19800e8SDoug Rabson printf("%.*s", (int)input_token.length, (char *)input_token.value); 171c19800e8SDoug Rabson 172c19800e8SDoug Rabson if (output_token.length != 0) 173c19800e8SDoug Rabson gss_release_buffer(&min_stat, &output_token); 174c19800e8SDoug Rabson 175c19800e8SDoug Rabson if (maj_stat & GSS_S_CONTINUE_NEEDED) 176c19800e8SDoug Rabson ; 177c19800e8SDoug Rabson else 178c19800e8SDoug Rabson server_done = 1; 179c19800e8SDoug Rabson } 180c19800e8SDoug Rabson if (output_token.length != 0) 181c19800e8SDoug Rabson gss_release_buffer(&min_stat, &output_token); 182c19800e8SDoug Rabson if (input_token.length != 0) 183c19800e8SDoug Rabson gss_release_buffer(&min_stat, &input_token); 184c19800e8SDoug Rabson gss_release_name(&min_stat, &gss_target_name); 185c19800e8SDoug Rabson 186c19800e8SDoug Rabson if (gss_oid_equal(actual_mech_server, actual_mech_client) == 0) 187c19800e8SDoug Rabson errx(1, "mech mismatch"); 188c19800e8SDoug Rabson *actual_mech = actual_mech_server; 189c19800e8SDoug Rabson } 190c19800e8SDoug Rabson 191c19800e8SDoug Rabson static void 192c19800e8SDoug Rabson wrapunwrap(gss_ctx_id_t cctx, gss_ctx_id_t sctx, gss_OID mechoid) 193c19800e8SDoug Rabson { 194c19800e8SDoug Rabson gss_buffer_desc input_token, output_token, output_token2; 195c19800e8SDoug Rabson OM_uint32 min_stat, maj_stat; 196c19800e8SDoug Rabson int32_t flags = 0; 197c19800e8SDoug Rabson gss_qop_t qop_state; 198c19800e8SDoug Rabson int conf_state; 199c19800e8SDoug Rabson 200c19800e8SDoug Rabson input_token.value = "foo"; 201c19800e8SDoug Rabson input_token.length = 3; 202c19800e8SDoug Rabson 203c19800e8SDoug Rabson maj_stat = gss_wrap(&min_stat, cctx, flags, 0, &input_token, 204c19800e8SDoug Rabson &conf_state, &output_token); 205c19800e8SDoug Rabson if (maj_stat != GSS_S_COMPLETE) 206c19800e8SDoug Rabson errx(1, "gss_wrap failed: %s", 207c19800e8SDoug Rabson gssapi_err(maj_stat, min_stat, mechoid)); 208c19800e8SDoug Rabson 209c19800e8SDoug Rabson maj_stat = gss_unwrap(&min_stat, sctx, &output_token, 210c19800e8SDoug Rabson &output_token2, &conf_state, &qop_state); 211c19800e8SDoug Rabson if (maj_stat != GSS_S_COMPLETE) 212c19800e8SDoug Rabson errx(1, "gss_unwrap failed: %s", 213c19800e8SDoug Rabson gssapi_err(maj_stat, min_stat, mechoid)); 214c19800e8SDoug Rabson } 215c19800e8SDoug Rabson 216c19800e8SDoug Rabson static void 217c19800e8SDoug Rabson getverifymic(gss_ctx_id_t cctx, gss_ctx_id_t sctx, gss_OID mechoid) 218c19800e8SDoug Rabson { 219c19800e8SDoug Rabson gss_buffer_desc input_token, output_token; 220c19800e8SDoug Rabson OM_uint32 min_stat, maj_stat; 221c19800e8SDoug Rabson gss_qop_t qop_state; 222c19800e8SDoug Rabson 223c19800e8SDoug Rabson input_token.value = "bar"; 224c19800e8SDoug Rabson input_token.length = 3; 225c19800e8SDoug Rabson 226c19800e8SDoug Rabson maj_stat = gss_get_mic(&min_stat, cctx, 0, &input_token, 227c19800e8SDoug Rabson &output_token); 228c19800e8SDoug Rabson if (maj_stat != GSS_S_COMPLETE) 229c19800e8SDoug Rabson errx(1, "gss_get_mic failed: %s", 230c19800e8SDoug Rabson gssapi_err(maj_stat, min_stat, mechoid)); 231c19800e8SDoug Rabson 232c19800e8SDoug Rabson maj_stat = gss_verify_mic(&min_stat, sctx, &input_token, 233c19800e8SDoug Rabson &output_token, &qop_state); 234c19800e8SDoug Rabson if (maj_stat != GSS_S_COMPLETE) 235c19800e8SDoug Rabson errx(1, "gss_verify_mic failed: %s", 236c19800e8SDoug Rabson gssapi_err(maj_stat, min_stat, mechoid)); 237c19800e8SDoug Rabson } 238c19800e8SDoug Rabson 239c19800e8SDoug Rabson 240c19800e8SDoug Rabson /* 241c19800e8SDoug Rabson * 242c19800e8SDoug Rabson */ 243c19800e8SDoug Rabson 244c19800e8SDoug Rabson static struct getargs args[] = { 245c19800e8SDoug Rabson {"name-type",0, arg_string, &type_string, "type of name", NULL }, 246c19800e8SDoug Rabson {"mech-type",0, arg_string, &mech_string, "type of mech", NULL }, 247c19800e8SDoug Rabson {"ret-mech-type",0, arg_string, &ret_mech_string, 248c19800e8SDoug Rabson "type of return mech", NULL }, 249c19800e8SDoug Rabson {"dns-canonicalize",0,arg_negative_flag, &dns_canon_flag, 250c19800e8SDoug Rabson "use dns to canonicalize", NULL }, 251c19800e8SDoug Rabson {"mutual-auth",0, arg_flag, &mutual_auth_flag,"mutual auth", NULL }, 252c19800e8SDoug Rabson {"dce-style",0, arg_flag, &dce_style_flag, "dce-style", NULL }, 253c19800e8SDoug Rabson {"wrapunwrap",0, arg_flag, &wrapunwrap_flag, "wrap/unwrap", NULL }, 254c19800e8SDoug Rabson {"getverifymic",0, arg_flag, &getverifymic_flag, 255c19800e8SDoug Rabson "get and verify mic", NULL }, 256c19800e8SDoug Rabson {"delegate",0, arg_flag, &deleg_flag, "delegate credential", NULL }, 257c19800e8SDoug Rabson {"version", 0, arg_flag, &version_flag, "print version", NULL }, 258c19800e8SDoug Rabson {"verbose", 'v', arg_flag, &verbose_flag, "verbose", NULL }, 259c19800e8SDoug Rabson {"help", 0, arg_flag, &help_flag, NULL, NULL } 260c19800e8SDoug Rabson }; 261c19800e8SDoug Rabson 262c19800e8SDoug Rabson static void 263c19800e8SDoug Rabson usage (int ret) 264c19800e8SDoug Rabson { 265c19800e8SDoug Rabson arg_printusage (args, sizeof(args)/sizeof(*args), 266c19800e8SDoug Rabson NULL, "service@host"); 267c19800e8SDoug Rabson exit (ret); 268c19800e8SDoug Rabson } 269c19800e8SDoug Rabson 270c19800e8SDoug Rabson int 271c19800e8SDoug Rabson main(int argc, char **argv) 272c19800e8SDoug Rabson { 273c19800e8SDoug Rabson int optind = 0; 274c19800e8SDoug Rabson OM_uint32 min_stat, maj_stat; 275c19800e8SDoug Rabson gss_ctx_id_t cctx, sctx; 276c19800e8SDoug Rabson void *ctx; 277c19800e8SDoug Rabson gss_OID nameoid, mechoid, actual_mech; 278c19800e8SDoug Rabson gss_cred_id_t deleg_cred = GSS_C_NO_CREDENTIAL; 279c19800e8SDoug Rabson 280c19800e8SDoug Rabson setprogname(argv[0]); 281c19800e8SDoug Rabson 282c19800e8SDoug Rabson cctx = sctx = GSS_C_NO_CONTEXT; 283c19800e8SDoug Rabson 284c19800e8SDoug Rabson if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind)) 285c19800e8SDoug Rabson usage(1); 286c19800e8SDoug Rabson 287c19800e8SDoug Rabson if (help_flag) 288c19800e8SDoug Rabson usage (0); 289c19800e8SDoug Rabson 290c19800e8SDoug Rabson if(version_flag){ 291c19800e8SDoug Rabson print_version(NULL); 292c19800e8SDoug Rabson exit(0); 293c19800e8SDoug Rabson } 294c19800e8SDoug Rabson 295c19800e8SDoug Rabson argc -= optind; 296c19800e8SDoug Rabson argv += optind; 297c19800e8SDoug Rabson 298c19800e8SDoug Rabson if (argc != 1) 299c19800e8SDoug Rabson usage(1); 300c19800e8SDoug Rabson 301c19800e8SDoug Rabson if (dns_canon_flag != -1) 302c19800e8SDoug Rabson gsskrb5_set_dns_canonicalize(dns_canon_flag); 303c19800e8SDoug Rabson 304c19800e8SDoug Rabson if (type_string == NULL) 305c19800e8SDoug Rabson nameoid = GSS_C_NT_HOSTBASED_SERVICE; 306c19800e8SDoug Rabson else if (strcmp(type_string, "hostbased-service") == 0) 307c19800e8SDoug Rabson nameoid = GSS_C_NT_HOSTBASED_SERVICE; 308c19800e8SDoug Rabson else if (strcmp(type_string, "krb5-principal-name") == 0) 309c19800e8SDoug Rabson nameoid = GSS_KRB5_NT_PRINCIPAL_NAME; 310c19800e8SDoug Rabson else 311c19800e8SDoug Rabson errx(1, "%s not suppported", type_string); 312c19800e8SDoug Rabson 313c19800e8SDoug Rabson if (mech_string == NULL) 314c19800e8SDoug Rabson mechoid = GSS_KRB5_MECHANISM; 315c19800e8SDoug Rabson else 316c19800e8SDoug Rabson mechoid = string_to_oid(mech_string); 317c19800e8SDoug Rabson 318c19800e8SDoug Rabson loop(mechoid, nameoid, argv[0], GSS_C_NO_CREDENTIAL, 319c19800e8SDoug Rabson &sctx, &cctx, &actual_mech, &deleg_cred); 320c19800e8SDoug Rabson 321c19800e8SDoug Rabson if (verbose_flag) 322c19800e8SDoug Rabson printf("resulting mech: %s\n", oid_to_string(actual_mech)); 323c19800e8SDoug Rabson 324c19800e8SDoug Rabson if (ret_mech_string) { 325c19800e8SDoug Rabson gss_OID retoid; 326c19800e8SDoug Rabson 327c19800e8SDoug Rabson retoid = string_to_oid(ret_mech_string); 328c19800e8SDoug Rabson 329c19800e8SDoug Rabson if (gss_oid_equal(retoid, actual_mech) == 0) 330c19800e8SDoug Rabson errx(1, "actual_mech mech is not the expected type %s", 331c19800e8SDoug Rabson ret_mech_string); 332c19800e8SDoug Rabson } 333c19800e8SDoug Rabson 334c19800e8SDoug Rabson /* XXX should be actual_mech */ 335c19800e8SDoug Rabson if (gss_oid_equal(mechoid, GSS_KRB5_MECHANISM)) { 336c19800e8SDoug Rabson krb5_context context; 337c19800e8SDoug Rabson time_t time, skew; 338c19800e8SDoug Rabson gss_buffer_desc authz_data; 339c19800e8SDoug Rabson gss_buffer_desc in, out1, out2; 340c19800e8SDoug Rabson krb5_keyblock *keyblock, *keyblock2; 341c19800e8SDoug Rabson krb5_timestamp now; 342c19800e8SDoug Rabson krb5_error_code ret; 343c19800e8SDoug Rabson 344c19800e8SDoug Rabson ret = krb5_init_context(&context); 345c19800e8SDoug Rabson if (ret) 346c19800e8SDoug Rabson errx(1, "krb5_init_context"); 347c19800e8SDoug Rabson 348c19800e8SDoug Rabson ret = krb5_timeofday(context, &now); 349c19800e8SDoug Rabson if (ret) 350c19800e8SDoug Rabson errx(1, "krb5_timeofday failed"); 351c19800e8SDoug Rabson 352c19800e8SDoug Rabson /* client */ 353c19800e8SDoug Rabson maj_stat = gss_krb5_export_lucid_sec_context(&min_stat, 354c19800e8SDoug Rabson &cctx, 355c19800e8SDoug Rabson 1, /* version */ 356c19800e8SDoug Rabson &ctx); 357c19800e8SDoug Rabson if (maj_stat != GSS_S_COMPLETE) 358c19800e8SDoug Rabson errx(1, "gss_krb5_export_lucid_sec_context failed: %s", 359c19800e8SDoug Rabson gssapi_err(maj_stat, min_stat, actual_mech)); 360c19800e8SDoug Rabson 361c19800e8SDoug Rabson 362c19800e8SDoug Rabson maj_stat = gss_krb5_free_lucid_sec_context(&maj_stat, ctx); 363c19800e8SDoug Rabson if (maj_stat != GSS_S_COMPLETE) 364c19800e8SDoug Rabson errx(1, "gss_krb5_free_lucid_sec_context failed: %s", 365c19800e8SDoug Rabson gssapi_err(maj_stat, min_stat, actual_mech)); 366c19800e8SDoug Rabson 367c19800e8SDoug Rabson /* server */ 368c19800e8SDoug Rabson maj_stat = gss_krb5_export_lucid_sec_context(&min_stat, 369c19800e8SDoug Rabson &sctx, 370c19800e8SDoug Rabson 1, /* version */ 371c19800e8SDoug Rabson &ctx); 372c19800e8SDoug Rabson if (maj_stat != GSS_S_COMPLETE) 373c19800e8SDoug Rabson errx(1, "gss_krb5_export_lucid_sec_context failed: %s", 374c19800e8SDoug Rabson gssapi_err(maj_stat, min_stat, actual_mech)); 375c19800e8SDoug Rabson maj_stat = gss_krb5_free_lucid_sec_context(&min_stat, ctx); 376c19800e8SDoug Rabson if (maj_stat != GSS_S_COMPLETE) 377c19800e8SDoug Rabson errx(1, "gss_krb5_free_lucid_sec_context failed: %s", 378c19800e8SDoug Rabson gssapi_err(maj_stat, min_stat, actual_mech)); 379c19800e8SDoug Rabson 380c19800e8SDoug Rabson maj_stat = gsskrb5_extract_authtime_from_sec_context(&min_stat, 381c19800e8SDoug Rabson sctx, 382c19800e8SDoug Rabson &time); 383c19800e8SDoug Rabson if (maj_stat != GSS_S_COMPLETE) 384c19800e8SDoug Rabson errx(1, "gsskrb5_extract_authtime_from_sec_context failed: %s", 385c19800e8SDoug Rabson gssapi_err(maj_stat, min_stat, actual_mech)); 386c19800e8SDoug Rabson 387c19800e8SDoug Rabson skew = abs(time - now); 388c19800e8SDoug Rabson if (skew > krb5_get_max_time_skew(context)) { 389c19800e8SDoug Rabson errx(1, "gsskrb5_extract_authtime_from_sec_context failed: " 390c19800e8SDoug Rabson "time skew too great %llu > %llu", 391c19800e8SDoug Rabson (unsigned long long)skew, 392c19800e8SDoug Rabson (unsigned long long)krb5_get_max_time_skew(context)); 393c19800e8SDoug Rabson } 394c19800e8SDoug Rabson 395c19800e8SDoug Rabson maj_stat = gsskrb5_extract_service_keyblock(&min_stat, 396c19800e8SDoug Rabson sctx, 397c19800e8SDoug Rabson &keyblock); 398c19800e8SDoug Rabson if (maj_stat != GSS_S_COMPLETE) 399c19800e8SDoug Rabson errx(1, "gsskrb5_export_service_keyblock failed: %s", 400c19800e8SDoug Rabson gssapi_err(maj_stat, min_stat, actual_mech)); 401c19800e8SDoug Rabson 402c19800e8SDoug Rabson krb5_free_keyblock(context, keyblock); 403c19800e8SDoug Rabson 404c19800e8SDoug Rabson maj_stat = gsskrb5_get_subkey(&min_stat, 405c19800e8SDoug Rabson sctx, 406c19800e8SDoug Rabson &keyblock); 407c19800e8SDoug Rabson if (maj_stat != GSS_S_COMPLETE 408c19800e8SDoug Rabson && (!(maj_stat == GSS_S_FAILURE && min_stat == GSS_KRB5_S_KG_NO_SUBKEY))) 409c19800e8SDoug Rabson errx(1, "gsskrb5_get_subkey server failed: %s", 410c19800e8SDoug Rabson gssapi_err(maj_stat, min_stat, actual_mech)); 411c19800e8SDoug Rabson 412c19800e8SDoug Rabson if (maj_stat != GSS_S_COMPLETE) 413c19800e8SDoug Rabson keyblock = NULL; 414c19800e8SDoug Rabson 415c19800e8SDoug Rabson maj_stat = gsskrb5_get_subkey(&min_stat, 416c19800e8SDoug Rabson cctx, 417c19800e8SDoug Rabson &keyblock2); 418c19800e8SDoug Rabson if (maj_stat != GSS_S_COMPLETE 419c19800e8SDoug Rabson && (!(maj_stat == GSS_S_FAILURE && min_stat == GSS_KRB5_S_KG_NO_SUBKEY))) 420c19800e8SDoug Rabson errx(1, "gsskrb5_get_subkey client failed: %s", 421c19800e8SDoug Rabson gssapi_err(maj_stat, min_stat, actual_mech)); 422c19800e8SDoug Rabson 423c19800e8SDoug Rabson if (maj_stat != GSS_S_COMPLETE) 424c19800e8SDoug Rabson keyblock2 = NULL; 425c19800e8SDoug Rabson 426c19800e8SDoug Rabson if (keyblock || keyblock2) { 427c19800e8SDoug Rabson if (keyblock == NULL) 428c19800e8SDoug Rabson errx(1, "server missing token keyblock"); 429c19800e8SDoug Rabson if (keyblock2 == NULL) 430c19800e8SDoug Rabson errx(1, "client missing token keyblock"); 431c19800e8SDoug Rabson 432c19800e8SDoug Rabson if (keyblock->keytype != keyblock2->keytype) 433c19800e8SDoug Rabson errx(1, "enctype mismatch"); 434c19800e8SDoug Rabson if (keyblock->keyvalue.length != keyblock2->keyvalue.length) 435c19800e8SDoug Rabson errx(1, "key length mismatch"); 436c19800e8SDoug Rabson if (memcmp(keyblock->keyvalue.data, keyblock2->keyvalue.data, 437c19800e8SDoug Rabson keyblock2->keyvalue.length) != 0) 438c19800e8SDoug Rabson errx(1, "key data mismatch"); 439c19800e8SDoug Rabson } 440c19800e8SDoug Rabson 441c19800e8SDoug Rabson if (keyblock) 442c19800e8SDoug Rabson krb5_free_keyblock(context, keyblock); 443c19800e8SDoug Rabson if (keyblock2) 444c19800e8SDoug Rabson krb5_free_keyblock(context, keyblock2); 445c19800e8SDoug Rabson 446c19800e8SDoug Rabson maj_stat = gsskrb5_get_initiator_subkey(&min_stat, 447c19800e8SDoug Rabson sctx, 448c19800e8SDoug Rabson &keyblock); 449c19800e8SDoug Rabson if (maj_stat != GSS_S_COMPLETE 450c19800e8SDoug Rabson && (!(maj_stat == GSS_S_FAILURE && min_stat == GSS_KRB5_S_KG_NO_SUBKEY))) 451c19800e8SDoug Rabson errx(1, "gsskrb5_get_initiator_subkey failed: %s", 452c19800e8SDoug Rabson gssapi_err(maj_stat, min_stat, actual_mech)); 453c19800e8SDoug Rabson 454c19800e8SDoug Rabson if (maj_stat == GSS_S_COMPLETE) 455c19800e8SDoug Rabson krb5_free_keyblock(context, keyblock); 456c19800e8SDoug Rabson 457c19800e8SDoug Rabson maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat, 458c19800e8SDoug Rabson sctx, 459c19800e8SDoug Rabson 128, 460c19800e8SDoug Rabson &authz_data); 461c19800e8SDoug Rabson if (maj_stat == GSS_S_COMPLETE) 462c19800e8SDoug Rabson gss_release_buffer(&min_stat, &authz_data); 463c19800e8SDoug Rabson 464c19800e8SDoug Rabson krb5_free_context(context); 465c19800e8SDoug Rabson 466c19800e8SDoug Rabson 467c19800e8SDoug Rabson memset(&out1, 0, sizeof(out1)); 468c19800e8SDoug Rabson memset(&out2, 0, sizeof(out2)); 469c19800e8SDoug Rabson 470c19800e8SDoug Rabson in.value = "foo"; 471c19800e8SDoug Rabson in.length = 3; 472c19800e8SDoug Rabson 473c19800e8SDoug Rabson gss_pseudo_random(&min_stat, sctx, GSS_C_PRF_KEY_FULL, &in, 474c19800e8SDoug Rabson 100, &out1); 475c19800e8SDoug Rabson gss_pseudo_random(&min_stat, cctx, GSS_C_PRF_KEY_FULL, &in, 476c19800e8SDoug Rabson 100, &out2); 477c19800e8SDoug Rabson 478c19800e8SDoug Rabson if (out1.length != out2.length) 479c19800e8SDoug Rabson errx(1, "prf len mismatch"); 480c19800e8SDoug Rabson if (memcmp(out1.value, out2.value, out1.length) != 0) 481c19800e8SDoug Rabson errx(1, "prf data mismatch"); 482c19800e8SDoug Rabson 483c19800e8SDoug Rabson gss_release_buffer(&min_stat, &out1); 484c19800e8SDoug Rabson 485c19800e8SDoug Rabson gss_pseudo_random(&min_stat, sctx, GSS_C_PRF_KEY_FULL, &in, 486c19800e8SDoug Rabson 100, &out1); 487c19800e8SDoug Rabson 488c19800e8SDoug Rabson if (out1.length != out2.length) 489c19800e8SDoug Rabson errx(1, "prf len mismatch"); 490c19800e8SDoug Rabson if (memcmp(out1.value, out2.value, out1.length) != 0) 491c19800e8SDoug Rabson errx(1, "prf data mismatch"); 492c19800e8SDoug Rabson 493c19800e8SDoug Rabson gss_release_buffer(&min_stat, &out1); 494c19800e8SDoug Rabson gss_release_buffer(&min_stat, &out2); 495c19800e8SDoug Rabson 496c19800e8SDoug Rabson in.value = "bar"; 497c19800e8SDoug Rabson in.length = 3; 498c19800e8SDoug Rabson 499c19800e8SDoug Rabson gss_pseudo_random(&min_stat, sctx, GSS_C_PRF_KEY_PARTIAL, &in, 500c19800e8SDoug Rabson 100, &out1); 501c19800e8SDoug Rabson gss_pseudo_random(&min_stat, cctx, GSS_C_PRF_KEY_PARTIAL, &in, 502c19800e8SDoug Rabson 100, &out2); 503c19800e8SDoug Rabson 504c19800e8SDoug Rabson if (out1.length != out2.length) 505c19800e8SDoug Rabson errx(1, "prf len mismatch"); 506c19800e8SDoug Rabson if (memcmp(out1.value, out2.value, out1.length) != 0) 507c19800e8SDoug Rabson errx(1, "prf data mismatch"); 508c19800e8SDoug Rabson 509c19800e8SDoug Rabson gss_release_buffer(&min_stat, &out1); 510c19800e8SDoug Rabson gss_release_buffer(&min_stat, &out2); 511c19800e8SDoug Rabson 512c19800e8SDoug Rabson wrapunwrap_flag = 1; 513c19800e8SDoug Rabson getverifymic_flag = 1; 514c19800e8SDoug Rabson } 515c19800e8SDoug Rabson 516c19800e8SDoug Rabson if (wrapunwrap_flag) { 517c19800e8SDoug Rabson wrapunwrap(cctx, sctx, actual_mech); 518c19800e8SDoug Rabson wrapunwrap(cctx, sctx, actual_mech); 519c19800e8SDoug Rabson wrapunwrap(sctx, cctx, actual_mech); 520c19800e8SDoug Rabson wrapunwrap(sctx, cctx, actual_mech); 521c19800e8SDoug Rabson } 522c19800e8SDoug Rabson if (getverifymic_flag) { 523c19800e8SDoug Rabson getverifymic(cctx, sctx, actual_mech); 524c19800e8SDoug Rabson getverifymic(cctx, sctx, actual_mech); 525c19800e8SDoug Rabson getverifymic(sctx, cctx, actual_mech); 526c19800e8SDoug Rabson getverifymic(sctx, cctx, actual_mech); 527c19800e8SDoug Rabson } 528c19800e8SDoug Rabson 529c19800e8SDoug Rabson gss_delete_sec_context(&min_stat, &cctx, NULL); 530c19800e8SDoug Rabson gss_delete_sec_context(&min_stat, &sctx, NULL); 531c19800e8SDoug Rabson 532c19800e8SDoug Rabson if (deleg_cred != GSS_C_NO_CREDENTIAL) { 533c19800e8SDoug Rabson 534c19800e8SDoug Rabson loop(mechoid, nameoid, argv[0], deleg_cred, &cctx, &sctx, &actual_mech, NULL); 535c19800e8SDoug Rabson 536c19800e8SDoug Rabson gss_delete_sec_context(&min_stat, &cctx, NULL); 537c19800e8SDoug Rabson gss_delete_sec_context(&min_stat, &sctx, NULL); 538c19800e8SDoug Rabson 539c19800e8SDoug Rabson } 540c19800e8SDoug Rabson 541c19800e8SDoug Rabson return 0; 542c19800e8SDoug Rabson } 543