Mix/max functor.
authorcantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Wed, 9 May 2007 02:06:10 +0000 (02:06 +0000)
committercantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Wed, 9 May 2007 02:06:10 +0000 (02:06 +0000)
Add safety feature when requiring metadata/trust.

git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/trunk@2242 cb58f699-b61c-0410-a6fe-9272a202ed29

schemas/shibboleth-2.0-afp-mf-basic.xsd
shibsp/Application.h
shibsp/Makefile.am
shibsp/attribute/filtering/MatchFunctor.h
shibsp/attribute/filtering/impl/AttributeScopeRegexFunctor.cpp
shibsp/attribute/filtering/impl/AuthenticationMethodRegexFunctor.cpp
shibsp/attribute/filtering/impl/MatchFunctor.cpp
shibsp/attribute/filtering/impl/NumberOfAttributeValuesFunctor.cpp [new file with mode: 0644]
shibsp/impl/XMLServiceProvider.cpp
shibsp/shibsp.vcproj

index b33a9f3..90ab2b8 100644 (file)
         </annotation>
         <complexContent>
             <extension base="afp:MatchFunctorType">
-                <attribute name="attributeID" type="string">
+                <attribute name="attributeID" type="string" use="required">
                     <annotation>
                         <documentation>The ID of the attribute whose value should be matched.</documentation>
                     </annotation>
