MIT SPI compat
authorLuke Howard <lukeh@padl.com>
Sun, 2 Jan 2011 09:30:57 +0000 (20:30 +1100)
committerLuke Howard <lukeh@padl.com>
Sun, 2 Jan 2011 09:30:57 +0000 (20:30 +1100)
lib/gssapi/Makefile.am
lib/gssapi/gssapi/gssapi.h
lib/gssapi/gssapi_mech.h
lib/gssapi/mech/cred.h
lib/gssapi/mech/gss_acquire_cred_with_password.c [new file with mode: 0644]
lib/gssapi/mech/gss_add_cred.c
lib/gssapi/mech/gss_add_cred_with_password.c [new file with mode: 0644]
lib/gssapi/mech/gss_mech_switch.c
lib/gssapi/version-script.map

index c74906103273d2308c5210c84fb9b2c6889d3d40..a380672c6c7240b6f5f97bd73e3ffb6d4f10779c 100644 (file)
@@ -80,7 +80,9 @@ mechsrc = \
        mech/doxygen.c \
        mech/gss_accept_sec_context.c \
        mech/gss_acquire_cred.c \
+       mech/gss_acquire_cred_with_password.c \
        mech/gss_add_cred.c \
+       mech/gss_add_cred_with_password.c \
        mech/gss_add_oid_set_member.c \
        mech/gss_aeap.c \
        mech/gss_buffer_set.c \
index 12833ebe149d4b1812001c0b42aa4bba16ff29e9..5739e91e866ee479a60d9c15d11cdc1808cc41d9 100644 (file)
@@ -986,6 +986,36 @@ gss_display_mech_attr(OM_uint32 * minor_status,
                      gss_buffer_t short_desc,
                      gss_buffer_t long_desc);
 
+/*
+ * Solaris compat
+ */
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_acquire_cred_with_password
+           (OM_uint32 * /*minor_status*/,
+            const gss_name_t /*desired_name*/,
+            const gss_buffer_t /*password*/,
+            OM_uint32 /*time_req*/,
+            const gss_OID_set /*desired_mechs*/,
+            gss_cred_usage_t /*cred_usage*/,
+            gss_cred_id_t * /*output_cred_handle*/,
+            gss_OID_set * /*actual_mechs*/,
+            OM_uint32 * /*time_rec*/
+           );
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL gss_add_cred_with_password (
+            OM_uint32 * /*minor_status*/,
+            const gss_cred_id_t /*input_cred_handle*/,
+            const gss_name_t /*desired_name*/,
+            const gss_OID /*desired_mech*/,
+            const gss_buffer_t /*password*/,
+            gss_cred_usage_t /*cred_usage*/,
+            OM_uint32 /*initiator_time_req*/,
+            OM_uint32 /*acceptor_time_req*/,
+            gss_cred_id_t * /*output_cred_handle*/,
+            gss_OID_set * /*actual_mechs*/,
+            OM_uint32 * /*initiator_time_rec*/,
+            OM_uint32 * /*acceptor_time_rec*/
+           );
 
 /*
  *
index b06e60a82f3efcce365241e30352a08c0ef1d3f3..9fe195cd26205c17d2b0d75cdef371cee90ce173 100644 (file)
@@ -406,8 +406,35 @@ struct gss_mo_desc_struct {
     int (*set)(gss_const_OID, gss_mo_desc *, int, gss_buffer_t);
 };
 
+typedef OM_uint32 GSSAPI_CALLCONV _gss_acquire_cred_with_password_t
+             (OM_uint32 *,            /* minor_status */
+              const gss_name_t,       /* desired_name */
+              const gss_buffer_t,     /* password */
+              OM_uint32,              /* time_req */
+              const gss_OID_set,      /* desired_mechs */
+              gss_cred_usage_t,       /* cred_usage */
+              gss_cred_id_t *,        /* output_cred_handle */
+              gss_OID_set *,          /* actual_mechs */
+              OM_uint32 *             /* time_rec */
+             );
+
+
+typedef OM_uint32 GSSAPI_CALLCONV _gss_add_cred_with_password_t (
+              OM_uint32 *,            /* minor_status */
+              const gss_cred_id_t,    /* input_cred_handle */
+              const gss_name_t,       /* desired_name */
+              const gss_OID,          /* desired_mech */
+              const gss_buffer_t,     /* password */
+              gss_cred_usage_t,       /* cred_usage */
+              OM_uint32,              /* initiator_time_req */
+              OM_uint32,              /* acceptor_time_req */
+              gss_cred_id_t *,        /* output_cred_handle */
+              gss_OID_set *,          /* actual_mechs */
+              OM_uint32 *,            /* initiator_time_rec */
+              OM_uint32 *             /* acceptor_time_rec */
+             );
 
