X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=saml%2Fsaml2%2Fmetadata%2Fimpl%2FMetadataProvider.cpp;h=fc5d7dee633501b84f2821231c09b5a7e4da4409;hb=01fe9dc618b7e57645b71a23757657102e9ac380;hp=b0bf17831894c19f5076f93b4bd5ad74a6a489ea;hpb=e55d708c3afe86d26819d5f6c141a67bf6f7ee61;p=shibboleth%2Fcpp-opensaml.git diff --git a/saml/saml2/metadata/impl/MetadataProvider.cpp b/saml/saml2/metadata/impl/MetadataProvider.cpp index b0bf178..fc5d7de 100644 --- a/saml/saml2/metadata/impl/MetadataProvider.cpp +++ b/saml/saml2/metadata/impl/MetadataProvider.cpp @@ -21,38 +21,81 @@ */ #include "internal.h" +#include "SAMLArtifact.h" +#include "saml2/metadata/Metadata.h" #include "saml2/metadata/MetadataProvider.h" #include +#include #include +#include using namespace opensaml::saml2md; +using namespace opensaml; using namespace xmltooling; using namespace log4cpp; using namespace std; +namespace opensaml { + namespace saml2md { + SAML_DLLLOCAL PluginManager::Factory FilesystemMetadataProviderFactory; + SAML_DLLLOCAL PluginManager::Factory BlacklistMetadataFilterFactory; + SAML_DLLLOCAL PluginManager::Factory WhitelistMetadataFilterFactory; + SAML_DLLLOCAL PluginManager::Factory SignatureMetadataFilterFactory; + }; +}; + +void SAML_API opensaml::saml2md::registerMetadataProviders() +{ + SAMLConfig& conf=SAMLConfig::getConfig(); + conf.MetadataProviderManager.registerFactory(FILESYSTEM_METADATA_PROVIDER, FilesystemMetadataProviderFactory); + conf.MetadataProviderManager.registerFactory("edu.internet2.middleware.shibboleth.metadata.provider.XMLMetadata", FilesystemMetadataProviderFactory); + conf.MetadataProviderManager.registerFactory("edu.internet2.middleware.shibboleth.common.provider.XMLMetadata", FilesystemMetadataProviderFactory); +} + +void SAML_API opensaml::saml2md::registerMetadataFilters() +{ + SAMLConfig::getConfig().MetadataFilterManager.registerFactory(BLACKLIST_METADATA_FILTER, BlacklistMetadataFilterFactory); + SAMLConfig::getConfig().MetadataFilterManager.registerFactory(WHITELIST_METADATA_FILTER, WhitelistMetadataFilterFactory); + SAMLConfig::getConfig().MetadataFilterManager.registerFactory(SIGNATURE_METADATA_FILTER, SignatureMetadataFilterFactory); +} + static const XMLCh Blacklist[] = UNICODE_LITERAL_23(B,l,a,c,k,l,i,s,t,M,e,t,a,d,a,t,a,F,i,l,t,e,r); +static const XMLCh Whitelist[] = UNICODE_LITERAL_23(W,h,i,t,e,l,i,s,t,M,e,t,a,d,a,t,a,F,i,l,t,e,r); +static const XMLCh SigFilter[] = UNICODE_LITERAL_23(S,i,g,n,a,t,u,r,e,M,e,t,a,d,a,t,a,F,i,l,t,e,r); static const XMLCh Exclude[] = UNICODE_LITERAL_7(E,x,c,l,u,d,e); static const XMLCh Include[] = UNICODE_LITERAL_7(I,n,c,l,u,d,e); +static const XMLCh GenericKeyResolver[] = UNICODE_LITERAL_11(K,e,y,R,e,s,o,l,v,e,r); static const XMLCh GenericMetadataFilter[] = UNICODE_LITERAL_14(M,e,t,a,d,a,t,a,F,i,l,t,e,r); static const XMLCh type[] = UNICODE_LITERAL_4(t,y,p,e); -static const XMLCh Whitelist[] = UNICODE_LITERAL_23(W,h,i,t,e,l,i,s,t,M,e,t,a,d,a,t,a,F,i,l,t,e,r); -MetadataProvider::MetadataProvider(const DOMElement* e) +MetadataProvider::MetadataProvider(const DOMElement* e) : m_resolver(NULL) { #ifdef _DEBUG NDC ndc("MetadataProvider"); #endif SAMLConfig& conf=SAMLConfig::getConfig(); - // Locate any default recognized filters. + // Locate any default recognized filters and plugins. try { DOMElement* child = e ? XMLHelper::getFirstChildElement(e) : NULL; while (child) { - if (XMLString::equals(child->getLocalName(),GenericMetadataFilter)) { + if (!m_resolver && XMLString::equals(child->getLocalName(),GenericKeyResolver)) { + auto_ptr_char t(child->getAttributeNS(NULL,type)); + if (t.get()) + m_resolver = XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(t.get(),child); + else + throw UnknownExtensionException(" element found with no type attribute"); + } + else if (XMLString::equals(child->getLocalName(),GenericMetadataFilter)) { auto_ptr_char t(child->getAttributeNS(NULL,type)); if (t.get()) m_filters.push_back(conf.MetadataFilterManager.newPlugin(t.get(),child)); + else + throw UnknownExtensionException(" element found with no type attribute"); + } + else if (XMLString::equals(child->getLocalName(),SigFilter)) { + m_filters.push_back(conf.MetadataFilterManager.newPlugin(SIGNATURE_METADATA_FILTER,child)); } else if (XMLString::equals(child->getLocalName(),Whitelist)) { m_filters.push_back(conf.MetadataFilterManager.newPlugin(WHITELIST_METADATA_FILTER,child)); @@ -68,9 +111,14 @@ MetadataProvider::MetadataProvider(const DOMElement* e) } child = XMLHelper::getNextSiblingElement(child); } + + if (!m_resolver) { + m_resolver = XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(INLINE_KEY_RESOLVER, child); + } } catch (XMLToolingException& ex) { - Category::getInstance(SAML_LOGCAT".Metadata").error("caught exception while installing filters: %s", ex.what()); + Category::getInstance(SAML_LOGCAT".Metadata").error("caught exception while installing plugins and filters: %s", ex.what()); + delete m_resolver; for_each(m_filters.begin(),m_filters.end(),xmltooling::cleanup()); throw; } @@ -78,6 +126,7 @@ MetadataProvider::MetadataProvider(const DOMElement* e) MetadataProvider::~MetadataProvider() { + delete m_resolver; for_each(m_filters.begin(),m_filters.end(),xmltooling::cleanup()); } @@ -93,24 +142,137 @@ void MetadataProvider::doFilters(XMLObject& xmlObject) const } } -namespace opensaml { - namespace saml2md { - SAML_DLLLOCAL PluginManager::Factory FilesystemMetadataProviderFactory; - SAML_DLLLOCAL PluginManager::Factory BlacklistMetadataFilterFactory; - SAML_DLLLOCAL PluginManager::Factory WhitelistMetadataFilterFactory; - }; -}; +void MetadataProvider::index(EntityDescriptor* site, time_t validUntil) +{ + if (validUntil < site->getValidUntilEpoch()) + site->setValidUntil(validUntil); -void SAML_API opensaml::saml2md::registerMetadataProviders() + auto_ptr_char id(site->getEntityID()); + if (id.get()) { + m_sites.insert(make_pair(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)) { + // 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++) { + SourceID* sid=dynamic_cast(*ext); + if (sid) { + auto_ptr_char sourceid(sid->getID()); + if (sourceid.get()) { + m_sources.insert(pair(sourceid.get(),site)); + break; + } + } + } + } + + // Hash the ID. + m_sources.insert( + pair(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)); + } + } + + // SAML 2.0? + if ((*i)->hasSupport(SAMLConstants::SAML20P_NS)) { + // Hash the ID. + m_sources.insert( + pair(SAMLConfig::getConfig().hashSHA1(id.get(), true),site) + ); + } + } +} + +void MetadataProvider::index(EntitiesDescriptor* group, time_t validUntil) { - SAMLConfig& conf=SAMLConfig::getConfig(); - conf.MetadataProviderManager.registerFactory(FILESYSTEM_METADATA_PROVIDER, FilesystemMetadataProviderFactory); - conf.MetadataProviderManager.registerFactory("edu.internet2.middleware.shibboleth.metadata.provider.XMLMetadata", FilesystemMetadataProviderFactory); - conf.MetadataProviderManager.registerFactory("edu.internet2.middleware.shibboleth.common.provider.XMLMetadata", FilesystemMetadataProviderFactory); + if (validUntil < group->getValidUntilEpoch()) + group->setValidUntil(validUntil); + + auto_ptr_char name(group->getName()); + if (name.get()) { + m_groups.insert(make_pair(name.get(),group)); + } + + const vector& groups=const_cast(group)->getEntitiesDescriptors(); + for (vector::const_iterator i=groups.begin(); i!=groups.end(); i++) + index(*i,group->getValidUntilEpoch()); + + const vector& sites=const_cast(group)->getEntityDescriptors(); + for (vector::const_iterator j=sites.begin(); j!=sites.end(); j++) + index(*j,group->getValidUntilEpoch()); } -void SAML_API opensaml::saml2md::registerMetadataFilters() +void MetadataProvider::clearDescriptorIndex() { - SAMLConfig::getConfig().MetadataFilterManager.registerFactory(BLACKLIST_METADATA_FILTER, BlacklistMetadataFilterFactory); - SAMLConfig::getConfig().MetadataFilterManager.registerFactory(WHITELIST_METADATA_FILTER, WhitelistMetadataFilterFactory); + m_sources.clear(); + m_sites.clear(); + m_groups.clear(); +} + +const EntitiesDescriptor* MetadataProvider::getEntitiesDescriptor(const char* name, bool strict) const +{ + pair range=m_groups.equal_range(name); + + time_t now=time(NULL); + for (groupmap_t::const_iterator i=range.first; i!=range.second; i++) + if (now < i->second->getValidUntilEpoch()) + return i->second; + + if (!strict && range.first!=range.second) + return range.first->second; + + return NULL; +} + +const EntitiesDescriptor* MetadataProvider::getEntitiesDescriptor(const XMLCh* name, bool strict) const +{ + auto_ptr_char temp(name); + return getEntitiesDescriptor(temp.get(),strict); +} + +const EntityDescriptor* MetadataProvider::getEntityDescriptor(const char* name, bool strict) const +{ + pair range=m_sites.equal_range(name); + + time_t now=time(NULL); + for (sitemap_t::const_iterator i=range.first; i!=range.second; i++) + if (now < i->second->getValidUntilEpoch()) + return i->second; + + if (!strict && range.first!=range.second) + return range.first->second; + + return NULL; +} + +const EntityDescriptor* MetadataProvider::getEntityDescriptor(const XMLCh* name, bool strict) const +{ + auto_ptr_char temp(name); + return getEntityDescriptor(temp.get(),strict); +} + +const EntityDescriptor* MetadataProvider::getEntityDescriptor(const SAMLArtifact* artifact) const +{ + pair range=m_sources.equal_range(artifact->getSource()); + + time_t now=time(NULL); + for (sitemap_t::const_iterator i=range.first; i!=range.second; i++) + if (now < i->second->getValidUntilEpoch()) + return i->second; + + return NULL; }