Move Shib constants to new lib, fixed symbol conflicts.
[shibboleth/cpp-sp.git] / shib-target / shib-ini.cpp
index 1c487cc..3e7244b 100644 (file)
 
 #include "internal.h"
 
+#include <shibsp/DOMPropertySet.h>
+#include <shibsp/SPConfig.h>
+#include <shibsp/SPConstants.h>
 #include <log4cpp/Category.hh>
 #include <log4cpp/PropertyConfigurator.hh>
 #include <algorithm>
 #include <sys/types.h>
 #include <sys/stat.h>
 
-using namespace std;
-using namespace saml;
-using namespace shibboleth;
+using namespace shibsp;
 using namespace shibtarget;
+using namespace shibboleth;
+using namespace saml;
 using namespace log4cpp;
+using namespace std;
+
+using xmltooling::TrustEngine;
+using opensaml::saml2md::MetadataProvider;
 
 namespace shibtarget {
 
     // Application configuration wrapper
-    class XMLApplication : public virtual IApplication, public XMLPropertySet, public DOMNodeFilter
+    class XMLApplication : public virtual IApplication, public DOMPropertySet, public DOMNodeFilter
     {
     public:
         XMLApplication(const IConfig*, const Iterator<ICredentials*>& creds, const DOMElement* e, const XMLApplication* base=NULL);
         ~XMLApplication() { cleanup(); }
     
-        // IPropertySet
+        // PropertySet
         pair<bool,bool> getBool(const char* name, const char* ns=NULL) const;
         pair<bool,const char*> getString(const char* name, const char* ns=NULL) const;
         pair<bool,const XMLCh*> getXMLString(const char* name, const char* ns=NULL) const;
         pair<bool,unsigned int> getUnsignedInt(const char* name, const char* ns=NULL) const;
         pair<bool,int> getInt(const char* name, const char* ns=NULL) const;
-        const IPropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const;
+        const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const;
 
         // IApplication
         const char* getId() const {return getString("id").second;}
@@ -59,7 +66,11 @@ namespace shibtarget {
         Iterator<IMetadata*> getMetadataProviders() const;
         Iterator<ITrust*> getTrustProviders() const;
         Iterator<const XMLCh*> getAudiences() const;
-        const IPropertySet* getCredentialUse(const IEntityDescriptor* provider) const;
+        const PropertySet* getCredentialUse(const IEntityDescriptor* provider) const;
+
+        const MetadataProvider* getMetadataProvider() const;
+        const TrustEngine* getTrustEngine() const;
+        
         const SAMLBrowserProfile* getBrowserProfile() const {return m_profile;}
         const SAMLBinding* getBinding(const XMLCh* binding) const
             {return XMLString::compareString(SAMLBinding::SOAP,binding) ? NULL : m_binding;}
@@ -89,6 +100,8 @@ namespace shibtarget {
         vector<IAAP*> m_aaps;
         vector<IMetadata*> m_metadatas;
         vector<ITrust*> m_trusts;
+        MetadataProvider* m_metadata;
+        TrustEngine* m_trust;
         vector<const XMLCh*> m_audiences;
         ShibBrowserProfile* m_profile;
         SAMLBinding* m_binding;
@@ -96,7 +109,7 @@ namespace shibtarget {
 
         // vectors manage object life for handlers and their property sets
         vector<IHandler*> m_handlers;
-        vector<XMLPropertySet*> m_handlerProps;
+        vector<PropertySet*> m_handlerProps;
 
         // maps location (path info) to applicable handlers
         map<string,const IHandler*> m_handlerMap;
@@ -121,17 +134,17 @@ namespace shibtarget {
         // pointer to default session initiator
         const IHandler* m_sessionInitDefault;
 
-        XMLPropertySet* m_credDefault;
+        DOMPropertySet* m_credDefault;
 #ifdef HAVE_GOOD_STL
-        map<xstring,XMLPropertySet*> m_credMap;
+        map<xstring,PropertySet*> m_credMap;
 #else
-        map<const XMLCh*,XMLPropertySet*> m_credMap;
+        map<const XMLCh*,PropertySet*> m_credMap;
 #endif
     };
 
     // Top-level configuration implementation
     class XMLConfig;
-    class XMLConfigImpl : public ReloadableXMLFileImpl, public XMLPropertySet, public DOMNodeFilter
+    class XMLConfigImpl : public ReloadableXMLFileImpl, public DOMPropertySet, public DOMNodeFilter
     {
     public:
         XMLConfigImpl(const char* pathname, bool first, const XMLConfig* outer)
@@ -170,17 +183,17 @@ namespace shibtarget {
 
         void init() { getImplementation(); }
 
-        // IPropertySet
+        // PropertySet
         pair<bool,bool> getBool(const char* name, const char* ns=NULL) const {return static_cast<XMLConfigImpl*>(m_impl)->getBool(name,ns);}
         pair<bool,const char*> getString(const char* name, const char* ns=NULL) const {return static_cast<XMLConfigImpl*>(m_impl)->getString(name,ns);}
         pair<bool,const XMLCh*> getXMLString(const char* name, const char* ns=NULL) const {return static_cast<XMLConfigImpl*>(m_impl)->getXMLString(name,ns);}
         pair<bool,unsigned int> getUnsignedInt(const char* name, const char* ns=NULL) const {return static_cast<XMLConfigImpl*>(m_impl)->getUnsignedInt(name,ns);}
         pair<bool,int> getInt(const char* name, const char* ns=NULL) const {return static_cast<XMLConfigImpl*>(m_impl)->getInt(name,ns);}
-        const IPropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const {return static_cast<XMLConfigImpl*>(m_impl)->getPropertySet(name,ns);}
+        const PropertySet* getPropertySet(const char* name, const char* ns="urn:mace:shibboleth:target:config:1.0") const {return static_cast<XMLConfigImpl*>(m_impl)->getPropertySet(name,ns);}
         const DOMElement* getElement() const {return static_cast<XMLConfigImpl*>(m_impl)->getElement();}
 
         // IConfig
-        IListener* getListener() const {return m_listener;}
+        ListenerService* getListener() const {return m_listener;}
         ISessionCache* getSessionCache() const {return m_sessionCache;}
         IReplayCache* getReplayCache() const {return m_replayCache;}
         IRequestMapper* getRequestMapper() const {return static_cast<XMLConfigImpl*>(m_impl)->m_requestMapper;}
@@ -196,7 +209,7 @@ namespace shibtarget {
 
     private:
         friend class XMLConfigImpl;
-        mutable IListener* m_listener;
+        mutable ListenerService* m_listener;
         mutable ISessionCache* m_sessionCache;
         mutable IReplayCache* m_replayCache;
     };
@@ -207,196 +220,16 @@ IConfig* STConfig::ShibTargetConfigFactory(const DOMElement* e)
     return new XMLConfig(e);
 }
 
-XMLPropertySet::~XMLPropertySet()
-{
-    for (map<string,pair<char*,const XMLCh*> >::iterator i=m_map.begin(); i!=m_map.end(); i++)
-        XMLString::release(&(i->second.first));
-    for_each(m_nested.begin(),m_nested.end(),shibtarget::cleanup_pair<string,IPropertySet>());
-}
-
-void XMLPropertySet::load(
-    const DOMElement* e,
-    Category& log,
-    DOMNodeFilter* filter,
-    const std::map<std::string,std::string>* remapper
-    )
-{
-#ifdef _DEBUG
-    saml::NDC ndc("load");
-#endif
-    m_root=e;
-
-    // Process each attribute as a property.
-    DOMNamedNodeMap* attrs=m_root->getAttributes();
-    for (XMLSize_t i=0; i<attrs->getLength(); i++) {
-        DOMNode* a=attrs->item(i);
-        if (!XMLString::compareString(a->getNamespaceURI(),saml::XML::XMLNS_NS))
-            continue;
-        char* val=XMLString::transcode(a->getNodeValue());
-        if (val && *val) {
-            auto_ptr_char ns(a->getNamespaceURI());
-            auto_ptr_char name(a->getLocalName());
-            const char* realname=name.get();
-            if (remapper) {
-                map<string,string>::const_iterator remap=remapper->find(realname);
-                if (remap!=remapper->end()) {
-                    log.warn("remapping property (%s) to (%s)",realname,remap->second.c_str());
-                    realname=remap->second.c_str();
-                }
-            }
-            if (ns.get()) {
-                m_map[string("{") + ns.get() + '}' + realname]=pair<char*,const XMLCh*>(val,a->getNodeValue());
-                log.debug("added property {%s}%s (%s)",ns.get(),realname,val);
-            }
-            else {
-                m_map[realname]=pair<char*,const XMLCh*>(val,a->getNodeValue());
-                log.debug("added property %s (%s)",realname,val);
-            }
-        }
-    }
-    
-    // Process non-excluded elements as nested sets.
-    DOMTreeWalker* walker=
-        static_cast<DOMDocumentTraversal*>(
-            m_root->getOwnerDocument())->createTreeWalker(const_cast<DOMElement*>(m_root),DOMNodeFilter::SHOW_ELEMENT,filter,false
-            );
-    e=static_cast<DOMElement*>(walker->firstChild());
-    while (e) {
-        auto_ptr_char ns(e->getNamespaceURI());
-        auto_ptr_char name(e->getLocalName());
-        const char* realname=name.get();
-        if (remapper) {
-            map<string,string>::const_iterator remap=remapper->find(realname);
-            if (remap!=remapper->end()) {
-                log.warn("remapping property set (%s) to (%s)",realname,remap->second.c_str());
-                realname=remap->second.c_str();
-            }
-        }
-        string key;
-        if (ns.get())
-            key=string("{") + ns.get() + '}' + realname;
-        else
-            key=realname;
-        if (m_nested.find(key)!=m_nested.end())
-            log.warn("load() skipping duplicate property set: %s",key.c_str());
-        else {
-            XMLPropertySet* set=new XMLPropertySet();
-            set->load(e,log,filter,remapper);
-            m_nested[key]=set;
-            log.debug("added nested property set: %s",key.c_str());
-        }
-        e=static_cast<DOMElement*>(walker->nextSibling());
-    }
-    walker->release();
-}
-
-pair<bool,bool> XMLPropertySet::getBool(const char* name, const char* ns) const
-{
-    pair<bool,bool> ret(false,false);
-    map<string,pair<char*,const XMLCh*> >::const_iterator i;
-
-    if (ns)
-        i=m_map.find(string("{") + ns + '}' + name);
-    else
-        i=m_map.find(name);
-
-    if (i!=m_map.end()) {
-        ret.first=true;
-        ret.second=(!strcmp(i->second.first,"true") || !strcmp(i->second.first,"1"));
-    }
-    return ret;
-}
-
-pair<bool,const char*> XMLPropertySet::getString(const char* name, const char* ns) const
-{
-    pair<bool,const char*> ret(false,NULL);
-    map<string,pair<char*,const XMLCh*> >::const_iterator i;
-
-    if (ns)
-        i=m_map.find(string("{") + ns + '}' + name);
-    else
-        i=m_map.find(name);
-
-    if (i!=m_map.end()) {
-        ret.first=true;
-        ret.second=i->second.first;
-    }
-    return ret;
-}
-
-pair<bool,const XMLCh*> XMLPropertySet::getXMLString(const char* name, const char* ns) const
-{
-    pair<bool,const XMLCh*> ret(false,NULL);
-    map<string,pair<char*,const XMLCh*> >::const_iterator i;
-
-    if (ns)
-        i=m_map.find(string("{") + ns + '}' + name);
-    else
-        i=m_map.find(name);
-
-    if (i!=m_map.end()) {
-        ret.first=true;
-        ret.second=i->second.second;
-    }
-    return ret;
-}
-
-pair<bool,unsigned int> XMLPropertySet::getUnsignedInt(const char* name, const char* ns) const
-{
-    pair<bool,unsigned int> ret(false,0);
-    map<string,pair<char*,const XMLCh*> >::const_iterator i;
-
-    if (ns)
-        i=m_map.find(string("{") + ns + '}' + name);
-    else
-        i=m_map.find(name);
-
-    if (i!=m_map.end()) {
-        ret.first=true;
-        ret.second=strtol(i->second.first,NULL,10);
-    }
-    return ret;
-}
-
-pair<bool,int> XMLPropertySet::getInt(const char* name, const char* ns) const
-{
-    pair<bool,int> ret(false,0);
-    map<string,pair<char*,const XMLCh*> >::const_iterator i;
-
-    if (ns)
-        i=m_map.find(string("{") + ns + '}' + name);
-    else
-        i=m_map.find(name);
-
-    if (i!=m_map.end()) {
-        ret.first=true;
-        ret.second=atoi(i->second.first);
-    }
-    return ret;
-}
-
-const IPropertySet* XMLPropertySet::getPropertySet(const char* name, const char* ns) const
-{
-    map<string,IPropertySet*>::const_iterator i;
-
-    if (ns)
-        i=m_nested.find(string("{") + ns + '}' + name);
-    else
-        i=m_nested.find(name);
-
-    return (i!=m_nested.end()) ? i->second : NULL;
-}
-
 XMLApplication::XMLApplication(
     const IConfig* ini,
     const Iterator<ICredentials*>& creds,
     const DOMElement* e,
     const XMLApplication* base
-    ) : m_ini(ini), m_base(base), m_profile(NULL), m_binding(NULL), m_bindingHook(NULL),
+    ) : m_ini(ini), 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
-    saml::NDC ndc("XMLApplication");
+    NDC ndc("XMLApplication");
 #endif
     Category& log=Category::getInstance("shibtarget.XMLApplication");
 
@@ -407,7 +240,7 @@ XMLApplication::XMLApplication(
         root_remap["shireURL"]="handlerURL";
         root_remap["shireSSL"]="handlerSSL";
         load(e,log,this,&root_remap);
-        const IPropertySet* propcheck=getPropertySet("Errors");
+        const PropertySet* propcheck=getPropertySet("Errors");
         if (propcheck && !propcheck->getString("session").first)
             throw ConfigurationException("<Errors> element requires 'session' (or deprecated 'shire') attribute");
         propcheck=getPropertySet("Sessions");
@@ -418,7 +251,7 @@ XMLApplication::XMLApplication(
         m_hash+=getString("providerId").second;
         m_hash=SAMLArtifact::toHex(SAMLArtifactType0001::generateSourceId(m_hash.c_str()));
 
-        ShibTargetConfig& conf=ShibTargetConfig::getConfig();
+        SPConfig& conf=SPConfig::getConfig();
         SAMLConfig& shibConf=SAMLConfig::getConfig();
 
         // Process handlers.
@@ -428,7 +261,7 @@ XMLApplication::XMLApplication(
             // A handler is split across a property set and the plugin itself, which is based on the Binding property.
             // We build both objects first and then insert them into various structures for lookup.
             IHandler* hobj=NULL;
-            XMLPropertySet* hprops=new XMLPropertySet();
+            DOMPropertySet* hprops=new DOMPropertySet();
             try {
                 hprops->load(handler,log,this); // filter irrelevant for now, no embedded elements expected
                 const char* bindprop=hprops->getString("Binding").second;
@@ -517,9 +350,9 @@ XMLApplication::XMLApplication(
         // If no handlers defined at the root, assume a legacy configuration.
         if (!m_base && m_handlers.empty()) {
             // A legacy config installs a SAML POST handler at the root handler location.
-            // We use the Sessions element itself as the IPropertySet.
+            // We use the Sessions element itself as the PropertySet.
 
-            auto_ptr_char b1(Constants::SHIB_SESSIONINIT_PROFILE_URI);
+            auto_ptr_char b1(shibspconstants::SHIB1_SESSIONINIT_PROFILE_URI);
             IPlugIn* hplug=shibConf.getPlugMgr().newPlugin(b1.get(),propcheck->getElement());
             IHandler* h1=dynamic_cast<IHandler*>(hplug);
             if (!h1) {
@@ -562,7 +395,7 @@ XMLApplication::XMLApplication(
         // Always include our own providerId as an audience.
         m_audiences.push_back(getXMLString("providerId").second);
 
-        if (conf.isEnabled(ShibTargetConfig::AAP)) {
+        if (conf.isEnabled(SPConfig::AAP)) {
             nlist=e->getElementsByTagNameNS(shibtarget::XML::SHIBTARGET_NS,SHIBT_L(AAPProvider));
             for (i=0; nlist && i<nlist->getLength(); i++) {
                 if (nlist->item(i)->getParentNode()->isSameNode(e)) {
@@ -585,7 +418,7 @@ XMLApplication::XMLApplication(
             }
         }
 
-        if (conf.isEnabled(ShibTargetConfig::Metadata)) {
+        if (conf.isEnabled(SPConfig::Metadata)) {
             nlist=e->getElementsByTagNameNS(shibtarget::XML::SHIBTARGET_NS,SHIBT_L(MetadataProvider));
             for (i=0; nlist && i<nlist->getLength(); i++) {
                 if (nlist->item(i)->getParentNode()->isSameNode(e)) {
@@ -628,7 +461,9 @@ XMLApplication::XMLApplication(
             }
         }
 
-        if (conf.isEnabled(ShibTargetConfig::Trust)) {
+        if (conf.isEnabled(SPConfig::Trust)) {
+            // First build the old plugins.
+            // TODO: remove this later
             nlist=e->getElementsByTagNameNS(shibtarget::XML::SHIBTARGET_NS,SHIBT_L(TrustProvider));
             for (i=0; nlist && i<nlist->getLength(); i++) {
                 if (nlist->item(i)->getParentNode()->isSameNode(e)) {
@@ -654,18 +489,18 @@ XMLApplication::XMLApplication(
         // Finally, load credential mappings.
         const DOMElement* cu=saml::XML::getFirstChildElement(e,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(CredentialUse));
         if (cu) {
-            m_credDefault=new XMLPropertySet();
+            m_credDefault=new DOMPropertySet();
             m_credDefault->load(cu,log,this);
             cu=saml::XML::getFirstChildElement(cu,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(RelyingParty));
             while (cu) {
-                XMLPropertySet* rp=new XMLPropertySet();
+                DOMPropertySet* rp=new DOMPropertySet();
                 rp->load(cu,log,this);
                 m_credMap[cu->getAttributeNS(NULL,SHIBT_L(Name))]=rp;
                 cu=saml::XML::getNextSiblingElement(cu,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(RelyingParty));
             }
         }
         
-        if (conf.isEnabled(ShibTargetConfig::OutOfProcess)) {
+        if (conf.isEnabled(SPConfig::OutOfProcess)) {
             // Really finally, build local browser profile and binding objects.
             m_profile=new ShibBrowserProfile(
                 this,
@@ -704,18 +539,18 @@ void XMLApplication::cleanup()
     delete m_bindingHook;
     delete m_binding;
     delete m_profile;
-    for_each(m_handlers.begin(),m_handlers.end(),shibtarget::cleanup<IHandler>());
+    for_each(m_handlers.begin(),m_handlers.end(),xmltooling::cleanup<IHandler>());
         
     delete m_credDefault;
 #ifdef HAVE_GOOD_STL
-    for_each(m_credMap.begin(),m_credMap.end(),shibtarget::cleanup_pair<xstring,XMLPropertySet>());
+    for_each(m_credMap.begin(),m_credMap.end(),xmltooling::cleanup_pair<xstring,PropertySet>());
 #else
-    for_each(m_credMap.begin(),m_credMap.end(),shibtarget::cleanup_pair<const XMLCh*,XMLPropertySet>());
+    for_each(m_credMap.begin(),m_credMap.end(),xmltooling::cleanup_pair<const XMLCh*,PropertySet>());
 #endif
-    for_each(m_designators.begin(),m_designators.end(),shibtarget::cleanup<SAMLAttributeDesignator>());
-    for_each(m_aaps.begin(),m_aaps.end(),shibtarget::cleanup<IAAP>());
-    for_each(m_metadatas.begin(),m_metadatas.end(),shibtarget::cleanup<IMetadata>());
-    for_each(m_trusts.begin(),m_trusts.end(),shibtarget::cleanup<ITrust>());
+    for_each(m_designators.begin(),m_designators.end(),xmltooling::cleanup<SAMLAttributeDesignator>());
+    for_each(m_aaps.begin(),m_aaps.end(),xmltooling::cleanup<IAAP>());
+    for_each(m_metadatas.begin(),m_metadatas.end(),xmltooling::cleanup<IMetadata>());
+    for_each(m_trusts.begin(),m_trusts.end(),xmltooling::cleanup<ITrust>());
 }
 
 short XMLApplication::acceptNode(const DOMNode* node) const
@@ -743,7 +578,7 @@ short XMLApplication::acceptNode(const DOMNode* node) const
 
 pair<bool,bool> XMLApplication::getBool(const char* name, const char* ns) const
 {
-    pair<bool,bool> ret=XMLPropertySet::getBool(name,ns);
+    pair<bool,bool> ret=DOMPropertySet::getBool(name,ns);
     if (ret.first)
         return ret;
     return m_base ? m_base->getBool(name,ns) : ret;
@@ -751,7 +586,7 @@ pair<bool,bool> XMLApplication::getBool(const char* name, const char* ns) const
 
 pair<bool,const char*> XMLApplication::getString(const char* name, const char* ns) const
 {
-    pair<bool,const char*> ret=XMLPropertySet::getString(name,ns);
+    pair<bool,const char*> ret=DOMPropertySet::getString(name,ns);
     if (ret.first)
         return ret;
     return m_base ? m_base->getString(name,ns) : ret;
@@ -759,7 +594,7 @@ pair<bool,const char*> XMLApplication::getString(const char* name, const char* n
 
 pair<bool,const XMLCh*> XMLApplication::getXMLString(const char* name, const char* ns) const
 {
-    pair<bool,const XMLCh*> ret=XMLPropertySet::getXMLString(name,ns);
+    pair<bool,const XMLCh*> ret=DOMPropertySet::getXMLString(name,ns);
     if (ret.first)
         return ret;
     return m_base ? m_base->getXMLString(name,ns) : ret;
@@ -767,7 +602,7 @@ pair<bool,const XMLCh*> XMLApplication::getXMLString(const char* name, const cha
 
 pair<bool,unsigned int> XMLApplication::getUnsignedInt(const char* name, const char* ns) const
 {
-    pair<bool,unsigned int> ret=XMLPropertySet::getUnsignedInt(name,ns);
+    pair<bool,unsigned int> ret=DOMPropertySet::getUnsignedInt(name,ns);
     if (ret.first)
         return ret;
     return m_base ? m_base->getUnsignedInt(name,ns) : ret;
@@ -775,15 +610,15 @@ pair<bool,unsigned int> XMLApplication::getUnsignedInt(const char* name, const c
 
 pair<bool,int> XMLApplication::getInt(const char* name, const char* ns) const
 {
-    pair<bool,int> ret=XMLPropertySet::getInt(name,ns);
+    pair<bool,int> ret=DOMPropertySet::getInt(name,ns);
     if (ret.first)
         return ret;
     return m_base ? m_base->getInt(name,ns) : ret;
 }
 
-const IPropertySet* XMLApplication::getPropertySet(const char* name, const char* ns) const
+const PropertySet* XMLApplication::getPropertySet(const char* name, const char* ns) const
 {
-    const IPropertySet* ret=XMLPropertySet::getPropertySet(name,ns);
+    const PropertySet* ret=DOMPropertySet::getPropertySet(name,ns);
     if (ret || !m_base)
         return ret;
     return m_base->getPropertySet(name,ns);
@@ -816,13 +651,13 @@ Iterator<const XMLCh*> XMLApplication::getAudiences() const
     return (m_audiences.empty() && m_base) ? m_base->getAudiences() : m_audiences;
 }
 
-const IPropertySet* XMLApplication::getCredentialUse(const IEntityDescriptor* provider) const
+const PropertySet* XMLApplication::getCredentialUse(const IEntityDescriptor* provider) const
 {
     if (!m_credDefault && m_base)
         return m_base->getCredentialUse(provider);
         
 #ifdef HAVE_GOOD_STL
-    map<xstring,XMLPropertySet*>::const_iterator i=m_credMap.find(provider->getId());
+    map<xstring,PropertySet*>::const_iterator i=m_credMap.find(provider->getId());
     if (i!=m_credMap.end())
         return i->second;
     const IEntitiesDescriptor* group=provider->getEntitiesDescriptor();
@@ -835,7 +670,7 @@ const IPropertySet* XMLApplication::getCredentialUse(const IEntityDescriptor* pr
         group=group->getEntitiesDescriptor();
     }
 #else
-    map<const XMLCh*,XMLPropertySet*>::const_iterator i=m_credMap.begin();
+    map<const XMLCh*,PropertySet*>::const_iterator i=m_credMap.begin();
     for (; i!=m_credMap.end(); i++) {
         if (!XMLString::compareString(i->first,provider->getId()))
             return i->second;
@@ -850,6 +685,16 @@ const IPropertySet* XMLApplication::getCredentialUse(const IEntityDescriptor* pr
     return m_credDefault;
 }
 
+const MetadataProvider* XMLApplication::getMetadataProvider() const
+{
+    return (!m_metadata && m_base) ? m_base->getMetadataProvider() : m_metadata;
+}
+
+const TrustEngine* XMLApplication::getTrustEngine() const
+{
+    return (!m_trust && m_base) ? m_base->getTrustEngine() : m_trust;
+}
+
 void XMLApplication::validateToken(SAMLAssertion* token, time_t ts, const IRoleDescriptor* role, const Iterator<ITrust*>& trusts) const
 {
 #ifdef _DEBUG
@@ -892,7 +737,7 @@ void XMLApplication::validateToken(SAMLAssertion* token, time_t ts, const IRoleD
         return;
     }
 
-    const IPropertySet* credUse=getCredentialUse(role->getEntityDescriptor());
+    const PropertySet* credUse=getCredentialUse(role->getEntityDescriptor());
     pair<bool,bool> signedAssertions=credUse ? credUse->getBool("signedAssertions") : make_pair(false,false);
     Trust t(trusts);
 
@@ -1000,7 +845,7 @@ void XMLConfigImpl::init(bool first)
         }
 
         SAMLConfig& shibConf=SAMLConfig::getConfig();
-        ShibTargetConfig& conf=ShibTargetConfig::getConfig();
+        SPConfig& conf=SPConfig::getConfig();
         const DOMElement* SHAR=saml::XML::getFirstChildElement(ReloadableXMLFileImpl::m_root,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(SHAR));
         if (!SHAR)
             SHAR=saml::XML::getFirstChildElement(ReloadableXMLFileImpl::m_root,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Global));
@@ -1013,11 +858,11 @@ void XMLConfigImpl::init(bool first)
             SHIRE=saml::XML::getFirstChildElement(ReloadableXMLFileImpl::m_root,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(InProcess));
 
         // Initialize log4cpp manually in order to redirect log messages as soon as possible.
-        if (conf.isEnabled(ShibTargetConfig::Logging)) {
+        if (conf.isEnabled(SPConfig::Logging)) {
             const XMLCh* logger=NULL;
-            if (conf.isEnabled(ShibTargetConfig::OutOfProcess))
+            if (conf.isEnabled(SPConfig::OutOfProcess))
                 logger=SHAR->getAttributeNS(NULL,SHIBT_L(logger));
-            else if (conf.isEnabled(ShibTargetConfig::InProcess))
+            else if (conf.isEnabled(SPConfig::InProcess))
                 logger=SHIRE->getAttributeNS(NULL,SHIBT_L(logger));
             if (!logger || !*logger)
                 logger=ReloadableXMLFileImpl::m_root->getAttributeNS(NULL,SHIBT_L(logger));
@@ -1067,7 +912,7 @@ void XMLConfigImpl::init(bool first)
                 }
             }
             
-            if (conf.isEnabled(ShibTargetConfig::OutOfProcess)) {
+            if (conf.isEnabled(SPConfig::OutOfProcess)) {
                 exts=saml::XML::getFirstChildElement(SHAR,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Extensions));
                 if (exts) {
                     exts=saml::XML::getFirstChildElement(exts,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Library));
@@ -1091,7 +936,7 @@ void XMLConfigImpl::init(bool first)
                 }
             }
 
-            if (conf.isEnabled(ShibTargetConfig::InProcess)) {
+            if (conf.isEnabled(SPConfig::InProcess)) {
                 exts=saml::XML::getFirstChildElement(SHIRE,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Extensions));
                 if (exts) {
                     exts=saml::XML::getFirstChildElement(exts,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Library));
@@ -1115,26 +960,25 @@ void XMLConfigImpl::init(bool first)
                 }
             }
             
-            // Instantiate the Listener and SessionCache objects.
-            if (conf.isEnabled(ShibTargetConfig::Listener)) {
-                IPlugIn* plugin=NULL;
+            // Instantiate the ListenerService and SessionCache objects.
+            if (conf.isEnabled(SPConfig::Listener)) {
                 exts=saml::XML::getFirstChildElement(SHAR,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(UnixListener));
                 if (exts) {
-                    log.info("building Listener of type %s...",shibtarget::XML::UnixListenerType);
-                    plugin=shibConf.getPlugMgr().newPlugin(shibtarget::XML::UnixListenerType,exts);
+                    log.info("building Listener of type %s...",UNIX_LISTENER_SERVICE);
+                    m_outer->m_listener=conf.ListenerServiceManager.newPlugin(UNIX_LISTENER_SERVICE,exts);
                 }
                 else {
                     exts=saml::XML::getFirstChildElement(SHAR,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(TCPListener));
                     if (exts) {
-                        log.info("building Listener of type %s...",shibtarget::XML::TCPListenerType);
-                        plugin=shibConf.getPlugMgr().newPlugin(shibtarget::XML::TCPListenerType,exts);
+                        log.info("building Listener of type %s...",TCP_LISTENER_SERVICE);
+                        m_outer->m_listener=conf.ListenerServiceManager.newPlugin(TCP_LISTENER_SERVICE,exts);
                     }
                     else {
                         exts=saml::XML::getFirstChildElement(SHAR,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(Listener));
                         if (exts) {
                             auto_ptr_char type(exts->getAttributeNS(NULL,SHIBT_L(type)));
                             log.info("building Listener of type %s...",type.get());
-                            plugin=shibConf.getPlugMgr().newPlugin(type.get(),exts);
+                            m_outer->m_listener=conf.ListenerServiceManager.newPlugin(type.get(),exts);
                         }
                         else {
                             log.fatal("can't build Listener object, missing conf:Listener element?");
@@ -1142,21 +986,11 @@ void XMLConfigImpl::init(bool first)
                         }
                     }
                 }
-                if (plugin) {
-                    IListener* listen=dynamic_cast<IListener*>(plugin);
-                    if (listen)
-                        m_outer->m_listener=listen;
-                    else {
-                        delete plugin;
-                        log.fatal("plugin was not a Listener object");
-                        throw UnsupportedExtensionException("plugin was not a Listener object");
-                    }
-                }
             }
 
-            if (conf.isEnabled(ShibTargetConfig::Caching)) {
+            if (conf.isEnabled(SPConfig::Caching)) {
                 IPlugIn* plugin=NULL;
-                const DOMElement* container=conf.isEnabled(ShibTargetConfig::OutOfProcess) ? SHAR : SHIRE;
+                const DOMElement* container=conf.isEnabled(SPConfig::OutOfProcess) ? SHAR : SHIRE;
                 exts=saml::XML::getFirstChildElement(container,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(MemorySessionCache));
                 if (exts) {
                     log.info("building Session Cache of type %s...",shibtarget::XML::MemorySessionCacheType);
@@ -1200,7 +1034,7 @@ void XMLConfigImpl::init(bool first)
                 }
                 
                 // Replay cache.
-                container=conf.isEnabled(ShibTargetConfig::OutOfProcess) ? SHAR : SHIRE;
+                container=conf.isEnabled(SPConfig::OutOfProcess) ? SHAR : SHIRE;
                 exts=saml::XML::getFirstChildElement(container,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(ODBCReplayCache));
                 if (exts) {
                     log.info("building Replay Cache of type %s...",shibtarget::XML::ODBCReplayCacheType);
@@ -1230,7 +1064,7 @@ void XMLConfigImpl::init(bool first)
         }
         
         // Back to the fully dynamic stuff...next up is the Request Mapper.
-        if (conf.isEnabled(ShibTargetConfig::RequestMapper)) {
+        if (conf.isEnabled(SPConfig::RequestMapper)) {
             const DOMElement* child=saml::XML::getFirstChildElement(SHIRE,shibtarget::XML::SHIBTARGET_NS,SHIBT_L(RequestMapProvider));
             if (child) {
                 auto_ptr_char type(child->getAttributeNS(NULL,SHIBT_L(type)));
@@ -1255,7 +1089,7 @@ void XMLConfigImpl::init(bool first)
         
         // Now we load any credentials providers.
         DOMNodeList* nlist;
-        if (conf.isEnabled(ShibTargetConfig::Credentials)) {
+        if (conf.isEnabled(SPConfig::Credentials)) {
             nlist=ReloadableXMLFileImpl::m_root->getElementsByTagNameNS(shibtarget::XML::SHIBTARGET_NS,SHIBT_L(CredentialsProvider));
             for (unsigned int i=0; nlist && i<nlist->getLength(); i++) {
                 auto_ptr_char type(static_cast<DOMElement*>(nlist->item(i))->getAttributeNS(NULL,SHIBT_L(type)));
@@ -1326,6 +1160,10 @@ void XMLConfigImpl::init(bool first)
                 m_appmap[iapp->getId()]=iapp.release();
         }
     }
+    catch (xmltooling::XMLToolingException& e) {
+        log.errorStream() << "Error while loading SP configuration: " << e.what() << CategoryStream::ENDLINE;
+        throw ConfigurationException(e.what());
+    }
     catch (SAMLException& e) {
         log.errorStream() << "Error while loading SP configuration: " << e.what() << CategoryStream::ENDLINE;
         throw ConfigurationException(e.what());
@@ -1341,8 +1179,8 @@ void XMLConfigImpl::init(bool first)
 XMLConfigImpl::~XMLConfigImpl()
 {
     delete m_requestMapper;
-    for_each(m_appmap.begin(),m_appmap.end(),cleanup_pair<string,IApplication>());
-    for_each(m_creds.begin(),m_creds.end(),cleanup<ICredentials>());
+    for_each(m_appmap.begin(),m_appmap.end(),xmltooling::cleanup_pair<string,IApplication>());
+    for_each(m_creds.begin(),m_creds.end(),xmltooling::cleanup<ICredentials>());
     ShibConfig::getConfig().clearAttributeMappings();
-    for_each(m_attrFactories.begin(),m_attrFactories.end(),cleanup<IAttributeFactory>());
+    for_each(m_attrFactories.begin(),m_attrFactories.end(),xmltooling::cleanup<IAttributeFactory>());
 }