Move config logic into an "XML" SP plugin, divorce shibd and modules from old libs.
[shibboleth/cpp-sp.git] / shib-target / shib-config.cpp
1 /*
2  *  Copyright 2001-2007 Internet2
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /*
18  * shib-config.cpp -- ShibTarget initialization and finalization routines
19  *
20  * Created By:  Derek Atkins <derek@ihtfp.com>
21  *
22  * $Id$
23  */
24
25 #include "internal.h"
26 #include <shibsp/SPConfig.h>
27 #include <xmltooling/XMLToolingConfig.h>
28
29 #include <log4cpp/OstreamAppender.hh>
30
31 using namespace shibsp;
32 using namespace shibtarget;
33 using namespace shibboleth;
34 using namespace saml;
35 using namespace log4cpp;
36 using namespace std;
37
38 using xmltooling::XMLToolingConfig;
39 using xmltooling::PluginManager;
40
41 namespace {
42     STConfig g_Config;
43 }
44
45 // Factories for built-in plugins we can manufacture. Actual definitions
46 // will be with the actual object implementation.
47 #ifndef WIN32
48 PlugManager::Factory UnixListenerFactory;
49 #endif
50 PlugManager::Factory TCPListenerFactory;
51 //PlugManager::Factory MemoryListenerFactory;
52
53 PluginManager<Handler,const DOMElement*>::Factory ShibSessionInitiatorFactory;
54 PluginManager<Handler,const DOMElement*>::Factory SAML1POSTFactory;
55 PluginManager<Handler,const DOMElement*>::Factory SAML1ArtifactFactory;
56 PluginManager<Handler,const DOMElement*>::Factory ShibLogoutFactory;
57
58 ShibTargetConfig& ShibTargetConfig::getConfig()
59 {
60     return g_Config;
61 }
62
63 bool STConfig::init(const char* schemadir)
64 {
65 #ifdef _DEBUG
66     xmltooling::NDC ndc("init");
67 #endif
68     Category& log = Category::getInstance(SHIBT_LOGCAT".Config");
69
70     if (!schemadir) {
71         log.fatal("XML schema directory not supplied");
72         return false;
73     }
74
75     // This will cause some extra console logging, but for now,
76     // initialize the underlying libraries.
77     SAMLConfig& samlConf=SAMLConfig::getConfig();
78     if (schemadir)
79         samlConf.schema_dir = schemadir;
80     if (!samlConf.init()) {
81         log.fatal("failed to initialize OpenSAML1 library");
82         return false;
83     }
84
85     ShibConfig& shibConf=ShibConfig::getConfig();
86     if (!shibConf.init()) {
87         log.fatal("Failed to initialize Shib library");
88         samlConf.term();
89         return false;
90     }
91     
92     SPConfig& conf=SPConfig::getConfig();
93     if (!SPConfig::getConfig().init(NULL)) {
94         log.fatal("Failed to initialize SP library");
95         shibConf.term();
96         samlConf.term();
97         return false;
98     }
99
100     // Register built-in plugin types.
101     conf.ServiceProviderManager.registerFactory(XML_SERVICE_PROVIDER, XMLServiceProviderFactory);
102
103     conf.SessionInitiatorManager.registerFactory(shibspconstants::SHIB1_SESSIONINIT_PROFILE_URI,&ShibSessionInitiatorFactory);
104     conf.AssertionConsumerServiceManager.registerFactory(samlconstants::SAML1_PROFILE_BROWSER_POST,&SAML1POSTFactory);
105     conf.AssertionConsumerServiceManager.registerFactory(samlconstants::SAML1_PROFILE_BROWSER_ARTIFACT,&SAML1ArtifactFactory);
106     conf.SingleLogoutServiceManager.registerFactory(shibspconstants::SHIB1_LOGOUT_PROFILE_URI,&ShibLogoutFactory);
107     
108     log.info("finished initializing");
109     return true;
110 }
111
112 bool STConfig::load(const char* config)
113 {
114 #ifdef _DEBUG
115     xmltooling::NDC ndc("load");
116 #endif
117     Category& log = Category::getInstance(SHIBT_LOGCAT".Config");
118
119     if (!config) {
120         log.fatal("path to configuration file not supplied");
121         shutdown();
122         return false;
123     }
124
125     try {
126         log.info("loading configuration file: %s", config);
127         static const XMLCh path[] = UNICODE_LITERAL_4(p,a,t,h);
128         DOMImplementation* impl=DOMImplementationRegistry::getDOMImplementation(NULL);
129         DOMDocument* dummydoc=impl->createDocument();
130         xmltooling::XercesJanitor<DOMDocument> docjanitor(dummydoc);
131         DOMElement* dummy = dummydoc->createElementNS(NULL,path);
132
133         auto_ptr_XMLCh src(config);
134         dummy->setAttributeNS(NULL,path,src.get());
135
136         auto_ptr<ServiceProvider> sp(SPConfig::getConfig().ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER,dummy));
137         sp->init();
138         
139         pair<bool,unsigned int> skew=sp->getUnsignedInt("clockSkew");
140         SAMLConfig::getConfig().clock_skew_secs=skew.first ? skew.second : 180;
141         SPConfig::getConfig().setServiceProvider(sp.release());
142         
143         m_tranLog=new FixedContextCategory(SHIBTRAN_LOGCAT);
144         m_tranLog->info("opened transaction log");
145         m_tranLogLock = xmltooling::Mutex::create();
146     }
147     catch (SAMLException& ex) {
148         log.fatal("caught exception while loading/initializing configuration: %s",ex.what());
149         shutdown();
150         return false;
151     }
152 #ifndef _DEBUG
153     catch (...) {
154         log.fatal("caught exception while loading/initializing configuration");
155         shutdown();
156         return false;
157     }
158 #endif
159
160     log.info("finished loading configuration");
161     return true;
162 }
163
164 void STConfig::shutdown()
165 {
166 #ifdef _DEBUG
167     xmltooling::NDC ndc("shutdown");
168 #endif
169     Category& log = Category::getInstance(SHIBT_LOGCAT".Config");
170     log.info("shutting down the library");
171     delete m_tranLogLock;
172     m_tranLogLock = NULL;
173     //delete m_tranLog; // This is crashing for some reason, but we're shutting down anyway.
174     SPConfig::getConfig().term();
175     ShibConfig::getConfig().term();
176     SAMLConfig::getConfig().term();
177     log.info("library shutdown complete");
178 }