From 529b003774ec45cad19910b845a52a70d273043d Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Thu, 10 Jul 2008 21:31:13 +0000 Subject: [PATCH] https://issues.shibboleth.net/jira/browse/CPPOST-15 --- saml/saml2/metadata/DynamicMetadataProvider.h | 6 +- .../metadata/impl/DynamicMetadataProvider.cpp | 95 +++++++++++++++------- 2 files changed, 69 insertions(+), 32 deletions(-) diff --git a/saml/saml2/metadata/DynamicMetadataProvider.h b/saml/saml2/metadata/DynamicMetadataProvider.h index fb9968b..21c3d10 100644 --- a/saml/saml2/metadata/DynamicMetadataProvider.h +++ b/saml/saml2/metadata/DynamicMetadataProvider.h @@ -69,12 +69,12 @@ namespace opensaml { time_t m_maxCacheDuration; /** - * Resolves an entityID into a metadata instance for that entity. + * Resolves a metadata instance using the supplied criteria. * - * @param entityID entity ID to resolve + * @param criteria lookup criteria * @return a valid metadata instance */ - virtual EntityDescriptor* resolve(const char* entityID) const; + virtual EntityDescriptor* resolve(const Criteria& criteria) const; private: mutable xmltooling::RWLock* m_lock; diff --git a/saml/saml2/metadata/impl/DynamicMetadataProvider.cpp b/saml/saml2/metadata/impl/DynamicMetadataProvider.cpp index 4ccd536..2db9a48 100644 --- a/saml/saml2/metadata/impl/DynamicMetadataProvider.cpp +++ b/saml/saml2/metadata/impl/DynamicMetadataProvider.cpp @@ -53,13 +53,16 @@ namespace opensaml { }; DynamicMetadataProvider::DynamicMetadataProvider(const DOMElement* e) - : AbstractMetadataProvider(e), m_maxCacheDuration(0), m_lock(RWLock::create()) + : AbstractMetadataProvider(e), m_maxCacheDuration(28800), m_lock(RWLock::create()) { const XMLCh* flag=e ? e->getAttributeNS(NULL,validate) : NULL; m_validate=(XMLString::equals(flag,xmlconstants::XML_TRUE) || XMLString::equals(flag,xmlconstants::XML_ONE)); flag = e ? e->getAttributeNS(NULL,maxCacheDuration) : NULL; - if (flag && *flag) + if (flag && *flag) { m_maxCacheDuration = XMLString::parseInt(flag); + if (m_maxCacheDuration == 0) + m_maxCacheDuration = 28800; + } } DynamicMetadataProvider::~DynamicMetadataProvider() @@ -91,41 +94,81 @@ pair DynamicMetadataProvider::get Category& log = Category::getInstance(SAML_LOGCAT".MetadataProvider.Dynamic"); log.info("resolving metadata for (%s)", name.c_str()); - // Try resolving it. - auto_ptr entity2(resolve(name.c_str())); + try { + // Try resolving it. + auto_ptr entity2(resolve(criteria)); - // Filter it, which may throw. - doFilters(*entity2.get()); + // Verify the entityID. + if (criteria.entityID_unicode && !XMLString::equals(criteria.entityID_unicode, entity2->getEntityID())) { + Category::getInstance(SAML_LOGCAT".MetadataProvider.Dynamic").error("metadata instance did not match expected entityID"); + return entity; + } + else { + auto_ptr_XMLCh temp2(name.c_str()); + if (!XMLString::equals(temp2.get(), entity2->getEntityID())) { + Category::getInstance(SAML_LOGCAT".MetadataProvider.Dynamic").error("metadata instance did not match expected entityID"); + return entity; + } + } - log.info("caching resolved metadata for (%s)", name.c_str()); + // Filter it, which may throw. + doFilters(*entity2.get()); - // Translate cacheDuration into validUntil. - if (entity2->getCacheDuration()) - entity2->setValidUntil(time(NULL) + min(m_maxCacheDuration, entity2->getCacheDurationEpoch())); + log.info("caching resolved metadata for (%s)", name.c_str()); + + // Translate cacheDuration into validUntil. + time_t exp = m_maxCacheDuration; + if (entity2->getCacheDuration()) + exp = min(m_maxCacheDuration, entity2->getCacheDurationEpoch()); + exp += time(NULL); + if (entity2->getValidUntil()) { + if (exp < entity2->getValidUntilEpoch()) + entity2->setValidUntil(exp); + } + else { + entity2->setValidUntil(exp); + } - // Upgrade our lock so we can cache the new metadata. - m_lock->unlock(); - m_lock->wrlock(); + // Upgrade our lock so we can cache the new metadata. + m_lock->unlock(); + m_lock->wrlock(); - // Notify observers. - emitChangeEvent(); + // Notify observers. + emitChangeEvent(); - // Make sure we clear out any existing copies, including stale metadata or if somebody snuck in. - index(entity2.release(), SAMLTIME_MAX, true); + // Make sure we clear out any existing copies, including stale metadata or if somebody snuck in. + index(entity2.release(), SAMLTIME_MAX, true); - // Downgrade back to a read lock. - m_lock->unlock(); - m_lock->rdlock(); + // Downgrade back to a read lock. + m_lock->unlock(); + m_lock->rdlock(); + } + catch (exception& e) { + Category::getInstance(SAML_LOGCAT".MetadataProvider.Dynamic").error( + "error while resolving entityID (%s): %s", name.c_str(), e.what() + ); + return entity; + } // Rinse and repeat. return getEntityDescriptor(criteria); } -EntityDescriptor* DynamicMetadataProvider::resolve(const char* entityID) const +EntityDescriptor* DynamicMetadataProvider::resolve(const Criteria& criteria) const { + string name; + if (criteria.entityID_ascii) + name = criteria.entityID_ascii; + else if (criteria.entityID_unicode) { + auto_ptr_char temp(criteria.entityID_unicode); + name = temp.get(); + } + else if (criteria.artifact) + name = criteria.artifact->getSource(); + try { DOMDocument* doc=NULL; - auto_ptr_XMLCh widenit(entityID); + auto_ptr_XMLCh widenit(name.c_str()); URLInputSource src(widenit.get()); Wrapper4InputSource dsrc(&src,false); if (m_validate) @@ -153,14 +196,8 @@ EntityDescriptor* DynamicMetadataProvider::resolve(const char* entityID) const catch (XMLException& e) { auto_ptr_char msg(e.getMessage()); Category::getInstance(SAML_LOGCAT".MetadataProvider.Dynamic").error( - "Xerces error while resolving entityID (%s): %s", entityID, msg.get() + "Xerces error while resolving entityID (%s): %s", name.c_str(), msg.get() ); throw MetadataException(msg.get()); } - catch (exception& e) { - Category::getInstance(SAML_LOGCAT".MetadataProvider.Dynamic").error( - "error while resolving entityID (%s): %s", entityID, e.what() - ); - throw; - } } -- 2.1.4