Correct location of TransportOption feature, makes no sense inside policies.
[shibboleth/sp.git] / shibsp / impl / XMLServiceProvider.cpp
index 4f790ec..eeb3f38 100644 (file)
@@ -95,11 +95,10 @@ namespace {
         SAML2Artifact* generateSAML2Artifact(const EntityDescriptor* relyingParty) const {
             pair<bool,int> index = make_pair(false,0);
             const PropertySet* props = getRelyingParty(relyingParty);
-            if (props)
-                index = getInt("artifactEndpointIndex");
+            index = props->getInt("artifactEndpointIndex");
             if (!index.first)
                 index = getArtifactEndpointIndex();
-            return new SAML2ArtifactType0004(SAMLConfig::getConfig().hashSHA1(getString("entityID").second),index.first ? index.second : 1);
+            return new SAML2ArtifactType0004(SAMLConfig::getConfig().hashSHA1(props->getString("entityID").second),index.first ? index.second : 1);
         }
 
         MetadataProvider* getMetadataProvider(bool required=true) const {
@@ -125,8 +124,8 @@ namespace {
             return (!m_credResolver && m_base) ? m_base->getCredentialResolver() : m_credResolver;
         }
         const PropertySet* getRelyingParty(const EntityDescriptor* provider) const;
-        const vector<const XMLCh*>& getAudiences() const {
-            return (m_audiences.empty() && m_base) ? m_base->getAudiences() : m_audiences;
+        const vector<const XMLCh*>* getAudiences() const {
+            return (m_audiences.empty() && m_base) ? m_base->getAudiences() : &m_audiences;
         }
 #endif
         string getNotificationURL(const char* resource, bool front, unsigned int index) const;
@@ -172,7 +171,6 @@ namespace {
         vector<const XMLCh*> m_audiences;
 
         // RelyingParty properties
-        DOMPropertySet* m_partyDefault;
 #ifdef HAVE_GOOD_STL
         map<xstring,PropertySet*> m_partyMap;
 #else
@@ -228,7 +226,7 @@ namespace {
         map<string,Application*> m_appmap;
 #ifndef SHIBSP_LITE
         map< string,pair< PropertySet*,vector<const SecurityPolicyRule*> > > m_policyMap;
-        map< string, vector< pair< string, pair<string,string> > > > m_transportOptionMap;
+        vector< pair< string, pair<string,string> > > m_transportOptions;
 #endif
         
         // Provides filter to exclude special config elements.
@@ -347,14 +345,10 @@ namespace {
             throw ConfigurationException("Security Policy ($1) not found, check <SecurityPolicies> element.", params(1,id));
         }
 
-        bool setTransportOptions(const char* id, SOAPTransport& transport) const {
+        bool setTransportOptions(SOAPTransport& transport) const {
             bool ret = true;
-            map< string, vector< pair< string, pair<string,string> > > >::const_iterator p =
-                m_impl->m_transportOptionMap.find(id);
-            if (p == m_impl->m_transportOptionMap.end())
-                return ret;
             vector< pair< string, pair<string,string> > >::const_iterator opt;
-            for (opt = p->second.begin(); opt != p->second.end(); ++opt) {
+            for (opt = m_impl->m_transportOptions.begin(); opt != m_impl->m_transportOptions.end(); ++opt) {
                 if (!transport.setProviderOption(opt->first.c_str(), opt->second.first.c_str(), opt->second.second.c_str())) {
                     m_log.error("failed to set SOAPTransport option (%s)", opt->second.first.c_str());
                     ret = false;
@@ -382,8 +376,8 @@ namespace {
     #pragma warning( pop )
 #endif
 
-    static const XMLCh _Application[] =         UNICODE_LITERAL_11(A,p,p,l,i,c,a,t,i,o,n);
-    static const XMLCh Applications[] =         UNICODE_LITERAL_12(A,p,p,l,i,c,a,t,i,o,n,s);
+    static const XMLCh ApplicationOverride[] =  UNICODE_LITERAL_19(A,p,p,l,i,c,a,t,i,o,n,O,v,e,r,r,i,d,e);
+    static const XMLCh ApplicationDefaults[] =  UNICODE_LITERAL_19(A,p,p,l,i,c,a,t,i,o,n,D,e,f,a,u,l,t,s);
     static const XMLCh _ArtifactMap[] =         UNICODE_LITERAL_11(A,r,t,i,f,a,c,t,M,a,p);
     static const XMLCh _AttributeExtractor[] =  UNICODE_LITERAL_18(A,t,t,r,i,b,u,t,e,E,x,t,r,a,c,t,o,r);
     static const XMLCh _AttributeFilter[] =     UNICODE_LITERAL_15(A,t,t,r,i,b,u,t,e,F,i,l,t,e,r);
@@ -394,7 +388,6 @@ namespace {
     static const XMLCh Binding[] =              UNICODE_LITERAL_7(B,i,n,d,i,n,g);
     static const XMLCh Channel[]=               UNICODE_LITERAL_7(C,h,a,n,n,e,l);
     static const XMLCh _CredentialResolver[] =  UNICODE_LITERAL_18(C,r,e,d,e,n,t,i,a,l,R,e,s,o,l,v,e,r);
-    static const XMLCh DefaultRelyingParty[] =  UNICODE_LITERAL_19(D,e,f,a,u,l,t,R,e,l,y,i,n,g,P,a,r,t,y);
     static const XMLCh _Extensions[] =          UNICODE_LITERAL_10(E,x,t,e,n,s,i,o,n,s);
     static const XMLCh _fatal[] =               UNICODE_LITERAL_5(f,a,t,a,l);
     static const XMLCh _Handler[] =             UNICODE_LITERAL_7(H,a,n,d,l,e,r);
@@ -455,7 +448,7 @@ XMLApplication::XMLApplication(
 #ifndef SHIBSP_LITE
         m_metadata(NULL), m_trust(NULL),
         m_attrExtractor(NULL), m_attrFilter(NULL), m_attrResolver(NULL),
-        m_credResolver(NULL), m_partyDefault(NULL),
+        m_credResolver(NULL),
 #endif
         m_acsDefault(NULL), m_sessionInitDefault(NULL), m_artifactResolutionDefault(NULL)
 {
@@ -466,7 +459,7 @@ XMLApplication::XMLApplication(
 
     try {
         // First load any property sets.
-        load(e,log,this);
+        load(e,NULL,this);
         if (base)
             setParent(base);
 
@@ -734,9 +727,6 @@ XMLApplication::XMLApplication(
             if (nlist->item(i)->getParentNode()->isSameNode(e) && nlist->item(i)->hasChildNodes())
                 m_audiences.push_back(nlist->item(i)->getFirstChild()->getNodeValue());
 
-        // Always include our own entityID as an audience.
-        m_audiences.push_back(getXMLString("entityID").second);
-
         if (conf.isEnabled(SPConfig::Metadata)) {
             child = XMLHelper::getFirstChildElement(e,_MetadataProvider);
             if (child) {
@@ -862,18 +852,13 @@ XMLApplication::XMLApplication(
         }
 
         // Finally, load relying parties.
-        child = XMLHelper::getFirstChildElement(e,DefaultRelyingParty);
-        if (child) {
-            m_partyDefault=new DOMPropertySet();
-            m_partyDefault->load(child,log,this);
-            child = XMLHelper::getFirstChildElement(child,RelyingParty);
-            while (child) {
-                auto_ptr<DOMPropertySet> rp(new DOMPropertySet());
-                rp->load(child,log,this);
-                rp->setParent(m_partyDefault);
-                m_partyMap[child->getAttributeNS(NULL,saml2::Attribute::NAME_ATTRIB_NAME)]=rp.release();
-                child = XMLHelper::getNextSiblingElement(child,RelyingParty);
-            }
+        child = XMLHelper::getFirstChildElement(e,RelyingParty);
+        while (child) {
+            auto_ptr<DOMPropertySet> rp(new DOMPropertySet());
+            rp->load(child,NULL,this);
+            rp->setParent(this);
+            m_partyMap[child->getAttributeNS(NULL,saml2::Attribute::NAME_ATTRIB_NAME)]=rp.release();
+            child = XMLHelper::getNextSiblingElement(child,RelyingParty);
         }
 #endif
 
@@ -910,8 +895,6 @@ void XMLApplication::cleanup()
     for_each(m_handlers.begin(),m_handlers.end(),xmltooling::cleanup<Handler>());
     m_handlers.clear();
 #ifndef SHIBSP_LITE
-    delete m_partyDefault;
-    m_partyDefault = NULL;
 #ifdef HAVE_GOOD_STL
     for_each(m_partyMap.begin(),m_partyMap.end(),cleanup_pair<xstring,PropertySet>());
 #else
@@ -936,7 +919,7 @@ void XMLApplication::cleanup()
 short XMLApplication::acceptNode(const DOMNode* node) const
 {
     const XMLCh* name=node->getLocalName();
-    if (XMLString::equals(name,_Application) ||
+    if (XMLString::equals(name,ApplicationOverride) ||
         XMLString::equals(name,_Audience) ||
         XMLString::equals(name,Notify) ||
         XMLString::equals(name,_Handler) ||
@@ -946,7 +929,6 @@ short XMLApplication::acceptNode(const DOMNode* node) const
         XMLString::equals(name,_ManageNameIDService) ||
         XMLString::equals(name,_SessionInitiator) ||
         XMLString::equals(name,_SingleLogoutService) ||
-        XMLString::equals(name,DefaultRelyingParty) ||
         XMLString::equals(name,RelyingParty) ||
         XMLString::equals(name,_MetadataProvider) ||
         XMLString::equals(name,_TrustEngine) ||
@@ -963,10 +945,8 @@ short XMLApplication::acceptNode(const DOMNode* node) const
 
 const PropertySet* XMLApplication::getRelyingParty(const EntityDescriptor* provider) const
 {
-    if (!m_partyDefault && m_base)
-        return m_base->getRelyingParty(provider);
-    else if (!provider)
-        return m_partyDefault;
+    if (!provider)
+        return this;
         
 #ifdef HAVE_GOOD_STL
     map<xstring,PropertySet*>::const_iterator i=m_partyMap.find(provider->getEntityID());
@@ -994,7 +974,7 @@ const PropertySet* XMLApplication::getRelyingParty(const EntityDescriptor* provi
         }
     }
 #endif
-    return m_partyDefault;
+    return this;
 }
 
 #endif
@@ -1135,17 +1115,18 @@ short XMLConfigImpl::acceptNode(const DOMNode* node) const
     if (!XMLString::equals(node->getNamespaceURI(),shibspconstants::SHIB2SPCONFIG_NS))
         return FILTER_ACCEPT;
     const XMLCh* name=node->getLocalName();
-    if (XMLString::equals(name,Applications) ||
+    if (XMLString::equals(name,ApplicationDefaults) ||
         XMLString::equals(name,_ArtifactMap) ||
         XMLString::equals(name,_Extensions) ||
         XMLString::equals(name,Listener) ||
-        XMLString::equals(name,Policy) ||
         XMLString::equals(name,_RequestMapper) ||
         XMLString::equals(name,_ReplayCache) ||
+        XMLString::equals(name,SecurityPolicies) ||
         XMLString::equals(name,_SessionCache) ||
         XMLString::equals(name,Site) ||
         XMLString::equals(name,_StorageService) ||
         XMLString::equals(name,TCPListener) ||
+        XMLString::equals(name,TransportOption) ||
         XMLString::equals(name,UnixListener))
         return FILTER_REJECT;
 
@@ -1218,7 +1199,7 @@ XMLConfigImpl::XMLConfigImpl(const DOMElement* e, bool first, const XMLConfig* o
         }
         
         // First load any property sets.
-        load(e,log,this);
+        load(e,NULL,this);
 
         const DOMElement* child;
         string plugtype;
@@ -1363,7 +1344,7 @@ XMLConfigImpl::XMLConfigImpl(const DOMElement* e, bool first, const XMLConfig* o
                 pair< PropertySet*,vector<const SecurityPolicyRule*> >& rules = m_policyMap[id.get()];
                 rules.first = NULL;
                 auto_ptr<DOMPropertySet> settings(new DOMPropertySet());
-                settings->load(child, log, &filter);
+                settings->load(child, NULL, &filter);
                 rules.first = settings.release();
                 
                 // Process Rule elements.
@@ -1379,46 +1360,44 @@ XMLConfigImpl::XMLConfigImpl(const DOMElement* e, bool first, const XMLConfig* o
                     rule = XMLHelper::getNextSiblingElement(rule,Rule);
                 }
                 
-                // Process TransportOption elements.
-                rule = XMLHelper::getFirstChildElement(child,TransportOption);
-                while (rule) {
-                    if (rule->hasChildNodes()) {
-                        auto_ptr_char provider(rule->getAttributeNS(NULL,_provider));
-                        auto_ptr_char option(rule->getAttributeNS(NULL,_option));
-                        auto_ptr_char value(rule->getFirstChild()->getNodeValue());
-                        if (provider.get() && *provider.get() && option.get() && *option.get() && value.get() && *value.get()) {
-                            m_transportOptionMap[id.get()].push_back(
-                                make_pair(string(provider.get()), make_pair(string(option.get()), string(value.get())))
-                                );
-                        }
-                    }
-                    rule = XMLHelper::getNextSiblingElement(rule,TransportOption);
-                }
-                
                 child = XMLHelper::getNextSiblingElement(child,Policy);
             }
         }
+
+        // Process TransportOption elements.
+        child = XMLHelper::getLastChildElement(e,TransportOption);
+        while (child) {
+            if (child->hasChildNodes()) {
+                auto_ptr_char provider(child->getAttributeNS(NULL,_provider));
+                auto_ptr_char option(child->getAttributeNS(NULL,_option));
+                auto_ptr_char value(child->getFirstChild()->getNodeValue());
+                if (provider.get() && *provider.get() && option.get() && *option.get() && value.get() && *value.get()) {
+                    m_transportOptions.push_back(make_pair(string(provider.get()), make_pair(string(option.get()), string(value.get()))));
+                }
+            }
+            child = XMLHelper::getPreviousSiblingElement(child,TransportOption);
+        }
 #endif
 
         // Load the default application. This actually has a fixed ID of "default". ;-)
-        child=XMLHelper::getLastChildElement(e,Applications);
+        child=XMLHelper::getLastChildElement(e,ApplicationDefaults);
         if (!child) {
-            log.fatal("can't build default Application object, missing conf:Applications element?");
-            throw ConfigurationException("can't build default Application object, missing conf:Applications element?");
+            log.fatal("can't build default Application object, missing conf:ApplicationDefaults element?");
+            throw ConfigurationException("can't build default Application object, missing conf:ApplicationDefaults element?");
         }
         XMLApplication* defapp=new XMLApplication(m_outer,child);
         m_appmap[defapp->getId()]=defapp;
         
         // Load any overrides.
-        child = XMLHelper::getFirstChildElement(child,_Application);
+        child = XMLHelper::getFirstChildElement(child,ApplicationOverride);
         while (child) {
             auto_ptr<XMLApplication> iapp(new XMLApplication(m_outer,child,defapp));
             if (m_appmap.count(iapp->getId()))
-                log.crit("found conf:Application element with duplicate id attribute (%s), skipping it", iapp->getId());
+                log.crit("found conf:ApplicationOverride element with duplicate id attribute (%s), skipping it", iapp->getId());
             else
                 m_appmap[iapp->getId()]=iapp.release();
 
-            child = XMLHelper::getNextSiblingElement(child,_Application);
+            child = XMLHelper::getNextSiblingElement(child,ApplicationOverride);
         }
     }
     catch (exception&) {