From: Theodore Tso Date: Wed, 15 Nov 1995 16:21:13 +0000 (+0000) Subject: Initial checkin of Sun's (Derek's) multi-mechanism GSSAPI support X-Git-Tag: krb5-1.0-beta6~798 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=393f9bb1f6d53da6a4ddb4451324a0bad76c2f1a;p=krb5.git Initial checkin of Sun's (Derek's) multi-mechanism GSSAPI support git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@7107 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/lib/gssapi/mechglue/.cvsignore b/src/lib/gssapi/mechglue/.cvsignore new file mode 100644 index 000000000..e8c05a6b1 --- /dev/null +++ b/src/lib/gssapi/mechglue/.cvsignore @@ -0,0 +1 @@ +configure diff --git a/src/lib/gssapi/mechglue/Makefile.in b/src/lib/gssapi/mechglue/Makefile.in new file mode 100644 index 000000000..b32292f94 --- /dev/null +++ b/src/lib/gssapi/mechglue/Makefile.in @@ -0,0 +1,98 @@ +CFLAGS = $(CCOPTS) $(DEFS) -I. -I$(srcdir) + +##DOSBUILDTOP = ..\..\.. +##DOSLIBNAME=..\gssapi.$(LIBEXT) +##DOSsrcdir = . +##DOS!include $(BUILDTOP)\config\windows.in + +LIBDONE=DONE +LIB_SUBDIRSS=. + +SRCS = gss_acquire_cred.c \ + gss_release_cred.c \ + gss_init_sec_context.c \ + gss_accept_sec_context.c \ + gss_process_context.c \ + gss_delete_sec_context.c \ + gss_context_time.c \ + gss_sign.c \ + gss_verify.c \ + gss_seal.c \ + gss_unseal.c \ + gss_display_status.c \ + gss_indicate_mechs.c \ + gss_compare_name.c \ + gss_display_name.c \ + gss_import_name.c \ + gss_release_name.c \ + gss_release_buffer.c \ + gss_release_oid_set.c \ + gss_inquire_cred.c \ + gss_initialize.c \ + get_mech_type.c \ + get_mechanism.c \ + internal_name.c \ + gssd_pname_to_uid.c \ + add_mechanism.c + +OBJS = gss_acquire_cred.$(OBJEXT) \ + gss_release_cred.$(OBJEXT) \ + gss_init_sec_context.$(OBJEXT) \ + gss_accept_sec_context.$(OBJEXT) \ + gss_process_context.$(OBJEXT) \ + gss_delete_sec_context.$(OBJEXT) \ + gss_context_time.$(OBJEXT) \ + gss_sign.$(OBJEXT) \ + gss_verify.$(OBJEXT) \ + gss_seal.$(OBJEXT) \ + gss_unseal.$(OBJEXT) \ + gss_display_status.$(OBJEXT) \ + gss_indicate_mechs.$(OBJEXT) \ + gss_compare_name.$(OBJEXT) \ + gss_display_name.$(OBJEXT) \ + gss_import_name.$(OBJEXT) \ + gss_release_name.$(OBJEXT) \ + gss_release_buffer.$(OBJEXT) \ + gss_release_oid_set.$(OBJEXT) \ + gss_inquire_cred.$(OBJEXT) \ + gss_initialize.$(OBJEXT) \ + get_mech_type.$(OBJEXT) \ + get_mechanism.$(OBJEXT) \ + internal_name.$(OBJEXT) \ + gssd_pname_to_uid.$(OBJEXT) \ + add_mechanism.$(OBJEXT) + +EXPORTED_HEADERS = mechglue.h + +all:: all-$(WHAT) $(OBJS) + +all-unix:: + +all-mac:: + +all-windows:: + if not exist $(EHDRDIR)\nul mkdir $(EHDRDIR) + copy mechglue.h $(EHDRDIR) + +unixmac: + +libgssapi.$(LIBEXT): $(OBJS) + $(ARCHIVE) $@ $(OBJS) + $(RANLIB) $@ + +clean:: clean-$(WHAT) + +clean-unix:: + +clean-mac:: + +clean-windows:: + $(RM) $(EHDRDIR)\gssapi.h $(EHDRDIR)\gssapi_generic.h + if exist $(EHDRDIR)\nul rmdir $(EHDRDIR) + +# Krb5InstallHeaders($(EXPORTED_HEADERS), $(KRB5_INCDIR)/krb5) +install:: + @set -x; for f in $(EXPORTED_HEADERS) ; \ + do $(INSTALL_DATA) $(srcdir)$(S)$$f \ + $(DESTDIR)$(KRB5_INCDIR)$(S)gssapi$(S)$$f ; \ + done diff --git a/src/lib/gssapi/mechglue/add_mechanism.c b/src/lib/gssapi/mechglue/add_mechanism.c new file mode 100644 index 000000000..fa5ea5322 --- /dev/null +++ b/src/lib/gssapi/mechglue/add_mechanism.c @@ -0,0 +1,67 @@ +#ident "@(#)add_mechanism.c 1.5 95/08/04 SMI" +/* + * This function will add a new mechanism to the mechs_array + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" +#include + +static struct gss_config null_mech = { + {0,NULL}}; + +gss_mechanism *mechs_array = NULL; + +OM_uint32 add_mechanism (gss_mechanism mech, int replace) +{ + gss_mechanism *temp_array; + int i; + + if (mech == NULL) + return GSS_S_COMPLETE; + + /* initialize the mechs_array if it hasn't already been initialized */ + if (mechs_array == NULL) { + mechs_array = (gss_mechanism *) malloc (sizeof(gss_mechanism)); + + if (mechs_array == NULL) + return ENOMEM; + + mechs_array[0] = &null_mech; + } + + /* + * Find the length of mechs_array, and look for an existing + * entry for this OID + */ + for (i=0; mechs_array[i]->mech_type.length != 0; i++) { + if ((mechs_array[i]->mech_type.length == mech->mech_type.length) && + (memcmp (mechs_array[i]->mech_type.elements, + mech->mech_type.elements, + mech->mech_type.length) == 0)) { + + /* We found a match. Replace it? */ + if (!replace) + return GSS_S_FAILURE; + + mechs_array[i] = mech; + return GSS_S_COMPLETE; + } + } + + /* we didn't find it -- add it to the end of the mechs_array */ + temp_array = (gss_mechanism *) realloc(mechs_array, + (i+2)*sizeof(gss_mechanism)); + + if (temp_array == NULL) + return ENOMEM; + + temp_array[i++] = mech; + temp_array[i] = &null_mech; + + mechs_array = temp_array; + + return GSS_S_COMPLETE; +} diff --git a/src/lib/gssapi/mechglue/configure.in b/src/lib/gssapi/mechglue/configure.in new file mode 100644 index 000000000..3cd9048db --- /dev/null +++ b/src/lib/gssapi/mechglue/configure.in @@ -0,0 +1,11 @@ +AC_INIT(configure.in) +CONFIG_RULES +AC_PROG_ARCHIVE +AC_PROG_RANLIB +AC_PROG_INSTALL +CopySrcHeader(mechglue.h,[$(EHDRDIR)]) +AppendRule([install:: libgssapi.[$](LIBEXT) + [$](INSTALL_DATA) libgssapi.[$](LIBEXT) [$](DESTDIR)[$](KRB5_LIBDIR)[$](S)libgssapi.[$](LIBEXT)]) +LinkFileDir([$](TOPLIBD)/libgssapi.[$](LIBEXT),libgssapi.[$](LIBEXT),./gssapi/mechglue) +AppendRule([all:: [$](TOPLIBD)/libgssapi.[$](LIBEXT)]) +V5_AC_OUTPUT_MAKEFILE diff --git a/src/lib/gssapi/mechglue/get_mech_type.c b/src/lib/gssapi/mechglue/get_mech_type.c new file mode 100644 index 000000000..0dc087512 --- /dev/null +++ b/src/lib/gssapi/mechglue/get_mech_type.c @@ -0,0 +1,66 @@ +#ident "@(#)get_mech_type.c 1.4 95/06/08 SMI" +/* + * glue routine for get_mech_type + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +OM_uint32 get_mech_type(OID, token) + +gss_OID * OID; +gss_buffer_t token; + +{ + unsigned char * buffer_ptr; + + /* + * 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 returns a pointer to the OID value. The return code is + * the length of the OID, if successful; otherwise it is 0. + */ + + if (OID == NULL || *OID == GSS_C_NULL_OID) + return (0); + + /* if the token is a null pointer, return a zero length OID */ + + if(token == NULL) { + (*OID)->length = 0; + (*OID)->elements = NULL; + return (0); + } + + /* Skip past the APP/Sequnce byte and the token length */ + + buffer_ptr = (unsigned char *) token->value; + + while(*(++buffer_ptr) & (1<<7)) + continue; + + /* increment buffer_ptr to point to the OID and return its length */ + + (*OID)->length = (OM_uint32) *(buffer_ptr+3); + (*OID)->elements = (void *) (buffer_ptr+4); + return ((*OID)->length); +} diff --git a/src/lib/gssapi/mechglue/get_mechanism.c b/src/lib/gssapi/mechglue/get_mechanism.c new file mode 100644 index 000000000..b3f7b6900 --- /dev/null +++ b/src/lib/gssapi/mechglue/get_mechanism.c @@ -0,0 +1,32 @@ +#ident "@(#)get_mechanism.c 1.10 95/08/04 SMI" +/* + * 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. + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +extern gss_mechanism *mechs_array; + +gss_mechanism get_mechanism (const_gss_OID type) +{ + int i; + + if (type == GSS_C_NULL_OID) + return (mechs_array[0]); + + for (i=0; mechs_array[i]->mech_type.length != 0; i++) { + if ((mechs_array[i]->mech_type.length == type->length) && + (memcmp (mechs_array[i]->mech_type.elements, type->elements, + type->length) == 0)) { + + return (mechs_array[i]); + } + } + return NULL; +} diff --git a/src/lib/gssapi/mechglue/gss_accept_sec_context.c b/src/lib/gssapi/mechglue/gss_accept_sec_context.c new file mode 100644 index 000000000..e9fd1193c --- /dev/null +++ b/src/lib/gssapi/mechglue/gss_accept_sec_context.c @@ -0,0 +1,215 @@ +#ident "@(#)gss_accept_sec_context.c 1.19 95/08/07 SMI" +/* + * glue routine for gss_accept_sec_context + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +OM_uint32 +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; +int * 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_buffer_desc external_name_desc; + gss_buffer_t external_name = &external_name_desc; + gss_OID name_type; + gss_OID_desc token_mech_type_desc; + gss_OID token_mech_type = &token_mech_type_desc; + gss_mechanism mech; + int i; + + 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) { + + 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)); + + /* + * get the token mech type, create the context id mech type space + * and copy in the OID + */ + + get_mech_type(&token_mech_type, input_token_buffer); + + union_ctx_id->mech_type->elements = (void *) + malloc(token_mech_type->length); + + 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; + + /* + * 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; + + if (verifier_cred_handle != GSS_C_NO_CREDENTIAL) + for (i=0; i < union_cred->count; i++) { + if((union_cred->mechs_array[i].length == token_mech_type->length) + && + (memcmp(union_cred->mechs_array[i].elements, + token_mech_type->elements, + token_mech_type->length) == 0)) { + + input_cred_handle = union_cred->cred_array[i]; + break; + } + } + + /* + * now select the approprate underlying mechanism routine and + * call it. + */ + + mech = get_mechanism (token_mech_type); + if (mech && mech->gss_accept_sec_context) { + + status = mech->gss_accept_sec_context( + mech->context, + 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 the call failed, return with failure */ + + if(status != GSS_S_COMPLETE + && + status != GSS_S_CONTINUE_NEEDED) + return(status); + + /* + * 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(src_name != NULL) { + temp_status = display_internal_name ( + &temp_minor_status, + &mech->mech_type, + internal_name, + external_name, + &name_type); + + if (temp_status != GSS_S_COMPLETE) { + + /* + * this should never happen, since we just got + * the name from the mechanism gss_accept_sec_context + * call. However, things that can't happen often do. + */ + if (minor_status) + *minor_status = temp_minor_status; + gss_release_buffer( + &temp_minor_status, + output_token); + release_internal_name(&temp_minor_status, + &mech->mech_type, + &internal_name); + return(GSS_S_FAILURE); + } + + /* now create the union name */ + + temp_status = gss_import_name( + &temp_minor_status, + external_name, + name_type, + src_name); + + if(temp_status != GSS_S_COMPLETE) { + if (minor_status) + *minor_status = temp_minor_status; + gss_release_buffer( + &temp_minor_status, + output_token); + release_internal_name( + &temp_minor_status, + &mech->mech_type, + &internal_name); + gss_release_buffer( + &temp_minor_status, + external_name); + return(GSS_S_FAILURE); + } + + release_internal_name( + &temp_minor_status, + &mech->mech_type, + &internal_name); + gss_release_buffer( + &temp_minor_status, + external_name); + } + + if(*context_handle == GSS_C_NO_CONTEXT) + *context_handle = (gss_ctx_id_t *) union_ctx_id; + + return(status); + } + + return(GSS_S_BAD_MECH); +} diff --git a/src/lib/gssapi/mechglue/gss_acquire_cred.c b/src/lib/gssapi/mechglue/gss_acquire_cred.c new file mode 100644 index 000000000..3b1c5680b --- /dev/null +++ b/src/lib/gssapi/mechglue/gss_acquire_cred.c @@ -0,0 +1,271 @@ +#ident "@(#)gss_acquire_cred.c 1.19 95/08/07 SMI" +/* + * glue routine for gss_acquire_cred + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +OM_uint32 +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_status, + temp_minor_status, temp_time_rec = ~0; + int i, j, creds_acquired = 0; + 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_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; + + if (desired_name == GSS_C_NO_NAME) + return GSS_S_BAD_NAME; + + /* 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 desired_mechs equals GSS_C_NULL_OID_SET, set it to the + * first entry in the mechs_array. + */ + + if(desired_mechs == GSS_C_NULL_OID_SET) { + if ((mech = get_mechanism (NULL)) == 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. */ + + for(j=0; j < desired_mechs->count; j++) { + + creds_returned[j].available = 0; + + mech = get_mechanism (&desired_mechs->elements[j]); + if (mech && mech->gss_acquire_cred) { + + /* + * we first have to import the external name in + * union_name so it can be used in the + * gss_acquire_cred() call. + */ + + if ((status = import_internal_name( + minor_status, + &mech->mech_type, + union_name, + &internal_name))) { + status = GSS_S_BAD_NAME; + continue; + } + + status = mech->gss_acquire_cred( + mech->context, + minor_status, + internal_name, + time_req, + desired_mechs, + cred_usage, + &creds_returned[j].cred, + NULL, + &temp_time_rec); + + if ((temp_status = release_internal_name( + &temp_minor_status, + &mech->mech_type, + &internal_name))) { + /* Not much we can do here, really... Just keep on going */ + ; + } + + /* + * Add this into the creds_returned structure, if we got + * a good credential for this mechanism. + */ + if(status == GSS_S_COMPLETE) { + 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++; + } + } + } + + /* + * 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(GSS_S_BAD_MECH); + } + + 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; icount; 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; + + (*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 (gss_display_name(&temp_minor_status, desired_name, + &creds->auxinfo.name, &creds->auxinfo.name_type) + != GSS_S_COMPLETE) { + + /* This really shouldn't ever fail, but just in case.... */ + + for(i=0; i < creds->count; i++) { + free(creds->mechs_array[i].elements); + free((*actual_mechs)->elements[i].elements); + } + + 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(GSS_S_BAD_NAME); + } + + *output_cred_handle = (gss_cred_id_t) creds; + return(GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/mechglue/gss_compare_name.c b/src/lib/gssapi/mechglue/gss_compare_name.c new file mode 100644 index 000000000..b07ace599 --- /dev/null +++ b/src/lib/gssapi/mechglue/gss_compare_name.c @@ -0,0 +1,79 @@ +#ident "@(#)gss_compare_name.c 1.13 95/08/02 SMI" +/* + * glue routine for gss_compare_name + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +OM_uint32 +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 status; + gss_union_name_t union_name1, union_name2; + + gss_initialize(); + + if (name1 == GSS_C_NO_NAME || name2 == GSS_C_NO_NAME) { + if (name_equal) + *name_equal = 0; + return GSS_S_BAD_NAME; + } + + /* + * 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(). + */ + + union_name1 = (gss_union_name_t) name1; + union_name2 = (gss_union_name_t) name2; + + if(name_equal != NULL) + *name_equal = 1; + else + return(GSS_S_COMPLETE); + + status = GSS_S_COMPLETE; + + do { + if((union_name1->name_type->length != + union_name2->name_type->length) + || + (memcmp(union_name1->name_type->elements, + union_name2->name_type->elements, + union_name1->name_type->length) != 0)) { + + *name_equal = 0; + break; + } + + 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)) { + + *name_equal = 0; + break; + } + + } while (0); + + return(status); +} diff --git a/src/lib/gssapi/mechglue/gss_context_time.c b/src/lib/gssapi/mechglue/gss_context_time.c new file mode 100644 index 000000000..efcd5d607 --- /dev/null +++ b/src/lib/gssapi/mechglue/gss_context_time.c @@ -0,0 +1,53 @@ +#ident "@(#)gss_context_time.c 1.8 95/08/07 SMI" +/* + * glue routines for gss_context_time + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +OM_uint32 +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 = get_mechanism (ctx->mech_type); + + if (mech) { + + if (mech->gss_context_time) + status = mech->gss_context_time( + mech->context, + minor_status, + ctx->internal_ctx_id, + time_rec); + else + status = GSS_S_BAD_BINDINGS; + + return(status); + } + + return(GSS_S_NO_CONTEXT); +} diff --git a/src/lib/gssapi/mechglue/gss_delete_sec_context.c b/src/lib/gssapi/mechglue/gss_delete_sec_context.c new file mode 100644 index 000000000..69866bd04 --- /dev/null +++ b/src/lib/gssapi/mechglue/gss_delete_sec_context.c @@ -0,0 +1,62 @@ +#ident "@(#)gss_delete_sec_context.c 1.10 95/08/07 SMI" +/* + * glue routine for gss_delete_sec_context + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +OM_uint32 +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 = get_mechanism (ctx->mech_type); + + if (mech) { + + if (mech->gss_delete_sec_context) + status = mech->gss_delete_sec_context( + mech->context, + 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/src/lib/gssapi/mechglue/gss_display_name.c b/src/lib/gssapi/mechglue/gss_display_name.c new file mode 100644 index 000000000..4f1a27861 --- /dev/null +++ b/src/lib/gssapi/mechglue/gss_display_name.c @@ -0,0 +1,54 @@ +#ident "%Z%%M% %I% %E% SMI" +/* + * glue routine for gss_display_name() + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +OM_uint32 +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; + +{ + gss_union_name_t union_name; + + /* + * 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 (input_name == GSS_C_NO_NAME) + return GSS_S_BAD_NAME; + + union_name = (gss_union_name_t) input_name; + + if(output_name_type != NULL) + *output_name_type = union_name->name_type; + + 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/src/lib/gssapi/mechglue/gss_display_status.c b/src/lib/gssapi/mechglue/gss_display_status.c new file mode 100644 index 000000000..43decb6ba --- /dev/null +++ b/src/lib/gssapi/mechglue/gss_display_status.c @@ -0,0 +1,59 @@ +#ident "@(#)gss_display_status.c 1.8 95/08/07 SMI" +/* + * glue routine gss_display_status + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +OM_uint32 +gss_display_status (minor_status, + status_value, + status_type, + req_mech_type, + message_context, + status_string) + +OM_uint32 * minor_status; +int status_value; +int status_type; +const_gss_OID req_mech_type; +int * 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 = 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( + mech->context, + minor_status, + status_value, + status_type, + mech_type, + message_context, + status_string); + else + status = GSS_S_BAD_BINDINGS; + + return(status); +} diff --git a/src/lib/gssapi/mechglue/gss_import_name.c b/src/lib/gssapi/mechglue/gss_import_name.c new file mode 100644 index 000000000..6ec428df2 --- /dev/null +++ b/src/lib/gssapi/mechglue/gss_import_name.c @@ -0,0 +1,64 @@ +#ident "%Z%%M% %I% %E% SMI" +/* + * glue routine gss_import_name + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +OM_uint32 +gss_import_name(minor_status, + input_name_buffer, + input_name_type, + output_name) + +OM_uint32 * minor_status; +gss_buffer_t input_name_buffer; +const_gss_OID input_name_type; +gss_name_t * output_name; + +{ + gss_union_name_t union_name; + + if (minor_status) + *minor_status = 0; + + /* if output_name is NULL, simply return */ + + if(output_name == NULL) + return (GSS_S_COMPLETE); + + if (input_name_buffer == GSS_C_NO_BUFFER) + return (GSS_S_BAD_NAME); + + /* + * First create the union name struct that will hold the internal + * name and the mech_type. Then fill in the mech_type. + */ + + union_name = (gss_union_name_t) malloc (sizeof(gss_union_name_desc)); + + /* + * 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)); + union_name->external_name->length = input_name_buffer->length; + union_name->external_name->value = + (void *) malloc(input_name_buffer->length); + memcpy(union_name->external_name->value, input_name_buffer->value, + input_name_buffer->length); + + union_name->name_type = (gss_OID) input_name_type; + + *output_name = (gss_name_t) union_name; + + return(GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/mechglue/gss_indicate_mechs.c b/src/lib/gssapi/mechglue/gss_indicate_mechs.c new file mode 100644 index 000000000..3b8183e10 --- /dev/null +++ b/src/lib/gssapi/mechglue/gss_indicate_mechs.c @@ -0,0 +1,65 @@ +#ident "@(#)gss_indicate_mechs.c 1.13 95/08/04 SMI" +/* + * glue routine for gss_indicate_mechs + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +extern gss_mechanism *mechs_array; + +static gss_OID_set_desc supported_mechs_desc; +static gss_OID_set supported_mechs = NULL; + +OM_uint32 +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; 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 = + mechs_array[i]->mech_type.length; + supported_mechs->elements[i].elements = (void *) + malloc(mechs_array[i]->mech_type.length); + memcpy(supported_mechs->elements[i].elements, + mechs_array[i]->mech_type.elements, + mechs_array[i]->mech_type.length); + } + } + + if(mech_set != NULL) + *mech_set = supported_mechs; + + return(GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/mechglue/gss_init_sec_context.c b/src/lib/gssapi/mechglue/gss_init_sec_context.c new file mode 100644 index 000000000..ed6f81fbb --- /dev/null +++ b/src/lib/gssapi/mechglue/gss_init_sec_context.c @@ -0,0 +1,147 @@ +#ident "@(#)gss_init_sec_context.c 1.20 95/08/07 SMI" +/* + * glue routine for gss_init_sec_context + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +OM_uint32 +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; +const_gss_OID req_mech_type; +int req_flags; +int time_req; +gss_channel_bindings_t input_chan_bindings; +gss_buffer_t input_token; +gss_OID * actual_mech_type; +gss_buffer_t output_token; +int * ret_flags; +OM_uint32 * time_rec; + +{ + OM_uint32 status, temp_status, temp_minor_status; + gss_union_name_t union_name; + 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_initialize(); + + if (context_handle == NULL) + return GSS_S_NO_CONTEXT; + + /* + * obtain the gss mechanism information for the requested + * mechanism. If mech_type is NULL, set it to the resultant + * mechanism + */ + mech = get_mechanism (mech_type); + if (mech == NULL) + return (GSS_S_BAD_MECH); + + if (mech_type == GSS_C_NULL_OID) + mech_type = &mech->mech_type; + + /* + * Get the internal name for the mechanism requested from + * the supplied target name. + */ + + union_name = (gss_union_name_t) target_name; + + if ((temp_status = 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; + + /* + * now call the approprate underlying mechanism routine + */ + + if (mech->gss_init_sec_context) { + status = mech->gss_init_sec_context( + mech->context, + minor_status, + claimant_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; + + temp_status = release_internal_name( + &temp_minor_status, + mech_type, + &internal_name); + + if (temp_status != GSS_S_COMPLETE) { + if (minor_status) + *minor_status = temp_minor_status; + return(GSS_S_BAD_NAME); + } + + return(status); +} diff --git a/src/lib/gssapi/mechglue/gss_initialize.c b/src/lib/gssapi/mechglue/gss_initialize.c new file mode 100644 index 000000000..a6e7ed101 --- /dev/null +++ b/src/lib/gssapi/mechglue/gss_initialize.c @@ -0,0 +1,34 @@ +#ident "@(#)gss_initialize.c 1.5 95/09/11 SMI" +/* + * This function will initialize the gssapi mechglue library + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +static int _gss_initialized = 0; + +void gss_initialize (void) +{ + gss_mechanism mech; + + /* Make sure we've not run already */ + if (_gss_initialized) + return; + _gss_initialized = 1; + + /* + * 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); + + return; +} diff --git a/src/lib/gssapi/mechglue/gss_inquire_cred.c b/src/lib/gssapi/mechglue/gss_inquire_cred.c new file mode 100644 index 000000000..460e8c3ae --- /dev/null +++ b/src/lib/gssapi/mechglue/gss_inquire_cred.c @@ -0,0 +1,104 @@ +#ident "@(#)gss_inquire_cred.c 1.9 95/08/02 SMI" +/* + * glue routine for gss_inquire_cred + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +OM_uint32 +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; + int i; + + gss_initialize(); + + if(cred_handle == GSS_C_NO_CREDENTIAL) + + /* This action doesn't conform to the spec. We are supposed + * to return information about the default credential. + * However, we don't know what mechanism the default + * credential is associated with, so we can't call + * the mechanism specific version of gss_inquire_cred(). + * Consequently, we just return NO_CRED. + */ + + return(GSS_S_NO_CRED); + else + + /* 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); +} diff --git a/src/lib/gssapi/mechglue/gss_process_context.c b/src/lib/gssapi/mechglue/gss_process_context.c new file mode 100644 index 000000000..e44e41649 --- /dev/null +++ b/src/lib/gssapi/mechglue/gss_process_context.c @@ -0,0 +1,53 @@ +#ident "@(#)gss_process_context.c 1.9 95/08/07 SMI" +/* + * glue routine gss_process_context + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +OM_uint32 +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 = get_mechanism (ctx->mech_type); + + if (mech) { + + if (mech->gss_process_context_token) + status = mech->gss_process_context_token( + mech->context, + minor_status, + ctx->internal_ctx_id, + token_buffer); + else + status = GSS_S_BAD_BINDINGS; + + return(status); + } + + return(GSS_S_NO_CONTEXT); +} diff --git a/src/lib/gssapi/mechglue/gss_release_buffer.c b/src/lib/gssapi/mechglue/gss_release_buffer.c new file mode 100644 index 000000000..99ed4d5a8 --- /dev/null +++ b/src/lib/gssapi/mechglue/gss_release_buffer.c @@ -0,0 +1,34 @@ +#ident "%Z%%M% %I% %E% SMI" +/* + * glue routine for gss_release_buffer + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +OM_uint32 +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/src/lib/gssapi/mechglue/gss_release_cred.c b/src/lib/gssapi/mechglue/gss_release_cred.c new file mode 100644 index 000000000..2ef94276c --- /dev/null +++ b/src/lib/gssapi/mechglue/gss_release_cred.c @@ -0,0 +1,74 @@ +#ident "@(#)gss_release_cred.c 1.15 95/08/07 SMI" +/* + * glue routine for gss_release_cred + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +OM_uint32 +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 = get_mechanism (&union_cred->mechs_array[j]); + + if (mech) { + + if (mech->gss_release_cred) { + temp_status = mech->gss_release_cred + (mech->context, + 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; + } + + free(union_cred->cred_array); + free(union_cred->mechs_array); + free(union_cred); + + return(status); +} diff --git a/src/lib/gssapi/mechglue/gss_release_name.c b/src/lib/gssapi/mechglue/gss_release_name.c new file mode 100644 index 000000000..87b7d3126 --- /dev/null +++ b/src/lib/gssapi/mechglue/gss_release_name.c @@ -0,0 +1,43 @@ +#ident "@(#)gss_release_name.c 1.2 95/05/09 SMI" +/* + * glue routine for gss_release_name + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +OM_uint32 +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 */ + + if(input_name == GSS_C_NO_NAME) + 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 = GSS_C_NO_NAME; + *minor_status = 0; + + if (union_name == NULL) + return GSS_S_BAD_NAME; + + free(union_name->external_name->value); + free(union_name->external_name); + free(union_name); + + return(GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/mechglue/gss_release_oid_set.c b/src/lib/gssapi/mechglue/gss_release_oid_set.c new file mode 100644 index 000000000..3a98df27d --- /dev/null +++ b/src/lib/gssapi/mechglue/gss_release_oid_set.c @@ -0,0 +1,33 @@ +#ident "@(#)gss_release_oid_set.c 1.12 95/08/23 SMI" +/* + * glue routine for gss_release_oid_set + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +OM_uint32 +gss_release_oid_set (minor_status, + set) + +OM_uint32 * minor_status; +gss_OID_set * set; +{ + if (minor_status) + *minor_status = 0; + + if (set ==NULL) + return GSS_S_COMPLETE; + + if (*set == GSS_C_NULL_OID_SET) + return(GSS_S_COMPLETE); + + free((*set)->elements); + free(*set); + + *set = GSS_C_NULL_OID_SET; + + return(GSS_S_COMPLETE); +} diff --git a/src/lib/gssapi/mechglue/gss_seal.c b/src/lib/gssapi/mechglue/gss_seal.c new file mode 100644 index 000000000..47cb5c5c5 --- /dev/null +++ b/src/lib/gssapi/mechglue/gss_seal.c @@ -0,0 +1,64 @@ +#ident "@(#)gss_seal.c 1.10 95/08/07 SMI" +/* + * glue routine for gss_seal + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +OM_uint32 +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 = get_mechanism (ctx->mech_type); + + if (mech) { + if (mech->gss_seal) + status = mech->gss_seal( + mech->context, + 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); +} diff --git a/src/lib/gssapi/mechglue/gss_sign.c b/src/lib/gssapi/mechglue/gss_sign.c new file mode 100644 index 000000000..ba00f28a7 --- /dev/null +++ b/src/lib/gssapi/mechglue/gss_sign.c @@ -0,0 +1,58 @@ +#ident "@(#)gss_sign.c 1.10 95/08/07 SMI" +/* + * glue routine gss_sign + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +OM_uint32 +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 = get_mechanism (ctx->mech_type); + + if (mech) { + if (mech->gss_sign) + status = mech->gss_sign( + mech->context, + 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); +} diff --git a/src/lib/gssapi/mechglue/gss_unseal.c b/src/lib/gssapi/mechglue/gss_unseal.c new file mode 100644 index 000000000..97d19a59e --- /dev/null +++ b/src/lib/gssapi/mechglue/gss_unseal.c @@ -0,0 +1,61 @@ +#ident "@(#)gss_unseal.c 1.10 95/08/07 SMI" +/* + * glue routine gss_unseal + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +OM_uint32 +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 = get_mechanism (ctx->mech_type); + + if (mech) { + if (mech->gss_unseal) + status = mech->gss_unseal( + mech->context, + 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); +} diff --git a/src/lib/gssapi/mechglue/gss_verify.c b/src/lib/gssapi/mechglue/gss_verify.c new file mode 100644 index 000000000..50784930b --- /dev/null +++ b/src/lib/gssapi/mechglue/gss_verify.c @@ -0,0 +1,58 @@ +#ident "@(#)gss_verify.c 1.9 95/08/07 SMI" +/* + * glue routine for gss_verify + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +OM_uint32 +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 = get_mechanism (ctx->mech_type); + + if (mech) { + if (mech->gss_verify) + status = mech->gss_verify( + mech->context, + 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); +} diff --git a/src/lib/gssapi/mechglue/gssd_pname_to_uid.c b/src/lib/gssapi/mechglue/gssd_pname_to_uid.c new file mode 100644 index 000000000..da0da92c7 --- /dev/null +++ b/src/lib/gssapi/mechglue/gssd_pname_to_uid.c @@ -0,0 +1,45 @@ +#ident "@(#)gssd_pname_to_uid.c 1.5 95/08/02 SMI" +/* + * 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. + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.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 = get_mechanism (mech_type); + + if (mech) { + if (mech_type == GSS_C_NULL_OID) + mech_type = &mech->mech_type; + + if (mech->pname_to_uid) + status = mech->pname_to_uid(pname, name_type, mech_type, uid); + else + status = GSS_S_BAD_MECH; + } else + status = GSS_S_BAD_MECH; + + return(status); +} diff --git a/src/lib/gssapi/mechglue/internal_name.c b/src/lib/gssapi/mechglue/internal_name.c new file mode 100644 index 000000000..0fba73fdb --- /dev/null +++ b/src/lib/gssapi/mechglue/internal_name.c @@ -0,0 +1,90 @@ +#ident "@(#)internal_name.c 1.5 95/08/07 SMI" +/* + * Internal routines to get and release an internal mechanism name + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#include "mechglueP.h" + +OM_uint32 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 = get_mechanism (mech_type); + if (mech) { + if (mech->gss_import_name) + status = mech->gss_import_name ( + mech->context, + 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 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 = get_mechanism (mech_type); + if (mech) { + if (mech->gss_display_name) + status = mech->gss_display_name ( + mech->context, + minor_status, + internal_name, + external_name, + name_type); + else + status = GSS_S_BAD_BINDINGS; + + return (status); + } + + return (GSS_S_BAD_MECH); +} + +OM_uint32 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 = get_mechanism (mech_type); + if (mech) { + if (mech->gss_release_name) + status = mech->gss_release_name ( + mech->context, + minor_status, + internal_name); + else + status = GSS_S_BAD_BINDINGS; + + return (status); + } + + return (GSS_S_BAD_MECH); +} diff --git a/src/lib/gssapi/mechglue/mechglue.h b/src/lib/gssapi/mechglue/mechglue.h new file mode 100644 index 000000000..304bcfb66 --- /dev/null +++ b/src/lib/gssapi/mechglue/mechglue.h @@ -0,0 +1,22 @@ +#ident "@(#)mechglue.h 1.13 95/08/07 SMI" +/* + * This header contains the mechglue definitions. + * + * Copyright (c) 1995, by Sun Microsystems, Inc. + * All rights reserved. + */ + +#ifndef _GSS_MECHGLUE_H +#define _GSS_MECHGLUE_H + +#include +#include + +/********************************************************/ +/* 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); + +#endif /* _GSS_MECHGLUE_H */ diff --git a/src/lib/gssapi/mechglue/mechglueP.h b/src/lib/gssapi/mechglue/mechglueP.h new file mode 100644 index 000000000..34f007f28 --- /dev/null +++ b/src/lib/gssapi/mechglue/mechglueP.h @@ -0,0 +1,239 @@ +#ident "%Z%%M% %I% %E% 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 +#include + +/* + * 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; + +/* + * Array of names typed by the name OID (XXX - mechanism OID?) + */ +typedef struct gss_union_name_t { + gss_OID name_type; + gss_buffer_t external_name; +} gss_union_name_desc, *gss_union_name_t; + +/* + * 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) + (void*, /* context */ + 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) + (void*, /* context */ + OM_uint32*, /* minor_status */ + gss_cred_id_t* /* cred_handle */ + ); + OM_uint32 (*gss_init_sec_context) + (void*, /* context */ + OM_uint32*, /* minor_status */ + gss_cred_id_t, /* claimant_cred_handle */ + gss_ctx_id_t*, /* context_handle */ + gss_name_t, /* target_name */ + const_gss_OID, /* mech_type */ + int, /* 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 */ + int*, /* ret_flags */ + OM_uint32* /* time_rec */ + ); + OM_uint32 (*gss_accept_sec_context) + (void*, /* context */ + 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 */ + int*, /* ret_flags */ + OM_uint32*, /* time_rec */ + gss_cred_id_t* /* delegated_cred_handle */ + ); + OM_uint32 (*gss_process_context_token) + (void*, /* context */ + OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + gss_buffer_t /* token_buffer */ + ); + OM_uint32 (*gss_delete_sec_context) + (void*, /* context */ + OM_uint32*, /* minor_status */ + gss_ctx_id_t*, /* context_handle */ + gss_buffer_t /* output_token */ + ); + OM_uint32 (*gss_context_time) + (void*, /* context */ + OM_uint32*, /* minor_status */ + gss_ctx_id_t, /* context_handle */ + OM_uint32* /* time_rec */ + ); + OM_uint32 (*gss_sign) + (void*, /* context */ + 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) + (void*, /* context */ + 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) + (void*, /* context */ + 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) + (void*, /* context */ + 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) + (void*, /* context */ + OM_uint32*, /* minor_status */ + OM_uint32, /* status_value */ + int, /* status_type */ + const_gss_OID, /* mech_type */ + int*, /* message_context */ + gss_buffer_t /* status_string */ + ); + OM_uint32 (*gss_indicate_mechs) + (void*, /* context */ + OM_uint32*, /* minor_status */ + gss_OID_set* /* mech_set */ + ); + OM_uint32 (*gss_compare_name) + (void*, /* context */ + OM_uint32*, /* minor_status */ + gss_name_t, /* name1 */ + gss_name_t, /* name2 */ + int* /* name_equal */ + ); + OM_uint32 (*gss_display_name) + (void*, /* context */ + 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) + (void*, /* context */ + OM_uint32*, /* minor_status */ + gss_buffer_t, /* input_name_buffer */ + const_gss_OID, /* input_name_type */ + gss_name_t* /* output_name */ + ); + OM_uint32 (*gss_release_name) + (void*, /* context */ + OM_uint32*, /* minor_status */ + gss_name_t* /* input_name */ + ); + OM_uint32 (*gss_inquire_cred) + (void*, /* context */ + OM_uint32 *, /* minor_status */ + gss_cred_id_t, /* cred_handle */ + gss_name_t *, /* name */ + OM_uint32 *, /* lifetime */ + int *, /* cred_usage */ + gss_OID_set * /* mechanisms */ + ); + int (*pname_to_uid) + (char *, /* pname */ + gss_OID, /* name type */ + gss_OID, /* mech type */ + uid_t * /* uid */ + ); +} *gss_mechanism; + +/********************************************************/ +/* Internal mechglue routines */ + +gss_mechanism get_mechanism (const_gss_OID); +OM_uint32 add_mechanism (gss_mechanism, int); +OM_uint32 get_mech_type(gss_OID *, gss_buffer_t); +OM_uint32 import_internal_name (OM_uint32 *, gss_OID, gss_union_name_t, + gss_name_t *); +OM_uint32 display_internal_name (OM_uint32 *, gss_OID, gss_name_t, + gss_buffer_t, gss_OID *); +OM_uint32 release_internal_name (OM_uint32 *, gss_OID, gss_name_t *); + +#endif /* _GSS_MECHGLUEP_H */