Next refactoring stage, STPriv class gone, most of ST API gutted.
[shibboleth/sp.git] / shib-target / shib-config.cpp
1 /*
2  *  Copyright 2001-2005 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 PlugManager::Factory MemoryCacheFactory;
53 PlugManager::Factory ShibSessionInitiatorFactory;
54 PlugManager::Factory SAML1POSTFactory;
55 PlugManager::Factory SAML1ArtifactFactory;
56 PlugManager::Factory ShibLogoutFactory;
57 //PlugManager::Factory htaccessFactory;
58
59 ShibTargetConfig& ShibTargetConfig::getConfig()
60 {
61     return g_Config;
62 }
63
64 bool STConfig::init(const char* schemadir)
65 {
66 #ifdef _DEBUG
67     xmltooling::NDC ndc("init");
68 #endif
69     Category& log = Category::getInstance(SHIBT_LOGCAT".Config");
70
71     if (!schemadir) {
72         log.fatal("XML schema directory not supplied");
73         return false;
74     }
75
76     // This will cause some extra console logging, but for now,
77     // initialize the underlying libraries.
78     SAMLConfig& samlConf=SAMLConfig::getConfig();
79     if (schemadir)
80         samlConf.schema_dir = schemadir;
81     if (!samlConf.init()) {
82         log.fatal("failed to initialize OpenSAML1 library");
83         return false;
84     }
85
86     ShibConfig& shibConf=ShibConfig::getConfig();
87     if (!shibConf.init()) {
88         log.fatal("Failed to initialize Shib library");
89         samlConf.term();
90         return false;
91     }
92     
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     SPConfig::getConfig().ServiceProviderManager.registerFactory(XML_SERVICE_PROVIDER, XMLServiceProviderFactory);
102
103     samlConf.getPlugMgr().regFactory(MEMORY_SESSIONCACHE,&MemoryCacheFactory);
104     
105     auto_ptr_char temp1(shibspconstants::SHIB1_SESSIONINIT_PROFILE_URI);
106     samlConf.getPlugMgr().regFactory(temp1.get(),&ShibSessionInitiatorFactory);
107     samlConf.getPlugMgr().regFactory(samlconstants::SAML1_PROFILE_BROWSER_POST,&SAML1POSTFactory);
108     samlConf.getPlugMgr().regFactory(samlconstants::SAML1_PROFILE_BROWSER_ARTIFACT,&SAML1ArtifactFactory);
109     auto_ptr_char temp4(shibspconstants::SHIB1_LOGOUT_PROFILE_URI);
110     samlConf.getPlugMgr().regFactory(temp4.get(),&ShibLogoutFactory);
111     
112     log.info("finished initializing");
113     return true;
114 }
115
116 bool STConfig::load(const char* config)
117 {
118 #ifdef _DEBUG
119     xmltooling::NDC ndc("load");
120 #endif
121     Category& log = Category::getInstance(SHIBT_LOGCAT".Config");
122
123     if (!config) {
124         log.fatal("path to configuration file not supplied");
125         shutdown();
126         return false;
127     }
128
129     try {
130         log.info("loading configuration file: %s", config);
131         static const XMLCh path[] = UNICODE_LITERAL_4(p,a,t,h);
132         DOMImplementation* impl=DOMImplementationRegistry::getDOMImplementation(NULL);
133         DOMDocument* dummydoc=impl->createDocument();
134         xmltooling::XercesJanitor<DOMDocument> docjanitor(dummydoc);
135         DOMElement* dummy = dummydoc->createElementNS(NULL,path);
136
137         auto_ptr_XMLCh src(config);
138         dummy->setAttributeNS(NULL,path,src.get());
139
140         auto_ptr<ServiceProvider> sp(SPConfig::getConfig().ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER,dummy));
141         sp->init();
142         
143         pair<bool,unsigned int> skew=sp->getUnsignedInt("clockSkew");
144         SAMLConfig::getConfig().clock_skew_secs=skew.first ? skew.second : 180;
145         if (skew.first)
146             XMLToolingConfig::getConfig().clock_skew_secs=skew.second;
147         SPConfig::getConfig().setServiceProvider(sp.release());
148         
149         m_tranLog=new FixedContextCategory(SHIBTRAN_LOGCAT);
150         m_tranLog->info("opened transaction log");
151         m_tranLogLock = xmltooling::Mutex::create();
152     }
153     catch (SAMLException& ex) {
154         log.fatal("caught exception while loading/initializing configuration: %s",ex.what());
155         shutdown();
156         return false;
157     }
158 #ifndef _DEBUG
159     catch (...) {
160         log.fatal("caught exception while loading/initializing configuration");
161         shutdown();
162         return false;
163     }
164 #endif
165
166     log.info("finished loading configuration");
167     return true;
168 }
169
170 void STConfig::shutdown()
171 {
172 #ifdef _DEBUG
173     xmltooling::NDC ndc("shutdown");
174 #endif
175     Category& log = Category::getInstance(SHIBT_LOGCAT".Config");
176     log.info("shutting down the library");
177     delete m_tranLogLock;
178     m_tranLogLock = NULL;
179     //delete m_tranLog; // This is crashing for some reason, but we're shutting down anyway.
180     SPConfig::getConfig().term();
181     ShibConfig::getConfig().term();
182     SAMLConfig::getConfig().term();
183     log.info("library shutdown complete");
184 }