SSPCPP-616 - clean up concatenated string literals
[shibboleth/cpp-sp.git] / shibsp / impl / XMLAccessControl.cpp
index 23463c8..29829ea 100644 (file)
 #include "attribute/Attribute.h"
 
 #include <algorithm>
-#include <boost/scoped_ptr.hpp>
+#include <boost/bind.hpp>
 #include <boost/algorithm/string.hpp>
-#include <boost/lambda/bind.hpp>
-#include <boost/lambda/lambda.hpp>
 #include <boost/ptr_container/ptr_vector.hpp>
 #include <xmltooling/unicode.h>
 #include <xmltooling/util/ReloadableXMLFile.h>
@@ -50,7 +48,6 @@
 
 using namespace shibsp;
 using namespace xmltooling;
-using namespace boost::lambda;
 using namespace boost;
 using namespace std;
 
@@ -114,7 +111,7 @@ namespace shibsp {
     {
     public:
         XMLAccessControl(const DOMElement* e)
-                : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT".AccessControl.XML")) {
+                : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT ".AccessControl.XML")) {
             background_load(); // guarantees an exception or the policy is loaded
         }
 
@@ -141,6 +138,7 @@ namespace shibsp {
     }
 
     static const XMLCh _AccessControl[] =   UNICODE_LITERAL_13(A,c,c,e,s,s,C,o,n,t,r,o,l);
+    static const XMLCh _Handler[] =         UNICODE_LITERAL_7(H,a,n,d,l,e,r);
     static const XMLCh ignoreCase[] =       UNICODE_LITERAL_10(i,g,n,o,r,e,C,a,s,e);
     static const XMLCh ignoreOption[] =     UNICODE_LITERAL_1(i);
     static const XMLCh _list[] =            UNICODE_LITERAL_4(l,i,s,t);
@@ -156,20 +154,24 @@ Rule::Rule(const DOMElement* e) : m_alias(XMLHelper::getAttrString(e, nullptr, r
 {
     if (m_alias.empty())
         throw ConfigurationException("Access control rule missing require attribute");
+    if (!e->hasChildNodes())
+        return; // empty rule
 
-    auto_arrayptr<char> vals(toUTF8(e->hasChildNodes() ? e->getFirstChild()->getNodeValue() : nullptr));
-    if (!vals.get())
-        return;
+    auto_arrayptr<char> vals(toUTF8(e->getTextContent()));
+    if (!vals.get() || !*vals.get())
+        throw ConfigurationException("Unable to convert Rule content into UTF-8.");
 
     bool listflag = XMLHelper::getAttrBool(e, true, _list);
     if (!listflag) {
-        if (*vals.get())
-            m_vals.insert(vals.get());
+        m_vals.insert(vals.get());
         return;
     }
 
     string temp(vals.get());
+    trim(temp);
     split(m_vals, temp, boost::is_space(), algorithm::token_compress_on);
+    if (m_vals.empty())
+        throw ConfigurationException("Rule did not contain any usable values.");
 }
 
 AccessControl::aclresult_t Rule::authorized(const SPRequest& request, const Session* session) const
@@ -221,6 +223,10 @@ AccessControl::aclresult_t Rule::authorized(const SPRequest& request, const Sess
         request.log(SPRequest::SPWarn, string("rule requires attribute (") + m_alias + "), not found in session");
         return shib_acl_false;
     }
+    else if (m_vals.empty()) {
+        request.log(SPRequest::SPDebug, string("AccessControl plugin requires presence of attribute (") + m_alias + "), authz granted");
+        return shib_acl_true;
+    }
 
     for (; attrs.first != attrs.second; ++attrs.first) {
         bool caseSensitive = attrs.first->second->isCaseSensitive();
@@ -373,9 +379,15 @@ AccessControl::aclresult_t Operator::authorized(const SPRequest& request, const
         case OP_AND:
         {
             // Look for a rule that returns non-true.
+            for (ptr_vector<AccessControl>::const_iterator i = m_operands.begin(); i != m_operands.end(); ++i) {
+                if (i->authorized(request,session) != shib_acl_true)
+                    return shib_acl_false;
+            }
+            return shib_acl_true;
+
             ptr_vector<AccessControl>::const_iterator i = find_if(
                 m_operands.begin(), m_operands.end(),
-                lambda::bind(&AccessControl::authorized, _1, boost::ref(request), session) != shib_acl_true
+                boost::bind(&AccessControl::authorized, _1, boost::cref(request), session) != shib_acl_true
                 );
             return (i != m_operands.end()) ? shib_acl_false : shib_acl_true;
         }
@@ -385,7 +397,7 @@ AccessControl::aclresult_t Operator::authorized(const SPRequest& request, const
             // Look for a rule that returns true.
             ptr_vector<AccessControl>::const_iterator i = find_if(
                 m_operands.begin(), m_operands.end(),
-                lambda::bind(&AccessControl::authorized, _1, boost::ref(request), session) == shib_acl_true
+                boost::bind(&AccessControl::authorized, _1, boost::cref(request), session) == shib_acl_true
                 );
             return (i != m_operands.end()) ? shib_acl_true : shib_acl_false;
         }
@@ -403,8 +415,16 @@ pair<bool,DOMElement*> XMLAccessControl::background_load()
     XercesJanitor<DOMDocument> docjanitor(raw.first ? raw.second->getOwnerDocument() : nullptr);
 
     // Check for AccessControl wrapper and drop a level.
-    if (XMLString::equals(raw.second->getLocalName(),_AccessControl))
+    if (XMLString::equals(raw.second->getLocalName(),_AccessControl)) {
+        raw.second = XMLHelper::getFirstChildElement(raw.second);
+        if (!raw.second)
+            throw ConfigurationException("No child element found in AccessControl parent element.");
+    }
+    else if (XMLString::equals(raw.second->getLocalName(),_Handler)) {
         raw.second = XMLHelper::getFirstChildElement(raw.second);
+        if (!raw.second)
+            throw ConfigurationException("No child element found in Handler parent element.");
+    }
 
     scoped_ptr<AccessControl> authz;
     if (XMLString::equals(raw.second->getLocalName(),_Rule))