cleanup, hook in RADIUS to Shib
authorLuke Howard <lukeh@padl.com>
Sat, 18 Sep 2010 09:47:35 +0000 (11:47 +0200)
committerLuke Howard <lukeh@padl.com>
Sat, 18 Sep 2010 09:47:35 +0000 (11:47 +0200)
mech_eap/util_attr.cpp
mech_eap/util_attr.h
mech_eap/util_radius.cpp
mech_eap/util_saml.cpp
mech_eap/util_shib.cpp
mech_eap/util_shib.h

index 53ad003..74cf43b 100644 (file)
@@ -36,7 +36,7 @@
 #include <exception>
 #include <new>
 
-static gss_eap_attr_create_cb
+static gss_eap_attr_create_factory
 gss_eap_attr_factories[ATTR_TYPE_MAX] = {
     gss_eap_radius_attr_provider::createAttrContext,
     gss_eap_saml_assertion_provider::createAttrContext,
@@ -318,6 +318,8 @@ gss_eap_attr_ctx::unmarshall(const gss_eap_attr_ctx *ctx,
     for (i = 0; i < ATTR_TYPE_MAX; i++) {
         gss_eap_attr_provider *provider = m_providers[i];
     }
+
+    return false;
 }
 
 
@@ -366,7 +368,7 @@ gss_eap_attr_ctx::attributePrefixToType(const gss_buffer_t prefix)
     return ATTR_TYPE_LOCAL;
 }
 
-gss_buffer_t
+const gss_buffer_t
 gss_eap_attr_ctx::attributeTypeToPrefix(unsigned int type)
 {
     if (type < ATTR_TYPE_MIN || type >= ATTR_TYPE_LOCAL)
@@ -402,44 +404,52 @@ gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute,
     }
 }
 
-void
+std::string
 gss_eap_attr_ctx::composeAttributeName(const gss_buffer_t prefix,
-                                       const gss_buffer_t suffix,
-                                       gss_buffer_t attribute)
+                                       const gss_buffer_t suffix)
 {
-    size_t len = 0;
-    char *p;
-
-    attribute->length = 0;
-    attribute->value = NULL;
+    std::string str;
 
     if (prefix == GSS_C_NO_BUFFER || prefix->length == 0)
-        return;
+        return str;
+
+    str.append((const char *)prefix->value, prefix->length);
 
-    len = prefix->length;
     if (suffix != GSS_C_NO_BUFFER) {
-        len += 1 + suffix->length;
+        str.append(" ");
+        str.append((const char *)suffix->value, suffix->length);
     }
 
-    attribute->value = GSSEAP_MALLOC(len + 1);
-    if (attribute->value == NULL) {
-        throw new std::bad_alloc;
-    }
-    attribute->length = len;
+    return str;
+}
 
-    p = (char *)attribute->value;
-    memcpy(p, prefix->value, prefix->length);
-    if (suffix != NULL) {
-        p[prefix->length] = ' ';
-        memcpy(p + prefix->length + 1, suffix->value, suffix->length);
-    }
+std::string
+gss_eap_attr_ctx::composeAttributeName(unsigned int type,
+                                       const gss_buffer_t suffix)
+{
+    const gss_buffer_t prefix = attributeTypeToPrefix(type);
 
-    p[attribute->length] = '\0';
+    return composeAttributeName(prefix, suffix);
+}
+
+void
+gss_eap_attr_ctx::composeAttributeName(const gss_buffer_t prefix,
+                                       const gss_buffer_t suffix,
+                                       gss_buffer_t attribute)
+{
+    std::string str = composeAttributeName(prefix, suffix);
+
+    if (str.length() != 0) {
+        return duplicateBuffer(str, attribute);
+    } else {
+        attribute->length = 0;
+        attribute->value = NULL;
+    }
 }
 
 void
 gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute,
