From: cantor Date: Tue, 10 Aug 2010 17:38:58 +0000 (+0000) Subject: Add protocol family property to protocol handlers, and fix up error handling to recog... X-Git-Tag: 2.4~49 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fsp.git;a=commitdiff_plain;h=c9adabf4ac03ccedc541385da3b2ce38fd43c45d Add protocol family property to protocol handlers, and fix up error handling to recognize it. git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/branches/REL_2@3290 cb58f699-b61c-0410-a6fe-9272a202ed29 --- diff --git a/adfs/adfs.cpp b/adfs/adfs.cpp index c957c19..333249f 100644 --- a/adfs/adfs.cpp +++ b/adfs/adfs.cpp @@ -90,6 +90,10 @@ namespace { ADFSDecoder() : m_ns(WSTRUST_NS) {} virtual ~ADFSDecoder() {} + const XMLCh* getProtocolFamily() const { + return m_ns.get(); + } + XMLObject* decode(string& relayState, const GenericRequest& genericRequest, SecurityPolicy& policy) const; protected: @@ -140,6 +144,10 @@ namespace { pair unwrap(SPRequest& request, DDF& out) const; pair run(SPRequest& request, string& entityID, bool isHandler=true) const; + const XMLCh* getProtocolFamily() const { + return m_binding.get(); + } + private: pair doRequest( const Application& application, @@ -156,13 +164,10 @@ namespace { class SHIBSP_DLLLOCAL ADFSConsumer : public shibsp::AssertionConsumerService { + auto_ptr_XMLCh m_protocol; public: ADFSConsumer(const DOMElement* e, const char* appId) - : shibsp::AssertionConsumerService(e, appId, Category::getInstance(SHIBSP_LOGCAT".SSO.ADFS")) -#ifndef SHIBSP_LITE - ,m_protocol(WSFED_NS) -#endif - {} + : shibsp::AssertionConsumerService(e, appId, Category::getInstance(SHIBSP_LOGCAT".SSO.ADFS")), m_protocol(WSFED_NS) {} virtual ~ADFSConsumer() {} #ifndef SHIBSP_LITE @@ -171,8 +176,6 @@ namespace { role.addSupport(m_protocol.get()); } - auto_ptr_XMLCh m_protocol; - private: void implementProtocol( const Application& application, @@ -182,6 +185,10 @@ namespace { const PropertySet*, const XMLObject& xmlObject ) const; +#else + const XMLCh* getProtocolFamily() const { + return m_protocol.get(); + } #endif }; @@ -219,6 +226,9 @@ namespace { return "LogoutInitiator"; } #endif + const XMLCh* getProtocolFamily() const { + return m_binding.get(); + } private: pair doRequest(const Application& application, const HTTPRequest& httpRequest, HTTPResponse& httpResponse, Session* session) const; @@ -254,7 +264,7 @@ namespace { auto_ptr_XMLCh widen(hurl.c_str()); SingleLogoutService* ep = SingleLogoutServiceBuilder::buildSingleLogoutService(); ep->setLocation(widen.get()); - ep->setBinding(m_login.m_protocol.get()); + ep->setBinding(m_login.getProtocolFamily()); role.getSingleLogoutServices().push_back(ep); } @@ -262,6 +272,9 @@ namespace { return m_login.getType(); } #endif + const XMLCh* getProtocolFamily() const { + return m_login.getProtocolFamily(); + } private: ADFSConsumer m_login; @@ -378,12 +391,9 @@ pair ADFSSessionInitiator::run(SPRequest& request, string& entityID, } // Validate the ACS for use with this protocol. - pair ACSbinding = ACS->getXMLString("Binding"); - if (ACSbinding.first) { - if (!XMLString::equals(ACSbinding.second, m_binding.get())) { - m_log.error("configured or requested ACS has non-ADFS binding"); - throw ConfigurationException("Configured or requested ACS has non-ADFS binding ($1).", params(1, ACSbinding.second)); - } + if (!XMLString::equals(getProtocolFamily(), ACS->getProtocolFamily())) { + m_log.error("configured or requested ACS has non-ADFS binding"); + throw ConfigurationException("Configured or requested ACS has non-ADFS binding ($1).", params(1, ACS->getString("Binding").second)); } // Since we're not passing by index, we need to fully compute the return URL. diff --git a/shibsp/handler/AssertionConsumerService.h b/shibsp/handler/AssertionConsumerService.h index a7618fb..1233268 100644 --- a/shibsp/handler/AssertionConsumerService.h +++ b/shibsp/handler/AssertionConsumerService.h @@ -174,7 +174,7 @@ namespace shibsp { public: const char* getType() const; - + const XMLCh* getProtocolFamily() const; #endif private: std::pair processMessage( diff --git a/shibsp/handler/Handler.h b/shibsp/handler/Handler.h index 24bb798..624d983 100644 --- a/shibsp/handler/Handler.h +++ b/shibsp/handler/Handler.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2009 Internet2 + * Copyright 2001-2010 Internet2 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -98,6 +98,13 @@ namespace shibsp { virtual ~Handler(); /** + * Returns an identifier for the protocol family associated with the handler, if any. + * + * @return a protocol identifier, or nullptr + */ + virtual const XMLCh* getProtocolFamily() const; + + /** * Executes handler functionality as an incoming request. * *

Handlers can be run either directly by incoming web requests diff --git a/shibsp/handler/impl/AbstractHandler.cpp b/shibsp/handler/impl/AbstractHandler.cpp index e8e8b55..a2e5439 100644 --- a/shibsp/handler/impl/AbstractHandler.cpp +++ b/shibsp/handler/impl/AbstractHandler.cpp @@ -158,6 +158,11 @@ Handler::~Handler() { } +const XMLCh* Handler::getProtocolFamily() const +{ + return nullptr; +} + void Handler::log(SPRequest::SPLogLevel level, const string& msg) const { Category::getInstance(SHIBSP_LOGCAT".Handler").log( diff --git a/shibsp/handler/impl/AssertionConsumerService.cpp b/shibsp/handler/impl/AssertionConsumerService.cpp index b35cd5c..e9176c8 100644 --- a/shibsp/handler/impl/AssertionConsumerService.cpp +++ b/shibsp/handler/impl/AssertionConsumerService.cpp @@ -224,6 +224,11 @@ void AssertionConsumerService::checkAddress(const Application& application, cons #ifndef SHIBSP_LITE +const XMLCh* AssertionConsumerService::getProtocolFamily() const +{ + return m_decoder ? m_decoder->getProtocolFamily() : nullptr; +} + const char* AssertionConsumerService::getType() const { return "AssertionConsumerService"; diff --git a/shibsp/handler/impl/SAML1Consumer.cpp b/shibsp/handler/impl/SAML1Consumer.cpp index 78cd49a..0470e02 100644 --- a/shibsp/handler/impl/SAML1Consumer.cpp +++ b/shibsp/handler/impl/SAML1Consumer.cpp @@ -97,6 +97,10 @@ namespace shibsp { bool m_post; SecurityPolicyRule* m_ssoRule; +#else + const XMLCh* getProtocolFamily() const { + return samlconstants::SAML11_PROTOCOL_ENUM; + } #endif }; diff --git a/shibsp/handler/impl/SAML2ArtifactResolution.cpp b/shibsp/handler/impl/SAML2ArtifactResolution.cpp index 7857965..0d0cc76 100644 --- a/shibsp/handler/impl/SAML2ArtifactResolution.cpp +++ b/shibsp/handler/impl/SAML2ArtifactResolution.cpp @@ -45,7 +45,8 @@ using namespace opensaml::saml2md; using namespace opensaml::saml2p; using namespace opensaml::saml2; using namespace opensaml; -using namespace samlconstants; +#else +# include "lite/SAMLConstants.h" #endif #include @@ -106,6 +107,9 @@ namespace shibsp { role.getArtifactResolutionServices().push_back(ep); } #endif + const XMLCh* getProtocolFamily() const { + return samlconstants::SAML20P_NS; + } private: pair processMessage(const Application& application, HTTPRequest& httpRequest, HTTPResponse& httpResponse) const; diff --git a/shibsp/handler/impl/SAML2Consumer.cpp b/shibsp/handler/impl/SAML2Consumer.cpp index e67297e..ce543ab 100644 --- a/shibsp/handler/impl/SAML2Consumer.cpp +++ b/shibsp/handler/impl/SAML2Consumer.cpp @@ -45,6 +45,8 @@ using namespace opensaml; # ifndef min # define min(a,b) (((a) < (b)) ? (a) : (b)) # endif +#else +# include "lite/SAMLConstants.h" #endif using namespace shibsp; @@ -92,6 +94,10 @@ namespace shibsp { ) const; SecurityPolicyRule* m_ssoRule; +#else + const XMLCh* getProtocolFamily() const { + return samlconstants::SAML20P_NS; + } #endif }; diff --git a/shibsp/handler/impl/SAML2Logout.cpp b/shibsp/handler/impl/SAML2Logout.cpp index 1ea0ef1..acfdd26 100644 --- a/shibsp/handler/impl/SAML2Logout.cpp +++ b/shibsp/handler/impl/SAML2Logout.cpp @@ -47,6 +47,8 @@ using namespace opensaml::saml2; using namespace opensaml::saml2p; using namespace opensaml::saml2md; using namespace opensaml; +#else +# include "lite/SAMLConstants.h" #endif using namespace shibsp; @@ -96,6 +98,9 @@ namespace shibsp { return "SingleLogoutService"; } #endif + const XMLCh* getProtocolFamily() const { + return samlconstants::SAML20P_NS; + } private: pair doRequest(const Application& application, const HTTPRequest& httpRequest, HTTPResponse& httpResponse) const; @@ -178,13 +183,13 @@ SAML2Logout::SAML2Logout(const DOMElement* e, const char* appId) MessageEncoder * encoder = conf.MessageEncoderManager.newPlugin( b.get(), pair(e,shibspconstants::SHIB2SPCONFIG_NS) ); - if (encoder->isUserAgentPresent()) { + if (encoder->isUserAgentPresent() && XMLString::equals(getProtocolFamily(), encoder->getProtocolFamily())) { m_encoders[start] = encoder; m_log.debug("supporting outgoing binding (%s)", b.get()); } else { delete encoder; - m_log.warn("skipping outgoing binding (%s), not a front-channel mechanism", b.get()); + m_log.warn("skipping outgoing binding (%s), not a SAML 2.0 front-channel mechanism", b.get()); } } catch (exception& ex) { diff --git a/shibsp/handler/impl/SAML2LogoutInitiator.cpp b/shibsp/handler/impl/SAML2LogoutInitiator.cpp index a776bc3..66528a0 100644 --- a/shibsp/handler/impl/SAML2LogoutInitiator.cpp +++ b/shibsp/handler/impl/SAML2LogoutInitiator.cpp @@ -80,6 +80,9 @@ namespace shibsp { return "LogoutInitiator"; } #endif + const XMLCh* getProtocolFamily() const { + return samlconstants::SAML20P_NS; + } private: pair doRequest( @@ -142,13 +145,13 @@ SAML2LogoutInitiator::SAML2LogoutInitiator(const DOMElement* e, const char* appI auto_ptr_char b(start); MessageEncoder * encoder = SAMLConfig::getConfig().MessageEncoderManager.newPlugin(b.get(),pair(e,nullptr)); - if (encoder->isUserAgentPresent()) { + if (encoder->isUserAgentPresent() && XMLString::equals(getProtocolFamily(), encoder->getProtocolFamily())) { m_encoders[start] = encoder; m_log.debug("supporting outgoing binding (%s)", b.get()); } else { delete encoder; - m_log.warn("skipping outgoing binding (%s), not a front-channel mechanism", b.get()); + m_log.warn("skipping outgoing binding (%s), not a SAML 2.0 front-channel mechanism", b.get()); } } catch (exception& ex) { diff --git a/shibsp/handler/impl/SAML2NameIDMgmt.cpp b/shibsp/handler/impl/SAML2NameIDMgmt.cpp index 8d0c17d..df91db9 100644 --- a/shibsp/handler/impl/SAML2NameIDMgmt.cpp +++ b/shibsp/handler/impl/SAML2NameIDMgmt.cpp @@ -46,6 +46,8 @@ using namespace opensaml::saml2; using namespace opensaml::saml2p; using namespace opensaml::saml2md; using namespace opensaml; +#else +# include "lite/SAMLConstants.h" #endif using namespace shibsp; @@ -95,6 +97,9 @@ namespace shibsp { return "ManageNameIDService"; } #endif + const XMLCh* getProtocolFamily() const { + return samlconstants::SAML20P_NS; + } private: pair doRequest(const Application& application, const HTTPRequest& httpRequest, HTTPResponse& httpResponse) const; @@ -174,13 +179,13 @@ SAML2NameIDMgmt::SAML2NameIDMgmt(const DOMElement* e, const char* appId) MessageEncoder * encoder = conf.MessageEncoderManager.newPlugin( b.get(), pair(e,shibspconstants::SHIB2SPCONFIG_NS) ); - if (encoder->isUserAgentPresent()) { + if (encoder->isUserAgentPresent() && XMLString::equals(getProtocolFamily(), encoder->getProtocolFamily())) { m_encoders[start] = encoder; m_log.debug("supporting outgoing binding (%s)", b.get()); } else { delete encoder; - m_log.warn("skipping outgoing binding (%s), not a front-channel mechanism", b.get()); + m_log.warn("skipping outgoing binding (%s), not a SAML 2.0 front-channel mechanism", b.get()); } } catch (exception& ex) { diff --git a/shibsp/handler/impl/SAML2SessionInitiator.cpp b/shibsp/handler/impl/SAML2SessionInitiator.cpp index 2765ce6..17056a2 100644 --- a/shibsp/handler/impl/SAML2SessionInitiator.cpp +++ b/shibsp/handler/impl/SAML2SessionInitiator.cpp @@ -77,6 +77,10 @@ namespace shibsp { pair unwrap(SPRequest& request, DDF& out) const; pair run(SPRequest& request, string& entityID, bool isHandler=true) const; + const XMLCh* getProtocolFamily() const { + return samlconstants::SAML20P_NS; + } + private: pair doRequest( const Application& application, @@ -177,13 +181,13 @@ SAML2SessionInitiator::SAML2SessionInitiator(const DOMElement* e, const char* ap MessageEncoder * encoder = SAMLConfig::getConfig().MessageEncoderManager.newPlugin( b.get(),pair(e,nullptr) ); - if (encoder->isUserAgentPresent()) { + if (encoder->isUserAgentPresent() && XMLString::equals(getProtocolFamily(), encoder->getProtocolFamily())) { m_encoders[start] = encoder; m_log.debug("supporting outgoing binding (%s)", b.get()); } else { delete encoder; - m_log.warn("skipping outgoing binding (%s), not a front-channel mechanism", b.get()); + m_log.warn("skipping outgoing binding (%s), not a SAML 2.0 front-channel mechanism", b.get()); } } catch (exception& ex) { @@ -324,21 +328,9 @@ pair SAML2SessionInitiator::run(SPRequest& request, string& entityID, } // Validate the ACS for use with this protocol. - if (!ECP) { - pair ACSbinding = ACS ? ACS->getString("Binding") : pair(false,nullptr); - if (ACSbinding.first) { - pair compatibleBindings = getString("compatibleBindings"); - if (compatibleBindings.first && strstr(compatibleBindings.second, ACSbinding.second) == nullptr) { - m_log.error("configured or requested ACS has non-SAML 2.0 binding"); - throw ConfigurationException("Configured or requested ACS has non-SAML 2.0 binding ($1).", params(1, ACSbinding.second)); - } - else if (strcmp(ACSbinding.second, samlconstants::SAML20_BINDING_HTTP_POST) && - strcmp(ACSbinding.second, samlconstants::SAML20_BINDING_HTTP_ARTIFACT) && - strcmp(ACSbinding.second, samlconstants::SAML20_BINDING_HTTP_POST_SIMPLESIGN)) { - m_log.error("configured or requested ACS has non-SAML 2.0 binding"); - throw ConfigurationException("Configured or requested ACS has non-SAML 2.0 binding ($1).", params(1, ACSbinding.second)); - } - } + if (!ECP && ACS && !XMLString::equals(getProtocolFamily(), ACS->getProtocolFamily())) { + m_log.error("configured or requested ACS has non-SAML 2.0 binding"); + throw ConfigurationException("Configured or requested ACS has non-SAML 2.0 binding ($1).", params(1, ACS->getString("Binding").second)); } // To invoke the request builder, the key requirement is to figure out how diff --git a/shibsp/handler/impl/Shib1SessionInitiator.cpp b/shibsp/handler/impl/Shib1SessionInitiator.cpp index d210ff4..21a1703 100644 --- a/shibsp/handler/impl/Shib1SessionInitiator.cpp +++ b/shibsp/handler/impl/Shib1SessionInitiator.cpp @@ -72,6 +72,10 @@ namespace shibsp { pair unwrap(SPRequest& request, DDF& out) const; pair run(SPRequest& request, string& entityID, bool isHandler=true) const; + const XMLCh* getProtocolFamily() const { + return samlconstants::SAML11_PROTOCOL_ENUM; + } + private: pair doRequest( const Application& application, @@ -158,18 +162,9 @@ pair Shib1SessionInitiator::run(SPRequest& request, string& entityID, } // Validate the ACS for use with this protocol. - pair ACSbinding = ACS ? ACS->getString("Binding") : pair(false,nullptr); - if (ACSbinding.first) { - pair compatibleBindings = getString("compatibleBindings"); - if (compatibleBindings.first && strstr(compatibleBindings.second, ACSbinding.second) == nullptr) { - m_log.error("configured or requested ACS has non-SAML 1.x binding"); - throw ConfigurationException("Configured or requested ACS has non-SAML 1.x binding ($1).", params(1, ACSbinding.second)); - } - else if (strcmp(ACSbinding.second, samlconstants::SAML1_PROFILE_BROWSER_POST) && - strcmp(ACSbinding.second, samlconstants::SAML1_PROFILE_BROWSER_ARTIFACT)) { - m_log.error("configured or requested ACS has non-SAML 1.x binding"); - throw ConfigurationException("Configured or requested ACS has non-SAML 1.x binding ($1).", params(1, ACSbinding.second)); - } + if (ACS && !XMLString::equals(getProtocolFamily(), ACS->getProtocolFamily())) { + m_log.error("configured or requested ACS has non-SAML 1.x binding"); + throw ConfigurationException("Configured or requested ACS has non-SAML 1.x binding ($1).", params(1, ACS->getString("Binding").second)); } // Compute the ACS URL. We add the ACS location to the base handlerURL. diff --git a/shibsp/handler/impl/WAYFSessionInitiator.cpp b/shibsp/handler/impl/WAYFSessionInitiator.cpp index b9cc9c9..160000d 100644 --- a/shibsp/handler/impl/WAYFSessionInitiator.cpp +++ b/shibsp/handler/impl/WAYFSessionInitiator.cpp @@ -135,18 +135,9 @@ pair WAYFSessionInitiator::run(SPRequest& request, string& entityID, } // Validate the ACS for use with this protocol. - pair ACSbinding = ACS ? ACS->getString("Binding") : pair(false,nullptr); - if (ACSbinding.first) { - pair compatibleBindings = getString("compatibleBindings"); - if (compatibleBindings.first && strstr(compatibleBindings.second, ACSbinding.second) == nullptr) { - m_log.error("configured or requested ACS has non-SAML 1.x binding"); - throw ConfigurationException("Configured or requested ACS has non-SAML 1.x binding ($1).", params(1, ACSbinding.second)); - } - else if (strcmp(ACSbinding.second, samlconstants::SAML1_PROFILE_BROWSER_POST) && - strcmp(ACSbinding.second, samlconstants::SAML1_PROFILE_BROWSER_ARTIFACT)) { - m_log.error("configured or requested ACS has non-SAML 1.x binding"); - throw ConfigurationException("Configured or requested ACS has non-SAML 1.x binding ($1).", params(1, ACSbinding.second)); - } + if (ACS && !XMLString::equals(samlconstants::SAML11_PROTOCOL_ENUM, ACS->getProtocolFamily())) { + m_log.error("configured or requested ACS has non-SAML 1.x binding"); + throw ConfigurationException("Configured or requested ACS has non-SAML 1.x binding ($1).", params(1, ACS->getString("Binding").second)); } if (!discoveryURL.first) diff --git a/shibsp/shibsp-lite.vcxproj b/shibsp/shibsp-lite.vcxproj index 3942708..f885d42 100644 --- a/shibsp/shibsp-lite.vcxproj +++ b/shibsp/shibsp-lite.vcxproj @@ -241,7 +241,6 @@ - diff --git a/shibsp/shibsp-lite.vcxproj.filters b/shibsp/shibsp-lite.vcxproj.filters index 9293c01..4b98a41 100644 --- a/shibsp/shibsp-lite.vcxproj.filters +++ b/shibsp/shibsp-lite.vcxproj.filters @@ -218,9 +218,6 @@ Header Files - - Header Files - Header Files