/*
- * Copyright 2001-2005 Internet2
+ * Copyright 2001-2007 Internet2
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <log4cpp/PropertyConfigurator.hh>
#include <shibsp/RequestMapper.h>
#include <shibsp/SPConfig.h>
+#include <shibsp/TransactionLog.h>
#include <shibsp/security/PKIXTrustEngine.h>
#include <shibsp/util/DOMPropertySet.h>
#include <saml/SAMLConfig.h>
#include <xmltooling/XMLToolingConfig.h>
#include <xmltooling/security/ChainingTrustEngine.h>
#include <xmltooling/util/ReloadableXMLFile.h>
+#include <xmltooling/util/ReplayCache.h>
using namespace shibsp;
using namespace shibtarget;
class XMLApplication : public virtual IApplication, public DOMPropertySet, public DOMNodeFilter
{
public:
- XMLApplication(const IConfig*, const DOMElement* e, const XMLApplication* base=NULL);
+ XMLApplication(const ServiceProvider*, const DOMElement* e, const XMLApplication* base=NULL);
~XMLApplication() { cleanup(); }
// PropertySet
// IApplication
const char* getId() const {return getString("id").second;}
const char* getHash() const {return m_hash.c_str();}
- Iterator<SAMLAttributeDesignator*> getAttributeDesignators() const;
- Iterator<IAAP*> getAAPProviders() const;
MetadataProvider* getMetadataProvider() const;
TrustEngine* getTrustEngine() const;
- Iterator<const XMLCh*> getAudiences() const;
+ const vector<const XMLCh*>& getAudiences() const;
const PropertySet* getCredentialUse(const EntityDescriptor* provider) const;
const SAMLBrowserProfile* getBrowserProfile() const {return m_profile;}
private:
void cleanup();
- const IConfig* m_ini; // this is ok because its locking scope includes us
+ const ServiceProvider* m_sp; // this is ok because its locking scope includes us
const XMLApplication* m_base;
string m_hash;
- vector<SAMLAttributeDesignator*> m_designators;
- vector<IAAP*> m_aaps;
MetadataProvider* m_metadata;
TrustEngine* m_trust;
vector<const XMLCh*> m_audiences;
#pragma warning( disable : 4250 )
#endif
- class XMLConfig : public IConfig, public ReloadableXMLFile
+ class XMLConfig : public ServiceProvider, public ReloadableXMLFile
{
public:
XMLConfig(const DOMElement* e)
- : ReloadableXMLFile(e), m_impl(NULL), m_listener(NULL), m_sessionCache(NULL), m_replayCache(NULL) {
+ : ReloadableXMLFile(e), m_impl(NULL), m_listener(NULL), m_sessionCache(NULL) {
}
void init() {
~XMLConfig() {
delete m_impl;
delete m_sessionCache;
- delete m_replayCache;
delete m_listener;
+ delete m_tranLog;
+ XMLToolingConfig::getConfig().setReplayCache(NULL);
+ for_each(m_storage.begin(), m_storage.end(), xmltooling::cleanup_pair<string,StorageService>());
}
// PropertySet
const DOMElement* getElement() const {return m_impl->getElement();}
// ServiceProvider
+ TransactionLog* getTransactionLog() const {
+ if (m_tranLog)
+ return m_tranLog;
+ throw ConfigurationException("No TransactionLog available.");
+ }
+
+ StorageService* getStorageService(const char* id) const {
+ if (id) {
+ map<string,StorageService*>::const_iterator i=m_storage.find(id);
+ if (i!=m_storage.end())
+ return i->second;
+ }
+ return NULL;
+ }
+
ListenerService* getListenerService(bool required=true) const {
if (required && !m_listener)
throw ConfigurationException("No ListenerService available.");
return m_listener;
}
- ISessionCache* getSessionCache() const {return m_sessionCache;}
- IReplayCache* getReplayCache() const {return m_replayCache;}
- RequestMapper* getRequestMapper() const {return m_impl->m_requestMapper;}
+ SessionCache* getSessionCache(bool required=true) const {
+ if (required && !m_sessionCache)
+ throw ConfigurationException("No SessionCache available.");
+ return m_sessionCache;
+ }
+
+ RequestMapper* getRequestMapper(bool required=true) const {
+ if (required && !m_impl->m_requestMapper)
+ throw ConfigurationException("No RequestMapper available.");
+ return m_impl->m_requestMapper;
+ }
+
const Application* getApplication(const char* applicationId) const {
map<string,Application*>::const_iterator i=m_impl->m_appmap.find(applicationId);
return (i!=m_impl->m_appmap.end()) ? i->second : NULL;
friend class XMLConfigImpl;
XMLConfigImpl* m_impl;
mutable ListenerService* m_listener;
- mutable ISessionCache* m_sessionCache;
- mutable IReplayCache* m_replayCache;
+ mutable SessionCache* m_sessionCache;
+ mutable TransactionLog* m_tranLog;
+ mutable map<string,StorageService*> m_storage;
};
#if defined (_MSC_VER)
static const XMLCh MemoryListener[] = UNICODE_LITERAL_14(M,e,m,o,r,y,L,i,s,t,e,n,e,r);
static const XMLCh MemorySessionCache[] = UNICODE_LITERAL_18(M,e,m,o,r,y,S,e,s,s,i,o,n,C,a,c,h,e);
static const XMLCh RelyingParty[] = UNICODE_LITERAL_12(R,e,l,y,i,n,g,P,a,r,t,y);
- static const XMLCh ReplayCache[] = UNICODE_LITERAL_11(R,e,p,l,a,y,C,a,c,h,e);
+ static const XMLCh _ReplayCache[] = UNICODE_LITERAL_11(R,e,p,l,a,y,C,a,c,h,e);
static const XMLCh RequestMapProvider[] = UNICODE_LITERAL_18(R,e,q,u,e,s,t,M,a,p,P,r,o,v,i,d,e,r);
- static const XMLCh SessionCache[] = UNICODE_LITERAL_12(S,e,s,s,i,o,n,C,a,c,h,e);
+ static const XMLCh _SessionCache[] = UNICODE_LITERAL_12(S,e,s,s,i,o,n,C,a,c,h,e);
static const XMLCh SessionInitiator[] = UNICODE_LITERAL_16(S,e,s,s,i,o,n,I,n,i,t,i,a,t,o,r);
+ static const XMLCh _StorageService[] = UNICODE_LITERAL_14(S,t,o,r,a,g,e,S,e,r,v,i,c,e);
static const XMLCh OutOfProcess[] = UNICODE_LITERAL_12(O,u,t,O,f,P,r,o,c,e,s,s);
static const XMLCh TCPListener[] = UNICODE_LITERAL_11(T,C,P,L,i,s,t,e,n,e,r);
static const XMLCh TrustProvider[] = UNICODE_LITERAL_13(T,r,u,s,t,P,r,o,v,i,d,e,r);
}
XMLApplication::XMLApplication(
- const IConfig* ini,
+ const ServiceProvider* sp,
const DOMElement* e,
const XMLApplication* base
- ) : m_ini(ini), m_base(base), m_metadata(NULL), m_trust(NULL), m_profile(NULL), m_binding(NULL), m_bindingHook(NULL),
+ ) : m_sp(sp), m_base(base), m_metadata(NULL), m_trust(NULL), m_profile(NULL), m_binding(NULL), m_bindingHook(NULL),
m_credDefault(NULL), m_sessionInitDefault(NULL), m_acsDefault(NULL)
{
#ifdef _DEBUG
m_acsDefault=h2;
}
- // Process general configuration elements.
- XMLSize_t i;
- DOMNodeList* nlist=e->getElementsByTagNameNS(samlconstants::SAML1_NS,AttributeDesignator::LOCAL_NAME);
- for (i=0; nlist && i<nlist->getLength(); i++)
- if (nlist->item(i)->getParentNode()->isSameNode(e))
- m_designators.push_back(new SAMLAttributeDesignator(static_cast<DOMElement*>(nlist->item(i))));
-
- nlist=e->getElementsByTagNameNS(samlconstants::SAML1_NS,Audience::LOCAL_NAME);
- for (i=0; nlist && i<nlist->getLength(); i++)
+ DOMNodeList* nlist=e->getElementsByTagNameNS(samlconstants::SAML1_NS,Audience::LOCAL_NAME);
+ for (XMLSize_t i=0; nlist && i<nlist->getLength(); i++)
if (nlist->item(i)->getParentNode()->isSameNode(e) && nlist->item(i)->hasChildNodes())
m_audiences.push_back(nlist->item(i)->getFirstChild()->getNodeValue());
if (conf.isEnabled(SPConfig::AAP)) {
child = XMLHelper::getFirstChildElement(e,AAPProvider);
while (child) {
- xmltooling::auto_ptr_char type(child->getAttributeNS(NULL,_type));
- log.info("building AAP provider of type %s...",type.get());
- try {
- IPlugIn* plugin=shibConf.getPlugMgr().newPlugin(type.get(),child);
- IAAP* aap=dynamic_cast<IAAP*>(plugin);
- if (aap)
- m_aaps.push_back(aap);
- else {
- delete plugin;
- log.crit("plugin was not an AAP provider");
- }
- }
- catch (exception& ex) {
- log.crit("error building AAP provider: %s", ex.what());
- }
-
+ // TODO: some kind of compatibility
child = XMLHelper::getNextSiblingElement(child,AAPProvider);
}
}
#else
for_each(m_credMap.begin(),m_credMap.end(),xmltooling::cleanup_pair<const XMLCh*,PropertySet>());
#endif
- for_each(m_designators.begin(),m_designators.end(),xmltooling::cleanup<SAMLAttributeDesignator>());
- for_each(m_aaps.begin(),m_aaps.end(),xmltooling::cleanup<IAAP>());
delete m_trust;
delete m_metadata;
{
if (XMLHelper::isNodeNamed(node,samlconstants::SAML1_NS,AttributeDesignator::LOCAL_NAME))
return FILTER_REJECT;
+ else if (XMLHelper::isNodeNamed(node,samlconstants::SAML20_NS,opensaml::saml1::Attribute::LOCAL_NAME))
+ return FILTER_REJECT;
else if (XMLHelper::isNodeNamed(node,samlconstants::SAML1_NS,Audience::LOCAL_NAME))
return FILTER_REJECT;
const XMLCh* name=node->getLocalName();
return m_base->getPropertySet(name,ns);
}
-Iterator<SAMLAttributeDesignator*> XMLApplication::getAttributeDesignators() const
-{
- if (!m_designators.empty() || !m_base)
- return m_designators;
- return m_base->getAttributeDesignators();
-}
-
-Iterator<IAAP*> XMLApplication::getAAPProviders() const
-{
- return (m_aaps.empty() && m_base) ? m_base->getAAPProviders() : m_aaps;
-}
-
MetadataProvider* XMLApplication::getMetadataProvider() const
{
return (!m_metadata && m_base) ? m_base->getMetadataProvider() : m_metadata;
return (!m_trust && m_base) ? m_base->getTrustEngine() : m_trust;
}
-Iterator<const XMLCh*> XMLApplication::getAudiences() const
+const vector<const XMLCh*>& XMLApplication::getAudiences() const
{
return (m_audiences.empty() && m_base) ? m_base->getAudiences() : m_audiences;
}
XMLString::equals(name,MemoryListener) ||
XMLString::equals(name,MemorySessionCache) ||
XMLString::equals(name,RequestMapProvider) ||
- XMLString::equals(name,ReplayCache) ||
- XMLString::equals(name,SessionCache) ||
+ XMLString::equals(name,_ReplayCache) ||
+ XMLString::equals(name,_SessionCache) ||
+ XMLString::equals(name,_StorageService) ||
XMLString::equals(name,TCPListener) ||
XMLString::equals(name,UnixListener))
return FILTER_REJECT;
Category& log=Category::getInstance(SHIBT_LOGCAT".Config");
try {
- SAMLConfig& shibConf=SAMLConfig::getConfig();
SPConfig& conf=SPConfig::getConfig();
+ SAMLConfig& shibConf=SAMLConfig::getConfig();
+ XMLToolingConfig& xmlConf=XMLToolingConfig::getConfig();
const DOMElement* SHAR=XMLHelper::getFirstChildElement(e,OutOfProcess);
if (!SHAR)
SHAR=XMLHelper::getFirstChildElement(e,Global);
log.debug("loading new logging configuration from (%s), check log destination for status of configuration",logpath.get());
XMLToolingConfig::getConfig().log_config(logpath.get());
}
+
+ if (first)
+ m_outer->m_tranLog = new TransactionLog();
}
// First load any property sets.
load(e,log,this,&root_remap);
const DOMElement* child;
- IPlugIn* plugin=NULL;
string plugtype;
// Much of the processing can only occur on the first instantiation.
// TODO: This code's a mess, due to a very bad config layout for the caches...
// Needs rework with the new config file.
const DOMElement* container=conf.isEnabled(SPConfig::OutOfProcess) ? SHAR : SHIRE;
- child=XMLHelper::getFirstChildElement(container,MemorySessionCache);
+
+ // First build any StorageServices.
+ string inmemID;
+ child=XMLHelper::getFirstChildElement(container,_StorageService);
+ while (child) {
+ xmltooling::auto_ptr_char id(child->getAttributeNS(NULL,Id));
+ xmltooling::auto_ptr_char type(child->getAttributeNS(NULL,_type));
+ if (id.get() && type.get()) {
+ try {
+ log.info("building StorageService (%s) of type %s...", id.get(), type.get());
+ m_outer->m_storage[id.get()] = xmlConf.StorageServiceManager.newPlugin(type.get(),child);
+ if (!strcmp(type.get(),MEMORY_STORAGE_SERVICE))
+ inmemID = id.get();
+ }
+ catch (exception& ex) {
+ log.crit("failed to instantiate StorageService (%s): %s", id.get(), ex.what());
+ }
+ }
+ child=XMLHelper::getNextSiblingElement(container,_StorageService);
+ }
+
+ child=XMLHelper::getFirstChildElement(container,_SessionCache);
if (child) {
- log.info("building Session Cache of type %s...",MEMORY_SESSIONCACHE);
- plugin=shibConf.getPlugMgr().newPlugin(MEMORY_SESSIONCACHE,child);
+ xmltooling::auto_ptr_char type(child->getAttributeNS(NULL,_type));
+ log.info("building Session Cache of type %s...",type.get());
+ m_outer->m_sessionCache=conf.SessionCacheManager.newPlugin(type.get(),child);
}
- else {
- child=XMLHelper::getFirstChildElement(container,SessionCache);
- if (child) {
- xmltooling::auto_ptr_char type(child->getAttributeNS(NULL,_type));
- log.info("building Session Cache of type %s...",type.get());
- plugin=shibConf.getPlugMgr().newPlugin(type.get(),child);
- }
- else {
- log.info("custom SessionCache unspecified or no longer supported, building SessionCache of type %s...",MEMORY_SESSIONCACHE);
- plugin=shibConf.getPlugMgr().newPlugin(MEMORY_SESSIONCACHE,child);
+ else if (conf.isEnabled(SPConfig::OutOfProcess)) {
+ log.warn("custom SessionCache unspecified or no longer supported, building SessionCache of type %s...",STORAGESERVICE_SESSION_CACHE);
+ if (inmemID.empty()) {
+ inmemID = "memory";
+ log.info("no StorageServices configured, providing in-memory version for legacy config");
+ m_outer->m_storage[inmemID] = xmlConf.StorageServiceManager.newPlugin(MEMORY_STORAGE_SERVICE,NULL);
}
+ child = container->getOwnerDocument()->createElementNS(NULL,_SessionCache);
+ xmltooling::auto_ptr_XMLCh ssid(inmemID.c_str());
+ const_cast<DOMElement*>(child)->setAttributeNS(NULL,_StorageService,ssid.get());
+ m_outer->m_sessionCache=conf.SessionCacheManager.newPlugin(STORAGESERVICE_SESSION_CACHE,child);
}
- if (plugin) {
- ISessionCache* cache=dynamic_cast<ISessionCache*>(plugin);
- if (cache)
- m_outer->m_sessionCache=cache;
- else {
- delete plugin;
- log.fatal("plugin was not a Session Cache object");
- throw UnknownExtensionException("plugin was not a Session Cache object");
- }
+ else {
+ log.warn("custom SessionCache unspecified or no longer supported, building SessionCache of type %s...",REMOTED_SESSION_CACHE);
+ m_outer->m_sessionCache=conf.SessionCacheManager.newPlugin(REMOTED_SESSION_CACHE,NULL);
}
// Replay cache.
- // TODO: switch to new cache interface
- child=XMLHelper::getFirstChildElement(container,ReplayCache);
+ StorageService* replaySS=NULL;
+ child=XMLHelper::getFirstChildElement(container,_ReplayCache);
if (child) {
- xmltooling::auto_ptr_char type(child->getAttributeNS(NULL,_type));
- log.info("building ReplayCache of type %s...",type.get());
- m_outer->m_replayCache=IReplayCache::getInstance(type.get(),child);
+ xmltooling::auto_ptr_char ssid(child->getAttributeNS(NULL,_StorageService));
+ if (ssid.get() && *ssid.get()) {
+ replaySS = m_outer->m_storage[ssid.get()];
+ if (replaySS)
+ log.info("building ReplayCache on top of StorageService (%s)...", ssid.get());
+ else
+ log.crit("unable to locate StorageService (%s) in configuration", ssid.get());
+ }
}
- else {
- // OpenSAML default provider.
- log.info("custom ReplayCache unspecified or no longer supported, building default ReplayCache...");
- m_outer->m_replayCache=IReplayCache::getInstance();
+ if (!replaySS) {
+ log.info("building ReplayCache using in-memory StorageService...");
+ if (inmemID.empty()) {
+ inmemID = "memory";
+ log.info("no StorageServices configured, providing in-memory version for legacy config");
+ m_outer->m_storage[inmemID] = xmlConf.StorageServiceManager.newPlugin(MEMORY_STORAGE_SERVICE,NULL);
+ }
+ replaySS = m_outer->m_storage[inmemID];
}
+ xmlConf.setReplayCache(new ReplayCache(replaySS));
}
} // end of first-time-only stuff
xmltooling::auto_ptr_char type(child->getAttributeNS(NULL,_type));
log.info("building Attribute factory of type %s...",type.get());
try {
- plugin=shibConf.getPlugMgr().newPlugin(type.get(),child);
+ IPlugIn* plugin=shibConf.getPlugMgr().newPlugin(type.get(),child);
if (plugin) {
IAttributeFactory* fact=dynamic_cast<IAttributeFactory*>(plugin);
if (fact) {
m_attrFactories.push_back(fact);
ShibConfig::getConfig().regAttributeMapping(
- child->getAttributeNS(NULL,Attribute::ATTRIBUTENAME_ATTRIB_NAME), fact
+ child->getAttributeNS(NULL,opensaml::saml1::Attribute::ATTRIBUTENAME_ATTRIB_NAME), fact
);
}
else {