Porting changes from 1.2 branch
[shibboleth/sp.git] / shib / ShibConfig.cpp
index 412205c..4372d77 100644 (file)
@@ -63,6 +63,8 @@
 #define SHIB_INSTANTIATE
 
 #include "internal.h"
+#include "shib-threads.h"
+
 #include <openssl/err.h>
 
 using namespace saml;
@@ -70,149 +72,73 @@ using namespace shibboleth;
 using namespace log4cpp;
 using namespace std;
 
-SAML_EXCEPTION_FACTORY(UnsupportedProtocolException);
 SAML_EXCEPTION_FACTORY(MetadataException);
 SAML_EXCEPTION_FACTORY(CredentialException);
+SAML_EXCEPTION_FACTORY(InvalidHandleException);
 
 namespace {
-    ShibInternalConfig g_config;
+    ShibConfig g_config;
+    vector<Mutex*> g_openssl_locks;
 }
 
-ShibConfig::~ShibConfig() {}
-
-bool ShibInternalConfig::init()
+extern "C" void openssl_locking_callback(int mode,int n,const char *file,int line)
 {
-    saml::NDC ndc("init");
-
-    REGISTER_EXCEPTION_FACTORY(edu.internet2.middleware.shibboleth.common,UnsupportedProtocolException);
-    REGISTER_EXCEPTION_FACTORY(edu.internet2.middleware.shibboleth.common,MetadataException);
-    REGISTER_EXCEPTION_FACTORY(edu.internet2.middleware.shibboleth.common,CredentialException);
-
-    return true;
+    if (mode & CRYPTO_LOCK)
+        g_openssl_locks[n]->lock();
+    else
+        g_openssl_locks[n]->unlock();
 }
 
-void ShibInternalConfig::regFactory(const char* type, MetadataFactory* factory)
+#ifndef WIN32
+extern "C" unsigned long openssl_thread_id(void)
 {
-    if (type && factory)
-        m_metadataFactoryMap[type]=factory;
+    return (unsigned long)(pthread_self());
 }
+#endif
 
-void ShibInternalConfig::regFactory(const char* type, RevocationFactory* factory)
+bool ShibConfig::init()
 {
-    if (type && factory)
-        m_revocationFactoryMap[type]=factory;
-}
+    REGISTER_EXCEPTION_FACTORY(MetadataException);
+    REGISTER_EXCEPTION_FACTORY(CredentialException);
+    REGISTER_EXCEPTION_FACTORY(InvalidHandleException);
 
-void ShibInternalConfig::regFactory(const char* type, TrustFactory* factory)
-{
-    if (type && factory)
-        m_trustFactoryMap[type]=factory;
-}
+    // Set up OpenSSL locking.
+       for (int i=0; i<CRYPTO_num_locks(); i++)
+        g_openssl_locks.push_back(Mutex::create());
+       CRYPTO_set_locking_callback(openssl_locking_callback);
+#ifndef WIN32
+    CRYPTO_set_id_callback(openssl_thread_id);
+#endif
 
-void ShibInternalConfig::regFactory(const char* type, CredentialsFactory* factory)
-{
-    if (type && factory)
-    {
-        m_credFactoryMap[type]=factory;
-        SAMLConfig::getConfig().binding_defaults.ssl_ctx_callback=
-            reinterpret_cast<SAMLConfig::SAMLBindingConfig::ssl_ctx_callback_fn>(ssl_ctx_callback);
-    }
+    return true;
 }
 
-void ShibInternalConfig::regFactory(const char* type, CredResolverFactory* factory)
+void ShibConfig::term()
 {
-    if (type && factory)
-        m_credResolverFactoryMap[type]=factory;
+    CRYPTO_set_locking_callback(NULL);
+    for (vector<Mutex*>::iterator i=g_openssl_locks.begin(); i!=g_openssl_locks.end(); i++)
+        delete (*i);
+    g_openssl_locks.clear();
 }
 
