X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=support%2Fgssapi%2Fg_glue.c;fp=support%2Fgssapi%2Fg_glue.c;h=cf2f76a2c037259690b848b42ea64bd98f1c087e;hp=0000000000000000000000000000000000000000;hb=f1bfe0916c04d93de7a4fae5315fff6e4ccac23f;hpb=981d25a37fe4a71eddd162672a658da223453985 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 +#ifdef HAVE_STDLIB_H +#include +#endif +#include +#include + +#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 + * + * + * Numerically, this looks like : + * + * 0x60 + * - could be multiple bytes + * 0x06 + * - assume only one byte, hence OID length < 127 + * + * + * 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); +}