-#define GMI_VERSION 4
+#define GMI_VERSION 5
 
 /* gm_flags */
 #define GM_USE_MG_CRED         1       /* uses mech glue credentials */
@@ -467,6 +494,8 @@ typedef struct gssapi_mech_interface_desc {
        _gss_cred_label_set_t           *gm_cred_label_set;
         gss_mo_desc                    *gm_mo;
         size_t                          gm_mo_num;
+        _gss_acquire_cred_with_password_t  *gm_acquire_cred_with_password;
+        _gss_add_cred_with_password_t   *gm_add_cred_with_password;
 } gssapi_mech_interface_desc, *gssapi_mech_interface;
 
 gssapi_mech_interface
index adffe6893e5af6114959d9e5a72e88337f734179..5d6430f69cddc091a7abff31e2592feb05849b76 100644 (file)
@@ -39,3 +39,6 @@ struct _gss_cred {
        struct _gss_mechanism_cred_list gc_mc;
 };
 
+struct _gss_mechanism_cred *
+_gss_copy_cred(struct _gss_mechanism_cred *mc);
+
diff --git a/lib/gssapi/mech/gss_acquire_cred_with_password.c b/lib/gssapi/mech/gss_acquire_cred_with_password.c
new file mode 100644 (file)
index 0000000..d551abc
--- /dev/null
@@ -0,0 +1,169 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     $FreeBSD: src/lib/libgssapi/gss_acquire_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_acquire_cred_with_password(OM_uint32 *minor_status,
+    const gss_name_t desired_name,
+    const gss_buffer_t password,
+    OM_uint32 time_req,
+    const gss_OID_set desired_mechs,
+    gss_cred_usage_t cred_usage,
+    gss_cred_id_t *output_cred_handle,
+    gss_OID_set *actual_mechs,
+    OM_uint32 *time_rec)
+{
+       OM_uint32 major_status;
+       gss_OID_set mechs = desired_mechs;
+       gss_OID_set_desc set;
+       struct _gss_name *name = (struct _gss_name *) desired_name;
+       gssapi_mech_interface m;
+       struct _gss_cred *cred;
+       struct _gss_mechanism_cred *mc;
+       OM_uint32 min_time, cred_time;
+       int i;
+
+       *minor_status = 0;
+       if (output_cred_handle == NULL)
+           return GSS_S_CALL_INACCESSIBLE_READ;
+       if (actual_mechs)
+           *actual_mechs = GSS_C_NO_OID_SET;
+       if (time_rec)
+           *time_rec = 0;
+
+       _gss_load_mech();
+
+       /*
+        * First make sure that at least one of the requested
+        * mechanisms is one that we support.
+        */
+       if (mechs) {
+               for (i = 0; i < mechs->count; i++) {
+                       int t;
+                       gss_test_oid_set_member(minor_status,
+                           &mechs->elements[i], _gss_mech_oids, &t);
+                       if (t)
+                               break;
+               }
+               if (i == mechs->count) {
+                       *minor_status = 0;
+                       return (GSS_S_BAD_MECH);
+               }
+       }
+
+       if (actual_mechs) {
+               major_status = gss_create_empty_oid_set(minor_status,
+                   actual_mechs);
+               if (major_status)
+                       return (major_status);
+       }
+
+       cred = malloc(sizeof(struct _gss_cred));
+       if (!cred) {
+               if (actual_mechs)
+                       gss_release_oid_set(minor_status, actual_mechs);
+               *minor_status = ENOMEM;
+               return (GSS_S_FAILURE);
+       }
+       HEIM_SLIST_INIT(&cred->gc_mc);
+
+       if (mechs == GSS_C_NO_OID_SET)
+               mechs = _gss_mech_oids;
+
+       set.count = 1;
+       min_time = GSS_C_INDEFINITE;
+       for (i = 0; i < mechs->count; i++) {
+               struct _gss_mechanism_name *mn = NULL;
+
+               m = __gss_get_mechanism(&mechs->elements[i]);
+               if (!m || !m->gm_acquire_cred_with_password)
+                       continue;
+
+               if (desired_name != GSS_C_NO_NAME) {
+                       major_status = _gss_find_mn(minor_status, name,
+                                                   &mechs->elements[i], &mn);
+                       if (major_status != GSS_S_COMPLETE)
+                               continue;
+               }
+
+               mc = malloc(sizeof(struct _gss_mechanism_cred));
+               if (!mc) {
+                       continue;
+               }
+               mc->gmc_mech = m;
+               mc->gmc_mech_oid = &m->gm_mech_oid;
+
+               /*
+                * XXX Probably need to do something with actual_mechs.
+                */
+               set.elements = &mechs->elements[i];
+               major_status = m->gm_acquire_cred_with_password(minor_status,
+                   (desired_name != GSS_C_NO_NAME
+                       ? mn->gmn_name : GSS_C_NO_NAME),
+                   password, time_req, &set, cred_usage,
+                   &mc->gmc_cred, NULL, &cred_time);
+               if (major_status) {
+                       free(mc);
+                       continue;
+               }
+               if (cred_time < min_time)
+                       min_time = cred_time;
+
+               if (actual_mechs) {
+                       major_status = gss_add_oid_set_member(minor_status,
+                           mc->gmc_mech_oid, actual_mechs);
+                       if (major_status) {
+                               m->gm_release_cred(minor_status,
+                                   &mc->gmc_cred);
+                               free(mc);
+                               continue;
+                       }
+               }
+
+               HEIM_SLIST_INSERT_HEAD(&cred->gc_mc, mc, gmc_link);
+       }
+
+       /*
+        * If we didn't manage to create a single credential, return
+        * an error.
+        */
+       if (!HEIM_SLIST_FIRST(&cred->gc_mc)) {
+               free(cred);
+               if (actual_mechs)
+                       gss_release_oid_set(minor_status, actual_mechs);
+               *minor_status = 0;
+               return (GSS_S_NO_CRED);
+       }
+
+       if (time_rec)
+               *time_rec = min_time;
+       *output_cred_handle = (gss_cred_id_t) cred;
+       *minor_status = 0;
+       return (GSS_S_COMPLETE);
+}
index 19deea5b062b9fc8b88b8325bf08211e88c63452..a998bc60ff800470dfe68487df01f41e51a9c058 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "mech_locl.h"
 
