X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=saml%2Fsaml2%2Fmetadata%2Fimpl%2FAbstractMetadataProvider.cpp;h=d59e8e2c43ee4f16f0e23a99c16b7fa8cb47a116;hb=b1614d3c1fc1f4230ab2a123f43994127c25462c;hp=46e4297d7238f6bf2d07904220c90ed0ffaa678b;hpb=66136f386ddbdd855e1a078e13e19ddbf64a01e2;p=shibboleth%2Fcpp-opensaml.git diff --git a/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp b/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp index 46e4297..d59e8e2 100644 --- a/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp +++ b/saml/saml2/metadata/impl/AbstractMetadataProvider.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2006 Internet2 + * Copyright 2001-2007 Internet2 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,46 +24,48 @@ #include "binding/SAMLArtifact.h" #include "saml2/metadata/Metadata.h" #include "saml2/metadata/AbstractMetadataProvider.h" +#include "saml2/metadata/MetadataCredentialCriteria.h" #include -#include +#include #include using namespace opensaml::saml2md; -using namespace opensaml; using namespace xmltooling; using namespace std; +using opensaml::SAMLArtifact; -static const XMLCh GenericKeyResolver[] = UNICODE_LITERAL_11(K,e,y,R,e,s,o,l,v,e,r); -static const XMLCh type[] = UNICODE_LITERAL_4(t,y,p,e); +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); -AbstractMetadataProvider::AbstractMetadataProvider(const DOMElement* e) : ObservableMetadataProvider(e), m_resolver(NULL) +AbstractMetadataProvider::AbstractMetadataProvider(const DOMElement* e) + : ObservableMetadataProvider(e), m_resolver(NULL), m_credentialLock(NULL) { - e = e ? XMLHelper::getFirstChildElement(e, GenericKeyResolver) : NULL; + e = e ? XMLHelper::getFirstChildElement(e, _KeyInfoResolver) : NULL; if (e) { auto_ptr_char t(e->getAttributeNS(NULL,type)); if (t.get()) - m_resolver = XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(t.get(),e); + m_resolver = XMLToolingConfig::getConfig().KeyInfoResolverManager.newPlugin(t.get(),e); else - throw UnknownExtensionException(" element found with no type attribute"); - } - - if (!m_resolver) { - m_resolver = XMLToolingConfig::getConfig().KeyResolverManager.newPlugin(INLINE_KEY_RESOLVER, NULL); + 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(), cleanup_pair()); + delete m_credentialLock; delete m_resolver; } void AbstractMetadataProvider::emitChangeEvent() { - xmlsignature::CachingKeyResolver* ckr=dynamic_cast(m_resolver); - if (ckr) - ckr->clearCache(); - ObservableMetadataProvider::emitChangeEvent(); + for (credmap_t::iterator c = m_credentialMap.begin(); c!=m_credentialMap.end(); ++c) + for_each(c->second.begin(), c->second.end(), cleanup_pair()); + m_credentialMap.clear(); + ObservableMetadataProvider::emitChangeEvent(); } void AbstractMetadataProvider::index(EntityDescriptor* site, time_t validUntil) @@ -188,3 +190,76 @@ const EntityDescriptor* AbstractMetadataProvider::getEntityDescriptor(const SAML return NULL; } + +const Credential* AbstractMetadataProvider::resolve(const CredentialCriteria* criteria) const +{ + const MetadataCredentialCriteria* metacrit = dynamic_cast(criteria); + if (!metacrit) + throw MetadataException("Cannot resolve credentials without a MetadataCredentialCriteria object."); + + 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 (matches(*c,criteria)) + return c->second; + return NULL; +} + +vector::size_type AbstractMetadataProvider::resolve( + vector& results, const CredentialCriteria* criteria + ) const +{ + const MetadataCredentialCriteria* metacrit = dynamic_cast(criteria); + if (!metacrit) + throw MetadataException("Cannot resolve credentials without a MetadataCredentialCriteria object."); + + 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 (matches(*c,criteria)) + results.push_back(c->second); + 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()) + 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()) { + Credential* c = resolver->resolve((*k)->getKeyInfo()); + resolved.push_back(make_pair((*k)->getUse(), c)); + } + } + return resolved; +} + +bool AbstractMetadataProvider::matches(const pair& cred, const CredentialCriteria* criteria) const +{ + if (criteria) { + // Check for a usage mismatch. + if ((criteria->getUsage()==CredentialCriteria::SIGNING_CREDENTIAL || criteria->getUsage()==CredentialCriteria::TLS_CREDENTIAL) && + XMLString::equals(cred.first,KeyDescriptor::KEYTYPE_ENCRYPTION)) + return false; + else if (criteria->getUsage()==CredentialCriteria::ENCRYPTION_CREDENTIAL && XMLString::equals(cred.first,KeyDescriptor::KEYTYPE_SIGNING)) + return false; + + if (cred.second->getPublicKey()) { + // See if we have to match a specific key. + auto_ptr critcred( + XMLToolingConfig::getConfig().getKeyInfoResolver()->resolve(*criteria,Credential::RESOLVE_KEYS) + ); + if (critcred.get()) + if (!critcred->isEqual(*(cred.second->getPublicKey()))) + return false; + } + } + return true; +}