Make it possible to disable Shibboleth
authorLuke Howard <lukeh@padl.com>
Wed, 22 Sep 2010 08:04:26 +0000 (10:04 +0200)
committerLuke Howard <lukeh@padl.com>
Wed, 22 Sep 2010 08:04:26 +0000 (10:04 +0200)
mech_eap/eap_mech.c
mech_eap/gssapiP_eap.h
mech_eap/gssapi_eap.h
mech_eap/mech_eap.exports
mech_eap/set_cred_option.c
mech_eap/util_attr.cpp
mech_eap/util_attr.h

index 5cd5f6a..ea43ad3 100644 (file)
@@ -298,3 +298,4 @@ gssEapFinalize(void)
     eap_peer_unregister_methods();
     eap_server_unregister_methods();
 }
+
index 99665b6..9b8247d 100644 (file)
@@ -77,12 +77,11 @@ struct gss_name_struct {
     struct gss_eap_attr_ctx *attrCtx;
 };
 
-#define CRED_FLAG_INITIATE                  0x00000001
-#define CRED_FLAG_ACCEPT                    0x00000002
-#define CRED_FLAG_DEFAULT_IDENTITY          0x00000004
-#define CRED_FLAG_PASSWORD                  0x00000008
-#define CRED_FLAG_DISABLE_LOCAL_ATTRS       0x00010000
-#define CRED_FLAG_SET_CRED_OPTION_MASK      0x00FF0000
+#define CRED_FLAG_INITIATE                  0x00010000
+#define CRED_FLAG_ACCEPT                    0x00020000
+#define CRED_FLAG_DEFAULT_IDENTITY          0x00040000
+#define CRED_FLAG_PASSWORD                  0x00080000
+#define CRED_FLAG_PUBLIC_MASK               0x0000FFFF
 
 struct gss_cred_id_struct {
     GSSEAP_MUTEX mutex;
index 5e121f5..4ae9e08 100644 (file)
@@ -46,8 +46,10 @@ extern gss_OID GSS_EAP_AES256_CTS_HMAC_SHA1_96_MECHANISM;
 /* name type */
 extern gss_OID GSS_EAP_NT_PRINCIPAL_NAME;
 
-/* set credential option for acceptor configuration file */
-extern gss_OID GSS_EAP_CRED_SET_RADIUS_CONFIG_FILE;
+extern gss_OID GSS_EAP_CRED_SET_RADIUS_CONFIG;
+extern gss_OID GSS_EAP_CRED_SET_CRED_FLAG;
+
+#define GSS_EAP_DISABLE_LOCAL_ATTRS_FLAG    0x00000001
 
 #ifdef __cplusplus
 }
index ddd2826..ad4dc24 100644 (file)
@@ -47,5 +47,4 @@ GSS_EAP_MECHANISM
 GSS_EAP_AES128_CTS_HMAC_SHA1_96_MECHANISM
 GSS_EAP_AES256_CTS_HMAC_SHA1_96_MECHANISM
 GSS_EAP_NT_PRINCIPAL_NAME
-GSS_EAP_CRED_SET_RADIUS_CONFIG_FILE
 gssspi_acquire_cred_with_password
index 0affb32..9e9c8ee 100644 (file)
 #include "gssapiP_eap.h"
 
 static OM_uint32