-static struct _gss_mechanism_cred *
+struct _gss_mechanism_cred *
 _gss_copy_cred(struct _gss_mechanism_cred *mc)
 {
        struct _gss_mechanism_cred *new_mc;
diff --git a/lib/gssapi/mech/gss_add_cred_with_password.c b/lib/gssapi/mech/gss_add_cred_with_password.c
new file mode 100644 (file)
index 0000000..a0dc9f0
--- /dev/null
@@ -0,0 +1,151 @@
+/*-
+ * Copyright (c) 2005 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     $FreeBSD: src/lib/libgssapi/gss_add_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
+ */
+
+#include "mech_locl.h"
+
+GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
+gss_add_cred_with_password(OM_uint32 *minor_status,
+    const gss_cred_id_t input_cred_handle,
+    const gss_name_t desired_name,
+    const gss_OID desired_mech,
+    const gss_buffer_t password,
+    gss_cred_usage_t cred_usage,
+    OM_uint32 initiator_time_req,
+    OM_uint32 acceptor_time_req,
+    gss_cred_id_t *output_cred_handle,
+    gss_OID_set *actual_mechs,
+    OM_uint32 *initiator_time_rec,
+    OM_uint32 *acceptor_time_rec)
+{
+       OM_uint32 major_status;
+       gssapi_mech_interface m;
+       struct _gss_cred *cred = (struct _gss_cred *) input_cred_handle;
+       struct _gss_cred *new_cred;
+       gss_cred_id_t release_cred;
+       struct _gss_mechanism_cred *mc, *target_mc, *copy_mc;
+       struct _gss_mechanism_name *mn;
+       OM_uint32 junk;
+
+       *minor_status = 0;
+       *output_cred_handle = GSS_C_NO_CREDENTIAL;
+       if (initiator_time_rec)
+           *initiator_time_rec = 0;
+       if (acceptor_time_rec)
+           *acceptor_time_rec = 0;
+       if (actual_mechs)
+           *actual_mechs = GSS_C_NO_OID_SET;
+
+       new_cred = malloc(sizeof(struct _gss_cred));
+       if (!new_cred) {
+               *minor_status = ENOMEM;
+               return (GSS_S_FAILURE);
+       }
+       HEIM_SLIST_INIT(&new_cred->gc_mc);
+
+       /*
+        * We go through all the mc attached to the input_cred_handle
+        * and check the mechanism. If it matches, we call
+        * gss_add_cred for that mechanism, otherwise we copy the mc
+        * to new_cred.
+        */
+       target_mc = 0;
+       if (cred) {
+               HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
+                       if (gss_oid_equal(mc->gmc_mech_oid, desired_mech)) {
+                               target_mc = mc;
+                       }
+                       copy_mc = _gss_copy_cred(mc);
+                       if (!copy_mc) {
+                               release_cred = (gss_cred_id_t)new_cred;
+                               gss_release_cred(&junk, &release_cred);
+                               *minor_status = ENOMEM;
+                               return (GSS_S_FAILURE);
+                       }
+                       HEIM_SLIST_INSERT_HEAD(&new_cred->gc_mc, copy_mc, gmc_link);
+               }
+       }
+
+       /*
+        * Figure out a suitable mn, if any.
+        */
+       if (desired_name) {
+               major_status = _gss_find_mn(minor_status,
+                                           (struct _gss_name *) desired_name,
+                                           desired_mech,
+                                           &mn);
+               if (major_status != GSS_S_COMPLETE) {
+                       free(new_cred);
+                       return major_status;
+               }
+       } else {
+               mn = 0;
+       }
+
+       m = __gss_get_mechanism(desired_mech);
+       if (m->gm_add_cred_with_password == NULL) {
+               release_cred = (gss_cred_id_t)new_cred;
+               gss_release_cred(&junk, &release_cred);
+               return (GSS_S_UNAVAILABLE);
+       }
+
+       mc = malloc(sizeof(struct _gss_mechanism_cred));
+       if (!mc) {
+               release_cred = (gss_cred_id_t)new_cred;
+               gss_release_cred(&junk, &release_cred);
+               *minor_status = ENOMEM;
+               return (GSS_S_FAILURE);
+       }
+       mc->gmc_mech = m;
+       mc->gmc_mech_oid = &m->gm_mech_oid;
+
+       major_status = m->gm_add_cred_with_password(minor_status,
+           target_mc ? target_mc->gmc_cred : GSS_C_NO_CREDENTIAL,
+           desired_name ? mn->gmn_name : GSS_C_NO_NAME,
+           password,
+           desired_mech,
+           cred_usage,
+           initiator_time_req,
+           acceptor_time_req,
+           &mc->gmc_cred,
+           actual_mechs,
+           initiator_time_rec,
+           acceptor_time_rec);
+
+       if (major_status) {
+               _gss_mg_error(m, major_status, *minor_status);
+               release_cred = (gss_cred_id_t)new_cred;
+               gss_release_cred(&junk, &release_cred);
+               free(mc);
+               return (major_status);
+       }
+       HEIM_SLIST_INSERT_HEAD(&new_cred->gc_mc, mc, gmc_link);
+       *output_cred_handle = (gss_cred_id_t) new_cred;
+
+       return (GSS_S_COMPLETE);
+}
+
index 48444a8fada5ecc30c3c4f10dad84e21b21a3a3e..6da7411a947a106b4f86c0d2dc9c3ac366e78718 100644 (file)
@@ -160,7 +160,12 @@ do {                                                                       \
 
 #define OPTSYM(name)                                                   \
 do {                                                                   \
-       m->gm_mech.gm_ ## name = dlsym(so, "gss_" #name);                       \
+       m->gm_mech.gm_ ## name = dlsym(so, "gss_" #name);               \
+} while (0)
+
+#define OPTSPISYM(name)                                                        \
+do {                                                                   \
+       m->gm_mech.gm_ ## name = dlsym(so, "gssspi_" #name);            \
 } while (0)
 
 /*
@@ -332,11 +337,22 @@ _gss_load_mech(void)
                OPTSYM(inquire_cred_by_oid);
                OPTSYM(inquire_sec_context_by_oid);
                OPTSYM(set_sec_context_option);
-               OPTSYM(set_cred_option);
+               OPTSPISYM(set_cred_option);
                OPTSYM(pseudo_random);
                OPTSYM(wrap_iov);
                OPTSYM(unwrap_iov);
                OPTSYM(wrap_iov_length);
+               OPTSPISYM(acquire_cred_with_password);
+               OPTSYM(add_cred_with_password);
+
+               /* pick up the oid sets of names */
+
+               if (m->gm_mech.gm_inquire_names_for_mech)
+                       (*m->gm_mech.gm_inquire_names_for_mech)(&minor_status,
+                       &m->gm_mech.gm_mech_oid, &m->gm_name_types);
+
+               if (m->gm_name_types == NULL)
+                       gss_create_empty_oid_set(&minor_status, &m->gm_name_types);
 
                HEIM_SLIST_INSERT_HEAD(&_gss_mechs, m, gm_link);
                continue;
index 087b29a50011ea181986e915687c3ac28349ca16..c0f6dcb62f62acbb2b339ee883fe9844577b62de 100644 (file)
@@ -13,8 +13,10 @@ HEIMDAL_GSS_2.0 {
                __gss_c_attr_stream_sizes_oid_desc;
                gss_accept_sec_context;
                gss_acquire_cred;
+               gss_acquire_cred_with_password;
                gss_add_buffer_set_member;
                gss_add_cred;
+               gss_add_cred_with_password;
                gss_add_oid_set_member;
                gss_canonicalize_name;
                gss_compare_name;