/crypto/heimdal/lib/gssapi/test_context.c
https://bitbucket.org/freebsd/freebsd-head/ · C · 970 lines · 756 code · 172 blank · 42 comment · 213 complexity · 2704fa17d924722cc3f24736124de54e MD5 · raw file
- /*
- * Copyright (c) 2006 - 2008 Kungliga Tekniska Hรถgskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 3. Neither the name of KTH nor the names of its contributors may be
- * used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include "krb5/gsskrb5_locl.h"
- #include <err.h>
- #include <getarg.h>
- #include <gssapi.h>
- #include <gssapi_krb5.h>
- #include <gssapi_spnego.h>
- #include <gssapi_ntlm.h>
- #include "test_common.h"
- static char *type_string;
- static char *mech_string;
- static char *ret_mech_string;
- static char *client_name;
- static char *client_password;
- static int dns_canon_flag = -1;
- static int mutual_auth_flag = 0;
- static int dce_style_flag = 0;
- static int wrapunwrap_flag = 0;
- static int iov_flag = 0;
- static int getverifymic_flag = 0;
- static int deleg_flag = 0;
- static int policy_deleg_flag = 0;
- static int server_no_deleg_flag = 0;
- static int ei_flag = 0;
- static char *gsskrb5_acceptor_identity = NULL;
- static char *session_enctype_string = NULL;
- static int client_time_offset = 0;
- static int server_time_offset = 0;
- static int max_loops = 0;
- static char *limit_enctype_string = NULL;
- static int version_flag = 0;
- static int verbose_flag = 0;
- static int help_flag = 0;
- static krb5_context context;
- static krb5_enctype limit_enctype = 0;
- static struct {
- const char *name;
- gss_OID oid;
- } o2n[] = {
- { "krb5", NULL /* GSS_KRB5_MECHANISM */ },
- { "spnego", NULL /* GSS_SPNEGO_MECHANISM */ },
- { "ntlm", NULL /* GSS_NTLM_MECHANISM */ },
- { "sasl-digest-md5", NULL /* GSS_SASL_DIGEST_MD5_MECHANISM */ }
- };
- static void
- init_o2n(void)
- {
- o2n[0].oid = GSS_KRB5_MECHANISM;
- o2n[1].oid = GSS_SPNEGO_MECHANISM;
- o2n[2].oid = GSS_NTLM_MECHANISM;
- o2n[3].oid = GSS_SASL_DIGEST_MD5_MECHANISM;
- }
- static gss_OID
- string_to_oid(const char *name)
- {
- int i;
- for (i = 0; i < sizeof(o2n)/sizeof(o2n[0]); i++)
- if (strcasecmp(name, o2n[i].name) == 0)
- return o2n[i].oid;
- errx(1, "name '%s' not unknown", name);
- }
- static const char *
- oid_to_string(const gss_OID oid)
- {
- int i;
- for (i = 0; i < sizeof(o2n)/sizeof(o2n[0]); i++)
- if (gss_oid_equal(oid, o2n[i].oid))
- return o2n[i].name;
- return "unknown oid";
- }
- static void
- loop(gss_OID mechoid,
- gss_OID nameoid, const char *target,
- gss_cred_id_t init_cred,
- gss_ctx_id_t *sctx, gss_ctx_id_t *cctx,
- gss_OID *actual_mech,
- gss_cred_id_t *deleg_cred)
- {
- int server_done = 0, client_done = 0;
- int num_loops = 0;
- OM_uint32 maj_stat, min_stat;
- gss_name_t gss_target_name;
- gss_buffer_desc input_token, output_token;
- OM_uint32 flags = 0, ret_cflags, ret_sflags;
- gss_OID actual_mech_client;
- gss_OID actual_mech_server;
- *actual_mech = GSS_C_NO_OID;
- flags |= GSS_C_INTEG_FLAG;
- flags |= GSS_C_CONF_FLAG;
- if (mutual_auth_flag)
- flags |= GSS_C_MUTUAL_FLAG;
- if (dce_style_flag)
- flags |= GSS_C_DCE_STYLE;
- if (deleg_flag)
- flags |= GSS_C_DELEG_FLAG;
- if (policy_deleg_flag)
- flags |= GSS_C_DELEG_POLICY_FLAG;
- input_token.value = rk_UNCONST(target);
- input_token.length = strlen(target);
- maj_stat = gss_import_name(&min_stat,
- &input_token,
- nameoid,
- &gss_target_name);
- if (GSS_ERROR(maj_stat))
- err(1, "import name creds failed with: %d", maj_stat);
- input_token.length = 0;
- input_token.value = NULL;
- while (!server_done || !client_done) {
- num_loops++;
- gsskrb5_set_time_offset(client_time_offset);
- maj_stat = gss_init_sec_context(&min_stat,
- init_cred,
- cctx,
- gss_target_name,
- mechoid,
- flags,
- 0,
- NULL,
- &input_token,
- &actual_mech_client,
- &output_token,
- &ret_cflags,
- NULL);
- if (GSS_ERROR(maj_stat))
- errx(1, "init_sec_context: %s",
- gssapi_err(maj_stat, min_stat, mechoid));
- if (maj_stat & GSS_S_CONTINUE_NEEDED)
- ;
- else
- client_done = 1;
- gsskrb5_get_time_offset(&client_time_offset);
- if (client_done && server_done)
- break;
- if (input_token.length != 0)
- gss_release_buffer(&min_stat, &input_token);
- gsskrb5_set_time_offset(server_time_offset);
- maj_stat = gss_accept_sec_context(&min_stat,
- sctx,
- GSS_C_NO_CREDENTIAL,
- &output_token,
- GSS_C_NO_CHANNEL_BINDINGS,
- NULL,
- &actual_mech_server,
- &input_token,
- &ret_sflags,
- NULL,
- deleg_cred);
- if (GSS_ERROR(maj_stat))
- errx(1, "accept_sec_context: %s",
- gssapi_err(maj_stat, min_stat, actual_mech_server));
- gsskrb5_get_time_offset(&server_time_offset);
- if (output_token.length != 0)
- gss_release_buffer(&min_stat, &output_token);
- if (maj_stat & GSS_S_CONTINUE_NEEDED)
- ;
- else
- server_done = 1;
- }
- if (output_token.length != 0)
- gss_release_buffer(&min_stat, &output_token);
- if (input_token.length != 0)
- gss_release_buffer(&min_stat, &input_token);
- gss_release_name(&min_stat, &gss_target_name);
- if (deleg_flag || policy_deleg_flag) {
- if (server_no_deleg_flag) {
- if (*deleg_cred != GSS_C_NO_CREDENTIAL)
- errx(1, "got delegated cred but didn't expect one");
- } else if (*deleg_cred == GSS_C_NO_CREDENTIAL)
- errx(1, "asked for delegarated cred but did get one");
- } else if (*deleg_cred != GSS_C_NO_CREDENTIAL)
- errx(1, "got deleg_cred cred but didn't ask");
- if (gss_oid_equal(actual_mech_server, actual_mech_client) == 0)
- errx(1, "mech mismatch");
- *actual_mech = actual_mech_server;
- if (max_loops && num_loops > max_loops)
- errx(1, "num loops %d was lager then max loops %d",
- num_loops, max_loops);
- if (verbose_flag) {
- printf("server time offset: %d\n", server_time_offset);
- printf("client time offset: %d\n", client_time_offset);
- printf("num loops %d\n", num_loops);
- }
- }
- static void
- wrapunwrap(gss_ctx_id_t cctx, gss_ctx_id_t sctx, int flags, gss_OID mechoid)
- {
- gss_buffer_desc input_token, output_token, output_token2;
- OM_uint32 min_stat, maj_stat;
- gss_qop_t qop_state;
- int conf_state;
- input_token.value = "foo";
- input_token.length = 3;
- maj_stat = gss_wrap(&min_stat, cctx, flags, 0, &input_token,
- &conf_state, &output_token);
- if (maj_stat != GSS_S_COMPLETE)
- errx(1, "gss_wrap failed: %s",
- gssapi_err(maj_stat, min_stat, mechoid));
- maj_stat = gss_unwrap(&min_stat, sctx, &output_token,
- &output_token2, &conf_state, &qop_state);
- if (maj_stat != GSS_S_COMPLETE)
- errx(1, "gss_unwrap failed: %s",
- gssapi_err(maj_stat, min_stat, mechoid));
- gss_release_buffer(&min_stat, &output_token);
- gss_release_buffer(&min_stat, &output_token2);
- #if 0 /* doesn't work for NTLM yet */
- if (!!conf_state != !!flags)
- errx(1, "conf_state mismatch");
- #endif
- }
- #define USE_CONF 1
- #define USE_HEADER_ONLY 2
- #define USE_SIGN_ONLY 4
- #define FORCE_IOV 8
- static void
- wrapunwrap_iov(gss_ctx_id_t cctx, gss_ctx_id_t sctx, int flags, gss_OID mechoid)
- {
- krb5_data token, header, trailer;
- OM_uint32 min_stat, maj_stat;
- gss_qop_t qop_state;
- int conf_state, conf_state2;
- gss_iov_buffer_desc iov[6];
- unsigned char *p;
- int iov_len;
- char header_data[9] = "ABCheader";
- char trailer_data[10] = "trailerXYZ";
- char token_data[16] = "0123456789abcdef";
- memset(&iov, 0, sizeof(iov));
- if (flags & USE_SIGN_ONLY) {
- header.data = header_data;
- header.length = 9;
- trailer.data = trailer_data;
- trailer.length = 10;
- } else {
- header.data = NULL;
- header.length = 0;
- trailer.data = NULL;
- trailer.length = 0;
- }
- token.data = token_data;
- token.length = 16;
- iov_len = sizeof(iov)/sizeof(iov[0]);
- memset(iov, 0, sizeof(iov));
- iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER | GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE;
- if (header.length != 0) {
- iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
- iov[1].buffer.length = header.length;
- iov[1].buffer.value = header.data;
- } else {
- iov[1].type = GSS_IOV_BUFFER_TYPE_EMPTY;
- iov[1].buffer.length = 0;
- iov[1].buffer.value = NULL;
- }
- iov[2].type = GSS_IOV_BUFFER_TYPE_DATA;
- iov[2].buffer.length = token.length;
- iov[2].buffer.value = token.data;
- if (trailer.length != 0) {
- iov[3].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
- iov[3].buffer.length = trailer.length;
- iov[3].buffer.value = trailer.data;
- } else {
- iov[3].type = GSS_IOV_BUFFER_TYPE_EMPTY;
- iov[3].buffer.length = 0;
- iov[3].buffer.value = NULL;
- }
- if (dce_style_flag) {
- iov[4].type = GSS_IOV_BUFFER_TYPE_EMPTY;
- } else {
- iov[4].type = GSS_IOV_BUFFER_TYPE_PADDING | GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE;
- }
- iov[4].buffer.length = 0;
- iov[4].buffer.value = 0;
- if (dce_style_flag) {
- iov[5].type = GSS_IOV_BUFFER_TYPE_EMPTY;
- } else if (flags & USE_HEADER_ONLY) {
- iov[5].type = GSS_IOV_BUFFER_TYPE_EMPTY;
- } else {
- iov[5].type = GSS_IOV_BUFFER_TYPE_TRAILER | GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE;
- }
- iov[5].buffer.length = 0;
- iov[5].buffer.value = 0;
- maj_stat = gss_wrap_iov(&min_stat, cctx, dce_style_flag || flags & USE_CONF, 0, &conf_state,
- iov, iov_len);
- if (maj_stat != GSS_S_COMPLETE)
- errx(1, "gss_wrap_iov failed");
- token.length =
- iov[0].buffer.length +
- iov[1].buffer.length +
- iov[2].buffer.length +
- iov[3].buffer.length +
- iov[4].buffer.length +
- iov[5].buffer.length;
- token.data = emalloc(token.length);
- p = token.data;
- memcpy(p, iov[0].buffer.value, iov[0].buffer.length);
- p += iov[0].buffer.length;
- memcpy(p, iov[1].buffer.value, iov[1].buffer.length);
- p += iov[1].buffer.length;
- memcpy(p, iov[2].buffer.value, iov[2].buffer.length);
- p += iov[2].buffer.length;
- memcpy(p, iov[3].buffer.value, iov[3].buffer.length);
- p += iov[3].buffer.length;
- memcpy(p, iov[4].buffer.value, iov[4].buffer.length);
- p += iov[4].buffer.length;
- memcpy(p, iov[5].buffer.value, iov[5].buffer.length);
- p += iov[5].buffer.length;
- assert(p - ((unsigned char *)token.data) == token.length);
- if ((flags & (USE_SIGN_ONLY|FORCE_IOV)) == 0) {
- gss_buffer_desc input, output;
- input.value = token.data;
- input.length = token.length;
- maj_stat = gss_unwrap(&min_stat, sctx, &input,
- &output, &conf_state2, &qop_state);
- if (maj_stat != GSS_S_COMPLETE)
- errx(1, "gss_unwrap from gss_wrap_iov failed: %s",
- gssapi_err(maj_stat, min_stat, mechoid));
- gss_release_buffer(&min_stat, &output);
- } else {
- maj_stat = gss_unwrap_iov(&min_stat, sctx, &conf_state2, &qop_state,
- iov, iov_len);
- if (maj_stat != GSS_S_COMPLETE)
- errx(1, "gss_unwrap_iov failed: %x %s", flags,
- gssapi_err(maj_stat, min_stat, mechoid));
- }
- if (conf_state2 != conf_state)
- errx(1, "conf state wrong for iov: %x", flags);
- free(token.data);
- }
- static void
- getverifymic(gss_ctx_id_t cctx, gss_ctx_id_t sctx, gss_OID mechoid)
- {
- gss_buffer_desc input_token, output_token;
- OM_uint32 min_stat, maj_stat;
- gss_qop_t qop_state;
- input_token.value = "bar";
- input_token.length = 3;
- maj_stat = gss_get_mic(&min_stat, cctx, 0, &input_token,
- &output_token);
- if (maj_stat != GSS_S_COMPLETE)
- errx(1, "gss_get_mic failed: %s",
- gssapi_err(maj_stat, min_stat, mechoid));
- maj_stat = gss_verify_mic(&min_stat, sctx, &input_token,
- &output_token, &qop_state);
- if (maj_stat != GSS_S_COMPLETE)
- errx(1, "gss_verify_mic failed: %s",
- gssapi_err(maj_stat, min_stat, mechoid));
- gss_release_buffer(&min_stat, &output_token);
- }
- static void
- empty_release(void)
- {
- gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
- gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
- gss_name_t name = GSS_C_NO_NAME;
- gss_OID_set oidset = GSS_C_NO_OID_SET;
- OM_uint32 junk;
- gss_delete_sec_context(&junk, &ctx, NULL);
- gss_release_cred(&junk, &cred);
- gss_release_name(&junk, &name);
- gss_release_oid_set(&junk, &oidset);
- }
- /*
- *
- */
- static struct getargs args[] = {
- {"name-type",0, arg_string, &type_string, "type of name", NULL },
- {"mech-type",0, arg_string, &mech_string, "type of mech", NULL },
- {"ret-mech-type",0, arg_string, &ret_mech_string,
- "type of return mech", NULL },
- {"dns-canonicalize",0,arg_negative_flag, &dns_canon_flag,
- "use dns to canonicalize", NULL },
- {"mutual-auth",0, arg_flag, &mutual_auth_flag,"mutual auth", NULL },
- {"client-name", 0, arg_string, &client_name, "client name", NULL },
- {"client-password", 0, arg_string, &client_password, "client password", NULL },
- {"limit-enctype",0, arg_string, &limit_enctype_string, "enctype", NULL },
- {"dce-style",0, arg_flag, &dce_style_flag, "dce-style", NULL },
- {"wrapunwrap",0, arg_flag, &wrapunwrap_flag, "wrap/unwrap", NULL },
- {"iov", 0, arg_flag, &iov_flag, "wrap/unwrap iov", NULL },
- {"getverifymic",0, arg_flag, &getverifymic_flag,
- "get and verify mic", NULL },
- {"delegate",0, arg_flag, &deleg_flag, "delegate credential", NULL },
- {"policy-delegate",0, arg_flag, &policy_deleg_flag, "policy delegate credential", NULL },
- {"server-no-delegate",0, arg_flag, &server_no_deleg_flag,
- "server should get a credential", NULL },
- {"export-import-cred",0, arg_flag, &ei_flag, "test export/import cred", NULL },
- {"gsskrb5-acceptor-identity", 0, arg_string, &gsskrb5_acceptor_identity, "keytab", NULL },
- {"session-enctype", 0, arg_string, &session_enctype_string, "enctype", NULL },
- {"client-time-offset", 0, arg_integer, &client_time_offset, "time", NULL },
- {"server-time-offset", 0, arg_integer, &server_time_offset, "time", NULL },
- {"max-loops", 0, arg_integer, &max_loops, "time", NULL },
- {"version", 0, arg_flag, &version_flag, "print version", NULL },
- {"verbose", 'v', arg_flag, &verbose_flag, "verbose", NULL },
- {"help", 0, arg_flag, &help_flag, NULL, NULL }
- };
- static void
- usage (int ret)
- {
- arg_printusage (args, sizeof(args)/sizeof(*args),
- NULL, "service@host");
- exit (ret);
- }
- int
- main(int argc, char **argv)
- {
- int optind = 0;
- OM_uint32 min_stat, maj_stat;
- gss_ctx_id_t cctx, sctx;
- void *ctx;
- gss_OID nameoid, mechoid, actual_mech, actual_mech2;
- gss_cred_id_t client_cred = GSS_C_NO_CREDENTIAL, deleg_cred = GSS_C_NO_CREDENTIAL;
- gss_name_t cname = GSS_C_NO_NAME;
- gss_buffer_desc credential_data = GSS_C_EMPTY_BUFFER;
- setprogname(argv[0]);
- init_o2n();
- if (krb5_init_context(&context))
- errx(1, "krb5_init_context");
- cctx = sctx = GSS_C_NO_CONTEXT;
- if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind))
- usage(1);
- if (help_flag)
- usage (0);
- if(version_flag){
- print_version(NULL);
- exit(0);
- }
- argc -= optind;
- argv += optind;
- if (argc != 1)
- usage(1);
- if (dns_canon_flag != -1)
- gsskrb5_set_dns_canonicalize(dns_canon_flag);
- if (type_string == NULL)
- nameoid = GSS_C_NT_HOSTBASED_SERVICE;
- else if (strcmp(type_string, "hostbased-service") == 0)
- nameoid = GSS_C_NT_HOSTBASED_SERVICE;
- else if (strcmp(type_string, "krb5-principal-name") == 0)
- nameoid = GSS_KRB5_NT_PRINCIPAL_NAME;
- else
- errx(1, "%s not suppported", type_string);
- if (mech_string == NULL)
- mechoid = GSS_KRB5_MECHANISM;
- else
- mechoid = string_to_oid(mech_string);
- if (gsskrb5_acceptor_identity) {
- maj_stat = gsskrb5_register_acceptor_identity(gsskrb5_acceptor_identity);
- if (maj_stat)
- errx(1, "gsskrb5_acceptor_identity: %s",
- gssapi_err(maj_stat, 0, GSS_C_NO_OID));
- }
- if (client_password) {
- credential_data.value = client_password;
- credential_data.length = strlen(client_password);
- }
- if (client_name) {
- gss_buffer_desc cn;
- cn.value = client_name;
- cn.length = strlen(client_name);
- maj_stat = gss_import_name(&min_stat, &cn, GSS_C_NT_USER_NAME, &cname);
- if (maj_stat)
- errx(1, "gss_import_name: %s",
- gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
- }
- if (client_password) {
- maj_stat = gss_acquire_cred_with_password(&min_stat,
- cname,
- &credential_data,
- GSS_C_INDEFINITE,
- GSS_C_NO_OID_SET,
- GSS_C_INITIATE,
- &client_cred,
- NULL,
- NULL);
- if (GSS_ERROR(maj_stat))
- errx(1, "gss_acquire_cred_with_password: %s",
- gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
- } else {
- maj_stat = gss_acquire_cred(&min_stat,
- cname,
- GSS_C_INDEFINITE,
- GSS_C_NO_OID_SET,
- GSS_C_INITIATE,
- &client_cred,
- NULL,
- NULL);
- if (GSS_ERROR(maj_stat))
- errx(1, "gss_acquire_cred: %s",
- gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
- }
- if (limit_enctype_string) {
- krb5_error_code ret;
- ret = krb5_string_to_enctype(context,
- limit_enctype_string,
- &limit_enctype);
- if (ret)
- krb5_err(context, 1, ret, "krb5_string_to_enctype");
- }
- if (limit_enctype) {
- if (client_cred == NULL)
- errx(1, "client_cred missing");
- maj_stat = gss_krb5_set_allowable_enctypes(&min_stat, client_cred,
- 1, &limit_enctype);
- if (maj_stat)
- errx(1, "gss_krb5_set_allowable_enctypes: %s",
- gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
- }
- loop(mechoid, nameoid, argv[0], client_cred,
- &sctx, &cctx, &actual_mech, &deleg_cred);
- if (verbose_flag)
- printf("resulting mech: %s\n", oid_to_string(actual_mech));
- if (ret_mech_string) {
- gss_OID retoid;
- retoid = string_to_oid(ret_mech_string);
- if (gss_oid_equal(retoid, actual_mech) == 0)
- errx(1, "actual_mech mech is not the expected type %s",
- ret_mech_string);
- }
- /* XXX should be actual_mech */
- if (gss_oid_equal(mechoid, GSS_KRB5_MECHANISM)) {
- time_t time;
- gss_buffer_desc authz_data;
- gss_buffer_desc in, out1, out2;
- krb5_keyblock *keyblock, *keyblock2;
- krb5_timestamp now;
- krb5_error_code ret;
- ret = krb5_timeofday(context, &now);
- if (ret)
- errx(1, "krb5_timeofday failed");
- /* client */
- maj_stat = gss_krb5_export_lucid_sec_context(&min_stat,
- &cctx,
- 1, /* version */
- &ctx);
- if (maj_stat != GSS_S_COMPLETE)
- errx(1, "gss_krb5_export_lucid_sec_context failed: %s",
- gssapi_err(maj_stat, min_stat, actual_mech));
- maj_stat = gss_krb5_free_lucid_sec_context(&maj_stat, ctx);
- if (maj_stat != GSS_S_COMPLETE)
- errx(1, "gss_krb5_free_lucid_sec_context failed: %s",
- gssapi_err(maj_stat, min_stat, actual_mech));
- /* server */
- maj_stat = gss_krb5_export_lucid_sec_context(&min_stat,
- &sctx,
- 1, /* version */
- &ctx);
- if (maj_stat != GSS_S_COMPLETE)
- errx(1, "gss_krb5_export_lucid_sec_context failed: %s",
- gssapi_err(maj_stat, min_stat, actual_mech));
- maj_stat = gss_krb5_free_lucid_sec_context(&min_stat, ctx);
- if (maj_stat != GSS_S_COMPLETE)
- errx(1, "gss_krb5_free_lucid_sec_context failed: %s",
- gssapi_err(maj_stat, min_stat, actual_mech));
- maj_stat = gsskrb5_extract_authtime_from_sec_context(&min_stat,
- sctx,
- &time);
- if (maj_stat != GSS_S_COMPLETE)
- errx(1, "gsskrb5_extract_authtime_from_sec_context failed: %s",
- gssapi_err(maj_stat, min_stat, actual_mech));
- if (time > now)
- errx(1, "gsskrb5_extract_authtime_from_sec_context failed: "
- "time authtime is before now: %ld %ld",
- (long)time, (long)now);
- maj_stat = gsskrb5_extract_service_keyblock(&min_stat,
- sctx,
- &keyblock);
- if (maj_stat != GSS_S_COMPLETE)
- errx(1, "gsskrb5_export_service_keyblock failed: %s",
- gssapi_err(maj_stat, min_stat, actual_mech));
- krb5_free_keyblock(context, keyblock);
- maj_stat = gsskrb5_get_subkey(&min_stat,
- sctx,
- &keyblock);
- if (maj_stat != GSS_S_COMPLETE
- && (!(maj_stat == GSS_S_FAILURE && min_stat == GSS_KRB5_S_KG_NO_SUBKEY)))
- errx(1, "gsskrb5_get_subkey server failed: %s",
- gssapi_err(maj_stat, min_stat, actual_mech));
- if (maj_stat != GSS_S_COMPLETE)
- keyblock = NULL;
- else if (limit_enctype && keyblock->keytype != limit_enctype)
- errx(1, "gsskrb5_get_subkey wrong enctype");
- maj_stat = gsskrb5_get_subkey(&min_stat,
- cctx,
- &keyblock2);
- if (maj_stat != GSS_S_COMPLETE
- && (!(maj_stat == GSS_S_FAILURE && min_stat == GSS_KRB5_S_KG_NO_SUBKEY)))
- errx(1, "gsskrb5_get_subkey client failed: %s",
- gssapi_err(maj_stat, min_stat, actual_mech));
- if (maj_stat != GSS_S_COMPLETE)
- keyblock2 = NULL;
- else if (limit_enctype && keyblock->keytype != limit_enctype)
- errx(1, "gsskrb5_get_subkey wrong enctype");
- if (keyblock || keyblock2) {
- if (keyblock == NULL)
- errx(1, "server missing token keyblock");
- if (keyblock2 == NULL)
- errx(1, "client missing token keyblock");
- if (keyblock->keytype != keyblock2->keytype)
- errx(1, "enctype mismatch");
- if (keyblock->keyvalue.length != keyblock2->keyvalue.length)
- errx(1, "key length mismatch");
- if (memcmp(keyblock->keyvalue.data, keyblock2->keyvalue.data,
- keyblock2->keyvalue.length) != 0)
- errx(1, "key data mismatch");
- }
- if (session_enctype_string) {
- krb5_enctype enctype;
- ret = krb5_string_to_enctype(context,
- session_enctype_string,
- &enctype);
- if (ret)
- krb5_err(context, 1, ret, "krb5_string_to_enctype");
- if (enctype != keyblock->keytype)
- errx(1, "keytype is not the expected %d != %d",
- (int)enctype, (int)keyblock2->keytype);
- }
- if (keyblock)
- krb5_free_keyblock(context, keyblock);
- if (keyblock2)
- krb5_free_keyblock(context, keyblock2);
- maj_stat = gsskrb5_get_initiator_subkey(&min_stat,
- sctx,
- &keyblock);
- if (maj_stat != GSS_S_COMPLETE
- && (!(maj_stat == GSS_S_FAILURE && min_stat == GSS_KRB5_S_KG_NO_SUBKEY)))
- errx(1, "gsskrb5_get_initiator_subkey failed: %s",
- gssapi_err(maj_stat, min_stat, actual_mech));
- if (maj_stat == GSS_S_COMPLETE) {
- if (limit_enctype && keyblock->keytype != limit_enctype)
- errx(1, "gsskrb5_get_initiator_subkey wrong enctype");
- krb5_free_keyblock(context, keyblock);
- }
- maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat,
- sctx,
- 128,
- &authz_data);
- if (maj_stat == GSS_S_COMPLETE)
- gss_release_buffer(&min_stat, &authz_data);
- memset(&out1, 0, sizeof(out1));
- memset(&out2, 0, sizeof(out2));
- in.value = "foo";
- in.length = 3;
- gss_pseudo_random(&min_stat, sctx, GSS_C_PRF_KEY_FULL, &in,
- 100, &out1);
- gss_pseudo_random(&min_stat, cctx, GSS_C_PRF_KEY_FULL, &in,
- 100, &out2);
- if (out1.length != out2.length)
- errx(1, "prf len mismatch");
- if (memcmp(out1.value, out2.value, out1.length) != 0)
- errx(1, "prf data mismatch");
- gss_release_buffer(&min_stat, &out1);
- gss_pseudo_random(&min_stat, sctx, GSS_C_PRF_KEY_FULL, &in,
- 100, &out1);
- if (out1.length != out2.length)
- errx(1, "prf len mismatch");
- if (memcmp(out1.value, out2.value, out1.length) != 0)
- errx(1, "prf data mismatch");
- gss_release_buffer(&min_stat, &out1);
- gss_release_buffer(&min_stat, &out2);
- in.value = "bar";
- in.length = 3;
- gss_pseudo_random(&min_stat, sctx, GSS_C_PRF_KEY_PARTIAL, &in,
- 100, &out1);
- gss_pseudo_random(&min_stat, cctx, GSS_C_PRF_KEY_PARTIAL, &in,
- 100, &out2);
- if (out1.length != out2.length)
- errx(1, "prf len mismatch");
- if (memcmp(out1.value, out2.value, out1.length) != 0)
- errx(1, "prf data mismatch");
- gss_release_buffer(&min_stat, &out1);
- gss_release_buffer(&min_stat, &out2);
- wrapunwrap_flag = 1;
- getverifymic_flag = 1;
- }
- if (wrapunwrap_flag) {
- wrapunwrap(cctx, sctx, 0, actual_mech);
- wrapunwrap(cctx, sctx, 1, actual_mech);
- wrapunwrap(sctx, cctx, 0, actual_mech);
- wrapunwrap(sctx, cctx, 1, actual_mech);
- }
- if (iov_flag) {
- wrapunwrap_iov(cctx, sctx, 0, actual_mech);
- wrapunwrap_iov(cctx, sctx, USE_HEADER_ONLY|FORCE_IOV, actual_mech);
- wrapunwrap_iov(cctx, sctx, USE_HEADER_ONLY, actual_mech);
- wrapunwrap_iov(cctx, sctx, USE_CONF, actual_mech);
- wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY, actual_mech);
- wrapunwrap_iov(cctx, sctx, FORCE_IOV, actual_mech);
- wrapunwrap_iov(cctx, sctx, USE_CONF|FORCE_IOV, actual_mech);
- wrapunwrap_iov(cctx, sctx, USE_HEADER_ONLY|FORCE_IOV, actual_mech);
- wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY|FORCE_IOV, actual_mech);
- wrapunwrap_iov(cctx, sctx, USE_SIGN_ONLY|FORCE_IOV, actual_mech);
- wrapunwrap_iov(cctx, sctx, USE_CONF|USE_SIGN_ONLY|FORCE_IOV, actual_mech);
- wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY|USE_SIGN_ONLY|FORCE_IOV, actual_mech);
- /* works */
- wrapunwrap_iov(cctx, sctx, 0, actual_mech);
- wrapunwrap_iov(cctx, sctx, FORCE_IOV, actual_mech);
- wrapunwrap_iov(cctx, sctx, USE_CONF, actual_mech);
- wrapunwrap_iov(cctx, sctx, USE_CONF|FORCE_IOV, actual_mech);
- wrapunwrap_iov(cctx, sctx, USE_SIGN_ONLY, actual_mech);
- wrapunwrap_iov(cctx, sctx, USE_SIGN_ONLY|FORCE_IOV, actual_mech);
- wrapunwrap_iov(cctx, sctx, USE_CONF|USE_SIGN_ONLY, actual_mech);
- wrapunwrap_iov(cctx, sctx, USE_CONF|USE_SIGN_ONLY|FORCE_IOV, actual_mech);
- wrapunwrap_iov(cctx, sctx, USE_HEADER_ONLY, actual_mech);
- wrapunwrap_iov(cctx, sctx, USE_HEADER_ONLY|FORCE_IOV, actual_mech);
- wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY, actual_mech);
- wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY|FORCE_IOV, actual_mech);
- }
- if (getverifymic_flag) {
- getverifymic(cctx, sctx, actual_mech);
- getverifymic(cctx, sctx, actual_mech);
- getverifymic(sctx, cctx, actual_mech);
- getverifymic(sctx, cctx, actual_mech);
- }
- gss_delete_sec_context(&min_stat, &cctx, NULL);
- gss_delete_sec_context(&min_stat, &sctx, NULL);
- if (deleg_cred != GSS_C_NO_CREDENTIAL) {
- gss_cred_id_t cred2 = GSS_C_NO_CREDENTIAL;
- gss_buffer_desc cb;
- if (verbose_flag)
- printf("checking actual mech (%s) on delegated cred\n",
- oid_to_string(actual_mech));
- loop(actual_mech, nameoid, argv[0], deleg_cred, &sctx, &cctx, &actual_mech2, &cred2);
- gss_delete_sec_context(&min_stat, &cctx, NULL);
- gss_delete_sec_context(&min_stat, &sctx, NULL);
- gss_release_cred(&min_stat, &cred2);
- /* try again using SPNEGO */
- if (verbose_flag)
- printf("checking spnego on delegated cred\n");
- loop(GSS_SPNEGO_MECHANISM, nameoid, argv[0], deleg_cred, &sctx, &cctx,
- &actual_mech2, &cred2);
- gss_delete_sec_context(&min_stat, &cctx, NULL);
- gss_delete_sec_context(&min_stat, &sctx, NULL);
- gss_release_cred(&min_stat, &cred2);
- /* check export/import */
- if (ei_flag) {
- maj_stat = gss_export_cred(&min_stat, deleg_cred, &cb);
- if (maj_stat != GSS_S_COMPLETE)
- errx(1, "export failed: %s",
- gssapi_err(maj_stat, min_stat, NULL));
- maj_stat = gss_import_cred(&min_stat, &cb, &cred2);
- if (maj_stat != GSS_S_COMPLETE)
- errx(1, "import failed: %s",
- gssapi_err(maj_stat, min_stat, NULL));
- gss_release_buffer(&min_stat, &cb);
- gss_release_cred(&min_stat, &deleg_cred);
- if (verbose_flag)
- printf("checking actual mech (%s) on export/imported cred\n",
- oid_to_string(actual_mech));
- loop(actual_mech, nameoid, argv[0], cred2, &sctx, &cctx,
- &actual_mech2, &deleg_cred);
- gss_release_cred(&min_stat, &deleg_cred);
- gss_delete_sec_context(&min_stat, &cctx, NULL);
- gss_delete_sec_context(&min_stat, &sctx, NULL);
- /* try again using SPNEGO */
- if (verbose_flag)
- printf("checking SPNEGO on export/imported cred\n");
- loop(GSS_SPNEGO_MECHANISM, nameoid, argv[0], cred2, &sctx, &cctx,
- &actual_mech2, &deleg_cred);
- gss_release_cred(&min_stat, &deleg_cred);
- gss_delete_sec_context(&min_stat, &cctx, NULL);
- gss_delete_sec_context(&min_stat, &sctx, NULL);
- gss_release_cred(&min_stat, &cred2);
- } else {
- gss_release_cred(&min_stat, &deleg_cred);
- }
- }
- empty_release();
- krb5_free_context(context);
- return 0;
- }