X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=saml%2Fsaml2%2Fmetadata%2Fimpl%2FAbstractMetadataProvider.cpp;h=196962b1893b8343244dab9866f7ef450361ae5d;hb=46ac496b77b850309c07e732ff89fa41c776915d;hp=59e430308870f536d8cff38a1a3b688ab20fced4;hpb=4a6e7f38d8e33c6a9bb02cb96a952f130c82968e;p=shibboleth%2Fcpp-opensaml.git diff --git a/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp b/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp index 59e4303..196962b 100644 --- a/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp +++ b/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2006 Internet2 + * Copyright 2001-2007 Internet2 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,49 +21,52 @@ */ #include "internal.h" -#include "SAMLArtifact.h" +#include "binding/SAMLArtifact.h" #include "saml2/metadata/Metadata.h" #include "saml2/metadata/AbstractMetadataProvider.h" +#include "saml2/metadata/MetadataCredentialContext.h" +#include "saml2/metadata/MetadataCredentialCriteria.h" #include -#include +#include #include using namespace opensaml::saml2md; -using namespace opensaml; using namespace xmltooling; using namespace std; +using opensaml::SAMLArtifact; -static const XMLCh GenericKeyResolver[] = UNICODE_LITERAL_11(K,e,y,R,e,s,o,l,v,e,r); -static const XMLCh type[] = UNICODE_LITERAL_4(t,y,p,e); +static const XMLCh _KeyInfoResolver[] = UNICODE_LITERAL_15(K,e,y,I,n,f,o,R,e,s,o,l,v,e,r); +static const XMLCh type[] = UNICODE_LITERAL_4(t,y,p,e); -AbstractMetadataProvider::AbstractMetadataProvider(const DOMElement* e) : ObservableMetadataProvider(e), m_resolver(NULL) +AbstractMetadataProvider::AbstractMetadataProvider(const DOMElement* e) + : ObservableMetadataProvider(e), m_resolver(NULL), m_credentialLock(NULL) { - e = e ? XMLHelper::getFirstChildElement(e, GenericKeyResolver) : NULL; + e = e ? XMLHelper::getFirstChildElement(e, _KeyInfoResolver) : NULL; if (e) { auto_ptr_char t(e->getAttributeNS(NULL,type)); if (t.get()) - m_resolver = XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(t.get(),e); + m_resolver = XMLToolingConfig::getConfig().KeyInfoResolverManager.newPlugin(t.get(),e); else - throw UnknownExtensionException(" element found with no type attribute"); - } - - if (!m_resolver) { - m_resolver = XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(INLINE_KEY_RESOLVER, NULL); + throw UnknownExtensionException(" element found with no type attribute"); } + m_credentialLock = Mutex::create(); } AbstractMetadataProvider::~AbstractMetadataProvider() { + for (credmap_t::iterator c = m_credentialMap.begin(); c!=m_credentialMap.end(); ++c) + for_each(c->second.begin(), c->second.end(), xmltooling::cleanup()); + delete m_credentialLock; delete m_resolver; } -void AbstractMetadataProvider::emitChangeEvent() +void AbstractMetadataProvider::emitChangeEvent() const { - xmlsignature::CachingKeyResolver* ckr=dynamic_cast(m_resolver); - if (ckr) - ckr->clearCache(); - ObservableMetadataProvider::emitChangeEvent(); + for (credmap_t::iterator c = m_credentialMap.begin(); c!=m_credentialMap.end(); ++c) + for_each(c->second.begin(), c->second.end(), xmltooling::cleanup()); + m_credentialMap.clear(); + ObservableMetadataProvider::emitChangeEvent(); } void AbstractMetadataProvider::index(EntityDescriptor* site, time_t validUntil) @@ -73,24 +76,24 @@ void AbstractMetadataProvider::index(EntityDescriptor* site, time_t validUntil) auto_ptr_char id(site->getEntityID()); if (id.get()) { - m_sites.insert(make_pair(id.get(),site)); + m_sites.insert(sitemap_t::value_type(id.get(),site)); } // Process each IdP role. const vector& roles=const_cast(site)->getIDPSSODescriptors(); for (vector::const_iterator i=roles.begin(); i!=roles.end(); i++) { // SAML 1.x? - if ((*i)->hasSupport(SAMLConstants::SAML10_PROTOCOL_ENUM) || (*i)->hasSupport(SAMLConstants::SAML11_PROTOCOL_ENUM)) { + if ((*i)->hasSupport(samlconstants::SAML10_PROTOCOL_ENUM) || (*i)->hasSupport(samlconstants::SAML11_PROTOCOL_ENUM)) { // Check for SourceID extension element. const Extensions* exts=(*i)->getExtensions(); - if (exts) { - const list& children=exts->getXMLObjects(); - for (list::const_iterator ext=children.begin(); ext!=children.end(); ext++) { + if (exts && exts->hasChildren()) { + const vector& children=exts->getUnknownXMLObjects(); + for (vector::const_iterator ext=children.begin(); ext!=children.end(); ++ext) { SourceID* sid=dynamic_cast(*ext); if (sid) { auto_ptr_char sourceid(sid->getID()); if (sourceid.get()) { - m_sources.insert(pair(sourceid.get(),site)); + m_sources.insert(sitemap_t::value_type(sourceid.get(),site)); break; } } @@ -98,25 +101,21 @@ void AbstractMetadataProvider::index(EntityDescriptor* site, time_t validUntil) } // Hash the ID. - m_sources.insert( - pair(SAMLConfig::getConfig().hashSHA1(id.get(), true),site) - ); + m_sources.insert(sitemap_t::value_type(SAMLConfig::getConfig().hashSHA1(id.get(), true),site)); // Load endpoints for type 0x0002 artifacts. const vector& locs=const_cast(*i)->getArtifactResolutionServices(); for (vector::const_iterator loc=locs.begin(); loc!=locs.end(); loc++) { auto_ptr_char location((*loc)->getLocation()); if (location.get()) - m_sources.insert(pair(location.get(),site)); + m_sources.insert(sitemap_t::value_type(location.get(),site)); } } // SAML 2.0? - if ((*i)->hasSupport(SAMLConstants::SAML20P_NS)) { + if ((*i)->hasSupport(samlconstants::SAML20P_NS)) { // Hash the ID. - m_sources.insert( - pair(SAMLConfig::getConfig().hashSHA1(id.get(), true),site) - ); + m_sources.insert(sitemap_t::value_type(SAMLConfig::getConfig().hashSHA1(id.get(), true),site)); } } } @@ -128,7 +127,7 @@ void AbstractMetadataProvider::index(EntitiesDescriptor* group, time_t validUnti auto_ptr_char name(group->getName()); if (name.get()) { - m_groups.insert(make_pair(name.get(),group)); + m_groups.insert(groupmap_t::value_type(name.get(),group)); } const vector& groups=const_cast(group)->getEntitiesDescriptors(); @@ -188,3 +187,55 @@ const EntityDescriptor* AbstractMetadataProvider::getEntityDescriptor(const SAML return NULL; } + +const Credential* AbstractMetadataProvider::resolve(const CredentialCriteria* criteria) const +{ + const MetadataCredentialCriteria* metacrit = dynamic_cast(criteria); + if (!metacrit) + throw MetadataException("Cannot resolve credentials without a MetadataCredentialCriteria object."); + + Lock lock(m_credentialLock); + const credmap_t::mapped_type& creds = resolveCredentials(metacrit->getRole()); + + for (credmap_t::mapped_type::const_iterator c = creds.begin(); c!=creds.end(); ++c) + if (metacrit->matches(*(*c))) + return *c; + return NULL; +} + +vector::size_type AbstractMetadataProvider::resolve( + vector& results, const CredentialCriteria* criteria + ) const +{ + const MetadataCredentialCriteria* metacrit = dynamic_cast(criteria); + if (!metacrit) + throw MetadataException("Cannot resolve credentials without a MetadataCredentialCriteria object."); + + Lock lock(m_credentialLock); + const credmap_t::mapped_type& creds = resolveCredentials(metacrit->getRole()); + + for (credmap_t::mapped_type::const_iterator c = creds.begin(); c!=creds.end(); ++c) + if (metacrit->matches(*(*c))) + results.push_back(*c); + return results.size(); +} + +const AbstractMetadataProvider::credmap_t::mapped_type& AbstractMetadataProvider::resolveCredentials(const RoleDescriptor& role) const +{ + credmap_t::const_iterator i = m_credentialMap.find(&role); + if (i!=m_credentialMap.end()) + return i->second; + + const KeyInfoResolver* resolver = m_resolver ? m_resolver : XMLToolingConfig::getConfig().getKeyInfoResolver(); + const vector& keys = role.getKeyDescriptors(); + AbstractMetadataProvider::credmap_t::mapped_type& resolved = m_credentialMap[&role]; + for (vector::const_iterator k = keys.begin(); k!=keys.end(); ++k) { + if ((*k)->getKeyInfo()) { + auto_ptr mcc(new MetadataCredentialContext(*(*k))); + Credential* c = resolver->resolve(mcc.get()); + mcc.release(); + resolved.push_back(c); + } + } + return resolved; +}