Next integration phase, metadata and trust conversion.
[shibboleth/cpp-sp.git] / shib / ShibConfig.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 /* ShibConfig.cpp - Shibboleth runtime configuration
18
19    Scott Cantor
20    6/4/02
21
22    $History:$
23 */
24
25 #include <time.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28
29 #define SHIB_INSTANTIATE
30
31 #include "internal.h"
32
33 #include <openssl/err.h>
34
35 using namespace saml;
36 using namespace shibboleth;
37 using namespace xmltooling;
38 using namespace log4cpp;
39 using namespace std;
40
41
42 namespace {
43     ShibConfig g_config;
44     vector<Mutex*> g_openssl_locks;
45 #ifdef HAVE_GOOD_STL
46     map<xmltooling::xstring,const IAttributeFactory*> attrMap;
47 #else
48     map<XMLCh*,const IAttributeFactory*> attrMap;
49 #endif
50 }
51
52 extern "C" SAMLAttribute* ShibAttributeFactory(DOMElement* e)
53 {
54     // First check for an explicit factory.
55 #ifdef HAVE_GOOD_STL
56     map<xmltooling::xstring,const IAttributeFactory*>::const_iterator i=attrMap.find(e->getAttributeNS(NULL,L(AttributeName)));
57 #else
58     const XMLCh* aname=e->getAttributeNS(NULL,L(AttributeName));
59     map<XMLCh*,const IAttributeFactory*>::const_iterator i;
60     for (i=attrMap.begin(); i!=attrMap.end(); i++)
61         if (!XMLString::compareString(aname,i->first))
62             break;
63 #endif
64     if (i!=attrMap.end())
65         return i->second->build(e);
66
67     // Now check for a Scope attribute to ensure proper value handling whenever possible.
68     DOMElement* n=saml::XML::getFirstChildElement(e,saml::XML::SAML_NS,L(AttributeValue));
69     if (n && n->hasAttributeNS(NULL,ScopedAttribute::Scope))
70         return new ScopedAttribute(e);
71         
72     // Just use the default class.
73     return new SAMLAttribute(e);
74 }
75
76 void ShibConfig::regAttributeMapping(const XMLCh* name, const IAttributeFactory* factory)
77 {
78     if (name && factory) {
79 #ifdef HAVE_GOOD_STL
80         attrMap[name]=factory;
81 #else
82         attrMap.insert(make_pair(XMLString::replicate(name),factory));
83 #endif
84     }
85 }
86
87 void ShibConfig::unregAttributeMapping(const XMLCh* name)
88 {
89     if (name) {
90 #ifdef HAVE_GOOD_STL
91         attrMap.erase(name);
92 #else
93         for (map<XMLCh*,const IAttributeFactory*>::iterator i=attrMap.begin(); i!=attrMap.end(); i++) {
94             if (!XMLString::compareString(name,i->first)) {
95                 XMLCh* temp=i->first;
96                 XMLString::release(&temp);
97                 attrMap.erase(i);
98                 break;
99             }
100         }
101 #endif
102     }
103 }
104
105 void ShibConfig::clearAttributeMappings()
106 {
107 #ifndef HAVE_GOOD_STL
108     for (map<XMLCh*,const IAttributeFactory*>::iterator i=attrMap.begin(); i!=attrMap.end(); i++) {
109         XMLCh* temp=i->first;
110         XMLString::release(&temp);
111     }
112 #endif
113     attrMap.clear();
114 }
115
116 extern "C" void openssl_locking_callback(int mode,int n,const char *file,int line)
117 {
118     if (mode & CRYPTO_LOCK)
119         g_openssl_locks[n]->lock();
120     else
121         g_openssl_locks[n]->unlock();
122 }
123
124 #ifndef WIN32
125 extern "C" unsigned long openssl_thread_id(void)
126 {
127     return (unsigned long)(pthread_self());
128 }
129 #endif
130
131 bool ShibConfig::init()
132 {
133     // Set up OpenSSL locking.
134         for (int i=0; i<CRYPTO_num_locks(); i++)
135         g_openssl_locks.push_back(Mutex::create());
136         CRYPTO_set_locking_callback(openssl_locking_callback);
137 #ifndef WIN32
138     CRYPTO_set_id_callback(openssl_thread_id);
139 #endif
140
141     SAMLAttribute::setFactory(&ShibAttributeFactory);
142     return true;
143 }
144
145 void ShibConfig::term()
146 {
147     SAMLAttribute::setFactory(NULL);
148     clearAttributeMappings();
149    
150     CRYPTO_set_locking_callback(NULL);
151     for (vector<Mutex*>::iterator j=g_openssl_locks.begin(); j!=g_openssl_locks.end(); j++)
152         delete (*j);
153     g_openssl_locks.clear();
154 }
155
156 ShibConfig& ShibConfig::getConfig()
157 {
158     return g_config;
159 }