https://issues.shibboleth.net/jira/browse/SSPCPP-128
authorScott Cantor <cantor.2@osu.edu>
Tue, 5 Aug 2008 18:27:16 +0000 (18:27 +0000)
committerScott Cantor <cantor.2@osu.edu>
Tue, 5 Aug 2008 18:27:16 +0000 (18:27 +0000)
apache/mod_apache.cpp
fastcgi/shibauthorizer.cpp
fastcgi/shibresponder.cpp
isapi_shib/isapi_shib.cpp
nsapi_shib/nsapi_shib.cpp
shibd/shibd.cpp
shibsp/SPConfig.cpp
shibsp/SPConfig.h

index e9957b8..d44ec98 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright 2001-2007 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
@@ -16,7 +16,7 @@
 
 /**
  * mod_apache.cpp
- * 
+ *
  * Apache module implementation
  */
 
@@ -545,7 +545,7 @@ extern "C" int shib_check_user(request_rec* r)
   // Short-circuit entirely?
   if (((shib_dir_config*)ap_get_module_config(r->per_dir_config, &mod_shib))->bOff==1)
     return DECLINED;
-    
+
   ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,SH_AP_R(r), "shib_check_user(%d): ENTER", (int)getpid());
 
   ostringstream threadid;
@@ -688,7 +688,7 @@ public:
     Lockable* lock() { return m_mapper->lock(); }
     void unlock() { m_staKey->setData(NULL); m_propsKey->setData(NULL); m_mapper->unlock(); }
     Settings getSettings(const HTTPRequest& request) const;
-    
+
     const PropertySet* getParent() const { return NULL; }
     void setParent(const PropertySet*) {}
     pair<bool,bool> getBool(const char* name, const char* ns=NULL) const;
