X-Git-Url: http://www.project-moonshot.org/gitweb/?p=mech_eap.git;a=blobdiff_plain;f=mech_eap%2Futil_shib.cpp;h=4ba70e0666da228d4d53595ba3f68539254af630;hp=61244840897fa35d032a8a8796b32040bf0c6d9c;hb=HEAD;hpb=bea93e7b7f10bad0cbd4c92e0841b56499b480bc diff --git a/mech_eap/util_shib.cpp b/mech_eap/util_shib.cpp index 6124484..4ba70e0 100644 --- a/mech_eap/util_shib.cpp +++ b/mech_eap/util_shib.cpp @@ -49,25 +49,86 @@ * Local attribute provider implementation. */ +#include "gssapiP_eap.h" + #include +#ifndef HAVE_OPENSAML +#include +#include +#endif #include #include -#include #include +#include +#include #include #include -#include "gssapiP_eap.h" - using namespace shibsp; using namespace shibresolver; -using namespace opensaml::saml2md; -using namespace opensaml; using namespace xmltooling; using namespace std; +#ifdef HAVE_OPENSAML +using namespace opensaml::saml2md; +using namespace opensaml; +#else +using namespace xercesc; +#endif + + +namespace { + + + class ShibFinalizer { + public: + + static bool isShibInitialized() {return shibInitialized;} + static void createSingleton(); + + private: + ShibFinalizer(): is_extra(false) { + if (shibInitialized) { + // This should never, ever happen. Initialization is (supposed to be) + // funneled through a single thread, so there should be no race + // conditions here. And only this class sets this flag, and there's + // only a single instance of this class. + wpa_printf(MSG_ERROR, "### ShibFinalizer::ShibFinalizer(): Attempt to construct an extraneous instance!"); + is_extra = true; + } + else { + wpa_printf(MSG_INFO, "### ShibFinalizer::ShibFinalizer(): Constructing"); + shibInitialized = true; + } + } + + ~ShibFinalizer() { + if (!is_extra) { + wpa_printf(MSG_INFO, "### ShibFinalizer::~ShibFinalizer(): Destructing"); + gss_eap_shib_attr_provider::finalize(); + shibInitialized = false; + } + else { + wpa_printf(MSG_INFO, "### ShibFinalizer::~ShibFinalizer(): This was an extraneous instance; not destructing anything."); + } + } + + bool is_extra; + static bool shibInitialized; + }; +} + + +bool ShibFinalizer::shibInitialized = false; + +void ShibFinalizer::createSingleton() { + // This object's constructor is invoked on the first call to this method. + // At exit, its destructor will terminate Shibboleth. + static ShibFinalizer finalizer; +} + gss_eap_shib_attr_provider::gss_eap_shib_attr_provider(void) { @@ -142,12 +203,32 @@ gss_eap_shib_attr_provider::initWithGssContext(const gss_eap_attr_ctx *manager, gss_release_buffer(&minor, &mechName); } +#ifdef HAVE_OPENSAML 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()); } +#else + /* If no OpenSAML, parse the XML assertion explicitly */ + const gss_eap_radius_attr_provider *radius; + int authenticated, complete; + gss_buffer_desc value = GSS_C_EMPTY_BUFFER; + gss_eap_attrid attrid(VENDORPEC_UKERNA, PW_SAML_AAA_ASSERTION); + + radius = static_cast + (m_manager->getProvider(ATTR_TYPE_RADIUS)); + if (radius != NULL && + radius->getFragmentedAttribute(attrid, &authenticated, &complete, &value)) { + string str((char *)value.value, value.length); + istringstream istream(str); + DOMDocument *doc = XMLToolingConfig::getConfig().getParser().parse(istream); + const XMLObjectBuilder *b = XMLObjectBuilder::getBuilder(doc->getDocumentElement()); + resolver->addToken(b->buildFromDocument(doc)); + gss_release_buffer(&minor, &value); + } +#endif /* HAVE_OPENSAML */ try { resolver->resolve(); @@ -168,7 +249,7 @@ gss_eap_shib_attr_provider::getAttributeIndex(const gss_buffer_t attr) const { int i = 0; - assert(m_initialized); + GSSEAP_ASSERT(m_initialized); for (vector::const_iterator a = m_attributes.begin(); a != m_attributes.end(); @@ -196,7 +277,7 @@ gss_eap_shib_attr_provider::setAttribute(int complete GSSEAP_UNUSED, vector ids(1, attrStr); BinaryAttribute *a = new BinaryAttribute(ids); - assert(m_initialized); + GSSEAP_ASSERT(m_initialized); if (value->length != 0) { string valueStr((char *)value->value, value->length); @@ -215,7 +296,7 @@ gss_eap_shib_attr_provider::deleteAttribute(const gss_buffer_t attr) { int i; - assert(m_initialized); + GSSEAP_ASSERT(m_initialized); i = getAttributeIndex(attr); if (i >= 0) @@ -230,7 +311,7 @@ bool gss_eap_shib_attr_provider::getAttributeTypes(gss_eap_attr_enumeration_cb addAttribute, void *data) const { - assert(m_initialized); + GSSEAP_ASSERT(m_initialized); for (vector::const_iterator a = m_attributes.begin(); a != m_attributes.end(); @@ -253,7 +334,7 @@ gss_eap_shib_attr_provider::getAttribute(const gss_buffer_t attr) const { const Attribute *ret = NULL; - assert(m_initialized); + GSSEAP_ASSERT(m_initialized); for (vector::const_iterator a = m_attributes.begin(); a != m_attributes.end(); @@ -289,7 +370,7 @@ gss_eap_shib_attr_provider::getAttribute(const gss_buffer_t attr, gss_buffer_desc displayValueBuf = GSS_C_EMPTY_BUFFER; int nvalues, i = *more; - assert(m_initialized); + GSSEAP_ASSERT(m_initialized); *more = 0; @@ -316,7 +397,12 @@ gss_eap_shib_attr_provider::getAttribute(const gss_buffer_t attr, valueBuf.value = (void *)str.c_str(); valueBuf.length = str.length(); - displayValueBuf = valueBuf; + const SimpleAttribute *simpleAttr = + dynamic_cast(shibAttr); + const ScopedAttribute *scopedAttr = + dynamic_cast(shibAttr); + if (simpleAttr != NULL || scopedAttr != NULL) + displayValueBuf = valueBuf; } if (authenticated != NULL) @@ -339,7 +425,7 @@ gss_eap_shib_attr_provider::mapToAny(int authenticated, { gss_any_t output; - assert(m_initialized); + GSSEAP_ASSERT(m_initialized); if (authenticated && !m_authenticated) return (gss_any_t)NULL; @@ -355,7 +441,7 @@ void gss_eap_shib_attr_provider::releaseAnyNameMapping(gss_buffer_t type_id GSSEAP_UNUSED, gss_any_t input) const { - assert(m_initialized); + GSSEAP_ASSERT(m_initialized); vector *v = ((vector *)input); delete v; @@ -404,8 +490,8 @@ gss_eap_shib_attr_provider::initWithJsonObject(const gss_eap_attr_ctx *ctx, if (!gss_eap_attr_provider::initWithJsonObject(ctx, obj)) return false; - assert(m_authenticated == false); - assert(m_attributes.size() == 0); + GSSEAP_ASSERT(m_authenticated == false); + GSSEAP_ASSERT(m_attributes.size() == 0); JSONObject jattrs = obj["attributes"]; size_t nelems = jattrs.size(); @@ -429,14 +515,22 @@ gss_eap_shib_attr_provider::init(void) { bool ret = false; + if (ShibFinalizer::isShibInitialized()) { + wpa_printf(MSG_INFO, "### gss_eap_shib_attr_provider::init(): ShibResolver library is already initialized; ignoring."); + return true; + } + + wpa_printf(MSG_INFO, "### gss_eap_shib_attr_provider::init(): Initializing ShibResolver library"); + try { - if (SPConfig::getConfig().getFeatures() == 0) - ret = ShibbolethResolver::init(); + ret = ShibbolethResolver::init(); } catch (exception &e) { } - if (ret) + if (ret) { + ShibFinalizer::createSingleton(); gss_eap_attr_ctx::registerProvider(ATTR_TYPE_LOCAL, createAttrContext); + } return ret; } @@ -444,6 +538,7 @@ gss_eap_shib_attr_provider::init(void) void gss_eap_shib_attr_provider::finalize(void) { + wpa_printf(MSG_INFO, "### gss_eap_shib_attr_provider::finalize(): calling ShibbolethResolver::term()"); gss_eap_attr_ctx::unregisterProvider(ATTR_TYPE_LOCAL); ShibbolethResolver::term(); } @@ -501,6 +596,7 @@ gss_eap_shib_attr_provider::duplicateAttributes(const vector src) return dst; } + OM_uint32 gssEapLocalAttrProviderInit(OM_uint32 *minor) { @@ -508,14 +604,6 @@ gssEapLocalAttrProviderInit(OM_uint32 *minor) *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; }