Collapse entity/role lookup in metadata API.
authorScott Cantor <cantor.2@osu.edu>
Thu, 8 Nov 2007 06:45:17 +0000 (06:45 +0000)
committerScott Cantor <cantor.2@osu.edu>
Thu, 8 Nov 2007 06:45:17 +0000 (06:45 +0000)
22 files changed:
saml/saml1/binding/impl/SAML1ArtifactDecoder.cpp
saml/saml1/binding/impl/SAML1MessageDecoder.cpp
saml/saml2/binding/impl/SAML2ArtifactDecoder.cpp
saml/saml2/binding/impl/SAML2MessageDecoder.cpp
saml/saml2/metadata/AbstractMetadataProvider.h
saml/saml2/metadata/ChainingMetadataProvider.h
saml/saml2/metadata/DynamicMetadataProvider.h
saml/saml2/metadata/MetadataProvider.h
saml/saml2/metadata/impl/AbstractMetadataProvider.cpp
saml/saml2/metadata/impl/ChainingMetadataProvider.cpp
saml/saml2/metadata/impl/DynamicMetadataProvider.cpp
saml/saml2/metadata/impl/MetadataProvider.cpp
samlsign/samlsign.cpp
samltest/encryption/EncryptedAssertionTest.h
samltest/saml1/binding/SAML1ArtifactTest.h
samltest/saml1/binding/SAML1POSTTest.h
samltest/saml2/binding/SAML2ArtifactTest.h
samltest/saml2/binding/SAML2POSTTest.h
samltest/saml2/binding/SAML2RedirectTest.h
samltest/saml2/metadata/XMLMetadataProviderTest.h
samltest/security/ExplicitKeyTrustEngineTest.h
samltest/security/StaticPKIXTrustEngineTest.h

index 87b6f8c..cbaf9a5 100644 (file)
@@ -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<const EntityDescriptor*,const RoleDescriptor*> 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<const IDPSSODescriptor*>(roledesc)) {
-        log.error("unable to find compatible SAML role (%s) in metadata", policy.getRole()->toString().c_str());
+    if (!provider.second || !dynamic_cast<const IDPSSODescriptor*>(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<SAMLArtifact>());
         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> response(
-            m_artifactResolver->resolve(artifacts, dynamic_cast<const IDPSSODescriptor&>(*roledesc), policy)
+            m_artifactResolver->resolve(artifacts, dynamic_cast<const IDPSSODescriptor&>(*provider.second), policy)
             );
         
         // The policy should be enforced against the Response by the resolve step.
index 7a59796..8fe02a1 100644 (file)
@@ -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<const EntityDescriptor*,const RoleDescriptor*> 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);
     }
 }
