diff --git a/lib/gssapi/Makefile.am b/lib/gssapi/Makefile.am index 2d4f8caa0..f09c7ef59 100644 --- a/lib/gssapi/Makefile.am +++ b/lib/gssapi/Makefile.am @@ -27,6 +27,7 @@ krb5src = \ krb5/aeap.c \ krb5/arcfour.c \ krb5/canonicalize_name.c \ + krb5/creds.c \ krb5/ccache_name.c \ krb5/cfx.c \ krb5/cfx.h \ @@ -87,6 +88,7 @@ mechsrc = \ mech/gss_compare_name.c \ mech/gss_context_time.c \ mech/gss_create_empty_oid_set.c \ + mech/gss_cred.c \ mech/gss_decapsulate_token.c \ mech/gss_delete_sec_context.c \ mech/gss_display_name.c \ diff --git a/lib/gssapi/gssapi/gssapi.h b/lib/gssapi/gssapi/gssapi.h index 357b98972..6052ec813 100644 --- a/lib/gssapi/gssapi/gssapi.h +++ b/lib/gssapi/gssapi/gssapi.h @@ -900,6 +900,17 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_release_iov_buffer(OM_uint32 *, gss_iov_buffer_desc *, int); +OM_uint32 GSSAPI_LIB_FUNCTION +gss_export_cred(OM_uint32 * /* minor_status */, + gss_cred_id_t /* cred_handle */, + gss_buffer_t /* cred_token */); + +OM_uint32 GSSAPI_LIB_FUNCTION +gss_import_cred(OM_uint32 * /* minor_status */, + gss_buffer_t /* cred_token */, + gss_cred_id_t * /* cred_handle */); + + GSSAPI_CPP_END #endif /* GSSAPI_GSSAPI_H_ */ diff --git a/lib/gssapi/gssapi_mech.h b/lib/gssapi/gssapi_mech.h index 6470df30a..206a24ef7 100644 --- a/lib/gssapi/gssapi_mech.h +++ b/lib/gssapi/gssapi_mech.h @@ -343,6 +343,15 @@ _gss_store_cred_t(OM_uint32 *minor_status, gss_OID_set *elements_stored, gss_cred_usage_t *cred_usage_stored); +typedef OM_uint32 +_gss_export_cred_t(OM_uint32 *minor_status, + gss_cred_id_t cred_handle, + gss_buffer_t cred_token); + +typedef OM_uint32 +_gss_import_cred_t(OM_uint32 * minor_status, + gss_buffer_t cred_token, + gss_cred_id_t * cred_handle); #define GMI_VERSION 2 @@ -389,6 +398,8 @@ typedef struct gssapi_mech_interface_desc { _gss_unwrap_iov_t *gm_unwrap_iov; _gss_wrap_iov_length_t *gm_wrap_iov_length; _gss_store_cred_t *gm_store_cred; + _gss_export_cred_t *gm_export_cred; + _gss_import_cred_t *gm_import_cred; } gssapi_mech_interface_desc, *gssapi_mech_interface; gssapi_mech_interface diff --git a/lib/gssapi/krb5/accept_sec_context.c b/lib/gssapi/krb5/accept_sec_context.c index 8d998ed09..355d1c433 100644 --- a/lib/gssapi/krb5/accept_sec_context.c +++ b/lib/gssapi/krb5/accept_sec_context.c @@ -170,12 +170,12 @@ gsskrb5_accept_delegated_token if (delegated_cred_handle) { gsskrb5_cred handle; - - ret = _gsskrb5_import_cred(minor_status, - ccache, - NULL, - NULL, - delegated_cred_handle); + + ret = _gsskrb5_krb5_import_cred(minor_status, + ccache, + NULL, + NULL, + delegated_cred_handle); if (ret != GSS_S_COMPLETE) goto out; diff --git a/lib/gssapi/krb5/copy_ccache.c b/lib/gssapi/krb5/copy_ccache.c index a4b28f91e..4e65fc1cf 100644 --- a/lib/gssapi/krb5/copy_ccache.c +++ b/lib/gssapi/krb5/copy_ccache.c @@ -63,11 +63,11 @@ gss_krb5_copy_ccache(OM_uint32 *minor_status, OM_uint32 -_gsskrb5_import_cred(OM_uint32 *minor_status, - krb5_ccache id, - krb5_principal keytab_principal, - krb5_keytab keytab, - gss_cred_id_t *cred) +_gsskrb5_krb5_import_cred(OM_uint32 *minor_status, + krb5_ccache id, + krb5_principal keytab_principal, + krb5_keytab keytab, + gss_cred_id_t *cred) { krb5_context context; krb5_error_code kret; diff --git a/lib/gssapi/krb5/creds.c b/lib/gssapi/krb5/creds.c new file mode 100644 index 000000000..c9befe9d7 --- /dev/null +++ b/lib/gssapi/krb5/creds.c @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2009 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 the Institute 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 THE INSTITUTE AND 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 THE INSTITUTE OR 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 "gsskrb5_locl.h" + +OM_uint32 +_gsskrb5_export_cred(OM_uint32 *minor_status, + gss_cred_id_t cred_handle, + gss_buffer_t cred_token) +{ + gsskrb5_cred handle = (gsskrb5_cred)cred_handle; + krb5_context context; + krb5_error_code ret; + krb5_storage *sp; + krb5_data data, mech; + const char *type; + char *str; + + GSSAPI_KRB5_INIT (&context); + + if (handle->usage != GSS_C_INITIATE && handle->usage != GSS_C_BOTH) { + *minor_status = GSS_KRB5_S_G_BAD_USAGE; + return GSS_S_FAILURE; + } + + sp = krb5_storage_emem(); + if (sp == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + type = krb5_cc_get_type(context, handle->ccache); + if (strcmp(type, "MEMORY") == 0) { + krb5_creds *creds; + ret = krb5_store_uint32(sp, 0); + if (ret) { + krb5_storage_free(sp); + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = _krb5_get_krbtgt(context, handle->ccache, + handle->principal->realm, + &creds); + if (ret) { + krb5_storage_free(sp); + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = krb5_store_creds(sp, creds); + krb5_free_creds(context, creds); + if (ret) { + krb5_storage_free(sp); + *minor_status = ret; + return GSS_S_FAILURE; + } + + } else { + ret = krb5_store_uint32(sp, 1); + if (ret) { + krb5_storage_free(sp); + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = krb5_cc_get_full_name(context, handle->ccache, &str); + if (ret) { + krb5_storage_free(sp); + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = krb5_store_string(sp, str); + free(str); + if (ret) { + krb5_storage_free(sp); + *minor_status = ret; + return GSS_S_FAILURE; + } + } + ret = krb5_storage_to_data(sp, &data); + krb5_storage_free(sp); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + sp = krb5_storage_emem(); + if (sp == NULL) { + krb5_data_free(&data); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + mech.data = GSS_KRB5_MECHANISM->elements; + mech.length = GSS_KRB5_MECHANISM->length; + + ret = krb5_store_data(sp, mech); + if (ret) { + krb5_data_free(&data); + krb5_storage_free(sp); + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = krb5_store_data(sp, data); + krb5_data_free(&data); + if (ret) { + krb5_storage_free(sp); + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = krb5_storage_to_data(sp, &data); + krb5_storage_free(sp); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + cred_token->value = data.data; + cred_token->length = data.length; + + return GSS_S_COMPLETE; +} + +OM_uint32 +_gsskrb5_import_cred(OM_uint32 * minor_status, + gss_buffer_t cred_token, + gss_cred_id_t * cred_handle) +{ + krb5_context context; + krb5_error_code ret; + gsskrb5_cred handle; + krb5_ccache id; + krb5_storage *sp; + char *str; + uint32_t type; + int flags = 0; + + *cred_handle = GSS_C_NO_CREDENTIAL; + + GSSAPI_KRB5_INIT (&context); + + sp = krb5_storage_from_mem(cred_token->value, cred_token->length); + if (sp == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + ret = krb5_ret_uint32(sp, &type); + if (ret) { + krb5_storage_free(sp); + *minor_status = ret; + return GSS_S_FAILURE; + } + switch (type) { + case 0: { + krb5_creds creds; + + ret = krb5_ret_creds(sp, &creds); + krb5_storage_free(sp); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = krb5_cc_new_unique(context, "MEMORY", NULL, &id); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = krb5_cc_initialize(context, id, creds.client); + if (ret) { + krb5_cc_destroy(context, id); + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = krb5_cc_store_cred(context, id, &creds); + krb5_free_cred_contents(context, &creds); + + flags |= GSS_CF_DESTROY_CRED_ON_RELEASE; + + break; + } + case 1: + ret = krb5_ret_string(sp, &str); + krb5_storage_free(sp); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = krb5_cc_resolve(context, str, &id); + krb5_xfree(str); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + break; + + default: + krb5_storage_free(sp); + *minor_status = 0; + return GSS_S_NO_CRED; + } + + handle = calloc(1, sizeof(*handle)); + if (handle == NULL) { + krb5_cc_close(context, id); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + handle->usage = GSS_C_INITIATE; + krb5_cc_get_principal(context, id, &handle->principal); + handle->ccache = id; + handle->cred_flags = flags; + + return GSS_S_COMPLETE; +} diff --git a/lib/gssapi/krb5/external.c b/lib/gssapi/krb5/external.c index b86ab74b2..fc835bd84 100644 --- a/lib/gssapi/krb5/external.c +++ b/lib/gssapi/krb5/external.c @@ -471,7 +471,9 @@ static gssapi_mech_interface_desc krb5_mech = { _gk_wrap_iov, _gk_unwrap_iov, _gk_wrap_iov_length, - _gsskrb5_store_cred + _gsskrb5_store_cred, + _gsskrb5_export_cred, + _gsskrb5_import_cred }; gssapi_mech_interface diff --git a/lib/gssapi/krb5/set_cred_option.c b/lib/gssapi/krb5/set_cred_option.c index 15d7632e4..ee29bf8c6 100644 --- a/lib/gssapi/krb5/set_cred_option.c +++ b/lib/gssapi/krb5/set_cred_option.c @@ -119,8 +119,8 @@ import_cred(OM_uint32 *minor_status, free(str); str = NULL; - major_stat = _gsskrb5_import_cred(minor_status, id, keytab_principal, - keytab, cred_handle); + major_stat = _gsskrb5_krb5_import_cred(minor_status, id, keytab_principal, + keytab, cred_handle); out: if (id) krb5_cc_close(context, id); diff --git a/lib/gssapi/mech/gss_cred.c b/lib/gssapi/mech/gss_cred.c new file mode 100644 index 000000000..2efbe93ad --- /dev/null +++ b/lib/gssapi/mech/gss_cred.c @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2009 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 "mech_locl.h" +#include + +/* + * format: any number of: + * mech-len: int32 + * mech-data: char * (not alligned) + * cred-len: int32 + * cred-data char * (not alligned) +*/ + +OM_uint32 GSSAPI_LIB_FUNCTION +gss_export_cred(OM_uint32 * minor_status, + gss_cred_id_t cred_handle, + gss_buffer_t token) +{ + struct _gss_cred *cred = (struct _gss_cred *)cred_handle; + struct _gss_mechanism_cred *mc; + gss_buffer_desc buffer; + krb5_error_code ret; + krb5_storage *sp; + OM_uint32 major; + krb5_data data; + + _mg_buffer_zero(token); + + if (cred == NULL) { + *minor_status = 0; + return GSS_S_NO_CRED; + } + + SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { + if (mc->gmc_mech->gm_export_cred == NULL) { + *minor_status = 0; + return GSS_S_NO_CRED; + } + } + + sp = krb5_storage_emem(); + if (sp == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { + + major = mc->gmc_mech->gm_export_cred(minor_status, + mc->gmc_cred, &buffer); + if (major) { + krb5_storage_free(sp); + return major; + } + + ret = krb5_storage_write(sp, buffer.value, buffer.length); + if (ret != buffer.length) { + gss_release_buffer(minor_status, &buffer); + krb5_storage_free(sp); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + gss_release_buffer(minor_status, &buffer); + } + + ret = krb5_storage_to_data(sp, &data); + krb5_storage_free(sp); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + token->value = data.data; + token->length = data.length; + + return GSS_S_COMPLETE; +} + +OM_uint32 GSSAPI_LIB_FUNCTION +gss_import_cred(OM_uint32 * minor_status, + gss_buffer_t token, + gss_cred_id_t * cred_handle) +{ + gssapi_mech_interface m; + krb5_error_code ret; + struct _gss_cred *cred; + krb5_storage *sp; + OM_uint32 major, junk; + krb5_data data; + + *cred_handle = GSS_C_NO_CREDENTIAL; + + if (token->length == 0) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + sp = krb5_storage_from_readonly_mem(token->value, token->length); + if (sp == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + cred = calloc(1, sizeof(struct _gss_cred)); + if (cred == NULL) { + krb5_storage_free(sp); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + SLIST_INIT(&cred->gc_mc); + + *cred_handle = (gss_cred_id_t)cred; + + while(1) { + struct _gss_mechanism_cred *mc; + gss_buffer_desc buffer; + gss_cred_id_t mcred; + gss_OID_desc oid; + + ret = krb5_ret_data(sp, &data); + if (ret == HEIM_ERR_EOF) { + break; + } else if (ret) { + *minor_status = ret; + major = GSS_S_FAILURE; + goto out; + } + oid.elements = data.data; + oid.length = data.length; + + m = __gss_get_mechanism(&oid); + krb5_data_free(&data); + if (!m) { + *minor_status = 0; + major = GSS_S_BAD_MECH; + goto out; + } + + if (m->gm_import_cred == NULL) { + *minor_status = 0; + major = GSS_S_BAD_MECH; + goto out; + } + + ret = krb5_ret_data(sp, &data); + if (ret) { + *minor_status = ret; + major = GSS_S_FAILURE; + goto out; + } + + buffer.value = data.data; + buffer.length = data.length; + + major = m->gm_import_cred(minor_status, + &buffer, &mcred); + krb5_data_free(&data); + if (major) { + goto out; + } + + mc = malloc(sizeof(struct _gss_mechanism_cred)); + if (mc == NULL) { + *minor_status = EINVAL; + major = GSS_S_FAILURE; + goto out; + } + + mc->gmc_mech = m; + mc->gmc_mech_oid = &m->gm_mech_oid; + mc->gmc_cred = mcred; + + SLIST_INSERT_HEAD(&cred->gc_mc, mc, gmc_link); + } + krb5_storage_free(sp); + + if (SLIST_EMPTY(&cred->gc_mc)) { + major = GSS_S_NO_CRED; + goto out; + } + + return GSS_S_COMPLETE; + + out: + krb5_storage_free(sp); + + gss_release_cred(&junk, cred_handle); + + return major; + +} diff --git a/lib/gssapi/spnego/cred_stubs.c b/lib/gssapi/spnego/cred_stubs.c index a3a984e22..a10a10f1e 100644 --- a/lib/gssapi/spnego/cred_stubs.c +++ b/lib/gssapi/spnego/cred_stubs.c @@ -354,3 +354,39 @@ _gss_spnego_set_cred_option (OM_uint32 *minor_status, value); } + +OM_uint32 +_gss_spnego_export_cred (OM_uint32 *minor_status, + gss_cred_id_t cred_handle, + gss_buffer_t value) +{ + gssspnego_cred cred = (gssspnego_cred)cred_handle; + + return gss_export_cred(minor_status, cred->negotiated_cred_id, value); +} + +OM_uint32 +_gss_spnego_import_cred (OM_uint32 *minor_status, + gss_buffer_t value, + gss_cred_id_t *cred_handle) +{ + gssspnego_cred cred; + OM_uint32 major; + + *cred_handle = GSS_C_NO_CREDENTIAL; + + cred = calloc(1, sizeof(*cred)); + if (cred == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + major = gss_import_cred(minor_status, value, &cred->negotiated_cred_id); + if (major == GSS_S_COMPLETE) + *cred_handle = (gss_cred_id_t)cred; + else + free(cred); + + return major; +} + diff --git a/lib/gssapi/spnego/external.c b/lib/gssapi/spnego/external.c index 2dc809bbb..f3edcba38 100644 --- a/lib/gssapi/spnego/external.c +++ b/lib/gssapi/spnego/external.c @@ -79,7 +79,13 @@ static gssapi_mech_interface_desc spnego_mech = { _gss_spnego_inquire_cred_by_oid, _gss_spnego_set_sec_context_option, _gss_spnego_set_cred_option, - _gss_spnego_pseudo_random + _gss_spnego_pseudo_random, + NULL, + NULL, + NULL, + NULL, + _gss_spnego_export_cred, + _gss_spnego_import_cred }; gssapi_mech_interface diff --git a/lib/gssapi/test_context.c b/lib/gssapi/test_context.c index 27f83da52..3745ea190 100644 --- a/lib/gssapi/test_context.c +++ b/lib/gssapi/test_context.c @@ -54,6 +54,7 @@ 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; @@ -443,6 +444,7 @@ static struct getargs args[] = { {"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 }, @@ -753,17 +755,44 @@ main(int argc, char **argv) gss_delete_sec_context(&min_stat, &sctx, NULL); if (deleg_cred != GSS_C_NO_CREDENTIAL) { - gss_cred_id_t deleg_cred2 = GSS_C_NO_CREDENTIAL; + gss_cred_id_t cred2 = GSS_C_NO_CREDENTIAL; + gss_buffer_desc cb; - loop(mechoid, nameoid, argv[0], deleg_cred, &cctx, &sctx, &actual_mech, &deleg_cred2); - - gss_release_cred(&min_stat, &deleg_cred2); + loop(mechoid, nameoid, argv[0], deleg_cred, &cctx, &sctx, &actual_mech, &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); + + loop(mechoid, nameoid, argv[0], cred2, &cctx, &sctx, &actual_mech, &deleg_cred); + + gss_release_cred(&min_stat, &cred2); + } + + gss_delete_sec_context(&min_stat, &cctx, NULL); + gss_delete_sec_context(&min_stat, &sctx, NULL); + + gss_release_cred(&min_stat, &deleg_cred); + } + empty_release(); return 0; diff --git a/lib/krb5/version-script.map b/lib/krb5/version-script.map index 5cc48fc66..9bc19a37f 100644 --- a/lib/krb5/version-script.map +++ b/lib/krb5/version-script.map @@ -710,6 +710,7 @@ HEIMDAL_KRB5_2.0 { # Shared with GSSAPI krb5 _krb5_crc_init_table; _krb5_crc_update; + _krb5_get_krbtgt; # V4 compat glue _krb5_krb_tf_setup; diff --git a/tests/gss/check-context.in b/tests/gss/check-context.in index b691b9572..6632ce4ba 100644 --- a/tests/gss/check-context.in +++ b/tests/gss/check-context.in @@ -316,6 +316,24 @@ ${context} \ --name-type=hostbased-service host@lucid.test.h5l.se || \ { exitcode=1 ; echo "test failed"; } +echo "======export/import cred" + +echo "export-import cred (krb5)" +${context} \ + --mech-type=krb5 \ + --delegate \ + --export-import-cred \ + --name-type=hostbased-service host@ok-delegate.test.h5l.se || \ + { exitcode=1 ; echo "test failed"; } + +echo "export-import cred (spnego)" +${context} \ + --mech-type=spnego \ + --delegate \ + --export-import-cred \ + --name-type=hostbased-service host@ok-delegate.test.h5l.se || \ + { exitcode=1 ; echo "test failed"; } + echo "======time diffs between client and server"