Porting changes from 1.2 branch
[shibboleth/sp.git] / shib / ShibConfig.cpp
index 0ad1415..4372d77 100644 (file)
@@ -63,7 +63,8 @@
 #define SHIB_INSTANTIATE
 
 #include "internal.h"
-#include <log4cpp/Category.hh>
+#include "shib-threads.h"
+
 #include <openssl/err.h>
 
 using namespace saml;
@@ -71,163 +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() {}
-
-// Metadata Factories
-extern "C" IMetadata* XMLMetadataFactory(const char* source);
-extern "C" ITrust* XMLTrustFactory(const char* source);
-extern "C" ICredentials* XMLCredentialsFactory(const char* source);
-extern "C" ICredResolver* FileCredResolverFactory(const DOMElement* e);
-extern "C" ICredResolver* KeyInfoResolverFactory(const DOMElement* e);
-extern "C" IAAP* XMLAAPFactory(const char* source);
-
-extern "C" SAMLAttribute* ShibAttributeFactory(DOMElement* e)
+extern "C" void openssl_locking_callback(int mode,int n,const char *file,int line)
 {
-    DOMNode* n=e->getFirstChild();
-    while (n && n->getNodeType()!=DOMNode::ELEMENT_NODE)
-        n=n->getNextSibling();
-    if (n && static_cast<DOMElement*>(n)->hasAttributeNS(NULL,SHIB_L(Scope)))
-        return new ScopedAttribute(e);
-    return new SAMLAttribute(e);
+    if (mode & CRYPTO_LOCK)
+        g_openssl_locks[n]->lock();
+    else
+        g_openssl_locks[n]->unlock();
 }
 
-
-bool ShibInternalConfig::init()
+#ifndef WIN32
+extern "C" unsigned long openssl_thread_id(void)
 {
-    saml::NDC ndc("init");
-
-    REGISTER_EXCEPTION_FACTORY(edu.internet2.middleware.shibboleth.common,UnsupportedProtocolException);
-    REGISTER_EXCEPTION_FACTORY(edu.internet2.middleware.shibboleth.common,MetadataException);
-
-    // Register extension schema.
-    saml::XML::registerSchema(XML::SHIB_NS,XML::SHIB_SCHEMA_ID);
-
-    SAMLAttribute::setFactory(&ShibAttributeFactory);
-
-    // Register metadata factories (some duplicates for backward-compatibility)
-    regFactory("edu.internet2.middleware.shibboleth.metadata.XML",&XMLMetadataFactory);
-    regFactory("edu.internet2.middleware.shibboleth.metadata.provider.XML",&XMLMetadataFactory);
-    regFactory("edu.internet2.middleware.shibboleth.trust.XML",&XMLTrustFactory);
-    regFactory("edu.internet2.middleware.shibboleth.trust.provider.XML",&XMLTrustFactory);
-    regFactory("edu.internet2.middleware.shibboleth.creds.provider.XML",&XMLCredentialsFactory);
-    regFactory("edu.internet2.middleware.shibboleth.creds.provider.FileCredResolver",&FileCredResolverFactory);
-    regFactory("edu.internet2.middleware.shibboleth.creds.provider.KeyInfoResolver",&KeyInfoResolverFactory);
-    regFactory("edu.internet2.middleware.shibboleth.target.AAP.XML",&XMLAAPFactory);
-    regFactory("edu.internet2.middleware.shibboleth.target.AAP.provider.XML",&XMLAAPFactory);
-
-    return true;
+    return (unsigned long)(pthread_self());
 }
+#endif
 
-void ShibInternalConfig::regFactory(const char* type, MetadataFactory* factory)
+bool ShibConfig::init()
 {
-    if (type && factory)
-        m_metadataFactoryMap[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=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_trustFactoryMap.erase(type);
-        m_credFactoryMap.erase(type);
-        m_credResolverFactoryMap.erase(type);
-        m_aapFactoryMap.erase(type);
-    }
+        m_map[type]=factory;
 }
 
-IMetadata* ShibInternalConfig::newMetadata(const char* type, const char* source) const
+IPlugIn* PlugManager::newPlugin(const char* type, const DOMElement* source)
 {
-    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);
-}
-
-ITrust* ShibInternalConfig::newTrust(const char* type, const char* source) const
-{
-    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 char* 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;
-    }
+    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);
 }
 
-IAAP* ShibInternalConfig::newAAP(const char* type, const char* source) const
+void PlugManager::unregFactory(const char* type)
 {
-    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()
@@ -251,16 +162,3 @@ void shibboleth::log_openssl()
         code=ERR_get_error_line_data(&file,&line,&data,&flags);
     }
 }
-
-X509* shibboleth::B64_to_X509(const char* buf)
-{
-       BIO* bmem = BIO_new_mem_buf((void*)buf,-1);
-       BIO* b64 = BIO_new(BIO_f_base64());
-       b64 = BIO_push(b64, bmem);
-    X509* x=NULL;
-    d2i_X509_bio(b64,&x);
-    if (!x)
-        log_openssl();
-    BIO_free_all(b64);
-    return x;
-}