2 * shib-config.cpp -- ShibTarget initialization and finalization routines
4 * Created By: Derek Atkins <derek@ihtfp.com>
9 #include "shib-target.h"
10 #include "ccache-utils.h"
11 #include <shib/shib-threads.h>
13 #include <log4cpp/PropertyConfigurator.hh>
14 #include <log4cpp/Category.hh>
17 using namespace shibboleth;
18 using namespace shibtarget;
20 using namespace log4cpp;
22 #ifndef SHIBTARGET_INIFILE
23 #define SHIBTARGET_INIFILE "/opt/shibboleth/etc/shibboleth/shibboleth.ini"
26 class STConfig : public ShibTargetConfig
29 STConfig(const char* app_name, const char* inifile);
33 ShibINI& getINI() { return *ini; }
35 Iterator<const XMLCh*> getPolicies() { return Iterator<const XMLCh*>(policies); }
44 vector<const XMLCh*> policies;
48 STConfig * g_Config = NULL;
49 Mutex * g_lock = NULL;
52 CCache* shibtarget::g_shibTargetCCache = NULL;
54 /****************************************************************************/
58 void ShibTargetConfig::preinit()
61 g_lock = Mutex::create();
64 ShibTargetConfig& ShibTargetConfig::init(const char* app_name, const char* inifile)
67 throw runtime_error ("ShibTargetConfig not pre-initialized");
70 throw runtime_error ("No Application name");
78 g_Config = new STConfig(app_name, inifile);
83 ShibTargetConfig& ShibTargetConfig::getConfig()
86 throw SAMLException("ShibTargetConfig::getConfig() called with NULL configuration");
90 ShibTargetConfig::~ShibTargetConfig()
94 if (m_SocketName) free(m_SocketName);
98 /****************************************************************************/
101 STConfig::STConfig(const char* app_name, const char* inifile)
102 : samlConf(SAMLConfig::getConfig()), shibConf(ShibConfig::getConfig()),
106 ini = new ShibINI((inifile ? inifile : SHIBTARGET_INIFILE));
108 cerr << "Unable to load the INI file: " <<
109 (inifile ? inifile : SHIBTARGET_INIFILE) << endl;
114 extern "C" SAMLAttribute* ScopedFactory(DOMElement* e)
116 return new ScopedAttribute(e);
119 extern "C" SAMLAttribute* SimpleFactory(DOMElement* e)
121 return new SimpleAttribute(e);
124 void STConfig::init()
126 string app = m_app_name;
129 // Initialize Log4cpp
130 if (ini->get_tag (app, SHIBTARGET_TAG_LOGGER, true, &tag)) {
131 cerr << "Trying to load logger configuration: " << tag << "\n";
133 PropertyConfigurator::configure(tag);
134 } catch (ConfigureFailure& e) {
135 cerr << "Error reading configuration: " << e.what() << "\n";
138 Category& category = Category::getRoot();
139 category.setPriority(log4cpp::Priority::DEBUG);
140 cerr << "No logger configuration found\n";
143 Category& log = Category::getInstance("shibtarget.STConfig");
145 saml::NDC ndc("STConfig::init");
147 // Init SAML Configuration
148 if (ini->get_tag (app, SHIBTARGET_TAG_SAMLCOMPAT, true, &tag))
149 samlConf.compatibility_mode = ShibINI::boolean(tag);
150 if (ini->get_tag (app, SHIBTARGET_TAG_SCHEMAS, true, &tag))
151 samlConf.schema_dir = tag;
153 // Init SAML Binding Configuration
154 if (ini->get_tag (app, SHIBTARGET_TAG_AATIMEOUT, true, &tag))
155 samlConf.binding_defaults.timeout = atoi(tag.c_str());
156 if (ini->get_tag (app, SHIBTARGET_TAG_AACONNECTTO, true, &tag))
157 samlConf.binding_defaults.conn_timeout = atoi(tag.c_str());
158 if (ini->get_tag (app, SHIBTARGET_TAG_CERTFILE, true, &tag))
159 samlConf.binding_defaults.ssl_certfile = tag;
160 if (ini->get_tag (app, SHIBTARGET_TAG_KEYFILE, true, &tag))
161 samlConf.binding_defaults.ssl_keyfile = tag;
162 if (ini->get_tag (app, SHIBTARGET_TAG_KEYPASS, true, &tag))
163 samlConf.binding_defaults.ssl_keypass = tag;
164 if (ini->get_tag (app, SHIBTARGET_TAG_CALIST, true, &tag))
165 samlConf.binding_defaults.ssl_calist = tag;
168 if (!samlConf.init()) {
169 log.fatal ("Failed to initialize SAML Library");
170 throw runtime_error ("Failed to initialize SAML Library");
172 log.debug ("SAML Initialized");
174 log.crit ("Died initializing SAML Library");
179 if (ini->get_tag(app, SHIBTARGET_TAG_AAP, true, &tag))
180 shibConf.aapFile=tag;
183 if (!shibConf.init()) {
184 log.fatal ("Failed to initialize Shib library");
185 throw runtime_error ("Failed to initialize Shib Library");
187 log.debug ("Shib Initialized");
189 log.crit ("Failed initializing Shib library.");
193 // Load any SAML extensions
194 string ext = "extensions:saml";
195 if (ini->exists(ext)) {
196 saml::NDC ndc("load_extensions");
197 ShibINI::Iterator* iter = ini->tag_iterator(ext);
199 for (const string* str = iter->begin(); str; str = iter->next()) {
200 string file = ini->get(ext, *str);
203 samlConf.saml_register_extension(file.c_str(),ini);
204 log.debug("%s: loading %s", str->c_str(), file.c_str());
206 catch (SAMLException& e)
208 log.crit("%s: %s", str->c_str(), e.what());
214 // Load the specified metadata.
215 if (ini->get_tag(app, SHIBTARGET_TAG_METADATA, true, &tag) && ini->exists(tag))
217 ShibINI::Iterator* iter=ini->tag_iterator(tag);
218 for (const string* prov=iter->begin(); prov; prov=iter->next())
220 const string source=ini->get(tag,*prov);
221 log.info("registering metadata provider: type=%s, source=%s",prov->c_str(),source.c_str());
222 if (!shibConf.addMetadata(prov->c_str(),source.c_str()))
224 log.crit("error adding metadata provider: type=%s, source=%s",prov->c_str(),source.c_str());
225 if (!strcmp(app.c_str(), SHIBTARGET_SHAR))
226 throw runtime_error("error adding metadata provider");
232 // Register attributes based on built-in classes.
233 if (ini->exists("attributes")) {
234 log.info("registering attributes");
235 ShibINI::Iterator* iter=ini->tag_iterator("attributes");
236 for (const string* attrname=iter->begin(); attrname; attrname=iter->next())
238 const string factory=ini->get("attributes",*attrname);
239 if (factory=="scoped")
241 auto_ptr<XMLCh> temp(XMLString::transcode(attrname->c_str()));
242 SAMLAttribute::regFactory(temp.get(),shibboleth::Constants::SHIB_ATTRIBUTE_NAMESPACE_URI,&ScopedFactory);
243 log.info("registered scoped attribute (%s)",attrname->c_str());
245 else if (factory=="simple")
247 auto_ptr<XMLCh> temp(XMLString::transcode(attrname->c_str()));
248 SAMLAttribute::regFactory(temp.get(),shibboleth::Constants::SHIB_ATTRIBUTE_NAMESPACE_URI,&SimpleFactory);
249 log.info("registered simple attribute (%s)",attrname->c_str());
255 // Load SAML policies.
256 if (ini->exists(SHIBTARGET_POLICIES)) {
257 log.info("loading SAML policies");
258 ShibINI::Iterator* iter = ini->tag_iterator(SHIBTARGET_POLICIES);
260 for (const string* str = iter->begin(); str; str = iter->next()) {
261 policies.push_back(XMLString::transcode(ini->get(SHIBTARGET_POLICIES, *str).c_str()));
266 // Initialize the SHAR Cache
267 if (!strcmp (app.c_str(), SHIBTARGET_SHAR)) {
268 const char * cache_type = NULL;
269 if (ini->get_tag (app, SHIBTARGET_TAG_CACHETYPE, true, &tag))
270 cache_type = tag.c_str();
272 g_shibTargetCCache = CCache::getInstance(cache_type);
275 string sockname=ini->get(SHIBTARGET_GENERAL, "sharsocket");
277 if (sockname.length()>0)
278 m_SocketName=atoi(sockname.c_str());
280 m_SocketName=SHIB_SHAR_SOCKET;
282 if (sockname.length()>0)
283 m_SocketName=strdup(sockname.c_str());
285 m_SocketName=strdup(SHIB_SHAR_SOCKET);
289 log.debug("finished");
292 STConfig::~STConfig()
294 for (vector<const XMLCh*>::iterator i=policies.begin(); i!=policies.end(); i++)
295 delete const_cast<XMLCh*>(*i);
297 // Unregister attributes based on built-in classes.
298 if (ini && ini->exists("attributes")) {
299 ShibINI::Iterator* iter=ini->tag_iterator("attributes");
300 for (const string* attrname=iter->begin(); attrname; attrname=iter->next())
302 const string factory=ini->get("attributes",*attrname);
303 if (factory=="scoped")
305 auto_ptr<XMLCh> temp(XMLString::transcode(attrname->c_str()));
306 SAMLAttribute::unregFactory(temp.get(),shibboleth::Constants::SHIB_ATTRIBUTE_NAMESPACE_URI);
308 else if (factory=="simple")
310 auto_ptr<XMLCh> temp(XMLString::transcode(attrname->c_str()));
311 SAMLAttribute::unregFactory(temp.get(),shibboleth::Constants::SHIB_ATTRIBUTE_NAMESPACE_URI);
319 if (g_shibTargetCCache)
320 delete g_shibTargetCCache;
331 void STConfig::shutdown()