add export_sec_context variant that does not reenter local attribute path
authorLuke Howard <lukeh@padl.com>
Mon, 28 Mar 2011 14:58:03 +0000 (01:58 +1100)
committerLuke Howard <lukeh@padl.com>
Mon, 28 Mar 2011 14:58:03 +0000 (01:58 +1100)
mech_eap/export_sec_context.c
mech_eap/gssapiP_eap.h
mech_eap/util.h
mech_eap/util_attr.cpp
mech_eap/util_attr.h
mech_eap/util_name.c
mech_eap/util_reauth.c
mech_eap/util_shib.cpp

index 2ea2c5c..7d3842b 100644 (file)
@@ -50,8 +50,12 @@ gssEapExportPartialContext(OM_uint32 *minor,
     if (ctx->acceptorCtx.radConn != NULL) {
         if (rs_conn_get_current_peer(ctx->acceptorCtx.radConn,
                                      serverBuf, sizeof(serverBuf)) != 0) {
+#if 0
             return gssEapRadiusMapError(minor,
                                         rs_err_conn_pop(ctx->acceptorCtx.radConn));
+#else
+            serverBuf[0] = '\0'; /* not implemented yet */
+#endif
         }
         serverLen = strlen(serverBuf);
     }
@@ -95,10 +99,11 @@ cleanup:
     return major;
 }
 
