From: Scott Cantor Date: Tue, 21 Jun 2011 16:22:56 +0000 (+0000) Subject: Fix svn props X-Git-Tag: 2.4.3~16 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fcpp-sp.git;a=commitdiff_plain;h=deb366ac2ee049e1c36f4d7fc92a1735ea23d626 Fix svn props --- diff --git a/configs/example-shibboleth2.xml b/configs/example-shibboleth2.xml index 8ab846d..87066d4 100644 --- a/configs/example-shibboleth2.xml +++ b/configs/example-shibboleth2.xml @@ -1,270 +1,270 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/configs/protocols.xml b/configs/protocols.xml index 8a0164a..648bcbc 100644 --- a/configs/protocols.xml +++ b/configs/protocols.xml @@ -1,57 +1,57 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/configs/win-shibboleth2.xml b/configs/win-shibboleth2.xml index bacede7..68c0bfc 100644 --- a/configs/win-shibboleth2.xml +++ b/configs/win-shibboleth2.xml @@ -1,161 +1,161 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SAML2 SAML1 - - - - SAML2 Local - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SAML2 SAML1 + + + + SAML2 Local + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/schemas/shibboleth-2.0-native-sp-protocols.xsd b/schemas/shibboleth-2.0-native-sp-protocols.xsd index e613e32..63ae444 100644 --- a/schemas/shibboleth-2.0-native-sp-protocols.xsd +++ b/schemas/shibboleth-2.0-native-sp-protocols.xsd @@ -1,59 +1,59 @@ - - - - - - Schema for specifying protocols, services, and bindings, and defaults for the locations of handlers. - First appearing in Shibboleth 2.4 release. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + Schema for specifying protocols, services, and bindings, and defaults for the locations of handlers. + First appearing in Shibboleth 2.4 release. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/shibsp/attribute/filtering/impl/DummyAttributeFilter.cpp b/shibsp/attribute/filtering/impl/DummyAttributeFilter.cpp index f85f2df..d4f5660 100644 --- a/shibsp/attribute/filtering/impl/DummyAttributeFilter.cpp +++ b/shibsp/attribute/filtering/impl/DummyAttributeFilter.cpp @@ -16,47 +16,47 @@ * "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. - */ - -/** - * DummyAttributeFilter.cpp - * - * Pathological AttributeFilter that rejects all attributes. - */ - -#include "internal.h" -#include "attribute/Attribute.h" -#include "attribute/filtering/AttributeFilter.h" - -using namespace shibsp; -using namespace xmltooling; -using namespace std; - -namespace shibsp { - - class SHIBSP_DLLLOCAL DummyAttributeFilter : public AttributeFilter - { - public: - DummyAttributeFilter(const DOMElement* e) { - } - virtual ~DummyAttributeFilter() { - } - - Lockable* lock() { - return this; - } - void unlock() { - } - - void filterAttributes(const FilteringContext& context, vector& attributes) const { - Category::getInstance(SHIBSP_LOGCAT".AttributeFilter.Dummy").warn("filtering out all attributes"); - for_each(attributes.begin(), attributes.end(), xmltooling::cleanup()); - attributes.clear(); - } - }; - - AttributeFilter* SHIBSP_DLLLOCAL DummyAttributeFilterFactory(const DOMElement* const & e) - { - return new DummyAttributeFilter(e); - } -}; + */ + +/** + * DummyAttributeFilter.cpp + * + * Pathological AttributeFilter that rejects all attributes. + */ + +#include "internal.h" +#include "attribute/Attribute.h" +#include "attribute/filtering/AttributeFilter.h" + +using namespace shibsp; +using namespace xmltooling; +using namespace std; + +namespace shibsp { + + class SHIBSP_DLLLOCAL DummyAttributeFilter : public AttributeFilter + { + public: + DummyAttributeFilter(const DOMElement* e) { + } + virtual ~DummyAttributeFilter() { + } + + Lockable* lock() { + return this; + } + void unlock() { + } + + void filterAttributes(const FilteringContext& context, vector& attributes) const { + Category::getInstance(SHIBSP_LOGCAT".AttributeFilter.Dummy").warn("filtering out all attributes"); + for_each(attributes.begin(), attributes.end(), xmltooling::cleanup()); + attributes.clear(); + } + }; + + AttributeFilter* SHIBSP_DLLLOCAL DummyAttributeFilterFactory(const DOMElement* const & e) + { + return new DummyAttributeFilter(e); + } +}; diff --git a/shibsp/attribute/filtering/impl/NameIDQualifierStringFunctor.cpp b/shibsp/attribute/filtering/impl/NameIDQualifierStringFunctor.cpp index 0182c05..daaa692 100644 --- a/shibsp/attribute/filtering/impl/NameIDQualifierStringFunctor.cpp +++ b/shibsp/attribute/filtering/impl/NameIDQualifierStringFunctor.cpp @@ -16,158 +16,158 @@ * "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. - */ - -/** - * NameIDQualifierStringFunctor.cpp - * - * A match function that ensures that a NameID-valued attribute's qualifier(s) - * match particular values. - */ - -#include "internal.h" -#include "exceptions.h" -#include "attribute/NameIDAttribute.h" -#include "attribute/filtering/FilteringContext.h" -#include "attribute/filtering/FilterPolicyContext.h" -#include "attribute/filtering/MatchFunctor.h" - -#include -#include - -using namespace shibsp; -using namespace xmltooling::logging; -using namespace xmltooling; -using namespace std; -using opensaml::saml2::NameID; - -namespace shibsp { - - static const XMLCh attributeID[] = UNICODE_LITERAL_11(a,t,t,r,i,b,u,t,e,I,D); - - /** - * A match function that ensures that a NameID-valued attribute's qualifier(s) - * match particular values. - */ - class SHIBSP_DLLLOCAL NameIDQualifierStringFunctor : public MatchFunctor - { - string m_attributeID,m_matchNameQualifier,m_matchSPNameQualifier; - - bool hasValue(const FilteringContext& filterContext) const; - bool matches(const FilteringContext& filterContext, const Attribute& attribute, size_t index) const; - - public: - NameIDQualifierStringFunctor(const DOMElement* e) - : m_attributeID(XMLHelper::getAttrString(e, nullptr, attributeID)), - m_matchNameQualifier(XMLHelper::getAttrString(e, nullptr, NameID::NAMEQUALIFIER_ATTRIB_NAME)), - m_matchSPNameQualifier(XMLHelper::getAttrString(e, nullptr, NameID::SPNAMEQUALIFIER_ATTRIB_NAME)) { - } - - virtual ~NameIDQualifierStringFunctor() { - } - - bool evaluatePolicyRequirement(const FilteringContext& filterContext) const { - if (m_attributeID.empty()) - throw AttributeFilteringException("No attributeID specified."); - return hasValue(filterContext); - } - - bool evaluatePermitValue(const FilteringContext& filterContext, const Attribute& attribute, size_t index) const { - if (m_attributeID.empty() || m_attributeID == attribute.getId()) - return matches(filterContext, attribute, index); - return hasValue(filterContext); - } - }; - - MatchFunctor* SHIBSP_DLLLOCAL NameIDQualifierStringFactory(const std::pair& p) - { - return new NameIDQualifierStringFunctor(p.second); - } - -}; - -bool NameIDQualifierStringFunctor::hasValue(const FilteringContext& filterContext) const -{ - size_t count; - pair::const_iterator,multimap::const_iterator> attrs = - filterContext.getAttributes().equal_range(m_attributeID); - for (; attrs.first != attrs.second; ++attrs.first) { - count = attrs.first->second->valueCount(); - for (size_t index = 0; index < count; ++index) { - if (matches(filterContext, *(attrs.first->second), index)) - return true; - } - } - return false; -} - -bool NameIDQualifierStringFunctor::matches(const FilteringContext& filterContext, const Attribute& attribute, size_t index) const -{ - const NameIDAttribute* nameattr = dynamic_cast(&attribute); - if (!nameattr) { - Category::getInstance(SHIBSP_LOGCAT".AttributeFilter").warn( - "NameIDQualifierString MatchFunctor applied to non-NameID-valued attribute (%s)", attribute.getId() - ); - return false; - } - - const NameIDAttribute::Value& val = nameattr->getValues()[index]; - if (!val.m_NameQualifier.empty()) { - if (m_matchNameQualifier.empty()) { - auto_ptr_char issuer(filterContext.getAttributeIssuer()); - if (issuer.get() && *issuer.get()) { - if (val.m_NameQualifier != issuer.get()) { - Category::getInstance(SHIBSP_LOGCAT".AttributeFilter").warn( - "NameIDQualifierString MatchFunctor rejecting NameQualifier (%s), should be (%s)", - val.m_NameQualifier.c_str(), issuer.get() - ); - return false; - } - } - else { - Category::getInstance(SHIBSP_LOGCAT".AttributeFilter").warn( - "NameIDQualifierString MatchFunctor rejecting NameQualifier (%s), attribute issuer unknown", - val.m_NameQualifier.c_str() - ); - return false; - } - } - else if (m_matchNameQualifier != val.m_NameQualifier) { - Category::getInstance(SHIBSP_LOGCAT".AttributeFilter").warn( - "NameIDQualifierString MatchFunctor rejecting NameQualifier (%s), should be (%s)", - val.m_NameQualifier.c_str(), m_matchNameQualifier.c_str() - ); - return false; - } - } - if (!val.m_SPNameQualifier.empty()) { - if (m_matchSPNameQualifier.empty()) { - auto_ptr_char req(filterContext.getAttributeRequester()); - if (req.get() && *req.get()) { - if (val.m_SPNameQualifier != req.get()) { - Category::getInstance(SHIBSP_LOGCAT".AttributeFilter").warn( - "NameIDQualifierString MatchFunctor rejecting SPNameQualifier (%s), should be (%s)", - val.m_SPNameQualifier.c_str(), req.get() - ); - return false; - } - } - else { - Category::getInstance(SHIBSP_LOGCAT".AttributeFilter").warn( - "NameIDQualifierString MatchFunctor rejecting SPNameQualifier (%s), attribute requester unknown", - val.m_SPNameQualifier.c_str() - ); - return false; - } - } - else if (m_matchSPNameQualifier != val.m_SPNameQualifier) { - Category::getInstance(SHIBSP_LOGCAT".AttributeFilter").warn( - "NameIDQualifierString MatchFunctor rejecting SPNameQualifier (%s), should be (%s)", - val.m_SPNameQualifier.c_str(), m_matchSPNameQualifier.c_str() - ); - return false; - } - } - - return true; -} + */ + +/** + * NameIDQualifierStringFunctor.cpp + * + * A match function that ensures that a NameID-valued attribute's qualifier(s) + * match particular values. + */ + +#include "internal.h" +#include "exceptions.h" +#include "attribute/NameIDAttribute.h" +#include "attribute/filtering/FilteringContext.h" +#include "attribute/filtering/FilterPolicyContext.h" +#include "attribute/filtering/MatchFunctor.h" + +#include +#include + +using namespace shibsp; +using namespace xmltooling::logging; +using namespace xmltooling; +using namespace std; +using opensaml::saml2::NameID; + +namespace shibsp { + + static const XMLCh attributeID[] = UNICODE_LITERAL_11(a,t,t,r,i,b,u,t,e,I,D); + + /** + * A match function that ensures that a NameID-valued attribute's qualifier(s) + * match particular values. + */ + class SHIBSP_DLLLOCAL NameIDQualifierStringFunctor : public MatchFunctor + { + string m_attributeID,m_matchNameQualifier,m_matchSPNameQualifier; + + bool hasValue(const FilteringContext& filterContext) const; + bool matches(const FilteringContext& filterContext, const Attribute& attribute, size_t index) const; + + public: + NameIDQualifierStringFunctor(const DOMElement* e) + : m_attributeID(XMLHelper::getAttrString(e, nullptr, attributeID)), + m_matchNameQualifier(XMLHelper::getAttrString(e, nullptr, NameID::NAMEQUALIFIER_ATTRIB_NAME)), + m_matchSPNameQualifier(XMLHelper::getAttrString(e, nullptr, NameID::SPNAMEQUALIFIER_ATTRIB_NAME)) { + } + + virtual ~NameIDQualifierStringFunctor() { + } + + bool evaluatePolicyRequirement(const FilteringContext& filterContext) const { + if (m_attributeID.empty()) + throw AttributeFilteringException("No attributeID specified."); + return hasValue(filterContext); + } + + bool evaluatePermitValue(const FilteringContext& filterContext, const Attribute& attribute, size_t index) const { + if (m_attributeID.empty() || m_attributeID == attribute.getId()) + return matches(filterContext, attribute, index); + return hasValue(filterContext); + } + }; + + MatchFunctor* SHIBSP_DLLLOCAL NameIDQualifierStringFactory(const std::pair& p) + { + return new NameIDQualifierStringFunctor(p.second); + } + +}; + +bool NameIDQualifierStringFunctor::hasValue(const FilteringContext& filterContext) const +{ + size_t count; + pair::const_iterator,multimap::const_iterator> attrs = + filterContext.getAttributes().equal_range(m_attributeID); + for (; attrs.first != attrs.second; ++attrs.first) { + count = attrs.first->second->valueCount(); + for (size_t index = 0; index < count; ++index) { + if (matches(filterContext, *(attrs.first->second), index)) + return true; + } + } + return false; +} + +bool NameIDQualifierStringFunctor::matches(const FilteringContext& filterContext, const Attribute& attribute, size_t index) const +{ + const NameIDAttribute* nameattr = dynamic_cast(&attribute); + if (!nameattr) { + Category::getInstance(SHIBSP_LOGCAT".AttributeFilter").warn( + "NameIDQualifierString MatchFunctor applied to non-NameID-valued attribute (%s)", attribute.getId() + ); + return false; + } + + const NameIDAttribute::Value& val = nameattr->getValues()[index]; + if (!val.m_NameQualifier.empty()) { + if (m_matchNameQualifier.empty()) { + auto_ptr_char issuer(filterContext.getAttributeIssuer()); + if (issuer.get() && *issuer.get()) { + if (val.m_NameQualifier != issuer.get()) { + Category::getInstance(SHIBSP_LOGCAT".AttributeFilter").warn( + "NameIDQualifierString MatchFunctor rejecting NameQualifier (%s), should be (%s)", + val.m_NameQualifier.c_str(), issuer.get() + ); + return false; + } + } + else { + Category::getInstance(SHIBSP_LOGCAT".AttributeFilter").warn( + "NameIDQualifierString MatchFunctor rejecting NameQualifier (%s), attribute issuer unknown", + val.m_NameQualifier.c_str() + ); + return false; + } + } + else if (m_matchNameQualifier != val.m_NameQualifier) { + Category::getInstance(SHIBSP_LOGCAT".AttributeFilter").warn( + "NameIDQualifierString MatchFunctor rejecting NameQualifier (%s), should be (%s)", + val.m_NameQualifier.c_str(), m_matchNameQualifier.c_str() + ); + return false; + } + } + if (!val.m_SPNameQualifier.empty()) { + if (m_matchSPNameQualifier.empty()) { + auto_ptr_char req(filterContext.getAttributeRequester()); + if (req.get() && *req.get()) { + if (val.m_SPNameQualifier != req.get()) { + Category::getInstance(SHIBSP_LOGCAT".AttributeFilter").warn( + "NameIDQualifierString MatchFunctor rejecting SPNameQualifier (%s), should be (%s)", + val.m_SPNameQualifier.c_str(), req.get() + ); + return false; + } + } + else { + Category::getInstance(SHIBSP_LOGCAT".AttributeFilter").warn( + "NameIDQualifierString MatchFunctor rejecting SPNameQualifier (%s), attribute requester unknown", + val.m_SPNameQualifier.c_str() + ); + return false; + } + } + else if (m_matchSPNameQualifier != val.m_SPNameQualifier) { + Category::getInstance(SHIBSP_LOGCAT".AttributeFilter").warn( + "NameIDQualifierString MatchFunctor rejecting SPNameQualifier (%s), should be (%s)", + val.m_SPNameQualifier.c_str(), m_matchSPNameQualifier.c_str() + ); + return false; + } + } + + return true; +} diff --git a/shibsp/binding/ProtocolProvider.h b/shibsp/binding/ProtocolProvider.h index b8501b9..69c5ad1 100644 --- a/shibsp/binding/ProtocolProvider.h +++ b/shibsp/binding/ProtocolProvider.h @@ -16,63 +16,63 @@ * "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. - */ - -/** - * @file shibsp/binding/ProtocolProvider.h - * - * Interface to protocol, binding, and default endpoint information. - */ - -#ifndef __shibsp_protprov_h__ -#define __shibsp_protprov_h__ - -#include - -#include -#include - -namespace shibsp { - - class SHIBSP_API PropertySet; - - /** - * Interface to protocol, binding, and default endpoint information. - */ - class SHIBSP_API ProtocolProvider : public virtual xmltooling::Lockable - { - MAKE_NONCOPYABLE(ProtocolProvider); - protected: - ProtocolProvider(); - public: - virtual ~ProtocolProvider(); - - /** - * Returns configuration details for initiating a protocol service, as a PropertySet. - * - * @param protocol the name of a protocol - * @param service the name of a service - * @return a PropertySet associated with initiation/request of a service - */ - virtual const PropertySet* getInitiator(const char* protocol, const char* service) const=0; - - /** - * Returns an ordered array of protocol bindings available for a specified service. - * - * @param protocol the name of a protocol - * @param service name of the protocol service - * @return the array of bindings, each represented as a PropertySet - */ - virtual const std::vector& getBindings(const char* protocol, const char* service) const=0; - }; - - /** - * Registers ProtocolProvider classes into the runtime. - */ - void SHIBSP_API registerProtocolProviders(); - - /** ProtocolProvider based on an XML configuration format. */ - #define XML_PROTOCOL_PROVIDER "XML" -}; - -#endif /* __shibsp_protprov_h__ */ + */ + +/** + * @file shibsp/binding/ProtocolProvider.h + * + * Interface to protocol, binding, and default endpoint information. + */ + +#ifndef __shibsp_protprov_h__ +#define __shibsp_protprov_h__ + +#include + +#include +#include + +namespace shibsp { + + class SHIBSP_API PropertySet; + + /** + * Interface to protocol, binding, and default endpoint information. + */ + class SHIBSP_API ProtocolProvider : public virtual xmltooling::Lockable + { + MAKE_NONCOPYABLE(ProtocolProvider); + protected: + ProtocolProvider(); + public: + virtual ~ProtocolProvider(); + + /** + * Returns configuration details for initiating a protocol service, as a PropertySet. + * + * @param protocol the name of a protocol + * @param service the name of a service + * @return a PropertySet associated with initiation/request of a service + */ + virtual const PropertySet* getInitiator(const char* protocol, const char* service) const=0; + + /** + * Returns an ordered array of protocol bindings available for a specified service. + * + * @param protocol the name of a protocol + * @param service name of the protocol service + * @return the array of bindings, each represented as a PropertySet + */ + virtual const std::vector& getBindings(const char* protocol, const char* service) const=0; + }; + + /** + * Registers ProtocolProvider classes into the runtime. + */ + void SHIBSP_API registerProtocolProviders(); + + /** ProtocolProvider based on an XML configuration format. */ + #define XML_PROTOCOL_PROVIDER "XML" +}; + +#endif /* __shibsp_protprov_h__ */ diff --git a/shibsp/binding/impl/XMLProtocolProvider.cpp b/shibsp/binding/impl/XMLProtocolProvider.cpp index 93399dd..907c1ff 100644 --- a/shibsp/binding/impl/XMLProtocolProvider.cpp +++ b/shibsp/binding/impl/XMLProtocolProvider.cpp @@ -16,225 +16,225 @@ * "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. - */ - -/** - * XMLProtocolProvider.cpp - * - * XML-based protocol provider. - */ - -#include "internal.h" -#include "exceptions.h" -#include "binding/ProtocolProvider.h" -#include "util/DOMPropertySet.h" -#include "util/SPConstants.h" - -#include -#include -#include -#include -#include -#include -#include - -using shibspconstants::SHIB2SPPROTOCOLS_NS; -using namespace shibsp; -using namespace xmltooling; -using namespace std; - -namespace shibsp { - - static const XMLCh _id[] = UNICODE_LITERAL_2(i,d); - static const XMLCh Binding[] = UNICODE_LITERAL_7(B,i,n,d,i,n,g); - static const XMLCh Initiator[] = UNICODE_LITERAL_9(I,n,i,t,i,a,t,o,r); - static const XMLCh Protocol[] = UNICODE_LITERAL_8(P,r,o,t,o,c,o,l); - static const XMLCh Protocols[] = UNICODE_LITERAL_9(P,r,o,t,o,c,o,l,s); - static const XMLCh Service[] = UNICODE_LITERAL_7(S,e,r,v,i,c,e); - -#if defined (_MSC_VER) - #pragma warning( push ) - #pragma warning( disable : 4250 ) -#endif - - class SHIBSP_DLLLOCAL XMLProtocolProviderImpl : public DOMNodeFilter, DOMPropertySet - { - public: - XMLProtocolProviderImpl(const DOMElement* e, Category& log); - ~XMLProtocolProviderImpl() { - for (protmap_t::iterator i = m_map.begin(); i != m_map.end(); ++i) { - delete i->second.first; - for_each(i->second.second.begin(), i->second.second.end(), xmltooling::cleanup()); - } - if (m_document) - m_document->release(); - } - - void setDocument(DOMDocument* doc) { - m_document = doc; - } - -#ifdef SHIBSP_XERCESC_SHORT_ACCEPTNODE - short -#else - FilterAction -#endif - acceptNode(const DOMNode* node) const { - return FILTER_REJECT; - } - - private: - DOMDocument* m_document; - // Map of protocol/service pair to an Initiator propset plus an array of Binding propsets. - typedef map< pair, pair< PropertySet*,vector > > protmap_t; - protmap_t m_map; - - friend class SHIBSP_DLLLOCAL XMLProtocolProvider; - }; - - class XMLProtocolProvider : public ProtocolProvider, public ReloadableXMLFile - { - public: - XMLProtocolProvider(const DOMElement* e) - : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT".ProtocolProvider.XML")), m_impl(nullptr) { - background_load(); // guarantees an exception or the policy is loaded - } - - ~XMLProtocolProvider() { - shutdown(); - delete m_impl; - } - - const PropertySet* getInitiator(const char* protocol, const char* service) const { - XMLProtocolProviderImpl::protmap_t::const_iterator i = m_impl->m_map.find(pair(protocol,service)); - return (i != m_impl->m_map.end()) ? i->second.first : nullptr; - } - - const vector& getBindings(const char* protocol, const char* service) const { - XMLProtocolProviderImpl::protmap_t::const_iterator i = m_impl->m_map.find(pair(protocol,service)); - return (i != m_impl->m_map.end()) ? i->second.second : m_noBindings; - } - - protected: - pair load(bool backup); - pair background_load(); - - private: - static vector m_noBindings; - XMLProtocolProviderImpl* m_impl; - }; - -#if defined (_MSC_VER) - #pragma warning( pop ) -#endif - - ProtocolProvider* SHIBSP_DLLLOCAL XMLProtocolProviderFactory(const DOMElement* const & e) - { - return new XMLProtocolProvider(e); - } -} - -void SHIBSP_API shibsp::registerProtocolProviders() -{ - SPConfig::getConfig().ProtocolProviderManager.registerFactory(XML_PROTOCOL_PROVIDER, XMLProtocolProviderFactory); -} - -ProtocolProvider::ProtocolProvider() -{ -} - -ProtocolProvider::~ProtocolProvider() -{ -} - -vector XMLProtocolProvider::m_noBindings; - -XMLProtocolProviderImpl::XMLProtocolProviderImpl(const DOMElement* e, Category& log) : m_document(nullptr) -{ -#ifdef _DEBUG - xmltooling::NDC ndc("XMLProtocolProviderImpl"); -#endif - //typedef map< pair, pair< PropertySet*,vector > > protmap_t; - - if (!XMLHelper::isNodeNamed(e, SHIB2SPPROTOCOLS_NS, Protocols)) - throw ConfigurationException("XML ProtocolProvider requires prot:Protocols at root of configuration."); - - e = XMLHelper::getFirstChildElement(e, SHIB2SPPROTOCOLS_NS, Protocol); - while (e) { - string id = XMLHelper::getAttrString(e, nullptr, _id); - if (!id.empty()) { - const DOMElement* svc = XMLHelper::getFirstChildElement(e, SHIB2SPPROTOCOLS_NS, Service); - while (svc) { - string svcid = XMLHelper::getAttrString(svc, nullptr, _id); - if (!svcid.empty() && m_map.count(make_pair(id,svcid)) == 0) { - pair< PropertySet*,vector >& entry = m_map[make_pair(id,svcid)]; - // Wrap the Initiator in a propset, if any. - const DOMElement* child = XMLHelper::getFirstChildElement(svc, SHIB2SPPROTOCOLS_NS, Initiator); - if (child) { - DOMPropertySet* initprop = new DOMPropertySet(); - entry.first = initprop; - initprop->load(child, nullptr, this); - } - else { - entry.first = nullptr; - } - - // Walk the Bindings. - child = XMLHelper::getFirstChildElement(svc, SHIB2SPPROTOCOLS_NS, Binding); - while (child) { - DOMPropertySet* bindprop = new DOMPropertySet(); - entry.second.push_back(bindprop); - bindprop->load(child, nullptr, this); - child = XMLHelper::getNextSiblingElement(child, SHIB2SPPROTOCOLS_NS, Binding); - } - } - svc = XMLHelper::getNextSiblingElement(svc, SHIB2SPPROTOCOLS_NS, Service); - } - } - e = XMLHelper::getNextSiblingElement(e, SHIB2SPPROTOCOLS_NS, Protocol); - } -} - - -pair XMLProtocolProvider::load(bool backup) -{ - // Load from source using base class. - pair raw = ReloadableXMLFile::load(backup); - - // If we own it, wrap it. - XercesJanitor docjanitor(raw.first ? raw.second->getOwnerDocument() : nullptr); - - XMLProtocolProviderImpl* impl = new XMLProtocolProviderImpl(raw.second, m_log); - - // If we held the document, transfer it to the impl. If we didn't, it's a no-op. - impl->setDocument(docjanitor.release()); - - // Perform the swap inside a lock. - if (m_lock) - m_lock->wrlock(); - SharedLock locker(m_lock, false); - delete m_impl; - m_impl = impl; - - - return make_pair(false,(DOMElement*)nullptr); -} - -pair XMLProtocolProvider::background_load() -{ - try { - return load(false); - } - catch (long& ex) { - if (ex == HTTPResponse::XMLTOOLING_HTTP_STATUS_NOTMODIFIED) - m_log.info("remote resource (%s) unchanged", m_source.c_str()); - if (!m_loaded && !m_backing.empty()) - return load(true); - throw; - } - catch (exception&) { - if (!m_loaded && !m_backing.empty()) - return load(true); - throw; - } -} + */ + +/** + * XMLProtocolProvider.cpp + * + * XML-based protocol provider. + */ + +#include "internal.h" +#include "exceptions.h" +#include "binding/ProtocolProvider.h" +#include "util/DOMPropertySet.h" +#include "util/SPConstants.h" + +#include +#include +#include +#include +#include +#include +#include + +using shibspconstants::SHIB2SPPROTOCOLS_NS; +using namespace shibsp; +using namespace xmltooling; +using namespace std; + +namespace shibsp { + + static const XMLCh _id[] = UNICODE_LITERAL_2(i,d); + static const XMLCh Binding[] = UNICODE_LITERAL_7(B,i,n,d,i,n,g); + static const XMLCh Initiator[] = UNICODE_LITERAL_9(I,n,i,t,i,a,t,o,r); + static const XMLCh Protocol[] = UNICODE_LITERAL_8(P,r,o,t,o,c,o,l); + static const XMLCh Protocols[] = UNICODE_LITERAL_9(P,r,o,t,o,c,o,l,s); + static const XMLCh Service[] = UNICODE_LITERAL_7(S,e,r,v,i,c,e); + +#if defined (_MSC_VER) + #pragma warning( push ) + #pragma warning( disable : 4250 ) +#endif + + class SHIBSP_DLLLOCAL XMLProtocolProviderImpl : public DOMNodeFilter, DOMPropertySet + { + public: + XMLProtocolProviderImpl(const DOMElement* e, Category& log); + ~XMLProtocolProviderImpl() { + for (protmap_t::iterator i = m_map.begin(); i != m_map.end(); ++i) { + delete i->second.first; + for_each(i->second.second.begin(), i->second.second.end(), xmltooling::cleanup()); + } + if (m_document) + m_document->release(); + } + + void setDocument(DOMDocument* doc) { + m_document = doc; + } + +#ifdef SHIBSP_XERCESC_SHORT_ACCEPTNODE + short +#else + FilterAction +#endif + acceptNode(const DOMNode* node) const { + return FILTER_REJECT; + } + + private: + DOMDocument* m_document; + // Map of protocol/service pair to an Initiator propset plus an array of Binding propsets. + typedef map< pair, pair< PropertySet*,vector > > protmap_t; + protmap_t m_map; + + friend class SHIBSP_DLLLOCAL XMLProtocolProvider; + }; + + class XMLProtocolProvider : public ProtocolProvider, public ReloadableXMLFile + { + public: + XMLProtocolProvider(const DOMElement* e) + : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT".ProtocolProvider.XML")), m_impl(nullptr) { + background_load(); // guarantees an exception or the policy is loaded + } + + ~XMLProtocolProvider() { + shutdown(); + delete m_impl; + } + + const PropertySet* getInitiator(const char* protocol, const char* service) const { + XMLProtocolProviderImpl::protmap_t::const_iterator i = m_impl->m_map.find(pair(protocol,service)); + return (i != m_impl->m_map.end()) ? i->second.first : nullptr; + } + + const vector& getBindings(const char* protocol, const char* service) const { + XMLProtocolProviderImpl::protmap_t::const_iterator i = m_impl->m_map.find(pair(protocol,service)); + return (i != m_impl->m_map.end()) ? i->second.second : m_noBindings; + } + + protected: + pair load(bool backup); + pair background_load(); + + private: + static vector m_noBindings; + XMLProtocolProviderImpl* m_impl; + }; + +#if defined (_MSC_VER) + #pragma warning( pop ) +#endif + + ProtocolProvider* SHIBSP_DLLLOCAL XMLProtocolProviderFactory(const DOMElement* const & e) + { + return new XMLProtocolProvider(e); + } +} + +void SHIBSP_API shibsp::registerProtocolProviders() +{ + SPConfig::getConfig().ProtocolProviderManager.registerFactory(XML_PROTOCOL_PROVIDER, XMLProtocolProviderFactory); +} + +ProtocolProvider::ProtocolProvider() +{ +} + +ProtocolProvider::~ProtocolProvider() +{ +} + +vector XMLProtocolProvider::m_noBindings; + +XMLProtocolProviderImpl::XMLProtocolProviderImpl(const DOMElement* e, Category& log) : m_document(nullptr) +{ +#ifdef _DEBUG + xmltooling::NDC ndc("XMLProtocolProviderImpl"); +#endif + //typedef map< pair, pair< PropertySet*,vector > > protmap_t; + + if (!XMLHelper::isNodeNamed(e, SHIB2SPPROTOCOLS_NS, Protocols)) + throw ConfigurationException("XML ProtocolProvider requires prot:Protocols at root of configuration."); + + e = XMLHelper::getFirstChildElement(e, SHIB2SPPROTOCOLS_NS, Protocol); + while (e) { + string id = XMLHelper::getAttrString(e, nullptr, _id); + if (!id.empty()) { + const DOMElement* svc = XMLHelper::getFirstChildElement(e, SHIB2SPPROTOCOLS_NS, Service); + while (svc) { + string svcid = XMLHelper::getAttrString(svc, nullptr, _id); + if (!svcid.empty() && m_map.count(make_pair(id,svcid)) == 0) { + pair< PropertySet*,vector >& entry = m_map[make_pair(id,svcid)]; + // Wrap the Initiator in a propset, if any. + const DOMElement* child = XMLHelper::getFirstChildElement(svc, SHIB2SPPROTOCOLS_NS, Initiator); + if (child) { + DOMPropertySet* initprop = new DOMPropertySet(); + entry.first = initprop; + initprop->load(child, nullptr, this); + } + else { + entry.first = nullptr; + } + + // Walk the Bindings. + child = XMLHelper::getFirstChildElement(svc, SHIB2SPPROTOCOLS_NS, Binding); + while (child) { + DOMPropertySet* bindprop = new DOMPropertySet(); + entry.second.push_back(bindprop); + bindprop->load(child, nullptr, this); + child = XMLHelper::getNextSiblingElement(child, SHIB2SPPROTOCOLS_NS, Binding); + } + } + svc = XMLHelper::getNextSiblingElement(svc, SHIB2SPPROTOCOLS_NS, Service); + } + } + e = XMLHelper::getNextSiblingElement(e, SHIB2SPPROTOCOLS_NS, Protocol); + } +} + + +pair XMLProtocolProvider::load(bool backup) +{ + // Load from source using base class. + pair raw = ReloadableXMLFile::load(backup); + + // If we own it, wrap it. + XercesJanitor docjanitor(raw.first ? raw.second->getOwnerDocument() : nullptr); + + XMLProtocolProviderImpl* impl = new XMLProtocolProviderImpl(raw.second, m_log); + + // If we held the document, transfer it to the impl. If we didn't, it's a no-op. + impl->setDocument(docjanitor.release()); + + // Perform the swap inside a lock. + if (m_lock) + m_lock->wrlock(); + SharedLock locker(m_lock, false); + delete m_impl; + m_impl = impl; + + + return make_pair(false,(DOMElement*)nullptr); +} + +pair XMLProtocolProvider::background_load() +{ + try { + return load(false); + } + catch (long& ex) { + if (ex == HTTPResponse::XMLTOOLING_HTTP_STATUS_NOTMODIFIED) + m_log.info("remote resource (%s) unchanged", m_source.c_str()); + if (!m_loaded && !m_backing.empty()) + return load(true); + throw; + } + catch (exception&) { + if (!m_loaded && !m_backing.empty()) + return load(true); + throw; + } +} diff --git a/shibsp/impl/XMLSecurityPolicyProvider.cpp b/shibsp/impl/XMLSecurityPolicyProvider.cpp index d9aee64..ac31af0 100644 --- a/shibsp/impl/XMLSecurityPolicyProvider.cpp +++ b/shibsp/impl/XMLSecurityPolicyProvider.cpp @@ -16,301 +16,301 @@ * "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. - */ - -/** - * XMLSecurityPolicyProvider.cpp - * - * XML-based security policy provider. - */ - -#include "internal.h" -#include "exceptions.h" -#include "Application.h" -#include "security/SecurityPolicy.h" -#include "security/SecurityPolicyProvider.h" -#include "util/DOMPropertySet.h" -#include "util/SPConstants.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using shibspconstants::SHIB2SPCONFIG_NS; -using opensaml::SAMLConfig; -using opensaml::SecurityPolicyRule; -using namespace shibsp; -using namespace xmltooling; -using namespace std; - -namespace shibsp { - -#if defined (_MSC_VER) - #pragma warning( push ) - #pragma warning( disable : 4250 ) -#endif - - class SHIBSP_DLLLOCAL XMLSecurityPolicyProviderImpl - { - public: - XMLSecurityPolicyProviderImpl(const DOMElement* e, Category& log); - ~XMLSecurityPolicyProviderImpl() { - for (map< string,pair > >::iterator i = m_policyMap.begin(); i != m_policyMap.end(); ++i) { - delete i->second.first; - for_each(i->second.second.begin(), i->second.second.end(), xmltooling::cleanup()); - } - if (m_document) - m_document->release(); - } - - void setDocument(DOMDocument* doc) { - m_document = doc; - } - - private: - DOMDocument* m_document; - vector m_whitelist,m_blacklist; - map< string,pair< PropertySet*,vector > > m_policyMap; - map< string,pair< PropertySet*,vector > >::const_iterator m_defaultPolicy; - - friend class SHIBSP_DLLLOCAL XMLSecurityPolicyProvider; - }; - - class XMLSecurityPolicyProvider : public SecurityPolicyProvider, public ReloadableXMLFile - { - public: - XMLSecurityPolicyProvider(const DOMElement* e) - : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT".SecurityPolicyProvider.XML")), m_impl(nullptr) { - background_load(); // guarantees an exception or the policy is loaded - } - - ~XMLSecurityPolicyProvider() { - shutdown(); - delete m_impl; - } - - const PropertySet* getPolicySettings(const char* id=nullptr) const { - if (!id || !*id) - return m_impl->m_defaultPolicy->second.first; - map > >::const_iterator i = m_impl->m_policyMap.find(id); - if (i != m_impl->m_policyMap.end()) - return i->second.first; - throw ConfigurationException("Security Policy ($1) not found, check element.", params(1,id)); - } - - const vector& getPolicyRules(const char* id=nullptr) const { - if (!id || !*id) - return m_impl->m_defaultPolicy->second.second; - map > >::const_iterator i = m_impl->m_policyMap.find(id); - if (i != m_impl->m_policyMap.end()) - return i->second.second; - throw ConfigurationException("Security Policy ($1) not found, check element.", params(1,id)); - } - const vector& getAlgorithmBlacklist() const { - return m_impl->m_blacklist; - } - const vector& getAlgorithmWhitelist() const { - return m_impl->m_whitelist; - } - - protected: - pair load(bool backup); - pair background_load(); - - private: - XMLSecurityPolicyProviderImpl* m_impl; - }; - -#if defined (_MSC_VER) - #pragma warning( pop ) -#endif - - SecurityPolicyProvider* SHIBSP_DLLLOCAL XMLSecurityPolicyProviderFactory(const DOMElement* const & e) - { - return new XMLSecurityPolicyProvider(e); - } - - class SHIBSP_DLLLOCAL PolicyNodeFilter : public DOMNodeFilter - { - public: -#ifdef SHIBSP_XERCESC_SHORT_ACCEPTNODE - short -#else - FilterAction -#endif - acceptNode(const DOMNode* node) const { - return FILTER_REJECT; - } - }; - - static const XMLCh _id[] = UNICODE_LITERAL_2(i,d); - static const XMLCh _type[] = UNICODE_LITERAL_4(t,y,p,e); - static const XMLCh AlgorithmBlacklist[] = UNICODE_LITERAL_18(A,l,g,o,r,i,t,h,m,B,l,a,c,k,l,i,s,t); - static const XMLCh AlgorithmWhitelist[] = UNICODE_LITERAL_18(A,l,g,o,r,i,t,h,m,W,h,i,t,e,l,i,s,t); - static const XMLCh Policy[] = UNICODE_LITERAL_6(P,o,l,i,c,y); - static const XMLCh PolicyRule[] = UNICODE_LITERAL_10(P,o,l,i,c,y,R,u,l,e); - static const XMLCh Rule[] = UNICODE_LITERAL_4(R,u,l,e); - static const XMLCh SecurityPolicies[] = UNICODE_LITERAL_16(S,e,c,u,r,i,t,y,P,o,l,i,c,i,e,s); -} - -void SHIBSP_API shibsp::registerSecurityPolicyProviders() -{ - SPConfig::getConfig().SecurityPolicyProviderManager.registerFactory(XML_SECURITYPOLICY_PROVIDER, XMLSecurityPolicyProviderFactory); -} - -SecurityPolicyProvider::SecurityPolicyProvider() -{ -} - -SecurityPolicyProvider::~SecurityPolicyProvider() -{ -} - -SecurityPolicy* SecurityPolicyProvider::createSecurityPolicy( - const Application& application, const xmltooling::QName* role, const char* policyId - ) const -{ - pair validate = getPolicySettings(policyId ? policyId : application.getString("policyId").second)->getBool("validate"); - return new SecurityPolicy(application, role, (validate.first && validate.second), policyId); -} - -XMLSecurityPolicyProviderImpl::XMLSecurityPolicyProviderImpl(const DOMElement* e, Category& log) - : m_document(nullptr), m_defaultPolicy(m_policyMap.end()) -{ -#ifdef _DEBUG - xmltooling::NDC ndc("XMLSecurityPolicyProviderImpl"); -#endif - - if (!XMLHelper::isNodeNamed(e, SHIB2SPCONFIG_NS, SecurityPolicies)) - throw ConfigurationException("XML SecurityPolicyProvider requires conf:SecurityPolicies at root of configuration."); - - const XMLCh* algs = nullptr; - const DOMElement* alglist = XMLHelper::getLastChildElement(e, AlgorithmBlacklist); - if (alglist && alglist->hasChildNodes()) { - algs = alglist->getFirstChild()->getNodeValue(); - } - else if ((alglist = XMLHelper::getLastChildElement(e, AlgorithmWhitelist)) && alglist->hasChildNodes()) { - algs = alglist->getFirstChild()->getNodeValue(); - } - if (algs) { - const XMLCh* token; - XMLStringTokenizer tokenizer(algs); - while (tokenizer.hasMoreTokens()) { - token = tokenizer.nextToken(); - if (token) { - if (XMLString::equals(alglist->getLocalName(), AlgorithmBlacklist)) - m_blacklist.push_back(token); - else - m_whitelist.push_back(token); - } - } - } - - PolicyNodeFilter filter; - SAMLConfig& samlConf = SAMLConfig::getConfig(); - e = XMLHelper::getFirstChildElement(e, Policy); - while (e) { - string id(XMLHelper::getAttrString(e, nullptr, _id)); - pair< PropertySet*,vector >& rules = m_policyMap[id]; - rules.first = nullptr; - auto_ptr settings(new DOMPropertySet()); - settings->load(e, nullptr, &filter); - rules.first = settings.release(); - - // Set default policy if not set, or id is "default". - if (m_defaultPolicy == m_policyMap.end() || id == "default") - m_defaultPolicy = m_policyMap.find(id); - - // Process PolicyRule elements. - const DOMElement* rule = XMLHelper::getFirstChildElement(e, PolicyRule); - while (rule) { - string t(XMLHelper::getAttrString(rule, nullptr, _type)); - if (!t.empty()) { - try { - rules.second.push_back(samlConf.SecurityPolicyRuleManager.newPlugin(t.c_str(), rule)); - } - catch (exception& ex) { - log.crit("error instantiating policy rule (%s) in policy (%s): %s", t.c_str(), id.c_str(), ex.what()); - } - } - rule = XMLHelper::getNextSiblingElement(rule, PolicyRule); - } - - if (rules.second.size() == 0) { - // Process Rule elements. - log.warn("detected legacy Policy configuration, please convert to new PolicyRule syntax"); - rule = XMLHelper::getFirstChildElement(e, Rule); - while (rule) { - string t(XMLHelper::getAttrString(rule, nullptr, _type)); - if (!t.empty()) { - try { - rules.second.push_back(samlConf.SecurityPolicyRuleManager.newPlugin(t.c_str(), rule)); - } - catch (exception& ex) { - log.crit("error instantiating policy rule (%s) in policy (%s): %s", t.c_str(), id.c_str(), ex.what()); - } - } - rule = XMLHelper::getNextSiblingElement(rule, Rule); - } - - // Manually add a basic Conditions rule. - log.info("installing a default Conditions rule in policy (%s) for compatibility with legacy configuration", id.c_str()); - rules.second.push_back(samlConf.SecurityPolicyRuleManager.newPlugin(CONDITIONS_POLICY_RULE, nullptr)); - } - - e = XMLHelper::getNextSiblingElement(e, Policy); - } - - if (m_defaultPolicy == m_policyMap.end()) - throw ConfigurationException("XML SecurityPolicyProvider requires at least one Policy."); -} - -pair XMLSecurityPolicyProvider::load(bool backup) -{ - // Load from source using base class. - pair raw = ReloadableXMLFile::load(backup); - - // If we own it, wrap it. - XercesJanitor docjanitor(raw.first ? raw.second->getOwnerDocument() : nullptr); - - XMLSecurityPolicyProviderImpl* impl = new XMLSecurityPolicyProviderImpl(raw.second, m_log); - - // If we held the document, transfer it to the impl. If we didn't, it's a no-op. - impl->setDocument(docjanitor.release()); - - // Perform the swap inside a lock. - if (m_lock) - m_lock->wrlock(); - SharedLock locker(m_lock, false); - delete m_impl; - m_impl = impl; - - - return make_pair(false,(DOMElement*)nullptr); -} - -pair XMLSecurityPolicyProvider::background_load() -{ - try { - return load(false); - } - catch (long& ex) { - if (ex == HTTPResponse::XMLTOOLING_HTTP_STATUS_NOTMODIFIED) - m_log.info("remote resource (%s) unchanged", m_source.c_str()); - if (!m_loaded && !m_backing.empty()) - return load(true); - throw; - } - catch (exception&) { - if (!m_loaded && !m_backing.empty()) - return load(true); - throw; - } -} + */ + +/** + * XMLSecurityPolicyProvider.cpp + * + * XML-based security policy provider. + */ + +#include "internal.h" +#include "exceptions.h" +#include "Application.h" +#include "security/SecurityPolicy.h" +#include "security/SecurityPolicyProvider.h" +#include "util/DOMPropertySet.h" +#include "util/SPConstants.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using shibspconstants::SHIB2SPCONFIG_NS; +using opensaml::SAMLConfig; +using opensaml::SecurityPolicyRule; +using namespace shibsp; +using namespace xmltooling; +using namespace std; + +namespace shibsp { + +#if defined (_MSC_VER) + #pragma warning( push ) + #pragma warning( disable : 4250 ) +#endif + + class SHIBSP_DLLLOCAL XMLSecurityPolicyProviderImpl + { + public: + XMLSecurityPolicyProviderImpl(const DOMElement* e, Category& log); + ~XMLSecurityPolicyProviderImpl() { + for (map< string,pair > >::iterator i = m_policyMap.begin(); i != m_policyMap.end(); ++i) { + delete i->second.first; + for_each(i->second.second.begin(), i->second.second.end(), xmltooling::cleanup()); + } + if (m_document) + m_document->release(); + } + + void setDocument(DOMDocument* doc) { + m_document = doc; + } + + private: + DOMDocument* m_document; + vector m_whitelist,m_blacklist; + map< string,pair< PropertySet*,vector > > m_policyMap; + map< string,pair< PropertySet*,vector > >::const_iterator m_defaultPolicy; + + friend class SHIBSP_DLLLOCAL XMLSecurityPolicyProvider; + }; + + class XMLSecurityPolicyProvider : public SecurityPolicyProvider, public ReloadableXMLFile + { + public: + XMLSecurityPolicyProvider(const DOMElement* e) + : ReloadableXMLFile(e, Category::getInstance(SHIBSP_LOGCAT".SecurityPolicyProvider.XML")), m_impl(nullptr) { + background_load(); // guarantees an exception or the policy is loaded + } + + ~XMLSecurityPolicyProvider() { + shutdown(); + delete m_impl; + } + + const PropertySet* getPolicySettings(const char* id=nullptr) const { + if (!id || !*id) + return m_impl->m_defaultPolicy->second.first; + map > >::const_iterator i = m_impl->m_policyMap.find(id); + if (i != m_impl->m_policyMap.end()) + return i->second.first; + throw ConfigurationException("Security Policy ($1) not found, check element.", params(1,id)); + } + + const vector& getPolicyRules(const char* id=nullptr) const { + if (!id || !*id) + return m_impl->m_defaultPolicy->second.second; + map > >::const_iterator i = m_impl->m_policyMap.find(id); + if (i != m_impl->m_policyMap.end()) + return i->second.second; + throw ConfigurationException("Security Policy ($1) not found, check element.", params(1,id)); + } + const vector& getAlgorithmBlacklist() const { + return m_impl->m_blacklist; + } + const vector& getAlgorithmWhitelist() const { + return m_impl->m_whitelist; + } + + protected: + pair load(bool backup); + pair background_load(); + + private: + XMLSecurityPolicyProviderImpl* m_impl; + }; + +#if defined (_MSC_VER) + #pragma warning( pop ) +#endif + + SecurityPolicyProvider* SHIBSP_DLLLOCAL XMLSecurityPolicyProviderFactory(const DOMElement* const & e) + { + return new XMLSecurityPolicyProvider(e); + } + + class SHIBSP_DLLLOCAL PolicyNodeFilter : public DOMNodeFilter + { + public: +#ifdef SHIBSP_XERCESC_SHORT_ACCEPTNODE + short +#else + FilterAction +#endif + acceptNode(const DOMNode* node) const { + return FILTER_REJECT; + } + }; + + static const XMLCh _id[] = UNICODE_LITERAL_2(i,d); + static const XMLCh _type[] = UNICODE_LITERAL_4(t,y,p,e); + static const XMLCh AlgorithmBlacklist[] = UNICODE_LITERAL_18(A,l,g,o,r,i,t,h,m,B,l,a,c,k,l,i,s,t); + static const XMLCh AlgorithmWhitelist[] = UNICODE_LITERAL_18(A,l,g,o,r,i,t,h,m,W,h,i,t,e,l,i,s,t); + static const XMLCh Policy[] = UNICODE_LITERAL_6(P,o,l,i,c,y); + static const XMLCh PolicyRule[] = UNICODE_LITERAL_10(P,o,l,i,c,y,R,u,l,e); + static const XMLCh Rule[] = UNICODE_LITERAL_4(R,u,l,e); + static const XMLCh SecurityPolicies[] = UNICODE_LITERAL_16(S,e,c,u,r,i,t,y,P,o,l,i,c,i,e,s); +} + +void SHIBSP_API shibsp::registerSecurityPolicyProviders() +{ + SPConfig::getConfig().SecurityPolicyProviderManager.registerFactory(XML_SECURITYPOLICY_PROVIDER, XMLSecurityPolicyProviderFactory); +} + +SecurityPolicyProvider::SecurityPolicyProvider() +{ +} + +SecurityPolicyProvider::~SecurityPolicyProvider() +{ +} + +SecurityPolicy* SecurityPolicyProvider::createSecurityPolicy( + const Application& application, const xmltooling::QName* role, const char* policyId + ) const +{ + pair validate = getPolicySettings(policyId ? policyId : application.getString("policyId").second)->getBool("validate"); + return new SecurityPolicy(application, role, (validate.first && validate.second), policyId); +} + +XMLSecurityPolicyProviderImpl::XMLSecurityPolicyProviderImpl(const DOMElement* e, Category& log) + : m_document(nullptr), m_defaultPolicy(m_policyMap.end()) +{ +#ifdef _DEBUG + xmltooling::NDC ndc("XMLSecurityPolicyProviderImpl"); +#endif + + if (!XMLHelper::isNodeNamed(e, SHIB2SPCONFIG_NS, SecurityPolicies)) + throw ConfigurationException("XML SecurityPolicyProvider requires conf:SecurityPolicies at root of configuration."); + + const XMLCh* algs = nullptr; + const DOMElement* alglist = XMLHelper::getLastChildElement(e, AlgorithmBlacklist); + if (alglist && alglist->hasChildNodes()) { + algs = alglist->getFirstChild()->getNodeValue(); + } + else if ((alglist = XMLHelper::getLastChildElement(e, AlgorithmWhitelist)) && alglist->hasChildNodes()) { + algs = alglist->getFirstChild()->getNodeValue(); + } + if (algs) { + const XMLCh* token; + XMLStringTokenizer tokenizer(algs); + while (tokenizer.hasMoreTokens()) { + token = tokenizer.nextToken(); + if (token) { + if (XMLString::equals(alglist->getLocalName(), AlgorithmBlacklist)) + m_blacklist.push_back(token); + else + m_whitelist.push_back(token); + } + } + } + + PolicyNodeFilter filter; + SAMLConfig& samlConf = SAMLConfig::getConfig(); + e = XMLHelper::getFirstChildElement(e, Policy); + while (e) { + string id(XMLHelper::getAttrString(e, nullptr, _id)); + pair< PropertySet*,vector >& rules = m_policyMap[id]; + rules.first = nullptr; + auto_ptr settings(new DOMPropertySet()); + settings->load(e, nullptr, &filter); + rules.first = settings.release(); + + // Set default policy if not set, or id is "default". + if (m_defaultPolicy == m_policyMap.end() || id == "default") + m_defaultPolicy = m_policyMap.find(id); + + // Process PolicyRule elements. + const DOMElement* rule = XMLHelper::getFirstChildElement(e, PolicyRule); + while (rule) { + string t(XMLHelper::getAttrString(rule, nullptr, _type)); + if (!t.empty()) { + try { + rules.second.push_back(samlConf.SecurityPolicyRuleManager.newPlugin(t.c_str(), rule)); + } + catch (exception& ex) { + log.crit("error instantiating policy rule (%s) in policy (%s): %s", t.c_str(), id.c_str(), ex.what()); + } + } + rule = XMLHelper::getNextSiblingElement(rule, PolicyRule); + } + + if (rules.second.size() == 0) { + // Process Rule elements. + log.warn("detected legacy Policy configuration, please convert to new PolicyRule syntax"); + rule = XMLHelper::getFirstChildElement(e, Rule); + while (rule) { + string t(XMLHelper::getAttrString(rule, nullptr, _type)); + if (!t.empty()) { + try { + rules.second.push_back(samlConf.SecurityPolicyRuleManager.newPlugin(t.c_str(), rule)); + } + catch (exception& ex) { + log.crit("error instantiating policy rule (%s) in policy (%s): %s", t.c_str(), id.c_str(), ex.what()); + } + } + rule = XMLHelper::getNextSiblingElement(rule, Rule); + } + + // Manually add a basic Conditions rule. + log.info("installing a default Conditions rule in policy (%s) for compatibility with legacy configuration", id.c_str()); + rules.second.push_back(samlConf.SecurityPolicyRuleManager.newPlugin(CONDITIONS_POLICY_RULE, nullptr)); + } + + e = XMLHelper::getNextSiblingElement(e, Policy); + } + + if (m_defaultPolicy == m_policyMap.end()) + throw ConfigurationException("XML SecurityPolicyProvider requires at least one Policy."); +} + +pair XMLSecurityPolicyProvider::load(bool backup) +{ + // Load from source using base class. + pair raw = ReloadableXMLFile::load(backup); + + // If we own it, wrap it. + XercesJanitor docjanitor(raw.first ? raw.second->getOwnerDocument() : nullptr); + + XMLSecurityPolicyProviderImpl* impl = new XMLSecurityPolicyProviderImpl(raw.second, m_log); + + // If we held the document, transfer it to the impl. If we didn't, it's a no-op. + impl->setDocument(docjanitor.release()); + + // Perform the swap inside a lock. + if (m_lock) + m_lock->wrlock(); + SharedLock locker(m_lock, false); + delete m_impl; + m_impl = impl; + + + return make_pair(false,(DOMElement*)nullptr); +} + +pair XMLSecurityPolicyProvider::background_load() +{ + try { + return load(false); + } + catch (long& ex) { + if (ex == HTTPResponse::XMLTOOLING_HTTP_STATUS_NOTMODIFIED) + m_log.info("remote resource (%s) unchanged", m_source.c_str()); + if (!m_loaded && !m_backing.empty()) + return load(true); + throw; + } + catch (exception&) { + if (!m_loaded && !m_backing.empty()) + return load(true); + throw; + } +} diff --git a/shibsp/security/SecurityPolicyProvider.h b/shibsp/security/SecurityPolicyProvider.h index 231ae06..65f5bdf 100644 --- a/shibsp/security/SecurityPolicyProvider.h +++ b/shibsp/security/SecurityPolicyProvider.h @@ -16,105 +16,105 @@ * "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. - */ - -/** - * @file shibsp/security/SecurityPolicyProvider.h - * - * Interface to a source of security policy settings and rules. - */ - -#ifndef __shibsp_policyfactory_h__ -#define __shibsp_policyfactory_h__ - -#ifndef SHIBSP_LITE - -#include - -#include -#include -#include - -namespace xmltooling { - class XMLTOOL_API QName; -}; - -namespace opensaml { - class SAML_API SecurityPolicyRule; -}; - -namespace shibsp { - - class SHIBSP_API Application; - class SHIBSP_API PropertySet; - class SHIBSP_API SecurityPolicy; - - /** - * Interface to a source of security policy settings and rules. - */ - class SHIBSP_API SecurityPolicyProvider : public virtual xmltooling::Lockable - { - MAKE_NONCOPYABLE(SecurityPolicyProvider); - protected: - SecurityPolicyProvider(); - public: - virtual ~SecurityPolicyProvider(); - - /** - * Returns the security policy settings for an identified policy. - * - * @param id identifies the policy to return, or nullptr for default - * @return a PropertySet - */ - virtual const PropertySet* getPolicySettings(const char* id=nullptr) const=0; - - /** - * Returns the security policy rules for an identified policy. - * - * @param id identifies the policy to return, or nullptr for default - * @return an array of policy rules - */ - virtual const std::vector& getPolicyRules(const char* id=nullptr) const=0; - - /** - * Returns a set of XML Signature/Encryption algorithm identifiers to block. - * - * @return an array of algorithm URIs to block - */ - virtual const std::vector& getAlgorithmBlacklist() const=0; - - /** - * Returns a set of XML Signature/Encryption algorithm identifiers to permit. - * - * @return an array of algorithm URIs to permit - */ - virtual const std::vector& getAlgorithmWhitelist() const=0; - - /** - * Returns a SecurityPolicy applicable to an application and/or policy identifier. - * - *

