Porting changes from 1.2 branch
[shibboleth/sp.git] / shib / ShibConfig.cpp
index 194cf81..4372d77 100644 (file)
    $History:$
 */
 
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#define SHIB_INSTANTIATE
+
 #include "internal.h"
-#include <log4cpp/Category.hh>
+#include "shib-threads.h"
+
+#include <openssl/err.h>
 
 using namespace saml;
 using namespace shibboleth;
+using namespace log4cpp;
+using namespace std;
 
-SAML_EXCEPTION_FACTORY(UnsupportedProtocolException);
-SAML_EXCEPTION_FACTORY(OriginSiteMapperException);
+SAML_EXCEPTION_FACTORY(MetadataException);
+SAML_EXCEPTION_FACTORY(CredentialException);
+SAML_EXCEPTION_FACTORY(InvalidHandleException);
 
 namespace {
-    ShibInternalConfig g_config;
+    ShibConfig g_config;
+    vector<Mutex*> g_openssl_locks;
 }
 
-bool ShibInternalConfig::init()
+extern "C" void openssl_locking_callback(int mode,int n,const char *file,int line)
 {
-    saml::NDC ndc("init");
+    if (mode & CRYPTO_LOCK)
+        g_openssl_locks[n]->lock();
+    else
+        g_openssl_locks[n]->unlock();
+}
 
-    REGISTER_EXCEPTION_FACTORY(UnsupportedProtocolException);
-    REGISTER_EXCEPTION_FACTORY(OriginSiteMapperException);
+#ifndef WIN32
+extern "C" unsigned long openssl_thread_id(void)
+{
+    return (unsigned long)(pthread_self());
+}
+#endif
 
-    // Register extension schema.
-    saml::XML::registerSchema(XML::SHIB_NS,XML::SHIB_SCHEMA_ID);
+bool ShibConfig::init()
+{
+    REGISTER_EXCEPTION_FACTORY(MetadataException);
+    REGISTER_EXCEPTION_FACTORY(CredentialException);
+    REGISTER_EXCEPTION_FACTORY(InvalidHandleException);
 
-    m_manager=xmlSecSimpleKeysMngrCreate();
-    if (origin_mapper && origin_mapper->getTrustedRoots() && *(origin_mapper->getTrustedRoots()) &&
-        xmlSecSimpleKeysMngrLoadPemCert(m_manager,origin_mapper->getTrustedRoots(),true) < 0)
-    {
-        log4cpp::Category::getInstance(SHIB_LOGCAT".ShibConfig").fatal("init: failed to load CAs into simple key manager");
-        xmlSecSimpleKeysMngrDestroy(m_manager);
-        m_manager=NULL;
-        return false;
-    }
-    SAMLConfig::getConfig().xmlsig_ptr=m_manager;
+    // 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
 
     return true;
 }
 
-void ShibInternalConfig::term()
+void ShibConfig::term()
+{
+    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 PlugManager::regFactory(const char* type, Factory* factory)
 {
-    if (m_manager)
-        xmlSecSimpleKeysMngrDestroy(m_manager);
+    if (type && factory)
+        m_map[type]=factory;
+}
+
+IPlugIn* PlugManager::newPlugin(const char* type, const DOMElement* source)
+{
+    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);
+}
+
+void PlugManager::unregFactory(const char* type)
+{
+    if (type)
+        m_map.erase(type);
 }
 
 ShibConfig& ShibConfig::getConfig()
 {
     return g_config;
 }
+
+void shibboleth::log_openssl()
+{
+    const char* file;
+    const char* data;
+    int flags,line;
+
+    unsigned long code=ERR_get_error_line_data(&file,&line,&data,&flags);
+    while (code)
+    {
+        Category& log=Category::getInstance("OpenSSL");
+        log.errorStream() << "error code: " << code << " in " << file << ", line " << line << CategoryStream::ENDLINE;
+        if (data && (flags & ERR_TXT_STRING))
+            log.errorStream() << "error data: " << data << CategoryStream::ENDLINE;
+        code=ERR_get_error_line_data(&file,&line,&data,&flags);
+    }
+}