-void ShibInternalConfig::regFactory(const char* type, AAPFactory* factory)
+void PlugManager::regFactory(const char* type, Factory* factory)
 {
     if (type && factory)
-        m_aapFactoryMap[type]=factory;
-}
-
-void ShibInternalConfig::unregFactory(const char* type)
-{
-    if (type) {
-        m_metadataFactoryMap.erase(type);
-        m_revocationFactoryMap.erase(type);
-        m_trustFactoryMap.erase(type);
-        m_credFactoryMap.erase(type);
-        m_aapFactoryMap.erase(type);
-        m_credResolverFactoryMap.erase(type);
-    }
-}
-
-IMetadata* ShibInternalConfig::newMetadata(const char* type, const DOMElement* source) const
-{
-    MetadataFactoryMap::const_iterator i=m_metadataFactoryMap.find(type);
-    if (i==m_metadataFactoryMap.end())
-    {
-        NDC ndc("newMetadata");
-        Category::getInstance(SHIB_LOGCAT".ShibInternalConfig").error("unknown metadata type: %s",type);
-        return NULL;
-    }
-    return i->second(source);
+        m_map[type]=factory;
 }
 
-IRevocation* ShibInternalConfig::newRevocation(const char* type, const DOMElement* source) const
+IPlugIn* PlugManager::newPlugin(const char* type, const DOMElement* source)
 {
-    RevocationFactoryMap::const_iterator i=m_revocationFactoryMap.find(type);
-    if (i==m_revocationFactoryMap.end())
-    {
-        NDC ndc("newRevocation");
-        Category::getInstance(SHIB_LOGCAT".ShibInternalConfig").error("unknown revocation type: %s",type);
-        return NULL;
-    }
+    FactoryMap::const_iterator i=m_map.find(type);
+    if (i==m_map.end())
+        throw saml::UnsupportedExtensionException(std::string("unable to build plugin of type '") + type + "'");
     return i->second(source);
 }
 
-ITrust* ShibInternalConfig::newTrust(const char* type, const DOMElement* source) const
+void PlugManager::unregFactory(const char* type)
 {
-    TrustFactoryMap::const_iterator i=m_trustFactoryMap.find(type);
-    if (i==m_trustFactoryMap.end())
-    {
-        NDC ndc("newTrust");
-        Category::getInstance(SHIB_LOGCAT".ShibInternalConfig").error("unknown trust type: %s",type);
-        return NULL;
-    }
-    return i->second(source);
-}
-
-ICredentials* ShibInternalConfig::newCredentials(const char* type, const DOMElement* source) const
-{
-    CredentialsFactoryMap::const_iterator i=m_credFactoryMap.find(type);
-    if (i==m_credFactoryMap.end())
-    {
-        NDC ndc("newCredentials");
-        Category::getInstance(SHIB_LOGCAT".ShibInternalConfig").error("unknown credentials type: %s",type);
-        return NULL;
-    }
-    return i->second(source);
-}
-
-IAAP* ShibInternalConfig::newAAP(const char* type, const DOMElement* source) const
-{
-    AAPFactoryMap::const_iterator i=m_aapFactoryMap.find(type);
-    if (i==m_aapFactoryMap.end())
-    {
-        NDC ndc("newAAP");
-        Category::getInstance(SHIB_LOGCAT".ShibInternalConfig").error("unknown AAP type: %s",type);
-        return NULL;
-    }
-    return i->second(source);
-}
-
-ICredResolver* ShibInternalConfig::newCredResolver(const char* type, const DOMElement* source) const
-{
-    CredResolverFactoryMap::const_iterator i=m_credResolverFactoryMap.find(type);
-    if (i==m_credResolverFactoryMap.end())
-    {
-        NDC ndc("newCredResolver");
-        Category::getInstance(SHIB_LOGCAT".ShibInternalConfig").error("unknown cred resolver type: %s",type);
-        return NULL;
-    }
-    return i->second(source);
+    if (type)
+        m_map.erase(type);
 }
 
 ShibConfig& ShibConfig::getConfig()