From f5bdfb8fde9b759d6bc5695ef7457c02d3b41d8f Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Sat, 18 Sep 2010 11:47:35 +0200 Subject: [PATCH] cleanup, hook in RADIUS to Shib --- mech_eap/util_attr.cpp | 66 +++++++++++++++++++++++----------------- mech_eap/util_attr.h | 13 ++++++-- mech_eap/util_radius.cpp | 2 ++ mech_eap/util_saml.cpp | 63 ++++++++++++++++++++++++++------------ mech_eap/util_shib.cpp | 79 ++++++++++++++++++++++++++++++++++++++---------- mech_eap/util_shib.h | 18 +++++++++-- 6 files changed, 175 insertions(+), 66 deletions(-) diff --git a/mech_eap/util_attr.cpp b/mech_eap/util_attr.cpp index 53ad003..74cf43b 100644 --- a/mech_eap/util_attr.cpp +++ b/mech_eap/util_attr.cpp @@ -36,7 +36,7 @@ #include #include -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 diff --git a/mech_eap/util_attr.h b/mech_eap/util_attr.h index eb0a041..43a5c88 100644 --- a/mech_eap/util_attr.h +++ b/mech_eap/util_attr.h @@ -41,6 +41,8 @@ #define ATTR_TYPE_MAX (ATTR_TYPE_LOCAL + 1U) #ifdef __cplusplus +#include + 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; diff --git a/mech_eap/util_radius.cpp b/mech_eap/util_radius.cpp index e851312..7fe84a4 100644 --- a/mech_eap/util_radius.cpp +++ b/mech_eap/util_radius.cpp @@ -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 diff --git a/mech_eap/util_saml.cpp b/mech_eap/util_saml.cpp index 2257b03..2a9e650 100644 --- a/mech_eap/util_saml.cpp +++ b/mech_eap/util_saml.cpp @@ -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(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 - (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(assertion->clone()); + + if (assertion != NULL) + m_assertion = dynamic_cast(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 diff --git a/mech_eap/util_shib.cpp b/mech_eap/util_shib.cpp index 35a5381..352fbed 100644 --- a/mech_eap/util_shib.cpp +++ b/mech_eap/util_shib.cpp @@ -76,9 +76,6 @@ using namespace xmltooling; using namespace xercesc; using namespace std; -static vector -duplicateAttributes(const vector 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(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 attributeIds(1); + SimpleAttribute *a; + + radius = dynamic_cast(provider); + shib = static_cast(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 (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()); + for_each(m_attributes.begin(), + m_attributes.end(), + xmltooling::cleanup()) + ; } 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 -duplicateAttributes(const vector src) +vector +gss_eap_shib_attr_provider::duplicateAttributes(const vector src) { vector dst; diff --git a/mech_eap/util_shib.h b/mech_eap/util_shib.h index 8064aa7..0d61fa2 100644 --- a/mech_eap/util_shib.h +++ b/mech_eap/util_shib.h @@ -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 + duplicateAttributes(const std::vector src); + int getAttributeIndex(const gss_buffer_t attr) const; const shibsp::Attribute *getAttribute(const gss_buffer_t attr) const; - const std::vector getAttributes(void) const { + std::vector getAttributes(void) const { return m_attributes; } - std::vector m_attributes; + friend bool + addRadiusAttribute(const gss_eap_attr_provider *provider, + const gss_buffer_t attribute, + void *data); + + mutable std::vector m_attributes; }; #endif /* _UTIL_SHIB_H_ */ -- 2.1.4