Corrected dummy mapper interface
[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 "/etc/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 // Mapper
67
68 class DummyMapper : public IOriginSiteMapper
69 {
70 public:
71     DummyMapper();
72     ~DummyMapper();
73     virtual Iterator<xstring> getHandleServiceNames(const XMLCh* originSite) { return Iterator<xstring>(m_hsnames); }
74     virtual Key* getHandleServiceKey(const XMLCh* handleService) { return NULL; }
75     virtual Iterator<xstring> getSecurityDomains(const XMLCh* originSite);
76     virtual const char* getTrustedRoots() { return SAMLConfig::getConfig().ssl_calist.c_str(); }
77
78 private:
79     typedef map<xstring,vector<xstring>*> domains_t;
80     domains_t m_domains;
81     vector<xstring> m_hsnames;
82 };
83
84 DummyMapper::DummyMapper()
85 {
86     auto_ptr<XMLCh> buf(XMLString::transcode("wayf.internet2.edu"));
87     m_hsnames.push_back(buf.get());
88 }
89
90 Iterator<xstring> DummyMapper::getSecurityDomains(const XMLCh* originSite)
91 {
92     domains_t::iterator i=m_domains.find(originSite);
93     if (i==m_domains.end())
94     {
95         vector<xstring>* pv=new vector<xstring>();
96         pv->push_back(originSite);
97         pair<domains_t::iterator,bool> p=m_domains.insert(domains_t::value_type(originSite,pv));
98         i=p.first;
99     }
100     return Iterator<xstring>(*(i->second));
101 }
102
103 DummyMapper::~DummyMapper()
104 {
105     for (domains_t::iterator i=m_domains.begin(); i!=m_domains.end(); i++)
106         delete i->second;
107 }
108
109
110
111
112 /****************************************************************************/
113 // STConfig
114
115 STConfig::STConfig(const char* app_name, const char* inifile)
116   :  samlConf(SAMLConfig::getConfig()), shibConf(ShibConfig::getConfig())
117 {
118   ini = new ShibINI((inifile ? inifile : SHIBTARGET_INIFILE));
119
120   string app = app_name;
121   string tag;
122
123   // Initialize Log4cpp
124   if (ini->get_tag (app, SHIBTARGET_TAG_LOGGER, true, &tag)) {
125     cerr << "Trying to load logger configuration: " << tag << "\n";
126     try {
127       log4cpp::PropertyConfigurator::configure(tag);
128     } catch (log4cpp::ConfigureFailure& e) {
129       cerr << "Error reading configuration: " << e.what() << "\n";
130     }
131   } else {
132     log4cpp::Category& category = log4cpp::Category::getRoot();
133     category.setPriority(log4cpp::Priority::DEBUG);
134     cerr << "No logger configuration found\n";
135   }
136
137   log4cpp::Category& log = log4cpp::Category::getInstance("shibtarget.STConfig");
138
139   // Init SAML
140   if (ini->get_tag (app, SHIBTARGET_TAG_SCHEMAS, true, &tag))
141     samlConf.schema_dir = tag;
142   if (ini->get_tag (app, SHIBTARGET_TAG_CERTFILE, true, &tag))
143     samlConf.ssl_certfile = tag;
144   if (ini->get_tag (app, SHIBTARGET_TAG_KEYFILE, true, &tag))
145     samlConf.ssl_keyfile = tag;
146   if (ini->get_tag (app, SHIBTARGET_TAG_KEYPASS, true, &tag))
147     samlConf.ssl_keypass = tag;
148   if (ini->get_tag (app, SHIBTARGET_TAG_CALIST, true, &tag))
149     samlConf.ssl_calist = tag;
150
151   if (!samlConf.init()) {
152     log.error ("Failed to initialize SAML Library");
153     throw runtime_error ("Failed to initialize SAML Library");
154   } else
155     log.debug ("SAML Initialized");
156
157   // Init Shib
158   if (! ini->get_tag (app, SHIBTARGET_TAG_SITES, true, &tag)) {
159     log.crit("No Sites File found in configuration");
160     throw runtime_error ("No Sites File found in configuration");
161   }
162
163   shibConf.origin_mapper = new XMLOriginSiteMapper(tag.c_str(),samlConf.ssl_calist.c_str());
164   
165   if (!shibConf.init()) {
166     log.error ("Failed to initialize Shib library");
167     throw runtime_error ("Failed to initialize Shib Library");
168   } else
169     log.debug ("Shib Initialized");
170
171   // Initialize the SHAR Cache
172   if (!strcmp (app_name, SHIBTARGET_SHAR))
173     g_shibTargetCCache = CCache::getInstance();  
174
175   // Load any extensions
176   string ext = "extensions";
177   if (ini->exists(ext)) {
178     saml::NDC ndc("load extensions");
179     ShibINI::Iterator* iter = ini->tag_iterator(ext);
180
181     for (const string* str = iter->begin(); str; str = iter->next()) {
182       string file = ini->get(ext, *str);
183       try
184       {
185         samlConf.saml_register_extension(file.c_str());
186         log.debug("%s: loading %s", str->c_str(), file.c_str());
187       }
188       catch (SAMLException& e)
189       {
190         log.error("%s: %s", str->c_str(), e.what());
191       }
192     }
193     delete iter;
194   }
195
196   ref();
197   log.debug("finished");
198 }
199
200 STConfig::~STConfig()
201 {
202   if (ini) delete ini;
203   
204   if (g_shibTargetCCache)
205     delete g_shibTargetCCache;
206
207   delete shibConf.origin_mapper;
208   shibConf.term();
209   samlConf.term();
210 }
211
212 void STConfig::ref()
213 {
214   refcount++;
215 }
216
217 void STConfig::shutdown()
218 {
219   refcount--;
220   if (!refcount) {
221     delete g_Config;
222     g_Config = NULL;
223   }
224 }