-static OM_uint32
+OM_uint32
 gssEapExportSecContext(OM_uint32 *minor,
                        gss_ctx_id_t ctx,
-                       gss_buffer_t token)
+                       gss_buffer_t token,
+                       OM_uint32 flags)
 {
     OM_uint32 major, tmpMinor;
     size_t length;
@@ -118,12 +123,17 @@ gssEapExportSecContext(OM_uint32 *minor,
     key.value  = KRB_KEY_DATA(&ctx->rfc3961Key);
 
     if (ctx->initiatorName != GSS_C_NO_NAME) {
+        OM_uint32 nameFlags = EXPORT_NAME_FLAG_COMPOSITE;
+
+        if (flags & EXPORT_CTX_FLAG_DISABLE_LOCAL_ATTRS)
+            nameFlags |= EXPORT_NAME_FLAG_DISABLE_LOCAL_ATTRS;
+
         major = gssEapExportNameInternal(minor, ctx->initiatorName,
-                                         &initiatorName,
-                                         EXPORT_NAME_FLAG_COMPOSITE);
+                                         &initiatorName, nameFlags);
         if (GSS_ERROR(major))
             goto cleanup;
     }
+
     if (ctx->acceptorName != GSS_C_NO_NAME) {
         major = gssEapExportNameInternal(minor, ctx->acceptorName,
                                          &acceptorName,
@@ -224,7 +234,7 @@ gss_export_sec_context(OM_uint32 *minor,
 
     GSSEAP_MUTEX_LOCK(&ctx->mutex);
 
-    major = gssEapExportSecContext(minor, ctx, interprocess_token);
+    major = gssEapExportSecContext(minor, ctx, interprocess_token, 0);
     if (GSS_ERROR(major)) {
         GSSEAP_MUTEX_UNLOCK(&ctx->mutex);
         return major;
index 81fcf3f..635c155 100644 (file)
@@ -262,6 +262,16 @@ gssEapSaveStatusInfo(OM_uint32 minor, const char *format, ...);
 #define IS_WIRE_ERROR(err)              ((err) > GSSEAP_RESERVED && \
                                          (err) <= GSSEAP_RADIUS_PROT_FAILURE)
 
+/* export_sec_context.c */
+#define EXPORT_CTX_FLAG_DISABLE_LOCAL_ATTRS     0x1
+
+OM_uint32
+gssEapExportSecContext(OM_uint32 *minor,
+                       gss_ctx_id_t ctx,
+                       gss_buffer_t token,
+                       OM_uint32 flags);
+
+
 #ifdef __cplusplus
 }
 #endif
index 5687d52..9ca587b 100644 (file)
@@ -453,8 +453,9 @@ gss_OID
 gssEapSaslNameToOid(const gss_buffer_t name);
 
 /* util_name.c */
-#define EXPORT_NAME_FLAG_OID        0x1
-#define EXPORT_NAME_FLAG_COMPOSITE  0x2
+#define EXPORT_NAME_FLAG_OID                    0x1
+#define EXPORT_NAME_FLAG_COMPOSITE              0x2
+#define EXPORT_NAME_FLAG_DISABLE_LOCAL_ATTRS    0x4
 
 OM_uint32 gssEapAllocName(OM_uint32 *minor, gss_name_t *pName);
 OM_uint32 gssEapReleaseName(OM_uint32 *minor, gss_name_t *pName);
@@ -464,7 +465,7 @@ OM_uint32 gssEapExportName(OM_uint32 *minor,
 OM_uint32 gssEapExportNameInternal(OM_uint32 *minor,
                                    const gss_name_t name,
                                    gss_buffer_t exportedName,
-                                   unsigned int flags);
+                                   OM_uint32 flags);
 OM_uint32 gssEapImportName(OM_uint32 *minor,
                            const gss_buffer_t input_name_buffer,
                            const gss_OID input_name_type,
@@ -473,7 +474,7 @@ OM_uint32 gssEapImportName(OM_uint32 *minor,
 OM_uint32 gssEapImportNameInternal(OM_uint32 *minor,
                                    const gss_buffer_t input_name_buffer,
                                    gss_name_t *output_name,
-                                   unsigned int flags);
+                                   OM_uint32 flags);
 OM_uint32
 gssEapDuplicateName(OM_uint32 *minor,
                     const gss_name_t input_name,
index 9973a00..f2e7661 100644 (file)
@@ -339,7 +339,7 @@ gss_eap_attr_ctx::initWithJsonObject(JSONObject &obj)
 }
 
 JSONObject
-gss_eap_attr_ctx::jsonRepresentation(void) const
+gss_eap_attr_ctx::jsonRepresentation(uint32_t flags) const
 {
     JSONObject obj, sources;
     unsigned int i;
@@ -351,6 +351,10 @@ gss_eap_attr_ctx::jsonRepresentation(void) const
         gss_eap_attr_provider *provider;
         const char *key;
 
+        if (i == ATTR_TYPE_LOCAL &&
+            (flags & ATTR_FLAG_DISABLE_LOCAL))
+            continue; /* reentrancy workaround */
+
         provider = m_providers[i];
         if (provider == NULL)
             continue; /* provider not initialised */
@@ -622,12 +626,13 @@ gss_eap_attr_ctx::releaseAnyNameMapping(gss_buffer_t type_id,
  * Export attribute context to buffer
  */
 void
-gss_eap_attr_ctx::exportToBuffer(gss_buffer_t buffer) const
+gss_eap_attr_ctx::exportToBuffer(gss_buffer_t buffer,
+                                 uint32_t flags) const
 {
     OM_uint32 minor;
     char *s;
 
-    JSONObject obj = jsonRepresentation();
+    JSONObject obj = jsonRepresentation(flags);
 
 #if 0
     obj.dump(stdout, JSON_INDENT(3));
@@ -968,7 +973,8 @@ gssEapSetNameAttribute(OM_uint32 *minor,
 OM_uint32
 gssEapExportAttrContext(OM_uint32 *minor,
                         gss_name_t name,
-                        gss_buffer_t buffer)
+                        gss_buffer_t buffer,
+                        OM_uint32 flags)
 {
     if (name->attrCtx == NULL) {
         buffer->length = 0;
@@ -981,7 +987,7 @@ gssEapExportAttrContext(OM_uint32 *minor,
         return GSS_S_UNAVAILABLE;
 
     try {
-        name->attrCtx->exportToBuffer(buffer);
+        name->attrCtx->exportToBuffer(buffer, flags);
     } catch (std::exception &e) {
         return name->attrCtx->mapException(minor, e);
     }
@@ -1134,12 +1140,10 @@ gssEapCreateAttrContext(OM_uint32 *minor,
     major = GSS_S_FAILURE;
 
     try {
-        ctx = new gss_eap_attr_ctx();
+        *pAttrContext = ctx = new gss_eap_attr_ctx();
         if (ctx->initFromGssContext(gssCred, gssCtx)) {
             *minor = 0;
             major = GSS_S_COMPLETE;
-        } else {
-            delete ctx;
         }
     } catch (std::exception &e) {
         if (ctx != NULL)
@@ -1147,8 +1151,10 @@ gssEapCreateAttrContext(OM_uint32 *minor,
     }
 
     if (major == GSS_S_COMPLETE) {
-        *pAttrContext = ctx;
         *pExpiryTime = ctx->getExpiryTime();
+    } else {
+        delete ctx;
+        *pAttrContext = NULL;
     }
 
     return major;
index e391df1..ad35c78 100644 (file)
@@ -59,8 +59,6 @@ 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.
@@ -209,7 +207,8 @@ public:
     void releaseAnyNameMapping(gss_buffer_t type_id,
                                gss_any_t input) const;
 
-    void exportToBuffer(gss_buffer_t buffer) const;
+    void exportToBuffer(gss_buffer_t buffer,
+                        uint32_t flags) const;
     bool initFromBuffer(const gss_buffer_t buffer);
 
     static std::string
@@ -255,7 +254,7 @@ private:
     gss_buffer_desc attributeTypeToPrefix(unsigned int type) const;
 
     bool initWithJsonObject(JSONObject &object);
-    JSONObject jsonRepresentation(void) const;
+    JSONObject jsonRepresentation(uint32_t flags) const;
 
     gss_eap_attr_provider *getPrimaryProvider(void) const;
 
@@ -303,6 +302,8 @@ struct gss_eap_attr_ctx;
 extern "C" {
 #endif
 
+#define ATTR_FLAG_DISABLE_LOCAL     0x00000001
+
 /*
  * C wrappers for attribute context functions. These match their
  * GSS naming extension equivalents. The caller is required to
@@ -348,7 +349,8 @@ gssEapSetNameAttribute(OM_uint32 *minor,
 OM_uint32
 gssEapExportAttrContext(OM_uint32 *minor,
                         gss_name_t name,
-                        gss_buffer_t buffer);
+                        gss_buffer_t buffer,
+                        OM_uint32 flags);
 
 OM_uint32
 gssEapImportAttrContext(OM_uint32 *minor,
index aa19b94..e8c0d66 100644 (file)
@@ -335,7 +335,7 @@ OM_uint32
 gssEapImportNameInternal(OM_uint32 *minor,
                          const gss_buffer_t nameBuffer,
                          gss_name_t *pName,
-                         unsigned int flags)
+                         OM_uint32 flags)
 {
     OM_uint32 major, tmpMinor;
     krb5_context krbContext;
@@ -524,7 +524,7 @@ OM_uint32
 gssEapExportNameInternal(OM_uint32 *minor,
                          const gss_name_t name,
                          gss_buffer_t exportedName,
-                         unsigned int flags)
+                         OM_uint32 flags)
 {
     OM_uint32 major = GSS_S_FAILURE, tmpMinor;
     gss_buffer_desc nameBuf = GSS_C_EMPTY_BUFFER;
@@ -551,7 +551,12 @@ gssEapExportNameInternal(OM_uint32 *minor,
     }
     exportedNameLen += 4 + nameBuf.length;
     if (flags & EXPORT_NAME_FLAG_COMPOSITE) {
-        major = gssEapExportAttrContext(minor, name, &attrs);
+        OM_uint32 attrFlags = 0;
+
+        if (flags & EXPORT_NAME_FLAG_DISABLE_LOCAL_ATTRS)
+            attrFlags |= ATTR_FLAG_DISABLE_LOCAL;
+
+        major = gssEapExportAttrContext(minor, name, &attrs, attrFlags);
         if (GSS_ERROR(major))
             goto cleanup;
         exportedNameLen += attrs.length;
index 465bb16..631a70f 100644 (file)
@@ -146,7 +146,7 @@ freezeAttrContext(OM_uint32 *minor,
 
     GSSEAP_KRB_INIT(&krbContext);
 
-    major = gssEapExportAttrContext(minor, initiatorName, &attrBuf);
+    major = gssEapExportAttrContext(minor, initiatorName, &attrBuf, 0);
     if (GSS_ERROR(major))
         return major;
 
index 27b03e2..7285aed 100644 (file)
@@ -157,9 +157,11 @@ gss_eap_shib_attr_provider::initFromGssContext(const gss_eap_attr_ctx *manager,
 {
     const gss_eap_saml_assertion_provider *saml;
     const gss_eap_radius_attr_provider *radius;
+    gss_buffer_desc exportedCtx = GSS_C_EMPTY_BUFFER;
+    OM_uint32 major, minor;
+
 #if 0
     gss_buffer_desc nameBuf = GSS_C_EMPTY_BUFFER;
-    OM_uint32 minor;
 #endif
     if (!gss_eap_attr_provider::initFromGssContext(manager, gssCred, gssCtx))
         return false;
@@ -187,6 +189,12 @@ gss_eap_shib_attr_provider::initFromGssContext(const gss_eap_attr_ctx *manager,
 
     m_authenticated = false;
 
+    major = gssEapExportSecContext(&minor, gssCtx, &exportedCtx,
+                                   EXPORT_CTX_FLAG_DISABLE_LOCAL_ATTRS);
+    if (major == GSS_S_COMPLETE) {
+        gss_release_buffer(&minor, &exportedCtx);
+    }
+
     if (radius != NULL) {
         radius->getAttributeTypes(addRadiusAttribute, (void *)this);
         m_authenticated = radius->authenticated();