From 870de4c8f1a850ef7c2a23d42a16e0c4ef24c159 Mon Sep 17 00:00:00 2001 From: cantor Date: Wed, 9 May 2007 02:06:10 +0000 Subject: [PATCH] Mix/max functor. 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 | 2 +- shibsp/Application.h | 6 +- shibsp/Makefile.am | 1 + shibsp/attribute/filtering/MatchFunctor.h | 3 + .../filtering/impl/AttributeScopeRegexFunctor.cpp | 8 +- .../impl/AuthenticationMethodRegexFunctor.cpp | 12 +-- shibsp/attribute/filtering/impl/MatchFunctor.cpp | 4 + .../impl/NumberOfAttributeValuesFunctor.cpp | 88 ++++++++++++++++++++++ shibsp/impl/XMLServiceProvider.cpp | 8 +- shibsp/shibsp.vcproj | 4 + 10 files changed, 121 insertions(+), 15 deletions(-) create mode 100644 shibsp/attribute/filtering/impl/NumberOfAttributeValuesFunctor.cpp diff --git a/schemas/shibboleth-2.0-afp-mf-basic.xsd b/schemas/shibboleth-2.0-afp-mf-basic.xsd index b33a9f3..90ab2b8 100644 --- a/schemas/shibboleth-2.0-afp-mf-basic.xsd +++ b/schemas/shibboleth-2.0-afp-mf-basic.xsd @@ -346,7 +346,7 @@ - + The ID of the attribute whose value should be matched. diff --git a/shibsp/Application.h b/shibsp/Application.h index a60d5b8..7f67005 100644 --- a/shibsp/Application.h +++ b/shibsp/Application.h @@ -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. diff --git a/shibsp/Makefile.am b/shibsp/Makefile.am index 985139d..161000c 100644 --- a/shibsp/Makefile.am +++ b/shibsp/Makefile.am @@ -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 \ diff --git a/shibsp/attribute/filtering/MatchFunctor.h b/shibsp/attribute/filtering/MatchFunctor.h index 9f55df4..69c5b9f 100644 --- a/shibsp/attribute/filtering/MatchFunctor.h +++ b/shibsp/attribute/filtering/MatchFunctor.h @@ -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. */ diff --git a/shibsp/attribute/filtering/impl/AttributeScopeRegexFunctor.cpp b/shibsp/attribute/filtering/impl/AttributeScopeRegexFunctor.cpp index d53449a..6164a76 100644 --- a/shibsp/attribute/filtering/impl/AttributeScopeRegexFunctor.cpp +++ b/shibsp/attribute/filtering/impl/AttributeScopeRegexFunctor.cpp @@ -57,10 +57,10 @@ namespace shibsp { try { m_regex = new RegularExpression(r, e->getAttributeNS(NULL,options)); } - catch (XMLException& ex) { - xmltooling::auto_ptr_char temp(ex.getMessage()); - throw ConfigurationException(temp.get()); - } + catch (XMLException& ex) { + xmltooling::auto_ptr_char temp(ex.getMessage()); + throw ConfigurationException(temp.get()); + } } bool evaluatePolicyRequirement(const FilteringContext& filterContext) const { diff --git a/shibsp/attribute/filtering/impl/AuthenticationMethodRegexFunctor.cpp b/shibsp/attribute/filtering/impl/AuthenticationMethodRegexFunctor.cpp index 9646690..b66bbbd 100644 --- a/shibsp/attribute/filtering/impl/AuthenticationMethodRegexFunctor.cpp +++ b/shibsp/attribute/filtering/impl/AuthenticationMethodRegexFunctor.cpp @@ -17,7 +17,7 @@ /** * AuthenticationMethodRegexFunctor.cpp * - * A match function that evaluates to true if the user's authentication method matches the provided regular + * 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 + * 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) { - xmltooling::auto_ptr_char temp(ex.getMessage()); - throw ConfigurationException(temp.get()); - } + catch (XMLException& ex) { + xmltooling::auto_ptr_char temp(ex.getMessage()); + throw ConfigurationException(temp.get()); + } } virtual ~AuthenticationMethodRegexFunctor() { diff --git a/shibsp/attribute/filtering/impl/MatchFunctor.cpp b/shibsp/attribute/filtering/impl/MatchFunctor.cpp index 1eabf5d..edb4f1a 100644 --- a/shibsp/attribute/filtering/impl/MatchFunctor.cpp +++ b/shibsp/attribute/filtering/impl/MatchFunctor.cpp @@ -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 index 0000000..b5e3dec --- /dev/null +++ b/shibsp/attribute/filtering/impl/NumberOfAttributeValuesFunctor.cpp @@ -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 + * 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& p) + { + return new NumberOfAttributeValuesFunctor(p.second); + } + +}; + +size_t NumberOfAttributeValuesFunctor::count(const FilteringContext& filterContext) const +{ + size_t count = 0; + pair::const_iterator,multimap::const_iterator> attrs = + filterContext.getAttributes().equal_range(m_attributeID.get()); + for (; attrs.first != attrs.second; ++attrs.first) + count += attrs.first->second->valueCount(); + return count; +} diff --git a/shibsp/impl/XMLServiceProvider.cpp b/shibsp/impl/XMLServiceProvider.cpp index d24a5d7..a3fdf9b 100644 --- a/shibsp/impl/XMLServiceProvider.cpp +++ b/shibsp/impl/XMLServiceProvider.cpp @@ -82,10 +82,14 @@ namespace { const char* getId() const {return getString("id").second;} const char* getHash() const {return m_hash.c_str();} - MetadataProvider* getMetadataProvider() const { + 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; } - TrustEngine* getTrustEngine() const { + 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; } AttributeExtractor* getAttributeExtractor() const { diff --git a/shibsp/shibsp.vcproj b/shibsp/shibsp.vcproj index 5b25b19..3a1cc0d 100644 --- a/shibsp/shibsp.vcproj +++ b/shibsp/shibsp.vcproj @@ -255,6 +255,10 @@ > + + -- 2.1.4