-setCredRadiusConfigFile(OM_uint32 *minor,
-                        gss_cred_id_t cred,
-                        const gss_OID oid,
-                        const gss_buffer_t buffer)
+setCredRadiusConfig(OM_uint32 *minor,
+                    gss_cred_id_t cred,
+                    const gss_OID oid,
+                    const gss_buffer_t buffer)
 {
     OM_uint32 major;
     gss_buffer_desc configFileBuffer = GSS_C_EMPTY_BUFFER;
@@ -56,6 +56,33 @@ setCredRadiusConfigFile(OM_uint32 *minor,
     return GSS_S_COMPLETE;
 }
 
+static OM_uint32
+setCredFlag(OM_uint32 *minor,
+            gss_cred_id_t cred,
+            const gss_OID oid,
+            const gss_buffer_t buffer)
+{
+    OM_uint32 flags;
+    unsigned char *p;
+
+    if (buffer == GSS_C_NO_BUFFER || buffer->length < 4) {
+        *minor = EINVAL;
+        return GSS_S_FAILURE;
+    }
+
+    p = (unsigned char *)buffer->value;
+
+    flags = load_uint32_be(buffer->value) & CRED_FLAG_PUBLIC_MASK;
+
+    if (buffer->length > 4 && p[4])
+        cred->flags &= ~(flags);
+    else
+        cred->flags |= flags;
+
+    *minor = 0;
+    return GSS_S_COMPLETE;
+}
+
 static struct {
     gss_OID_desc oid;
     OM_uint32 (*setOption)(OM_uint32 *, gss_cred_id_t cred,
@@ -64,11 +91,17 @@ static struct {
     /* 1.3.6.1.4.1.5322.21.3.3.1 */
     {
         { 11, "\x2B\x06\x01\x04\x01\xA9\x4A\x15\x03\x03\x01" },
-        setCredRadiusConfigFile,
+        setCredRadiusConfig,
+    },
+    /* 1.3.6.1.4.1.5322.21.3.3.2 */
+    {
+        { 11, "\x2B\x06\x01\x04\x01\xA9\x4A\x15\x03\x03\x02" },
+        setCredFlag,
     },
 };
 
-gss_OID GSS_EAP_CRED_SET_RADIUS_CONFIG_FILE = &setCredOps[0].oid;
+gss_OID GSS_EAP_CRED_SET_RADIUS_CONFIG = &setCredOps[0].oid;
+gss_OID GSS_EAP_CRED_SET_CRED_FLAG     = &setCredOps[1].oid;
 
 OM_uint32
 gssspi_set_cred_option(OM_uint32 *minor,
@@ -89,3 +122,24 @@ gssspi_set_cred_option(OM_uint32 *minor,
 
     return major;
 }
+
+#if 0
+OM_uint32
+gsseap_set_cred_flag(OM_uint32 *minor,
+                     gss_cred_id_t cred,
+                     OM_uint32 flag,
+                     int clear)
+{
+    unsigned char buf[5];
+    gss_buffer_desc value;
+
+    value.length = sizeof(buf);
+    value.value = buf;
+
+    store_uint32_be(flag, buf);
+    buf[4] = (clear != 0);
+
+    return gssspi_set_cred_option(minor, cred,
+                                  GSS_EAP_CRED_SET_CRED_FLAG, &value);
+}
+#endif
index f862f6e..56a0088 100644 (file)
@@ -80,6 +80,8 @@ gss_eap_attr_ctx::unregisterProvider(unsigned int type)
  */
 gss_eap_attr_ctx::gss_eap_attr_ctx(void)
 {
+    m_flags = 0;
+
     for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
         gss_eap_attr_provider *provider;
 
@@ -121,6 +123,26 @@ gss_eap_attr_ctx::attributeTypeToPrefix(unsigned int type)
     return &gssEapAttrPrefixes[type];
 }
 
+bool
+gss_eap_attr_ctx::providerEnabled(unsigned int type) const
+{
+    if (type == ATTR_TYPE_LOCAL &&
+        (m_flags & ATTR_FLAG_DISABLE_LOCAL))
+        return false;
+
+    if (m_providers[type] == NULL)
+        return false;
+
+    return true;
+}
+
+void
+gss_eap_attr_ctx::releaseProvider(unsigned int type)
+{
+    delete m_providers[type];
+    m_providers[type] = NULL;
+}
+
 /*
  * Initialize a context from an existing context.
  */
@@ -129,17 +151,22 @@ gss_eap_attr_ctx::initFromExistingContext(const gss_eap_attr_ctx *manager)
 {
     bool ret = true;
 
+    m_flags = manager->m_flags;
+
     for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
-        gss_eap_attr_provider *provider = m_providers[i];
+        gss_eap_attr_provider *provider;
 
-        if (provider == NULL)
+        if (!providerEnabled(i)) {
+            releaseProvider(i);
             continue;
+        }
+
+        provider = m_providers[i];
 
         ret = provider->initFromExistingContext(this,
                                                 manager->m_providers[i]);
         if (ret == false) {
-            delete provider;
-            m_providers[i] = NULL;
+            releaseProvider(i);
             break;
         }
     }
@@ -156,16 +183,24 @@ gss_eap_attr_ctx::initFromGssContext(const gss_cred_id_t cred,
 {
     bool ret = true;
 
+    if (cred != GSS_C_NO_CREDENTIAL &&
+        (cred->flags & GSS_EAP_DISABLE_LOCAL_ATTRS_FLAG)) {
+        m_flags |= ATTR_FLAG_DISABLE_LOCAL;
+    }
+
     for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
-        gss_eap_attr_provider *provider = m_providers[i];
+        gss_eap_attr_provider *provider;
 
-        if (provider == NULL)
+        if (!providerEnabled(i)) {
+            releaseProvider(i);
             continue;
+        }
+
+        provider = m_providers[i];
 
         ret = provider->initFromGssContext(this, cred, ctx);
         if (ret == false) {
-            delete provider;
-            m_providers[i] = NULL;
+            releaseProvider(i);
             break;
         }
     }
@@ -181,14 +216,29 @@ gss_eap_attr_ctx::initFromBuffer(const gss_buffer_t buffer)
 {
     bool ret;
     gss_eap_attr_provider *primaryProvider = getPrimaryProvider();
+    gss_buffer_desc primaryBuf;
+
+    if (buffer->length < 4)
+        return false;
+
+    m_flags = load_uint32_be(buffer->value);
+
+    primaryBuf.length = buffer->length - 4;
+    primaryBuf.value = (char *)buffer->value + 4;
 
-    ret = primaryProvider->initFromBuffer(this, buffer);
+    ret = primaryProvider->initFromBuffer(this, &primaryBuf);
     if (ret == false)
         return ret;
 
     for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
-        gss_eap_attr_provider *provider = m_providers[i];
+        gss_eap_attr_provider *provider;
+
+        if (!providerEnabled(i)) {
+            releaseProvider(i);
+            continue;
+        }
 
+        provider = m_providers[i];
         if (provider == primaryProvider)
             continue;
 
@@ -196,8 +246,7 @@ gss_eap_attr_ctx::initFromBuffer(const gss_buffer_t buffer)
                                            GSS_C_NO_CREDENTIAL,
                                            GSS_C_NO_CONTEXT);
         if (ret == false) {
-            delete provider;
-            m_providers[i] = NULL;
+            releaseProvider(i);
             break;
         }
     }
@@ -445,8 +494,22 @@ void
 gss_eap_attr_ctx::exportToBuffer(gss_buffer_t buffer) const
 {
     const gss_eap_attr_provider *primaryProvider = getPrimaryProvider();
+    gss_buffer_desc tmp;
+    unsigned char *p;
+    OM_uint32 tmpMinor;
+
+    primaryProvider->exportToBuffer(&tmp);
+
+    buffer->length = 4 + tmp.length;
+    buffer->value = GSSEAP_MALLOC(buffer->length);
+    if (buffer->value == NULL)
+        throw new std::bad_alloc;
+
+    p = (unsigned char *)buffer->value;
+    store_uint32_be(m_flags, p);
+    memcpy(p + 4, tmp.value, tmp.length);
 
-    primaryProvider->exportToBuffer(buffer);
+    gss_release_buffer(&tmpMinor, &tmp);
 }
 
 /*
index 8c4360e..2592b90 100644 (file)
@@ -51,6 +51,8 @@ typedef bool
 #define ATTR_TYPE_MIN               ATTR_TYPE_RADIUS
 #define ATTR_TYPE_MAX               ATTR_TYPE_LOCAL
 
+#define ATTR_FLAG_DISABLE_LOCAL     0x00000001
+
 /*
  * Attribute provider: this represents a source of attributes derived
  * from the security context.
@@ -204,12 +206,16 @@ public:
     time_t getExpiryTime(void) const;
 
 private:
+    bool providerEnabled(unsigned int type) const;
+    void releaseProvider(unsigned int type);
+
     gss_eap_attr_provider *getPrimaryProvider(void) const;
 
     /* make non-copyable */
     gss_eap_attr_ctx(const gss_eap_attr_ctx&);
     gss_eap_attr_ctx& operator=(const gss_eap_attr_ctx&);
 
+    uint32_t m_flags;
     gss_eap_attr_provider *m_providers[ATTR_TYPE_MAX + 1];
 };