index 1bb7af2..cb83ce7 100644 (file)
@@ -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<const EntityDescriptor*,const RoleDescriptor*> 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<const SSODescriptorType*>(roledesc)) {
-        log.error("unable to find compatible SAML role (%s) in metadata", policy.getRole()->toString().c_str());
+    if (!provider.second || !dynamic_cast<const SSODescriptorType*>(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<ArtifactResponse> response(
-        m_artifactResolver->resolve(*(artifact2.get()), dynamic_cast<const SSODescriptorType&>(*roledesc), policy)
+        m_artifactResolver->resolve(*(artifact2.get()), dynamic_cast<const SSODescriptorType&>(*provider.second), policy)
         );
     
     // The policy should be enforced against the ArtifactResponse by the resolve step.
index d9d21fd..97a38ac 100644 (file)
@@ -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<const EntityDescriptor*,const RoleDescriptor*> 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&) {
index 806347f..50d00f1 100644 (file)
@@ -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<const EntityDescriptor*,const RoleDescriptor*> 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<const xmltooling::Credential*>::size_type resolve(
index 5dc0f46..2e24646 100644 (file)
@@ -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<const EntityDescriptor*,const RoleDescriptor*> getEntityDescriptor(const Criteria& criteria) const;
             void onEvent(const ObservableMetadataProvider& provider) const;
     
             const xmltooling::Credential* resolve(const xmltooling::CredentialCriteria* criteria=NULL) const;
index 44b622b..7ca322c 100644 (file)
@@ -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<const EntityDescriptor*,const RoleDescriptor*> getEntityDescriptor(const Criteria& criteria) const;
 
         protected:
             /** Controls XML schema validation. */
index 2e9b4b9..483d05c 100644 (file)
@@ -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<const EntityDescriptor*,const RoleDescriptor*> getEntityDescriptor(const Criteria& criteria) const=0;
+
         protected:
             /**
              * Applies any installed filters to a metadata instance.
index 6508e58..7fa8431 100644 (file)
@@ -176,31 +176,42 @@ const EntitiesDescriptor* AbstractMetadataProvider::getEntitiesDescriptor(const
     return NULL;
 }
 
-const EntityDescriptor* AbstractMetadataProvider::getEntityDescriptor(const char* name, bool strict) const
+pair<const EntityDescriptor*,const RoleDescriptor*> AbstractMetadataProvider::getEntityDescriptor(const Criteria& criteria) const
 {
-    pair<sitemap_t::const_iterator,sitemap_t::const_iterator> range=m_sites.equal_range(name);
-
+    pair<sitemap_t::const_iterator,sitemap_t::const_iterator> 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<const EntityDescriptor*,const RoleDescriptor*>(NULL,NULL);
+    
+    pair<const EntityDescriptor*,const RoleDescriptor*> 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<sitemap_t::const_iterator,sitemap_t::const_iterator> 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
index ff7bc0a..9f90400 100644 (file)
@@ -138,16 +138,18 @@ const EntitiesDescriptor* ChainingMetadataProvider::getEntitiesDescriptor(const
     return NULL;
 }
 
-const EntityDescriptor* ChainingMetadataProvider::getEntityDescriptor(const char* id, bool requireValidMetadata) const
+pair<const EntityDescriptor*,const RoleDescriptor*> ChainingMetadataProvider::getEntityDescriptor(const Criteria& criteria) const
 {
     // Clear any existing lock.
     const_cast<ChainingMetadataProvider*>(this)->unlock();
 
     // Do a search.
-    const EntityDescriptor* ret=NULL;
+    pair<const EntityDescriptor*,const RoleDescriptor*> ret;
+    ret.first = NULL;
+    ret.second = NULL;
     for (vector<MetadataProvider*>::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<ChainingMetadataProvider*>(this)->unlock();
-
-    // Do a search.
-    const EntityDescriptor* ret=NULL;
-    for (vector<MetadataProvider*>::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
index 7078fac..288dd12 100644 (file)
@@ -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<const EntityDescriptor*,const RoleDescriptor*> DynamicMetadataProvider::getEntityDescriptor(const Criteria& criteria) const
 {
     // Check cache while holding the read lock.
-    const EntityDescriptor* entity = AbstractMetadataProvider::getEntityDescriptor(name, strict);
-    if (entity)
+    pair<const EntityDescriptor*,const RoleDescriptor*> 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<EntityDescriptor> entity2(resolve(name));
+    auto_ptr<EntityDescriptor> 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
index 62665a0..969be5a 100644 (file)
@@ -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);
-}
index 91c7b9a..9cdaa91 100644 (file)
@@ -293,18 +293,19 @@ int main(int argc,char* argv[])
                     auto_ptr<MetadataProvider> 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<const EntityDescriptor*,const RoleDescriptor*> 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
index 2fa9f93..3a6fba0 100644 (file)
@@ -112,11 +112,11 @@ public:
         // Now encrypt this puppy to the SP role in the example metadata.
         auto_ptr<EncryptedAssertion> 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<const EntityDescriptor*,const RoleDescriptor*> 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<const MetadataProvider*,MetadataCredentialCriteria*> > recipients(
             1, pair<const MetadataProvider*,MetadataCredentialCriteria*>(m_metadata, &mcc)
             );
@@ -132,7 +132,7 @@ public:
         
         // Unpack, then decypt with our key.
         auto_ptr<EncryptedAssertion> encrypted2(dynamic_cast<EncryptedAssertion*>(b->buildFromDocument(doc)));
-        auto_ptr<Assertion> assertion2(dynamic_cast<Assertion*>(encrypted2->decrypt(*m_resolver, sp->getEntityID())));
+        auto_ptr<Assertion> assertion2(dynamic_cast<Assertion*>(encrypted2->decrypt(*m_resolver, sp.first->getEntityID())));
         assertEquals("Unmarshalled assertion does not match", expectedChildElementsDOM, assertion2.get(), false);
         
         // And check the signature.
index 55b6bdf..03a0972 100644 (file)
@@ -66,7 +66,13 @@ public:
                 );\r
             Locker locker(m_metadata);\r
             encoder->encode(\r
-                *this,toSend.get(),"https://sp.example.org/SAML/SSO",m_metadata->getEntityDescriptor("https://sp.example.org/"),"state",this,cred\r
+                *this,\r
+                toSend.get(),\r
+                "https://sp.example.org/SAML/SSO",\r
+                m_metadata->getEntityDescriptor(MetadataProvider::Criteria("https://sp.example.org/")).first,\r
+                "state",\r
+                this,\r
+                cred\r
                 );\r
             toSend.release();\r
             \r
index 611da59..39941e7 100644 (file)
@@ -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();
             
index 77a419b..f76c337 100644 (file)
@@ -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();
             
index cce2a12..f03fbce 100644 (file)
@@ -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();
             
index 862d75d..6c4ba21 100644 (file)
@@ -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();
             
index 747d89e..582a0a3 100644 (file)
@@ -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<SAML2ArtifactType0004> 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());
     }
index 0af1958..c014404 100644 (file)
@@ -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<SignatureTrustEngine*>(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();
index fdc44dc..db584c1 100644 (file)
@@ -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<SignatureTrustEngine*>(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();