SSPCPP-616 - clean up concatenated string literals
[shibboleth/cpp-opensaml.git] / saml / profile / impl / ConditionsRule.cpp
index 933c61e..0153bb6 100644 (file)
@@ -1,36 +1,46 @@
-/*
- *  Copyright 2009 Internet2
+/**
+ * Licensed to the University Corporation for Advanced Internet
+ * Development, Inc. (UCAID) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for
+ * additional information regarding copyright ownership.
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * UCAID licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the
+ * License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the License.
  */
 
 /**
  * ConditionsRule.cpp
  *
- * SAML Conditions SecurityPolicyRule
+ * SAML Conditions SecurityPolicyRule.
  */
 
 #include "internal.h"
 #include "exceptions.h"
+#include "binding/SecurityPolicy.h"
 #include "binding/SecurityPolicyRule.h"
 #include "saml1/core/Assertions.h"
 #include "saml2/core/Assertions.h"
 
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <xercesc/util/XMLUniDefs.hpp>
 #include <xmltooling/logging.h>
+#include <xmltooling/XMLToolingConfig.h>
+#include <xmltooling/util/ParserPool.h>
 
 using namespace opensaml;
 using namespace xmltooling::logging;
 using namespace xmltooling;
+using namespace boost;
 using namespace std;
 
 namespace opensaml {
@@ -40,7 +50,6 @@ namespace opensaml {
         ConditionsRule(const DOMElement* e);
 
         virtual ~ConditionsRule() {
-            for_each(m_rules.begin(), m_rules.end(), xmltooling::cleanup<SecurityPolicyRule>());
             if (m_doc)
                 m_doc->release();
         }
@@ -51,7 +60,7 @@ namespace opensaml {
 
     private:
         DOMDocument* m_doc;
-        vector<SecurityPolicyRule*> m_rules;
+        ptr_vector<SecurityPolicyRule> m_rules;
     };
 
     SecurityPolicyRule* SAML_DLLLOCAL ConditionsRuleFactory(const DOMElement* const & e)
@@ -59,21 +68,21 @@ namespace opensaml {
         return new ConditionsRule(e);
     }
 
-    static const XMLCh Rule[] =     UNICODE_LITERAL_4(R,u,l,e);
+    static const XMLCh Rule[] =     UNICODE_LITERAL_10(P,o,l,i,c,y,R,u,l,e);
     static const XMLCh type[] =     UNICODE_LITERAL_4(t,y,p,e);
 
     const char config[] =
-        "<Rule type=\"Conditions\" xmlns:saml2=\"urn:oasis:names:tc:SAML:2.0:assertion\" xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\">"\r
-            "<Rule type=\"Audience\"/>"\r
-            "<Rule type=\"Ignore\">saml:DoNotCacheCondition</Rule>"\r
-            "<Rule type=\"Ignore\">saml2:OneTimeUse</Rule>"\r
-            "<Rule type=\"Ignore\">saml2:ProxyRestriction</Rule>"\r
-        "</Rule>";\r
+        "<PolicyRule type=\"Conditions\" xmlns:saml2=\"urn:oasis:names:tc:SAML:2.0:assertion\" xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\">"
+            "<PolicyRule type=\"Audience\"/>"
+            "<PolicyRule type=\"Ignore\">saml:DoNotCacheCondition</PolicyRule>"
+            "<PolicyRule type=\"Ignore\">saml2:OneTimeUse</PolicyRule>"
+            "<PolicyRule type=\"Ignore\">saml2:ProxyRestriction</PolicyRule>"
+        "</PolicyRule>";
 };
 
-ConditionsRule::ConditionsRule(const DOMElement* e) : m_doc(NULL)
+ConditionsRule::ConditionsRule(const DOMElement* e) : m_doc(nullptr)
 {
-    Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.Conditions");
+    Category& log=Category::getInstance(SAML_LOGCAT ".SecurityPolicyRule.Conditions");
 
     if (!e || !e->hasChildNodes()) {
         // Default the configuration.
@@ -84,13 +93,13 @@ ConditionsRule::ConditionsRule(const DOMElement* e) : m_doc(NULL)
 
     e = XMLHelper::getFirstChildElement(e, Rule);
     while (e) {
-        auto_ptr_char temp(e->getAttributeNS(NULL, type));
-        if (temp.get() && *temp.get()) {
+        string t = XMLHelper::getAttrString(e, nullptr, type);
+        if (!t.empty()) {
             try {
-                log.info("building SecurityPolicyRule of type %s", temp.get());
-                m_rules.push_back(SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(temp.get(),e));
+                log.info("building SecurityPolicyRule of type %s", t.c_str());
+                m_rules.push_back(SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(t.c_str(), e));
             }
-            catch (exception& ex) {
+            catch (std::exception& ex) {
                 log.crit("error building SecurityPolicyRule: %s", ex.what());
             }
         }
@@ -121,47 +130,43 @@ bool ConditionsRule::evaluate(const XMLObject& message, const GenericRequest* re
         bool valid;
 
         const vector<saml2::AudienceRestriction*>& acvec = conds->getAudienceRestrictions();
-        for (vector<saml2::AudienceRestriction*>::const_iterator ac = acvec.begin(); ac!=acvec.end(); ++ac) {
+        for (vector<saml2::AudienceRestriction*>::const_iterator ac = acvec.begin(); ac != acvec.end(); ++ac) {
             valid = false;
-            for (vector<SecurityPolicyRule*>::const_iterator r = m_rules.begin(); r != m_rules.end(); ++r) {
-                if ((*r)->evaluate(*(*ac), request, policy))
-                    valid = true;
-            }
+            for (ptr_vector<SecurityPolicyRule>::const_iterator r = m_rules.begin(); !valid && r != m_rules.end(); ++r)
+                valid = r->evaluate(*(*ac), request, policy);
             if (!valid)
-                throw SecurityPolicyException("AudienceRestriction was not understood by policy.");
+                throw SecurityPolicyException("AudienceRestriction condition not successfully validated by policy.");
         }
 
         const vector<saml2::OneTimeUse*>& otvec = conds->getOneTimeUses();
         for (vector<saml2::OneTimeUse*>::const_iterator ot = otvec.begin(); ot!=otvec.end(); ++ot) {
             valid = false;
-            for (vector<SecurityPolicyRule*>::const_iterator r = m_rules.begin(); r != m_rules.end(); ++r) {
-                if ((*r)->evaluate(*(*ot), request, policy))
-                    valid = true;
-            }
+            for (ptr_vector<SecurityPolicyRule>::const_iterator r = m_rules.begin(); !valid && r != m_rules.end(); ++r)
+                valid = r->evaluate(*(*ot), request, policy);
             if (!valid)
-                throw SecurityPolicyException("OneTimeUse was not understood by policy.");
+                throw SecurityPolicyException("OneTimeUse condition not successfully validated by policy.");
         }
 
         const vector<saml2::ProxyRestriction*> pvec = conds->getProxyRestrictions();
-        for (vector<saml2::ProxyRestriction*>::const_iterator p = pvec.begin(); p!=pvec.end(); ++p) {
+        for (vector<saml2::ProxyRestriction*>::const_iterator p = pvec.begin(); p != pvec.end(); ++p) {
             valid = false;
-            for (vector<SecurityPolicyRule*>::const_iterator r = m_rules.begin(); r != m_rules.end(); ++r) {
-                if ((*r)->evaluate(*(*p), request, policy))
-                    valid = true;
-            }
+            for (ptr_vector<SecurityPolicyRule>::const_iterator r = m_rules.begin(); !valid && r != m_rules.end(); ++r)
+                valid = r->evaluate(*(*p), request, policy);
             if (!valid)
-                throw SecurityPolicyException("ProxyRestriction was not understood by policy.");
+                throw SecurityPolicyException("ProxyRestriction condition not successfully validated by policy.");
         }
 
         const vector<saml2::Condition*>& convec = conds->getConditions();
-        for (vector<saml2::Condition*>::const_iterator c = convec.begin(); c!=convec.end(); ++c) {
+        for (vector<saml2::Condition*>::const_iterator c = convec.begin(); c != convec.end(); ++c) {
             valid = false;
-            for (vector<SecurityPolicyRule*>::const_iterator r = m_rules.begin(); r != m_rules.end(); ++r) {
-                if ((*r)->evaluate(*(*c), request, policy))
-                    valid = true;
+            for (ptr_vector<SecurityPolicyRule>::const_iterator r = m_rules.begin(); !valid && r != m_rules.end(); ++r)
+                valid = r->evaluate(*(*c), request, policy);
+            if (!valid) {
+                throw SecurityPolicyException(
+                    "Extension condition ($1) not successfully validated by policy.",
+                    params(1,((*c)->getSchemaType() ? (*c)->getSchemaType()->toString().c_str() : "Unknown Type"))
+                    );
             }
-            if (!valid)
-                throw SecurityPolicyException("Condition ($1) was not understood by policy.", params(1,(*c)->getElementQName().toString().c_str()));
         }
 
         return true;
@@ -188,36 +193,34 @@ bool ConditionsRule::evaluate(const XMLObject& message, const GenericRequest* re
         bool valid;
 
         const vector<saml1::AudienceRestrictionCondition*>& acvec = conds->getAudienceRestrictionConditions();
-        for (vector<saml1::AudienceRestrictionCondition*>::const_iterator ac = acvec.begin(); ac!=acvec.end(); ++ac) {
+        for (vector<saml1::AudienceRestrictionCondition*>::const_iterator ac = acvec.begin(); ac != acvec.end(); ++ac) {
             valid = false;
-            for (vector<SecurityPolicyRule*>::const_iterator r = m_rules.begin(); r != m_rules.end(); ++r) {
-                if ((*r)->evaluate(*(*ac), request, policy))
-                    valid = true;
-            }
+            for (ptr_vector<SecurityPolicyRule>::const_iterator r = m_rules.begin(); !valid && r != m_rules.end(); ++r)
+                valid = r->evaluate(*(*ac), request, policy);
             if (!valid)
-                throw SecurityPolicyException("AudienceRestrictionCondition was not understood by policy.");
+                throw SecurityPolicyException("AudienceRestrictionCondition not successfully validated by policy.");
         }
 
         const vector<saml1::DoNotCacheCondition*>& dncvec = conds->getDoNotCacheConditions();
-        for (vector<saml1::DoNotCacheCondition*>::const_iterator dnc = dncvec.begin(); dnc!=dncvec.end(); ++dnc) {
+        for (vector<saml1::DoNotCacheCondition*>::const_iterator dnc = dncvec.begin(); dnc != dncvec.end(); ++dnc) {
             valid = false;
-            for (vector<SecurityPolicyRule*>::const_iterator r = m_rules.begin(); r != m_rules.end(); ++r) {
-                if ((*r)->evaluate(*(*dnc), request, policy))
-                    valid = true;
-            }
+            for (ptr_vector<SecurityPolicyRule>::const_iterator r = m_rules.begin(); !valid && r != m_rules.end(); ++r)
+                valid = r->evaluate(*(*dnc), request, policy);
             if (!valid)
-                throw SecurityPolicyException("DoNotCacheCondition was not understood by policy.");
+                throw SecurityPolicyException("DoNotCacheCondition not successfully validated by policy.");
         }
 
         const vector<saml1::Condition*>& convec = conds->getConditions();
-        for (vector<saml1::Condition*>::const_iterator c = convec.begin(); c!=convec.end(); ++c) {
+        for (vector<saml1::Condition*>::const_iterator c = convec.begin(); c != convec.end(); ++c) {
             valid = false;
-            for (vector<SecurityPolicyRule*>::const_iterator r = m_rules.begin(); r != m_rules.end(); ++r) {
-                if ((*r)->evaluate(*(*c), request, policy))
-                    valid = true;
+            for (ptr_vector<SecurityPolicyRule>::const_iterator r = m_rules.begin(); !valid && r != m_rules.end(); ++r)
+                valid = r->evaluate(*(*c), request, policy);
+            if (!valid) {
+                throw SecurityPolicyException(
+                    "Extension condition ($1) not successfully validated by policy.",
+                    params(1,((*c)->getSchemaType() ? (*c)->getSchemaType()->toString().c_str() : (*c)->getElementQName().toString().c_str()))
+                    );
             }
-            if (!valid)
-                throw SecurityPolicyException("Condition ($1) was not understood by policy.", params(1,(*c)->getElementQName().toString().c_str()));
         }
 
         return true;