@@ -944,7 +944,7 @@ AccessControl::aclresult_t htAccessControl::authorized(const SPRequest& request,
     int m=sta->m_req->method_number;
     bool method_restricted=false;
     const char *t, *w;
-    
+
     const array_header* reqs_arr=ap_requires(sta->m_req);
     if (!reqs_arr)
         return shib_acl_indeterminate;  // should never happen
@@ -1028,7 +1028,7 @@ AccessControl::aclresult_t htAccessControl::authorized(const SPRequest& request,
                     request.log(SPRequest::SPDebug,string("htaccess plugin using groups file: ") + sta->m_dc->szAuthGrpFile);
                 grpstatus=groups_for_user(sta->m_req,remote_user.c_str(),sta->m_dc->szAuthGrpFile);
             }
-    
+
             bool negate=false;
             while (*t) {
                 w=ap_getword_conf(sta->m_req->pool,&t);
@@ -1113,7 +1113,7 @@ AccessControl::aclresult_t htAccessControl::authorized(const SPRequest& request,
                         auto_ptr<xercesc::RegularExpression> temp(new xercesc::RegularExpression(trans.get()));
                         re=temp;
                     }
-                    
+
                     for (; !status && attrs.first!=attrs.second; ++attrs.first) {
                         if (checkAttribute(request, attrs.first->second, w, regexp ? re.get() : NULL)) {
                             status = true;
@@ -1236,7 +1236,7 @@ extern "C" apr_status_t shib_exit(void* data)
 }
 #endif
 
-/* 
+/*
  * shire_child_init()
  *  Things to do when the child process is initialized.
  *  (or after the configs are read in apache-2)
@@ -1272,21 +1272,9 @@ extern "C" void shib_child_init(apr_pool_t* p, server_rec* s)
     g_Config->AccessControlManager.registerFactory(HT_ACCESS_CONTROL,&htAccessFactory);
     g_Config->RequestMapperManager.registerFactory(NATIVE_REQUEST_MAPPER,&ApacheRequestMapFactory);
 
-    if (!g_szSHIBConfig)
-        g_szSHIBConfig=getenv("SHIBSP_CONFIG");
-    if (!g_szSHIBConfig)
-        g_szSHIBConfig=SHIBSP_CONFIG;
-    
     try {
-        xercesc::DOMDocument* dummydoc=XMLToolingConfig::getConfig().getParser().newDocument();
-        XercesJanitor<xercesc::DOMDocument> docjanitor(dummydoc);
-        xercesc::DOMElement* dummy = dummydoc->createElementNS(NULL,path);
-        auto_ptr_XMLCh src(g_szSHIBConfig);
-        dummy->setAttributeNS(NULL,path,src.get());
-        dummy->setAttributeNS(NULL,validate,xmlconstants::XML_ONE);
-
-        g_Config->setServiceProvider(g_Config->ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER,dummy));
-        g_Config->getServiceProvider()->init();
+        if (!g_Config->instantiate(g_szSHIBConfig, true))
+            throw exception("unknown error");
     }
     catch (exception& ex) {
         ap_log_error(APLOG_MARK,APLOG_CRIT|APLOG_NOERRNO,SH_AP_R(s),ex.what());
@@ -1387,7 +1375,7 @@ static command_rec shire_cmds[] = {
   {"ShibURLScheme", (config_fn_t)shib_set_server_string_slot,
    (void *) XtOffsetOf (shib_server_config, szScheme),
    RSRC_CONF, TAKE1, "URL scheme to force into generated URLs for a vhost"},
-   
+
   {"ShibRequestSetting", (config_fn_t)shib_table_set, NULL,
    OR_AUTHCFG, TAKE2, "Set arbitrary Shibboleth request property for content"},
 
index 65fc832..4661ee8 100644 (file)
@@ -1,6 +1,6 @@
 /*\r
  *  Copyright 2001-2007 Internet2\r
- * \r
+ *\r
  * Licensed under the Apache License, Version 2.0 (the "License");\r
  * you may not use this file except in compliance with the License.\r
  * You may obtain a copy of the License at\r
@@ -169,7 +169,7 @@ public:
     const char* getRequestBody() const {\r
         throw runtime_error("getRequestBody not implemented by FastCGI authorizer.");\r
     }\r
\r
+\r
     long sendResponse(istream& in, long status) {\r
         string hdr = string("Connection: close\r\n");\r
         for (multimap<string,string>::const_iterator i=m_response_headers.begin(); i!=m_response_headers.end(); ++i)\r
@@ -206,7 +206,7 @@ public:
         return SHIB_RETURN_DONE;\r
     }\r
 \r
-    long returnDecline() { \r
+    long returnDecline() {\r
         return SHIB_RETURN_KO;\r
     }\r
 \r
@@ -250,20 +250,9 @@ int main(void)
         exit(1);\r
     }\r
 \r
-    const char* config=getenv("SHIBSP_CONFIG");\r
-    if (!config)\r
-        config=SHIBSP_CONFIG;\r
-\r
     try {\r
-        DOMDocument* dummydoc=XMLToolingConfig::getConfig().getParser().newDocument();\r
-        XercesJanitor<DOMDocument> docjanitor(dummydoc);\r
-        DOMElement* dummy = dummydoc->createElementNS(NULL,path);\r
-        auto_ptr_XMLCh src(config);\r
-        dummy->setAttributeNS(NULL,path,src.get());\r
-        dummy->setAttributeNS(NULL,validate,xmlconstants::XML_ONE);\r
-\r
-        g_Config->setServiceProvider(g_Config->ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER,dummy));\r
-        g_Config->getServiceProvider()->init();\r
+        if (!g_Config->instantiate(NULL, true))\r
+            throw exception("unknown error");\r
     }\r
     catch (exception& ex) {\r
         g_Config->term();\r
@@ -293,7 +282,7 @@ int main(void)
 \r
     FCGX_Init();\r
     FCGX_InitRequest(&request, 0, 0);\r
-    \r
+\r
     cout << "Shibboleth initialization complete. Starting request loop." << endl;\r
     while (FCGX_Accept_r(&request) == 0)\r
     {\r
@@ -309,7 +298,7 @@ int main(void)
         try {\r
             xmltooling::NDC ndc("FastCGI shibauthorizer");\r
             ShibTargetFCGIAuth sta(&request, g_ServerScheme.c_str(), g_ServerName.c_str(), g_ServerPort);\r
-          \r
+\r
             pair<bool,long> res = sta.getServiceProvider().doAuthentication(sta);\r
             if (res.first) {\r
 #ifdef _DEBUG\r
@@ -319,21 +308,21 @@ int main(void)
                     case SHIB_RETURN_OK:\r
                         print_ok(sta.m_request_headers);\r
                         continue;\r
-              \r
+\r
                     case SHIB_RETURN_KO:\r
                         print_ok(sta.m_request_headers);\r
                         continue;\r
 \r
                     case SHIB_RETURN_DONE:\r
                         continue;\r
-              \r
+\r
                     default:\r
                         cerr << "shib: doAuthentication returned an unexpected result: " << res.second << endl;\r
                         print_error("<html><body>FastCGI Shibboleth authorizer returned an unexpected result.</body></html>");\r
                         continue;\r
                 }\r
             }\r
-          \r
+\r
             res = sta.getServiceProvider().doExport(sta);\r
             if (res.first) {\r
 #ifdef _DEBUG\r
@@ -343,14 +332,14 @@ int main(void)
                     case SHIB_RETURN_OK:\r
                         print_ok(sta.m_request_headers);\r
                         continue;\r
-              \r
+\r
                     case SHIB_RETURN_KO:\r
                         print_ok(sta.m_request_headers);\r
                         continue;\r
 \r
                     case SHIB_RETURN_DONE:\r
                         continue;\r
-              \r
+\r
                     default:\r
                         cerr << "shib: doExport returned an unexpected result: " << res.second << endl;\r
                         print_error("<html><body>FastCGI Shibboleth authorizer returned an unexpected result.</body></html>");\r
@@ -367,14 +356,14 @@ int main(void)
                     case SHIB_RETURN_OK:\r
                         print_ok(sta.m_request_headers);\r
                         continue;\r
-              \r
+\r
                     case SHIB_RETURN_KO:\r
                         print_ok(sta.m_request_headers);\r
                         continue;\r
 \r
                     case SHIB_RETURN_DONE:\r
                         continue;\r
-              \r
+\r
                     default:\r
                         cerr << "shib: doAuthorization returned an unexpected result: " << res.second << endl;\r
                         print_error("<html><body>FastCGI Shibboleth authorizer returned an unexpected result.</body></html>");\r
@@ -383,7 +372,7 @@ int main(void)
             }\r
 \r
             print_ok(sta.m_request_headers);\r
-          \r
+\r
         }\r
         catch (exception& e) {\r
             cerr << "shib: FastCGI authorizer caught an exception: " << e.what() << endl;\r
@@ -402,6 +391,6 @@ int main(void)
 \r
     if (g_Config)\r
         g_Config->term();\r
\r
+\r
     return 0;\r
 }\r
index f40a2e7..fc29234 100644 (file)
@@ -1,6 +1,6 @@
 /*\r
  *  Copyright 2001-2007 Internet2\r
- * \r
+ *\r
  * Licensed under the Apache License, Version 2.0 (the "License");\r
  * you may not use this file except in compliance with the License.\r
  * You may obtain a copy of the License at\r
@@ -209,7 +209,7 @@ public:
     virtual void clearHeader(const char* rawname, const char* cginame) {\r
         throw runtime_error("clearHeader not implemented by FastCGI responder.");\r
     }\r
-  \r
+\r
     virtual void setHeader(const char* name, const char* value) {\r
         throw runtime_error("setHeader not implemented by FastCGI responder.");\r
     }\r
@@ -283,20 +283,9 @@ int main(void)
         exit(1);\r
     }\r
 \r
-    const char* config=getenv("SHIBSP_CONFIG");\r
-    if (!config)\r
-        config=SHIBSP_CONFIG;\r
-\r
     try {\r
-        DOMDocument* dummydoc=XMLToolingConfig::getConfig().getParser().newDocument();\r
-        XercesJanitor<DOMDocument> docjanitor(dummydoc);\r
-        DOMElement* dummy = dummydoc->createElementNS(NULL,path);\r
-        auto_ptr_XMLCh src(config);\r
-        dummy->setAttributeNS(NULL,path,src.get());\r
-        dummy->setAttributeNS(NULL,validate,xmlconstants::XML_ONE);\r
-\r
-        g_Config->setServiceProvider(g_Config->ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER,dummy));\r
-        g_Config->getServiceProvider()->init();\r
+        if (!g_Config->instantiate(NULL, true))\r
+            throw exception("unknown error");\r
     }\r
     catch (exception& ex) {\r
         g_Config->term();\r
@@ -327,7 +316,7 @@ int main(void)
 \r
     FCGX_Init();\r
     FCGX_InitRequest(&request, 0, 0);\r
-    \r
+\r
     cout << "Shibboleth initialization complete. Starting request loop." << endl;\r
     while (FCGX_Accept_r(&request) == 0) {\r
         // Note that the default bufsize (0) will cause the use of iostream\r
@@ -350,7 +339,7 @@ int main(void)
         try {\r
             xmltooling::NDC ndc("FastCGI shibresponder");\r
             ShibTargetFCGI stf(&request, content, g_ServerScheme.c_str(), g_ServerName.c_str(), g_ServerPort);\r
-          \r
+\r
             pair<bool,long> res = stf.getServiceProvider().doHandler(stf);\r
             if (res.first) {\r
 #ifdef _DEBUG\r
@@ -360,7 +349,7 @@ int main(void)
                     case SHIB_RETURN_OK:\r
                         print_ok();\r
                         break;\r
-              \r
+\r
                     case SHIB_RETURN_KO:\r
                         cerr << "shib: doHandler failed to handle the request" << endl;\r
                         print_error("<html><body>FastCGI Shibboleth responder should only be used for Shibboleth protocol requests.</body></html>");\r
@@ -369,7 +358,7 @@ int main(void)
                     case SHIB_RETURN_DONE:\r
                         // response already handled\r
                         break;\r
-              \r
+\r
                     default:\r
                         cerr << "shib: doHandler returned an unexpected result: " << res.second << endl;\r
                         print_error("<html><body>FastCGI Shibboleth responder returned an unexpected result.</body></html>");\r
@@ -379,8 +368,8 @@ int main(void)
             else {\r
                 cerr << "shib: doHandler failed to handle request." << endl;\r
                 print_error("<html><body>FastCGI Shibboleth responder failed to process request.</body></html>");\r
-            }          \r
-          \r
+            }\r
+\r
         }\r
         catch (exception& e) {\r
             cerr << "shib: FastCGI responder caught an exception: " << e.what() << endl;\r
@@ -403,6 +392,6 @@ int main(void)
 \r
     if (g_Config)\r
         g_Config->term();\r
\r
+\r
     return 0;\r
 }\r
index 25ed8a7..8f04cb3 100644 (file)
@@ -170,20 +170,9 @@ extern "C" BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer)
         return FALSE;
     }
 
-    LPCSTR config=getenv("SHIBSP_CONFIG");
-    if (!config)
-        config=SHIBSP_CONFIG;
-
     try {
-        DOMDocument* dummydoc=XMLToolingConfig::getConfig().getParser().newDocument();
-        XercesJanitor<DOMDocument> docjanitor(dummydoc);
-        DOMElement* dummy = dummydoc->createElementNS(NULL,path);
-        auto_ptr_XMLCh src(config);
-        dummy->setAttributeNS(NULL,path,src.get());
-        dummy->setAttributeNS(NULL,validate,xmlconstants::XML_ONE);
-
-        g_Config->setServiceProvider(g_Config->ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER,dummy));
-        g_Config->getServiceProvider()->init();
+        if (!g_Config->instantiate(NULL, true))
+            throw exception("unknown error");
     }
     catch (exception& ex) {
         g_Config->term();
index a8fe8bd..069591a 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright 2001-2007 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
@@ -16,7 +16,7 @@
 
 /**
  * nsapi_shib.cpp
- * 
+ *
  * Shibboleth NSAPI filter
  */
 
@@ -140,22 +140,9 @@ extern "C" NSAPI_PUBLIC int nsapi_shib_init(pblock* pb, ::Session* sn, Request*
 
     g_Config->RequestMapperManager.registerFactory(XML_REQUEST_MAPPER,&SunRequestMapFactory);
 
-    const char* config=pblock_findval("shib-config",pb);
-    if (!config)
-        config=getenv("SHIBSP_CONFIG");
-    if (!config)
-        config=SHIBSP_CONFIG;
-
     try {
-        xercesc::DOMDocument* dummydoc=XMLToolingConfig::getConfig().getParser().newDocument();
-        XercesJanitor<xercesc::DOMDocument> docjanitor(dummydoc);
-        xercesc::DOMElement* dummy = dummydoc->createElementNS(NULL,path);
-        auto_ptr_XMLCh src(config);
-        dummy->setAttributeNS(NULL,path,src.get());
-        dummy->setAttributeNS(NULL,validate,xmlconstants::XML_ONE);
-
-        g_Config->setServiceProvider(g_Config->ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER,dummy));
-        g_Config->getServiceProvider()->init();
+        if (!g_Config->instantiate(pblock_findval("shib-config",pb), true))
+            throw exception("unknown error");
     }
     catch (exception& ex) {
         pblock_nvinsert("error",ex.what(),pb);
@@ -260,7 +247,7 @@ public:
     if (level>=SPError)
         log_error(LOG_FAILURE, "nsapi_shib", m_sn, m_rq, const_cast<char*>(msg.c_str()));
   }
-  const char* getQueryString() const { 
+  const char* getQueryString() const {
     return pblock_findval("query", m_rq->reqpb);
   }
   const char* getRequestBody() const {
@@ -469,7 +456,7 @@ public:
     Lockable* lock() { return m_mapper->lock(); }
     void unlock() { m_stKey->setData(NULL); m_propsKey->setData(NULL); m_mapper->unlock(); }
     Settings getSettings(const HTTPRequest& request) const;
-    
+
     const PropertySet* getParent() const { return NULL; }
     void setParent(const PropertySet*) {}
     pair<bool,bool> getBool(const char* name, const char* ns=NULL) const;
index c1eaf5f..b7a6956 100644 (file)
@@ -1,6 +1,6 @@
 /*\r
  *  Copyright 2001-2007 Internet2\r
- * \r
+ *\r
  * Licensed under the Apache License, Version 2.0 (the "License");\r
  * you may not use this file except in compliance with the License.\r
  * You may obtain a copy of the License at\r
@@ -124,27 +124,9 @@ int real_main(int preinit)
             fprintf(stderr, "configuration is invalid, see console for specific problems\n");\r
             return -1;\r
         }\r
-        \r
-        if (!shar_config)\r
-            shar_config=getenv("SHIBSP_CONFIG");\r
-        if (!shar_config)\r
-            shar_config=SHIBSP_CONFIG;\r
-\r
-        try {\r
-            static const XMLCh path[] = UNICODE_LITERAL_4(p,a,t,h);\r
-            static const XMLCh validate[] = UNICODE_LITERAL_8(v,a,l,i,d,a,t,e);\r
-            xercesc::DOMDocument* dummydoc=XMLToolingConfig::getConfig().getParser().newDocument();\r
-            XercesJanitor<xercesc::DOMDocument> docjanitor(dummydoc);\r
-            xercesc::DOMElement* dummy = dummydoc->createElementNS(NULL,path);\r
-            auto_ptr_XMLCh src(shar_config);\r
-            dummy->setAttributeNS(NULL,path,src.get());\r
-            dummy->setAttributeNS(NULL,validate,xmlconstants::XML_ONE);\r
-    \r
-            conf.setServiceProvider(conf.ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER,dummy));\r
-            conf.getServiceProvider()->init();\r
-        }\r
-        catch (exception& ex) {\r
-            fprintf(stderr, "caught exception while loading configuration: %s\n", ex.what());\r
+\r
+        if (!conf.instantiate(shar_config)) {\r
+            fprintf(stderr, "configuration is invalid, check console for specific problems\n");\r
             conf.term();\r
             return -2;\r
         }\r
@@ -289,26 +271,8 @@ int main(int argc, char *argv[])
         return -1;\r
     }\r
 \r
-    if (!shar_config)\r
-        shar_config=getenv("SHIBSP_CONFIG");\r
-    if (!shar_config)\r
-        shar_config=SHIBSP_CONFIG;\r
-    \r
-    try {\r
-        static const XMLCh path[] = UNICODE_LITERAL_4(p,a,t,h);\r
-        static const XMLCh validate[] = UNICODE_LITERAL_8(v,a,l,i,d,a,t,e);\r
-        xercesc::DOMDocument* dummydoc=XMLToolingConfig::getConfig().getParser().newDocument();\r
-        XercesJanitor<xercesc::DOMDocument> docjanitor(dummydoc);\r
-        xercesc::DOMElement* dummy = dummydoc->createElementNS(NULL,path);\r
-        auto_ptr_XMLCh src(shar_config);\r
-        dummy->setAttributeNS(NULL,path,src.get());\r
-        dummy->setAttributeNS(NULL,validate,xmlconstants::XML_ONE);\r
-\r
-        conf.setServiceProvider(conf.ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER,dummy));\r
-        conf.getServiceProvider()->init();\r
-    }\r
-    catch (exception& ex) {\r
-        fprintf(stderr, "caught exception while loading configuration: %s\n", ex.what());\r
+    if (!conf.instantiate(shar_config)) {\r
+        fprintf(stderr, "configuration is invalid, check console for specific problems\n");\r
         conf.term();\r
         return -2;\r
     }\r
@@ -327,7 +291,7 @@ int main(int argc, char *argv[])
                 perror(pidfile);  // keep running though\r
             }\r
         }\r
-    \r
+\r
         // Run the listener\r
         if (!conf.getServiceProvider()->getListenerService()->run(&shibd_shutdown)) {\r
             fprintf(stderr, "listener failed to enter listen loop\n");\r
index f1a5f0f..7aaaf98 100644 (file)
@@ -1,7 +1,7 @@
 
 /*
  *  Copyright 2001-2007 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
@@ -17,8 +17,8 @@
 
 /**
  * SPConfig.cpp
- * 
- * Library configuration 
+ *
+ * Library configuration
  */
 
 #include "internal.h"
 #endif
 
 #include <ctime>
+#include <xercesc/util/XMLUniDefs.hpp>
 #include <xmltooling/util/NDC.h>
 #include <xmltooling/util/PathResolver.h>
 #include <xmltooling/util/TemplateEngine.h>
+#include <xmltooling/util/XMLHelper.h>
 
 using namespace shibsp;
 using namespace opensaml;
 using namespace xmltooling;
+using namespace std;
 
 DECL_XMLTOOLING_EXCEPTION_FACTORY(AttributeException,shibsp);
 DECL_XMLTOOLING_EXCEPTION_FACTORY(AttributeExtractionException,shibsp);
@@ -114,7 +117,7 @@ bool SPConfig::init(const char* catalog_path, const char* inst_prefix)
         inst_prefix2.push_back((*inst_prefix=='\\') ? ('/') : (*inst_prefix));
         ++inst_prefix;
     }
-    
+
     const char* loglevel=getenv("SHIBSP_LOGGING");
     if (!loglevel)
         loglevel = SHIBSP_LOGGING;
@@ -143,12 +146,12 @@ bool SPConfig::init(const char* catalog_path, const char* inst_prefix)
         log.fatal("failed to initialize XMLTooling library");
         return false;
     }
-#endif    
+#endif
     XMLToolingConfig::getConfig().getPathResolver()->setDefaultPackageName(PACKAGE_NAME);
     XMLToolingConfig::getConfig().getPathResolver()->setDefaultPrefix(inst_prefix2.c_str());
     XMLToolingConfig::getConfig().setTemplateEngine(new TemplateEngine());
     XMLToolingConfig::getConfig().getTemplateEngine()->setTagPrefix("shibmlp");
-    
+
     REGISTER_XMLTOOLING_EXCEPTION_FACTORY(AttributeException,shibsp);
     REGISTER_XMLTOOLING_EXCEPTION_FACTORY(AttributeExtractionException,shibsp);
     REGISTER_XMLTOOLING_EXCEPTION_FACTORY(AttributeFilteringException,shibsp);
@@ -259,3 +262,53 @@ void SPConfig::term()
 #endif
     log.info("%s library shutdown complete", PACKAGE_STRING);
 }
+
+bool SPConfig::instantiate(const char* config, bool rethrow)
+{
+#ifdef _DEBUG
+    NDC ndc("instantiate");
+#endif
+    if (!config)
+        config = getenv("SHIBSP_CONFIG");
+    if (!config)
+        config = SHIBSP_CONFIG;
+    try {
+        xercesc::DOMDocument* dummydoc;
+        if (*config == '"' || *config == '\'') {
+            throw ConfigurationException("The value of SHIBSP_CONFIG started with a quote.");
+        }
+        else if (*config != '<') {
+
+            // Mock up some XML.
+            string resolved(config);
+            stringstream snippet;
+            snippet
+                << "<Dummy path='"
+                << XMLToolingConfig::getConfig().getPathResolver()->resolve(resolved, PathResolver::XMLTOOLING_CFG_FILE)
+                << "' validate='1'/>";
+            dummydoc = XMLToolingConfig::getConfig().getParser().parse(snippet);
+            XercesJanitor<xercesc::DOMDocument> docjanitor(dummydoc);
+            setServiceProvider(ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER, dummydoc->getDocumentElement()));
+        }
+        else {
+            stringstream snippet(config);
+            dummydoc = XMLToolingConfig::getConfig().getParser().parse(snippet);
+            XercesJanitor<xercesc::DOMDocument> docjanitor(dummydoc);
+            static const XMLCh _type[] = UNICODE_LITERAL_4(t,y,p,e);
+            auto_ptr_char type(dummydoc->getDocumentElement()->getAttributeNS(NULL,_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.");
+        }
+
+        getServiceProvider()->init();
+        return true;
+    }
+    catch (exception& ex) {
+        if (rethrow)
+            throw;
+        Category::getInstance(SHIBSP_LOGCAT".Config").fatal("caught exception while loading configuration: %s", ex.what());
+    }
+    return false;
+}
index 81499cd..d58c3a4 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright 2001-2007 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
@@ -16,8 +16,8 @@
 
 /**
  * @file shibsp/SPConfig.h
- * 
- * Library configuration 
+ *
+ * Library configuration
  */
 
 #ifndef __shibsp_config_h__
@@ -75,7 +75,7 @@ namespace shibsp {
 
         /**
          * Returns the global configuration object for the library.
-         * 
+         *
          * @return reference to the global library configuration object
          */
         static SPConfig& getConfig();
@@ -98,10 +98,10 @@ namespace shibsp {
             Logging = 512,
             Handlers = 1024
         };
-        
+
         /**
          * Set a bitmask of subsystems to activate.
-         * 
+         *
          * @param enabled   bitmask of component constants
          */
         void setFeatures(unsigned long enabled) {
@@ -110,69 +110,79 @@ namespace shibsp {
 
         /**
          * Test whether a subsystem is enabled.
-         * 
+         *
          * @param feature   subsystem/component to test
          * @return true iff feature is enabled
          */
         bool isEnabled(components_t feature) {
             return (m_features & feature)>0;
         }
-        
+
         /**
          * Initializes library
-         * 
+         *
          * Each process using the library MUST call this function exactly once
          * before using any library classes.
-         * 
+         *
          * @param catalog_path  delimited set of schema catalog files to load
          * @param inst_prefix   installation prefix for software
-         * @return true iff initialization was successful 
+         * @return true iff initialization was successful
          */
         virtual bool init(const char* catalog_path=NULL, const char* inst_prefix=NULL);
-        
+
         /**
          * Shuts down library
-         * 
+         *
          * Each process using the library SHOULD call this function exactly once
          * before terminating itself.
          */
         virtual void term();
-        
+
         /**
          * Sets the global ServiceProvider instance.
          * This method must be externally synchronized with any code that uses the object.
          * Any previously set object is destroyed.
-         * 
+         *
          * @param serviceProvider   new ServiceProvider instance to store
          */
         void setServiceProvider(ServiceProvider* serviceProvider);
-        
+
         /**
          * Returns the global ServiceProvider instance.
-         * 
+         *
          * @return  global ServiceProvider or NULL
          */
         ServiceProvider* getServiceProvider() const {
             return m_serviceProvider;
         }
 
+        /**
+         * Instantiates and installs a ServiceProvider instance based on an XML configuration string
+         * or a configuration pathname.
+         *
+         * @param config    a snippet of XML to parse (it <strong>MUST</strong> contain a type attribute) or a pathname
+         * @param rethrow   true iff caught exceptions should be rethrown instead of just returning the status
+         * @return true iff instantiation was successful
+         */
+        virtual bool instantiate(const char* config=NULL, bool rethrow=false);
+
 #ifndef SHIBSP_LITE
         /**
          * Sets the global ArtifactResolver instance.
          *
          * <p>This method must be externally synchronized with any code that uses the object.
          * Any previously set object is destroyed.
-         * 
+         *
          * @param artifactResolver   new ArtifactResolver instance to store
          */
         void setArtifactResolver(opensaml::MessageDecoder::ArtifactResolver* artifactResolver) {
             delete m_artifactResolver;
             m_artifactResolver = artifactResolver;
         }
-        
+
         /**
          * Returns the global ArtifactResolver instance.
-         * 
+         *
          * @return  global ArtifactResolver or NULL
          */
         opensaml::MessageDecoder::ArtifactResolver* getArtifactResolver() const {
@@ -182,7 +192,7 @@ namespace shibsp {
 
         /** Separator for serialized values of multi-valued attributes. */
         char attribute_value_delimeter;
-        
+
         /**
          * Manages factories for AccessControl plugins.
          */