-                                         unsigned int*type,
+                                         unsigned int *type,
                                          gss_buffer_t suffix)
 {
     gss_buffer_desc prefix = GSS_C_EMPTY_BUFFER;
@@ -455,7 +465,7 @@ gss_eap_attr_ctx::composeAttributeName(unsigned int type,
 {
     gss_buffer_t prefix = attributeTypeToPrefix(type);
 
-    composeAttributeName(prefix, suffix, attribute);
+    return composeAttributeName(prefix, suffix, attribute);
 }
 
 OM_uint32
@@ -579,6 +589,8 @@ gssEapImportAttrContext(OM_uint32 *minor,
 {
     if (buffer->length)
         GSSEAP_NOT_IMPLEMENTED;
+
+    return GSS_S_COMPLETE;
 }
 
 OM_uint32
index eb0a041..43a5c88 100644 (file)
@@ -41,6 +41,8 @@
 #define ATTR_TYPE_MAX               (ATTR_TYPE_LOCAL + 1U)
 
 #ifdef __cplusplus
+#include <string>
+
 struct gss_eap_attr_ctx;
 
 struct gss_eap_attr_provider
@@ -103,7 +105,7 @@ protected:
     const gss_eap_attr_ctx *m_source;
 };
 
-typedef gss_eap_attr_provider *(*gss_eap_attr_create_cb)(void);
+typedef gss_eap_attr_provider *(*gss_eap_attr_create_factory)(void);
 
 struct gss_eap_attr_ctx : gss_eap_attr_provider
 {
@@ -146,7 +148,7 @@ public:
     static unsigned int
     attributePrefixToType(const gss_buffer_t prefix);
 
-    static gss_buffer_t
+    static const gss_buffer_t
     attributeTypeToPrefix(unsigned int type);
 
     static void
@@ -166,6 +168,13 @@ public:
                          const gss_buffer_t suffix,
                          gss_buffer_t attribute);
 
+    static std::string
+    composeAttributeName(const gss_buffer_t prefix,
+                         const gss_buffer_t suffix);
+    static std::string
+    composeAttributeName(unsigned int type,
+                         const gss_buffer_t suffix);
+
     gss_eap_attr_provider *getProvider(unsigned int type) const;
     gss_eap_attr_provider *getProvider(const gss_buffer_t prefix) const;
 
index e851312..7fe84a4 100644 (file)
@@ -101,6 +101,7 @@ gss_any_t
 gss_eap_radius_attr_provider::mapToAny(int authenticated,
                                        gss_buffer_t type_id) const
 {
+    return (gss_any_t)NULL;
 }
 
 void
@@ -124,6 +125,7 @@ gss_eap_radius_attr_provider::unmarshall(const gss_eap_attr_ctx *ctx,
 bool
 gss_eap_radius_attr_provider::init(void)
 {
+    return true;
 }
 
 void
index 2257b03..2a9e650 100644 (file)
@@ -81,11 +81,15 @@ gss_eap_saml_assertion_provider::initFromExistingContext(const gss_eap_attr_ctx
     /* Then we may be creating from an existing attribute context */
     const gss_eap_saml_assertion_provider *saml;
 
+    assert(m_assertion == NULL);
+
     if (!gss_eap_attr_provider::initFromExistingContext(source, ctx))
         return false;
 
     saml = dynamic_cast<const gss_eap_saml_assertion_provider *>(ctx);
     setAssertion(saml->getAssertion());
+
+    return true;
 }
 
 bool
@@ -98,17 +102,23 @@ gss_eap_saml_assertion_provider::initFromGssContext(const gss_eap_attr_ctx *sour
     int authenticated, complete, more = -1;
     OM_uint32 minor;
 
+    assert(m_assertion == NULL);
+
     if (!gss_eap_attr_provider::initFromGssContext(source, gssCred, gssCtx))
         return false;
 
     radius = dynamic_cast<const gss_eap_radius_attr_provider *>
-        (source->getProvider(ATTR_TYPE_RADIUS));
+        (m_source->getProvider(ATTR_TYPE_RADIUS));
     if (radius != NULL &&
-        radius->getAttribute(512, &authenticated, &complete,
+        radius->getAttribute(512 /* XXX */, &authenticated, &complete,
                              &value, NULL, &more)) {
         m_assertion = parseAssertion(&value);
         gss_release_buffer(&minor, &value);
+    } else {
+        m_assertion = NULL;
     }
+
+    return true;
 }
 
 gss_eap_saml_assertion_provider::~gss_eap_saml_assertion_provider(void)
@@ -121,7 +131,11 @@ gss_eap_saml_assertion_provider::setAssertion(const saml2::Assertion *assertion)
 {
 
     delete m_assertion;
-    m_assertion = dynamic_cast<saml2::Assertion*>(assertion->clone());
+
+    if (assertion != NULL)
+        m_assertion = dynamic_cast<saml2::Assertion*>(assertion->clone());
+    else
+        m_assertion = NULL;
 }
 
 saml2::Assertion *
@@ -139,8 +153,10 @@ gss_eap_saml_assertion_provider::parseAssertion(const gss_buffer_t buffer)
 }
 
 bool
-gss_eap_saml_assertion_provider::getAttributeTypes(gss_eap_attr_enumeration_cb addAttribute, void *data) const
+gss_eap_saml_assertion_provider::getAttributeTypes(gss_eap_attr_enumeration_cb addAttribute,
+                                                   void *data) const
 {
+    /* just add the prefix */
     return addAttribute(this, GSS_C_NO_BUFFER, data);
 }
 
@@ -149,9 +165,12 @@ gss_eap_saml_assertion_provider::setAttribute(int complete,
                                               const gss_buffer_t attr,
                                               const gss_buffer_t value)
 {
-    saml2::Assertion *assertion = parseAssertion(value);
+    if (attr == GSS_C_NO_BUFFER || attr->length == 0) {
+        saml2::Assertion *assertion = parseAssertion(value);
 
-    m_assertion = assertion;
+        delete m_assertion;
+        m_assertion = assertion;
+    }
 }
 
 void
@@ -171,20 +190,22 @@ gss_eap_saml_assertion_provider::getAttribute(const gss_buffer_t attr,
 {
     string str;
 
-    if (attr->length != 0 || m_assertion == NULL)
+    if (attr != GSS_C_NO_BUFFER || attr->length != 0)
         return false;
 
-    if (*more == -1)
-        *more = 0;
+    if (m_assertion == NULL)
+        return false;
 
-    if (*more == 0) {
-        *authenticated = true;
-        *complete = false;
+    if (*more != -1)
+        return false;
 
-        XMLHelper::serialize(m_assertion->marshall((DOMDocument *)NULL), str);
+    *authenticated = true;
+    *complete = false;
 
-        duplicateBuffer(str, value);
-    }
+    XMLHelper::serialize(m_assertion->marshall((DOMDocument *)NULL), str);
+
+    duplicateBuffer(str, value);
+    *more = 0;
 
     return true;
 }
@@ -227,8 +248,10 @@ gss_eap_saml_assertion_provider::unmarshall(const gss_eap_attr_ctx *ctx,
 {
     assert(m_assertion == NULL);
 
-    m_assertion = parseAssertion(buffer);
+    if (buffer->length == 0)
+        return true;
 
+    m_assertion = parseAssertion(buffer);
     return (m_assertion != NULL);
 }
 
@@ -383,9 +406,9 @@ gss_eap_saml_attr_provider::getAttribute(const gss_buffer_t attr,
 
 gss_any_t
 gss_eap_saml_attr_provider::mapToAny(int authenticated,
-                                          gss_buffer_t type_id) const
+                                     gss_buffer_t type_id) const
 {
-    return (gss_any_t)0;
+    return (gss_any_t)NULL;
 }
 
 void
@@ -397,13 +420,15 @@ gss_eap_saml_attr_provider::releaseAnyNameMapping(gss_buffer_t type_id,
 void
 gss_eap_saml_attr_provider::marshall(gss_buffer_t buffer) const
 {
+    buffer->length = 0;
+    buffer->value = NULL;
 }
 
 bool
 gss_eap_saml_attr_provider::unmarshall(const gss_eap_attr_ctx *ctx,
                                        const gss_buffer_t buffer)
 {
-    return false;
+    return true;
 }
 
 bool
index 35a5381..352fbed 100644 (file)
@@ -76,9 +76,6 @@ using namespace xmltooling;
 using namespace xercesc;
 using namespace std;
 
-static vector <Attribute *>
-duplicateAttributes(const vector <Attribute *>src);
-
 bool
 gss_eap_shib_attr_provider::initFromExistingContext(const gss_eap_attr_ctx *source,
                                                     const gss_eap_attr_provider *ctx)
@@ -90,7 +87,54 @@ gss_eap_shib_attr_provider::initFromExistingContext(const gss_eap_attr_ctx *sour
 
     shib = dynamic_cast<const gss_eap_shib_attr_provider *>(ctx);
     if (shib != NULL)
-        m_attributes = duplicateAttributes(shib->m_attributes);
+        m_attributes = duplicateAttributes(shib->getAttributes());
+
+    return true;
+}
+
+bool
+addRadiusAttribute(const gss_eap_attr_provider *provider,
+                   const gss_buffer_t attribute,
+                   void *data)
+{
+    const gss_eap_shib_attr_provider *shib;
+    const gss_eap_radius_attr_provider *radius;
+    int authenticated, complete, more = -1;
+    vector <string> attributeIds(1);
+    SimpleAttribute *a;
+
+    radius = dynamic_cast<const gss_eap_radius_attr_provider *>(provider);
+    shib = static_cast<const gss_eap_shib_attr_provider *>(data);
+
+    assert(radius != NULL && shib != NULL);
+
+    string attributeName =
+        gss_eap_attr_ctx::composeAttributeName(ATTR_TYPE_RADIUS, attribute);
+
+    attributeIds.push_back(attributeName);
+    a = new SimpleAttribute(attributeIds);
+    if (a == NULL)
+        return false;
+
+    while (more != 0) {
+        gss_buffer_desc value = GSS_C_EMPTY_BUFFER;
+        OM_uint32 minor;
+
+        if (!radius->getAttribute(attribute,
+                                  &authenticated,
+                                  &complete,
+                                  &value,
+                                  NULL,
+                                  &more))
+            return false;
+
+        string attributeValue((char *)value.value, value.length);
+        a->getValues().push_back(attributeValue);
+
+        gss_release_buffer(&minor, &value);
+    }
+
+    shib->getAttributes().push_back(a);
 
     return true;
 }
@@ -114,9 +158,6 @@ gss_eap_shib_attr_provider::initFromGssContext(const gss_eap_attr_ctx *source,
     radius = dynamic_cast<const gss_eap_radius_attr_provider *>
         (source->getProvider(ATTR_TYPE_RADIUS));
 
-    if (radius == NULL)
-        return true;
-
     if (gssCred != GSS_C_NO_CREDENTIAL &&
         gss_display_name(&minor, gssCred->name, &nameBuf, NULL) == GSS_S_COMPLETE)
         resolver->setApplicationID((const char *)nameBuf.value);
@@ -124,7 +165,8 @@ gss_eap_shib_attr_provider::initFromGssContext(const gss_eap_attr_ctx *source,
     if (saml != NULL && saml->getAssertion() != NULL)
         resolver->addToken(saml->getAssertion());
 
-    /* TODO inject RADIUS attribute types */
+    if (radius != NULL)
+        radius->getAttributeTypes(addRadiusAttribute, (void *)this);
 
     resolver->resolveAttributes(m_attributes);
 
@@ -137,7 +179,10 @@ gss_eap_shib_attr_provider::initFromGssContext(const gss_eap_attr_ctx *source,
 
 gss_eap_shib_attr_provider::~gss_eap_shib_attr_provider(void)
 {
-    for_each(m_attributes.begin(), m_attributes.end(), xmltooling::cleanup<Attribute>());
+    for_each(m_attributes.begin(),
+             m_attributes.end(),
+             xmltooling::cleanup<Attribute>())
+        ;
 }
 
 int
@@ -175,9 +220,9 @@ gss_eap_shib_attr_provider::setAttribute(int complete,
     SimpleAttribute *a = new SimpleAttribute(ids);
 
     if (value->length != 0) {
-        string valStr((char *)value->value, value->length);
+        string valueStr((char *)value->value, value->length);
 
-        a->getValues().push_back(valStr);        
+        a->getValues().push_back(valueStr);        
     }
 
     m_attributes.push_back(a);
@@ -295,13 +340,15 @@ gss_eap_shib_attr_provider::releaseAnyNameMapping(gss_buffer_t type_id,
 void
 gss_eap_shib_attr_provider::marshall(gss_buffer_t buffer) const
 {
+    buffer->length = 0;
+    buffer->value = NULL;
 }
 
 bool
 gss_eap_shib_attr_provider::unmarshall(const gss_eap_attr_ctx *ctx,
                                        const gss_buffer_t buffer)
 {
-    return false;
+    return true;
 }
 
 bool
@@ -322,8 +369,8 @@ gss_eap_shib_attr_provider::createAttrContext(void)
     return new gss_eap_shib_attr_provider;
 }
 
-static Attribute *
-duplicateAttribute(const Attribute *src)
+Attribute *
+gss_eap_shib_attr_provider::duplicateAttribute(const Attribute *src)
 {
     Attribute *attribute;
 
@@ -334,8 +381,8 @@ duplicateAttribute(const Attribute *src)
     return attribute;
 }
 
-static vector <Attribute *>
-duplicateAttributes(const vector <Attribute *>src)
+vector <Attribute *>
+gss_eap_shib_attr_provider::duplicateAttributes(const vector <Attribute *>src)
 {
     vector <Attribute *> dst;
 
index 8064aa7..0d61fa2 100644 (file)
@@ -39,6 +39,10 @@ namespace shibsp {
     class Attribute;
 };
 
+namespace shibresolver {
+    class ShibbolethResolver;
+};
+
 struct gss_eap_shib_attr_provider : gss_eap_attr_provider {
 public:
     gss_eap_shib_attr_provider(void) {}
@@ -77,14 +81,24 @@ public:
     static gss_eap_attr_provider *createAttrContext(void);
 
 private:
+    static shibsp::Attribute *
+        duplicateAttribute(const shibsp::Attribute *src);
+    static std::vector <shibsp::Attribute *>
+        duplicateAttributes(const std::vector <shibsp::Attribute *>src);
+
     int getAttributeIndex(const gss_buffer_t attr) const;
     const shibsp::Attribute *getAttribute(const gss_buffer_t attr) const;
 
-    const std::vector<shibsp::Attribute *> getAttributes(void) const {
+    std::vector<shibsp::Attribute *> getAttributes(void) const {
         return m_attributes;
     }
 
-    std::vector<shibsp::Attribute *> m_attributes;
+    friend bool
+    addRadiusAttribute(const gss_eap_attr_provider *provider,
+                       const gss_buffer_t attribute,
+                       void *data);
+
+    mutable std::vector<shibsp::Attribute *> m_attributes;
 };
 
 #endif /* _UTIL_SHIB_H_ */