The caller MUST lock the application's MetadataProvider for the life - * of the returned object. - * - * @param application reference to application applying policy - * @param role identifies the role (generally IdP or SP) of the policy peer - * @param policyId identifies policy, defaults to the application's default - * @return a new policy instance, which the caller is responsible for freeing - */ - virtual SecurityPolicy* createSecurityPolicy( - const Application& application, const xmltooling::QName* role, const char* policyId=nullptr - ) const; - }; - - /** - * Registers SecurityPolicyProvider classes into the runtime. - */ - void SHIBSP_API registerSecurityPolicyProviders(); - - /** SecurityPolicyProvider based on an XML configuration format. */ - #define XML_SECURITYPOLICY_PROVIDER "XML" -}; - -#endif - -#endif /* __shibsp_policyfactory_h__ */ + */ + +/** + * @file shibsp/security/SecurityPolicyProvider.h + * + * Interface to a source of security policy settings and rules. + */ + +#ifndef __shibsp_policyfactory_h__ +#define __shibsp_policyfactory_h__ + +#ifndef SHIBSP_LITE + +#include + +#include +#include +#include + +namespace xmltooling { + class XMLTOOL_API QName; +}; + +namespace opensaml { + class SAML_API SecurityPolicyRule; +}; + +namespace shibsp { + + class SHIBSP_API Application; + class SHIBSP_API PropertySet; + class SHIBSP_API SecurityPolicy; + + /** + * Interface to a source of security policy settings and rules. + */ + class SHIBSP_API SecurityPolicyProvider : public virtual xmltooling::Lockable + { + MAKE_NONCOPYABLE(SecurityPolicyProvider); + protected: + SecurityPolicyProvider(); + public: + virtual ~SecurityPolicyProvider(); + + /** + * Returns the security policy settings for an identified policy. + * + * @param id identifies the policy to return, or nullptr for default + * @return a PropertySet + */ + virtual const PropertySet* getPolicySettings(const char* id=nullptr) const=0; + + /** + * Returns the security policy rules for an identified policy. + * + * @param id identifies the policy to return, or nullptr for default + * @return an array of policy rules + */ + virtual const std::vector& getPolicyRules(const char* id=nullptr) const=0; + + /** + * Returns a set of XML Signature/Encryption algorithm identifiers to block. + * + * @return an array of algorithm URIs to block + */ + virtual const std::vector& getAlgorithmBlacklist() const=0; + + /** + * Returns a set of XML Signature/Encryption algorithm identifiers to permit. + * + * @return an array of algorithm URIs to permit + */ + virtual const std::vector& getAlgorithmWhitelist() const=0; + + /** + * Returns a SecurityPolicy applicable to an application and/or policy identifier. + * + *

The caller MUST lock the application's MetadataProvider for the life + * of the returned object. + * + * @param application reference to application applying policy + * @param role identifies the role (generally IdP or SP) of the policy peer + * @param policyId identifies policy, defaults to the application's default + * @return a new policy instance, which the caller is responsible for freeing + */ + virtual SecurityPolicy* createSecurityPolicy( + const Application& application, const xmltooling::QName* role, const char* policyId=nullptr + ) const; + }; + + /** + * Registers SecurityPolicyProvider classes into the runtime. + */ + void SHIBSP_API registerSecurityPolicyProviders(); + + /** SecurityPolicyProvider based on an XML configuration format. */ + #define XML_SECURITYPOLICY_PROVIDER "XML" +}; + +#endif + +#endif /* __shibsp_policyfactory_h__ */