--- /dev/null
+/*
+ * 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