X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=mech_eap%2Futil_shib.cpp;h=3d2aa2cd55fc53b9c10a5d7e93060aca085d4ea9;hb=ff85e98394f476c23efd83507d8931bfe6c14acf;hp=815b57a8d316b939c41c880ed1a9e3ff03d3ecf3;hpb=040fe91fb58c6c94e71e9c61f237c89d90eeec9d;p=moonshot.git diff --git a/mech_eap/util_shib.cpp b/mech_eap/util_shib.cpp index 815b57a..3d2aa2c 100644 --- a/mech_eap/util_shib.cpp +++ b/mech_eap/util_shib.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, JANET(UK) + * Copyright (c) 2011, JANET(UK) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,7 +31,7 @@ */ /* * Copyright 2001-2009 Internet2 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -45,44 +45,50 @@ * limitations under the License. */ -#include "gssapiP_eap.h" +/* + * Local attribute provider implementation. + */ + +#include + +#include -#include #include -#include -#include -#include #include -#include -#include -#include -#include +#include -#include -#include -#include -#include -#include -#include +#include -#include "resolver.h" +#include "gssapiP_eap.h" using namespace shibsp; using namespace shibresolver; using namespace opensaml::saml2md; using namespace opensaml; -using namespace xmltooling::logging; using namespace xmltooling; -using namespace xercesc; using namespace std; +gss_eap_shib_attr_provider::gss_eap_shib_attr_provider(void) +{ + m_initialized = false; + m_authenticated = false; +} + +gss_eap_shib_attr_provider::~gss_eap_shib_attr_provider(void) +{ + for_each(m_attributes.begin(), + m_attributes.end(), + xmltooling::cleanup()) + ; +} + bool -gss_eap_shib_attr_provider::initFromExistingContext(const gss_eap_attr_ctx *manager, +gss_eap_shib_attr_provider::initWithExistingContext(const gss_eap_attr_ctx *manager, const gss_eap_attr_provider *ctx) { const gss_eap_shib_attr_provider *shib; - if (!gss_eap_attr_provider::initFromExistingContext(manager, ctx)) { + if (!gss_eap_attr_provider::initWithExistingContext(manager, ctx)) { return false; } @@ -94,114 +100,75 @@ gss_eap_shib_attr_provider::initFromExistingContext(const gss_eap_attr_ctx *mana m_authenticated = shib->authenticated(); } - 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 = static_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); + m_initialized = true; return true; } bool -gss_eap_shib_attr_provider::initFromGssContext(const gss_eap_attr_ctx *manager, +gss_eap_shib_attr_provider::initWithGssContext(const gss_eap_attr_ctx *manager, const gss_cred_id_t gssCred, const gss_ctx_id_t gssCtx) { - const gss_eap_saml_assertion_provider *saml; - const gss_eap_radius_attr_provider *radius; - gss_buffer_desc nameBuf = GSS_C_EMPTY_BUFFER; - ShibbolethResolver *resolver = NULL; - OM_uint32 minor; - - if (!gss_eap_attr_provider::initFromGssContext(manager, gssCred, gssCtx)) + if (!gss_eap_attr_provider::initWithGssContext(manager, gssCred, gssCtx)) return false; - saml = static_cast - (manager->getProvider(ATTR_TYPE_SAML_ASSERTION)); - radius = static_cast - (manager->getProvider(ATTR_TYPE_RADIUS)); + auto_ptr resolver(ShibbolethResolver::create()); + /* + * For now, leave ApplicationID defaulted. + * Later on, we could allow this via config option to the mechanism + * or rely on an SPRequest interface to pass in a URI identifying the + * acceptor. + */ +#if 0 + gss_buffer_desc nameBuf = GSS_C_EMPTY_BUFFER; if (gssCred != GSS_C_NO_CREDENTIAL && - gss_display_name(&minor, gssCred->name, &nameBuf, NULL) == GSS_S_COMPLETE) + gssEapDisplayName(&minor, gssCred->name, &nameBuf, NULL) == GSS_S_COMPLETE) { resolver->setApplicationID((const char *)nameBuf.value); + gss_release_buffer(&minor, &nameBuf); + } +#endif - m_authenticated = false; + gss_buffer_desc mechName = GSS_C_EMPTY_BUFFER; + OM_uint32 major, minor; - if (radius != NULL) { - radius->getAttributeTypes(addRadiusAttribute, (void *)this); - m_authenticated = radius->authenticated(); + major = gssEapExportNameInternal(&minor, gssCtx->initiatorName, &mechName, + EXPORT_NAME_FLAG_OID | + EXPORT_NAME_FLAG_COMPOSITE); + if (major == GSS_S_COMPLETE) { + resolver->addToken(&mechName); + gss_release_buffer(&minor, &mechName); } + const gss_eap_saml_assertion_provider *saml; + saml = static_cast + (m_manager->getProvider(ATTR_TYPE_SAML_ASSERTION)); if (saml != NULL && saml->getAssertion() != NULL) { resolver->addToken(saml->getAssertion()); - if (m_authenticated) - m_authenticated = saml->authenticated(); } - resolver->resolveAttributes(m_attributes); - - gss_release_buffer(&minor, &nameBuf); + try { + resolver->resolve(); + m_attributes = resolver->getResolvedAttributes(); + resolver->getResolvedAttributes().clear(); + } catch (exception &e) { + return false; + } - delete resolver; + m_authenticated = true; + m_initialized = true; return true; } -gss_eap_shib_attr_provider::~gss_eap_shib_attr_provider(void) -{ - for_each(m_attributes.begin(), - m_attributes.end(), - xmltooling::cleanup()) - ; -} - -int +ssize_t gss_eap_shib_attr_provider::getAttributeIndex(const gss_buffer_t attr) const { int i = 0; + assert(m_initialized); + for (vector::const_iterator a = m_attributes.begin(); a != m_attributes.end(); ++a) @@ -219,44 +186,51 @@ gss_eap_shib_attr_provider::getAttributeIndex(const gss_buffer_t attr) const return -1; } -void -gss_eap_shib_attr_provider::setAttribute(int complete, +bool +gss_eap_shib_attr_provider::setAttribute(int complete GSSEAP_UNUSED, const gss_buffer_t attr, const gss_buffer_t value) { string attrStr((char *)attr->value, attr->length); - vector ids(1); - - ids.push_back(attrStr); - + vector ids(1, attrStr); SimpleAttribute *a = new SimpleAttribute(ids); + assert(m_initialized); + if (value->length != 0) { string valueStr((char *)value->value, value->length); - a->getValues().push_back(valueStr); + a->getValues().push_back(valueStr); } m_attributes.push_back(a); m_authenticated = false; + + return true; } -void +bool gss_eap_shib_attr_provider::deleteAttribute(const gss_buffer_t attr) { int i; + assert(m_initialized); + i = getAttributeIndex(attr); if (i >= 0) m_attributes.erase(m_attributes.begin() + i); m_authenticated = false; + + return true; } bool gss_eap_shib_attr_provider::getAttributeTypes(gss_eap_attr_enumeration_cb addAttribute, void *data) const { + assert(m_initialized); + for (vector::const_iterator a = m_attributes.begin(); a != m_attributes.end(); ++a) @@ -266,7 +240,7 @@ gss_eap_shib_attr_provider::getAttributeTypes(gss_eap_attr_enumeration_cb addAtt attribute.value = (void *)((*a)->getId()); attribute.length = strlen((char *)attribute.value); - if (!addAttribute(this, &attribute, data)) + if (!addAttribute(m_manager, this, &attribute, data)) return false; } @@ -278,6 +252,8 @@ gss_eap_shib_attr_provider::getAttribute(const gss_buffer_t attr) const { const Attribute *ret = NULL; + assert(m_initialized); + for (vector::const_iterator a = m_attributes.begin(); a != m_attributes.end(); ++a) @@ -310,6 +286,8 @@ gss_eap_shib_attr_provider::getAttribute(const gss_buffer_t attr, gss_buffer_desc buf; int nvalues, i = *more; + assert(m_initialized); + *more = 0; shibAttr = getAttribute(attr); @@ -320,10 +298,10 @@ gss_eap_shib_attr_provider::getAttribute(const gss_buffer_t attr, if (i == -1) i = 0; - else if (i >= nvalues) + if (i >= nvalues) return false; - buf.value = (void *)shibAttr->getString(*more); + buf.value = (void *)shibAttr->getSerializedValues()[*more].c_str(); buf.length = strlen((char *)buf.value); if (buf.length != 0) { @@ -333,9 +311,11 @@ gss_eap_shib_attr_provider::getAttribute(const gss_buffer_t attr, if (display_value != NULL) duplicateBuffer(buf, display_value); } - - *authenticated = m_authenticated; - *complete = false; + + if (authenticated != NULL) + *authenticated = m_authenticated; + if (complete != NULL) + *complete = false; if (nvalues > ++i) *more = i; @@ -345,10 +325,15 @@ gss_eap_shib_attr_provider::getAttribute(const gss_buffer_t attr, gss_any_t gss_eap_shib_attr_provider::mapToAny(int authenticated, - gss_buffer_t type_id) const + gss_buffer_t type_id GSSEAP_UNUSED) const { gss_any_t output; + assert(m_initialized); + + if (authenticated && !m_authenticated) + return (gss_any_t)NULL; + vector v = duplicateAttributes(m_attributes); output = (gss_any_t)new vector (v); @@ -357,74 +342,74 @@ gss_eap_shib_attr_provider::mapToAny(int authenticated, } void -gss_eap_shib_attr_provider::releaseAnyNameMapping(gss_buffer_t type_id, +gss_eap_shib_attr_provider::releaseAnyNameMapping(gss_buffer_t type_id GSSEAP_UNUSED, gss_any_t input) const { + assert(m_initialized); + vector *v = ((vector *)input); delete v; } -void -gss_eap_shib_attr_provider::exportToBuffer(gss_buffer_t buffer) const +const char * +gss_eap_shib_attr_provider::prefix(void) const { - DDF obj(NULL); - DDF attrs(NULL); + return NULL; +} - buffer->length = 0; - buffer->value = NULL; +const char * +gss_eap_shib_attr_provider::name(void) const +{ + return "local"; +} + +JSONObject +gss_eap_shib_attr_provider::jsonRepresentation(void) const +{ + JSONObject obj; - obj.addmember("version").integer(1); - obj.addmember("authenticated").integer(m_authenticated); + if (m_initialized == false) + return obj; /* don't export incomplete context */ + + JSONObject jattrs = JSONObject::array(); - attrs = obj.addmember("attributes").list(); for (vector::const_iterator a = m_attributes.begin(); a != m_attributes.end(); ++a) { DDF attr = (*a)->marshall(); - attrs.add(attr); + JSONObject jattr = JSONObject::ddf(attr); + jattrs.append(jattr); } - ostringstream sink; - sink << attrs; - string str = sink.str(); + obj.set("attributes", jattrs); - duplicateBuffer(str, buffer); + obj.set("authenticated", m_authenticated); - attrs.destroy(); + return obj; } bool -gss_eap_shib_attr_provider::initFromBuffer(const gss_eap_attr_ctx *ctx, - const gss_buffer_t buffer) +gss_eap_shib_attr_provider::initWithJsonObject(const gss_eap_attr_ctx *ctx, + JSONObject &obj) { - if (!gss_eap_attr_provider::initFromBuffer(ctx, buffer)) + if (!gss_eap_attr_provider::initWithJsonObject(ctx, obj)) return false; - if (buffer->length == 0) - return true; - assert(m_authenticated == false); assert(m_attributes.size() == 0); - DDF obj(NULL); - string str((const char *)buffer->value, buffer->length); - istringstream source(str); - - source >> obj; + JSONObject jattrs = obj["attributes"]; + size_t nelems = jattrs.size(); - if (obj["version"].integer() != 1) - return false; - - m_authenticated = (obj["authenticated"].integer() != 0); + for (size_t i = 0; i < nelems; i++) { + JSONObject jattr = jattrs.get(i); - DDF attrs = obj["attributes"]; - DDF attr = attrs.first(); - while (!attr.isnull()) { + DDF attr = jattr.ddf(); Attribute *attribute = Attribute::unmarshall(attr); m_attributes.push_back(attribute); - attr = attrs.next(); } - attrs.destroy(); + m_authenticated = obj["authenticated"].integer(); + m_initialized = true; return true; } @@ -432,12 +417,11 @@ gss_eap_shib_attr_provider::initFromBuffer(const gss_eap_attr_ctx *ctx, bool gss_eap_shib_attr_provider::init(void) { - if (!ShibbolethResolver::init()) + if (SPConfig::getConfig().getFeatures() == 0 && + ShibbolethResolver::init() == false) return false; - gss_eap_attr_ctx::registerProvider(ATTR_TYPE_LOCAL, - NULL, - gss_eap_shib_attr_provider::createAttrContext); + gss_eap_attr_ctx::registerProvider(ATTR_TYPE_LOCAL, createAttrContext); return true; } @@ -445,8 +429,32 @@ gss_eap_shib_attr_provider::init(void) void gss_eap_shib_attr_provider::finalize(void) { - ShibbolethResolver::term(); gss_eap_attr_ctx::unregisterProvider(ATTR_TYPE_LOCAL); + ShibbolethResolver::term(); +} + +OM_uint32 +gss_eap_shib_attr_provider::mapException(OM_uint32 *minor, + std::exception &e) const +{ + if (typeid(e) == typeid(AttributeException)) + *minor = GSSEAP_SHIB_ATTR_FAILURE; + else if (typeid(e) == typeid(AttributeExtractionException)) + *minor = GSSEAP_SHIB_ATTR_EXTRACT_FAILURE; + else if (typeid(e) == typeid(AttributeFilteringException)) + *minor = GSSEAP_SHIB_ATTR_FILTER_FAILURE; + else if (typeid(e) == typeid(AttributeResolutionException)) + *minor = GSSEAP_SHIB_ATTR_RESOLVE_FAILURE; + else if (typeid(e) == typeid(ConfigurationException)) + *minor = GSSEAP_SHIB_CONFIG_FAILURE; + else if (typeid(e) == typeid(ListenerException)) + *minor = GSSEAP_SHIB_LISTENER_FAILURE; + else + return GSS_S_CONTINUE_NEEDED; + + gssEapSaveStatusInfo(*minor, "%s", e.what()); + + return GSS_S_FAILURE; } gss_eap_attr_provider * @@ -458,10 +466,8 @@ gss_eap_shib_attr_provider::createAttrContext(void) Attribute * gss_eap_shib_attr_provider::duplicateAttribute(const Attribute *src) { - Attribute *attribute; - DDF obj = src->marshall(); - attribute = Attribute::unmarshall(obj); + Attribute *attribute = Attribute::unmarshall(obj); obj.destroy(); return attribute; @@ -479,3 +485,22 @@ gss_eap_shib_attr_provider::duplicateAttributes(const vector src) return dst; } + +OM_uint32 +gssEapLocalAttrProviderInit(OM_uint32 *minor) +{ + if (!gss_eap_shib_attr_provider::init()) { + *minor = GSSEAP_SHIB_INIT_FAILURE; + return GSS_S_FAILURE; + } + return GSS_S_COMPLETE; +} + +OM_uint32 +gssEapLocalAttrProviderFinalize(OM_uint32 *minor) +{ + gss_eap_shib_attr_provider::finalize(); + + *minor = 0; + return GSS_S_COMPLETE; +}