From 86e185cf72d47f6d3250414f7451ece13e7b7ec5 Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Wed, 3 Jan 2007 21:53:06 +0000 Subject: [PATCH] Layered basic metadata plugin on top of new base class. --- saml/Makefile.am | 2 +- saml/saml.vcproj | 8 +- saml/saml2/metadata/MetadataProvider.h | 4 +- .../metadata/impl/FilesystemMetadataProvider.cpp | 265 --------------------- saml/saml2/metadata/impl/MetadataProvider.cpp | 8 +- saml/saml2/metadata/impl/XMLMetadataProvider.cpp | 129 ++++++++++ samltest/Makefile.am | 2 +- samltest/binding.h | 2 +- ...etadataProvider.xml => XMLMetadataProvider.xml} | 0 ...temWithBlacklists.xml => XMLWithBlacklists.xml} | 0 ...temWithWhitelists.xml => XMLWithWhitelists.xml} | 0 ...etadataProvider.xml => XMLMetadataProvider.xml} | 0 samltest/internal.h | 5 + ...ataProviderTest.h => XMLMetadataProviderTest.h} | 20 +- samltest/samltest.vcproj | 4 +- samltest/security/AbstractPKIXTrustEngineTest.h | 4 +- samltest/security/ExplicitKeyTrustEngineTest.h | 4 +- 17 files changed, 163 insertions(+), 294 deletions(-) delete mode 100644 saml/saml2/metadata/impl/FilesystemMetadataProvider.cpp create mode 100644 saml/saml2/metadata/impl/XMLMetadataProvider.cpp rename samltest/data/saml2/metadata/{FilesystemMetadataProvider.xml => XMLMetadataProvider.xml} (100%) rename samltest/data/saml2/metadata/{FilesystemWithBlacklists.xml => XMLWithBlacklists.xml} (100%) rename samltest/data/saml2/metadata/{FilesystemWithWhitelists.xml => XMLWithWhitelists.xml} (100%) rename samltest/data/security/{FilesystemMetadataProvider.xml => XMLMetadataProvider.xml} (100%) rename samltest/saml2/metadata/{FilesystemMetadataProviderTest.h => XMLMetadataProviderTest.h} (89%) diff --git a/saml/Makefile.am b/saml/Makefile.am index 81322b2..d639669 100644 --- a/saml/Makefile.am +++ b/saml/Makefile.am @@ -143,13 +143,13 @@ libsaml_la_SOURCES = \ saml2/metadata/impl/AbstractMetadataProvider.cpp \ saml2/metadata/impl/BlacklistMetadataFilter.cpp \ saml2/metadata/impl/ChainingMetadataProvider.cpp \ - saml2/metadata/impl/FilesystemMetadataProvider.cpp \ saml2/metadata/impl/MetadataImpl.cpp \ saml2/metadata/impl/MetadataProvider.cpp \ saml2/metadata/impl/MetadataSchemaValidators.cpp \ saml2/metadata/impl/ObservableMetadataProvider.cpp \ saml2/metadata/impl/SignatureMetadataFilter.cpp \ saml2/metadata/impl/WhitelistMetadataFilter.cpp \ + saml2/metadata/impl/XMLMetadataProvider.cpp \ saml2/binding/impl/SAML2Artifact.cpp \ saml2/binding/impl/SAML2ArtifactType0004.cpp \ saml2/binding/impl/SAML2ArtifactDecoder.cpp \ diff --git a/saml/saml.vcproj b/saml/saml.vcproj index 864a6e2..5e8a06f 100644 --- a/saml/saml.vcproj +++ b/saml/saml.vcproj @@ -333,10 +333,6 @@ > - - @@ -360,6 +356,10 @@ RelativePath=".\saml2\metadata\impl\WhitelistMetadataFilter.cpp" > + + -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace opensaml::saml2md; -using namespace xmltooling; -using namespace log4cpp; -using namespace std; - -namespace opensaml { - namespace saml2md { - - - class SAML_DLLLOCAL FilesystemMetadataProvider : public AbstractMetadataProvider - { - public: - FilesystemMetadataProvider(const DOMElement* e); - ~FilesystemMetadataProvider(); - - Lockable* lock(); - void unlock() { - if (m_lock) - m_lock->unlock(); - } - - void init(); - - const XMLObject* getMetadata() const { - return m_object; - } - - private: - XMLObject* load() const; - void index(); - - const DOMElement* m_root; // survives only until init() method is done - std::string m_source; - time_t m_filestamp; - bool m_validate; - RWLock* m_lock; - XMLObject* m_object; - }; - - MetadataProvider* SAML_DLLLOCAL FilesystemMetadataProviderFactory(const DOMElement* const & e) - { - return new FilesystemMetadataProvider(e); - } - - }; -}; - -static const XMLCh uri[] = UNICODE_LITERAL_3(u,r,i); -static const XMLCh url[] = UNICODE_LITERAL_3(u,r,l); -static const XMLCh path[] = UNICODE_LITERAL_4(p,a,t,h); -static const XMLCh pathname[] = UNICODE_LITERAL_8(p,a,t,h,n,a,m,e); -static const XMLCh file[] = UNICODE_LITERAL_4(f,i,l,e); -static const XMLCh filename[] = UNICODE_LITERAL_8(f,i,l,e,n,a,m,e); -static const XMLCh validate[] = UNICODE_LITERAL_8(v,a,l,i,d,a,t,e); - -FilesystemMetadataProvider::FilesystemMetadataProvider(const DOMElement* e) - : AbstractMetadataProvider(e), m_root(e), m_filestamp(0), m_validate(false), m_lock(NULL), m_object(NULL) -{ -#ifdef _DEBUG - NDC ndc("FilesystemMetadataProvider"); -#endif - Category& log=Category::getInstance(SAML_LOGCAT".Metadata"); - - // Establish source of data... - const XMLCh* source=e->getAttributeNS(NULL,uri); - if (!source || !*source) { - source=e->getAttributeNS(NULL,url); - if (!source || !*source) { - source=e->getAttributeNS(NULL,path); - if (!source || !*source) { - source=e->getAttributeNS(NULL,pathname); - if (!source || !*source) { - source=e->getAttributeNS(NULL,file); - if (!source || !*source) { - source=e->getAttributeNS(NULL,filename); - } - } - } - } - } - - if (source && *source) { - const XMLCh* valflag=e->getAttributeNS(NULL,validate); - m_validate=(XMLString::equals(valflag,xmlconstants::XML_TRUE) || XMLString::equals(valflag,xmlconstants::XML_ONE)); - - auto_ptr_char temp(source); - m_source=temp.get(); - log.debug("using external metadata file (%s)", temp.get()); - -#ifdef WIN32 - struct _stat stat_buf; - if (_stat(m_source.c_str(), &stat_buf) == 0) -#else - struct stat stat_buf; - if (stat(m_source.c_str(), &stat_buf) == 0) -#endif - m_filestamp=stat_buf.st_mtime; - m_lock=RWLock::create(); - } - else - log.debug("no file path/name supplied, will look for metadata inline"); -} - -FilesystemMetadataProvider::~FilesystemMetadataProvider() -{ - delete m_lock; - delete m_object; -} - -void FilesystemMetadataProvider::init() -{ - m_object=load(); - index(); -} - -XMLObject* FilesystemMetadataProvider::load() const -{ -#ifdef _DEBUG - NDC ndc("load"); -#endif - Category& log=Category::getInstance(SAML_LOGCAT".Metadata"); - - try { - XMLObject* xmlObject=NULL; - - if (!m_source.empty()) { - // Data comes from a file we have to parse. - log.debug("loading metadata from file..."); - auto_ptr_XMLCh widenit(m_source.c_str()); - LocalFileInputSource src(widenit.get()); - Wrapper4InputSource dsrc(&src,false); - DOMDocument* doc=NULL; - if (m_validate) - doc=XMLToolingConfig::getConfig().getValidatingParser().parse(dsrc); - else - doc=XMLToolingConfig::getConfig().getParser().parse(dsrc); - XercesJanitor docjanitor(doc); - log.infoStream() << "loaded and parsed XML file (" << m_source << ")" << CategoryStream::ENDLINE; - - // Unmarshall objects, binding the document. - xmlObject = XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true); - docjanitor.release(); - } - else { - // Data comes from the DOM we were handed. - log.debug("loading inline metadata..."); - DOMElement* child = XMLHelper::getFirstChildElement(m_root); - if (!child) - throw XMLToolingException("No metadata was found inline."); - xmlObject = XMLObjectBuilder::buildOneFromElement(child); - } - - auto_ptr xmlObjectPtr(xmlObject); - - doFilters(*xmlObject); - - xmlObjectPtr->releaseThisAndChildrenDOM(); - xmlObjectPtr->setDocument(NULL); - return xmlObjectPtr.release(); - } - catch (XMLException& e) { - auto_ptr_char msg(e.getMessage()); - log.errorStream() << "Xerces parser error while loading metadata from (" - << (m_source.empty() ? "inline" : m_source) << "): " << msg.get() << CategoryStream::ENDLINE; - throw XMLParserException(msg.get()); - } - catch (XMLToolingException& e) { - log.errorStream() << "error while loading metadata from (" - << (m_source.empty() ? "inline" : m_source) << "): " << e.what() << CategoryStream::ENDLINE; - throw; - } -} - -Lockable* FilesystemMetadataProvider::lock() -{ - if (!m_lock) - return this; - - m_lock->rdlock(); - - // Check if we need to refresh. -#ifdef WIN32 - struct _stat stat_buf; - if (_stat(m_source.c_str(), &stat_buf) == 0) -#else - struct stat stat_buf; - if (stat(m_source.c_str(), &stat_buf) == 0) -#endif - { - if (m_filestamp>0 && m_filestampunlock(); - m_lock->wrlock(); - if (m_filestamp>0 && m_filestampunlock(); - } - m_lock->rdlock(); - } - } - return this; -} - -void FilesystemMetadataProvider::index() -{ - clearDescriptorIndex(); - EntitiesDescriptor* group=dynamic_cast(m_object); - if (group) { - AbstractMetadataProvider::index(group, SAMLTIME_MAX); - return; - } - EntityDescriptor* site=dynamic_cast(m_object); - AbstractMetadataProvider::index(site, SAMLTIME_MAX); -} diff --git a/saml/saml2/metadata/impl/MetadataProvider.cpp b/saml/saml2/metadata/impl/MetadataProvider.cpp index 8c01e62..7d8de17 100644 --- a/saml/saml2/metadata/impl/MetadataProvider.cpp +++ b/saml/saml2/metadata/impl/MetadataProvider.cpp @@ -36,7 +36,7 @@ using namespace std; namespace opensaml { namespace saml2md { - SAML_DLLLOCAL PluginManager::Factory FilesystemMetadataProviderFactory; + SAML_DLLLOCAL PluginManager::Factory XMLMetadataProviderFactory; SAML_DLLLOCAL PluginManager::Factory ChainingMetadataProviderFactory; SAML_DLLLOCAL PluginManager::Factory BlacklistMetadataFilterFactory; SAML_DLLLOCAL PluginManager::Factory WhitelistMetadataFilterFactory; @@ -47,10 +47,10 @@ namespace opensaml { void SAML_API opensaml::saml2md::registerMetadataProviders() { SAMLConfig& conf=SAMLConfig::getConfig(); - conf.MetadataProviderManager.registerFactory(FILESYSTEM_METADATA_PROVIDER, FilesystemMetadataProviderFactory); + conf.MetadataProviderManager.registerFactory(XML_METADATA_PROVIDER, XMLMetadataProviderFactory); conf.MetadataProviderManager.registerFactory(CHAINING_METADATA_PROVIDER, ChainingMetadataProviderFactory); - conf.MetadataProviderManager.registerFactory("edu.internet2.middleware.shibboleth.metadata.provider.XMLMetadata", FilesystemMetadataProviderFactory); - conf.MetadataProviderManager.registerFactory("edu.internet2.middleware.shibboleth.common.provider.XMLMetadata", FilesystemMetadataProviderFactory); + conf.MetadataProviderManager.registerFactory("edu.internet2.middleware.shibboleth.metadata.provider.XMLMetadata", XMLMetadataProviderFactory); + conf.MetadataProviderManager.registerFactory("edu.internet2.middleware.shibboleth.common.provider.XMLMetadata", XMLMetadataProviderFactory); } void SAML_API opensaml::saml2md::registerMetadataFilters() diff --git a/saml/saml2/metadata/impl/XMLMetadataProvider.cpp b/saml/saml2/metadata/impl/XMLMetadataProvider.cpp new file mode 100644 index 0000000..d47a1d4 --- /dev/null +++ b/saml/saml2/metadata/impl/XMLMetadataProvider.cpp @@ -0,0 +1,129 @@ +/* + * Copyright 2001-2006 Internet2 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * XMLMetadataProvider.cpp + * + * Supplies metadata from an XML file + */ + +#include "internal.h" +#include "saml2/metadata/Metadata.h" +#include "saml2/metadata/AbstractMetadataProvider.h" + +#include +#include +#include +#include + +using namespace opensaml::saml2md; +using namespace xmltooling; +using namespace log4cpp; +using namespace std; + +#if defined (_MSC_VER) + #pragma warning( push ) + #pragma warning( disable : 4250 ) +#endif + +namespace opensaml { + namespace saml2md { + + class SAML_DLLLOCAL XMLMetadataProvider : public AbstractMetadataProvider, public ReloadableXMLFile + { + public: + XMLMetadataProvider(const DOMElement* e) : AbstractMetadataProvider(e), ReloadableXMLFile(e), m_object(NULL) {} + virtual ~XMLMetadataProvider() { + delete m_object; + } + + void init() { + load(); // guarantees an exception or the metadata is loaded + } + + pair load(); + + const XMLObject* getMetadata() const { + return m_object; + } + + private: + void index(); + + XMLObject* m_object; + }; + + MetadataProvider* SAML_DLLLOCAL XMLMetadataProviderFactory(const DOMElement* const & e) + { + return new XMLMetadataProvider(e); + } + + }; +}; + +#if defined (_MSC_VER) + #pragma warning( pop ) +#endif + +pair XMLMetadataProvider::load() +{ +#ifdef _DEBUG + NDC ndc("load"); +#endif + + try { + // Load from source using base class. + pair raw = ReloadableXMLFile::load(); + + // If we own it, wrap it for now. + XercesJanitor docjanitor(raw.first ? raw.second->getOwnerDocument() : NULL); + + // Unmarshall objects, binding the document. + XMLObject* xmlObject=XMLObjectBuilder::buildOneFromElement(raw.second, true); + docjanitor.release(); + + // Preprocess the metadata. + auto_ptr xmlObjectPtr(xmlObject); + doFilters(*xmlObject); + xmlObjectPtr->releaseThisAndChildrenDOM(); + xmlObjectPtr->setDocument(NULL); + + // Swap it in. + bool changed = m_object!=NULL; + delete m_object; + m_object = xmlObjectPtr.release(); + index(); + if (changed) + emitChangeEvent(); + return make_pair(false,(DOMElement*)NULL); + } + catch (XMLToolingException& e) { + Category::getInstance(SAML_LOGCAT".Metadata").error("error while loading metadata: %s", e.what()); + throw; + } +} + +void XMLMetadataProvider::index() +{ + clearDescriptorIndex(); + EntitiesDescriptor* group=dynamic_cast(m_object); + if (group) { + AbstractMetadataProvider::index(group, SAMLTIME_MAX); + return; + } + EntityDescriptor* site=dynamic_cast(m_object); + AbstractMetadataProvider::index(site, SAMLTIME_MAX); +} diff --git a/samltest/Makefile.am b/samltest/Makefile.am index 681cb7a..932a2c5 100644 --- a/samltest/Makefile.am +++ b/samltest/Makefile.am @@ -92,7 +92,7 @@ samltest_h = \ saml2/binding/SAML2ArtifactTest.h \ saml2/binding/SAML2POSTTest.h \ saml2/binding/SAML2RedirectTest.h \ - saml2/metadata/FilesystemMetadataProviderTest.h + saml2/metadata/XMLMetadataProviderTest.h noinst_HEADERS = \ binding.h \ diff --git a/samltest/binding.h b/samltest/binding.h index fea95fb..2947a49 100644 --- a/samltest/binding.h +++ b/samltest/binding.h @@ -66,7 +66,7 @@ public: doc->getDocumentElement()->setAttributeNS(NULL,path.get(),file.get()); m_metadata = SAMLConfig::getConfig().MetadataProviderManager.newPlugin( - FILESYSTEM_METADATA_PROVIDER,doc->getDocumentElement() + XML_METADATA_PROVIDER,doc->getDocumentElement() ); m_metadata->init(); diff --git a/samltest/data/saml2/metadata/FilesystemMetadataProvider.xml b/samltest/data/saml2/metadata/XMLMetadataProvider.xml similarity index 100% rename from samltest/data/saml2/metadata/FilesystemMetadataProvider.xml rename to samltest/data/saml2/metadata/XMLMetadataProvider.xml diff --git a/samltest/data/saml2/metadata/FilesystemWithBlacklists.xml b/samltest/data/saml2/metadata/XMLWithBlacklists.xml similarity index 100% rename from samltest/data/saml2/metadata/FilesystemWithBlacklists.xml rename to samltest/data/saml2/metadata/XMLWithBlacklists.xml diff --git a/samltest/data/saml2/metadata/FilesystemWithWhitelists.xml b/samltest/data/saml2/metadata/XMLWithWhitelists.xml similarity index 100% rename from samltest/data/saml2/metadata/FilesystemWithWhitelists.xml rename to samltest/data/saml2/metadata/XMLWithWhitelists.xml diff --git a/samltest/data/security/FilesystemMetadataProvider.xml b/samltest/data/security/XMLMetadataProvider.xml similarity index 100% rename from samltest/data/security/FilesystemMetadataProvider.xml rename to samltest/data/security/XMLMetadataProvider.xml diff --git a/samltest/internal.h b/samltest/internal.h index 1cfe28f..5dddfa1 100644 --- a/samltest/internal.h +++ b/samltest/internal.h @@ -14,6 +14,11 @@ * limitations under the License. */ +#ifdef WIN32 +# define _CRT_SECURE_NO_DEPRECATE 1 +# define _CRT_NONSTDC_NO_DEPRECATE 1 +#endif + #include #include diff --git a/samltest/saml2/metadata/FilesystemMetadataProviderTest.h b/samltest/saml2/metadata/XMLMetadataProviderTest.h similarity index 89% rename from samltest/saml2/metadata/FilesystemMetadataProviderTest.h rename to samltest/saml2/metadata/XMLMetadataProviderTest.h index d422cd5..5ed4a94 100644 --- a/samltest/saml2/metadata/FilesystemMetadataProviderTest.h +++ b/samltest/saml2/metadata/XMLMetadataProviderTest.h @@ -23,7 +23,7 @@ using namespace opensaml::saml2md; using namespace opensaml::saml2p; -class FilesystemMetadataProviderTest : public CxxTest::TestSuite, public SAMLObjectBaseTestCase { +class XMLMetadataProviderTest : public CxxTest::TestSuite, public SAMLObjectBaseTestCase { XMLCh* entityID; XMLCh* entityID2; XMLCh* supportedProtocol; @@ -46,8 +46,8 @@ public: SAMLObjectBaseTestCase::tearDown(); } - void testFilesystemProvider() { - string config = data_path + "saml2/metadata/FilesystemMetadataProvider.xml"; + void testXMLProvider() { + string config = data_path + "saml2/metadata/XMLMetadataProvider.xml"; ifstream in(config.c_str()); DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in); XercesJanitor janitor(doc); @@ -58,7 +58,7 @@ public: doc->getDocumentElement()->setAttributeNS(NULL,path.get(),file.get()); auto_ptr metadataProvider( - SAMLConfig::getConfig().MetadataProviderManager.newPlugin(FILESYSTEM_METADATA_PROVIDER,doc->getDocumentElement()) + SAMLConfig::getConfig().MetadataProviderManager.newPlugin(XML_METADATA_PROVIDER,doc->getDocumentElement()) ); try { metadataProvider->init(); @@ -84,8 +84,8 @@ public: assertEquals("Entity's ID does not match requested ID", entityID, descriptor->getEntityID()); } - void testFilesystemWithBlacklists() { - string config = data_path + "saml2/metadata/FilesystemWithBlacklists.xml"; + void testXMLWithBlacklists() { + string config = data_path + "saml2/metadata/XMLWithBlacklists.xml"; ifstream in(config.c_str()); DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in); XercesJanitor janitor(doc); @@ -96,7 +96,7 @@ public: doc->getDocumentElement()->setAttributeNS(NULL,path.get(),file.get()); auto_ptr metadataProvider( - SAMLConfig::getConfig().MetadataProviderManager.newPlugin(FILESYSTEM_METADATA_PROVIDER,doc->getDocumentElement()) + SAMLConfig::getConfig().MetadataProviderManager.newPlugin(XML_METADATA_PROVIDER,doc->getDocumentElement()) ); try { metadataProvider->init(); @@ -114,8 +114,8 @@ public: assertEquals("Entity's ID does not match requested ID", entityID2, descriptor->getEntityID()); } - void testFilesystemWithWhitelists() { - string config = data_path + "saml2/metadata/FilesystemWithWhitelists.xml"; + void testXMLWithWhitelists() { + string config = data_path + "saml2/metadata/XMLWithWhitelists.xml"; ifstream in(config.c_str()); DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in); XercesJanitor janitor(doc); @@ -126,7 +126,7 @@ public: doc->getDocumentElement()->setAttributeNS(NULL,path.get(),file.get()); auto_ptr metadataProvider( - SAMLConfig::getConfig().MetadataProviderManager.newPlugin(FILESYSTEM_METADATA_PROVIDER,doc->getDocumentElement()) + SAMLConfig::getConfig().MetadataProviderManager.newPlugin(XML_METADATA_PROVIDER,doc->getDocumentElement()) ); try { metadataProvider->init(); diff --git a/samltest/samltest.vcproj b/samltest/samltest.vcproj index 75f8f94..f044fd7 100644 --- a/samltest/samltest.vcproj +++ b/samltest/samltest.vcproj @@ -530,7 +530,7 @@ Name="metadata" > @@ -2346,7 +2346,7 @@ Name="metadata" > janitor(doc); @@ -105,7 +105,7 @@ public: // Build metadata provider. auto_ptr metadataProvider( - SAMLConfig::getConfig().MetadataProviderManager.newPlugin(FILESYSTEM_METADATA_PROVIDER,doc->getDocumentElement()) + SAMLConfig::getConfig().MetadataProviderManager.newPlugin(XML_METADATA_PROVIDER,doc->getDocumentElement()) ); try { metadataProvider->init(); diff --git a/samltest/security/ExplicitKeyTrustEngineTest.h b/samltest/security/ExplicitKeyTrustEngineTest.h index 78271bf..d2dd668 100644 --- a/samltest/security/ExplicitKeyTrustEngineTest.h +++ b/samltest/security/ExplicitKeyTrustEngineTest.h @@ -36,7 +36,7 @@ public: } void testExplicitKeyTrustEngine() { - string config = data_path + "security/FilesystemMetadataProvider.xml"; + string config = data_path + "security/XMLMetadataProvider.xml"; ifstream in(config.c_str()); DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in); XercesJanitor janitor(doc); @@ -48,7 +48,7 @@ public: // Build metadata provider. auto_ptr metadataProvider( - SAMLConfig::getConfig().MetadataProviderManager.newPlugin(FILESYSTEM_METADATA_PROVIDER,doc->getDocumentElement()) + SAMLConfig::getConfig().MetadataProviderManager.newPlugin(XML_METADATA_PROVIDER,doc->getDocumentElement()) ); try { metadataProvider->init(); -- 2.1.4