diff options
Diffstat (limited to 'support/gssapi')
38 files changed, 5935 insertions, 0 deletions
diff --git a/support/gssapi/Makefile b/support/gssapi/Makefile new file mode 100644 index 0000000..65271f0 --- /dev/null +++ b/support/gssapi/Makefile @@ -0,0 +1,24 @@ +# +# libgssapi.a +# gssapi mechanism-switching layer +# + +LIBNAME = libgssapi.a +SRCS = g_accept_sec_context.c g_acquire_cred.c g_compare_name.c \ + g_context_time.c g_delete_sec_context.c g_dsp_name.c g_dsp_status.c \ + g_dup_name.c gen_oids.c g_exp_sec_context.c g_glue.c g_imp_name.c \ + g_imp_sec_context.c g_indicate_mechs.c g_initialize.c \ + g_init_sec_context.c g_inq_context.c g_inq_cred.c g_inq_names.c \ + g_mechname.c g_mit_krb5_mech.c g_oid_ops.c g_process_context.c \ + g_rel_buffer.c g_rel_cred.c g_rel_name.c g_rel_oid_set.c g_seal.c \ + g_sign.c gssd_pname_to_uid.c g_unseal.c g_verify.c oid_ops.c \ + g_set_allowable_enctypes.c + +OBJS = $(SRCS:.c=.o) + +include $(TOP)rules.mk + +CFLAGS += -DKRB5_VERSION=$(KRB5_VERSION) -I$(TOP)/support/include + +install:: + @: diff --git a/support/gssapi/SAMPLE_gssapi_mech.conf b/support/gssapi/SAMPLE_gssapi_mech.conf new file mode 100644 index 0000000..8eca824 --- /dev/null +++ b/support/gssapi/SAMPLE_gssapi_mech.conf @@ -0,0 +1,19 @@ +# GSSAPI Mechanism Definitions +# +# This configuration file determines which GSS-API mechanisms +# the gssd code should use +# +# NOTE: +# The initiaiization function "mechglue_internal_krb5_init" +# is used for the MIT krb5 gssapi mechanism. This special +# function name indicates that an internal function should +# be used to determine the entry points for the MIT gssapi +# mechanism funtions. +# +# library initialization function +# ================================ ========================== +# The MIT K5 gssapi library, use special function for initialization. +/usr/lib/libgssapi_krb5.so mechglue_internal_krb5_init +# +# The SPKM3 gssapi library function. Use the function spkm3_gss_initialize. +# /usr/local/gss_mechs/spkm/spkm3/libgssapi_spkm3.so spkm3_gss_initialize diff --git a/support/gssapi/g_accept_sec_context.c b/support/gssapi/g_accept_sec_context.c new file mode 100644 index 0000000..05e967b --- /dev/null +++ b/support/gssapi/g_accept_sec_context.c @@ -0,0 +1,213 @@ +/* #ident "@(#)gss_accept_sec_context.c 1.19 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_accept_sec_context + */ + +#include "mglueP.h" +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> +#include <errno.h> + +OM_uint32 KRB5_CALLCONV +gss_accept_sec_context (minor_status, + context_handle, + verifier_cred_handle, + input_token_buffer, + input_chan_bindings, + src_name, + mech_type, + output_token, + ret_flags, + time_rec, + delegated_cred_handle) + +OM_uint32 * minor_status; +gss_ctx_id_t * context_handle; +gss_cred_id_t verifier_cred_handle; +gss_buffer_t input_token_buffer; +gss_channel_bindings_t input_chan_bindings; +gss_name_t * src_name; +gss_OID * mech_type; +gss_buffer_t output_token; +OM_uint32 * ret_flags; +OM_uint32 * time_rec; +gss_cred_id_t * delegated_cred_handle; + +{ + OM_uint32 status, temp_status, temp_minor_status; + gss_union_ctx_id_t union_ctx_id; + gss_union_cred_t union_cred; + gss_cred_id_t input_cred_handle = GSS_C_NO_CREDENTIAL; + gss_name_t internal_name; + gss_OID_desc token_mech_type_desc; + gss_OID token_mech_type = &token_mech_type_desc; + gss_mechanism mech; + + gss_initialize(); + + if (context_handle == NULL) + return GSS_S_NO_CONTEXT; + + /* + * if context_handle is GSS_C_NO_CONTEXT, allocate a union context + * descriptor to hold the mech type information as well as the + * underlying mechanism context handle. Otherwise, cast the + * value of *context_handle to the union context variable. + */ + + if(*context_handle == GSS_C_NO_CONTEXT) { + + /* Get the token mech type */ + status = __gss_get_mech_type(token_mech_type, input_token_buffer); + if (status) + return status; + + status = GSS_S_FAILURE; + union_ctx_id = (gss_union_ctx_id_t) + malloc(sizeof(gss_union_ctx_id_desc)); + if (!union_ctx_id) { + *minor_status = ENOMEM; + goto error_out; + } + + union_ctx_id->mech_type = (gss_OID) malloc(sizeof(gss_OID_desc)); + if (!union_ctx_id->mech_type) { + *minor_status = ENOMEM; + goto error_out; + } + + union_ctx_id->mech_type->elements = (void *) + malloc(token_mech_type->length); + if (!union_ctx_id->mech_type->elements) { + *minor_status = ENOMEM; + goto error_out; + } + + union_ctx_id->mech_type->length = token_mech_type->length; + memcpy(union_ctx_id->mech_type->elements, + token_mech_type->elements, + token_mech_type->length); + + /* copy the supplied context handle */ + + union_ctx_id->internal_ctx_id = *context_handle; + } else { + union_ctx_id = *context_handle; + token_mech_type = union_ctx_id->mech_type; + } + + /* + * get the appropriate cred handle from the union cred struct. + * defaults to GSS_C_NO_CREDENTIAL if there is no cred, which will + * use the default credential. + */ + union_cred = (gss_union_cred_t) verifier_cred_handle; + input_cred_handle = __gss_get_mechanism_cred(union_cred, token_mech_type); + + /* + * now select the approprate underlying mechanism routine and + * call it. + */ + + mech = __gss_get_mechanism (token_mech_type); + if (mech && mech->gss_accept_sec_context) { + + status = mech->gss_accept_sec_context( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + &union_ctx_id->internal_ctx_id, + input_cred_handle, + input_token_buffer, + input_chan_bindings, + &internal_name, + mech_type, + output_token, + ret_flags, + time_rec, + delegated_cred_handle); + + /* If there's more work to do, keep going... */ + if (status == GSS_S_CONTINUE_NEEDED) + return GSS_S_CONTINUE_NEEDED; + + /* if the call failed, return with failure */ + if (status != GSS_S_COMPLETE) + goto error_out; + + /* + * if src_name is non-NULL, + * convert internal_name into a union name equivalent + * First call the mechanism specific display_name() + * then call gss_import_name() to create + * the union name struct cast to src_name + */ +#if 0 + /* ANDROS: src_name is never null, it is a ptr from the gss_accept_sec_context + * caller. internal_name may or may not be set by the mechanism. so, don't + * call __gss_convert_name_to_union_name which sets the src_name + * unless the internal name is set + * by the above mech->gss_accept_sec_context. + */ + if (internal_name != NULL && status == GSS_S_COMPLETE) { +#else + if (src_name != NULL && status == GSS_S_COMPLETE) { +#endif + temp_status = __gss_convert_name_to_union_name( + &temp_minor_status, mech, internal_name, src_name); + if (temp_status != GSS_S_COMPLETE) { + if (minor_status) + *minor_status = temp_minor_status; + gss_release_buffer(&temp_minor_status, output_token); + __gss_release_internal_name(&temp_minor_status, + &mech->mech_type, &internal_name); + return (temp_status); + } + } + + if(*context_handle == GSS_C_NO_CONTEXT) + *context_handle = (gss_ctx_id_t *) union_ctx_id; + + return(status); + } + + return(GSS_S_BAD_MECH); + +error_out: + if (union_ctx_id) { + if (union_ctx_id->mech_type) { + if (union_ctx_id->mech_type->elements) + free(union_ctx_id->mech_type->elements); + free(union_ctx_id->mech_type); + } + free(union_ctx_id); + } + return (status); +} + diff --git a/support/gssapi/g_acquire_cred.c b/support/gssapi/g_acquire_cred.c new file mode 100644 index 0000000..50087db --- /dev/null +++ b/support/gssapi/g_acquire_cred.c @@ -0,0 +1,539 @@ +/* #ident "@(#)gss_acquire_cred.c 1.19 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_acquire_cred + */ + +#include "mglueP.h" +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> +#include <errno.h> +#include <time.h> + +#define g_OID_equal(o1,o2) \ + (((o1)->length == (o2)->length) && \ + (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0)) + +static gss_OID_set +create_actual_mechs(creds) + gss_union_cred_t creds; +{ + gss_OID_set actual_mechs; + int i; + + actual_mechs = (gss_OID_set) malloc(sizeof(gss_OID_set_desc)); + if (!actual_mechs) + return NULL; + + actual_mechs->elements = (gss_OID) + malloc(sizeof(gss_OID_desc) * creds->count); + if (!actual_mechs->elements) { + free(actual_mechs); + return NULL; + } + + actual_mechs->count = creds->count; + + for (i=0; i < creds->count; i++) { + actual_mechs->elements[i].length = creds->mechs_array[i].length; + actual_mechs->elements[i].elements = (void *) + malloc(creds->mechs_array[i].length); + memcpy(actual_mechs->elements[i].elements, + creds->mechs_array[i].elements, creds->mechs_array[i].length); + } + + return actual_mechs; +} + + +OM_uint32 KRB5_CALLCONV +gss_acquire_cred(minor_status, + desired_name, + time_req, + desired_mechs, + cred_usage, + output_cred_handle, + actual_mechs, + time_rec) + +OM_uint32 * minor_status; +gss_name_t desired_name; +OM_uint32 time_req; +gss_OID_set desired_mechs; +int cred_usage; +gss_cred_id_t * output_cred_handle; +gss_OID_set * actual_mechs; +OM_uint32 * time_rec; + +{ + OM_uint32 status, temp_minor_status, temp_time_rec = ~0; + unsigned int i, j, creds_acquired = 0; + int k; + gss_union_name_t union_name; + gss_name_t internal_name; + gss_union_cred_t creds; + gss_OID_set_desc default_OID_set; + gss_OID_desc default_OID; + gss_OID specific_mech_type = 0; + gss_mechanism mech; + + /* + * This struct is used to keep track of which mech_types are + * actually available and to store the credentials returned + * from them by each mechanism specific gss_acquire_cred() call. + * The results are used to construct the final union_cred + * structure returned by the glue layer gss_acquire_cred() call + * and the actual_mechs gss_OID_set returned. + */ + + struct creds_returned { + unsigned char available; + gss_cred_id_t cred; + } *creds_returned; + + gss_initialize(); + + /* Set this to NULL for now */ + + if (actual_mechs) + *actual_mechs = GSS_C_NULL_OID_SET; + + if (minor_status) + *minor_status = 0; + + /* No need to continue if we don't have a place to store the creds */ + if (output_cred_handle == NULL) + return GSS_S_COMPLETE; + + /* get desired_name cast as a union_name type */ + + union_name = (gss_union_name_t) desired_name; + + if (union_name) + specific_mech_type = union_name->mech_type; + + /* + * if desired_mechs equals GSS_C_NULL_OID_SET, then pick an + * appropriate default. + */ + if(desired_mechs == GSS_C_NULL_OID_SET) { + /* + * If union_name->mech_type is NULL then we get the default + * mechanism; otherwise, we get the mechanism for the + * mechanism-specific name. + */ + mech = __gss_get_mechanism(specific_mech_type); + if (mech == NULL) + return (GSS_S_BAD_MECH); + + desired_mechs = &default_OID_set; + default_OID_set.count = 1 ; + default_OID_set.elements = &default_OID; + default_OID.length = mech->mech_type.length; + default_OID.elements = mech->mech_type.elements; + } + + /* + * Now allocate the creds returned array. There is one element + * for each member of the desired_mechs argument. + */ + + creds_returned = (struct creds_returned *) + malloc(sizeof(struct creds_returned) * desired_mechs->count); + + /* + * For each requested mechanism in desired_mechs, determine if it + * is supported. If so, mark the corresponding element in + * creds_returned->available as 1 and call the mechanism + * specific gss_acquire_cred(), placing the returned cred in + * creds_returned->cred. If not, mark creds_returned->available as + * 0. + */ + status = GSS_S_BAD_MECH; + for (j=0; j < desired_mechs->count; j++) { + creds_returned[j].available = 0; + + mech = __gss_get_mechanism (&desired_mechs->elements[j]); + if (!mech || !mech->gss_acquire_cred) + continue; + /* + * If this is a mechanism-specific name, then only use the + * mechanism of the name. + */ + if (specific_mech_type && !g_OID_equal(specific_mech_type, + &mech->mech_type)) + continue; + /* + * If this is not a mechanism-specific name, then we need to + * do an import the external name in union_name first. + */ + if (union_name == 0) + internal_name = (gss_name_t) 0; + else if (!union_name->mech_type) { + if (__gss_import_internal_name(&temp_minor_status, + &mech->mech_type, + union_name, &internal_name)) { + continue; + } + } else + internal_name = union_name->mech_name; + +#ifdef USE_MECH_CONTEXT + status = mech->gss_acquire_cred(mech->context, minor_status, +#else + status = mech->gss_acquire_cred(minor_status, +#endif + internal_name, time_req, + desired_mechs, cred_usage, + &creds_returned[j].cred, + NULL, &temp_time_rec); + + /* Release the internal name, if allocated above */ + if (union_name && !union_name->mech_type) { + (void) __gss_release_internal_name(&temp_minor_status, + &mech->mech_type, + &internal_name); + } + + if (status != GSS_S_COMPLETE) + continue; + + /* + * Add this into the creds_returned structure, if we got + * a good credential for this mechanism. + */ + if (time_rec) { + *time_rec = *time_rec > temp_time_rec ? temp_time_rec : *time_rec; + temp_time_rec = *time_rec; + } + + creds_returned[j].available = 1; + creds_acquired++; + + /* + * If union_name is set, then we're done. Continue, and + * declare success. Otherwise, if do an inquire credentials + * from the first mechanism that succeeds and use that as the + * union name. + */ + if (union_name) + continue; + +#ifdef USE_MECH_CONTEXT + status = mech->gss_inquire_cred(mech->context, &temp_minor_status, +#else + status = mech->gss_inquire_cred(&temp_minor_status, +#endif + creds_returned[j].cred, + &internal_name, 0, 0, 0); + if (status) { + /* Should never happen */ + creds_returned[j].available = 0; + creds_acquired--; + if (mech->gss_release_cred) +#ifdef USE_MECH_CONTEXT + mech->gss_release_cred(mech->context, minor_status, +#else + mech->gss_release_cred(minor_status, +#endif + &creds_returned[j].cred); + continue; + } + + status = __gss_convert_name_to_union_name(&temp_minor_status, mech, + internal_name, + (gss_name_t *) &union_name); + } + + /* + * Now allocate the creds struct, which will be cast as a gss_cred_id_t + * and returned in the output_cred_handle argument. If there were + * no credentials found, return an error. Also, allocate the + * actual_mechs data. + */ + if (creds_acquired == 0) { + free (creds_returned); + return (status); + } + + creds = (gss_union_cred_t) malloc(sizeof(gss_union_cred_desc)); + + creds->count = creds_acquired; + + creds->mechs_array = (gss_OID) + malloc(sizeof(gss_OID_desc) * creds_acquired); + + creds->cred_array = (gss_cred_id_t *) + malloc(sizeof(gss_cred_id_t) * creds_acquired); + + if(actual_mechs != NULL) { + *actual_mechs = (gss_OID_set) malloc(sizeof(gss_OID_set_desc)); + + (*actual_mechs)->count = creds_acquired; + + (*actual_mechs)->elements = (gss_OID) + malloc(sizeof(gss_OID_desc) * creds_acquired); + } + + /* + * copy the mechanisms found and their allocated credentials into the + * creds structure. At the same time, build up the actual_mechs + * data. + */ + + j = 0; + + for (i=0; i<desired_mechs->count; i++) { + if(creds_returned[i].available) { + + creds->mechs_array[j].length = + desired_mechs->elements[i].length; + creds->mechs_array[j].elements = (void *) + malloc(desired_mechs->elements[i].length); + memcpy(creds->mechs_array[j].elements, + desired_mechs->elements[i].elements, + desired_mechs->elements[i].length); + creds->cred_array[j] = creds_returned[i].cred; + if (actual_mechs) { + (*actual_mechs)->elements[j].length = + desired_mechs->elements[i].length; + (*actual_mechs)->elements[j].elements = (void *) + malloc(desired_mechs->elements[i].length); + memcpy((*actual_mechs)->elements[j].elements, + desired_mechs->elements[i].elements, + desired_mechs->elements[i].length); + } + j++; + } + } + + /* free the creds_returned struct, since we are done with it. */ + + free(creds_returned); + + /* record the information needed for gss_inquire_cred() */ + + creds->auxinfo.creation_time = time(0); + creds->auxinfo.time_rec = temp_time_rec; + creds->auxinfo.cred_usage = cred_usage; + + /* + * we can't just record the internal name, desired_name, since + * it may be destroyed between now and the time gss_inquire_cred() + * is called. So we must record the printable name in a + * gss_buffer_t, calling gss_display_name() to fill it in. When + * gss_inquire_name() is called, we must then call gss_import_name() + * to get the internal name that is required at that point. + */ + if (desired_name) { + status = gss_display_name(&temp_minor_status, desired_name, + &creds->auxinfo.name, + &creds->auxinfo.name_type); + if (status) { + status = GSS_S_BAD_NAME; + goto error_out; + } + } else { + status = gss_display_name(&temp_minor_status, union_name, + &creds->auxinfo.name, + &creds->auxinfo.name_type); + if (status) { + status = GSS_S_BAD_NAME; + goto error_out; + } + } + + *output_cred_handle = (gss_cred_id_t) creds; + return(GSS_S_COMPLETE); + +error_out: + for (k=0; k < creds->count; k++) { + free(creds->mechs_array[k].elements); + if (actual_mechs) + free((*actual_mechs)->elements[k].elements); + } + + if (actual_mechs) { + free((*actual_mechs)->elements); + free(*actual_mechs); + *actual_mechs = GSS_C_NULL_OID_SET; + } + free(creds->cred_array); + free(creds->mechs_array); + free(creds); + + return(status); +} + +/* V2 KRB5_CALLCONV */ +OM_uint32 KRB5_CALLCONV +gss_add_cred(minor_status, input_cred_handle, + desired_name, desired_mech, cred_usage, + initiator_time_req, acceptor_time_req, + output_cred_handle, actual_mechs, + initiator_time_rec, acceptor_time_rec) + OM_uint32 *minor_status; + gss_cred_id_t input_cred_handle; + gss_name_t desired_name; + gss_OID desired_mech; + 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; +{ + OM_uint32 status, temp_minor_status; + OM_uint32 time_req, time_rec; + gss_union_name_t union_name; + gss_union_cred_t new_union_cred, union_cred; + gss_name_t internal_name; + gss_mechanism mech; + gss_cred_id_t cred; + gss_OID new_mechs_array; + gss_cred_id_t * new_cred_array; + + if (input_cred_handle == GSS_C_NO_CREDENTIAL) + return GSS_S_NO_CRED; + + union_cred = (gss_union_cred_t) input_cred_handle; + + mech = __gss_get_mechanism(desired_mech); + if (!mech) + return GSS_S_BAD_MECH; + + if (__gss_get_mechanism_cred(union_cred, desired_mech) != + GSS_C_NO_CREDENTIAL) + return GSS_S_DUPLICATE_ELEMENT; + + union_name = (gss_union_name_t) desired_name; + if (union_name->mech_type) { + if (!g_OID_equal(desired_mech, union_name->mech_type)) + return GSS_S_BAD_NAMETYPE; + internal_name = union_name->mech_name; + } else { + if (__gss_import_internal_name(minor_status, desired_mech, + union_name, &internal_name)) + return (GSS_S_BAD_NAME); + } + + if (cred_usage == GSS_C_ACCEPT) + time_req = acceptor_time_req; + else if (cred_usage == GSS_C_INITIATE) + time_req = initiator_time_req; + else if (cred_usage == GSS_C_BOTH) + time_req = (acceptor_time_req > initiator_time_req) ? + acceptor_time_req : initiator_time_req; + +#ifdef USE_MECH_CONTEXT + status = mech->gss_acquire_cred(mech->context, minor_status, +#else + status = mech->gss_acquire_cred(minor_status, +#endif + internal_name, time_req, + GSS_C_NULL_OID_SET, cred_usage, + &cred, NULL, &time_rec); + if (status != GSS_S_COMPLETE) + goto errout; + + new_mechs_array = (gss_OID) + malloc(sizeof(gss_OID_desc) * (union_cred->count+1)); + + new_cred_array = (gss_cred_id_t *) + malloc(sizeof(gss_cred_id_t) * (union_cred->count+1)); + + if (!new_mechs_array || !new_cred_array) { + *minor_status = ENOMEM; + status = GSS_S_FAILURE; + goto errout; + } + + + if (acceptor_time_rec) + if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) + *acceptor_time_rec = time_rec; + if (initiator_time_rec) + if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH) + *initiator_time_rec = time_rec; + + /* + * OK, expand the mechanism array in the union credentials + * (Look for the union label...) + */ + memcpy(new_mechs_array, union_cred->mechs_array, + sizeof(gss_OID_desc) * union_cred->count); + memcpy(new_cred_array, union_cred->cred_array, + sizeof(gss_cred_id_t) * union_cred->count); + + new_cred_array[union_cred->count] = cred; + new_mechs_array[union_cred->count].length = desired_mech->length; + new_mechs_array[union_cred->count].elements = malloc(desired_mech->length); + if (!new_mechs_array[union_cred->count].elements) { + *minor_status = ENOMEM; + goto errout; + } + memcpy(new_mechs_array[union_cred->count].elements, desired_mech->elements, + desired_mech->length); + + if (output_cred_handle == NULL) { + free(union_cred->mechs_array); + free(union_cred->cred_array); + new_union_cred = union_cred; + } else { + new_union_cred = malloc(sizeof(gss_union_cred_desc)); + if (new_union_cred == NULL) { + *minor_status = ENOMEM; + goto errout; + } + *new_union_cred = *union_cred; + *output_cred_handle = new_union_cred; + } + new_union_cred->mechs_array = new_mechs_array; + new_union_cred->cred_array = new_cred_array; + new_union_cred->count++; + new_mechs_array = 0; + new_cred_array = 0; + + if (actual_mechs) + *actual_mechs = create_actual_mechs(new_union_cred); + + status = GSS_S_COMPLETE; + +errout: + if (new_mechs_array) + free(new_mechs_array); + if (new_cred_array) + free(new_cred_array); + if (!union_name->mech_type) { + (void) __gss_release_internal_name(&temp_minor_status, + desired_mech, &internal_name); + } + + return(status); +} diff --git a/support/gssapi/g_compare_name.c b/support/gssapi/g_compare_name.c new file mode 100644 index 0000000..496d497 --- /dev/null +++ b/support/gssapi/g_compare_name.c @@ -0,0 +1,165 @@ +/* #ident "@(#)gss_compare_name.c 1.13 95/08/02 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_compare_name + * + */ + +#include "mglueP.h" +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> + +#define g_OID_equal(o1,o2) \ + (((o1)->length == (o2)->length) && \ + (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0)) + +OM_uint32 KRB5_CALLCONV +gss_compare_name (minor_status, + name1, + name2, + name_equal) + +OM_uint32 * minor_status; +gss_name_t name1; +gss_name_t name2; +int * name_equal; + +{ + OM_uint32 major_status, temp_minor; + gss_union_name_t union_name1, union_name2; + gss_mechanism mech; + gss_name_t internal_name; + + gss_initialize(); + + if (name1 == 0 || name2 == 0) { + if (name_equal) + *name_equal = 0; + return GSS_S_BAD_NAME; + } + + union_name1 = (gss_union_name_t) name1; + union_name2 = (gss_union_name_t) name2; + /* + * Try our hardest to make union_name1 be the mechanism-specific + * name. (Of course we can't if both names aren't + * mechanism-specific.) + */ + if (union_name1->mech_type == 0) { + union_name1 = (gss_union_name_t) name2; + union_name2 = (gss_union_name_t) name1; + } + /* + * If union_name1 is mechanism specific, then fetch its mechanism + * information. + */ + if (union_name1->mech_type) { + mech = __gss_get_mechanism (union_name1->mech_type); + if (!mech) + return (GSS_S_BAD_MECH); + if (!mech->gss_compare_name) + return (GSS_S_BAD_BINDINGS); + } + + if (name_equal == NULL) + return GSS_S_COMPLETE; + + *name_equal = 0; /* Default to *not* equal.... */ + + /* + * First case... both names are mechanism-specific + */ + if (union_name1->mech_type && union_name2->mech_type) { + if (!g_OID_equal(union_name1->mech_type, union_name2->mech_type)) + return (GSS_S_COMPLETE); + if ((union_name1->mech_name == 0) || (union_name2->mech_name == 0)) + /* should never happen */ + return (GSS_S_BAD_NAME); +#ifdef USE_MECH_CONTEXT + return (mech->gss_compare_name(mech->context, minor_status, +#else + return (mech->gss_compare_name(minor_status, +#endif + union_name1->mech_name, + union_name2->mech_name, name_equal)); + + } + + /* + * Second case... both names are NOT mechanism specific. + * + * All we do here is make sure the two name_types are equal and then + * that the external_names are equal. Note the we do not take care + * of the case where two different external names map to the same + * internal name. We cannot determine this, since we as yet do not + * know what mechanism to use for calling the underlying + * gss_import_name(). + */ + if (!union_name1->mech_type && !union_name2->mech_type) { + if (!g_OID_equal(union_name1->name_type, union_name2->name_type)) + return (GSS_S_COMPLETE); + if ((union_name1->external_name->length != + union_name2->external_name->length) || + (memcmp(union_name1->external_name->value, + union_name2->external_name->value, + union_name1->external_name->length) != 0)) + return (GSS_S_COMPLETE); + *name_equal = 1; + return (GSS_S_COMPLETE); + } + + /* + * Final case... one name is mechanism specific, the other isn't. + * + * We attempt to convert the general name to the mechanism type of + * the mechanism-specific name, and then do the compare. If we + * can't import the general name, then we return that the name is + * _NOT_ equal. + */ + if (union_name2->mech_type) { + /* We make union_name1 the mechanism specific name. */ + union_name1 = (gss_union_name_t) name2; + union_name2 = (gss_union_name_t) name1; + } + major_status = __gss_import_internal_name(minor_status, + union_name1->mech_type, + union_name2, + &internal_name); + if (major_status != GSS_S_COMPLETE) + return (GSS_S_COMPLETE); +#ifdef USE_MECH_CONTEXT + major_status = mech->gss_compare_name(mech->context, minor_status, +#else + major_status = mech->gss_compare_name(minor_status, +#endif + union_name1->mech_name, + internal_name, name_equal); + __gss_release_internal_name(&temp_minor, union_name1->mech_type, + &internal_name); + return (major_status); + +} diff --git a/support/gssapi/g_context_time.c b/support/gssapi/g_context_time.c new file mode 100644 index 0000000..13ae5c8 --- /dev/null +++ b/support/gssapi/g_context_time.c @@ -0,0 +1,75 @@ +/* #ident "@(#)gss_context_time.c 1.8 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routines for gss_context_time + */ + +#include "mglueP.h" + +OM_uint32 KRB5_CALLCONV +gss_context_time (minor_status, + context_handle, + time_rec) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +OM_uint32 * time_rec; + +{ + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + gss_initialize(); + + if (context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + + if (mech) { + + if (mech->gss_context_time) + status = mech->gss_context_time( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + ctx->internal_ctx_id, + time_rec); + else + status = GSS_S_BAD_BINDINGS; + + return(status); + } + + return(GSS_S_NO_CONTEXT); +} diff --git a/support/gssapi/g_delete_sec_context.c b/support/gssapi/g_delete_sec_context.c new file mode 100644 index 0000000..e9253c8 --- /dev/null +++ b/support/gssapi/g_delete_sec_context.c @@ -0,0 +1,88 @@ +/* #ident "@(#)gss_delete_sec_context.c 1.10 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_delete_sec_context + */ + +#include "mglueP.h" +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +OM_uint32 KRB5_CALLCONV +gss_delete_sec_context (minor_status, + context_handle, + output_token) + +OM_uint32 * minor_status; +gss_ctx_id_t * context_handle; +gss_buffer_t output_token; + +{ + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + gss_initialize(); + + /* if the context_handle is Null, return NO_CONTEXT error */ + + if(context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT) + return(GSS_S_NO_CONTEXT); + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) *context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + + if (mech) { + + if (mech->gss_delete_sec_context) + status = mech->gss_delete_sec_context( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + &ctx->internal_ctx_id, + output_token); + else + status = GSS_S_BAD_BINDINGS; + + /* now free up the space for the union context structure */ + + free(ctx->mech_type->elements); + free(ctx->mech_type); + free(*context_handle); + *context_handle = NULL; + + return(status); + } + + return(GSS_S_NO_CONTEXT); +} diff --git a/support/gssapi/g_dsp_name.c b/support/gssapi/g_dsp_name.c new file mode 100644 index 0000000..dcf1800 --- /dev/null +++ b/support/gssapi/g_dsp_name.c @@ -0,0 +1,96 @@ +/* #ident "@(#)g_dsp_name.c 1.2 96/02/06 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_display_name() + * + */ + +#include "mglueP.h" +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> + +OM_uint32 KRB5_CALLCONV +gss_display_name (minor_status, + input_name, + output_name_buffer, + output_name_type) + +OM_uint32 * minor_status; +gss_name_t input_name; +gss_buffer_t output_name_buffer; +gss_OID * output_name_type; + +{ + OM_uint32 major_status; + gss_union_name_t union_name; + + if (input_name == 0) + return GSS_S_BAD_NAME; + + union_name = (gss_union_name_t) input_name; + + if (union_name->mech_type) { + /* + * OK, we have a mechanism-specific name; let's use it! + */ + return (__gss_display_internal_name(minor_status, + union_name->mech_type, + union_name->mech_name, + output_name_buffer, + output_name_type)); + } + + /* + * copy the value of the external_name component of the union + * name into the output_name_buffer and point the output_name_type + * to the name_type component of union_name + */ + if (output_name_type != NULL) { + major_status = generic_gss_copy_oid(minor_status, + union_name->name_type, + output_name_type); + if (major_status) + return (major_status); + } + + if (output_name_buffer != NULL) { + output_name_buffer->length = union_name->external_name->length; + + output_name_buffer->value = + (void *) malloc(output_name_buffer->length); + + memcpy(output_name_buffer->value, + union_name->external_name->value, + output_name_buffer->length); + } + + if (minor_status) + *minor_status = 0; + + return(GSS_S_COMPLETE); +} diff --git a/support/gssapi/g_dsp_status.c b/support/gssapi/g_dsp_status.c new file mode 100644 index 0000000..42cae0d --- /dev/null +++ b/support/gssapi/g_dsp_status.c @@ -0,0 +1,86 @@ +/* #ident "@(#)gss_display_status.c 1.8 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine gss_display_status + * + */ + +#include "mglueP.h" +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +OM_uint32 KRB5_CALLCONV +gss_display_status (minor_status, + status_value, + status_type, + req_mech_type, + message_context, + status_string) + +OM_uint32 * minor_status; +OM_uint32 status_value; +int status_type; +gss_OID req_mech_type; +OM_uint32 * message_context; +gss_buffer_t status_string; + +{ + OM_uint32 status; + gss_OID mech_type = (gss_OID) req_mech_type; + gss_mechanism mech; + + gss_initialize(); + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + mech = __gss_get_mechanism (mech_type); + + if (mech == NULL) + return (GSS_S_BAD_MECH); + + if (mech_type == GSS_C_NULL_OID) + mech_type = &mech->mech_type; + + if (mech->gss_display_status) + status = mech->gss_display_status( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + status_value, + status_type, + mech_type, + message_context, + status_string); + else + status = GSS_S_BAD_BINDINGS; + + return(status); +} diff --git a/support/gssapi/g_dup_name.c b/support/gssapi/g_dup_name.c new file mode 100644 index 0000000..bb88813 --- /dev/null +++ b/support/gssapi/g_dup_name.c @@ -0,0 +1,162 @@ +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * created andros 2.24.01 from g_compare_name.c + */ + +/* + * glue routine for gss_duplicate_name + * + */ + +#include <stdio.h> +#include "mglueP.h" +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> +#include <errno.h> + +OM_uint32 KRB5_CALLCONV +gss_duplicate_name (minor_status, + in_name, + exp_name) +OM_uint32 * minor_status; +const gss_name_t in_name; +gss_name_t *exp_name; +{ + OM_uint32 tmp,major_status = GSS_S_COMPLETE; + gss_union_name_t union_in_name, union_exp_name; + gss_mechanism mech; + + gss_initialize(); + + /* if exp_name is NULL, simply return */ + if (exp_name == NULL) + return (GSS_S_COMPLETE); + + *exp_name = NULL; + + if (in_name == 0) + return (GSS_S_BAD_NAME); + + union_in_name = (gss_union_name_t) in_name; + + /* + * Create the union name struct that will hold the exported + * name and the name type. + */ + + union_exp_name = (gss_union_name_t) malloc (sizeof(gss_union_name_desc)); + if (!union_exp_name) { + *minor_status = ENOMEM; + goto allocation_failure; + } +#ifdef DEBUG + fprintf(stderr, "gss_duplicate_name: copying *oid %p\n", + union_in_name->mech_type); +#endif + union_exp_name->gss_mech = union_in_name->gss_mech; + union_exp_name->mech_type = GSS_C_NO_OID; + if (union_in_name->mech_type != GSS_C_NO_OID && + (generic_gss_copy_oid(&tmp, union_in_name->mech_type, + &union_exp_name->mech_type) != GSS_S_COMPLETE)) { + *minor_status = ENOMEM; + goto allocation_failure; + } + union_exp_name->mech_name = NULL; + union_exp_name->name_type = GSS_C_NO_OID; + if (union_in_name->name_type != GSS_C_NO_OID && + (generic_gss_copy_oid(&tmp, union_in_name->name_type, + &union_exp_name->name_type) != GSS_S_COMPLETE)) { + *minor_status = ENOMEM; + goto allocation_failure; + } + union_exp_name->external_name = NULL; + union_exp_name->external_name = + (gss_buffer_t) malloc(sizeof(gss_buffer_desc)); + if (!union_exp_name->external_name) { + *minor_status = ENOMEM; + goto allocation_failure; + } + union_exp_name->external_name->length = union_in_name->external_name->length; + /* + * we malloc length+1 to stick a NULL on the end, just in case + * Note that this NULL is not included in ->length for a reason! + */ + + union_exp_name->external_name->value = + (void *) malloc(union_in_name->external_name->length); + if (!union_exp_name->external_name->value) { + *minor_status = ENOMEM; + goto allocation_failure; + } + memcpy(union_exp_name->external_name->value, + union_in_name->external_name->value, + union_exp_name->external_name->length); + + /* + * Mechanism specific name + */ + + if (union_in_name->mech_type != GSS_C_NO_OID) { + mech = __gss_get_mechanism (union_in_name->mech_type); + if (!mech) + return (GSS_S_BAD_MECH); + if (!mech->gss_duplicate_name) + return (GSS_S_BAD_BINDINGS); + +#ifdef USE_MECH_CONTEXT + major_status = mech->gss_duplicate_name(mech->context, minor_status, +#else + major_status = mech->gss_duplicate_name(minor_status, +#endif + union_in_name->mech_name, &union_exp_name->mech_name); + if (major_status != GSS_S_COMPLETE) + return (major_status); + } +#ifdef DEBUG + fprintf(stderr, "gss_duplicate_name: returning union_exp_name %p\n", + union_exp_name); +#endif + *exp_name = union_exp_name; + return (major_status); + +allocation_failure: + if (union_exp_name) { + if (union_exp_name->external_name) { + if (union_exp_name->external_name->value) + free(union_exp_name->external_name->value); + free(union_exp_name->external_name); + } + if (union_exp_name->name_type) + generic_gss_release_oid(&tmp, &union_exp_name->name_type); + if (union_exp_name->mech_name) + __gss_release_internal_name(minor_status, union_exp_name->mech_type, + &union_exp_name->mech_name); + if (union_exp_name->mech_type) + generic_gss_release_oid(&tmp, &union_exp_name->mech_type); + free(union_exp_name); + } +return (major_status); + +} + diff --git a/support/gssapi/g_exp_sec_context.c b/support/gssapi/g_exp_sec_context.c new file mode 100644 index 0000000..59d9e80 --- /dev/null +++ b/support/gssapi/g_exp_sec_context.c @@ -0,0 +1,108 @@ +/* #ident "@(#)g_exp_sec_context.c 1.2 96/01/18 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_export_sec_context + */ + +#include "mglueP.h" +#include <stdio.h> +#include <errno.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> + +OM_uint32 KRB5_CALLCONV +gss_export_sec_context(minor_status, + context_handle, + interprocess_token) + +OM_uint32 * minor_status; +gss_ctx_id_t * context_handle; +gss_buffer_t interprocess_token; + +{ + OM_uint32 status; + size_t length; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + gss_buffer_desc token; + char *buf; + + gss_initialize(); + + if (context_handle == NULL || *context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) *context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + if (!mech) + return GSS_S_BAD_MECH; + if (!mech->gss_export_sec_context) + return GSS_S_BAD_BINDINGS; + +#ifdef USE_MECH_CONTEXT + status = mech->gss_export_sec_context(mech->context, minor_status, +#else + status = mech->gss_export_sec_context(minor_status, +#endif + &ctx->internal_ctx_id, &token); + if (status != GSS_S_COMPLETE) + return (status); + + length = token.length + 4 + ctx->mech_type->length; + interprocess_token->length = length; + interprocess_token->value = malloc(length); + if (interprocess_token->value == 0) { + (void) gss_release_buffer(minor_status, &token); + *minor_status = ENOMEM; + return (GSS_S_FAILURE); + } + buf = interprocess_token->value; + length = ctx->mech_type->length; + buf[3] = (unsigned char) (length & 0xFF); + length >>= 8; + buf[2] = (unsigned char) (length & 0xFF); + length >>= 8; + buf[1] = (unsigned char) (length & 0xFF); + length >>= 8; + buf[0] = (unsigned char) (length & 0xFF); + memcpy(buf+4, ctx->mech_type->elements, (size_t) ctx->mech_type->length); + memcpy(buf+4+ctx->mech_type->length, token.value, token.length); + + (void) gss_release_buffer(minor_status, &token); + + free(ctx->mech_type->elements); + free(ctx->mech_type); + free(ctx); + *context_handle = 0; + + return(GSS_S_COMPLETE); +} diff --git a/support/gssapi/g_glue.c b/support/gssapi/g_glue.c new file mode 100644 index 0000000..cf2f76a --- /dev/null +++ b/support/gssapi/g_glue.c @@ -0,0 +1,344 @@ +/* #ident "@(#)g_glue.c 1.1 96/02/06 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "mglueP.h" +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> +#include <errno.h> + +#define g_OID_equal(o1,o2) \ + (((o1)->length == (o2)->length) && \ + (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0)) + +extern gss_mechanism *__gss_mechs_array; + +/* + * This file contains the support routines for the glue layer. + */ + +/* + * given the mechs_array and a mechanism OID, return the + * pointer to the mechanism, or NULL if that mechanism is + * not supported. If the requested OID is NULL, then return + * the first mechanism. + */ + +gss_mechanism __gss_get_mechanism (type) + gss_OID type; +{ + int i; + + if (type == GSS_C_NULL_OID) + return (__gss_mechs_array[0]); + + for (i=0; __gss_mechs_array[i]->mech_type.length != 0; i++) { + if ((__gss_mechs_array[i]->mech_type.length == type->length) && + (memcmp (__gss_mechs_array[i]->mech_type.elements, type->elements, + type->length) == 0)) { + + return (__gss_mechs_array[i]); + } + } + return NULL; +} + + +/* + * glue routine for get_mech_type + * + */ + +OM_uint32 __gss_get_mech_type(OID, token) + gss_OID OID; + gss_buffer_t token; +{ + unsigned char * buffer_ptr; + int length; + + /* + * This routine reads the prefix of "token" in order to determine + * its mechanism type. It assumes the encoding suggested in + * Appendix B of RFC 1508. This format starts out as follows : + * + * tag for APPLICATION 0, Sequence[constructed, definite length] + * length of remainder of token + * tag of OBJECT IDENTIFIER + * length of mechanism OID + * encoding of mechanism OID + * <the rest of the token> + * + * Numerically, this looks like : + * + * 0x60 + * <length> - could be multiple bytes + * 0x06 + * <length> - assume only one byte, hence OID length < 127 + * <mech OID bytes> + * + * The routine fills in the OID value and returns an error as necessary. + */ + + if (token == NULL) + return (GSS_S_DEFECTIVE_TOKEN); + + /* Skip past the APP/Sequnce byte and the token length */ + + buffer_ptr = (unsigned char *) token->value; + + if (*(buffer_ptr++) != 0x60) + return (GSS_S_DEFECTIVE_TOKEN); + length = *buffer_ptr++; + if (length & 0x80) { + if ((length & 0x7f) > 4) + return (GSS_S_DEFECTIVE_TOKEN); + buffer_ptr += length & 0x7f; + } + + if (*(buffer_ptr++) != 0x06) + return (GSS_S_DEFECTIVE_TOKEN); + + OID->length = (OM_uint32) *(buffer_ptr++); + OID->elements = (void *) buffer_ptr; + return (GSS_S_COMPLETE); +} + + +/* + * Internal routines to get and release an internal mechanism name + */ + +#include "mglueP.h" + +OM_uint32 __gss_import_internal_name (minor_status, mech_type, union_name, + internal_name) +OM_uint32 *minor_status; +gss_OID mech_type; +gss_union_name_t union_name; +gss_name_t *internal_name; +{ + OM_uint32 status; + gss_mechanism mech; + + mech = __gss_get_mechanism (mech_type); + if (mech) { + if (mech->gss_import_name) + status = mech->gss_import_name ( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + union_name->external_name, + union_name->name_type, + internal_name); + else + status = GSS_S_BAD_BINDINGS; + + return (status); + } + + return (GSS_S_BAD_MECH); +} + +OM_uint32 __gss_display_internal_name (minor_status, mech_type, internal_name, + external_name, name_type) +OM_uint32 *minor_status; +gss_OID mech_type; +gss_name_t internal_name; +gss_buffer_t external_name; +gss_OID *name_type; +{ + OM_uint32 status; + gss_mechanism mech; + + mech = __gss_get_mechanism (mech_type); + if (mech) { + if (mech->gss_display_name) + status = mech->gss_display_name ( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + internal_name, + external_name, + name_type); + else + status = GSS_S_BAD_BINDINGS; + + return (status); + } + + return (GSS_S_BAD_MECH); +} + +OM_uint32 __gss_release_internal_name (minor_status, mech_type, internal_name) +OM_uint32 *minor_status; +gss_OID mech_type; +gss_name_t *internal_name; +{ + OM_uint32 status; + gss_mechanism mech; + + mech = __gss_get_mechanism (mech_type); + if (mech) { + if (mech->gss_release_name) + status = mech->gss_release_name ( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + internal_name); + else + status = GSS_S_BAD_BINDINGS; + + return (status); + } + + return (GSS_S_BAD_MECH); +} + + +/* + * This function converts an internal gssapi name to a union gssapi + * name. Note that internal_name should be considered "consumed" by + * this call, whether or not we return an error. + */ +OM_uint32 __gss_convert_name_to_union_name(minor_status, mech, + internal_name, external_name) + OM_uint32 *minor_status; + gss_mechanism mech; + gss_name_t internal_name; + gss_name_t *external_name; +{ + OM_uint32 major_status,tmp; + gss_union_name_t union_name; + + union_name = (gss_union_name_t) malloc (sizeof(gss_union_name_desc)); + if (!union_name) { + *minor_status = ENOMEM; + goto allocation_failure; + } + union_name->mech_type = 0; + union_name->mech_name = internal_name; + union_name->name_type = 0; + union_name->external_name = 0; + union_name->gss_mech = mech; + + major_status = generic_gss_copy_oid(minor_status, &mech->mech_type, + &union_name->mech_type); + if (major_status != GSS_S_COMPLETE) + goto allocation_failure; + + union_name->external_name = + (gss_buffer_t) malloc(sizeof(gss_buffer_desc)); + if (!union_name->external_name) { + *minor_status = ENOMEM; + goto allocation_failure; + } + +#ifdef USE_MECH_CONTEXT + major_status = mech->gss_display_name(mech->context, minor_status, +#else + major_status = mech->gss_display_name(minor_status, +#endif + internal_name, + union_name->external_name, + &union_name->name_type); + if (major_status != GSS_S_COMPLETE) + goto allocation_failure; + + *external_name = union_name; + return (GSS_S_COMPLETE); + +allocation_failure: + if (union_name) { + if (union_name->external_name) { + if (union_name->external_name->value) + free(union_name->external_name->value); + free(union_name->external_name); + } + if (union_name->name_type) + generic_gss_release_oid(&tmp, &union_name->name_type); + if (union_name->mech_name) + __gss_release_internal_name(minor_status, union_name->mech_type, + &union_name->mech_name); + if (union_name->mech_type) + mech_gss_release_oid(&tmp, &union_name->mech_type, mech); + free(union_name); + } + return (major_status); +} + +/* + * Glue routine for returning the mechanism-specific credential from a + * external union credential. + */ +gss_cred_id_t +__gss_get_mechanism_cred(union_cred, mech_type) + gss_union_cred_t union_cred; + gss_OID mech_type; +{ + int i; + + if (union_cred == GSS_C_NO_CREDENTIAL) + return GSS_C_NO_CREDENTIAL; + + for (i=0; i < union_cred->count; i++) { + if (g_OID_equal(mech_type, &union_cred->mechs_array[i])) + return union_cred->cred_array[i]; + } + return GSS_C_NO_CREDENTIAL; +} + + +/* + * Glue routine to copy an external name buffer (used by gss_duplicate_name) + */ +OM_uint32 __gss_copy_namebuf(src, dest) + gss_buffer_t src; + gss_buffer_t *dest; +{ + gss_buffer_t temp = NULL; + + if (dest == NULL) + return (GSS_S_BAD_NAME); + + temp = (gss_buffer_t) malloc (sizeof(gss_buffer_t)); + if (!temp) { + return(GSS_S_FAILURE); + } + temp->value = (void *) malloc (src->length + 1); + if (temp->value == NULL) { + free(temp); + return(GSS_S_FAILURE); + } + + memcpy(temp->value, src->value, src->length); + temp->length = src->length; + + *dest = temp; + return (GSS_S_COMPLETE); +} diff --git a/support/gssapi/g_imp_name.c b/support/gssapi/g_imp_name.c new file mode 100644 index 0000000..43f9c50 --- /dev/null +++ b/support/gssapi/g_imp_name.c @@ -0,0 +1,161 @@ +/* #ident "@(#)g_imp_name.c 1.2 96/02/06 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine gss_import_name + * + */ + +#include "mglueP.h" +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> +#include <errno.h> + +OM_uint32 KRB5_CALLCONV +gss_import_name(minor_status, + input_name_buffer, + input_name_type, + output_name) + +OM_uint32 * minor_status; +gss_buffer_t input_name_buffer; +gss_OID input_name_type; +gss_name_t * output_name; + +{ + gss_union_name_t union_name; + OM_uint32 tmp, major_status = GSS_S_FAILURE; + gss_OID mech; + + gss_initialize(); + + if (minor_status) + *minor_status = 0; + + /* if output_name is NULL, simply return */ + + if(output_name == NULL) + return (GSS_S_COMPLETE); + + *output_name = 0; + + if (input_name_buffer == GSS_C_NO_BUFFER) + return (GSS_S_BAD_NAME); + + /* + * First create the union name struct that will hold the external + * name and the name type. + */ + + union_name = (gss_union_name_t) malloc (sizeof(gss_union_name_desc)); + if (!union_name) { + *minor_status = ENOMEM; + goto allocation_failure; + } + union_name->mech_type = 0; + union_name->mech_name = 0; + union_name->name_type = 0; + union_name->external_name = 0; + union_name->gss_mech = NULL; + + /* + * All we do here is record the external name and name_type. + * When the name is actually used, the underlying gss_import_name() + * is called for the appropriate mechanism. Note that the name type + * is assumed to be constant, so only a pointer to it is stored in + * union_name + */ + union_name->external_name = + (gss_buffer_t) malloc(sizeof(gss_buffer_desc)); + if (!union_name->external_name) { + *minor_status = ENOMEM; + goto allocation_failure; + } + + union_name->external_name->length = input_name_buffer->length; + /* we malloc length+1 to stick a NULL on the end, just in case */ + /* Note that this NULL is not included in ->length for a reason! */ + union_name->external_name->value = + (void *) malloc(input_name_buffer->length+1); + if (!union_name->external_name->value) { + *minor_status = ENOMEM; + goto allocation_failure; + } + + memcpy(union_name->external_name->value, input_name_buffer->value, + input_name_buffer->length); + + /* add NULL to end of external_name->value, just in case... */ + ((char *)union_name->external_name->value) + [input_name_buffer->length] = '\0'; + + major_status = generic_gss_copy_oid(minor_status, input_name_type, + &union_name->name_type); + if (major_status != GSS_S_COMPLETE) + goto allocation_failure; + + /* + * See if this is a mechanism-specific name. If so, let's import + * it now so we can get any error messages, and to avoid trouble + * later... + */ + mech = gss_find_mechanism_from_name_type(input_name_type); + if (mech) { + major_status = generic_gss_copy_oid(minor_status, mech, + &union_name->mech_type); + if (major_status != GSS_S_COMPLETE) + goto allocation_failure; + + major_status = __gss_import_internal_name(minor_status, mech, + union_name, + &union_name->mech_name); + if (major_status) + goto allocation_failure; + } + + *output_name = (gss_name_t) union_name; + + return(GSS_S_COMPLETE); + +allocation_failure: + if (union_name) { + if (union_name->external_name) { + if (union_name->external_name->value) + free(union_name->external_name->value); + free(union_name->external_name); + } + if (union_name->name_type) + generic_gss_release_oid(&tmp, &union_name->name_type); + if (union_name->mech_name) + __gss_release_internal_name(minor_status, union_name->mech_type, + &union_name->mech_name); + if (union_name->mech_type) + generic_gss_release_oid(&tmp, &union_name->mech_type); + free(union_name); + } + return (major_status); +} diff --git a/support/gssapi/g_imp_sec_context.c b/support/gssapi/g_imp_sec_context.c new file mode 100644 index 0000000..faa58ed --- /dev/null +++ b/support/gssapi/g_imp_sec_context.c @@ -0,0 +1,128 @@ +/* #ident "@(#)g_imp_sec_context.c 1.2 96/01/18 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine gss_export_sec_context + */ + +#include "mglueP.h" +#include <stdio.h> +#include <errno.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> + +OM_uint32 KRB5_CALLCONV +gss_import_sec_context(minor_status, + interprocess_token, + context_handle) + +OM_uint32 * minor_status; +gss_buffer_t interprocess_token; +gss_ctx_id_t * context_handle; + +{ + size_t length; + OM_uint32 status; + char *p; + gss_union_ctx_id_t ctx; + gss_buffer_desc token; + gss_mechanism mech; + + gss_initialize(); + + *minor_status = 0; + + if (interprocess_token->length == 0 || interprocess_token->value == 0) + return (GSS_S_DEFECTIVE_TOKEN); + + status = GSS_S_FAILURE; + + ctx = (gss_union_ctx_id_t) malloc(sizeof(gss_union_ctx_id_desc)); + if (!ctx) { + *minor_status = ENOMEM; + goto error_out; + } + ctx->mech_type = (gss_OID) malloc(sizeof(gss_OID_desc)); + if (!ctx->mech_type) { + *minor_status = ENOMEM; + goto error_out; + } + p = interprocess_token->value; + length = *p++; + length = (length << 8) + *p++; + length = (length << 8) + *p++; + length = (length << 8) + *p++; + + ctx->mech_type->length = length; + ctx->mech_type->elements = malloc(length); + if (!ctx->mech_type->elements) { + *minor_status = ENOMEM; + goto error_out; + } + memcpy(ctx->mech_type->elements, p, length); + p += length; + + token.length = interprocess_token->length - 4 - length; + token.value = p; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + mech = __gss_get_mechanism (ctx->mech_type); + if (!mech) { + status = GSS_S_BAD_MECH; + goto error_out; + } + if (!mech->gss_import_sec_context) { + status = GSS_S_BAD_BINDINGS; + goto error_out; + } + +#ifdef USE_MECH_CONTEXT + status = mech->gss_import_sec_context(mech->context, minor_status, +#else + status = mech->gss_import_sec_context(minor_status, +#endif + &token, &ctx->internal_ctx_id); + + if (status == GSS_S_COMPLETE) { + *context_handle = ctx; + return (GSS_S_COMPLETE); + } + +error_out: + if (ctx) { + if (ctx->mech_type) { + if (ctx->mech_type->elements) + free(ctx->mech_type->elements); + free(ctx->mech_type); + } + free(ctx); + } + return status; +} diff --git a/support/gssapi/g_indicate_mechs.c b/support/gssapi/g_indicate_mechs.c new file mode 100644 index 0000000..9006d6d --- /dev/null +++ b/support/gssapi/g_indicate_mechs.c @@ -0,0 +1,90 @@ +/* #ident "@(#)gss_indicate_mechs.c 1.13 95/08/04 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_indicate_mechs + */ + +#include "mglueP.h" +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> + +extern gss_mechanism *__gss_mechs_array; + +static gss_OID_set_desc supported_mechs_desc; +static gss_OID_set supported_mechs = NULL; + +OM_uint32 KRB5_CALLCONV +gss_indicate_mechs (minor_status, + mech_set) + +OM_uint32 * minor_status; +gss_OID_set * mech_set; + +{ + int i; + + gss_initialize(); + + if (minor_status) + *minor_status = 0; + + /* + * If we have already computed the mechanisms supported, return + * a pointer to it. Otherwise, compute them and return the pointer. + */ + + if(supported_mechs == NULL) { + + supported_mechs = &supported_mechs_desc; + supported_mechs->count = 0; + + /* Build the mech_set from the OIDs in mechs_array. */ + + for(i=0; __gss_mechs_array[i]->mech_type.length != 0; i++) + supported_mechs->count++; + + supported_mechs->elements = + (void *) malloc(supported_mechs->count * + sizeof(gss_OID_desc)); + + for(i=0; i < supported_mechs->count; i++) { + supported_mechs->elements[i].length = + __gss_mechs_array[i]->mech_type.length; + supported_mechs->elements[i].elements = (void *) + malloc(__gss_mechs_array[i]->mech_type.length); + memcpy(supported_mechs->elements[i].elements, + __gss_mechs_array[i]->mech_type.elements, + __gss_mechs_array[i]->mech_type.length); + } + } + + if(mech_set != NULL) + *mech_set = supported_mechs; + + return(GSS_S_COMPLETE); +} diff --git a/support/gssapi/g_init_sec_context.c b/support/gssapi/g_init_sec_context.c new file mode 100644 index 0000000..a838597 --- /dev/null +++ b/support/gssapi/g_init_sec_context.c @@ -0,0 +1,194 @@ +/* #ident "@(#)gss_init_sec_context.c 1.20 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_init_sec_context + */ + +#include "mglueP.h" +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> + +#define g_OID_equal(o1,o2) \ + (((o1)->length == (o2)->length) && \ + (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0)) + +OM_uint32 KRB5_CALLCONV +gss_init_sec_context (minor_status, + claimant_cred_handle, + context_handle, + target_name, + req_mech_type, + req_flags, + time_req, + input_chan_bindings, + input_token, + actual_mech_type, + output_token, + ret_flags, + time_rec) + +OM_uint32 * minor_status; +gss_cred_id_t claimant_cred_handle; +gss_ctx_id_t * context_handle; +gss_name_t target_name; +gss_OID req_mech_type; +OM_uint32 req_flags; +OM_uint32 time_req; +gss_channel_bindings_t input_chan_bindings; +gss_buffer_t input_token; +gss_OID * actual_mech_type; +gss_buffer_t output_token; +OM_uint32 * ret_flags; +OM_uint32 * time_rec; + +{ + OM_uint32 status, temp_status, temp_minor_status; + gss_union_name_t union_name; + gss_union_cred_t union_cred; + gss_name_t internal_name; + gss_union_ctx_id_t union_ctx_id; + gss_OID mech_type = (gss_OID) req_mech_type; + gss_mechanism mech; + gss_cred_id_t input_cred_handle; + + gss_initialize(); + + if (context_handle == NULL) + return GSS_S_NO_CONTEXT; + + union_name = (gss_union_name_t) target_name; + + /* + * If mech_type is NULL, and the target_name is + * mechanism-specific, then set it to the mech_type of + * target_name. + */ + if ((mech_type == GSS_C_NULL_OID) && union_name->mech_type) + mech_type = union_name->mech_type; + + /* + * obtain the gss mechanism information for the requested + * mechanism. If mech_type is NULL, set it to the resultant + * mechanism + */ + mech = __gss_get_mechanism (mech_type); + if (mech == NULL) + return (GSS_S_BAD_MECH); + + if (mech_type == GSS_C_NULL_OID) + mech_type = &mech->mech_type; + + /* + * If target_name is mechanism_specific, then it must match the + * mech_type that we're about to use. Otherwise, do an import on + * the external_name form of the target name. + */ + if (union_name->mech_type) { + if (!g_OID_equal(union_name->mech_type, mech_type)) + return (GSS_S_BAD_MECH); + internal_name = union_name->mech_name; + } else { + if ((temp_status = __gss_import_internal_name(minor_status, mech_type, + union_name, + &internal_name))) + return (GSS_S_BAD_NAME); + } + + /* + * if context_handle is GSS_C_NO_CONTEXT, allocate a union context + * descriptor to hold the mech type information as well as the + * underlying mechanism context handle. Otherwise, cast the + * value of *context_handle to the union context variable. + */ + + if(*context_handle == GSS_C_NO_CONTEXT) { + union_ctx_id = (gss_union_ctx_id_t) + malloc(sizeof(gss_union_ctx_id_desc)); + + union_ctx_id->mech_type = (gss_OID) + malloc(sizeof(gss_OID_desc)); + + /* copy in the mech type information */ + + union_ctx_id->mech_type->elements = (void *) + malloc(mech_type->length); + + union_ctx_id->mech_type->length = mech_type->length; + memcpy(union_ctx_id->mech_type->elements, mech_type->elements, + mech_type->length); + + /* copy the supplied context handle */ + + union_ctx_id->internal_ctx_id = *context_handle; + } else + union_ctx_id = *context_handle; + + /* + * get the appropriate cred handle from the union cred struct. + * defaults to GSS_C_NO_CREDENTIAL if there is no cred, which will + * use the default credential. + */ + union_cred = (gss_union_cred_t) claimant_cred_handle; + input_cred_handle = __gss_get_mechanism_cred(union_cred, mech_type); + + /* + * now call the approprate underlying mechanism routine + */ + + if (mech->gss_init_sec_context) { + status = mech->gss_init_sec_context( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + input_cred_handle, + &union_ctx_id->internal_ctx_id, + internal_name, + mech_type, + req_flags, + time_req, + input_chan_bindings, + input_token, + actual_mech_type, + output_token, + ret_flags, + time_rec); + + if (*context_handle == GSS_C_NO_CONTEXT) + *context_handle = (gss_ctx_id_t) union_ctx_id; + + } else + status = GSS_S_BAD_BINDINGS; + + if (!union_name->mech_type) { + (void) __gss_release_internal_name(&temp_minor_status, + mech_type, &internal_name); + } + + return(status); +} diff --git a/support/gssapi/g_initialize.c b/support/gssapi/g_initialize.c new file mode 100644 index 0000000..9523d40 --- /dev/null +++ b/support/gssapi/g_initialize.c @@ -0,0 +1,380 @@ +/* #ident "@(#)g_initialize.c 1.2 96/02/06 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This function will initialize the gssapi mechglue library + */ + +#include "config.h" +#include "mglueP.h" +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> + +#ifdef USE_SOLARIS_SHARED_LIBRARIES +#include <dlfcn.h> + +#define MECH_CONF "/etc/mech.conf" +#define MECH_SYM "gss_mech_initialize" + +static void solaris_initialize (void); +#endif /* USE_SOLARIS_SHARED_LIBRARIES */ + +#ifdef __linux__ +#define USE_LINUX_SHARED_LIBRARIES +#endif + +#ifdef USE_LINUX_SHARED_LIBRARIES +#include <dlfcn.h> +#define MECH_CONF "/etc/gssapi_mech.conf" +#define MECH_SYM "gss_mech_initialize" +static void linux_initialize (void); +#endif /* USE_LINUX_SHARED_LIBRARIES */ + +#define g_OID_equal(o1,o2) \ + (((o1)->length == (o2)->length) && \ + (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0)) + +extern gss_mechanism krb5_gss_initialize(); + +static int _gss_initialized = 0; + +static struct gss_config null_mech = { + {0,NULL}}; + +gss_mechanism *__gss_mechs_array = NULL; + +/* + * This function will add a new mechanism to the mechs_array + */ + +static OM_uint32 +add_mechanism (mech, replace) + gss_mechanism mech; + int replace; +{ + gss_mechanism * temp_array; + gss_OID_set mech_names; + OM_uint32 minor_status, major_status; + unsigned int i; + + if (mech == NULL) + return GSS_S_COMPLETE; + + /* initialize the mechs_array if it hasn't already been initialized */ + if (__gss_mechs_array == NULL) { + __gss_mechs_array = (gss_mechanism *) malloc (sizeof(gss_mechanism)); + + if (__gss_mechs_array == NULL) + return ENOMEM; + + __gss_mechs_array[0] = &null_mech; + } + + /* + * Find the length of __gss_mechs_array, and look for an existing + * entry for this OID + */ + for (i=0; __gss_mechs_array[i]->mech_type.length != 0; i++) { + if (!g_OID_equal(&__gss_mechs_array[i]->mech_type, + &mech->mech_type)) + continue; + + /* We found a match. Replace it? */ + if (!replace) + return GSS_S_FAILURE; + + __gss_mechs_array[i] = mech; + return GSS_S_COMPLETE; + } + + /* we didn't find it -- add it to the end of the __gss_mechs_array */ + temp_array = (gss_mechanism *) realloc(__gss_mechs_array, + (i+2)*sizeof(gss_mechanism)); + + if (temp_array == NULL) + return ENOMEM; + + temp_array[i++] = mech; + temp_array[i] = &null_mech; + + __gss_mechs_array = temp_array; + + /* + * OK, now let's register all of the name types this mechanism + * knows how to deal with. + */ + major_status = gss_inquire_names_for_mech(&minor_status, &mech->mech_type, + &mech_names); + if (major_status != GSS_S_COMPLETE) + return (GSS_S_COMPLETE); + for (i=0; i < mech_names->count; i++) { + gss_add_mech_name_type(&minor_status, &mech_names->elements[i], + &mech->mech_type); + } + (void) gss_release_oid_set(&minor_status, &mech_names); + + return GSS_S_COMPLETE; +} + +void gss_initialize () +{ + /* Make sure we've not run already */ + if (_gss_initialized) + return; + _gss_initialized = 1; + +#ifdef USE_SOLARIS_SHARED_LIBRARIES + solaris_initialize(); + +#elif defined(USE_LINUX_SHARED_LIBRARIES) + linux_initialize(); + +#else + { + gss_mechanism mech; + + /* + * Use hard-coded in mechanisms... I need to know what mechanisms + * are supported... As more mechanisms become supported, they + * should be added here, unless shared libraries are used. + */ + + /* Initialize the krb5 mechanism */ + mech = (gss_mechanism)krb5_gss_initialize(); + if (mech) + add_mechanism (mech, 1); + } + +#endif /* USE_SOLARIS_SHARED_LIBRARIES */ + +#if !defined(macintosh) + if (__gss_mechs_array == NULL) { /* this is very bad! */ + fprintf(stderr,"gss_initialize fatal error: no mechanisms loaded!\n"); + exit(-1); + } +#else + /* + * Nothing for now, since this should never happen using static + * mechanism loading. + */ +#endif + + return; +} + +#ifdef USE_SOLARIS_SHARED_LIBRARIES +/* + * read the configuration file to find out what mechanisms to + * load, load them, and then load the mechanism defitions in + * and add the mechanisms + */ +static void solaris_initialize () +{ + char buffer[BUFSIZ], *filename, *symname, *endp; + FILE *conffile; + void *dl; + gss_mechanism (*sym)(void), mech; + + if ((filename = getenv("GSSAPI_MECH_CONF")) == NULL) + filename = MECH_CONF; + + if ((conffile = fopen(filename, "r")) == NULL) { + fprintf(stderr,"fatal error: unable to open %s:" + " errno %d (%s)\n", filename, errno, strerror(errno)); + return; + } + + while (fgets (buffer, BUFSIZ, conffile) != NULL) { + /* ignore lines beginning with # */ + if (*buffer == '#') + continue; + + /* find the first white-space character after the filename */ + for (symname = buffer; *symname && !isspace(*symname); symname++); + + /* Now find the first non-white-space character */ + if (*symname) { + *symname = '\0'; + symname++; + while (*symname && isspace(*symname)) + symname++; + } + + if (! *symname) + symname = MECH_SYM; + else { + /* Find the end of the symname and make sure it is NULL-terminated */ + for (endp = symname; *endp && !isspace(*endp); endp++); + if (*endp) + *endp = '\0'; + } + + if ((dl = dlopen(buffer, RTLD_NOW)) == NULL) { + /* for debugging only */ + fprintf(stderr,"can't open %s: %s\n",buffer, dlerror()); + continue; + } + + if ((sym = (gss_mechanism (*)(void))dlsym(dl, symname)) == NULL) { + dlclose(dl); + continue; + } + + /* Call the symbol to get the mechanism table */ + mech = sym(); + + /* And add the mechanism (or close the shared library) */ + if (mech) + add_mechanism (mech, 1); + else + dlclose(dl); + + } /* while */ + + return; +} +#endif /* USE_SOLARIS_SHARED_LIBRARIES */ + +#ifdef USE_LINUX_SHARED_LIBRARIES +extern gss_mechanism internal_krb5_gss_initialize(void *dl); + +/* + * read the configuration file to find out what mechanisms to + * load, load them, and then load the mechanism defitions in + * and add the mechanisms + */ +static void linux_initialize () +{ + char buffer[BUFSIZ], *filename, *symname, *endp, *err_string; + FILE *conffile; + void *dl; + gss_mechanism (*sym)(void), mech; + + if ((filename = getenv("GSSAPI_MECH_CONF")) == NULL) + filename = MECH_CONF; + + if ((conffile = fopen(filename, "r")) == NULL) { + fprintf(stderr,"fatal error: unable to open %s:" + " errno %d (%s)\n", filename, errno, strerror(errno)); + return; + } + + while (fgets (buffer, BUFSIZ, conffile) != NULL) { + /* ignore lines beginning with # */ + if (*buffer == '#') + continue; + + /* find the first white-space character after the filename */ + for (symname = buffer; *symname && !isspace(*symname); symname++); + + /* Now find the first non-white-space character */ + if (*symname) { + *symname = '\0'; + symname++; + while (*symname && isspace(*symname)) + symname++; + } + + if (! *symname) + symname = MECH_SYM; + else { + /* Find the end of the symname and make sure it is + * NULL-terminated */ + for (endp = symname; *endp && !isspace(*endp); endp++); + if (*endp) + *endp = '\0'; + } + + if ((dl = dlopen(buffer, RTLD_NOW)) == NULL) { + /* for debugging only */ + fprintf(stderr,"can't open %s: %s\n",buffer, dlerror()); + continue; + } + +#if defined(HAVE_KRB5) && defined(HAVE_HEIMDAL) +#error Should not have both HAVE_KRB5 and HAVE_HEIMDAL defined!! +#endif + +#ifdef HAVE_KRB5 + /* Special case for dealing with MIT krb5 mechanism */ + if (strcmp(symname, "mechglue_internal_krb5_init") == 0) { +#ifdef DEBUG + fprintf(stderr, "Using special MIT initialization\n"); +#endif + mech = internal_krb5_gss_initialize(dl); + } + else +#endif + +#ifdef HAVE_HEIMDAL + /* Special case for dealing with heimdal krb5 mechanism */ + if (strcmp(symname, "mechglue_internal_heimdal_init") == 0) { +#ifdef DEBUG + fprintf(stderr, "Using special Heimdal initialization\n"); +#endif + mech = internal_heimdal_gss_initialize(dl); + } + else +#endif + { + if ((sym = (gss_mechanism (*)(void))dlsym(dl, symname)) == NULL) { + if ((err_string = dlerror()) != NULL) { + fprintf(stderr, "%s: searching for symbol '%s' in '%s'\n", + err_string, symname, buffer); + dlclose(dl); + } + continue; + } + + /* Call the symbol to get the mechanism table */ + mech = sym(); + } + + /* And add the mechanism (or close the shared library) */ + if (mech) { +#ifdef DEBUG + fprintf(stderr, "Adding mechanism for library '%s'\n", buffer); +#endif + add_mechanism (mech, 1); + } + else { +#ifdef DEBUG + fprintf(stderr, + "Failed to initialize mechanism for library '%s'\n", + buffer); +#endif + dlclose(dl); + } + + } /* while */ + + return; +} +#endif /* USE_LINUX_SHARED_LIBRARIES */ diff --git a/support/gssapi/g_inq_context.c b/support/gssapi/g_inq_context.c new file mode 100644 index 0000000..60f0e82 --- /dev/null +++ b/support/gssapi/g_inq_context.c @@ -0,0 +1,143 @@ +/* #ident "@(#)g_inquire_context.c 1.2 96/01/18 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_inquire_context + */ + +#include "mglueP.h" +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +/* Last argument new for V2 */ +OM_uint32 KRB5_CALLCONV +gss_inquire_context( + minor_status, + context_handle, + src_name, + targ_name, + lifetime_rec, + mech_type, + ctx_flags, + locally_initiated, + open) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +gss_name_t * src_name; +gss_name_t * targ_name; +OM_uint32 * lifetime_rec; +gss_OID * mech_type; +OM_uint32 * ctx_flags; +int * locally_initiated; +int * open; + + +{ + gss_union_ctx_id_t ctx; + gss_mechanism mech; + OM_uint32 status, temp_minor; + + gss_initialize(); + + /* if the context_handle is Null, return NO_CONTEXT error */ + + if(context_handle == GSS_C_NO_CONTEXT) + return(GSS_S_NO_CONTEXT); + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + + if (!mech || !mech->gss_inquire_context || !mech->gss_display_name) { + return(GSS_S_NO_CONTEXT); + + } + + status = mech->gss_inquire_context( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + ctx->internal_ctx_id, + src_name, + targ_name, + lifetime_rec, + mech_type, + ctx_flags, + locally_initiated, + open); + + if (status != GSS_S_COMPLETE) { + return status; + } + + /* need to convert names */ + + if (src_name) { + status = __gss_convert_name_to_union_name(minor_status, mech, + *src_name, src_name); + + if (status != GSS_S_COMPLETE) { +#ifdef USE_MECH_CONTEXT + (void) mech->gss_release_name(mech->context, +#else + (void) mech->gss_release_name( +#endif + &temp_minor, src_name); +#ifdef USE_MECH_CONTEXT + (void) mech->gss_release_name(mech->context, +#else + (void) mech->gss_release_name( +#endif + &temp_minor, targ_name); + if (mech_type) { + mech_gss_release_oid(&temp_minor, mech_type, + mech); + } + return (GSS_S_FAILURE); + } + + } + + if (targ_name) { + status = __gss_convert_name_to_union_name(minor_status, mech, + *targ_name, targ_name); + + if (status != GSS_S_COMPLETE) { + if (mech_type) { + mech_gss_release_oid(&temp_minor, mech_type, mech); + } + return (GSS_S_FAILURE); + } + } + + return(GSS_S_COMPLETE); +} + diff --git a/support/gssapi/g_inq_cred.c b/support/gssapi/g_inq_cred.c new file mode 100644 index 0000000..6671f70 --- /dev/null +++ b/support/gssapi/g_inq_cred.c @@ -0,0 +1,199 @@ +/* #ident "@(#)gss_inquire_cred.c 1.9 95/08/02 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_inquire_cred + */ + +#include "mglueP.h" +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> +#include <time.h> + +OM_uint32 KRB5_CALLCONV +gss_inquire_cred(minor_status, + cred_handle, + name, + lifetime, + cred_usage, + mechanisms) + +OM_uint32 * minor_status; +gss_cred_id_t cred_handle; +gss_name_t * name; +OM_uint32 * lifetime; +int * cred_usage; +gss_OID_set * mechanisms; + +{ + OM_uint32 status, elapsed_time, temp_minor_status; + gss_union_cred_t union_cred; + gss_mechanism mech; + gss_name_t internal_name; + int i; + + gss_initialize(); + + if (cred_handle == GSS_C_NO_CREDENTIAL) { + /* + * No credential was supplied. This means we can't get a mechanism + * pointer to call the mechanism specific gss_inquire_cred. + * So, call get_mechanism with an arguement of GSS_C_NULL_OID. + * get_mechanism will return the first mechanism in the mech + * array, which becomes the default mechanism. + */ + + if ((mech = __gss_get_mechanism(GSS_C_NULL_OID)) == NULL) + return(GSS_S_NO_CRED); + + if (!mech->gss_inquire_cred) + return (GSS_S_FAILURE); + +#ifdef USE_MECH_CONTEXT + status = mech->gss_inquire_cred(mech->context, minor_status, +#else + status = mech->gss_inquire_cred(minor_status, +#endif + GSS_C_NO_CREDENTIAL, + name ? &internal_name : NULL, + lifetime, cred_usage, mechanisms); + + if (status != GSS_S_COMPLETE) + return(status); + + if (name) { + /* + * Convert internal_name into a union_name equivalent. + */ + status = __gss_convert_name_to_union_name(&temp_minor_status, + mech, internal_name, + name); + if (status != GSS_S_COMPLETE) { + if (minor_status) + *minor_status = temp_minor_status; + __gss_release_internal_name(&temp_minor_status, + &mech->mech_type, &internal_name); + return (status); + } + } + return(GSS_S_COMPLETE); + } + + /* get the cred_handle cast as a union_credentials structure */ + + union_cred = (gss_union_cred_t) cred_handle; + + /* + * get the information out of the union_cred structure that was + * placed there during gss_acquire_cred. + */ + + if(cred_usage != NULL) + *cred_usage = union_cred->auxinfo.cred_usage; + + if(lifetime != NULL) { + elapsed_time = time(0) - union_cred->auxinfo.creation_time; + *lifetime = union_cred->auxinfo.time_rec < elapsed_time ? 0 : + union_cred->auxinfo.time_rec - elapsed_time; + } + + /* + * if name is non_null, + * call gss_import_name(), giving it the printable name held within + * union_cred in order to get an internal name to pass back to the + * caller. If this call fails, return failure to our caller. + */ + + if(name != NULL) + if(gss_import_name(&temp_minor_status, + &union_cred->auxinfo.name, + union_cred->auxinfo.name_type, + name) != GSS_S_COMPLETE) + return(GSS_S_DEFECTIVE_CREDENTIAL); + + /* + * copy the mechanism set in union_cred into an OID set and return in + * the mechanisms parameter. + */ + + if(mechanisms != NULL) { + + *mechanisms = (gss_OID_set) malloc(sizeof(gss_OID_set_desc)); + + (*mechanisms)->count = union_cred->count; + (*mechanisms)->elements = + (gss_OID) malloc(sizeof(gss_OID_desc) * + union_cred->count); + + for(i=0; i < union_cred->count; i++) { + (*mechanisms)->elements[i].length = + union_cred->mechs_array[i].length; + (*mechanisms)->elements[i].elements = (void *) + malloc(union_cred->mechs_array[i].length); + memcpy((*mechanisms)->elements[i].elements, + union_cred->mechs_array[i].elements, + union_cred->mechs_array[i].length); + } + } + + return(GSS_S_COMPLETE); +} + +OM_uint32 KRB5_CALLCONV +gss_inquire_cred_by_mech(minor_status, cred_handle, mech_type, name, + initiator_lifetime, acceptor_lifetime, cred_usage) + OM_uint32 *minor_status; + gss_cred_id_t cred_handle; + gss_OID mech_type; + gss_name_t *name; + OM_uint32 *initiator_lifetime; + OM_uint32 *acceptor_lifetime; + gss_cred_usage_t *cred_usage; +{ + gss_union_cred_t union_cred; + gss_cred_id_t mech_cred; + gss_mechanism mech; + + mech = __gss_get_mechanism (mech_type); + if (!mech) + return (GSS_S_BAD_MECH); + if (!mech->gss_inquire_cred_by_mech) + return (GSS_S_BAD_BINDINGS); + + union_cred = (gss_union_cred_t) cred_handle; + mech_cred = __gss_get_mechanism_cred(union_cred, mech_type); + +#ifdef USE_MECH_CONTEXT + return (mech->gss_inquire_cred_by_mech(mech->context, minor_status, +#else + return (mech->gss_inquire_cred_by_mech(minor_status, +#endif + mech_cred, mech_type, + name, initiator_lifetime, + acceptor_lifetime, cred_usage)); +} + diff --git a/support/gssapi/g_inq_names.c b/support/gssapi/g_inq_names.c new file mode 100644 index 0000000..cfcb27d --- /dev/null +++ b/support/gssapi/g_inq_names.c @@ -0,0 +1,69 @@ +/* #ident "@(#)g_inquire_names.c 1.1 95/12/19 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_inquire_context + */ + +#include "mglueP.h" + +/* Last argument new for V2 */ +OM_uint32 KRB5_CALLCONV +gss_inquire_names_for_mech(minor_status, mechanism, name_types) + +OM_uint32 * minor_status; +gss_OID mechanism; +gss_OID_set * name_types; + +{ + OM_uint32 status; + gss_mechanism mech; + + gss_initialize(); + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + mech = __gss_get_mechanism (mechanism); + + if (mech) { + + if (mech->gss_inquire_names_for_mech) + status = mech->gss_inquire_names_for_mech( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + mechanism, + name_types); + else + status = GSS_S_BAD_BINDINGS; + + return(status); + } + + return(GSS_S_NO_CONTEXT); +} diff --git a/support/gssapi/g_mechname.c b/support/gssapi/g_mechname.c new file mode 100644 index 0000000..4f0a013 --- /dev/null +++ b/support/gssapi/g_mechname.c @@ -0,0 +1,116 @@ +/* + * g_mechname.c --- registry of mechanism-specific name types + * + * This file contains a registry of mechanism-specific name types. It + * is used to determine which name types not should be lazy evaluated, + * but rather evaluated on the spot. + */ + +#include "mglueP.h" +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +#include <stdio.h> +#include <string.h> +#include <errno.h> + +#define g_OID_equal(o1,o2) \ + (((o1)->length == (o2)->length) && \ + (memcmp((o1)->elements,(o2)->elements,(int) (o1)->length) == 0)) + +static gss_mech_spec_name name_list = NULL; + +/* + * generic searching helper function. + */ +static gss_mech_spec_name search_mech_spec(name_type) + gss_OID name_type; +{ + gss_mech_spec_name p; + + for (p = name_list; p; p = p->next) { + if (g_OID_equal(name_type, p->name_type)) + return p; + } + return NULL; +} + +/* + * Given a name_type, if it is specific to a mechanism, return the + * mechanism OID. Otherwise, return NULL. + */ +gss_OID gss_find_mechanism_from_name_type(name_type) + gss_OID name_type; +{ + gss_mech_spec_name p; + + p = search_mech_spec(name_type); + if (!p) + return NULL; + return p->mech; +} + +/* + * This function adds a (name_type, mechanism) pair to the + * mechanism-specific name type registry. If an entry for the + * name_type already exists, then zero out the mechanism entry. + * Otherwise, enter the pair into the registry. + */ +OM_uint32 +gss_add_mech_name_type(minor_status, name_type, mech) + OM_uint32 *minor_status; + gss_OID name_type; + gss_OID mech; +{ + OM_uint32 major_status, tmp; + gss_mech_spec_name p; + + p = search_mech_spec(name_type); + if (p) { + /* + * We found an entry for this name type; mark it as not being + * a mechanism-specific name type. + */ + if (p->mech) { + if (!g_OID_equal(mech, p->mech)) { + generic_gss_release_oid(minor_status, &p->mech); + p->mech = 0; + } + } + return GSS_S_COMPLETE; + } + p = malloc(sizeof(gss_mech_spec_name_desc)); + if (!p) { + *minor_status = ENOMEM; + goto allocation_failure; + } + p->name_type = 0; + p->mech = 0; + + major_status = generic_gss_copy_oid(minor_status, name_type, + &p->name_type); + if (major_status) + goto allocation_failure; + major_status = generic_gss_copy_oid(minor_status, mech, + &p->mech); + if (major_status) + goto allocation_failure; + + p->next = name_list; + p->prev = 0; + name_list = p; + + return GSS_S_COMPLETE; + +allocation_failure: + if (p) { + if (p->mech) + generic_gss_release_oid(&tmp, &p->mech); + if (p->name_type) + generic_gss_release_oid(&tmp, &p->name_type); + free(p); + } + return GSS_S_FAILURE; +} + diff --git a/support/gssapi/g_mit_krb5_mech.c b/support/gssapi/g_mit_krb5_mech.c new file mode 100644 index 0000000..1caa8d2 --- /dev/null +++ b/support/gssapi/g_mit_krb5_mech.c @@ -0,0 +1,297 @@ +/* + * g_mit_krb5_mech.c + * + * Copyright (c) 2004 The Regents of the University of Michigan. + * All rights reserved. + * + * Kevin Coffman <kwc@umich.edu> + * + * 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 University 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 ``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 REGENTS 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 "config.h" +#include <stdio.h> +#include <dlfcn.h> +#include "mglueP.h" + +/* + * Table of function names that we need to locate within a mechanism's + * shared library if it does not support the xxx_gss_initialize function. + */ +static char *glue_func_names[] = { + "gss_acquire_cred", + "gss_release_cred", + "gss_init_sec_context", + "gss_accept_sec_context", + "gss_process_context_token", + "gss_delete_sec_context", + "gss_context_time", + "gss_sign", + "gss_verify", + "gss_seal", + "gss_unseal", + "gss_display_status", + "gss_indicate_mechs", + "gss_compare_name", + "gss_display_name", + "gss_import_name", + "gss_release_name", + "gss_inquire_cred", + "gss_add_cred", + "gss_export_sec_context", + "gss_import_sec_context", + "gss_inquire_cred_by_mech", + "gss_inquire_names_for_mech", + "gss_inquire_context", + "gss_internal_release_oid", + "gss_wrap_size_limit", + "pname_to_uid", + "gss_duplicate_name", + "gss_set_allowable_enctypes", + "gss_verify_mic", + NULL +}; + +#ifdef HAVE_KRB5 +/* + * The MIT code does not support the krb5_gss_initialize function, so + * we need to locate the functions within the gssapi_krb5.so library + * and fill in this structure. + */ +static struct gss_config mit_krb5_mechanism = { + {9, "\052\206\110\206\367\022\001\002\002"}, + NULL, /* mechanism context -- we don't currently use this */ + NULL, /* gss_acquire_cred */ + NULL, /* gss_release_cred */ + NULL, /* gss_init_sec_context */ + NULL, /* gss_accept_sec_context */ + NULL, /* gss_process_context_token */ + NULL, /* gss_delete_sec_context */ + NULL, /* gss_context_time */ + NULL, /* gss_sign */ + NULL, /* gss_verify */ + NULL, /* gss_seal */ + NULL, /* gss_unseal */ + NULL, /* gss_display_status */ + NULL, /* gss_indicate_mechs */ + NULL, /* gss_compare_name */ + NULL, /* gss_display_name */ + NULL, /* gss_import_name */ + NULL, /* gss_release_name */ + NULL, /* gss_inquire_cred */ + NULL, /* gss_add_cred */ + NULL, /* gss_export_sec_context */ + NULL, /* gss_import_sec_context */ + NULL, /* gss_inquire_cred_by_mech */ + NULL, /* gss_inquire_names_for_mech */ + NULL, /* gss_inquire_context */ + NULL, /* gss_internal_release_oid */ + NULL, /* gss_wrap_size_limit */ + NULL, /* pname_to_uid */ + NULL, /* gss_duplicate_name */ + NULL, /* gss_set_allowable_enctypes */ + NULL, /* gss_verify_mic */ +}; +#endif + +#ifdef HAVE_HEIMDAL +/* + * The heimdal code does not support the krb5_gss_initialize function, so + * we need to locate the functions within the libgssapi.so library + * and fill in this structure. + */ +static struct gss_config heimdal_krb5_mechanism = { + {9, "\052\206\110\206\367\022\001\002\002"}, + NULL, /* mechanism context -- we don't currently use this */ + NULL, /* gss_acquire_cred */ + NULL, /* gss_release_cred */ + NULL, /* gss_init_sec_context */ + NULL, /* gss_accept_sec_context */ + NULL, /* gss_process_context_token */ + NULL, /* gss_delete_sec_context */ + NULL, /* gss_context_time */ + NULL, /* gss_sign */ + NULL, /* gss_verify */ + NULL, /* gss_seal */ + NULL, /* gss_unseal */ + NULL, /* gss_display_status */ + NULL, /* gss_indicate_mechs */ + NULL, /* gss_compare_name */ + NULL, /* gss_display_name */ + NULL, /* gss_import_name */ + NULL, /* gss_release_name */ + NULL, /* gss_inquire_cred */ + NULL, /* gss_add_cred */ + NULL, /* gss_export_sec_context */ + NULL, /* gss_import_sec_context */ + NULL, /* gss_inquire_cred_by_mech */ + NULL, /* gss_inquire_names_for_mech */ + NULL, /* gss_inquire_context */ + NULL, /* gss_internal_release_oid */ + NULL, /* gss_wrap_size_limit */ + NULL, /* pname_to_uid */ + NULL, /* gss_duplicate_name */ + NULL, /* gss_set_allowable_enctypes */ + NULL, /* gss_verify_mic */ +}; +#endif + + +/* + * Given a handle to a dynamic library (dl) and a symbol + * name (symname), return its address. Returns -1 if the + * symbol cannot be located. (Note that the value of the + * symbol could be NULL, which is valid.) + */ +void * +locate_symbol(void *dl, char *symname, char *prefix) +{ + void *sym; + const char *err_string; + char fullname[256]; + + snprintf(fullname, sizeof(fullname), "%s%s", prefix, symname); + + if ((sym = dlsym(dl, fullname)) == NULL) { + if ((sym = dlsym(dl, symname)) == NULL) { + if ((err_string = dlerror()) != NULL) { + return (void *)-1; + } + else { + return NULL; + } + } + } + return sym; +} + +#ifdef HAVE_KRB5 +/* + * Locate all the symbols in the MIT gssapi library and + * fill in the gss_config (gss_mechanism) structure. + */ +gss_mechanism +internal_krb5_gss_initialize(void *dl) +{ + char *fname; + void *p; + void **fptr; + int i; + static int mit_krb5_initialized = 0; + + if (mit_krb5_initialized) + return (&mit_krb5_mechanism); + + fptr = (void *) &mit_krb5_mechanism.gss_acquire_cred; + + + for (i = 0, fname = glue_func_names[i]; + fname; + i++, fname = glue_func_names[i]) { + if ((p = locate_symbol(dl, fname, "krb5_")) != (void *)-1) { + *fptr++ = p; + } + else { + *fptr++ = NULL; + } + } + if (mit_krb5_mechanism.gss_internal_release_oid == NULL || + mit_krb5_mechanism.gss_internal_release_oid == (void *) -1) { + fprintf(stderr, "WARNING: unable to locate function " + "krb5_gss_internal_release_oid in krb5 mechanism library: " + "there will be problems if multiple mechanisms are used!\n"); + p = locate_symbol(dl, "krb5_gss_release_oid", ""); + if (p == NULL || p == (void *) -1) { + fprintf(stderr, "ERROR: Unable to locate function " + "krb5_gss_internal_release_oid or " + "krb5_gss_release_oid in krb5 mechanism library\n"); + return NULL; + } + } +#ifdef HAVE_SET_ALLOWABLE_ENCTYPES + /* + * Special case for set_allowable_enctypes which has a different + * name format than the rest of the gss routines :-/ + */ + if ((p = locate_symbol(dl, "gss_krb5_set_allowable_enctypes", "")) + != (void *)-1) { + mit_krb5_mechanism.gss_set_allowable_enctypes = p; + } +#endif + mit_krb5_initialized = 1; + return (&mit_krb5_mechanism); +} +#endif + +#ifdef HAVE_HEIMDAL +/* + * Locate all the symbols in the MIT gssapi library and + * fill in the gss_config (gss_mechanism) structure. + */ +gss_mechanism +internal_heimdal_gss_initialize(void *dl) +{ + char *fname; + void *p; + void **fptr; + int i; + static int heimdal_krb5_initialized = 0; + + if (heimdal_krb5_initialized) + return (&heimdal_krb5_mechanism); + + fptr = (void *) &heimdal_krb5_mechanism.gss_acquire_cred; + + + for (i = 0, fname = glue_func_names[i]; + fname; + i++, fname = glue_func_names[i]) { + if ((p = locate_symbol(dl, fname, "")) != (void *)-1) { + *fptr++ = p; + } + else { +printf("Failed to locate function '%s' !!!\n", fname); + *fptr++ = NULL; + } + } + if (heimdal_krb5_mechanism.gss_internal_release_oid == NULL || + heimdal_krb5_mechanism.gss_internal_release_oid == (void *) -1) { + fprintf(stderr, "WARNING: unable to locate function " + "gss_internal_release_oid in krb5 mechanism library: " + "there will be problems if multiple mechanisms are used!\n"); + p = locate_symbol(dl, "krb5_gss_release_oid", ""); + if (p == NULL || p == (void *) -1) { + fprintf(stderr, "ERROR: Unable to locate function " + "gss_internal_release_oid or " + "gss_release_oid in krb5 mechanism library\n"); + return NULL; + } + } + heimdal_krb5_initialized = 1; + return (&heimdal_krb5_mechanism); +} +#endif diff --git a/support/gssapi/g_oid_ops.c b/support/gssapi/g_oid_ops.c new file mode 100644 index 0000000..da0d61a --- /dev/null +++ b/support/gssapi/g_oid_ops.c @@ -0,0 +1,121 @@ +/* + * lib/gssapi/mechglue/g_oid_ops.c + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +/* + * oid_ops.c - GSS-API V2 interfaces to manipulate OIDs + */ + +#include <stdio.h> +#include "mglueP.h" +/* should include to get protos #include "../generic/gssapiP_generic.h" */ + +extern gss_mechanism *__gss_mechs_array; + +OM_uint32 KRB5_CALLCONV +gss_release_oid(minor_status, oid) + OM_uint32 *minor_status; + gss_OID *oid; +{ + int i; + OM_uint32 major_status; + + /* first call the gss_internal_release_oid for each mechanism + * until one returns success. gss_internal_release_oid will only return + * success when the OID was recognized as an internal mechanism OID. + * if no mechanisms recognize the OID, then call the generic version. + */ + + for(i=0; __gss_mechs_array[i]->mech_type.length !=0; i++) { + if (__gss_mechs_array[i]->gss_internal_release_oid) { + major_status = __gss_mechs_array[i]->gss_internal_release_oid( +#ifdef USE_MECH_CONTEXT + __gss_mechs_array[i]->context, +#endif + minor_status, + oid); +#ifdef DEBUG + fprintf(stderr, "gss_release_oid (glue): mech returned 0x%08x\n", + major_status); +#endif + if (major_status == GSS_S_COMPLETE) { + return (GSS_S_COMPLETE); + } + } + } + +#ifdef DEBUG + fprintf(stderr, "gss_release_oid (glue): calling " + "generic_gss_release_oid with oid %p (*oid %p)\n", oid, *oid); +#endif + return generic_gss_release_oid(minor_status, oid); +} + +OM_uint32 KRB5_CALLCONV +gss_create_empty_oid_set(minor_status, oid_set) + OM_uint32 *minor_status; + gss_OID_set *oid_set; +{ + return generic_gss_create_empty_oid_set(minor_status, oid_set); +} + +OM_uint32 KRB5_CALLCONV +gss_add_oid_set_member(minor_status, member_oid, oid_set) + OM_uint32 *minor_status; + gss_OID member_oid; + gss_OID_set *oid_set; +{ + return generic_gss_add_oid_set_member(minor_status, member_oid, oid_set); +} + +OM_uint32 KRB5_CALLCONV +gss_test_oid_set_member(minor_status, member, set, present) + OM_uint32 *minor_status; + gss_OID member; + gss_OID_set set; + int *present; +{ + return generic_gss_test_oid_set_member(minor_status, member, set, present); +} + +OM_uint32 KRB5_CALLCONV +gss_oid_to_str(minor_status, oid, oid_str) + OM_uint32 *minor_status; + gss_OID oid; + gss_buffer_t oid_str; +{ + return generic_gss_oid_to_str(minor_status, oid, oid_str); +} + +OM_uint32 KRB5_CALLCONV +gss_str_to_oid(minor_status, oid_str, oid) + OM_uint32 *minor_status; + gss_buffer_t oid_str; + gss_OID *oid; +{ + return generic_gss_str_to_oid(minor_status, oid_str, oid); +} + diff --git a/support/gssapi/g_process_context.c b/support/gssapi/g_process_context.c new file mode 100644 index 0000000..322d597 --- /dev/null +++ b/support/gssapi/g_process_context.c @@ -0,0 +1,75 @@ +/* #ident "@(#)gss_process_context.c 1.9 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine gss_process_context + */ + +#include "mglueP.h" + +OM_uint32 KRB5_CALLCONV +gss_process_context_token (minor_status, + context_handle, + token_buffer) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +gss_buffer_t token_buffer; + +{ + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + gss_initialize(); + + if (context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + + if (mech) { + + if (mech->gss_process_context_token) + status = mech->gss_process_context_token( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + ctx->internal_ctx_id, + token_buffer); + else + status = GSS_S_BAD_BINDINGS; + + return(status); + } + + return(GSS_S_NO_CONTEXT); +} diff --git a/support/gssapi/g_rel_buffer.c b/support/gssapi/g_rel_buffer.c new file mode 100644 index 0000000..c1104fd --- /dev/null +++ b/support/gssapi/g_rel_buffer.c @@ -0,0 +1,58 @@ +/* #ident "@(#)g_rel_buffer.c 1.2 96/02/06 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_release_buffer + */ + +#include "mglueP.h" +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +OM_uint32 KRB5_CALLCONV +gss_release_buffer (minor_status, + buffer) + +OM_uint32 * minor_status; +gss_buffer_t buffer; +{ + if (minor_status) + *minor_status = 0; + + /* if buffer is NULL, return */ + + if(buffer == GSS_C_NO_BUFFER) + return(GSS_S_COMPLETE); + + if ((buffer->length) && + (buffer->value)) { + free(buffer->value); + buffer->length = 0; + buffer->value = NULL; + } + + return (GSS_S_COMPLETE); +} diff --git a/support/gssapi/g_rel_cred.c b/support/gssapi/g_rel_cred.c new file mode 100644 index 0000000..27a6d82 --- /dev/null +++ b/support/gssapi/g_rel_cred.c @@ -0,0 +1,104 @@ +/* #ident "@(#)gss_release_cred.c 1.15 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_release_cred + */ + +#include "mglueP.h" +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +OM_uint32 KRB5_CALLCONV +gss_release_cred(minor_status, + cred_handle) + +OM_uint32 * minor_status; +gss_cred_id_t * cred_handle; + +{ + OM_uint32 status, temp_status; + int j; + gss_union_cred_t union_cred; + gss_mechanism mech; + + gss_initialize(); + + if (minor_status) + *minor_status = 0; + + /* if the cred_handle is null, return a NO_CRED error */ + + if (cred_handle == GSS_C_NO_CREDENTIAL) + return(GSS_S_NO_CRED); + + /* + * Loop through the union_cred struct, selecting the approprate + * underlying mechanism routine and calling it. At the end, + * release all of the storage taken by the union_cred struct. + */ + + union_cred = (gss_union_cred_t) *cred_handle; + *cred_handle = NULL; + + if (union_cred == NULL) + return GSS_S_NO_CRED; + + status = GSS_S_COMPLETE; + + for(j=0; j < union_cred->count; j++) { + + mech = __gss_get_mechanism (&union_cred->mechs_array[j]); + + if (union_cred->mechs_array[j].elements) + free(union_cred->mechs_array[j].elements); + if (mech) { + if (mech->gss_release_cred) { + temp_status = mech->gss_release_cred +#ifdef USE_MECH_CONTEXT + (mech->context, +#else + ( +#endif + minor_status, + &union_cred->cred_array[j]); + + if (temp_status != GSS_S_COMPLETE) + status = GSS_S_NO_CRED; + + } else + status = GSS_S_NO_CRED; + } else + status = GSS_S_NO_CRED; + } + + gss_release_buffer(minor_status, &union_cred->auxinfo.name); + free(union_cred->cred_array); + free(union_cred->mechs_array); + free(union_cred); + + return(status); +} diff --git a/support/gssapi/g_rel_name.c b/support/gssapi/g_rel_name.c new file mode 100644 index 0000000..ec5593a --- /dev/null +++ b/support/gssapi/g_rel_name.c @@ -0,0 +1,92 @@ +/* #ident "@(#)gss_release_name.c 1.2 95/05/09 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_release_name + */ + +#include "mglueP.h" +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> + +OM_uint32 KRB5_CALLCONV +gss_release_name (minor_status, + input_name) + +OM_uint32 * minor_status; +gss_name_t * input_name; + +{ + gss_union_name_t union_name; + + /* if input_name is NULL, return error */ + +#ifdef DEBUG + fprintf(stderr, "gss_release_name: input_name %p *input_name %p\n", + input_name, *input_name); +#endif + if (input_name == 0) + return(GSS_S_BAD_NAME); + + /* + * free up the space for the external_name and then + * free the union_name descriptor + */ + + union_name = (gss_union_name_t) *input_name; + *input_name = 0; + *minor_status = 0; + + if (union_name == GSS_C_NO_NAME) + return GSS_S_BAD_NAME; + + if (union_name->name_type != GSS_C_NO_OID) + mech_gss_release_oid(minor_status, &union_name->name_type, + union_name->gss_mech); + + free(union_name->external_name->value); + free(union_name->external_name); + + if (union_name->mech_type) { +#ifdef DEBUG + fprintf(stderr, + "gss_release_name: releasing internal name %p and oid %p\n", + union_name->mech_name, union_name->mech_type); +#endif + __gss_release_internal_name(minor_status, union_name->mech_type, + &union_name->mech_name); + mech_gss_release_oid(minor_status, &union_name->mech_type, + union_name->gss_mech); + } + +#ifdef DEBUG + fprintf(stderr, "gss_release_name: freeing union_name %p\n", union_name); +#endif + free(union_name); + + return(GSS_S_COMPLETE); +} diff --git a/support/gssapi/g_rel_oid_set.c b/support/gssapi/g_rel_oid_set.c new file mode 100644 index 0000000..90430c1 --- /dev/null +++ b/support/gssapi/g_rel_oid_set.c @@ -0,0 +1,63 @@ +/* #ident "@(#)gss_release_oid_set.c 1.12 95/08/23 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_release_oid_set + */ + +#include "mglueP.h" +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +OM_uint32 KRB5_CALLCONV +gss_release_oid_set (minor_status, + set) + +OM_uint32 * minor_status; +gss_OID_set * set; +{ + size_t index; + gss_OID oid; + if (minor_status) + *minor_status = 0; + + if (set ==NULL) + return GSS_S_COMPLETE; + + if (*set == GSS_C_NULL_OID_SET) + return(GSS_S_COMPLETE); + + for (index=0; index<(*set)->count; index++) { + oid = &(*set)->elements[index]; + free(oid->elements); + } + free((*set)->elements); + free(*set); + + *set = GSS_C_NULL_OID_SET; + + return(GSS_S_COMPLETE); +} diff --git a/support/gssapi/g_seal.c b/support/gssapi/g_seal.c new file mode 100644 index 0000000..ebc8f2e --- /dev/null +++ b/support/gssapi/g_seal.c @@ -0,0 +1,155 @@ +/* #ident "@(#)gss_seal.c 1.10 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_seal + */ + +#include "mglueP.h" + +OM_uint32 KRB5_CALLCONV +gss_seal (minor_status, + context_handle, + conf_req_flag, + qop_req, + input_message_buffer, + conf_state, + output_message_buffer) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +int conf_req_flag; +int qop_req; +gss_buffer_t input_message_buffer; +int * conf_state; +gss_buffer_t output_message_buffer; + +{ + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + gss_initialize(); + + if (context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + + if (mech) { + if (mech->gss_seal) + status = mech->gss_seal( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + ctx->internal_ctx_id, + conf_req_flag, + qop_req, + input_message_buffer, + conf_state, + output_message_buffer); + else + status = GSS_S_BAD_BINDINGS; + + return(status); + } + + return(GSS_S_NO_CONTEXT); +} + +OM_uint32 KRB5_CALLCONV +gss_wrap (minor_status, + context_handle, + conf_req_flag, + qop_req, + input_message_buffer, + conf_state, + output_message_buffer) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +int conf_req_flag; +gss_qop_t qop_req; +gss_buffer_t input_message_buffer; +int * conf_state; +gss_buffer_t output_message_buffer; + +{ + return gss_seal(minor_status, context_handle, conf_req_flag, + (int) qop_req, input_message_buffer, conf_state, + output_message_buffer); +} + +/* + * New for V2 + */ +OM_uint32 KRB5_CALLCONV +gss_wrap_size_limit(minor_status, context_handle, conf_req_flag, + qop_req, req_output_size, max_input_size) + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + int conf_req_flag; + gss_qop_t qop_req; + OM_uint32 req_output_size; + OM_uint32 *max_input_size; +{ + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + gss_initialize(); + + if (context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + + if (!mech) + return (GSS_S_NO_CONTEXT); + + if (!mech->gss_wrap_size_limit) + return (GSS_S_BAD_BINDINGS); + +#ifdef USE_MECH_CONTEXT + status = mech->gss_wrap_size_limit(mech->context, minor_status, +#else + status = mech->gss_wrap_size_limit(minor_status, +#endif + context_handle, conf_req_flag, qop_req, + req_output_size, max_input_size); + return(status); +} diff --git a/support/gssapi/g_set_allowable_enctypes.c b/support/gssapi/g_set_allowable_enctypes.c new file mode 100644 index 0000000..27c52a4 --- /dev/null +++ b/support/gssapi/g_set_allowable_enctypes.c @@ -0,0 +1,81 @@ +/* #ident "@(#)gss_set_allowable_enctype.c 1.9 95/08/02 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_set_allowable_enctypes + */ + +#include "mglueP.h" +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <string.h> + +OM_uint32 KRB5_CALLCONV +gss_set_allowable_enctypes(minor_status, + cred_handle, + mech_type, + num_ktypes, + ktypes) + +OM_uint32 * minor_status; +gss_cred_id_t cred_handle; +gss_OID mech_type; +OM_uint32 num_ktypes; +void * ktypes; + +{ + gss_union_cred_t union_cred; + gss_mechanism mech; + gss_cred_id_t mech_cred; + + gss_initialize(); + + if (cred_handle == GSS_C_NO_CREDENTIAL) + return (GSS_S_NO_CRED); + + if ((mech = __gss_get_mechanism(mech_type)) == NULL) + return (GSS_S_BAD_MECH); + + if (!mech->gss_set_allowable_enctypes) + return (GSS_S_FAILURE); + + /* get the mechanism-specific cred handle */ + + union_cred = (gss_union_cred_t) cred_handle; + mech_cred = __gss_get_mechanism_cred(union_cred, mech_type); + + if (mech_cred == GSS_C_NO_CREDENTIAL) + return (GSS_S_NO_CRED); + + /* Call the mechanism-specific routine */ +#ifdef USE_MECH_CONTEXT + return (mech->gss_set_allowable_enctypes(mech->context, minor_status, +#else + return (mech->gss_set_allowable_enctypes(minor_status, +#endif + mech_cred, num_ktypes, ktypes)); +} + diff --git a/support/gssapi/g_sign.c b/support/gssapi/g_sign.c new file mode 100644 index 0000000..fe3398c --- /dev/null +++ b/support/gssapi/g_sign.c @@ -0,0 +1,99 @@ +/* #ident "@(#)gss_sign.c 1.10 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine gss_sign + */ + +#include "mglueP.h" + +OM_uint32 KRB5_CALLCONV +gss_sign (minor_status, + context_handle, + qop_req, + message_buffer, + msg_token) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +int qop_req; +gss_buffer_t message_buffer; +gss_buffer_t msg_token; + +{ + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + gss_initialize(); + + if (context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + + if (mech) { + if (mech->gss_sign) + status = mech->gss_sign( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + ctx->internal_ctx_id, + qop_req, + message_buffer, + msg_token); + else + status = GSS_S_BAD_BINDINGS; + + return(status); + } + + return(GSS_S_NO_CONTEXT); +} + +OM_uint32 KRB5_CALLCONV +gss_get_mic (minor_status, + context_handle, + qop_req, + message_buffer, + msg_token) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +gss_qop_t qop_req; +gss_buffer_t message_buffer; +gss_buffer_t msg_token; + +{ + return (gss_sign(minor_status, context_handle, (int) qop_req, + message_buffer, msg_token)); +} + diff --git a/support/gssapi/g_unseal.c b/support/gssapi/g_unseal.c new file mode 100644 index 0000000..c274e38 --- /dev/null +++ b/support/gssapi/g_unseal.c @@ -0,0 +1,105 @@ +/* #ident "@(#)gss_unseal.c 1.10 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine gss_unseal + */ + +#include "mglueP.h" + +OM_uint32 KRB5_CALLCONV +gss_unseal (minor_status, + context_handle, + input_message_buffer, + output_message_buffer, + conf_state, + qop_state) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +gss_buffer_t input_message_buffer; +gss_buffer_t output_message_buffer; +int * conf_state; +int * qop_state; + +{ + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + gss_initialize(); + + if (context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + + if (mech) { + if (mech->gss_unseal) + status = mech->gss_unseal( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + ctx->internal_ctx_id, + input_message_buffer, + output_message_buffer, + conf_state, + qop_state); + else + status = GSS_S_BAD_BINDINGS; + + return(status); + } + + return(GSS_S_NO_CONTEXT); +} + +OM_uint32 KRB5_CALLCONV +gss_unwrap (minor_status, + context_handle, + input_message_buffer, + output_message_buffer, + conf_state, + qop_state) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +gss_buffer_t input_message_buffer; +gss_buffer_t output_message_buffer; +int * conf_state; +gss_qop_t * qop_state; + +{ + return (gss_unseal(minor_status, context_handle, + input_message_buffer, + output_message_buffer, + conf_state, (int *) qop_state)); +} diff --git a/support/gssapi/g_verify.c b/support/gssapi/g_verify.c new file mode 100644 index 0000000..404a6ee --- /dev/null +++ b/support/gssapi/g_verify.c @@ -0,0 +1,137 @@ +/* #ident "@(#)gss_verify.c 1.9 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routine for gss_verify + */ + +#include "mglueP.h" + +OM_uint32 KRB5_CALLCONV +gss_verify (minor_status, + context_handle, + message_buffer, + token_buffer, + qop_state) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +gss_buffer_t message_buffer; +gss_buffer_t token_buffer; +int * qop_state; + +{ + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + gss_initialize(); + + if (context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + + if (mech) { + if (mech->gss_verify) + status = mech->gss_verify( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + ctx->internal_ctx_id, + message_buffer, + token_buffer, + qop_state); + else + status = GSS_S_BAD_BINDINGS; + + return(status); + } + + return(GSS_S_NO_CONTEXT); +} + +OM_uint32 KRB5_CALLCONV +gss_verify_mic (minor_status, + context_handle, + message_buffer, + token_buffer, + qop_state) + +OM_uint32 * minor_status; +gss_ctx_id_t context_handle; +gss_buffer_t message_buffer; +gss_buffer_t token_buffer; +gss_qop_t * qop_state; + +{ +/* + return (gss_verify(minor_status, context_handle, + message_buffer, token_buffer, (int *) qop_state)); + */ + OM_uint32 status; + gss_union_ctx_id_t ctx; + gss_mechanism mech; + + gss_initialize(); + + if (context_handle == GSS_C_NO_CONTEXT) + return GSS_S_NO_CONTEXT; + + /* + * select the approprate underlying mechanism routine and + * call it. + */ + + ctx = (gss_union_ctx_id_t) context_handle; + mech = __gss_get_mechanism (ctx->mech_type); + + if (mech) { + if (mech->gss_verify_mic) { + status = mech->gss_verify_mic( +#ifdef USE_MECH_CONTEXT + mech->context, +#endif + minor_status, + ctx->internal_ctx_id, + message_buffer, + token_buffer, + qop_state); + return (status); + } + else + return (gss_verify(minor_status, context_handle, + message_buffer, token_buffer, + (int *) qop_state)); + } + + return(GSS_S_NO_CONTEXT); +} diff --git a/support/gssapi/gen_oids.c b/support/gssapi/gen_oids.c new file mode 100644 index 0000000..e06d60e --- /dev/null +++ b/support/gssapi/gen_oids.c @@ -0,0 +1,80 @@ +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "mglueP.h" + +/* + * See krb5/gssapi_krb5.c for a description of the algorithm for + * encoding an object identifier. + */ + +/* + * The OID of user_name is: + * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) + * generic(1) user_name(1) = 1.2.840.113554.1.2.1.1 + * machine_uid_name: + * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) + * generic(1) machine_uid_name(2) = 1.2.840.113554.1.2.1.2 + * string_uid_name: + * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) + * generic(1) string_uid_name(3) = 1.2.840.113554.1.2.1.3 + * service_name: + * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) + * generic(1) service_name(4) = 1.2.840.113554.1.2.1.4 + * anonymous_name: + * iso(1) org(3) dod(6) internet(1) security(5) nametypes(6) + * gss-anonymous-name(3) = 1.3.6.1.5.6.3 + * exported_name: + * iso(1) org(3) dod(6) internet(1) security(5) nametypes(6) + * gss-api-exported-name(4) = 1.3.6.1.5.6.4 + * + */ + +static const gss_OID_desc oids[] = { + {10, "\052\206\110\206\367\022\001\002\001\001"}, + {10, "\052\206\110\206\367\022\001\002\001\002"}, + {10, "\052\206\110\206\367\022\001\002\001\003"}, + {10, "\052\206\110\206\367\022\001\002\001\004"}, + {6, "\053\006\001\005\006\003"}, + {6, "\053\006\001\005\006\004"}, +}; + + +/* + * rfc2744 defines the UPPERCASE names, the lowercase names are + * the original MIT names and should not be used in new applications + */ +const gss_OID_desc * const GSS_C_NT_USER_NAME = oids+0; +const gss_OID_desc * const gss_nt_user_name = oids+0; + +const gss_OID_desc * const GSS_C_NT_MACHINE_UID_NAME = oids+1; +const gss_OID_desc * const gss_nt_machine_uid_name = oids+1; + +const gss_OID_desc * const GSS_C_NT_STRING_UID_NAME = oids+2; +const gss_OID_desc * const gss_nt_string_uid_name = oids+2; + +const gss_OID_desc * const GSS_C_NT_HOSTBASED_SERVICE = oids+3; +const gss_OID_desc * const gss_nt_service_name = oids+3; + +const gss_OID_desc * const GSS_C_NT_ANONYMOUS = oids+4; + +const gss_OID_desc * const GSS_C_NT_EXPORT_NAME = oids+5; diff --git a/support/gssapi/gssd_pname_to_uid.c b/support/gssapi/gssd_pname_to_uid.c new file mode 100644 index 0000000..b390974 --- /dev/null +++ b/support/gssapi/gssd_pname_to_uid.c @@ -0,0 +1,71 @@ +/* #ident "@(#)gssd_pname_to_uid.c 1.5 95/08/02 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * glue routines that test the mech id either passed in to + * gss_init_sec_contex() or gss_accept_sec_context() or within the glue + * routine supported version of the security context and then call + * the appropriate underlying mechanism library procedure. + * + */ + +#include "mglueP.h" + +int gssd_pname_to_uid(pname, name_type, mech_type, uid) + +char * pname; +gss_OID name_type; +gss_OID mech_type; +uid_t * uid; +{ + int status; + gss_mechanism mech; + + gss_initialize(); + + /* + * find the appropriate mechanism specific pname_to_uid procedure and + * call it. + */ + + mech = __gss_get_mechanism (mech_type); + + if (mech) { + if (mech_type == GSS_C_NULL_OID) + mech_type = &mech->mech_type; + + if (mech->pname_to_uid) +#ifdef USE_MECH_CONTEXT + status = mech->pname_to_uid(mech->context, +#else + status = mech->pname_to_uid( +#endif + pname, name_type, mech_type, uid); + else + status = GSS_S_BAD_MECH; + } else + status = GSS_S_BAD_MECH; + + return(status); +} diff --git a/support/gssapi/mechglue.h b/support/gssapi/mechglue.h new file mode 100644 index 0000000..079ea93 --- /dev/null +++ b/support/gssapi/mechglue.h @@ -0,0 +1,46 @@ +/* #ident "@(#)mechglue.h 1.13 95/08/07 SMI" */ + +/* + * Copyright 1996 by Sun Microsystems, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of Sun Microsystems not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Sun Microsystems makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This header contains the mechglue definitions. + */ + +#ifndef _GSS_MECHGLUE_H +#define _GSS_MECHGLUE_H + +#include <gssapi/gssapi.h> + +/********************************************************/ +/* GSSAPI Extension functions -- these functions aren't */ +/* in the GSSAPI, but they are provided in this library */ + +int gssd_pname_to_uid (char *, gss_OID, gss_OID, uid_t *); +void gss_initialize (void); +OM_uint32 gss_set_allowable_enctypes( OM_uint32 *, /* minor_status */ + gss_cred_id_t, /* cred_handle */ + gss_OID, /* mech type */ + OM_uint32, /* num_ktypes */ + void * /* ktypes */); + +#endif /* _GSS_MECHGLUE_H */ diff --git a/support/gssapi/mglueP.h b/support/gssapi/mglueP.h new file mode 100644 index 0000000..362b308 --- /dev/null +++ b/support/gssapi/mglueP.h @@ -0,0 +1,503 @@ +/* #ident "@(#)mglueP.h 1.2 96/01/18 SMI" */ + +/* + * This header contains the private mechglue definitions. + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#ifndef _GSS_MECHGLUEP_H +#define _GSS_MECHGLUEP_H + +#include "mechglue.h" + +/* + * Array of context IDs typed by mechanism OID + */ +typedef struct gss_union_ctx_id_t { + gss_OID mech_type; + gss_ctx_id_t internal_ctx_id; +} gss_union_ctx_id_desc, *gss_union_ctx_id_t; + +/* + * Structure for holding list of mechanism-specific name types + */ +typedef struct gss_mech_spec_name_t { + gss_OID name_type; + gss_OID mech; + struct gss_mech_spec_name_t *next, *prev; +} gss_mech_spec_name_desc, *gss_mech_spec_name; + +/* + * Credential auxiliary info, used in the credential structure + */ +typedef struct gss_union_cred_auxinfo { + gss_buffer_desc name; + gss_OID name_type; + time_t creation_time; + OM_uint32 time_rec; + int cred_usage; +} gss_union_cred_auxinfo; + +/* + * Set of Credentials typed on mechanism OID + */ +typedef struct gss_union_cred_t { + int count; + gss_OID mechs_array; + gss_cred_id_t * cred_array; + gss_union_cred_auxinfo auxinfo; +} gss_union_cred_desc, *gss_union_cred_t; + +/********************************************************/ +/* The Mechanism Dispatch Table -- a mechanism needs to */ +/* define one of these and provide a function to return */ +/* it to initialize the GSSAPI library */ + +/* + * This is the definition of the mechs_array struct, which is used to + * define the mechs array table. This table is used to indirectly + * access mechanism specific versions of the gssapi routines through + * the routines in the glue module (gssd_mech_glue.c) + * + * This contants all of the functions defined in gssapi.h except for + * gss_release_buffer() and gss_release_oid_set(), which I am + * assuming, for now, to be equal across mechanisms. + */ + +typedef struct gss_config { + gss_OID_desc mech_type; + void * context; + OM_uint32 (*gss_acquire_cred) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_name_t, /* desired_name */ + OM_uint32, /* time_req */ + gss_OID_set, /* desired_mechs */ + int, /* cred_usage */ + gss_cred_id_t*, /* output_cred_handle */ + gss_OID_set*, /* actual_mechs */ + OM_uint32* /* time_rec */ + ); + OM_uint32 (*gss_release_cred) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_cred_id_t* /* cred_handle */ + ); + OM_uint32 (*gss_init_sec_context) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_cred_id_t, /* claimant_cred_handle */ + gss_ctx_id_t*, /* context_handle */ + gss_name_t, /* target_name */ + gss_OID, /* mech_type */ + OM_uint32, /* req_flags */ + OM_uint32, /* time_req */ + gss_channel_bindings_t, /* input_chan_bindings */ + gss_buffer_t, /* input_token */ + gss_OID*, /* actual_mech_type */ + gss_buffer_t, /* output_token */ + OM_uint32*, /* ret_flags */ + OM_uint32* /* time_rec */ + ); + OM_uint32 (*gss_accept_sec_context) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_ctx_id_t*, /* context_handle */ + gss_cred_id_t, /* verifier_cred_handle */ + gss_buffer_t, /* input_token_buffer */ + gss_channel_bindings_t, /* input_chan_bindings */ + gss_name_t*, /* src_name */ + gss_OID*, /* mech_type */ + gss_buffer_t, /* output_token */ + OM_uint32*, /* ret_flags */ + OM_uint32*, /* time_rec */ + gss_cred_id_t* /* delegated_cred_handle */ + ); + OM_uint32 (*gss_process_context_token) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t /* token_buffer */ + ); + OM_uint32 (*gss_delete_sec_context) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_ctx_id_t*, /* context_handle */ + gss_buffer_t /* output_token */ + ); + OM_uint32 (*gss_context_time) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + OM_uint32* /* time_rec */ + ); + OM_uint32 (*gss_sign) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* qop_req */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t /* message_token */ + ); + OM_uint32 (*gss_verify) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t, /* token_buffer */ + int* /* qop_state */ + ); + OM_uint32 (*gss_seal) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* conf_req_flag */ + int, /* qop_req */ + gss_buffer_t, /* input_message_buffer */ + int*, /* conf_state */ + gss_buffer_t /* output_message_buffer */ + ); + OM_uint32 (*gss_unseal) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* input_message_buffer */ + gss_buffer_t, /* output_message_buffer */ + int*, /* conf_state */ + int* /* qop_state */ + ); + OM_uint32 (*gss_display_status) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + OM_uint32, /* status_value */ + int, /* status_type */ + gss_OID, /* mech_type */ + OM_uint32*, /* message_context */ + gss_buffer_t /* status_string */ + ); + OM_uint32 (*gss_indicate_mechs) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_OID_set* /* mech_set */ + ); + OM_uint32 (*gss_compare_name) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_name_t, /* name1 */ + gss_name_t, /* name2 */ + int* /* name_equal */ + ); + OM_uint32 (*gss_display_name) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_name_t, /* input_name */ + gss_buffer_t, /* output_name_buffer */ + gss_OID* /* output_name_type */ + ); + OM_uint32 (*gss_import_name) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_buffer_t, /* input_name_buffer */ + gss_OID, /* input_name_type */ + gss_name_t* /* output_name */ + ); + OM_uint32 (*gss_release_name) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_name_t* /* input_name */ + ); + OM_uint32 (*gss_inquire_cred) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32 *, /* minor_status */ + gss_cred_id_t, /* cred_handle */ + gss_name_t *, /* name */ + OM_uint32 *, /* lifetime */ + int *, /* cred_usage */ + gss_OID_set * /* mechanisms */ + ); + OM_uint32 (*gss_add_cred) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32 *, /* minor_status */ + gss_cred_id_t, /* input_cred_handle */ + gss_name_t, /* desired_name */ + gss_OID, /* desired_mech */ + 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 */ + ); + OM_uint32 (*gss_export_sec_context) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32 *, /* minor_status */ + gss_ctx_id_t *, /* context_handle */ + gss_buffer_t /* interprocess_token */ + ); + OM_uint32 (*gss_import_sec_context) + ( +#ifdef USE_MECH_CONTEXT + void *, /* context */ +#endif + OM_uint32 *, /* minor_status */ + gss_buffer_t, /* interprocess_token */ + gss_ctx_id_t * /* context_handle */ + ); + OM_uint32 (*gss_inquire_cred_by_mech) + ( +#ifdef USE_MECH_CONTEXT + void *, /* context */ +#endif + OM_uint32 *, /* minor_status */ + gss_cred_id_t, /* cred_handle */ + gss_OID, /* mech_type */ + gss_name_t *, /* name */ + OM_uint32 *, /* initiator_lifetime */ + OM_uint32 *, /* acceptor_lifetime */ + gss_cred_usage_t * /* cred_usage */ + ); + OM_uint32 (*gss_inquire_names_for_mech) + ( +#ifdef USE_MECH_CONTEXT + void *, /* context */ +#endif + OM_uint32 *, /* minor_status */ + gss_OID, /* mechanism */ + gss_OID_set * /* name_types */ + ); + OM_uint32 (*gss_inquire_context) + ( +#ifdef USE_MECH_CONTEXT + void *, /* context */ +#endif + OM_uint32 *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_name_t *, /* src_name */ + gss_name_t *, /* targ_name */ + OM_uint32 *, /* lifetime_rec */ + gss_OID *, /* mech_type */ + OM_uint32 *, /* ctx_flags */ + int *, /* locally_initiated */ + int * /* open */ + ); + OM_uint32 (*gss_internal_release_oid) + ( +#ifdef USE_MECH_CONTEXT + void *, /* context */ +#endif + OM_uint32 *, /* minor_status */ + gss_OID * /* OID */ + ); + OM_uint32 (*gss_wrap_size_limit) + ( +#ifdef USE_MECH_CONTEXT + void *, /* context */ +#endif + OM_uint32 *, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + int, /* conf_req_flag */ + gss_qop_t, /* qop_req */ + OM_uint32, /* req_output_size */ + OM_uint32 * /* max_input_size */ + ); + OM_uint32 (*pname_to_uid) + ( +#ifdef USE_MECH_CONTEXT + void *, /* context */ +#endif + char *, /* pname */ + gss_OID, /* name type */ + gss_OID, /* mech type */ + uid_t * /* uid */ + ); + OM_uint32 (*gss_duplicate_name) + ( +#ifdef USE_MECH_CONTEXT + void *, /* context */ +#endif + OM_uint32 *, /* minor_status */ + const gss_name_t, /* input_name */ + gss_name_t * /* dest_name */ + ); + OM_uint32 (*gss_set_allowable_enctypes) + ( +#ifdef USE_MECH_CONTEXT + void *, /* context */ +#endif + OM_uint32 *, /* minor_status */ + gss_cred_id_t, /* cred_handle */ + OM_uint32, /* num_ktypes */ + void * /* ktypes */ + ); + OM_uint32 (*gss_verify_mic) + ( +#ifdef USE_MECH_CONTEXT + void*, /* context */ +#endif + OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t, /* message_buffer */ + gss_buffer_t, /* token_buffer */ + int* /* qop_state */ + ); + +} *gss_mechanism; + +/* + * Generic GSSAPI names. A name can either be a generic name, or a + * mechanism specific name.... + */ +typedef struct gss_union_name_t { + gss_mechanism gss_mech; + gss_OID name_type; + gss_buffer_t external_name; + /* + * These last two fields are only filled in for mechanism + * names. + */ + gss_OID mech_type; + gss_name_t mech_name; +} gss_union_name_desc, *gss_union_name_t; + +/********************************************************/ +/* Internal mechglue routines */ + +gss_mechanism __gss_get_mechanism (gss_OID); +OM_uint32 __gss_get_mech_type (gss_OID, gss_buffer_t); +OM_uint32 __gss_import_internal_name (OM_uint32 *, gss_OID, gss_union_name_t, + gss_name_t *); +OM_uint32 __gss_display_internal_name (OM_uint32 *, gss_OID, gss_name_t, + gss_buffer_t, gss_OID *); +OM_uint32 __gss_release_internal_name (OM_uint32 *, gss_OID, gss_name_t *); + +OM_uint32 __gss_convert_name_to_union_name + (OM_uint32 *, /* minor_status */ + gss_mechanism, /* mech */ + gss_name_t, /* internal_name */ + gss_name_t * /* external_name */ + ); +gss_cred_id_t __gss_get_mechanism_cred + (gss_union_cred_t, /* union_cred */ + gss_OID /* mech_type */ + ); + +OM_uint32 generic_gss_release_oid + (OM_uint32 *, /* minor_status */ + gss_OID * /* oid */ + ); + +OM_uint32 mech_gss_release_oid + (OM_uint32 *, /* minor_status */ + gss_OID *, /* oid */ + gss_mechanism /* gss_mech */ + ); + +OM_uint32 generic_gss_copy_oid + (OM_uint32 *, /* minor_status */ + gss_OID, /* oid */ + gss_OID * /* new_oid */ + ); + +OM_uint32 generic_gss_create_empty_oid_set + (OM_uint32 *, /* minor_status */ + gss_OID_set * /* oid_set */ + ); + +OM_uint32 generic_gss_add_oid_set_member + (OM_uint32 *, /* minor_status */ + gss_OID, /* member_oid */ + gss_OID_set * /* oid_set */ + ); + +OM_uint32 generic_gss_test_oid_set_member + (OM_uint32 *, /* minor_status */ + gss_OID, /* member */ + gss_OID_set, /* set */ + int * /* present */ + ); + +OM_uint32 generic_gss_oid_to_str + (OM_uint32 *, /* minor_status */ + gss_OID, /* oid */ + gss_buffer_t /* oid_str */ + ); + +OM_uint32 generic_gss_str_to_oid + (OM_uint32 *, /* minor_status */ + gss_buffer_t, /* oid_str */ + gss_OID * /* oid */ + ); + + +gss_OID gss_find_mechanism_from_name_type (gss_OID); /* name_type */ + +OM_uint32 gss_add_mech_name_type + (OM_uint32 *, /* minor_status */ + gss_OID, /* name_type */ + gss_OID /* mech */ + ); + +#endif /* _GSS_MECHGLUEP_H */ diff --git a/support/gssapi/oid_ops.c b/support/gssapi/oid_ops.c new file mode 100644 index 0000000..ed24d58 --- /dev/null +++ b/support/gssapi/oid_ops.c @@ -0,0 +1,449 @@ +/* + * lib/gssapi/generic/oid_ops.c + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +/* + * oid_ops.c - GSS-API V2 interfaces to manipulate OIDs + */ + +#include "mglueP.h" +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> +#include <ctype.h> + +OM_uint32 +generic_gss_release_oid(minor_status, oid) + OM_uint32 *minor_status; + gss_OID *oid; +{ + *minor_status = 0; +#ifdef DEBUG + static int printed = 0; + + if (!printed++) + fprintf(stderr, "gss_generic_release_oid (glue):\n" + " GSS_C_NT_USER_NAME %p\n" + " GSS_C_NT_MACHINE_UID_NAME %p\n" + " GSS_C_NT_STRING_UID_NAME %p\n" + " GSS_C_NT_HOSTBASED_SERVICE %p\n" + " GSS_C_NT_ANONYMOUS %p\n" + " GSS_C_NT_EXPORT_NAME %p\n", + GSS_C_NT_USER_NAME, GSS_C_NT_MACHINE_UID_NAME, + GSS_C_NT_STRING_UID_NAME, GSS_C_NT_HOSTBASED_SERVICE, + GSS_C_NT_ANONYMOUS, GSS_C_NT_EXPORT_NAME); +#endif + + if (*oid == GSS_C_NO_OID) + return(GSS_S_COMPLETE); + + /* + * The V2 API says the following! + * + * gss_release_oid[()] will recognize any of the GSSAPI's own OID values, + * and will silently ignore attempts to free these OIDs; for other OIDs + * it will call the C free() routine for both the OID data and the + * descriptor. This allows applications to freely mix their own heap- + * allocated OID values with OIDs returned by GSS-API. + */ + if ((*oid != GSS_C_NT_USER_NAME) && + (*oid != GSS_C_NT_MACHINE_UID_NAME) && + (*oid != GSS_C_NT_STRING_UID_NAME) && + (*oid != GSS_C_NT_HOSTBASED_SERVICE) && + (*oid != GSS_C_NT_ANONYMOUS) && + (*oid != GSS_C_NT_EXPORT_NAME)) { +#ifdef DEBUG + fprintf(stderr, "generic_gss_release_oid (glue): freeing *oid at %p\n", + *oid); +#endif + free((*oid)->elements); + free(*oid); + } + *oid = GSS_C_NO_OID; + return(GSS_S_COMPLETE); +} + +OM_uint32 +mech_gss_release_oid(minor_status, oid, gss_mech) + OM_uint32 *minor_status; + gss_OID *oid; + gss_mechanism gss_mech; +{ + *minor_status = 0; + +#ifdef DEBUG + fprintf(stderr, "mech_gss_release_oid: *oid %p, gss_mech %p\n", + *oid, gss_mech); +#endif + if (*oid == GSS_C_NO_OID) + return (GSS_S_COMPLETE); + + if (gss_mech == NULL) { +#ifdef DEBUG + fprintf(stderr, "mech_gss_release_oid: no gss_mech!\n"); +#endif + return (generic_gss_release_oid(minor_status, oid)); + } + + if (!gss_mech->gss_internal_release_oid) { +#ifdef DEBUG + fprintf(stderr, "mech_gss_release_oid: mechanism has " + "no gss_internal_release_oid function! using " + "generic_gss_release_oid\n"); +#endif + return (generic_gss_release_oid(minor_status, oid)); + } + +#ifdef DEBUG + fprintf(stderr, "mech_gss_release_oid: calling mechanism's " + "gss_internal_release_oid\n"); +#endif + return (gss_mech->gss_internal_release_oid(minor_status, oid)); +} + +OM_uint32 +generic_gss_copy_oid(minor_status, oid, new_oid) + OM_uint32 *minor_status; + gss_OID oid, *new_oid; +{ + gss_OID p; + + if (oid == GSS_C_NO_OID) { + *new_oid = GSS_C_NO_OID; + return (GSS_S_COMPLETE); + } + + p = (gss_OID) malloc(sizeof(gss_OID_desc)); + if (!p) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + p->length = oid->length; + p->elements = malloc(p->length); + if (!p->elements) { + free(p); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + memcpy(p->elements, oid->elements, p->length); + *new_oid = p; + return (GSS_S_COMPLETE); +} + + +OM_uint32 +generic_gss_create_empty_oid_set(minor_status, oid_set) + OM_uint32 *minor_status; + gss_OID_set *oid_set; +{ + if ((*oid_set = (gss_OID_set) malloc(sizeof(gss_OID_set_desc)))) { + memset(*oid_set, 0, sizeof(gss_OID_set_desc)); + *minor_status = 0; + return(GSS_S_COMPLETE); + } + else { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } +} + +OM_uint32 +generic_gss_add_oid_set_member(minor_status, member_oid, oid_set) + OM_uint32 *minor_status; + gss_OID member_oid; + gss_OID_set *oid_set; +{ + gss_OID elist; + gss_OID lastel; + + elist = (*oid_set)->elements; + /* Get an enlarged copy of the array */ + if (((*oid_set)->elements = (gss_OID) malloc(((*oid_set)->count+1) * + sizeof(gss_OID_desc)))) { + /* Copy in the old junk */ + if (elist) + memcpy((*oid_set)->elements, + elist, + ((*oid_set)->count * sizeof(gss_OID_desc))); + + /* Duplicate the input element */ + lastel = &(*oid_set)->elements[(*oid_set)->count]; + if ((lastel->elements = + (void *) malloc((size_t) member_oid->length))) { + /* Success - copy elements */ + memcpy(lastel->elements, member_oid->elements, + (size_t) member_oid->length); + /* Set length */ + lastel->length = member_oid->length; + + /* Update count */ + (*oid_set)->count++; + if (elist) + free(elist); + *minor_status = 0; + return(GSS_S_COMPLETE); + } + else + free((*oid_set)->elements); + } + /* Failure - restore old contents of list */ + (*oid_set)->elements = elist; + *minor_status = ENOMEM; + return(GSS_S_FAILURE); +} + +OM_uint32 +generic_gss_test_oid_set_member(minor_status, member, set, present) + OM_uint32 *minor_status; + gss_OID member; + gss_OID_set set; + int *present; +{ + size_t i; + int result; + + result = 0; + for (i=0; i<set->count; i++) { + if ((set->elements[i].length == member->length) && + !memcmp(set->elements[i].elements, + member->elements, + (size_t) member->length)) { + result = 1; + break; + } + } + *present = result; + *minor_status = 0; + return(GSS_S_COMPLETE); +} + +/* + * OID<->string routines. These are uuuuugly. + */ +OM_uint32 +generic_gss_oid_to_str(minor_status, oid, oid_str) + OM_uint32 *minor_status; + gss_OID oid; + gss_buffer_t oid_str; +{ + char numstr[128]; + unsigned long number; + int numshift; + size_t string_length; + size_t i; + unsigned char *cp; + char *bp; + + /* Decoded according to krb5/gssapi_krb5.c */ + + /* First determine the size of the string */ + string_length = 0; + number = 0; + numshift = 0; + cp = (unsigned char *) oid->elements; + number = (unsigned long) cp[0]; + sprintf(numstr, "%ld ", number/40); + string_length += strlen(numstr); + sprintf(numstr, "%ld ", number%40); + string_length += strlen(numstr); + for (i=1; i<oid->length; i++) { + if ( (size_t) (numshift+7) < (sizeof(unsigned long)*8)) { + number = (number << 7) | (cp[i] & 0x7f); + numshift += 7; + } + else { + *minor_status = EINVAL; + return(GSS_S_FAILURE); + } + if ((cp[i] & 0x80) == 0) { + sprintf(numstr, "%ld ", number); + string_length += strlen(numstr); + number = 0; + numshift = 0; + } + } + /* + * If we get here, we've calculated the length of "n n n ... n ". Add 4 + * here for "{ " and "}\0". + */ + string_length += 4; + if ((bp = (char *) malloc(string_length))) { + strcpy(bp, "{ "); + number = (unsigned long) cp[0]; + sprintf(numstr, "%ld ", number/40); + strcat(bp, numstr); + sprintf(numstr, "%ld ", number%40); + strcat(bp, numstr); + number = 0; + cp = (unsigned char *) oid->elements; + for (i=1; i<oid->length; i++) { + number = (number << 7) | (cp[i] & 0x7f); + if ((cp[i] & 0x80) == 0) { + sprintf(numstr, "%ld ", number); + strcat(bp, numstr); + number = 0; + } + } + strcat(bp, "}"); + oid_str->length = strlen(bp)+1; + oid_str->value = (void *) bp; + *minor_status = 0; + return(GSS_S_COMPLETE); + } + *minor_status = ENOMEM; + return(GSS_S_FAILURE); +} + +OM_uint32 +generic_gss_str_to_oid(minor_status, oid_str, oid) + OM_uint32 *minor_status; + gss_buffer_t oid_str; + gss_OID *oid; +{ + char *cp, *bp, *startp; + int brace; + long numbuf; + long onumbuf; + OM_uint32 nbytes; + int index; + unsigned char *op; + + brace = 0; + bp = (char *) oid_str->value; + cp = bp; + /* Skip over leading space */ + while ((bp < &cp[oid_str->length]) && isspace(*bp)) + bp++; + if (*bp == '{') { + brace = 1; + bp++; + } + while ((bp < &cp[oid_str->length]) && isspace(*bp)) + bp++; + startp = bp; + nbytes = 0; + + /* + * The first two numbers are chewed up by the first octet. + */ + if (sscanf(bp, "%ld", &numbuf) != 1) { + *minor_status = EINVAL; + return(GSS_S_FAILURE); + } + while ((bp < &cp[oid_str->length]) && isdigit(*bp)) + bp++; + while ((bp < &cp[oid_str->length]) && isspace(*bp)) + bp++; + if (sscanf(bp, "%ld", &numbuf) != 1) { + *minor_status = EINVAL; + return(GSS_S_FAILURE); + } + while ((bp < &cp[oid_str->length]) && isdigit(*bp)) + bp++; + while ((bp < &cp[oid_str->length]) && isspace(*bp)) + bp++; + nbytes++; + while (isdigit(*bp)) { + if (sscanf(bp, "%ld", &numbuf) != 1) { + *minor_status = EINVAL; + return(GSS_S_FAILURE); + } + while (numbuf) { + nbytes++; + numbuf >>= 7; + } + while ((bp < &cp[oid_str->length]) && isdigit(*bp)) + bp++; + while ((bp < &cp[oid_str->length]) && isspace(*bp)) + bp++; + } + if (brace && (*bp != '}')) { + *minor_status = EINVAL; + return(GSS_S_FAILURE); + } + + /* + * Phew! We've come this far, so the syntax is good. + */ + if ((*oid = (gss_OID) malloc(sizeof(gss_OID_desc)))) { + if (((*oid)->elements = (void *) malloc((size_t) nbytes))) { + (*oid)->length = nbytes; + op = (unsigned char *) (*oid)->elements; + bp = startp; + sscanf(bp, "%ld", &numbuf); + while (isdigit(*bp)) + bp++; + while (isspace(*bp)) + bp++; + onumbuf = 40*numbuf; + sscanf(bp, "%ld", &numbuf); + onumbuf += numbuf; + *op = (unsigned char) onumbuf; + op++; + while (isdigit(*bp)) + bp++; + while (isspace(*bp)) + bp++; + while (isdigit(*bp)) { + sscanf(bp, "%ld", &numbuf); + nbytes = 0; + /* Have to fill in the bytes msb-first */ + onumbuf = numbuf; + while (numbuf) { + nbytes++; + numbuf >>= 7; + } + numbuf = onumbuf; + op += nbytes; + index = -1; + while (numbuf) { + op[index] = (unsigned char) numbuf & 0x7f; + if (index != -1) + op[index] |= 0x80; + index--; + numbuf >>= 7; + } + while (isdigit(*bp)) + bp++; + while (isspace(*bp)) + bp++; + } + *minor_status = 0; + return(GSS_S_COMPLETE); + } + else { + free(*oid); + *oid = GSS_C_NO_OID; + } + } + *minor_status = ENOMEM; + return(GSS_S_FAILURE); +} + |