Pass through critical bit in metadata/trust accessors.
[shibboleth/cpp-sp.git] / shibsp / impl / XMLServiceProvider.cpp
index 1c1d9f4..b6afa6f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2001-2010 Internet2
+ *  Copyright 2001-2011 Internet2
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -132,12 +132,12 @@ namespace {
         MetadataProvider* getMetadataProvider(bool required=true) const {
             if (required && !m_base && !m_metadata)
                 throw ConfigurationException("No MetadataProvider available.");
-            return (!m_metadata && m_base) ? m_base->getMetadataProvider() : m_metadata;
+            return (!m_metadata && m_base) ? m_base->getMetadataProvider(required) : m_metadata;
         }
         TrustEngine* getTrustEngine(bool required=true) const {
             if (required && !m_base && !m_trust)
                 throw ConfigurationException("No TrustEngine available.");
-            return (!m_trust && m_base) ? m_base->getTrustEngine() : m_trust;
+            return (!m_trust && m_base) ? m_base->getTrustEngine(required) : m_trust;
         }
         AttributeExtractor* getAttributeExtractor() const {
             return (!m_attrExtractor && m_base) ? m_base->getAttributeExtractor() : m_attrExtractor;
@@ -203,7 +203,8 @@ namespace {
             const char* chainingType,
             const XMLCh* localName,
             DOMElement* e,
-            Category& log
+            Category& log,
+            const char* dummyType=nullptr
             );
         void doAttributeInfo();
         void doHandlers(const ProtocolProvider*, const DOMElement*, Category&);
@@ -681,7 +682,8 @@ template <class T> T* XMLApplication::doChainedPlugins(
     const char* chainingType,
     const XMLCh* localName,
     DOMElement* e,
-    Category& log
+    Category& log,
+    const char* dummyType
     )
 {
     string t;
@@ -715,6 +717,11 @@ template <class T> T* XMLApplication::doChainedPlugins(
         }
         catch (exception& ex) {
             log.crit("error building %s: %s", pluginType, ex.what());
+            if (dummyType) {
+                // Install a dummy version as a safety valve.
+                log.crit("installing safe %s in place of failed version", pluginType);
+                return pluginMgr.newPlugin(dummyType, nullptr);
+            }
         }
     }
 
@@ -883,7 +890,7 @@ void XMLApplication::doHandlers(const ProtocolProvider* pp, const DOMElement* e,
                     child = XMLHelper::getNextSiblingElement(child);
                     continue;
                 }
-                handler = conf.AssertionConsumerServiceManager.newPlugin(bindprop.c_str(), make_pair(child, getId()));
+                handler = conf.AssertionConsumerServiceManager.newPlugin(bindprop.c_str(), pair<const DOMElement*,const char*>(child, getId()));
                 // Map by binding and protocol (may be > 1 per protocol and binding)
                 m_acsBindingMap[handler->getXMLString("Binding").second].push_back(handler);
                 const XMLCh* protfamily = handler->getProtocolFamily();
@@ -910,7 +917,7 @@ void XMLApplication::doHandlers(const ProtocolProvider* pp, const DOMElement* e,
                     child = XMLHelper::getNextSiblingElement(child);
                     continue;
                 }
-                SessionInitiator* sihandler = conf.SessionInitiatorManager.newPlugin(t.c_str(), make_pair(child, getId()));
+                SessionInitiator* sihandler = conf.SessionInitiatorManager.newPlugin(t.c_str(), pair<const DOMElement*,const char*>(child, getId()));
                 handler = sihandler;
                 pair<bool,const char*> si_id = handler->getString("id");
                 if (si_id.first && si_id.second)
@@ -935,7 +942,7 @@ void XMLApplication::doHandlers(const ProtocolProvider* pp, const DOMElement* e,
                     child = XMLHelper::getNextSiblingElement(child);
                     continue;
                 }
-                handler = conf.LogoutInitiatorManager.newPlugin(t.c_str(), make_pair(child, getId()));
+                handler = conf.LogoutInitiatorManager.newPlugin(t.c_str(), pair<const DOMElement*,const char*>(child, getId()));
             }
             else if (XMLString::equals(child->getLocalName(), _ArtifactResolutionService)) {
                 string bindprop(XMLHelper::getAttrString(child, nullptr, Binding));
@@ -944,7 +951,7 @@ void XMLApplication::doHandlers(const ProtocolProvider* pp, const DOMElement* e,
                     child = XMLHelper::getNextSiblingElement(child);
                     continue;
                 }
-                handler = conf.ArtifactResolutionServiceManager.newPlugin(bindprop.c_str(), make_pair(child, getId()));
+                handler = conf.ArtifactResolutionServiceManager.newPlugin(bindprop.c_str(), pair<const DOMElement*,const char*>(child, getId()));
 
                 if (!hardArt) {
                     pair<bool,bool> defprop = handler->getBool("isDefault");
@@ -965,7 +972,7 @@ void XMLApplication::doHandlers(const ProtocolProvider* pp, const DOMElement* e,
                     child = XMLHelper::getNextSiblingElement(child);
                     continue;
                 }
-                handler = conf.SingleLogoutServiceManager.newPlugin(bindprop.c_str(), make_pair(child, getId()));
+                handler = conf.SingleLogoutServiceManager.newPlugin(bindprop.c_str(), pair<const DOMElement*,const char*>(child, getId()));
             }
             else if (XMLString::equals(child->getLocalName(), _ManageNameIDService)) {
                 string bindprop(XMLHelper::getAttrString(child, nullptr, Binding));
@@ -974,7 +981,7 @@ void XMLApplication::doHandlers(const ProtocolProvider* pp, const DOMElement* e,
                     child = XMLHelper::getNextSiblingElement(child);
                     continue;
                 }
-                handler = conf.ManageNameIDServiceManager.newPlugin(bindprop.c_str(), make_pair(child, getId()));
+                handler = conf.ManageNameIDServiceManager.newPlugin(bindprop.c_str(), pair<const DOMElement*,const char*>(child, getId()));
             }
             else {
                 string t(XMLHelper::getAttrString(child, nullptr, _type));
@@ -983,7 +990,7 @@ void XMLApplication::doHandlers(const ProtocolProvider* pp, const DOMElement* e,
                     child = XMLHelper::getNextSiblingElement(child);
                     continue;
                 }
-                handler = conf.HandlerManager.newPlugin(t.c_str(), make_pair(child, getId()));
+                handler = conf.HandlerManager.newPlugin(t.c_str(), pair<const DOMElement*,const char*>(child, getId()));
             }
 
             m_handlers.push_back(handler);
@@ -1011,8 +1018,7 @@ void XMLApplication::doSSO(const ProtocolProvider& pp, set<string>& protocols, D
     SPConfig& conf = SPConfig::getConfig();
 
     // Tokenize the protocol list inside the element.
-    const XMLCh* protlist = e->getFirstChild()->getNodeValue();
-    XMLStringTokenizer prottokens(protlist);
+    XMLStringTokenizer prottokens(e->getTextContent());
     while (prottokens.hasMoreTokens()) {
         auto_ptr_char prot(prottokens.nextToken());
 
@@ -1055,7 +1061,9 @@ void XMLApplication::doSSO(const ProtocolProvider& pp, set<string>& protocols, D
                     acsdom->setAttributeNS(nullptr, _index, indexbuf.c_str());
 
                     log.info("adding AssertionConsumerService for Binding (%s) at (%s)", (*b)->getString("id").second, (*b)->getString("path").second);
-                    Handler* handler = conf.AssertionConsumerServiceManager.newPlugin((*b)->getString("id").second, make_pair(acsdom, getId()));
+                    Handler* handler = conf.AssertionConsumerServiceManager.newPlugin(
+                        (*b)->getString("id").second, pair<const DOMElement*,const char*>(acsdom, getId())
+                        );
                     m_handlers.push_back(handler);
 
                     // Setup maps and defaults.
@@ -1113,7 +1121,9 @@ void XMLApplication::doSSO(const ProtocolProvider& pp, set<string>& protocols, D
     e->setAttributeNS(nullptr, Location, _loc);
 
     // Instantiate Chaining initiator around the SSO element.
-    SessionInitiator* chain = conf.SessionInitiatorManager.newPlugin(CHAINING_SESSION_INITIATOR, make_pair(e, getId()));
+    SessionInitiator* chain = conf.SessionInitiatorManager.newPlugin(
+        CHAINING_SESSION_INITIATOR, pair<const DOMElement*,const char*>(e, getId())
+        );
     m_handlers.push_back(chain);
     m_sessionInitDefault = chain;
     m_handlerMap["/Login"] = chain;
@@ -1127,8 +1137,7 @@ void XMLApplication::doLogout(const ProtocolProvider& pp, set<string>& protocols
     SPConfig& conf = SPConfig::getConfig();
 
     // Tokenize the protocol list inside the element.
-    const XMLCh* protlist = e->getFirstChild()->getNodeValue();
-    XMLStringTokenizer prottokens(protlist);
+    XMLStringTokenizer prottokens(e->getTextContent());
     while (prottokens.hasMoreTokens()) {
         auto_ptr_char prot(prottokens.nextToken());
 
@@ -1168,7 +1177,9 @@ void XMLApplication::doLogout(const ProtocolProvider& pp, set<string>& protocols
                     slodom->setAttributeNS(nullptr, Location, pathprop.second);
 
                     log.info("adding SingleLogoutService for Binding (%s) at (%s)", (*b)->getString("id").second, (*b)->getString("path").second);
-                    Handler* handler = conf.SingleLogoutServiceManager.newPlugin((*b)->getString("id").second, make_pair(slodom, getId()));
+                    Handler* handler = conf.SingleLogoutServiceManager.newPlugin(
+                        (*b)->getString("id").second, pair<const DOMElement*,const char*>(slodom, getId())
+                        );
                     m_handlers.push_back(handler);
 
                     // Insert into location map.
@@ -1199,7 +1210,9 @@ void XMLApplication::doLogout(const ProtocolProvider& pp, set<string>& protocols
     e->setAttributeNS(nullptr, Location, _loc);
 
     // Instantiate Chaining initiator around the SSO element.
-    Handler* chain = conf.LogoutInitiatorManager.newPlugin(CHAINING_LOGOUT_INITIATOR, make_pair(e, getId()));
+    Handler* chain = conf.LogoutInitiatorManager.newPlugin(
+        CHAINING_LOGOUT_INITIATOR, pair<const DOMElement*,const char*>(e, getId())
+        );
     m_handlers.push_back(chain);
     m_handlerMap["/Logout"] = chain;
 }
@@ -1212,8 +1225,7 @@ void XMLApplication::doNameIDMgmt(const ProtocolProvider& pp, set<string>& proto
     SPConfig& conf = SPConfig::getConfig();
 
     // Tokenize the protocol list inside the element.
-    const XMLCh* protlist = e->getFirstChild()->getNodeValue();
-    XMLStringTokenizer prottokens(protlist);
+    XMLStringTokenizer prottokens(e->getTextContent());
     while (prottokens.hasMoreTokens()) {
         auto_ptr_char prot(prottokens.nextToken());
 
@@ -1231,7 +1243,9 @@ void XMLApplication::doNameIDMgmt(const ProtocolProvider& pp, set<string>& proto
                     nimdom->setAttributeNS(nullptr, Location, pathprop.second);
 
                     log.info("adding ManageNameIDService for Binding (%s) at (%s)", (*b)->getString("id").second, (*b)->getString("path").second);
-                    Handler* handler = conf.ManageNameIDServiceManager.newPlugin((*b)->getString("id").second, make_pair(nimdom, getId()));
+                    Handler* handler = conf.ManageNameIDServiceManager.newPlugin(
+                        (*b)->getString("id").second, pair<const DOMElement*,const char*>(nimdom, getId())
+                        );
                     m_handlers.push_back(handler);
 
                     // Insert into location map.
@@ -1280,7 +1294,9 @@ void XMLApplication::doArtifactResolution(const ProtocolProvider& pp, const char
                 artdom->setAttributeNS(nullptr, _index, indexbuf.c_str());
 
                 log.info("adding ArtifactResolutionService for Binding (%s) at (%s)", (*b)->getString("id").second, (*b)->getString("path").second);
-                Handler* handler = conf.ArtifactResolutionServiceManager.newPlugin((*b)->getString("id").second, make_pair(artdom, getId()));
+                Handler* handler = conf.ArtifactResolutionServiceManager.newPlugin(
+                    (*b)->getString("id").second, pair<const DOMElement*,const char*>(artdom, getId())
+                    );
                 m_handlers.push_back(handler);
 
                 if (!m_artifactResolutionDefault)
@@ -1309,7 +1325,7 @@ void XMLApplication::doAttributePlugins(DOMElement* e, Category& log)
         doChainedPlugins(conf.AttributeExtractorManager, "AttributeExtractor", CHAINING_ATTRIBUTE_EXTRACTOR, _AttributeExtractor, e, log);
 
     m_attrFilter =
-        doChainedPlugins(conf.AttributeFilterManager, "AttributeFilter", CHAINING_ATTRIBUTE_FILTER, _AttributeFilter, e, log);
+        doChainedPlugins(conf.AttributeFilterManager, "AttributeFilter", CHAINING_ATTRIBUTE_FILTER, _AttributeFilter, e, log, DUMMY_ATTRIBUTE_FILTER);
 
     m_attrResolver =
         doChainedPlugins(conf.AttributeResolverManager, "AttributeResolver", CHAINING_ATTRIBUTE_RESOLVER, _AttributeResolver, e, log);