X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=util_shib.cpp;h=27b03e2f61a4bacb90f2f4185bb6ff47bd3aab66;hb=refs%2Fheads%2Fjson-name;hp=7d3457782181925e2006e48f18ff3d7b88b36244;hpb=81378d116795fa8a7a56dc8e00c3b2666126682d;p=mech_eap.orig diff --git a/util_shib.cpp b/util_shib.cpp index 7d34577..27b03e2 100644 --- a/util_shib.cpp +++ b/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,90 +45,173 @@ * 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; -static vector -duplicateAttributes(const vector src); +gss_eap_shib_attr_provider::gss_eap_shib_attr_provider(void) +{ + m_authenticated = false; +} -gss_eap_shib_attr_provider::gss_eap_shib_attr_provider(const gss_eap_attr_ctx *ctx, - gss_cred_id_t gssCred, - gss_ctx_id_t gssCtx) - : gss_eap_attr_provider(ctx, gssCred, gssCtx) +gss_eap_shib_attr_provider::~gss_eap_shib_attr_provider(void) { - if (gssCtx == GSS_C_NO_CONTEXT) { - gss_eap_shib_attr_provider *shib; - - shib = dynamic_cast - (ctx->getProvider(ATTR_TYPE_LOCAL)); - if (shib != NULL) - m_attributes = duplicateAttributes(shib->m_attributes); - } else { - gss_eap_saml_assertion_provider *saml; - gss_eap_radius_attr_provider *radius; - gss_buffer_desc nameBuf = GSS_C_EMPTY_BUFFER; - ShibbolethResolver *resolver = NULL; - OM_uint32 minor; + for_each(m_attributes.begin(), + m_attributes.end(), + xmltooling::cleanup()) + ; +} - saml = dynamic_cast - (ctx->getProvider(ATTR_TYPE_SAML_ASSERTION)); - radius = dynamic_cast - (ctx->getProvider(ATTR_TYPE_RADIUS)); +bool +gss_eap_shib_attr_provider::initFromExistingContext(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)) { + return false; + } + + m_authenticated = false; + + shib = static_cast(ctx); + if (shib != NULL) { + m_attributes = duplicateAttributes(shib->getAttributes()); + m_authenticated = shib->authenticated(); + } - if (radius == NULL) - return; + 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); +bool +addRadiusAttribute(const gss_eap_attr_ctx *manager, + const gss_eap_attr_provider *provider, + const gss_buffer_t attribute, + void *data) +{ + const gss_eap_radius_attr_provider *radius; + const gss_eap_shib_attr_provider *shib; + int authenticated, complete, more = -1; + vector attributeIds(1); + SimpleAttribute *a; - if (saml != NULL && saml->getAssertion() != NULL) - resolver->addToken(saml->getAssertion()); + radius = static_cast(provider); + shib = static_cast(data); - /* TODO inject RADIUS attribute types */ + assert(radius != NULL && shib != NULL); - resolver->resolveAttributes(m_attributes); + string attributeName = + manager->composeAttributeName(ATTR_TYPE_RADIUS, attribute); - gss_release_buffer(&minor, &nameBuf); + attributeIds.push_back(attributeName); + a = new SimpleAttribute(attributeIds); + if (a == NULL) + return false; - delete resolver; + 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; } -gss_eap_shib_attr_provider::~gss_eap_shib_attr_provider(void) +bool +gss_eap_shib_attr_provider::initFromGssContext(const gss_eap_attr_ctx *manager, + const gss_cred_id_t gssCred, + const gss_ctx_id_t gssCtx) { - for_each(m_attributes.begin(), m_attributes.end(), xmltooling::cleanup()); + const gss_eap_saml_assertion_provider *saml; + const gss_eap_radius_attr_provider *radius; +#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; + + saml = static_cast + (m_manager->getProvider(ATTR_TYPE_SAML_ASSERTION)); + radius = static_cast + (m_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 + if (gssCred != GSS_C_NO_CREDENTIAL && + gssEapDisplayName(&minor, gssCred->name, &nameBuf, NULL) == GSS_S_COMPLETE) { + resolver->setApplicationID((const char *)nameBuf.value); + gss_release_buffer(&minor, &nameBuf); + } +#endif + + m_authenticated = false; + + if (radius != NULL) { + radius->getAttributeTypes(addRadiusAttribute, (void *)this); + m_authenticated = radius->authenticated(); + } + + if (saml != NULL && saml->getAssertion() != NULL) { + resolver->addToken(saml->getAssertion()); + if (m_authenticated) + m_authenticated = saml->authenticated(); + } + + try { + resolver->resolve(); + m_attributes = resolver->getResolvedAttributes(); + resolver->getResolvedAttributes().clear(); + } catch (exception &e) { +#if 0 + fprintf(stderr, "%s", e.what()); +#endif + } + + return true; } -int +ssize_t gss_eap_shib_attr_provider::getAttributeIndex(const gss_buffer_t attr) const { int i = 0; @@ -150,28 +233,28 @@ 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); 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); + m_authenticated = false; + + return true; } -void +bool gss_eap_shib_attr_provider::deleteAttribute(const gss_buffer_t attr) { int i; @@ -179,6 +262,10 @@ gss_eap_shib_attr_provider::deleteAttribute(const gss_buffer_t attr) i = getAttributeIndex(attr); if (i >= 0) m_attributes.erase(m_attributes.begin() + i); + + m_authenticated = false; + + return true; } bool @@ -194,7 +281,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; } @@ -236,35 +323,52 @@ gss_eap_shib_attr_provider::getAttribute(const gss_buffer_t attr, { const Attribute *shibAttr = NULL; gss_buffer_desc buf; + int nvalues, i = *more; + + *more = 0; shibAttr = getAttribute(attr); if (shibAttr == NULL) return false; - if (*more == -1) { - *more = 0; - } else if (*more >= (int)shibAttr->valueCount()) { - *more = 0; - return true; - } + nvalues = shibAttr->valueCount(); - buf.value = (void *)shibAttr->getString(*more); + if (i == -1) + i = 0; + else if (i >= nvalues) + return false; + + buf.value = (void *)shibAttr->getSerializedValues()[*more].c_str(); buf.length = strlen((char *)buf.value); - duplicateBuffer(buf, value); - - *authenticated = TRUE; - *complete = FALSE; + if (buf.length != 0) { + if (value != NULL) + duplicateBuffer(buf, value); + + if (display_value != NULL) + duplicateBuffer(buf, display_value); + } + + if (authenticated != NULL) + *authenticated = m_authenticated; + if (complete != NULL) + *complete = false; + + if (nvalues > ++i) + *more = i; return true; } 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; + if (authenticated && !m_authenticated) + return (gss_any_t)NULL; + vector v = duplicateAttributes(m_attributes); output = (gss_any_t)new vector (v); @@ -273,59 +377,128 @@ 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 { vector *v = ((vector *)input); delete v; } -void -gss_eap_shib_attr_provider::marshall(gss_buffer_t buffer) const +const char * +gss_eap_shib_attr_provider::prefix(void) const { + return NULL; } -gss_eap_attr_provider * -gss_eap_shib_attr_provider::unmarshall(const gss_eap_attr_ctx *ctx, - const gss_buffer_t buffer) +const char * +gss_eap_shib_attr_provider::name(void) const { - return NULL; + return "local"; +} + +JSONObject +gss_eap_shib_attr_provider::jsonRepresentation(void) const +{ + JSONObject obj; + + obj.set("authenticated", m_authenticated); + + JSONObject attrs = JSONObject::array(); + + for (vector::const_iterator a = m_attributes.begin(); + a != m_attributes.end(); ++a) { + DDF attr = (*a)->marshall(); + JSONObject jobj(attr); + attrs.append(jobj); + } + + obj.set("attributes", attrs); + + return obj; +} + +bool +gss_eap_shib_attr_provider::initWithJsonObject(const gss_eap_attr_ctx *ctx, + JSONObject &obj) +{ + if (!gss_eap_attr_provider::initWithJsonObject(ctx, obj)) + return false; + + assert(m_authenticated == false); + assert(m_attributes.size() == 0); + + m_authenticated = obj["authenticated"].integer(); + + JSONObject attrs = obj["attributes"]; + size_t nelems = attrs.size(); + + for (size_t i = 0; i < nelems; i++) { + DDF attr = attrs.get(i).ddf(); + Attribute *attribute = Attribute::unmarshall(attr); + m_attributes.push_back(attribute); + } + + return true; } bool gss_eap_shib_attr_provider::init(void) { - return ShibbolethResolver::init(); + if (!ShibbolethResolver::init()) + return false; + + gss_eap_attr_ctx::registerProvider(ATTR_TYPE_LOCAL, createAttrContext); + + return true; } void gss_eap_shib_attr_provider::finalize(void) { + gss_eap_attr_ctx::unregisterProvider(ATTR_TYPE_LOCAL); ShibbolethResolver::term(); } -gss_eap_attr_provider * -gss_eap_shib_attr_provider::createAttrContext(const gss_eap_attr_ctx *ctx, - gss_cred_id_t gssCred, - gss_ctx_id_t gssCtx) +OM_uint32 +gss_eap_shib_attr_provider::mapException(OM_uint32 *minor, + std::exception &e) const { - return new gss_eap_shib_attr_provider(ctx, gssCred, gssCtx); + 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; + + return GSS_S_FAILURE; } -static Attribute * -duplicateAttribute(const Attribute *src) +gss_eap_attr_provider * +gss_eap_shib_attr_provider::createAttrContext(void) { - Attribute *attribute; + return new gss_eap_shib_attr_provider; +} +Attribute * +gss_eap_shib_attr_provider::duplicateAttribute(const Attribute *src) +{ DDF obj = src->marshall(); - attribute = Attribute::unmarshall(obj); + Attribute *attribute = Attribute::unmarshall(obj); obj.destroy(); return attribute; } -static vector -duplicateAttributes(const vector src) +vector +gss_eap_shib_attr_provider::duplicateAttributes(const vector src) { vector dst; @@ -336,3 +509,22 @@ 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; +}