#ifndef SHIB_APACHE_13
#include <http_request.h>
+#include <apr_buckets.h>
#include <apr_strings.h>
#include <apr_pools.h>
#endif
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;
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) {
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="log4cpp.lib xerces-c_2.lib libapr.lib libhttpd.lib xmltooling-lite1.lib"
+ AdditionalDependencies="log4cpp.lib xerces-c_2.lib libapr.lib libaprutil.lib libhttpd.lib xmltooling-lite1.lib"
OutputFile="mod_shib20___Win32_Release/mod_shib_20.so"
LinkIncremental="1"
SuppressStartupBanner="true"
- AdditionalLibraryDirectories=""..\..\cpp-xmltooling\Release",\httpd-2.0.52\srclib\apr\Release,\httpd-2.0.52\Release"
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\Release";\Apache2\lib"
ProgramDatabaseFile=".\mod_shib20___Win32_Release/mod_shib_20.pdb"
ImportLibrary=".\mod_shib20___Win32_Release/mod_shib_20.lib"
TargetMachine="1"
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="log4cppD.lib xerces-c_2D.lib libapr.lib libhttpd.lib xmltooling-lite1D.lib"
+ AdditionalDependencies="log4cppD.lib xerces-c_2D.lib libapr.lib libaprutil.lib libhttpd.lib xmltooling-lite1D.lib"
OutputFile="mod_shib20___Win32_Debug/mod_shib_20.so"
LinkIncremental="2"
SuppressStartupBanner="true"
- AdditionalLibraryDirectories=""..\..\cpp-xmltooling\Debug";\httpd-2.0.52\srclib\apr\Debug,\httpd-2.0.52\Debug"
+ AdditionalLibraryDirectories=""..\..\cpp-xmltooling\Debug";\Apache2D\lib"
GenerateDebugInformation="true"
ImportLibrary=".\mod_shib20___Win32_Debug/mod_shib_20.lib"
TargetMachine="1"
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4cpp.lib xerces-c_2.lib xmltooling-lite1.lib libapr-1.lib libhttpd.lib"\r
+ AdditionalDependencies="log4cpp.lib xerces-c_2.lib xmltooling-lite1.lib libapr-1.lib libaprutil-1.lib libhttpd.lib"\r
OutputFile="mod_shib22___Win32_Release/mod_shib_22.so"\r
LinkIncremental="1"\r
SuppressStartupBanner="true"\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4cppD.lib xerces-c_2D.lib xmltooling-lite1D.lib libapr-1.lib libhttpd.lib"\r
+ AdditionalDependencies="log4cppD.lib xerces-c_2D.lib xmltooling-lite1D.lib libapr-1.lib libaprutil-1.lib libhttpd.lib"\r
OutputFile="mod_shib22___Win32_Debug/mod_shib_22.so"\r
LinkIncremental="2"\r
SuppressStartupBanner="true"\r
-->
<!-- Default example directs to a specific IdP's SSO service (favoring SAML 2 over Shib 1). -->
- <SessionInitiator type="Chaining" Location="/Login" isDefault="true" id="example.org"
+ <SessionInitiator type="Chaining" Location="/Login" isDefault="true" id="idp.example.org"
relayState="cookie" entityID="https://idp.example.org/shibboleth">
- <SessionInitiator type="SAML2" template="@-PKGSYSCONFDIR-@/bindingTemplate.html"/>
- <SessionInitiator type="Shibboleth"/>
+ <SessionInitiator type="SAML2" defaultACSIndex="1" template="@-PKGSYSCONFDIR-@/bindingTemplate.html"/>
+ <SessionInitiator type="Shibboleth" defaultACSIndex="3"/>
</SessionInitiator>
<!-- An example using an old-style WAYF, which means Shib 1 only unless an entityID is provided. -->
<SessionInitiator type="Chaining" Location="/WAYF" id="WAYF" relayState="cookie">
- <SessionInitiator type="SAML2" template="@-PKGSYSCONFDIR-@/bindingTemplate.html"/>
- <SessionInitiator type="Shibboleth"/>
- <SessionInitiator type="WAYF" URL="https://wayf.example.org/WAYF"/>
+ <SessionInitiator type="SAML2" defaultACSIndex="1" template="@-PKGSYSCONFDIR-@/bindingTemplate.html"/>
+ <SessionInitiator type="Shibboleth" defaultACSIndex="3"/>
+ <SessionInitiator type="WAYF" defaultACSIndex="3" URL="https://wayf.example.org/WAYF"/>
</SessionInitiator>
<!-- An example supporting the new-style of discovery service. -->
<SessionInitiator type="Chaining" Location="/DS" id="DS" relayState="cookie">
<SessionInitiator type="SAML2" template="@-PKGSYSCONFDIR-@/bindingTemplate.html"/>
- <SessionInitiator type="Shibboleth"/>
+ <SessionInitiator type="Shibboleth" defaultACSIndex="3"/>
<SessionInitiator type="SAMLDS" URL="https://ds.example.org/DS"/>
</SessionInitiator>
are used when sessions are initiated to determine how to tell the IdP where and
how to return the response.
-->
- <md:AssertionConsumerService Location="/SAML2/POST" index="1" isDefault="true"
+ <md:AssertionConsumerService Location="/SAML2/POST" index="1"
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"/>
<md:AssertionConsumerService Location="/SAML2/Artifact" index="2"
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"/>
<attribute name="template" type="anyURI"/>\r
<attribute name="postArtifact" type="boolean"/>\r
<attribute name="acsByIndex" type="boolean"/>\r
+ <attribute name="defaultACSIndex" type="unsignedShort"/>\r
<anyAttribute namespace="##any" processContents="lax"/>\r
</restriction>\r
</complexContent>\r
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");
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<bool,unsigned int> 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.
}
// 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<bool,const char*> loc=ACS ? ACS->getString("Location") : pair<bool,const char*>(false,NULL);
}
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<bool,const char*> loc=ACS ? ACS->getString("Location") : pair<bool,const char*>(false,NULL);
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)
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<bool,unsigned int> 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());
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)
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<bool,unsigned int> 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);