From 3e95c28cc8cd1c13ecd2424368db114e08c95cdd Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Mon, 10 Aug 2009 18:55:17 +0000 Subject: [PATCH] https://issues.shibboleth.net/jira/browse/SSPCPP-227 --- adfs/adfs.cpp | 45 ++++++++++++++------------- shibsp/handler/impl/SAML2SessionInitiator.cpp | 20 +++++++++++- shibsp/handler/impl/Shib1SessionInitiator.cpp | 17 +++++++++- shibsp/handler/impl/WAYFSessionInitiator.cpp | 15 +++++++++ 4 files changed, 74 insertions(+), 23 deletions(-) diff --git a/adfs/adfs.cpp b/adfs/adfs.cpp index a2d50e3..c551ecc 100644 --- a/adfs/adfs.cpp +++ b/adfs/adfs.cpp @@ -330,6 +330,13 @@ pair ADFSSessionInitiator::run(SPRequest& request, string& entityID, const Application& app=request.getApplication(); if (isHandler) { + option=request.getParameter("acsIndex"); + if (option) { + ACS = app.getAssertionConsumerServiceByIndex(atoi(option)); + if (!ACS) + request.log(SPRequest::SPWarn, "invalid acsIndex specified in request, using default ACS location"); + } + option = request.getParameter("target"); if (option) target = option; @@ -355,29 +362,25 @@ pair ADFSSessionInitiator::run(SPRequest& request, string& entityID, } // Since we're not passing by index, we need to fully compute the return URL. - // Get all the ADFS endpoints. - const vector& handlers = app.getAssertionConsumerServicesByBinding(m_binding.get()); - - // Index comes from request, or default set in the handler, or we just pick the first endpoint. - pair index(false,0); - if (isHandler) { - option = request.getParameter("acsIndex"); - if (option) - index = pair(true, atoi(option)); - } - if (!index.first) - index = getUnsignedInt("defaultACSIndex"); - if (index.first) { - for (vector::const_iterator h = handlers.begin(); !ACS && h!=handlers.end(); ++h) { - if (index.second == (*h)->getUnsignedInt("index").second) - ACS = *h; + if (!ACS) { + pair index = getUnsignedInt("defaultACSIndex"); + if (index.first) { + ACS = app.getAssertionConsumerServiceByIndex(index.second); + if (!ACS) + request.log(SPRequest::SPWarn, "invalid defaultACSIndex, using default ACS location"); } + if (!ACS) + ACS = app.getDefaultAssertionConsumerService(); } - else if (!handlers.empty()) { - ACS = handlers.front(); + + // Validate the ACS for use with this protocol. + pair ACSbinding = ACS ? ACS->getXMLString("Binding") : pair(false,NULL); + if (ACSbinding.first) { + if (!XMLString::equals(ACSbinding.second, m_binding.get())) { + m_log.info("configured or requested ACS has non-ADFS binding"); + return make_pair(false,0L); + } } - if (!ACS) - throw ConfigurationException("Unable to locate ADFS response endpoint."); // Compute the ACS URL. We add the ACS location to the base handlerURL. string ACSloc=request.getHandlerURL(target.c_str()); @@ -483,7 +486,7 @@ pair ADFSSessionInitiator::doRequest( throw MetadataException("Unable to locate metadata for identity provider ($entityID)", namedparams(1, "entityID", entityID)); } else if (!entity.second) { - m_log.warn("unable to locate ADFS-aware identity provider role for provider (%s)", entityID); + m_log.log(getParent() ? Priority::INFO : Priority::WARN, "unable to locate ADFS-aware identity provider role for provider (%s)", entityID); if (getParent()) return make_pair(false,0L); throw MetadataException("Unable to locate ADFS-aware identity provider role for provider ($entityID)", namedparams(1, "entityID", entityID)); diff --git a/shibsp/handler/impl/SAML2SessionInitiator.cpp b/shibsp/handler/impl/SAML2SessionInitiator.cpp index 096302b..c6a8d5f 100644 --- a/shibsp/handler/impl/SAML2SessionInitiator.cpp +++ b/shibsp/handler/impl/SAML2SessionInitiator.cpp @@ -333,6 +333,24 @@ 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,NULL); + if (ACSbinding.first) { + pair compatibleBindings = getString("compatibleBindings"); + if (compatibleBindings.first && strstr(compatibleBindings.second, ACSbinding.second) == NULL) { + m_log.info("configured or requested ACS has non-SAML 2.0 binding"); + return make_pair(false,0L); + } + 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.info("configured or requested ACS has non-SAML 2.0 binding"); + return make_pair(false,0L); + } + } + } + // To invoke the request builder, the key requirement is to figure out how // to express the ACS, by index or value, and if by value, where. // We have to compute the handlerURL no matter what, because we may need to @@ -571,7 +589,7 @@ pair SAML2SessionInitiator::doRequest( throw MetadataException("Unable to locate metadata for identity provider ($entityID)", namedparams(1, "entityID", entityID)); } else if (!entity.second) { - m_log.warn("unable to locate SAML 2.0 identity provider role for provider (%s)", entityID); + m_log.log(getParent() ? Priority::INFO : Priority::WARN, "unable to locate SAML 2.0 identity provider role for provider (%s)", entityID); if (getParent()) return make_pair(false,0L); throw MetadataException("Unable to locate SAML 2.0 identity provider role for provider ($entityID)", namedparams(1, "entityID", entityID)); diff --git a/shibsp/handler/impl/Shib1SessionInitiator.cpp b/shibsp/handler/impl/Shib1SessionInitiator.cpp index 5903e4b..c9de163 100644 --- a/shibsp/handler/impl/Shib1SessionInitiator.cpp +++ b/shibsp/handler/impl/Shib1SessionInitiator.cpp @@ -153,6 +153,21 @@ pair Shib1SessionInitiator::run(SPRequest& request, string& entityID, ACS = app.getDefaultAssertionConsumerService(); } + // Validate the ACS for use with this protocol. + pair ACSbinding = ACS ? ACS->getString("Binding") : pair(false,NULL); + if (ACSbinding.first) { + pair compatibleBindings = getString("compatibleBindings"); + if (compatibleBindings.first && strstr(compatibleBindings.second, ACSbinding.second) == NULL) { + m_log.info("configured or requested ACS has non-SAML 1.x binding"); + return make_pair(false,0L); + } + else if (strcmp(ACSbinding.second, samlconstants::SAML1_PROFILE_BROWSER_POST) && + strcmp(ACSbinding.second, samlconstants::SAML1_PROFILE_BROWSER_ARTIFACT)) { + m_log.info("configured or requested ACS has non-SAML 1.x binding"); + return make_pair(false,0L); + } + } + // Compute the ACS URL. We add the ACS location to the base handlerURL. string ACSloc=request.getHandlerURL(target.c_str()); pair loc=ACS ? ACS->getString("Location") : pair(false,NULL); @@ -260,7 +275,7 @@ pair Shib1SessionInitiator::doRequest( throw MetadataException("Unable to locate metadata for identity provider ($entityID)", namedparams(1, "entityID", entityID)); } else if (!entity.second) { - m_log.warn("unable to locate Shibboleth-aware identity provider role for provider (%s)", entityID); + m_log.log(getParent() ? Priority::INFO : Priority::WARN, "unable to locate Shibboleth-aware identity provider role for provider (%s)", entityID); if (getParent()) return make_pair(false,0L); throw MetadataException("Unable to locate Shibboleth-aware identity provider role for provider ($entityID)", namedparams(1, "entityID", entityID)); diff --git a/shibsp/handler/impl/WAYFSessionInitiator.cpp b/shibsp/handler/impl/WAYFSessionInitiator.cpp index af9b71a..f0e075d 100644 --- a/shibsp/handler/impl/WAYFSessionInitiator.cpp +++ b/shibsp/handler/impl/WAYFSessionInitiator.cpp @@ -116,6 +116,21 @@ pair WAYFSessionInitiator::run(SPRequest& request, string& entityID, ACS = app.getDefaultAssertionConsumerService(); } + // Validate the ACS for use with this protocol. + pair ACSbinding = ACS ? ACS->getString("Binding") : pair(false,NULL); + if (ACSbinding.first) { + pair compatibleBindings = getString("compatibleBindings"); + if (compatibleBindings.first && strstr(compatibleBindings.second, ACSbinding.second) == NULL) { + m_log.info("configured or requested ACS has non-SAML 1.x binding"); + return make_pair(false,0L); + } + else if (strcmp(ACSbinding.second, samlconstants::SAML1_PROFILE_BROWSER_POST) && + strcmp(ACSbinding.second, samlconstants::SAML1_PROFILE_BROWSER_ARTIFACT)) { + m_log.info("configured or requested ACS has non-SAML 1.x binding"); + return make_pair(false,0L); + } + } + m_log.debug("sending request to WAYF (%s)", m_url); // Compute the ACS URL. We add the ACS location to the base handlerURL. -- 2.1.4