2 * Copyright 2001-2006 Internet2
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * XMLToolingConfig.cpp
20 * Library configuration
24 #include "exceptions.h"
25 #include "XMLToolingConfig.h"
26 #include "encryption/Encryption.h"
27 #include "impl/UnknownElement.h"
28 #include "security/TrustEngine.h"
29 #include "security/OpenSSLCryptoX509CRL.h"
30 #include "signature/CredentialResolver.h"
31 #include "soap/SOAP.h"
33 #include "util/ReplayCache.h"
34 #include "util/StorageService.h"
35 #include "util/TemplateEngine.h"
36 #include "util/XMLConstants.h"
37 #include "validation/ValidatorSuite.h"
44 #include <log4cpp/Category.hh>
45 #include <log4cpp/PropertyConfigurator.hh>
46 #include <log4cpp/OstreamAppender.hh>
47 #include <xercesc/util/PlatformUtils.hpp>
48 #ifndef XMLTOOLING_NO_XMLSEC
49 #include <xsec/framework/XSECProvider.hpp>
50 #include <openssl/err.h>
53 using namespace soap11;
54 using namespace xmlencryption;
55 using namespace xmlsignature;
56 using namespace xmltooling;
57 using namespace log4cpp;
60 DECL_EXCEPTION_FACTORY(XMLParserException,xmltooling);
61 DECL_EXCEPTION_FACTORY(XMLObjectException,xmltooling);
62 DECL_EXCEPTION_FACTORY(MarshallingException,xmltooling);
63 DECL_EXCEPTION_FACTORY(UnmarshallingException,xmltooling);
64 DECL_EXCEPTION_FACTORY(UnknownElementException,xmltooling);
65 DECL_EXCEPTION_FACTORY(UnknownAttributeException,xmltooling);
66 DECL_EXCEPTION_FACTORY(UnknownExtensionException,xmltooling);
67 DECL_EXCEPTION_FACTORY(ValidationException,xmltooling);
68 DECL_EXCEPTION_FACTORY(XMLSecurityException,xmltooling);
69 DECL_EXCEPTION_FACTORY(IOException,xmltooling);
71 #ifndef XMLTOOLING_NO_XMLSEC
72 DECL_EXCEPTION_FACTORY(SignatureException,xmlsignature);
75 namespace xmltooling {
76 XMLToolingInternalConfig g_config;
79 XMLToolingConfig& XMLToolingConfig::getConfig()
84 XMLToolingInternalConfig& XMLToolingInternalConfig::getInternalConfig()
89 bool XMLToolingInternalConfig::log_config(const char* config)
92 if (!config || !*config)
93 config=getenv("XMLTOOLING_LOG_CONFIG");
94 if (!config || !*config)
98 Category& root = Category::getRoot();
99 if (!strcmp(config,"DEBUG")) {
100 root.setPriority(Priority::DEBUG);
103 else if (!strcmp(config,"INFO")) {
104 root.setPriority(Priority::INFO);
107 else if (!strcmp(config,"NOTICE")) {
108 root.setPriority(Priority::NOTICE);
111 else if (!strcmp(config,"WARN")) {
112 root.setPriority(Priority::WARN);
115 else if (!strcmp(config,"ERROR")) {
116 root.setPriority(Priority::ERROR);
119 else if (!strcmp(config,"CRIT")) {
120 root.setPriority(Priority::CRIT);
123 else if (!strcmp(config,"ALERT")) {
124 root.setPriority(Priority::ALERT);
127 else if (!strcmp(config,"EMERG")) {
128 root.setPriority(Priority::EMERG);
131 else if (!strcmp(config,"FATAL")) {
132 root.setPriority(Priority::FATAL);
136 root.setAppender(new OstreamAppender("default",&cerr));
138 PropertyConfigurator::configure(config);
140 catch (const ConfigureFailure& e) {
141 Category::getInstance(XMLTOOLING_LOGCAT".Logging").crit("failed to initialize log4cpp: %s", e.what());
148 void XMLToolingConfig::setReplayCache(ReplayCache* replayCache)
150 delete m_replayCache;
151 m_replayCache = replayCache;
154 void XMLToolingConfig::setTemplateEngine(TemplateEngine* templateEngine)
156 delete m_templateEngine;
157 m_templateEngine = templateEngine;
160 bool XMLToolingInternalConfig::init()
163 xmltooling::NDC ndc("init");
165 Category& log=Category::getInstance(XMLTOOLING_LOGCAT".XMLToolingConfig");
167 log.debug("library initialization started");
169 xercesc::XMLPlatformUtils::Initialize();
170 log.debug("Xerces initialization complete");
172 #ifndef XMLTOOLING_NO_XMLSEC
173 XSECPlatformUtils::Initialise();
174 m_xsecProvider=new XSECProvider();
175 log.debug("XMLSec initialization complete");
178 m_parserPool=new ParserPool();
179 m_validatingPool=new ParserPool(true,true);
180 m_lock=xercesc::XMLPlatformUtils::makeMutex();
182 // Load catalogs from path.
183 if (!catalog_path.empty()) {
184 char* catpath=strdup(catalog_path.c_str());
187 while (start && *start) {
188 sep=strchr(start,PATH_SEPARATOR_CHAR);
191 auto_ptr_XMLCh temp(start);
192 m_validatingPool->loadCatalog(temp.get());
193 start = sep ? sep + 1 : NULL;
198 // default registrations
199 XMLObjectBuilder::registerDefaultBuilder(new UnknownElementBuilder());
201 registerKeyInfoClasses();
202 registerEncryptionClasses();
203 registerSOAPClasses();
205 REGISTER_EXCEPTION_FACTORY(XMLParserException,xmltooling);
206 REGISTER_EXCEPTION_FACTORY(XMLObjectException,xmltooling);
207 REGISTER_EXCEPTION_FACTORY(MarshallingException,xmltooling);
208 REGISTER_EXCEPTION_FACTORY(UnmarshallingException,xmltooling);
209 REGISTER_EXCEPTION_FACTORY(UnknownElementException,xmltooling);
210 REGISTER_EXCEPTION_FACTORY(UnknownAttributeException,xmltooling);
211 REGISTER_EXCEPTION_FACTORY(ValidationException,xmltooling);
212 REGISTER_EXCEPTION_FACTORY(XMLSecurityException,xmltooling);
213 REGISTER_EXCEPTION_FACTORY(IOException,xmltooling);
215 #ifndef XMLTOOLING_NO_XMLSEC
216 XMLObjectBuilder::registerBuilder(QName(XMLConstants::XMLSIG_NS,Signature::LOCAL_NAME),new SignatureBuilder());
217 REGISTER_EXCEPTION_FACTORY(SignatureException,xmlsignature);
218 registerKeyResolvers();
219 registerCredentialResolvers();
220 registerTrustEngines();
222 registerStorageServices();
224 // Register xml:id as an ID attribute.
225 static const XMLCh xmlid[] = UNICODE_LITERAL_2(i,d);
226 AttributeExtensibleXMLObject::registerIDAttribute(QName(XMLConstants::XML_NS, xmlid));
228 catch (const xercesc::XMLException&) {
229 log.fatal("caught exception while initializing Xerces");
233 log.info("library initialization complete");
237 void XMLToolingInternalConfig::term()
239 SchemaValidators.destroyValidators();
240 XMLObjectBuilder::destroyBuilders();
241 XMLToolingException::deregisterFactories();
242 AttributeExtensibleXMLObject::deregisterIDAttributes();
244 #ifndef XMLTOOLING_NO_XMLSEC
245 TrustEngineManager.deregisterFactories();
246 CredentialResolverManager.deregisterFactories();
247 KeyResolverManager.deregisterFactories();
250 delete m_replayCache;
251 m_replayCache = NULL;
253 delete m_templateEngine;
254 m_templateEngine = NULL;
256 for (vector<void*>::reverse_iterator i=m_libhandles.rbegin(); i!=m_libhandles.rend(); i++) {
258 FARPROC fn=GetProcAddress(static_cast<HMODULE>(*i),"xmltooling_extension_term");
261 FreeLibrary(static_cast<HMODULE>(*i));
262 #elif defined(HAVE_DLFCN_H)
263 void (*fn)()=(void (*)())dlsym(*i,"xmltooling_extension_term");
268 # error "Don't know about dynamic loading on this platform!"
271 m_libhandles.clear();
275 delete m_validatingPool;
276 m_validatingPool=NULL;
278 #ifndef XMLTOOLING_NO_XMLSEC
279 delete m_xsecProvider;
281 XSECPlatformUtils::Terminate();
284 xercesc::XMLPlatformUtils::closeMutex(m_lock);
286 xercesc::XMLPlatformUtils::Terminate();
289 xmltooling::NDC ndc("term");
291 Category::getInstance(XMLTOOLING_LOGCAT".XMLToolingConfig").info("library shutdown complete");
294 Lockable* XMLToolingInternalConfig::lock()
296 xercesc::XMLPlatformUtils::lockMutex(m_lock);
300 void XMLToolingInternalConfig::unlock()
302 xercesc::XMLPlatformUtils::unlockMutex(m_lock);
305 bool XMLToolingInternalConfig::load_library(const char* path, void* context)
308 xmltooling::NDC ndc("LoadLibrary");
310 Category& log=Category::getInstance(XMLTOOLING_LOGCAT".XMLToolingConfig");
311 log.info("loading extension: %s", path);
317 char* fixed=const_cast<char*>(path);
318 if (strchr(fixed,'/')) {
321 while (p=strchr(p,'/'))
325 UINT em=SetErrorMode(SEM_FAILCRITICALERRORS);
327 handle=LoadLibraryEx(fixed,NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
329 handle=LoadLibraryEx(fixed,NULL,0);
331 throw runtime_error(string("unable to load extension library: ") + fixed);
332 FARPROC fn=GetProcAddress(handle,"xmltooling_extension_init");
334 throw runtime_error(string("unable to locate xmltooling_extension_init entry point: ") + fixed);
335 if (reinterpret_cast<int(*)(void*)>(fn)(context)!=0)
336 throw runtime_error(string("detected error in xmltooling_extension_init: ") + fixed);
341 catch(runtime_error& e) {
351 #elif defined(HAVE_DLFCN_H)
352 void* handle=dlopen(path,RTLD_LAZY);
354 throw runtime_error(string("unable to load extension library '") + path + "': " + dlerror());
355 int (*fn)(void*)=(int (*)(void*))(dlsym(handle,"xmltooling_extension_init"));
359 string("unable to locate xmltooling_extension_init entry point in '") + path + "': " +
360 (dlerror() ? dlerror() : "unknown error")
365 throw runtime_error(string("detected error in xmltooling_extension_init in ") + path);
367 catch(runtime_error& e) {
374 # error "Don't know about dynamic loading on this platform!"
376 m_libhandles.push_back(handle);
377 log.info("loaded extension: %s", path);
381 #ifndef XMLTOOLING_NO_XMLSEC
382 void xmltooling::log_openssl()
388 unsigned long code=ERR_get_error_line_data(&file,&line,&data,&flags);
390 Category& log=Category::getInstance("OpenSSL");
391 log.errorStream() << "error code: " << code << " in " << file << ", line " << line << CategoryStream::ENDLINE;
392 if (data && (flags & ERR_TXT_STRING))
393 log.errorStream() << "error data: " << data << CategoryStream::ENDLINE;
394 code=ERR_get_error_line_data(&file,&line,&data,&flags);
398 XSECCryptoX509CRL* XMLToolingInternalConfig::X509CRL() const
400 return new OpenSSLCryptoX509CRL();