X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=shibsp%2FSPConfig.cpp;h=e8b6d2f507a99971054cd87c13defb83997bb492;hb=c51bfd77603cf0ddb0b5e374c35586a8435895d6;hp=7aaaf9800ff65696117988729d31d0f5dfd97f3d;hpb=1da6ef95e89abf23b34e9d663a79a42c086b79b1;p=shibboleth%2Fcpp-sp.git diff --git a/shibsp/SPConfig.cpp b/shibsp/SPConfig.cpp index 7aaaf98..e8b6d2f 100644 --- a/shibsp/SPConfig.cpp +++ b/shibsp/SPConfig.cpp @@ -1,24 +1,27 @@ - -/* - * Copyright 2001-2007 Internet2 +/** + * Licensed to the University Corporation for Advanced Internet + * Development, Inc. (UCAID) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. * - * 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 + * UCAID licenses this file to you 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 + * 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. + * 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. */ /** * SPConfig.cpp * - * Library configuration + * Library configuration. */ #include "internal.h" @@ -35,13 +38,16 @@ # error "No supported logging library." #endif -#include "AccessControl.h" #include "exceptions.h" +#include "version.h" +#include "AccessControl.h" #include "RequestMapper.h" #include "ServiceProvider.h" #include "SessionCache.h" #include "SPConfig.h" #include "attribute/Attribute.h" +#include "binding/ProtocolProvider.h" +#include "handler/LogoutInitiator.h" #include "handler/SessionInitiator.h" #include "remoting/ListenerService.h" @@ -54,22 +60,26 @@ # include "binding/ArtifactResolver.h" # include "metadata/MetadataExt.h" # include "security/PKIXTrustEngine.h" +# include "security/SecurityPolicyProvider.h" +# include # include -# include -#else -# include #endif #include #include +#include +#include #include +#include #include #include +#include #include using namespace shibsp; using namespace opensaml; using namespace xmltooling; +using namespace boost; using namespace std; DECL_XMLTOOLING_EXCEPTION_FACTORY(AttributeException,shibsp); @@ -89,7 +99,21 @@ DECL_XMLTOOLING_EXCEPTION_FACTORY(MetadataException,opensaml::saml2md); #endif namespace shibsp { - SPConfig g_config; + class SHIBSP_DLLLOCAL SPInternalConfig : public SPConfig + { + public: + SPInternalConfig() : m_initCount(0), m_lock(Mutex::create()) {} + ~SPInternalConfig() {} + + bool init(const char* catalog_path=nullptr, const char* inst_prefix=nullptr); + void term(); + + private: + int m_initCount; + scoped_ptr m_lock; + }; + + SPInternalConfig g_config; } SPConfig& SPConfig::getConfig() @@ -97,17 +121,58 @@ SPConfig& SPConfig::getConfig() return g_config; } +SPConfig::SPConfig() : attribute_value_delimeter(';'), m_serviceProvider(nullptr), +#ifndef SHIBSP_LITE + m_artifactResolver(nullptr), +#endif + m_features(0), m_configDoc(nullptr) +{ +} + +SPConfig::~SPConfig() +{ +} + +void SPConfig::setFeatures(unsigned long enabled) +{ + m_features = enabled; +} + +unsigned long SPConfig::getFeatures() const { + return m_features; +} + +bool SPConfig::isEnabled(components_t feature) const +{ + return (m_features & feature)>0; +} + +ServiceProvider* SPConfig::getServiceProvider() const +{ + return m_serviceProvider; +} + void SPConfig::setServiceProvider(ServiceProvider* serviceProvider) { delete m_serviceProvider; m_serviceProvider = serviceProvider; } -bool SPConfig::init(const char* catalog_path, const char* inst_prefix) +#ifndef SHIBSP_LITE +void SPConfig::setArtifactResolver(MessageDecoder::ArtifactResolver* artifactResolver) { -#ifdef _DEBUG - NDC ndc("init"); + delete m_artifactResolver; + m_artifactResolver = artifactResolver; +} + +const MessageDecoder::ArtifactResolver* SPConfig::getArtifactResolver() const +{ + return m_artifactResolver; +} #endif + +bool SPConfig::init(const char* catalog_path, const char* inst_prefix) +{ if (!inst_prefix) inst_prefix = getenv("SHIBSP_PREFIX"); if (!inst_prefix) @@ -118,37 +183,90 @@ bool SPConfig::init(const char* catalog_path, const char* inst_prefix) ++inst_prefix; } - const char* loglevel=getenv("SHIBSP_LOGGING"); - if (!loglevel) - loglevel = SHIBSP_LOGGING; - std::string ll(loglevel); + const char* logconf = getenv("SHIBSP_LOGGING"); + if (!logconf || !*logconf) { + if (isEnabled(SPConfig::Logging) && isEnabled(SPConfig::OutOfProcess) && !isEnabled(SPConfig::InProcess)) + logconf = SHIBSP_OUTOFPROC_LOGGING; + else if (isEnabled(SPConfig::Logging) && isEnabled(SPConfig::InProcess) && !isEnabled(SPConfig::OutOfProcess)) + logconf = SHIBSP_INPROC_LOGGING; + else + logconf = SHIBSP_LOGGING; + } PathResolver localpr; localpr.setDefaultPrefix(inst_prefix2.c_str()); - XMLToolingConfig::getConfig().log_config(localpr.resolve(ll, PathResolver::XMLTOOLING_CFG_FILE, PACKAGE_NAME).c_str()); - - Category& log=Category::getInstance(SHIBSP_LOGCAT".Config"); + inst_prefix = getenv("SHIBSP_CFGDIR"); + if (!inst_prefix || !*inst_prefix) + inst_prefix = SHIBSP_CFGDIR; + localpr.setCfgDir(inst_prefix); + std::string lc(logconf); + XMLToolingConfig::getConfig().log_config(localpr.resolve(lc, PathResolver::XMLTOOLING_CFG_FILE, PACKAGE_NAME).c_str()); + + Category& log=Category::getInstance(SHIBSP_LOGCAT ".Config"); log.debug("%s library initialization started", PACKAGE_STRING); - if (!catalog_path) - catalog_path = getenv("SHIBSP_SCHEMAS"); - if (!catalog_path) - catalog_path = SHIBSP_SCHEMAS; - XMLToolingConfig::getConfig().catalog_path = catalog_path; - #ifndef SHIBSP_LITE + XMLToolingConfig::getConfig().user_agent = string(PACKAGE_NAME) + '/' + PACKAGE_VERSION + + " OpenSAML/" + gOpenSAMLDotVersionStr + + " XMLTooling/" + gXMLToolingDotVersionStr + + " XML-Security-C/" + XSEC_FULLVERSIONDOT + + " Xerces-C/" + XERCES_FULLVERSIONDOT + +#if defined(LOG4SHIB_VERSION) + " log4shib/" + LOG4SHIB_VERSION; +#elif defined(LOG4CPP_VERSION) + " log4cpp/" + LOG4CPP_VERSION; +#endif if (!SAMLConfig::getConfig().init()) { log.fatal("failed to initialize OpenSAML library"); return false; } - XMLPlatformUtils::fgNetAccessor = new CurlNetAccessor(); #else + XMLToolingConfig::getConfig().user_agent = string(PACKAGE_NAME) + '/' + PACKAGE_VERSION + + " XMLTooling/" + gXMLToolingDotVersionStr + + " Xerces-C/" + XERCES_FULLVERSIONDOT + +#if defined(LOG4SHIB_VERSION) + " log4shib/" + LOG4SHIB_VERSION; +#elif defined(LOG4CPP_VERSION) + " log4cpp/" + LOG4CPP_VERSION; +#endif if (!XMLToolingConfig::getConfig().init()) { log.fatal("failed to initialize XMLTooling library"); return false; } #endif - XMLToolingConfig::getConfig().getPathResolver()->setDefaultPackageName(PACKAGE_NAME); - XMLToolingConfig::getConfig().getPathResolver()->setDefaultPrefix(inst_prefix2.c_str()); + + PathResolver* pr = XMLToolingConfig::getConfig().getPathResolver(); + pr->setDefaultPackageName(PACKAGE_NAME); + pr->setDefaultPrefix(inst_prefix2.c_str()); + pr->setCfgDir(inst_prefix); + inst_prefix = getenv("SHIBSP_LIBDIR"); + if (!inst_prefix || !*inst_prefix) + inst_prefix = SHIBSP_LIBDIR; + pr->setLibDir(inst_prefix); + inst_prefix = getenv("SHIBSP_LOGDIR"); + if (!inst_prefix || !*inst_prefix) + inst_prefix = SHIBSP_LOGDIR; + pr->setLogDir(inst_prefix); + inst_prefix = getenv("SHIBSP_RUNDIR"); + if (!inst_prefix || !*inst_prefix) + inst_prefix = SHIBSP_RUNDIR; + pr->setRunDir(inst_prefix); + inst_prefix = getenv("SHIBSP_CACHEDIR"); + if (!inst_prefix || !*inst_prefix) + inst_prefix = SHIBSP_CACHEDIR; + pr->setCacheDir(inst_prefix); + inst_prefix = getenv("SHIBSP_XMLDIR"); + if (!inst_prefix || !*inst_prefix) + inst_prefix = SHIBSP_XMLDIR; + pr->setXMLDir(inst_prefix); + + if (!catalog_path) + catalog_path = getenv("SHIBSP_SCHEMAS"); + if (!catalog_path || !*catalog_path) + catalog_path = SHIBSP_SCHEMAS; + if (!XMLToolingConfig::getConfig().getValidatingParser().loadCatalogs(catalog_path)) { + log.warn("failed to load schema catalogs into validating parser"); + } + XMLToolingConfig::getConfig().setTemplateEngine(new TemplateEngine()); XMLToolingConfig::getConfig().getTemplateEngine()->setTagPrefix("shibmlp"); @@ -176,8 +294,14 @@ bool SPConfig::init(const char* catalog_path, const char* inst_prefix) #endif registerAttributeFactories(); - registerHandlers(); - registerSessionInitiators(); + + if (isEnabled(Handlers)) { + registerHandlers(); + registerLogoutInitiators(); + registerSessionInitiators(); + registerProtocolProviders(); + } + registerServiceProviders(); #ifndef SHIBSP_LITE @@ -188,6 +312,10 @@ bool SPConfig::init(const char* catalog_path, const char* inst_prefix) registerAttributeFilters(); registerMatchFunctors(); } + if (isEnabled(Logging)) { + registerEvents(); + } + registerSecurityPolicyProviders(); #endif if (isEnabled(Listener)) @@ -205,7 +333,7 @@ bool SPConfig::init(const char* catalog_path, const char* inst_prefix) if (isEnabled(OutOfProcess)) m_artifactResolver = new ArtifactResolver(); #endif - srand(static_cast(std::time(NULL))); + srand(static_cast(std::time(nullptr))); log.info("%s library initialization complete", PACKAGE_STRING); return true; @@ -213,28 +341,36 @@ bool SPConfig::init(const char* catalog_path, const char* inst_prefix) void SPConfig::term() { -#ifdef _DEBUG - NDC ndc("term"); -#endif - Category& log=Category::getInstance(SHIBSP_LOGCAT".Config"); + Category& log=Category::getInstance(SHIBSP_LOGCAT ".Config"); log.info("%s library shutting down", PACKAGE_STRING); - setServiceProvider(NULL); + setServiceProvider(nullptr); + if (m_configDoc) + m_configDoc->release(); + m_configDoc = nullptr; #ifndef SHIBSP_LITE - setArtifactResolver(NULL); + setArtifactResolver(nullptr); #endif - ArtifactResolutionServiceManager.deregisterFactories(); - AssertionConsumerServiceManager.deregisterFactories(); - LogoutInitiatorManager.deregisterFactories(); - ManageNameIDServiceManager.deregisterFactories(); - SessionInitiatorManager.deregisterFactories(); - SingleLogoutServiceManager.deregisterFactories(); - HandlerManager.deregisterFactories(); + if (isEnabled(Handlers)) { + ArtifactResolutionServiceManager.deregisterFactories(); + AssertionConsumerServiceManager.deregisterFactories(); + LogoutInitiatorManager.deregisterFactories(); + ManageNameIDServiceManager.deregisterFactories(); + SessionInitiatorManager.deregisterFactories(); + SingleLogoutServiceManager.deregisterFactories(); + HandlerManager.deregisterFactories(); + ProtocolProviderManager.deregisterFactories(); + } + ServiceProviderManager.deregisterFactories(); Attribute::deregisterFactories(); #ifndef SHIBSP_LITE + SecurityPolicyProviderManager.deregisterFactories(); + if (isEnabled(Logging)) { + EventManager.deregisterFactories(); + } if (isEnabled(AttributeResolution)) { MatchFunctorManager.deregisterFactories(); AttributeFilterManager.deregisterFactories(); @@ -289,17 +425,23 @@ bool SPConfig::instantiate(const char* config, bool rethrow) dummydoc = XMLToolingConfig::getConfig().getParser().parse(snippet); XercesJanitor docjanitor(dummydoc); setServiceProvider(ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER, dummydoc->getDocumentElement())); + if (m_configDoc) + m_configDoc->release(); + m_configDoc = docjanitor.release(); } else { stringstream snippet(config); dummydoc = XMLToolingConfig::getConfig().getParser().parse(snippet); XercesJanitor docjanitor(dummydoc); static const XMLCh _type[] = UNICODE_LITERAL_4(t,y,p,e); - auto_ptr_char type(dummydoc->getDocumentElement()->getAttributeNS(NULL,_type)); + auto_ptr_char type(dummydoc->getDocumentElement()->getAttributeNS(nullptr,_type)); if (type.get() && *type.get()) setServiceProvider(ServiceProviderManager.newPlugin(type.get(), dummydoc->getDocumentElement())); else throw ConfigurationException("The supplied XML bootstrapping configuration did not include a type attribute."); + if (m_configDoc) + m_configDoc->release(); + m_configDoc = docjanitor.release(); } getServiceProvider()->init(); @@ -308,7 +450,51 @@ bool SPConfig::instantiate(const char* config, bool rethrow) catch (exception& ex) { if (rethrow) throw; - Category::getInstance(SHIBSP_LOGCAT".Config").fatal("caught exception while loading configuration: %s", ex.what()); + Category::getInstance(SHIBSP_LOGCAT ".Config").fatal("caught exception while loading configuration: %s", ex.what()); } return false; } + +bool SPInternalConfig::init(const char* catalog_path, const char* inst_prefix) +{ +#ifdef _DEBUG + xmltooling::NDC ndc("init"); +#endif + + Lock initLock(m_lock); + + if (m_initCount == INT_MAX) { + Category::getInstance(SHIBSP_LOGCAT ".Config").crit("library initialized too many times"); + return false; + } + + if (m_initCount >= 1) { + ++m_initCount; + return true; + } + + if (!SPConfig::init(catalog_path, inst_prefix)) { + return false; + } + + ++m_initCount; + return true; +} + +void SPInternalConfig::term() +{ +#ifdef _DEBUG + xmltooling::NDC ndc("term"); +#endif + + Lock initLock(m_lock); + if (m_initCount == 0) { + Category::getInstance(SHIBSP_LOGCAT ".Config").crit("term without corresponding init"); + return; + } + else if (--m_initCount > 0) { + return; + } + + SPConfig::term(); +}