X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fcpp-opensaml.git;a=blobdiff_plain;f=saml%2Fsaml2%2Fmetadata%2Fimpl%2FAbstractMetadataProvider.cpp;h=f2cca921cd4ea9d6cc59c8ee6a0d4b262b757307;hp=9dd9bc409bc8142079a3f719c2bab28d3a13e46e;hb=1462057b3b9ae7e165d34d988e30b14c213672ca;hpb=d76fadfe73c89442f328a7540e7b0ae08e0fbae6 diff --git a/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp b/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp index 9dd9bc4..f2cca92 100644 --- a/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp +++ b/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp @@ -31,6 +31,10 @@ #include "saml2/metadata/MetadataCredentialContext.h" #include "saml2/metadata/MetadataCredentialCriteria.h" +#include +#include +#include +#include #include #include #include @@ -44,32 +48,34 @@ using namespace opensaml::saml2md; using namespace xmltooling::logging; using namespace xmltooling; +using namespace boost::lambda; +using namespace boost; using namespace std; using opensaml::SAMLArtifact; 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); +static const XMLCh _type[] = UNICODE_LITERAL_4(t,y,p,e); AbstractMetadataProvider::AbstractMetadataProvider(const DOMElement* e) - : ObservableMetadataProvider(e), m_lastUpdate(0), m_resolver(nullptr), m_credentialLock(nullptr) + : ObservableMetadataProvider(e), m_lastUpdate(0), m_resolver(nullptr), m_credentialLock(Mutex::create()) { e = XMLHelper::getFirstChildElement(e, _KeyInfoResolver); if (e) { - string t = XMLHelper::getAttrString(e, nullptr, type); - if (!t.empty()) - m_resolver = XMLToolingConfig::getConfig().KeyInfoResolverManager.newPlugin(t.c_str(), e); - else + string t = XMLHelper::getAttrString(e, nullptr, _type); + if (!t.empty()) { + m_resolverWrapper.reset(XMLToolingConfig::getConfig().KeyInfoResolverManager.newPlugin(t.c_str(), e)); + m_resolver = m_resolverWrapper.get(); + } + else { 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::outputStatus(ostream& os) const @@ -98,6 +104,14 @@ void AbstractMetadataProvider::emitChangeEvent() const ObservableMetadataProvider::emitChangeEvent(); } +void AbstractMetadataProvider::emitChangeEvent(const EntityDescriptor& entity) const +{ + 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(entity); +} + void AbstractMetadataProvider::indexEntity(EntityDescriptor* site, time_t& validUntil, bool replace) const { // If child expires later than input, reset child, otherwise lower input to match. @@ -109,9 +123,21 @@ void AbstractMetadataProvider::indexEntity(EntityDescriptor* site, time_t& valid auto_ptr_char id(site->getEntityID()); if (id.get()) { if (replace) { - m_sites.erase(id.get()); + // The data structure here needs work. + // We have to find all the sites stored against the replaced ID. Then we have to + // search for those sites in the entire set of sites tracked by the sources map and + // remove them from both places. + set existingSites; + pair existingRange = m_sites.equal_range(id.get()); + static pair::iterator,bool> (set::* ins)(const EntityDescriptor* const &) = + &set::insert; + for_each( + existingRange.first, existingRange.second, + lambda::bind(ins, boost::ref(existingSites), lambda::bind(&sitemap_t::value_type::second, _1)) + ); + m_sites.erase(existingRange.first, existingRange.second); for (sitemap_t::iterator s = m_sources.begin(); s != m_sources.end();) { - if (s->second == site) { + if (existingSites.count(s->second) > 0) { sitemap_t::iterator temp = s; ++s; m_sources.erase(temp); @@ -233,7 +259,7 @@ const EntitiesDescriptor* AbstractMetadataProvider::getEntitiesDescriptor(const return i->second; if (range.first != range.second) { - Category& log = Category::getInstance(SAML_LOGCAT".MetadataProvider"); + Category& log = Category::getInstance(SAML_LOGCAT ".MetadataProvider"); if (strict) { log.warn("ignored expired metadata group (%s)", range.first->first.c_str()); } @@ -273,7 +299,7 @@ pair AbstractMetadataProvider::ge } if (!result.first && range.first!=range.second) { - Category& log = Category::getInstance(SAML_LOGCAT".MetadataProvider"); + Category& log = Category::getInstance(SAML_LOGCAT ".MetadataProvider"); if (criteria.validOnly) { log.warn("ignored expired metadata instance for (%s)", range.first->first.c_str()); } @@ -302,9 +328,9 @@ const Credential* AbstractMetadataProvider::resolve(const CredentialCriteria* cr 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 nullptr; + if (metacrit->matches(*(*c))) + return *c; +return nullptr; } vector::size_type AbstractMetadataProvider::resolve( @@ -318,27 +344,31 @@ vector::size_type AbstractMetadataProvider::resolve( 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); + 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()) + 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); + for (indirect_iterator::const_iterator> k = make_indirect_iterator(keys.begin()); + k != make_indirect_iterator(keys.end()); ++k) { + if (k->getKeyInfo()) { + auto_ptr mcc(new MetadataCredentialContext(*k)); + auto_ptr c(resolver->resolve(mcc.get())); + if (c.get()) { + mcc.release(); // this API sucks, the object is now owned by the Credential + resolved.push_back(c.get()); + c.release(); + } } } return resolved;