From: cantor Date: Wed, 30 May 2007 17:31:39 +0000 (+0000) Subject: Merge in updated Apache POST body code. X-Git-Tag: 2.4~919 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fsp.git;a=commitdiff_plain;h=265f44e5f0056ec3159ec9e8d2e47a43c7637ec6 Merge in updated Apache POST body code. Add per-initiator ACS defaulting to handle different SAML versions. git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/trunk@2269 cb58f699-b61c-0410-a6fe-9272a202ed29 --- diff --git a/apache/mod_apache.cpp b/apache/mod_apache.cpp index 91e196f..417892f 100644 --- a/apache/mod_apache.cpp +++ b/apache/mod_apache.cpp @@ -66,6 +66,7 @@ #ifndef SHIB_APACHE_13 #include +#include #include #include #endif @@ -328,6 +329,7 @@ public: const char* getRequestBody() const { if (m_gotBody || m_req->method_number==M_GET) return m_body.c_str(); +#ifdef SHIB_APACHE_13 // Read the posted data if (ap_setup_client_block(m_req, REQUEST_CHUNKED_DECHUNK) != OK) { m_gotBody=true; @@ -350,6 +352,39 @@ public: m_body.append(buff, len); } ap_kill_timeout(m_req); +#else + const char *data; + apr_size_t len; + int seen_eos = 0; + apr_bucket_brigade* bb = apr_brigade_create(m_req->pool, m_req->connection->bucket_alloc); + do { + apr_bucket *bucket; + apr_status_t rv = ap_get_brigade(m_req->input_filters, bb, AP_MODE_READBYTES, APR_BLOCK_READ, HUGE_STRING_LEN); + if (rv != APR_SUCCESS) { + log(SPError, "Apache function (ap_get_brigade) failed while reading request body."); + break; + } + + for (bucket = APR_BRIGADE_FIRST(bb); bucket != APR_BRIGADE_SENTINEL(bb); bucket = APR_BUCKET_NEXT(bucket)) { + if (APR_BUCKET_IS_EOS(bucket)) { + seen_eos = 1; + break; + } + + /* We can't do much with this. */ + if (APR_BUCKET_IS_FLUSH(bucket)) + continue; + + /* read */ + apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ); + if (len > 0) + m_body.append(data, len); + } + apr_brigade_cleanup(bb); + } while (!seen_eos); + apr_brigade_destroy(bb); + m_gotBody=true; +#endif return m_body.c_str(); } void clearHeader(const char* name) { diff --git a/apache/mod_shib20.vcproj b/apache/mod_shib20.vcproj index 662a4a1..a1ac6ef 100644 --- a/apache/mod_shib20.vcproj +++ b/apache/mod_shib20.vcproj @@ -76,11 +76,11 @@ /> - - - + + - - - + + + - + @@ -174,7 +174,7 @@ are used when sessions are initiated to determine how to tell the IdP where and how to return the response. --> - diff --git a/schemas/shibboleth-2.0-native-sp-config.xsd b/schemas/shibboleth-2.0-native-sp-config.xsd index f36f284..50ee9f2 100644 --- a/schemas/shibboleth-2.0-native-sp-config.xsd +++ b/schemas/shibboleth-2.0-native-sp-config.xsd @@ -464,6 +464,7 @@ + diff --git a/shibsp/handler/impl/SAML2SessionInitiator.cpp b/shibsp/handler/impl/SAML2SessionInitiator.cpp index 5f9e87f..afb5e70 100644 --- a/shibsp/handler/impl/SAML2SessionInitiator.cpp +++ b/shibsp/handler/impl/SAML2SessionInitiator.cpp @@ -197,7 +197,7 @@ pair SAML2SessionInitiator::run(SPRequest& request, const char* entit if (option) { ACS = app.getAssertionConsumerServiceByIndex(atoi(option)); if (!ACS) - throw ConfigurationException("AssertionConsumerService with index ($1) not found, check configuration.", params(1,option)); + request.log(SPRequest::SPWarn, "invalid acsIndex specified in request, using default ACS location"); } option = request.getParameter("target"); @@ -240,13 +240,24 @@ pair SAML2SessionInitiator::run(SPRequest& request, const char* entit m_log.debug("attempting to initiate session using SAML 2.0 with provider (%s)", entityID); - // To invoke the request builder, the key requirement is to figure out how and whether + 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(); + } + + // 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. SPConfig& conf = SPConfig::getConfig(); if (conf.isEnabled(SPConfig::OutOfProcess)) { if (!acsByIndex.first || acsByIndex.second) { - // Pass by Index. This also allows for defaulting it entirely and sending nothing. + // Pass by Index. if (isHandler) { // We may already have RelayState set if we looped back here, // but just in case target is a resource, we reset it back. @@ -266,9 +277,6 @@ pair SAML2SessionInitiator::run(SPRequest& request, const char* entit } // Since we're not passing by index, we need to fully compute the return URL and binding. - if (!ACS) - ACS = app.getDefaultAssertionConsumerService(); - // 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); @@ -312,9 +320,6 @@ pair SAML2SessionInitiator::run(SPRequest& request, const char* entit } else { // Since we're not passing by index, we need to fully compute the return URL and binding. - if (!ACS) - ACS = app.getDefaultAssertionConsumerService(); - // 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); diff --git a/shibsp/handler/impl/Shib1SessionInitiator.cpp b/shibsp/handler/impl/Shib1SessionInitiator.cpp index c085095..d98b608 100644 --- a/shibsp/handler/impl/Shib1SessionInitiator.cpp +++ b/shibsp/handler/impl/Shib1SessionInitiator.cpp @@ -117,8 +117,11 @@ pair Shib1SessionInitiator::run(SPRequest& request, const char* entit if (isHandler) { option=request.getParameter("acsIndex"); - if (option) + 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) @@ -134,9 +137,17 @@ pair Shib1SessionInitiator::run(SPRequest& request, const char* entit target=request.getRequestURL(); } - // Since we're not passing by index, we need to fully compute the return URL and binding. - if (!ACS) - ACS = app.getDefaultAssertionConsumerService(); + // Since we're not passing by index, we need to fully compute the return URL. + 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(); + } // Compute the ACS URL. We add the ACS location to the base handlerURL. string ACSloc=request.getHandlerURL(target.c_str()); diff --git a/shibsp/handler/impl/WAYFSessionInitiator.cpp b/shibsp/handler/impl/WAYFSessionInitiator.cpp index 92de900..be55d48 100644 --- a/shibsp/handler/impl/WAYFSessionInitiator.cpp +++ b/shibsp/handler/impl/WAYFSessionInitiator.cpp @@ -87,8 +87,11 @@ pair WAYFSessionInitiator::run(SPRequest& request, const char* entity if (isHandler) { option=request.getParameter("acsIndex"); - if (option) + 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) @@ -101,8 +104,17 @@ pair WAYFSessionInitiator::run(SPRequest& request, const char* entity target=request.getRequestURL(); } - if (!ACS) - ACS = app.getDefaultAssertionConsumerService(); + // Since we're not passing by index, we need to fully compute the return URL. + 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(); + } m_log.debug("sending request to WAYF (%s)", m_url);