From 5cd3da8d9bd792f4a24372ab8e6d24b8409df41a Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Thu, 8 Nov 2007 06:45:17 +0000 Subject: [PATCH] Collapse entity/role lookup in metadata API. --- saml/saml1/binding/impl/SAML1ArtifactDecoder.cpp | 24 +++-- saml/saml1/binding/impl/SAML1MessageDecoder.cpp | 21 +++-- saml/saml2/binding/impl/SAML2ArtifactDecoder.cpp | 19 ++-- saml/saml2/binding/impl/SAML2MessageDecoder.cpp | 13 ++- saml/saml2/metadata/AbstractMetadataProvider.h | 3 +- saml/saml2/metadata/ChainingMetadataProvider.h | 3 +- saml/saml2/metadata/DynamicMetadataProvider.h | 2 +- saml/saml2/metadata/MetadataProvider.h | 102 ++++++++++++++------- .../metadata/impl/AbstractMetadataProvider.cpp | 53 ++++++----- .../metadata/impl/ChainingMetadataProvider.cpp | 30 ++---- .../metadata/impl/DynamicMetadataProvider.cpp | 27 ++++-- saml/saml2/metadata/impl/MetadataProvider.cpp | 6 -- samlsign/samlsign.cpp | 15 +-- samltest/encryption/EncryptedAssertionTest.h | 12 +-- samltest/saml1/binding/SAML1ArtifactTest.h | 8 +- samltest/saml1/binding/SAML1POSTTest.h | 8 +- samltest/saml2/binding/SAML2ArtifactTest.h | 8 +- samltest/saml2/binding/SAML2POSTTest.h | 16 +++- samltest/saml2/binding/SAML2RedirectTest.h | 8 +- samltest/saml2/metadata/XMLMetadataProviderTest.h | 16 ++-- samltest/security/ExplicitKeyTrustEngineTest.h | 4 +- samltest/security/StaticPKIXTrustEngineTest.h | 4 +- 22 files changed, 233 insertions(+), 169 deletions(-) diff --git a/saml/saml1/binding/impl/SAML1ArtifactDecoder.cpp b/saml/saml1/binding/impl/SAML1ArtifactDecoder.cpp index 87b6f8c..cbaf9a5 100644 --- a/saml/saml1/binding/impl/SAML1ArtifactDecoder.cpp +++ b/saml/saml1/binding/impl/SAML1ArtifactDecoder.cpp @@ -119,8 +119,10 @@ XMLObject* SAML1ArtifactDecoder::decode( } log.debug("attempting to determine source of artifact(s)..."); - const EntityDescriptor* provider=policy.getMetadataProvider()->getEntityDescriptor(artifacts.front()); - if (!provider) { + MetadataProvider::Criteria mc(artifacts.front(), policy.getRole(), samlconstants::SAML11_PROTOCOL_ENUM); + mc.protocol2 = samlconstants::SAML10_PROTOCOL_ENUM; + pair provider=policy.getMetadataProvider()->getEntityDescriptor(mc); + if (!provider.first) { log.error( "metadata lookup failed, unable to determine issuer of artifact (0x%s)", SAMLArtifact::toHex(artifacts.front()->getBytes()).c_str() @@ -130,27 +132,23 @@ XMLObject* SAML1ArtifactDecoder::decode( } if (log.isDebugEnabled()) { - auto_ptr_char issuer(provider->getEntityID()); - log.debug("lookup succeeded, artifact issued by (%s)", issuer.get()); + auto_ptr_char issuer(provider.first->getEntityID()); + log.debug("artifact issued by (%s)", issuer.get()); } - log.debug("attempting to find artifact issuing role..."); - const RoleDescriptor* roledesc=provider->getRoleDescriptor(*(policy.getRole()), samlconstants::SAML11_PROTOCOL_ENUM); - if (!roledesc) - roledesc=provider->getRoleDescriptor(*(policy.getRole()), samlconstants::SAML10_PROTOCOL_ENUM); - if (!roledesc || !dynamic_cast(roledesc)) { - log.error("unable to find compatible SAML role (%s) in metadata", policy.getRole()->toString().c_str()); + if (!provider.second || !dynamic_cast(provider.second)) { + log.error("unable to find compatible SAML 1.x role (%s) in metadata", policy.getRole()->toString().c_str()); for_each(artifacts.begin(), artifacts.end(), xmltooling::cleanup()); throw BindingException("Unable to find compatible metadata role for artifact issuer."); } // Set Issuer for the policy. - policy.setIssuer(provider->getEntityID()); - policy.setIssuerMetadata(roledesc); + policy.setIssuer(provider.first->getEntityID()); + policy.setIssuerMetadata(provider.second); try { log.debug("calling ArtifactResolver..."); auto_ptr response( - m_artifactResolver->resolve(artifacts, dynamic_cast(*roledesc), policy) + m_artifactResolver->resolve(artifacts, dynamic_cast(*provider.second), policy) ); // The policy should be enforced against the Response by the resolve step. diff --git a/saml/saml1/binding/impl/SAML1MessageDecoder.cpp b/saml/saml1/binding/impl/SAML1MessageDecoder.cpp index 7a59796..8fe02a1 100644 --- a/saml/saml1/binding/impl/SAML1MessageDecoder.cpp +++ b/saml/saml1/binding/impl/SAML1MessageDecoder.cpp @@ -93,18 +93,19 @@ void SAML1MessageDecoder::extractMessageDetails( if (policy.getMetadataProvider() && policy.getRole()) { log.debug("searching metadata for response issuer..."); - const EntityDescriptor* entity = policy.getMetadataProvider()->getEntityDescriptor(issuer); - if (entity) { - log.debug("matched response issuer against metadata, searching for applicable role..."); - const RoleDescriptor* roledesc=entity->getRoleDescriptor(*policy.getRole(), protocol); - if (roledesc) - policy.setIssuerMetadata(roledesc); - else if (log.isWarnEnabled()) - log.warn("unable to find compatible role (%s) in metadata", policy.getRole()->toString().c_str()); - } - else if (log.isWarnEnabled()) { + + MetadataProvider::Criteria mc(issuer, policy.getRole(), protocol); + pair entity = policy.getMetadataProvider()->getEntityDescriptor(mc); + + if (!entity.first) { auto_ptr_char iname(issuer); log.warn("no metadata found, can't establish identity of issuer (%s)", iname.get()); + return; + } + else if (!entity.second) { + log.warn("unable to find compatible role (%s) in metadata", policy.getRole()->toString().c_str()); + return; } + policy.setIssuerMetadata(entity.second); } } diff --git a/saml/saml2/binding/impl/SAML2ArtifactDecoder.cpp b/saml/saml2/binding/impl/SAML2ArtifactDecoder.cpp index 1bb7af2..cb83ce7 100644 --- a/saml/saml2/binding/impl/SAML2ArtifactDecoder.cpp +++ b/saml/saml2/binding/impl/SAML2ArtifactDecoder.cpp @@ -119,8 +119,9 @@ XMLObject* SAML2ArtifactDecoder::decode( } log.debug("attempting to determine source of artifact..."); - const EntityDescriptor* provider=policy.getMetadataProvider()->getEntityDescriptor(artifact); - if (!provider) { + MetadataProvider::Criteria mc(artifact, policy.getRole(), samlconstants::SAML20P_NS); + pair provider=policy.getMetadataProvider()->getEntityDescriptor(mc); + if (!provider.first) { log.error( "metadata lookup failed, unable to determine issuer of artifact (0x%s)", SAMLArtifact::toHex(artifact->getBytes()).c_str() @@ -129,23 +130,21 @@ XMLObject* SAML2ArtifactDecoder::decode( } if (log.isDebugEnabled()) { - auto_ptr_char issuer(provider->getEntityID()); + auto_ptr_char issuer(provider.first->getEntityID()); log.debug("lookup succeeded, artifact issued by (%s)", issuer.get()); } - log.debug("attempting to find artifact issuing role..."); - const RoleDescriptor* roledesc=provider->getRoleDescriptor(*(policy.getRole()), samlconstants::SAML20P_NS); - if (!roledesc || !dynamic_cast(roledesc)) { - log.error("unable to find compatible SAML role (%s) in metadata", policy.getRole()->toString().c_str()); + if (!provider.second || !dynamic_cast(provider.second)) { + log.error("unable to find compatible SAML 2.0 role (%s) in metadata", policy.getRole()->toString().c_str()); throw BindingException("Unable to find compatible metadata role for artifact issuer."); } // Set issuer into policy. - policy.setIssuer(provider->getEntityID()); - policy.setIssuerMetadata(roledesc); + policy.setIssuer(provider.first->getEntityID()); + policy.setIssuerMetadata(provider.second); log.debug("calling ArtifactResolver..."); auto_ptr response( - m_artifactResolver->resolve(*(artifact2.get()), dynamic_cast(*roledesc), policy) + m_artifactResolver->resolve(*(artifact2.get()), dynamic_cast(*provider.second), policy) ); // The policy should be enforced against the ArtifactResponse by the resolve step. diff --git a/saml/saml2/binding/impl/SAML2MessageDecoder.cpp b/saml/saml2/binding/impl/SAML2MessageDecoder.cpp index d9d21fd..97a38ac 100644 --- a/saml/saml2/binding/impl/SAML2MessageDecoder.cpp +++ b/saml/saml2/binding/impl/SAML2MessageDecoder.cpp @@ -91,20 +91,19 @@ void SAML2MessageDecoder::extractMessageDetails( } log.debug("searching metadata for message issuer..."); - const EntityDescriptor* entity = policy.getMetadataProvider()->getEntityDescriptor(issuer->getName()); - if (!entity) { + + MetadataProvider::Criteria mc(issuer->getName(), policy.getRole(), protocol); + pair entity = policy.getMetadataProvider()->getEntityDescriptor(mc); + if (!entity.first) { auto_ptr_char temp(issuer->getName()); log.warn("no metadata found, can't establish identity of issuer (%s)", temp.get()); return; } - - log.debug("matched message issuer against metadata, searching for applicable role..."); - const RoleDescriptor* roledesc=entity->getRoleDescriptor(*policy.getRole(), protocol); - if (!roledesc) { + else if (!entity.second) { log.warn("unable to find compatible role (%s) in metadata", policy.getRole()->toString().c_str()); return; } - policy.setIssuerMetadata(roledesc); + policy.setIssuerMetadata(entity.second); } } catch (bad_cast&) { diff --git a/saml/saml2/metadata/AbstractMetadataProvider.h b/saml/saml2/metadata/AbstractMetadataProvider.h index 806347f..50d00f1 100644 --- a/saml/saml2/metadata/AbstractMetadataProvider.h +++ b/saml/saml2/metadata/AbstractMetadataProvider.h @@ -65,8 +65,7 @@ namespace opensaml { using MetadataProvider::getEntitiesDescriptor; void emitChangeEvent() const; - const EntityDescriptor* getEntityDescriptor(const char* id, bool requireValidMetadata=true) const; - const EntityDescriptor* getEntityDescriptor(const SAMLArtifact* artifact) const; + std::pair getEntityDescriptor(const Criteria& criteria) const; const EntitiesDescriptor* getEntitiesDescriptor(const char* name, bool requireValidMetadata=true) const; const xmltooling::Credential* resolve(const xmltooling::CredentialCriteria* criteria=NULL) const; std::vector::size_type resolve( diff --git a/saml/saml2/metadata/ChainingMetadataProvider.h b/saml/saml2/metadata/ChainingMetadataProvider.h index 5dc0f46..2e24646 100644 --- a/saml/saml2/metadata/ChainingMetadataProvider.h +++ b/saml/saml2/metadata/ChainingMetadataProvider.h @@ -94,8 +94,7 @@ namespace opensaml { void init(); const xmltooling::XMLObject* getMetadata() const; const EntitiesDescriptor* getEntitiesDescriptor(const char* name, bool requireValidMetadata=true) const; - const EntityDescriptor* getEntityDescriptor(const char* id, bool requireValidMetadata=true) const; - const EntityDescriptor* getEntityDescriptor(const SAMLArtifact* artifact) const; + std::pair getEntityDescriptor(const Criteria& criteria) const; void onEvent(const ObservableMetadataProvider& provider) const; const xmltooling::Credential* resolve(const xmltooling::CredentialCriteria* criteria=NULL) const; diff --git a/saml/saml2/metadata/DynamicMetadataProvider.h b/saml/saml2/metadata/DynamicMetadataProvider.h index 44b622b..7ca322c 100644 --- a/saml/saml2/metadata/DynamicMetadataProvider.h +++ b/saml/saml2/metadata/DynamicMetadataProvider.h @@ -59,7 +59,7 @@ namespace opensaml { throw MetadataException("getMetadata operation not implemented on this provider."); } - const EntityDescriptor* getEntityDescriptor(const char* id, bool requireValidMetadata=true) const; + std::pair getEntityDescriptor(const Criteria& criteria) const; protected: /** Controls XML schema validation. */ diff --git a/saml/saml2/metadata/MetadataProvider.h b/saml/saml2/metadata/MetadataProvider.h index 2e9b4b9..483d05c 100644 --- a/saml/saml2/metadata/MetadataProvider.h +++ b/saml/saml2/metadata/MetadataProvider.h @@ -129,41 +129,6 @@ namespace opensaml { virtual const xmltooling::XMLObject* getMetadata() const=0; /** - * Gets the metadata for a given entity. If a valid entity is returned, - * the provider will be left in a locked state. The caller MUST unlock the - * provider when finished with the entity. - * - * @param id the ID of the entity - * @param requireValidMetadata indicates whether the metadata for the entity must be valid/current - * - * @return the entity's metadata or NULL if there is no metadata or no valid metadata - */ - virtual const EntityDescriptor* getEntityDescriptor(const XMLCh* id, bool requireValidMetadata=true) const; - - /** - * Gets the metadata for a given entity. If a valid entity is returned, - * the provider will be left in a locked state. The caller MUST unlock the - * provider when finished with the entity. - * - * @param id the ID of the entity - * @param requireValidMetadata indicates whether the metadata for the entity must be valid/current - * - * @return the entity's metadata or NULL if there is no metadata or no valid metadata - */ - virtual const EntityDescriptor* getEntityDescriptor(const char* id, bool requireValidMetadata=true) const=0; - - /** - * Gets the metadata for an entity that issued a SAML artifact. If a valid entity is returned, - * the provider will be left in a locked state. The caller MUST unlock the - * provider when finished with the entity. - * - * @param artifact a SAML artifact to find the issuer of - * - * @return the entity's metadata or NULL if there is no valid metadata - */ - virtual const EntityDescriptor* getEntityDescriptor(const SAMLArtifact* artifact) const=0; - - /** * Gets the metadata for a given group of entities. If a valid group is returned, * the resolver will be left in a locked state. The caller MUST unlock the * resolver when finished with the group. @@ -187,6 +152,73 @@ namespace opensaml { */ virtual const EntitiesDescriptor* getEntitiesDescriptor(const char* name, bool requireValidMetadata=true) const=0; + /** + * Batches up criteria for entity lookup. + */ + struct Criteria { + /** + * Constructor. + * + * @param id entityID to lookup + * @param q element/type of role, if any + * @param prot protocol support constant, if any + * @param valid true iff stale metadata should be ignored + */ + Criteria(const XMLCh* id, const xmltooling::QName* q=NULL, const XMLCh* prot=NULL, bool valid=true) + : entityID_unicode(id), entityID_ascii(NULL), artifact(NULL), role(q), protocol(prot), protocol2(NULL), validOnly(valid) { + } + + /** + * Constructor. + * + * @param id entityID to lookup + * @param q element/type of role, if any + * @param prot protocol support constant, if any + * @param valid true iff stale metadata should be ignored + */ + Criteria(const char* id, const xmltooling::QName* q=NULL, const XMLCh* prot=NULL, bool valid=true) + : entityID_unicode(NULL), entityID_ascii(id), artifact(NULL), role(q), protocol(prot), protocol2(NULL), validOnly(valid) { + } + + /** + * Constructor. + * + * @param a artifact to lookup + * @param q element/type of role, if any + * @param prot protocol support constant, if any + * @param valid true iff stale metadata should be ignored + */ + Criteria(const SAMLArtifact* a, const xmltooling::QName* q=NULL, const XMLCh* prot=NULL, bool valid=true) + : entityID_unicode(NULL), entityID_ascii(NULL), artifact(a), role(q), protocol(prot), protocol2(NULL), validOnly(valid) { + } + + /** Unique ID of entity. */ + const XMLCh* entityID_unicode; + /** Unique ID of entity. */ + const char* entityID_ascii; + /** SAML artifact */ + const SAMLArtifact* artifact; + /** Element or schema type QName of metadata role. */ + const xmltooling::QName* role; + /** Protocol support constant. */ + const XMLCh* protocol; + /** Backup protocol support constant. */ + const XMLCh* protocol2; + /** Controls whether stale metadata is ignored. */ + bool validOnly; + }; + + /** + * Gets entity metadata based on supplied criteria. If a valid entity is returned, + * the provider will be left in a locked state. The caller MUST unlock the + * provider when finished with the entity. + * + * @param criteria lookup criteria + * + * @return the entity's metadata (and optionally a role) or NULL if there is no qualifying metadata + */ + virtual std::pair getEntityDescriptor(const Criteria& criteria) const=0; + protected: /** * Applies any installed filters to a metadata instance. diff --git a/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp b/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp index 6508e58..7fa8431 100644 --- a/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp +++ b/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp @@ -176,31 +176,42 @@ const EntitiesDescriptor* AbstractMetadataProvider::getEntitiesDescriptor(const return NULL; } -const EntityDescriptor* AbstractMetadataProvider::getEntityDescriptor(const char* name, bool strict) const +pair AbstractMetadataProvider::getEntityDescriptor(const Criteria& criteria) const { - pair range=m_sites.equal_range(name); - + pair range; + if (criteria.entityID_ascii) + range = m_sites.equal_range(criteria.entityID_ascii); + else if (criteria.entityID_unicode) { + auto_ptr_char id(criteria.entityID_unicode); + range = m_sites.equal_range(id.get()); + } + else if (criteria.artifact) + range = m_sources.equal_range(criteria.artifact->getSource()); + else + return pair(NULL,NULL); + + pair result; + result.first = NULL; + result.second = NULL; + 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; + for (sitemap_t::const_iterator i=range.first; i!=range.second; i++) { + if (now < i->second->getValidUntilEpoch()) { + result.first = i->second; + break; + } + } - if (!strict && range.first!=range.second) - return range.first->second; + if (!result.first && !criteria.validOnly && range.first!=range.second) + result.first = range.first->second; - return NULL; -} - -const EntityDescriptor* AbstractMetadataProvider::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; + if (result.first && criteria.role && criteria.protocol) { + result.second = result.first->getRoleDescriptor(*criteria.role, criteria.protocol); + if (!result.second && criteria.protocol2) + result.second = result.first->getRoleDescriptor(*criteria.role, criteria.protocol2); + } + + return result; } const Credential* AbstractMetadataProvider::resolve(const CredentialCriteria* criteria) const diff --git a/saml/saml2/metadata/impl/ChainingMetadataProvider.cpp b/saml/saml2/metadata/impl/ChainingMetadataProvider.cpp index ff7bc0a..9f90400 100644 --- a/saml/saml2/metadata/impl/ChainingMetadataProvider.cpp +++ b/saml/saml2/metadata/impl/ChainingMetadataProvider.cpp @@ -138,16 +138,18 @@ const EntitiesDescriptor* ChainingMetadataProvider::getEntitiesDescriptor(const return NULL; } -const EntityDescriptor* ChainingMetadataProvider::getEntityDescriptor(const char* id, bool requireValidMetadata) const +pair ChainingMetadataProvider::getEntityDescriptor(const Criteria& criteria) const { // Clear any existing lock. const_cast(this)->unlock(); // Do a search. - const EntityDescriptor* ret=NULL; + pair ret; + ret.first = NULL; + ret.second = NULL; for (vector::const_iterator i=m_providers.begin(); i!=m_providers.end(); ++i) { (*i)->lock(); - if (ret=(*i)->getEntityDescriptor(id,requireValidMetadata)) { + if ((ret=(*i)->getEntityDescriptor(criteria)).first) { // Save locked provider. m_tlsKey->setData(*i); return ret; @@ -155,27 +157,7 @@ const EntityDescriptor* ChainingMetadataProvider::getEntityDescriptor(const char (*i)->unlock(); } - return NULL; -} - -const EntityDescriptor* ChainingMetadataProvider::getEntityDescriptor(const SAMLArtifact* artifact) const -{ - // Clear any existing lock. - const_cast(this)->unlock(); - - // Do a search. - const EntityDescriptor* ret=NULL; - for (vector::const_iterator i=m_providers.begin(); i!=m_providers.end(); ++i) { - (*i)->lock(); - if (ret=(*i)->getEntityDescriptor(artifact)) { - // Save locked provider. - m_tlsKey->setData(*i); - return ret; - } - (*i)->unlock(); - } - - return NULL; + return ret; } const Credential* ChainingMetadataProvider::resolve(const CredentialCriteria* criteria) const diff --git a/saml/saml2/metadata/impl/DynamicMetadataProvider.cpp b/saml/saml2/metadata/impl/DynamicMetadataProvider.cpp index 7078fac..288dd12 100644 --- a/saml/saml2/metadata/impl/DynamicMetadataProvider.cpp +++ b/saml/saml2/metadata/impl/DynamicMetadataProvider.cpp @@ -21,6 +21,7 @@ */ #include "internal.h" +#include "binding/SAMLArtifact.h" #include "saml2/metadata/Metadata.h" #include "saml2/metadata/DynamicMetadataProvider.h" @@ -60,23 +61,35 @@ DynamicMetadataProvider::~DynamicMetadataProvider() delete m_lock; } -const EntityDescriptor* DynamicMetadataProvider::getEntityDescriptor(const char* name, bool strict) const +pair DynamicMetadataProvider::getEntityDescriptor(const Criteria& criteria) const { // Check cache while holding the read lock. - const EntityDescriptor* entity = AbstractMetadataProvider::getEntityDescriptor(name, strict); - if (entity) + pair entity = AbstractMetadataProvider::getEntityDescriptor(criteria); + if (entity.first) // even if the role isn't found, we're done + return entity; + + 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(); + else return entity; Category& log = Category::getInstance(SAML_LOGCAT".MetadataProvider.Dynamic"); - log.info("resolving metadata for (%s)", name); + log.info("resolving metadata for (%s)", name.c_str()); // Try resolving it. - auto_ptr entity2(resolve(name)); + auto_ptr entity2(resolve(name.c_str())); // Filter it, which may throw. doFilters(*entity2.get()); - log.info("caching resolved metadata for (%s)", name); + log.info("caching resolved metadata for (%s)", name.c_str()); // Translate cacheDuration into validUntil. if (entity2->getCacheDuration()) @@ -97,7 +110,7 @@ const EntityDescriptor* DynamicMetadataProvider::getEntityDescriptor(const char* m_lock->rdlock(); // Rinse and repeat. - return getEntityDescriptor(name, strict); + return getEntityDescriptor(criteria); } EntityDescriptor* DynamicMetadataProvider::resolve(const char* entityID) const diff --git a/saml/saml2/metadata/impl/MetadataProvider.cpp b/saml/saml2/metadata/impl/MetadataProvider.cpp index 62665a0..969be5a 100644 --- a/saml/saml2/metadata/impl/MetadataProvider.cpp +++ b/saml/saml2/metadata/impl/MetadataProvider.cpp @@ -140,9 +140,3 @@ const EntitiesDescriptor* MetadataProvider::getEntitiesDescriptor(const XMLCh* n auto_ptr_char temp(name); return getEntitiesDescriptor(temp.get(),strict); } - -const EntityDescriptor* MetadataProvider::getEntityDescriptor(const XMLCh* name, bool strict) const -{ - auto_ptr_char temp(name); - return getEntityDescriptor(temp.get(),strict); -} diff --git a/samlsign/samlsign.cpp b/samlsign/samlsign.cpp index 91c7b9a..9cdaa91 100644 --- a/samlsign/samlsign.cpp +++ b/samlsign/samlsign.cpp @@ -293,18 +293,19 @@ int main(int argc,char* argv[]) auto_ptr metadata(buildPlugin(m_param, conf.MetadataProviderManager)); metadata->init(); - Locker locker(metadata.get()); - const EntityDescriptor* entity = metadata->getEntityDescriptor(issuer); - if (!entity) - throw MetadataException("no metadata found for ($1)", params(1, issuer)); const XMLCh* ns = rns ? XMLString::transcode(rns) : samlconstants::SAML20MD_NS; auto_ptr_XMLCh n(rname); QName q(ns, n.get()); - const RoleDescriptor* role = entity->getRoleDescriptor(q, protocol); - if (!role) + + Locker locker(metadata.get()); + MetadataProvider::Criteria mc(issuer, &q, protocol); + pair entity = metadata->getEntityDescriptor(mc); + if (!entity.first) + throw MetadataException("no metadata found for ($1)", params(1, issuer)); + else if (!entity.second) throw MetadataException("compatible role $1 not found for ($2)", params(2, q.toString().c_str(), issuer)); - MetadataCredentialCriteria mcc(*role); + MetadataCredentialCriteria mcc(*entity.second); if (sigtrust->validate(*signable->getSignature(), *metadata.get(), &mcc)) log.info("successful signature verification"); else diff --git a/samltest/encryption/EncryptedAssertionTest.h b/samltest/encryption/EncryptedAssertionTest.h index 2fa9f93..3a6fba0 100644 --- a/samltest/encryption/EncryptedAssertionTest.h +++ b/samltest/encryption/EncryptedAssertionTest.h @@ -112,11 +112,11 @@ public: // Now encrypt this puppy to the SP role in the example metadata. auto_ptr encrypted(EncryptedAssertionBuilder::buildEncryptedAssertion()); Locker mlocker(m_metadata); - const EntityDescriptor* sp = m_metadata->getEntityDescriptor("https://sp.example.org/"); - TSM_ASSERT("No metadata for recipient.", sp!=NULL); - const SPSSODescriptor* sprole = sp->getSPSSODescriptor(samlconstants::SAML20P_NS); - TSM_ASSERT("No SP role for recipient.", sprole!=NULL); - MetadataCredentialCriteria mcc(*sprole); + MetadataProvider::Criteria mc("https://sp.example.org/", &SPSSODescriptor::ELEMENT_QNAME, samlconstants::SAML20P_NS); + pair sp = m_metadata->getEntityDescriptor(mc); + TSM_ASSERT("No metadata for recipient.", sp.first!=NULL); + TSM_ASSERT("No SP role for recipient.", sp.second!=NULL); + MetadataCredentialCriteria mcc(*sp.second); vector< pair > recipients( 1, pair(m_metadata, &mcc) ); @@ -132,7 +132,7 @@ public: // Unpack, then decypt with our key. auto_ptr encrypted2(dynamic_cast(b->buildFromDocument(doc))); - auto_ptr assertion2(dynamic_cast(encrypted2->decrypt(*m_resolver, sp->getEntityID()))); + auto_ptr assertion2(dynamic_cast(encrypted2->decrypt(*m_resolver, sp.first->getEntityID()))); assertEquals("Unmarshalled assertion does not match", expectedChildElementsDOM, assertion2.get(), false); // And check the signature. diff --git a/samltest/saml1/binding/SAML1ArtifactTest.h b/samltest/saml1/binding/SAML1ArtifactTest.h index 55b6bdf..03a0972 100644 --- a/samltest/saml1/binding/SAML1ArtifactTest.h +++ b/samltest/saml1/binding/SAML1ArtifactTest.h @@ -66,7 +66,13 @@ public: ); Locker locker(m_metadata); encoder->encode( - *this,toSend.get(),"https://sp.example.org/SAML/SSO",m_metadata->getEntityDescriptor("https://sp.example.org/"),"state",this,cred + *this, + toSend.get(), + "https://sp.example.org/SAML/SSO", + m_metadata->getEntityDescriptor(MetadataProvider::Criteria("https://sp.example.org/")).first, + "state", + this, + cred ); toSend.release(); diff --git a/samltest/saml1/binding/SAML1POSTTest.h b/samltest/saml1/binding/SAML1POSTTest.h index 611da59..39941e7 100644 --- a/samltest/saml1/binding/SAML1POSTTest.h +++ b/samltest/saml1/binding/SAML1POSTTest.h @@ -74,7 +74,13 @@ public: Locker locker(m_metadata); encoder->encode( - *this,toSend.get(),"https://sp.example.org/SAML/SSO",m_metadata->getEntityDescriptor("https://sp.example.org/"),"state",NULL,cred + *this, + toSend.get(), + "https://sp.example.org/SAML/SSO", + m_metadata->getEntityDescriptor(MetadataProvider::Criteria("https://sp.example.org/")).first, + "state", + NULL, + cred ); toSend.release(); diff --git a/samltest/saml2/binding/SAML2ArtifactTest.h b/samltest/saml2/binding/SAML2ArtifactTest.h index 77a419b..f76c337 100644 --- a/samltest/saml2/binding/SAML2ArtifactTest.h +++ b/samltest/saml2/binding/SAML2ArtifactTest.h @@ -68,7 +68,13 @@ public: ); Locker locker(m_metadata); encoder->encode( - *this,toSend.get(),"https://sp.example.org/SAML/SSO",m_metadata->getEntityDescriptor("https://sp.example.org/"),"state",this,cred + *this, + toSend.get(), + "https://sp.example.org/SAML/SSO", + m_metadata->getEntityDescriptor(MetadataProvider::Criteria("https://sp.example.org/")).first, + "state", + this, + cred ); toSend.release(); diff --git a/samltest/saml2/binding/SAML2POSTTest.h b/samltest/saml2/binding/SAML2POSTTest.h index cce2a12..f03fbce 100644 --- a/samltest/saml2/binding/SAML2POSTTest.h +++ b/samltest/saml2/binding/SAML2POSTTest.h @@ -73,7 +73,13 @@ public: ); Locker locker(m_metadata); encoder->encode( - *this,toSend.get(),"https://sp.example.org/SAML/SSO",m_metadata->getEntityDescriptor("https://sp.example.org/"),"state",NULL,cred + *this, + toSend.get(), + "https://sp.example.org/SAML/SSO", + m_metadata->getEntityDescriptor(MetadataProvider::Criteria("https://sp.example.org/")).first, + "state", + NULL, + cred ); toSend.release(); @@ -146,7 +152,13 @@ public: ); Locker locker(m_metadata); encoder->encode( - *this,toSend.get(),"https://sp.example.org/SAML/SSO",m_metadata->getEntityDescriptor("https://sp.example.org/"),"state",NULL,cred + *this, + toSend.get(), + "https://sp.example.org/SAML/SSO", + m_metadata->getEntityDescriptor(MetadataProvider::Criteria("https://sp.example.org/")).first, + "state", + NULL, + cred ); toSend.release(); diff --git a/samltest/saml2/binding/SAML2RedirectTest.h b/samltest/saml2/binding/SAML2RedirectTest.h index 862d75d..6c4ba21 100644 --- a/samltest/saml2/binding/SAML2RedirectTest.h +++ b/samltest/saml2/binding/SAML2RedirectTest.h @@ -65,7 +65,13 @@ public: ); Locker locker(m_metadata); encoder->encode( - *this,toSend.get(),"https://sp.example.org/SAML/SSO",m_metadata->getEntityDescriptor("https://sp.example.org/"),"state",NULL,cred + *this, + toSend.get(), + "https://sp.example.org/SAML/SSO", + m_metadata->getEntityDescriptor(MetadataProvider::Criteria("https://sp.example.org/")).first, + "state", + NULL, + cred ); toSend.release(); diff --git a/samltest/saml2/metadata/XMLMetadataProviderTest.h b/samltest/saml2/metadata/XMLMetadataProviderTest.h index 747d89e..582a0a3 100644 --- a/samltest/saml2/metadata/XMLMetadataProviderTest.h +++ b/samltest/saml2/metadata/XMLMetadataProviderTest.h @@ -70,17 +70,17 @@ public: } Locker locker(metadataProvider.get()); - const EntityDescriptor* descriptor = metadataProvider->getEntityDescriptor(entityID); + const EntityDescriptor* descriptor = metadataProvider->getEntityDescriptor(MetadataProvider::Criteria(entityID)).first; TSM_ASSERT("Retrieved entity descriptor was null", descriptor!=NULL); assertEquals("Entity's ID does not match requested ID", entityID, descriptor->getEntityID()); TSM_ASSERT_EQUALS("Unexpected number of roles", 1, descriptor->getIDPSSODescriptors().size()); - TSM_ASSERT("Role lookup failed", descriptor->getIDPSSODescriptor(supportedProtocol)!=NULL); - TSM_ASSERT("Role lookup failed", descriptor->getIDPSSODescriptor(supportedProtocol2)!=NULL); + TSM_ASSERT("Role lookup failed", find_if(descriptor->getIDPSSODescriptors(), isValidForProtocol(supportedProtocol))!=NULL); + TSM_ASSERT("Role lookup failed", find_if(descriptor->getIDPSSODescriptors(), isValidForProtocol(supportedProtocol2))!=NULL); auto_ptr artifact( new SAML2ArtifactType0004(SAMLConfig::getConfig().hashSHA1("urn:mace:incommon:washington.edu"),1) ); - descriptor = metadataProvider->getEntityDescriptor(artifact.get()); + descriptor = metadataProvider->getEntityDescriptor(MetadataProvider::Criteria(artifact.get())).first; TSM_ASSERT("Retrieved entity descriptor was null", descriptor!=NULL); assertEquals("Entity's ID does not match requested ID", entityID, descriptor->getEntityID()); } @@ -108,9 +108,9 @@ public: } Locker locker(metadataProvider.get()); - const EntityDescriptor* descriptor = metadataProvider->getEntityDescriptor(entityID); + const EntityDescriptor* descriptor = metadataProvider->getEntityDescriptor(MetadataProvider::Criteria(entityID)).first; TSM_ASSERT("Retrieved entity descriptor was not null", descriptor==NULL); - descriptor = metadataProvider->getEntityDescriptor(entityID2); + descriptor = metadataProvider->getEntityDescriptor(MetadataProvider::Criteria(entityID2)).first; TSM_ASSERT("Retrieved entity descriptor was null", descriptor!=NULL); assertEquals("Entity's ID does not match requested ID", entityID2, descriptor->getEntityID()); } @@ -138,9 +138,9 @@ public: } Locker locker(metadataProvider.get()); - const EntityDescriptor* descriptor = metadataProvider->getEntityDescriptor(entityID2); + const EntityDescriptor* descriptor = metadataProvider->getEntityDescriptor(MetadataProvider::Criteria(entityID2)).first; TSM_ASSERT("Retrieved entity descriptor was not null", descriptor==NULL); - descriptor = metadataProvider->getEntityDescriptor(entityID); + descriptor = metadataProvider->getEntityDescriptor(MetadataProvider::Criteria(entityID)).first; TSM_ASSERT("Retrieved entity descriptor was null", descriptor!=NULL); assertEquals("Entity's ID does not match requested ID", entityID, descriptor->getEntityID()); } diff --git a/samltest/security/ExplicitKeyTrustEngineTest.h b/samltest/security/ExplicitKeyTrustEngineTest.h index 0af1958..c014404 100644 --- a/samltest/security/ExplicitKeyTrustEngineTest.h +++ b/samltest/security/ExplicitKeyTrustEngineTest.h @@ -73,7 +73,7 @@ public: janitor2.release(); Locker locker(metadataProvider.get()); - const EntityDescriptor* descriptor = metadataProvider->getEntityDescriptor("https://idp.example.org"); + const EntityDescriptor* descriptor = metadataProvider->getEntityDescriptor(MetadataProvider::Criteria("https://idp.example.org")).first; TSM_ASSERT("Retrieved entity descriptor was null", descriptor!=NULL); RoleDescriptor* role=descriptor->getIDPSSODescriptors().front(); @@ -86,7 +86,7 @@ public: cc.setPeerName("https://idp.example.org"); TSM_ASSERT("Signature failed to validate.", dynamic_cast(trustEngine.get())->validate(*sig, *metadataProvider, &cc)); - descriptor = metadataProvider->getEntityDescriptor("https://idp2.example.org"); + descriptor = metadataProvider->getEntityDescriptor(MetadataProvider::Criteria("https://idp2.example.org")).first; TSM_ASSERT("Retrieved entity descriptor was null", descriptor!=NULL); role=descriptor->getIDPSSODescriptors().front(); diff --git a/samltest/security/StaticPKIXTrustEngineTest.h b/samltest/security/StaticPKIXTrustEngineTest.h index fdc44dc..db584c1 100644 --- a/samltest/security/StaticPKIXTrustEngineTest.h +++ b/samltest/security/StaticPKIXTrustEngineTest.h @@ -76,7 +76,7 @@ public: janitor3.release(); Locker locker(metadataProvider.get()); - const EntityDescriptor* descriptor = metadataProvider->getEntityDescriptor("https://idp.example.org"); + const EntityDescriptor* descriptor = metadataProvider->getEntityDescriptor(MetadataProvider::Criteria("https://idp.example.org")).first; TSM_ASSERT("Retrieved entity descriptor was null", descriptor!=NULL); RoleDescriptor* role=descriptor->getIDPSSODescriptors().front(); @@ -89,7 +89,7 @@ public: cc.setPeerName("https://idp.example.org"); TSM_ASSERT("Signature failed to validate.", dynamic_cast(trustEngine.get())->validate(*sig, *metadataProvider, &cc)); - descriptor = metadataProvider->getEntityDescriptor("https://idp2.example.org"); + descriptor = metadataProvider->getEntityDescriptor(MetadataProvider::Criteria("https://idp2.example.org")).first; TSM_ASSERT("Retrieved entity descriptor was null", descriptor!=NULL); role=descriptor->getIDPSSODescriptors().front(); -- 2.1.4