From: Scott Cantor Date: Thu, 5 May 2016 18:24:08 +0000 (-0400) Subject: SSPCPP-697 - Align the filter schema(s) and functor types where feasible. X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fcpp-sp.git;a=commitdiff_plain;h=7fe60b9708489a50951f05dac6274a605ea4c03d SSPCPP-697 - Align the filter schema(s) and functor types where feasible. https://issues.shibboleth.net/jira/browse/SSPCPP-697 Add RegistrationAuthority and AttributeIssuerRegistrationAuthority functors. --- diff --git a/.gitignore b/.gitignore index bc4d500..0035096 100644 --- a/.gitignore +++ b/.gitignore @@ -67,6 +67,7 @@ x64 /Projects/VC??/fastcgi/shibresponder-Debug/ /Projects/VC??/fastcgi/shibresponder-Release/ /Projects/VC??/ipch/ +/Projects/VC??/.vs /Projects/VC??/plugins/plugins-lite-Debug/ /Projects/VC??/plugins/plugins-lite-Release/ /Projects/VC??/shibsp/shibsp-lite-Debug/ diff --git a/Projects/vc10/shibsp/shibsp.vcxproj b/Projects/vc10/shibsp/shibsp.vcxproj index 19b6392..daf761a 100644 --- a/Projects/vc10/shibsp/shibsp.vcxproj +++ b/Projects/vc10/shibsp/shibsp.vcxproj @@ -1,4 +1,4 @@ - + @@ -188,6 +188,7 @@ + @@ -364,4 +365,4 @@ - + \ No newline at end of file diff --git a/Projects/vc10/shibsp/shibsp.vcxproj.filters b/Projects/vc10/shibsp/shibsp.vcxproj.filters index 1819d1f..929c38e 100644 --- a/Projects/vc10/shibsp/shibsp.vcxproj.filters +++ b/Projects/vc10/shibsp/shibsp.vcxproj.filters @@ -426,6 +426,9 @@ Source Files\security + + Source Files\attribute\filtering\impl + diff --git a/shibsp/Makefile.am b/shibsp/Makefile.am index e522bea..6e75bc7 100644 --- a/shibsp/Makefile.am +++ b/shibsp/Makefile.am @@ -212,6 +212,7 @@ libshibsp_la_SOURCES = \ attribute/filtering/impl/AttributeIssuerEntityMatcherFunctor.cpp \ attribute/filtering/impl/AttributeRequesterEntityMatcherFunctor.cpp \ attribute/filtering/impl/AttributeScopeMatchesShibMDScopeFunctor.cpp \ + attribute/filtering/impl/RegistrationAuthorityFunctor.cpp \ attribute/resolver/impl/ChainingAttributeResolver.cpp \ attribute/resolver/impl/QueryAttributeResolver.cpp \ attribute/resolver/impl/SimpleAggregationAttributeResolver.cpp \ diff --git a/shibsp/attribute/filtering/MatchFunctor.h b/shibsp/attribute/filtering/MatchFunctor.h index a8f14c9..8b9ac58 100644 --- a/shibsp/attribute/filtering/MatchFunctor.h +++ b/shibsp/attribute/filtering/MatchFunctor.h @@ -152,6 +152,12 @@ namespace shibsp { /** Matches based on NameID NameQualifiers. */ extern SHIBSP_API xmltooling::QName NameIDQualifierStringType; + /** Matches based on RegistrationAuthority extension in issuer's metadata. */ + extern SHIBSP_API xmltooling::QName AttributeIssuerRegistrationAuthorityType; + + /** Matches based on RegistrationAuthority extension in requester's metadata. */ + extern SHIBSP_API xmltooling::QName RegistrationAuthorityType; + /** * Registers MatchFunctor classes into the runtime. */ diff --git a/shibsp/attribute/filtering/impl/MatchFunctor.cpp b/shibsp/attribute/filtering/impl/MatchFunctor.cpp index bb82c69..689989a 100644 --- a/shibsp/attribute/filtering/impl/MatchFunctor.cpp +++ b/shibsp/attribute/filtering/impl/MatchFunctor.cpp @@ -73,6 +73,8 @@ namespace shibsp { DECL_FACTORY(AttributeRequesterEntityMatcher); DECL_FACTORY(AttributeScopeMatchesShibMDScope); DECL_FACTORY(NameIDQualifierString); + DECL_FACTORY(AttributeIssuerRegistrationAuthority); + DECL_FACTORY(RegistrationAuthority); static const XMLCh ANY[] = UNICODE_LITERAL_3(A,N,Y); @@ -103,6 +105,8 @@ namespace shibsp { static const XMLCh AttributeRequesterEntityMatcher[] = UNICODE_LITERAL_31(A,t,t,r,i,b,u,t,e,R,e,q,u,e,s,t,e,r,E,n,t,i,t,y,M,a,t,c,h,e,r); static const XMLCh AttributeScopeMatchesShibMDScope[] = UNICODE_LITERAL_32(A,t,t,r,i,b,u,t,e,S,c,o,p,e,M,a,t,c,h,e,s,S,h,i,b,M,D,S,c,o,p,e); static const XMLCh NameIDQualifierString[] = UNICODE_LITERAL_21(N,a,m,e,I,D,Q,u,a,l,i,f,i,e,r,S,t,r,i,n,g); + static const XMLCh AttributeIssuerRegistrationAuthority[] = UNICODE_LITERAL_36(A,t,t,r,i,b,u,t,e,I,s,s,u,e,r,R,e,g,i,s,t,r,a,t,i,o,n,A,u,t,h,o,r,i,t,y); + static const XMLCh RegistrationAuthority[] = UNICODE_LITERAL_21(R,e,g,i,s,t,r,a,t,i,o,n,A,u,t,h,o,r,i,t,y); }; DECL_BASIC_QNAME(AnyMatchFunctor, ANY); @@ -133,6 +137,8 @@ DECL_SAML_QNAME(AttributeIssuerEntityMatcher, AttributeIssuerEntityMatcher); DECL_SAML_QNAME(AttributeRequesterEntityMatcher, AttributeRequesterEntityMatcher); DECL_SAML_QNAME(AttributeScopeMatchesShibMDScope, AttributeScopeMatchesShibMDScope); DECL_SAML_QNAME(NameIDQualifierString, NameIDQualifierString); +DECL_SAML_QNAME(AttributeIssuerRegistrationAuthority, AttributeIssuerRegistrationAuthority); +DECL_SAML_QNAME(RegistrationAuthority, RegistrationAuthority); void SHIBSP_API shibsp::registerMatchFunctors() { @@ -163,6 +169,8 @@ void SHIBSP_API shibsp::registerMatchFunctors() REGISTER_FACTORY(AttributeRequesterEntityMatcher); REGISTER_FACTORY(AttributeScopeMatchesShibMDScope); REGISTER_FACTORY(NameIDQualifierString); + REGISTER_FACTORY(AttributeIssuerRegistrationAuthority); + REGISTER_FACTORY(RegistrationAuthority); mgr.registerFactory(EntityAttributeExactMatchType, AttributeRequesterEntityAttributeExactMatchFactory); mgr.registerFactory(EntityAttributeRegexMatchType, AttributeRequesterEntityAttributeRegexMatchFactory); diff --git a/shibsp/attribute/filtering/impl/RegistrationAuthorityFunctor.cpp b/shibsp/attribute/filtering/impl/RegistrationAuthorityFunctor.cpp new file mode 100644 index 0000000..5b73652 --- /dev/null +++ b/shibsp/attribute/filtering/impl/RegistrationAuthorityFunctor.cpp @@ -0,0 +1,149 @@ +/** + * 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. + * + * 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 + * + * 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. + */ + +/** + * AttributeIssuerRegistrationAuthority.cpp + * + * A match function that evaluates to true if the attribute issuer's metadata includes + * a matching RegistrationAuthority extension. + */ + +#include "internal.h" +#include "exceptions.h" +#include "attribute/filtering/FilteringContext.h" +#include "attribute/filtering/FilterPolicyContext.h" +#include "attribute/filtering/MatchFunctor.h" + +#include +#include +#include +#include +#include +#include +#include + +using namespace opensaml::saml2md; +using namespace xmltooling; +using namespace boost::lambda; +using namespace boost; +using namespace std; + +namespace shibsp { + + static const XMLCh registrars[] = UNICODE_LITERAL_10(r,e,g,i,s,t,r,a,r,s); + static const XMLCh matchIfMetadataSilent[] = UNICODE_LITERAL_21(m,a,t,c,h,I,f,M,e,t,a,d,a,t,a,S,i,l,e,n,t); + + /** + * A match function base class that evaluates to true if the supplied metadata includes + * a matching RegistrationAuthority extension. + */ + class SHIBSP_DLLLOCAL AbstractRegistrationAuthorityFunctor : public MatchFunctor + { + bool m_matchIfMetadataSilent; + set m_registrars; + public: + AbstractRegistrationAuthorityFunctor(const DOMElement* e) + : m_matchIfMetadataSilent(XMLHelper::getAttrBool(e, false, matchIfMetadataSilent)) { + const XMLCh* prop = e ? e->getAttributeNS(nullptr,registrars) : nullptr; + if (!prop || !*prop) + throw ConfigurationException("AttributeIssuerRegistrationAuthorityFunctor MatchFunctor requires non-empty registrars attribute."); + auto_ptr_char regs(prop); + string dup(regs.get()); + split(m_registrars, dup, is_space(), algorithm::token_compress_on); + if (m_registrars.empty()) + throw ConfigurationException("AttributeIssuerRegistrationAuthorityFunctor MatchFunctor requires non-empty registrars attribute."); + } + + bool evaluatePolicyRequirement(const FilteringContext& filterContext) const { + const RoleDescriptor* issuer = getMetadata(filterContext); + if (!issuer) + return m_matchIfMetadataSilent; + + const EntityDescriptor* entity = dynamic_cast(issuer->getParent()); + const RegistrationInfo* info = getRegistrationInfo(entity->getExtensions()); + if (!info) { + const EntitiesDescriptor* group = dynamic_cast(entity->getParent()); + while (!info && group) { + info = getRegistrationInfo(group->getExtensions()); + group = dynamic_cast(group->getParent()); + } + } + + if (info) { + auto_ptr_char authority(info->getRegistrationAuthority()); + return authority.get() && m_registrars.find(authority.get()) != m_registrars.end(); + } + return m_matchIfMetadataSilent; + } + + bool evaluatePermitValue(const FilteringContext& filterContext, const Attribute& attribute, size_t index) const { + return evaluatePolicyRequirement(filterContext); + } + + protected: + virtual const RoleDescriptor* getMetadata(const FilteringContext& filterContext) const = 0; + + private: + const RegistrationInfo* getRegistrationInfo(const Extensions* extensions) const { + if (extensions) { + const vector& exts = extensions->getUnknownXMLObjects(); + const XMLObject* xo = find_if(exts, ll_dynamic_cast(_1) != ((RegistrationInfo*)nullptr)); + if (xo) { + return dynamic_cast(xo); + } + } + return nullptr; + } + }; + + class SHIBSP_DLLLOCAL AttributeIssuerRegistrationAuthorityFunctor : public AbstractRegistrationAuthorityFunctor + { + public: + AttributeIssuerRegistrationAuthorityFunctor(const DOMElement* e) : AbstractRegistrationAuthorityFunctor(e) {} + + protected: + const RoleDescriptor* getMetadata(const FilteringContext& filterContext) const { + return filterContext.getAttributeIssuerMetadata(); + } + }; + + class SHIBSP_DLLLOCAL AttributeRequesterRegistrationAuthorityFunctor : public AbstractRegistrationAuthorityFunctor + { + public: + AttributeRequesterRegistrationAuthorityFunctor(const DOMElement* e) : AbstractRegistrationAuthorityFunctor(e) {} + + protected: + const RoleDescriptor* getMetadata(const FilteringContext& filterContext) const { + return filterContext.getAttributeRequesterMetadata(); + } + }; + + + MatchFunctor* SHIBSP_DLLLOCAL AttributeIssuerRegistrationAuthorityFactory(const std::pair& p) + { + return new AttributeIssuerRegistrationAuthorityFunctor(p.second); + } + + MatchFunctor* SHIBSP_DLLLOCAL RegistrationAuthorityFactory(const std::pair& p) + { + return new AttributeRequesterRegistrationAuthorityFunctor(p.second); + } + +};