Pass ShibINI object to extension libraries
[shibboleth/sp.git] / shib-target / shib-config.cpp
1 /*
2  * shib-config.cpp -- ShibTarget initialization and finalization routines
3  *
4  * Created By:  Derek Atkins <derek@ihtfp.com>
5  *
6  * $Id$
7  */
8
9 #include "shib-target.h"
10
11 #include <log4cpp/PropertyConfigurator.hh>
12 #include <log4cpp/Category.hh>
13
14 using namespace saml;
15 using namespace shibboleth;
16 using namespace shibtarget;
17 using namespace std;
18
19 #ifndef SHIBTARGET_INIFILE
20 #define SHIBTARGET_INIFILE "/opt/shibboleth/etc/shibboleth/shibboleth.ini"
21 #endif
22
23 class STConfig : public ShibTargetConfig
24 {
25 public:
26   STConfig(const char* app_name, const char* inifile);
27   ~STConfig();
28   void shutdown();
29   ShibINI& getINI() { return *ini; }
30
31   void ref();
32 private:
33   SAMLConfig& samlConf;
34   ShibConfig& shibConf;
35   ShibINI* ini;
36   int refcount;
37 };
38
39 namespace {
40   STConfig * g_Config = NULL;
41 }
42
43 CCache* shibtarget::g_shibTargetCCache = NULL;
44
45 /****************************************************************************/
46 // External Interface
47
48
49 ShibTargetConfig& ShibTargetConfig::init(const char* app_name, const char* inifile)
50 {
51   if (!app_name)
52     throw runtime_error ("No Application name");
53
54   if (g_Config) {
55     g_Config->ref();
56     return *g_Config;
57   }
58
59   g_Config = new STConfig(app_name, inifile);
60   return *g_Config;
61 }
62
63
64
65 /****************************************************************************/
66 // STConfig
67
68 STConfig::STConfig(const char* app_name, const char* inifile)
69   :  samlConf(SAMLConfig::getConfig()), shibConf(ShibConfig::getConfig())
70 {
71   ini = new ShibINI((inifile ? inifile : SHIBTARGET_INIFILE));
72
73   string app = app_name;
74   string tag;
75
76   // Initialize Log4cpp
77   if (ini->get_tag (app, SHIBTARGET_TAG_LOGGER, true, &tag)) {
78     cerr << "Trying to load logger configuration: " << tag << "\n";
79     try {
80       log4cpp::PropertyConfigurator::configure(tag);
81     } catch (log4cpp::ConfigureFailure& e) {
82       cerr << "Error reading configuration: " << e.what() << "\n";
83     }
84   } else {
85     log4cpp::Category& category = log4cpp::Category::getRoot();
86     category.setPriority(log4cpp::Priority::DEBUG);
87     cerr << "No logger configuration found\n";
88   }
89
90   log4cpp::Category& log = log4cpp::Category::getInstance("shibtarget.STConfig");
91
92   // Init SAML
93   if (ini->get_tag (app, SHIBTARGET_TAG_SCHEMAS, true, &tag))
94     samlConf.schema_dir = tag;
95   if (ini->get_tag (app, SHIBTARGET_TAG_CERTFILE, true, &tag))
96     samlConf.ssl_certfile = tag;
97   if (ini->get_tag (app, SHIBTARGET_TAG_KEYFILE, true, &tag))
98     samlConf.ssl_keyfile = tag;
99   if (ini->get_tag (app, SHIBTARGET_TAG_KEYPASS, true, &tag))
100     samlConf.ssl_keypass = tag;
101   if (ini->get_tag (app, SHIBTARGET_TAG_CALIST, true, &tag))
102     samlConf.ssl_calist = tag;
103
104   if (!samlConf.init()) {
105     log.error ("Failed to initialize SAML Library");
106     throw runtime_error ("Failed to initialize SAML Library");
107   } else
108     log.debug ("SAML Initialized");
109
110   // Init Shib
111   if (! ini->get_tag (app, SHIBTARGET_TAG_SITES, true, &tag)) {
112     log.crit("No Sites File found in configuration");
113     throw runtime_error ("No Sites File found in configuration");
114   }
115
116   string sitesFile = tag;
117   X509Certificate* verifyKey = NULL;
118
119   if (ini->get_tag (app, SHIBTARGET_TAG_SITESCERT, true, &tag)) {
120     verifyKey = new X509Certificate (X509Certificate::PEM, tag.c_str());
121   }
122
123   shibConf.origin_mapper = new XMLOriginSiteMapper(sitesFile.c_str(),
124                                                    samlConf.ssl_calist.c_str(),
125                                                    verifyKey);
126
127   if (verifyKey)
128     delete verifyKey;
129   
130   if (!shibConf.init()) {
131     log.error ("Failed to initialize Shib library");
132     throw runtime_error ("Failed to initialize Shib Library");
133   } else
134     log.debug ("Shib Initialized");
135
136   // Initialize the SHAR Cache
137   if (!strcmp (app_name, SHIBTARGET_SHAR))
138     g_shibTargetCCache = CCache::getInstance();  
139
140   // Load any extensions
141   string ext = "extensions";
142   if (ini->exists(ext)) {
143     saml::NDC ndc("load extensions");
144     ShibINI::Iterator* iter = ini->tag_iterator(ext);
145
146     for (const string* str = iter->begin(); str; str = iter->next()) {
147       string file = ini->get(ext, *str);
148       try
149       {
150         samlConf.saml_register_extension(file.c_str(),ini);
151         log.debug("%s: loading %s", str->c_str(), file.c_str());
152       }
153       catch (SAMLException& e)
154       {
155         log.error("%s: %s", str->c_str(), e.what());
156       }
157     }
158     delete iter;
159   }
160
161   ref();
162   log.debug("finished");
163 }
164
165 STConfig::~STConfig()
166 {
167   if (ini) delete ini;
168   
169   if (g_shibTargetCCache)
170     delete g_shibTargetCCache;
171
172   delete shibConf.origin_mapper;
173   shibConf.term();
174   samlConf.term();
175 }
176
177 void STConfig::ref()
178 {
179   refcount++;
180 }
181
182 void STConfig::shutdown()
183 {
184   refcount--;
185   if (!refcount) {
186     delete g_Config;
187     g_Config = NULL;
188   }
189 }