From 098148ac20dfa77a314b8e860edcf6837afacdbc Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Sun, 2 Jan 2011 20:30:57 +1100 Subject: [PATCH] MIT SPI compat --- lib/gssapi/Makefile.am | 2 + lib/gssapi/gssapi/gssapi.h | 30 ++++ lib/gssapi/gssapi_mech.h | 31 +++- lib/gssapi/mech/cred.h | 3 + lib/gssapi/mech/gss_acquire_cred_with_password.c | 169 +++++++++++++++++++++ lib/gssapi/mech/gss_add_cred.c | 2 +- ...gss_add_cred.c => gss_add_cred_with_password.c} | 53 ++----- lib/gssapi/mech/gss_mech_switch.c | 20 ++- lib/gssapi/version-script.map | 2 + 9 files changed, 264 insertions(+), 48 deletions(-) create mode 100644 lib/gssapi/mech/gss_acquire_cred_with_password.c copy lib/gssapi/mech/{gss_add_cred.c => gss_add_cred_with_password.c} (78%) diff --git a/lib/gssapi/Makefile.am b/lib/gssapi/Makefile.am index c74906103..a380672c6 100644 --- a/lib/gssapi/Makefile.am +++ b/lib/gssapi/Makefile.am @@ -80,7 +80,9 @@ mechsrc = \ mech/doxygen.c \ mech/gss_accept_sec_context.c \ mech/gss_acquire_cred.c \ + mech/gss_acquire_cred_with_password.c \ mech/gss_add_cred.c \ + mech/gss_add_cred_with_password.c \ mech/gss_add_oid_set_member.c \ mech/gss_aeap.c \ mech/gss_buffer_set.c \ diff --git a/lib/gssapi/gssapi/gssapi.h b/lib/gssapi/gssapi/gssapi.h index 12833ebe1..5739e91e8 100644 --- a/lib/gssapi/gssapi/gssapi.h +++ b/lib/gssapi/gssapi/gssapi.h @@ -986,6 +986,36 @@ gss_display_mech_attr(OM_uint32 * minor_status, gss_buffer_t short_desc, gss_buffer_t long_desc); +/* + * Solaris compat + */ + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_acquire_cred_with_password + (OM_uint32 * /*minor_status*/, + const gss_name_t /*desired_name*/, + const gss_buffer_t /*password*/, + OM_uint32 /*time_req*/, + const gss_OID_set /*desired_mechs*/, + gss_cred_usage_t /*cred_usage*/, + gss_cred_id_t * /*output_cred_handle*/, + gss_OID_set * /*actual_mechs*/, + OM_uint32 * /*time_rec*/ + ); + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_add_cred_with_password ( + OM_uint32 * /*minor_status*/, + const gss_cred_id_t /*input_cred_handle*/, + const gss_name_t /*desired_name*/, + const gss_OID /*desired_mech*/, + const gss_buffer_t /*password*/, + gss_cred_usage_t /*cred_usage*/, + OM_uint32 /*initiator_time_req*/, + OM_uint32 /*acceptor_time_req*/, + gss_cred_id_t * /*output_cred_handle*/, + gss_OID_set * /*actual_mechs*/, + OM_uint32 * /*initiator_time_rec*/, + OM_uint32 * /*acceptor_time_rec*/ + ); /* * diff --git a/lib/gssapi/gssapi_mech.h b/lib/gssapi/gssapi_mech.h index b06e60a82..9fe195cd2 100644 --- a/lib/gssapi/gssapi_mech.h +++ b/lib/gssapi/gssapi_mech.h @@ -406,8 +406,35 @@ struct gss_mo_desc_struct { int (*set)(gss_const_OID, gss_mo_desc *, int, gss_buffer_t); }; +typedef OM_uint32 GSSAPI_CALLCONV _gss_acquire_cred_with_password_t + (OM_uint32 *, /* minor_status */ + const gss_name_t, /* desired_name */ + const gss_buffer_t, /* password */ + OM_uint32, /* time_req */ + const gss_OID_set, /* desired_mechs */ + gss_cred_usage_t, /* cred_usage */ + gss_cred_id_t *, /* output_cred_handle */ + gss_OID_set *, /* actual_mechs */ + OM_uint32 * /* time_rec */ + ); + + +typedef OM_uint32 GSSAPI_CALLCONV _gss_add_cred_with_password_t ( + OM_uint32 *, /* minor_status */ + const gss_cred_id_t, /* input_cred_handle */ + const gss_name_t, /* desired_name */ + const gss_OID, /* desired_mech */ + const gss_buffer_t, /* password */ + gss_cred_usage_t, /* cred_usage */ + OM_uint32, /* initiator_time_req */ + OM_uint32, /* acceptor_time_req */ + gss_cred_id_t *, /* output_cred_handle */ + gss_OID_set *, /* actual_mechs */ + OM_uint32 *, /* initiator_time_rec */ + OM_uint32 * /* acceptor_time_rec */ + ); -#define GMI_VERSION 4 +#define GMI_VERSION 5 /* gm_flags */ #define GM_USE_MG_CRED 1 /* uses mech glue credentials */ @@ -467,6 +494,8 @@ typedef struct gssapi_mech_interface_desc { _gss_cred_label_set_t *gm_cred_label_set; gss_mo_desc *gm_mo; size_t gm_mo_num; + _gss_acquire_cred_with_password_t *gm_acquire_cred_with_password; + _gss_add_cred_with_password_t *gm_add_cred_with_password; } gssapi_mech_interface_desc, *gssapi_mech_interface; gssapi_mech_interface diff --git a/lib/gssapi/mech/cred.h b/lib/gssapi/mech/cred.h index adffe6893..5d6430f69 100644 --- a/lib/gssapi/mech/cred.h +++ b/lib/gssapi/mech/cred.h @@ -39,3 +39,6 @@ struct _gss_cred { struct _gss_mechanism_cred_list gc_mc; }; +struct _gss_mechanism_cred * +_gss_copy_cred(struct _gss_mechanism_cred *mc); + diff --git a/lib/gssapi/mech/gss_acquire_cred_with_password.c b/lib/gssapi/mech/gss_acquire_cred_with_password.c new file mode 100644 index 000000000..d551abc39 --- /dev/null +++ b/lib/gssapi/mech/gss_acquire_cred_with_password.c @@ -0,0 +1,169 @@ +/*- + * Copyright (c) 2005 Doug Rabson + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: src/lib/libgssapi/gss_acquire_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $ + */ + +#include "mech_locl.h" + +GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL +gss_acquire_cred_with_password(OM_uint32 *minor_status, + const gss_name_t desired_name, + const gss_buffer_t password, + OM_uint32 time_req, + const gss_OID_set desired_mechs, + gss_cred_usage_t cred_usage, + gss_cred_id_t *output_cred_handle, + gss_OID_set *actual_mechs, + OM_uint32 *time_rec) +{ + OM_uint32 major_status; + gss_OID_set mechs = desired_mechs; + gss_OID_set_desc set; + struct _gss_name *name = (struct _gss_name *) desired_name; + gssapi_mech_interface m; + struct _gss_cred *cred; + struct _gss_mechanism_cred *mc; + OM_uint32 min_time, cred_time; + int i; + + *minor_status = 0; + if (output_cred_handle == NULL) + return GSS_S_CALL_INACCESSIBLE_READ; + if (actual_mechs) + *actual_mechs = GSS_C_NO_OID_SET; + if (time_rec) + *time_rec = 0; + + _gss_load_mech(); + + /* + * First make sure that at least one of the requested + * mechanisms is one that we support. + */ + if (mechs) { + for (i = 0; i < mechs->count; i++) { + int t; + gss_test_oid_set_member(minor_status, + &mechs->elements[i], _gss_mech_oids, &t); + if (t) + break; + } + if (i == mechs->count) { + *minor_status = 0; + return (GSS_S_BAD_MECH); + } + } + + if (actual_mechs) { + major_status = gss_create_empty_oid_set(minor_status, + actual_mechs); + if (major_status) + return (major_status); + } + + cred = malloc(sizeof(struct _gss_cred)); + if (!cred) { + if (actual_mechs) + gss_release_oid_set(minor_status, actual_mechs); + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + HEIM_SLIST_INIT(&cred->gc_mc); + + if (mechs == GSS_C_NO_OID_SET) + mechs = _gss_mech_oids; + + set.count = 1; + min_time = GSS_C_INDEFINITE; + for (i = 0; i < mechs->count; i++) { + struct _gss_mechanism_name *mn = NULL; + + m = __gss_get_mechanism(&mechs->elements[i]); + if (!m || !m->gm_acquire_cred_with_password) + continue; + + if (desired_name != GSS_C_NO_NAME) { + major_status = _gss_find_mn(minor_status, name, + &mechs->elements[i], &mn); + if (major_status != GSS_S_COMPLETE) + continue; + } + + mc = malloc(sizeof(struct _gss_mechanism_cred)); + if (!mc) { + continue; + } + mc->gmc_mech = m; + mc->gmc_mech_oid = &m->gm_mech_oid; + + /* + * XXX Probably need to do something with actual_mechs. + */ + set.elements = &mechs->elements[i]; + major_status = m->gm_acquire_cred_with_password(minor_status, + (desired_name != GSS_C_NO_NAME + ? mn->gmn_name : GSS_C_NO_NAME), + password, time_req, &set, cred_usage, + &mc->gmc_cred, NULL, &cred_time); + if (major_status) { + free(mc); + continue; + } + if (cred_time < min_time) + min_time = cred_time; + + if (actual_mechs) { + major_status = gss_add_oid_set_member(minor_status, + mc->gmc_mech_oid, actual_mechs); + if (major_status) { + m->gm_release_cred(minor_status, + &mc->gmc_cred); + free(mc); + continue; + } + } + + HEIM_SLIST_INSERT_HEAD(&cred->gc_mc, mc, gmc_link); + } + + /* + * If we didn't manage to create a single credential, return + * an error. + */ + if (!HEIM_SLIST_FIRST(&cred->gc_mc)) { + free(cred); + if (actual_mechs) + gss_release_oid_set(minor_status, actual_mechs); + *minor_status = 0; + return (GSS_S_NO_CRED); + } + + if (time_rec) + *time_rec = min_time; + *output_cred_handle = (gss_cred_id_t) cred; + *minor_status = 0; + return (GSS_S_COMPLETE); +} diff --git a/lib/gssapi/mech/gss_add_cred.c b/lib/gssapi/mech/gss_add_cred.c index 19deea5b0..a998bc60f 100644 --- a/lib/gssapi/mech/gss_add_cred.c +++ b/lib/gssapi/mech/gss_add_cred.c @@ -28,7 +28,7 @@ #include "mech_locl.h" -static struct _gss_mechanism_cred * +struct _gss_mechanism_cred * _gss_copy_cred(struct _gss_mechanism_cred *mc) { struct _gss_mechanism_cred *new_mc; diff --git a/lib/gssapi/mech/gss_add_cred.c b/lib/gssapi/mech/gss_add_cred_with_password.c similarity index 78% copy from lib/gssapi/mech/gss_add_cred.c copy to lib/gssapi/mech/gss_add_cred_with_password.c index 19deea5b0..a0dc9f002 100644 --- a/lib/gssapi/mech/gss_add_cred.c +++ b/lib/gssapi/mech/gss_add_cred_with_password.c @@ -28,53 +28,12 @@ #include "mech_locl.h" -static struct _gss_mechanism_cred * -_gss_copy_cred(struct _gss_mechanism_cred *mc) -{ - struct _gss_mechanism_cred *new_mc; - gssapi_mech_interface m = mc->gmc_mech; - OM_uint32 major_status, minor_status; - gss_name_t name; - gss_cred_id_t cred; - OM_uint32 initiator_lifetime, acceptor_lifetime; - gss_cred_usage_t cred_usage; - - major_status = m->gm_inquire_cred_by_mech(&minor_status, - mc->gmc_cred, mc->gmc_mech_oid, - &name, &initiator_lifetime, &acceptor_lifetime, &cred_usage); - if (major_status) { - _gss_mg_error(m, major_status, minor_status); - return (0); - } - - major_status = m->gm_add_cred(&minor_status, - GSS_C_NO_CREDENTIAL, name, mc->gmc_mech_oid, - cred_usage, initiator_lifetime, acceptor_lifetime, - &cred, 0, 0, 0); - m->gm_release_name(&minor_status, &name); - - if (major_status) { - _gss_mg_error(m, major_status, minor_status); - return (0); - } - - new_mc = malloc(sizeof(struct _gss_mechanism_cred)); - if (!new_mc) { - m->gm_release_cred(&minor_status, &cred); - return (0); - } - new_mc->gmc_mech = m; - new_mc->gmc_mech_oid = &m->gm_mech_oid; - new_mc->gmc_cred = cred; - - return (new_mc); -} - GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL -gss_add_cred(OM_uint32 *minor_status, +gss_add_cred_with_password(OM_uint32 *minor_status, const gss_cred_id_t input_cred_handle, const gss_name_t desired_name, const gss_OID desired_mech, + const gss_buffer_t password, gss_cred_usage_t cred_usage, OM_uint32 initiator_time_req, OM_uint32 acceptor_time_req, @@ -148,6 +107,11 @@ gss_add_cred(OM_uint32 *minor_status, } m = __gss_get_mechanism(desired_mech); + if (m->gm_add_cred_with_password == NULL) { + release_cred = (gss_cred_id_t)new_cred; + gss_release_cred(&junk, &release_cred); + return (GSS_S_UNAVAILABLE); + } mc = malloc(sizeof(struct _gss_mechanism_cred)); if (!mc) { @@ -159,9 +123,10 @@ gss_add_cred(OM_uint32 *minor_status, mc->gmc_mech = m; mc->gmc_mech_oid = &m->gm_mech_oid; - major_status = m->gm_add_cred(minor_status, + major_status = m->gm_add_cred_with_password(minor_status, target_mc ? target_mc->gmc_cred : GSS_C_NO_CREDENTIAL, desired_name ? mn->gmn_name : GSS_C_NO_NAME, + password, desired_mech, cred_usage, initiator_time_req, diff --git a/lib/gssapi/mech/gss_mech_switch.c b/lib/gssapi/mech/gss_mech_switch.c index 48444a8fa..6da7411a9 100644 --- a/lib/gssapi/mech/gss_mech_switch.c +++ b/lib/gssapi/mech/gss_mech_switch.c @@ -160,7 +160,12 @@ do { \ #define OPTSYM(name) \ do { \ - m->gm_mech.gm_ ## name = dlsym(so, "gss_" #name); \ + m->gm_mech.gm_ ## name = dlsym(so, "gss_" #name); \ +} while (0) + +#define OPTSPISYM(name) \ +do { \ + m->gm_mech.gm_ ## name = dlsym(so, "gssspi_" #name); \ } while (0) /* @@ -332,11 +337,22 @@ _gss_load_mech(void) OPTSYM(inquire_cred_by_oid); OPTSYM(inquire_sec_context_by_oid); OPTSYM(set_sec_context_option); - OPTSYM(set_cred_option); + OPTSPISYM(set_cred_option); OPTSYM(pseudo_random); OPTSYM(wrap_iov); OPTSYM(unwrap_iov); OPTSYM(wrap_iov_length); + OPTSPISYM(acquire_cred_with_password); + OPTSYM(add_cred_with_password); + + /* pick up the oid sets of names */ + + if (m->gm_mech.gm_inquire_names_for_mech) + (*m->gm_mech.gm_inquire_names_for_mech)(&minor_status, + &m->gm_mech.gm_mech_oid, &m->gm_name_types); + + if (m->gm_name_types == NULL) + gss_create_empty_oid_set(&minor_status, &m->gm_name_types); HEIM_SLIST_INSERT_HEAD(&_gss_mechs, m, gm_link); continue; diff --git a/lib/gssapi/version-script.map b/lib/gssapi/version-script.map index 087b29a50..c0f6dcb62 100644 --- a/lib/gssapi/version-script.map +++ b/lib/gssapi/version-script.map @@ -13,8 +13,10 @@ HEIMDAL_GSS_2.0 { __gss_c_attr_stream_sizes_oid_desc; gss_accept_sec_context; gss_acquire_cred; + gss_acquire_cred_with_password; gss_add_buffer_set_member; gss_add_cred; + gss_add_cred_with_password; gss_add_oid_set_member; gss_canonicalize_name; gss_compare_name; -- 2.11.4.GIT