index a60d5b8..7f67005 100644 (file)
@@ -83,16 +83,18 @@ namespace shibsp {
         /**
          * Returns a MetadataProvider for use with this Application.
          * 
+         * @param required  true iff an exception should be thrown if no MetadataProvider is available
          * @return  a MetadataProvider instance, or NULL
          */
-        virtual opensaml::saml2md::MetadataProvider* getMetadataProvider() const=0;
+        virtual opensaml::saml2md::MetadataProvider* getMetadataProvider(bool required=true) const=0;
         
         /**
          * Returns a TrustEngine for use with this Application.
          * 
+         * @param required  true iff an exception should be thrown if no TrustEngine is available
          * @return  a TrustEngine instance, or NULL
          */
-        virtual xmltooling::TrustEngine* getTrustEngine() const=0;
+        virtual xmltooling::TrustEngine* getTrustEngine(bool required=true) const=0;
 
         /**
          * Returns an AttributeExtractor for use with this Application.
index 985139d..161000c 100644 (file)
@@ -117,6 +117,7 @@ libshibsp_la_SOURCES = \
        attribute/filtering/AttributeScopeRegexFunctor.cpp \
        attribute/filtering/AttributeValueRegexFunctor.cpp \
        attribute/filtering/AuthenticationMethodRegexFunctor.cpp \
+       attribute/filtering/NumberOfAttributeValuesFunctor.cpp \
        attribute/resolver/impl/ChainingAttributeResolver.cpp \
        attribute/resolver/impl/QueryAttributeResolver.cpp \
        attribute/resolver/impl/XMLAttributeExtractor.cpp \
index 9f55df4..69c5b9f 100644 (file)
@@ -106,6 +106,9 @@ namespace shibsp {
     /** Matches an attribute's "scope". */
     extern SHIBSP_API xmltooling::QName AttributeScopeRegexType;
 
+    /** Matches based on the number of values. */
+    extern SHIBSP_API xmltooling::QName NumberOfAttributeValuesType;
+
     /**
      * Registers MatchFunctor classes into the runtime.
      */
index d53449a..6164a76 100644 (file)
@@ -57,10 +57,10 @@ namespace shibsp {
             try {
                 m_regex = new RegularExpression(r, e->getAttributeNS(NULL,options));
             }
-            catch (XMLException& ex) {\r
-                xmltooling::auto_ptr_char temp(ex.getMessage());\r
-                throw ConfigurationException(temp.get());\r
-            }\r
+            catch (XMLException& ex) {
+                xmltooling::auto_ptr_char temp(ex.getMessage());
+                throw ConfigurationException(temp.get());
+            }
         }
 
         bool evaluatePolicyRequirement(const FilteringContext& filterContext) const {
index 9646690..b66bbbd 100644 (file)
@@ -17,7 +17,7 @@
 /**
  * AuthenticationMethodRegexFunctor.cpp
  * 
- * A match function that evaluates to true if the user's authentication method matches the provided regular\r
+ * A match function that evaluates to true if the user's authentication method matches the provided regular
  * expression.
  */
 
@@ -34,7 +34,7 @@ namespace shibsp {
     static const XMLCh regex[] =    UNICODE_LITERAL_5(r,e,g,e,x);
     
     /**
-     * A match function that evaluates to true if the user's authentication method matches the provided regular\r
+     * A match function that evaluates to true if the user's authentication method matches the provided regular
      * expression.
      */
     class SHIBSP_DLLLOCAL AuthenticationMethodRegexFunctor : public MatchFunctor
@@ -48,10 +48,10 @@ namespace shibsp {
             try {
                 m_regex = new RegularExpression(r, e->getAttributeNS(NULL,options));
             }
-            catch (XMLException& ex) {\r
-                xmltooling::auto_ptr_char temp(ex.getMessage());\r
-                throw ConfigurationException(temp.get());\r
-            }\r
+            catch (XMLException& ex) {
+                xmltooling::auto_ptr_char temp(ex.getMessage());
+                throw ConfigurationException(temp.get());
+            }
         }
 
         virtual ~AuthenticationMethodRegexFunctor() {
index 1eabf5d..edb4f1a 100644 (file)
@@ -54,6 +54,7 @@ namespace shibsp {
     DECL_FACTORY(AuthenticationMethodRegex);
     DECL_FACTORY(AttributeValueRegex);
     DECL_FACTORY(AttributeScopeRegex);
+    DECL_FACTORY(NumberOfAttributeValues);
 
     static const XMLCh ANY[] =                          UNICODE_LITERAL_3(A,N,Y);
     static const XMLCh AND[] =                          UNICODE_LITERAL_3(A,N,D);
@@ -69,6 +70,7 @@ namespace shibsp {
     static const XMLCh AuthenticationMethodRegex[] =    UNICODE_LITERAL_25(A,u,t,h,e,n,t,i,c,a,t,i,o,n,M,e,t,h,o,d,R,e,g,e,x);
     static const XMLCh AttributeValueRegex[] =          UNICODE_LITERAL_19(A,t,t,r,i,b,u,t,e,V,a,l,u,e,R,e,g,e,x);
     static const XMLCh AttributeScopeRegex[] =          UNICODE_LITERAL_19(A,t,t,r,i,b,u,t,e,S,c,o,p,e,R,e,g,e,x);
+    static const XMLCh NumberOfAttributeValues[] =      UNICODE_LITERAL_23(N,u,m,b,e,r,O,f,A,t,t,r,i,b,u,t,e,V,a,l,u,e,s);
 };
 
 DECL_BASIC_QNAME(AnyMatchFunctor, ANY);
@@ -85,6 +87,7 @@ DECL_BASIC_QNAME(AttributeRequesterRegex, AttributeRequesterRegex);
 DECL_BASIC_QNAME(AuthenticationMethodRegex, AuthenticationMethodRegex);
 DECL_BASIC_QNAME(AttributeValueRegex, AttributeValueRegex);
 DECL_BASIC_QNAME(AttributeScopeRegex, AttributeScopeRegex);
+DECL_BASIC_QNAME(NumberOfAttributeValues, NumberOfAttributeValues);
 
 void SHIBSP_API shibsp::registerMatchFunctors()
 {
@@ -104,4 +107,5 @@ void SHIBSP_API shibsp::registerMatchFunctors()
     REGISTER_FACTORY(AuthenticationMethodRegex);
     REGISTER_FACTORY(AttributeValueRegex);
     REGISTER_FACTORY(AttributeScopeRegex);
+    REGISTER_FACTORY(NumberOfAttributeValues);
 }
diff --git a/shibsp/attribute/filtering/impl/NumberOfAttributeValuesFunctor.cpp b/shibsp/attribute/filtering/impl/NumberOfAttributeValuesFunctor.cpp
new file mode 100644 (file)
index 0000000..b5e3dec
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *  Copyright 2001-2007 Internet2
+ * 
+ * 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
+ *
+ *     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.
+ */
+
+/**
+ * NumberOfAttributeValuesFunctor.cpp
+ * 
+ * A match function that evaluates to true if the given attribute has as a number\r
+ * of values that falls between the minimum and maximum.
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "attribute/Attribute.h"
+#include "attribute/filtering/FilteringContext.h"
+#include "attribute/filtering/FilterPolicyContext.h"
+
+using namespace shibsp;
+using namespace std;
+
+namespace shibsp {
+
+    static const XMLCh attributeID[] =  UNICODE_LITERAL_11(a,t,t,r,i,b,u,t,e,I,D);
+    static const XMLCh maximum[] =      UNICODE_LITERAL_7(m,a,x,i,m,u,m);
+    static const XMLCh minimum[] =      UNICODE_LITERAL_7(m,i,n,i,m,u,m);
+
+    /**
+     * A match function that matches the scope of an attribute value against the specified value.
+     */
+    class SHIBSP_DLLLOCAL NumberOfAttributeValuesFunctor : public MatchFunctor
+    {
+        unsigned int m_min,m_max;
+        xmltooling::auto_ptr_char m_attributeID;
+
+        size_t count(const FilteringContext& filterContext) const;
+
+    public:
+        NumberOfAttributeValuesFunctor(const DOMElement* e)
+                : m_min(0), m_max(INT_MAX), m_attributeID(e ? e->getAttributeNS(NULL,attributeID) : NULL) {
+            if (!m_attributeID.get() || !*m_attributeID.get())
+                throw ConfigurationException("No attributeID specified.");
+            const XMLCh* num = e->getAttributeNS(NULL, minimum);
+            if (num && *num)
+                m_min = XMLString::parseInt(num);
+            num = e->getAttributeNS(NULL, maximum);
+            if (num && *num)
+                m_max = XMLString::parseInt(num);
+        }
+
+        bool evaluatePolicyRequirement(const FilteringContext& filterContext) const {
+            size_t c = count(filterContext);
+            return (m_min <= c && c <= m_max);
+        }
+
+        bool evaluatePermitValue(const FilteringContext& filterContext, const Attribute& attribute, size_t index) const {
+            size_t c = count(filterContext);
+            return (m_min <= c && c <= m_max);
+        }
+    };
+
+    MatchFunctor* SHIBSP_DLLLOCAL NumberOfAttributeValuesFactory(const std::pair<const FilterPolicyContext*,const DOMElement*>& p)
+    {
+        return new NumberOfAttributeValuesFunctor(p.second);
+    }
+
+};
+
+size_t NumberOfAttributeValuesFunctor::count(const FilteringContext& filterContext) const
+{
+    size_t count = 0;
+    pair<multimap<string,Attribute*>::const_iterator,multimap<string,Attribute*>::const_iterator> attrs =
+        filterContext.getAttributes().equal_range(m_attributeID.get());
+    for (; attrs.first != attrs.second; ++attrs.first)
+        count += attrs.first->second->valueCount();
+    return count;
+}
index d24a5d7..a3fdf9b 100644 (file)
@@ -82,10 +82,14 @@ namespace {
         const char* getId() const {return getString("id").second;}\r
         const char* getHash() const {return m_hash.c_str();}\r
 \r
-        MetadataProvider* getMetadataProvider() const {\r
+        MetadataProvider* getMetadataProvider(bool required=true) const {\r
+            if (required && !m_base && !m_metadata)\r
+                throw ConfigurationException("No MetadataProvider available.");\r
             return (!m_metadata && m_base) ? m_base->getMetadataProvider() : m_metadata;\r
         }\r
-        TrustEngine* getTrustEngine() const {\r
+        TrustEngine* getTrustEngine(bool required=true) const {\r
+            if (required && !m_base && !m_trust)\r
+                throw ConfigurationException("No TrustEngine available.");\r
             return (!m_trust && m_base) ? m_base->getTrustEngine() : m_trust;\r
         }\r
         AttributeExtractor* getAttributeExtractor() const {\r
index 5b25b19..3a1cc0d 100644 (file)
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\attribute\filtering\impl\NumberOfAttributeValuesFunctor.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\attribute\filtering\impl\OrMatchFunctor.cpp"\r
                                >\r
                        </File>\r