[cpp-sp] branch main updated: Migrate components off of Application class.
Scott Cantor
cantor.2 at osu.edu
Tue Jan 7 01:55:15 UTC 2025
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository cpp-sp.
View the commit online:
http://git.shibboleth.net/view/?p=cpp-sp.git;a=commit;h=6853fdd9a008f00c49dc10ce206b33dc334046c2
The following commit(s) were added to refs/heads/main by this push:
new 6853fdd9 Migrate components off of Application class.
6853fdd9 is described below
commit 6853fdd9a008f00c49dc10ce206b33dc334046c2
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Mon Jan 6 20:55:07 2025 -0500
Migrate components off of Application class.
---
apache/mod_shib_24.cpp | 9 +-
shibsp/AbstractSPRequest.cpp | 316 +++++++++++++++++------
shibsp/AbstractSPRequest.h | 9 +-
shibsp/Agent.cpp | 8 +-
shibsp/Agent.h | 11 +-
shibsp/SPRequest.h | 54 ++--
shibsp/ServiceProvider.cpp | 41 ++-
shibsp/ServiceProvider.h | 10 +-
shibsp/SessionCache.h | 65 ++---
shibsp/handler/AbstractHandler.h | 33 +--
shibsp/handler/AssertionConsumerService.h | 41 +--
shibsp/handler/Handler.h | 48 +---
shibsp/handler/LogoutHandler.h | 27 +-
shibsp/handler/impl/AbstractHandler.cpp | 152 +++++------
shibsp/handler/impl/AdminLogoutInitiator.cpp | 46 ++--
shibsp/handler/impl/AssertionConsumerService.cpp | 63 ++---
shibsp/handler/impl/AssertionLookup.cpp | 9 +-
shibsp/handler/impl/AttributeCheckerHandler.cpp | 24 +-
shibsp/handler/impl/DiscoveryFeed.cpp | 31 +--
shibsp/handler/impl/LocalLogoutInitiator.cpp | 35 ++-
shibsp/handler/impl/LogoutHandler.cpp | 73 +-----
shibsp/handler/impl/MetadataGenerator.cpp | 23 +-
shibsp/handler/impl/RemotedHandler.cpp | 2 -
shibsp/handler/impl/SAML2Logout.cpp | 10 +-
shibsp/handler/impl/SAML2LogoutInitiator.cpp | 21 +-
shibsp/handler/impl/SAML2SessionInitiator.cpp | 29 +--
shibsp/handler/impl/SAMLDSSessionInitiator.cpp | 31 ++-
shibsp/handler/impl/SessionHandler.cpp | 1 -
shibsp/handler/impl/SessionInitiator.cpp | 8 +-
shibsp/handler/impl/StatusHandler.cpp | 14 +-
shibsp/impl/StorageServiceSessionCache.cpp | 251 +++++-------------
shibsp/impl/StorageServiceSessionCache.h | 53 ++--
shibsp/impl/StoredSession.cpp | 213 +--------------
shibsp/impl/StoredSession.h | 7 +-
tests/impl/XMLAccessControlTests.cpp | 2 +-
tests/impl/XMLRequestMapperTests.cpp | 2 +-
36 files changed, 668 insertions(+), 1104 deletions(-)
diff --git a/apache/mod_shib_24.cpp b/apache/mod_shib_24.cpp
index 8edfe411..dd770805 100644
--- a/apache/mod_shib_24.cpp
+++ b/apache/mod_shib_24.cpp
@@ -39,6 +39,7 @@
#include <shibsp/exceptions.h>
#include <shibsp/AbstractSPRequest.h>
#include <shibsp/AccessControl.h>
+#include <shibsp/Agent.h>
#include <shibsp/AgentConfig.h>
#include <shibsp/RequestMapper.h>
#include <shibsp/SPConfig.h>
@@ -648,7 +649,7 @@ extern "C" int shib_check_user(request_rec* r)
}
// Check user authentication and export information, then set the handler bypass
- pair<bool,long> res = psta->getServiceProvider().doAuthentication(*psta, true);
+ pair<bool,long> res = psta->getAgent().doAuthentication(*psta, true);
apr_pool_userdata_setn((const void*)42,g_UserDataKey,nullptr,r->pool);
// If directed, install a spoof key to recognize when we've already cleared headers.
if (!g_spoofKey.empty() && (((shib_dir_config*)ap_get_module_config(r->per_dir_config, &shib_module))->bUseHeaders == 1))
@@ -664,7 +665,7 @@ extern "C" int shib_check_user(request_rec* r)
}
// user auth was okay -- export the session data now
- res = psta->getServiceProvider().doExport(*psta);
+ res = psta->getAgent().doExport(*psta);
if (res.first) {
// See above for explanation of this hack.
if (res.second == OK && !r->user)
@@ -722,7 +723,7 @@ extern "C" int shib_handler(request_rec* r)
return HTTP_INTERNAL_SERVER_ERROR;
}
- pair<bool,long> res = psta->getServiceProvider().doHandler(*psta);
+ pair<bool,long> res = psta->getAgent().doHandler(*psta);
if (res.first) return res.second;
ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r, "doHandler() did not handle the request");
@@ -769,7 +770,7 @@ extern "C" int shib_auth_checker(request_rec* r)
return HTTP_INTERNAL_SERVER_ERROR;
}
- pair<bool,long> res = psta->getServiceProvider().doAuthorization(*psta);
+ pair<bool,long> res = psta->getAgent().doAuthorization(*psta);
if (res.first) return res.second;
// The SP method should always return true, so if we get this far, something unusual happened.
diff --git a/shibsp/AbstractSPRequest.cpp b/shibsp/AbstractSPRequest.cpp
index ea49d8fc..903457ef 100644
--- a/shibsp/AbstractSPRequest.cpp
+++ b/shibsp/AbstractSPRequest.cpp
@@ -23,13 +23,16 @@
#include "AbstractSPRequest.h"
#include "Agent.h"
#include "AgentConfig.h"
-#include "Application.h"
-#include "ServiceProvider.h"
#include "SessionCache.h"
#include "logging/Category.h"
#include "util/CGIParser.h"
#include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
+
+#ifndef HAVE_STRCASECMP
+# define strncasecmp _strnicmp
+#endif
using namespace shibsp;
using namespace std;
@@ -46,11 +49,8 @@ SPRequest::~SPRequest()
AbstractSPRequest::AbstractSPRequest(const char* category)
: m_log(Category::getInstance(category)),
m_agent(AgentConfig::getConfig().getAgent()),
- m_sp(SPConfig::getConfig().getServiceProvider()),
- m_mapper(nullptr), m_app(nullptr), m_sessionTried(false), m_session(nullptr)
+ m_mapper(nullptr), m_sessionTried(false), m_session(nullptr)
{
- if (m_sp)
- m_sp->lock();
}
AbstractSPRequest::~AbstractSPRequest()
@@ -59,8 +59,6 @@ AbstractSPRequest::~AbstractSPRequest()
m_session->unlock();
if (m_mapper)
m_mapper->unlock_shared();
- if (m_sp)
- m_sp->unlock();
}
const Agent& AbstractSPRequest::getAgent() const
@@ -68,11 +66,6 @@ const Agent& AbstractSPRequest::getAgent() const
return m_agent;
}
-const ServiceProvider& AbstractSPRequest::getServiceProvider() const
-{
- return *m_sp;
-}
-
RequestMapper::Settings AbstractSPRequest::getRequestSettings() const
{
if (!m_mapper) {
@@ -88,17 +81,6 @@ RequestMapper::Settings AbstractSPRequest::getRequestSettings() const
return m_settings;
}
-const Application& AbstractSPRequest::getApplication() const
-{
- if (!m_app) {
- // Now find the application from the URL settings
- m_app = m_sp->getApplication(getRequestSettings().first->getString("applicationId"));
- if (!m_app)
- throw ConfigurationException("Unable to map non-default applicationId to an ApplicationOverride, check configuration.");
- }
- return *m_app;
-}
-
Session* AbstractSPRequest::getSession(bool checkTimeout, bool ignoreAddress, bool cache)
{
// Only attempt this once.
@@ -118,7 +100,7 @@ Session* AbstractSPRequest::getSession(bool checkTimeout, bool ignoreAddress, bo
// The cache will either silently pass a session or nullptr back, or throw an exception out.
Session* session = getAgent().getSessionCache()->find(
- getApplication(), *this, (ignoreAddress ? nullptr : getRemoteAddr().c_str()), (checkTimeout ? &timeout : nullptr)
+ *this, (ignoreAddress ? nullptr : getRemoteAddr().c_str()), (checkTimeout ? &timeout : nullptr)
);
if (cache)
m_session = session;
@@ -180,6 +162,52 @@ vector<const char*>::size_type AbstractSPRequest::getParameters(const char* name
return values.size();
}
+string AbstractSPRequest::getCookieName(const char* prefix, time_t* lifetime) const
+{
+ if (lifetime) {
+ *lifetime = getRequestSettings().first->getUnsignedInt("cookieLifetime", 0);
+ }
+
+ if (!prefix)
+ prefix = "";
+
+ const char* p = getRequestSettings().first->getString("cookieName");
+ if (p) {
+ return string(prefix) + p;
+ }
+
+ return string(prefix); // + getHash(); TODO: uniqueify the cookie name
+}
+
+pair<string,const char*> AbstractSPRequest::getCookieNameProps(const char* prefix, time_t* lifetime) const
+{
+ static const char* defProps="; path=/; HttpOnly";
+ static const char* sslProps="; path=/; secure; HttpOnly";
+
+ if (lifetime) {
+ *lifetime = getRequestSettings().first->getUnsignedInt("cookieLifetime", 0);
+ }
+
+ if (!prefix)
+ prefix = "";
+
+ const char* cookieProps = getRequestSettings().first->getString("cookieProps");
+ if (!cookieProps || !strcasecmp(cookieProps, "http")) {
+ cookieProps = defProps;
+ }
+ else if (!strcasecmp(cookieProps, "https")) {
+ cookieProps = sslProps;
+ }
+
+ const char* cookieName = getRequestSettings().first->getString("cookieName");
+ if (cookieName) {
+ return make_pair(string(prefix) + cookieName, cookieProps);
+ }
+
+ // TODO: uniqueify the cookie name
+ return make_pair(string(prefix) /* + getHash() */, cookieProps);
+}
+
const char* AbstractSPRequest::getHandlerURL(const char* resource) const
{
if (!resource)
@@ -208,25 +236,11 @@ const char* AbstractSPRequest::getHandlerURL(const char* resource) const
#endif
throw ConfigurationException("Target resource was not an absolute URL.");
- bool ssl_only = true;
- const char* handler = nullptr;
- const PropertySet* props = getApplication().getPropertySet("Sessions");
- if (props) {
- pair<bool,bool> p = props->getBool("handlerSSL");
- if (p.first)
- ssl_only = p.second;
- pair<bool,const char*> p2 = props->getString("handlerURL");
- if (p2.first)
- handler = p2.second;
- }
+ bool ssl_only = getRequestSettings().first->getBool("handlerSSL", true);
+ const char* handler = getRequestSettings().first->getString("handlerURL", "/Shibboleth.sso");
- if (!handler) {
- handler = "/Shibboleth.sso";
- }
- else if (*handler!='/' && strncmp(handler,"http:",5) && strncmp(handler,"https:",6)) {
- throw ConfigurationException(
- string("Invalid handlerURL property in <Sessions> element for Application ") + m_app->getId()
- );
+ if (*handler!='/' && strncmp(handler,"http:",5) && strncmp(handler,"https:",6)) {
+ throw ConfigurationException(string("Invalid handlerURL property: ") + handler);
}
// The "handlerURL" property can be in one of three formats:
@@ -282,6 +296,170 @@ const char* AbstractSPRequest::getHandlerURL(const char* resource) const
return m_handlerURL.c_str();
}
+string AbstractSPRequest::getNotificationURL(bool front, unsigned int index) const
+{
+ // We have to process the underlying setting each call to this method unfortunately.
+ const char* rawlocs = getRequestSettings().first->getString(front ? "frontNotifyURLs" : "backNotifyURLs");
+ vector<string> locs;
+ boost::split(locs, rawlocs, boost::is_space(), boost::algorithm::token_compress_on);
+
+ if (index >= locs.size())
+ return string();
+
+ const char* resource = getRequestURL();
+ if (!resource || (strncasecmp(resource,"http://", 7) && strncasecmp(resource,"https://", 8))) {
+ throw ConfigurationException("Request URL was not absolute.");
+ }
+
+ const char* handler = locs[index].c_str();
+
+ // Should never happen...
+ if (!handler || (*handler!='/' && strncasecmp(handler, "http:", 5) && strncasecmp(handler, "https:", 6))) {
+ throw ConfigurationException("Invalid Location property in Notify element");
+ }
+
+ // The "Location" property can be in one of three formats:
+ //
+ // 1) a full URI: http://host/foo/bar
+ // 2) a hostless URI: http:///foo/bar
+ // 3) a relative path: /foo/bar
+ //
+ // # Protocol Host Path
+ // 1 handler handler handler
+ // 2 handler resource handler
+ // 3 resource resource handler
+
+ const char* path = nullptr;
+
+ // Decide whether to use the handler or the resource for the "protocol"
+ const char* prot;
+ if (*handler != '/') {
+ prot = handler;
+ }
+ else {
+ prot = resource;
+ path = handler;
+ }
+
+ // break apart the "protocol" string into protocol, host, and "the rest"
+ const char* colon=strchr(prot,':');
+ colon += 3;
+ const char* slash=strchr(colon,'/');
+ if (!path)
+ path = slash;
+
+ // Compute the actual protocol and store.
+ string notifyURL(prot, colon-prot);
+
+ // create the "host" from either the colon/slash or from the target string
+ // If prot == handler then we're in either #1 or #2, else #3.
+ // If slash == colon then we're in #2.
+ if (prot != handler || slash == colon) {
+ colon = strchr(resource, ':');
+ colon += 3; // Get past the ://
+ slash = strchr(colon, '/');
+ }
+ string host(colon, (slash ? slash-colon : strlen(colon)));
+
+ // Build the URL
+ notifyURL += host + path;
+ return notifyURL;
+}
+
+void AbstractSPRequest::limitRedirect(const char* url) const
+{
+ if (!url || *url == '/')
+ return;
+
+ enum {
+ REDIRECT_LIMIT_NONE,
+ REDIRECT_LIMIT_EXACT,
+ REDIRECT_LIMIT_HOST,
+ REDIRECT_LIMIT_ALLOW,
+ REDIRECT_LIMIT_EXACT_ALLOW,
+ REDIRECT_LIMIT_HOST_ALLOW
+ } redirectLimit;
+
+ // Derive the active rule.
+ vector<string> redirectAllow;
+ const char* prop = getRequestSettings().first->getString("redirectLimit", "exact");
+ if (!strcmp(prop, "none")) {
+ redirectLimit = REDIRECT_LIMIT_NONE;
+ }
+ else if (!strcmp(prop, "exact")) {
+ redirectLimit = REDIRECT_LIMIT_EXACT;
+ }
+ else if (!strcmp(prop, "host")) {
+ redirectLimit = REDIRECT_LIMIT_HOST;
+ }
+ else {
+ if (!strcmp(prop, "exact+allow")) {
+ redirectLimit = REDIRECT_LIMIT_EXACT_ALLOW;
+ }
+ else if (!strcmp(prop, "host+allow")) {
+ redirectLimit = REDIRECT_LIMIT_HOST_ALLOW;
+ }
+ else if (!strcmp(prop, "allow")) {
+ redirectLimit = REDIRECT_LIMIT_ALLOW;
+ }
+ else {
+ m_log.error("unrecognized redirectLimit setting (%s), falling back to 'exact' ", prop);
+ }
+ prop = getRequestSettings().first->getString("redirectAllow");
+ if (prop) {
+ string dup(prop);
+ boost::trim(dup);
+ boost::split(redirectAllow, dup, boost::is_space(), boost::algorithm::token_compress_on);
+ }
+ }
+
+ if (redirectLimit != REDIRECT_LIMIT_NONE) {
+
+ // This is ugly, but the purpose is to prevent blocking legitimate redirects
+ // that lack a trailing slash after the hostname. If there are fewer than 3
+ // slashes, we assume the hostname wasn't terminated.
+ string urlcopy(url);
+ if (count(urlcopy.begin(), urlcopy.end(), '/') < 3) {
+ urlcopy += '/';
+ }
+
+ vector<string> allowlist;
+ if (redirectLimit == REDIRECT_LIMIT_EXACT || redirectLimit == REDIRECT_LIMIT_EXACT_ALLOW) {
+ // Scheme and hostname have to match.
+ if (isDefaultPort()) {
+ allowlist.push_back(string(getScheme()) + "://" + getHostname() + '/');
+ }
+ allowlist.push_back(string(getScheme()) + "://" + getHostname() + ':' + boost::lexical_cast<string>(getPort()) + '/');
+ }
+ else if (redirectLimit == REDIRECT_LIMIT_HOST || redirectLimit == REDIRECT_LIMIT_HOST_ALLOW) {
+ // Allow any scheme or port.
+ allowlist.push_back(string("https://") + getHostname() + '/');
+ allowlist.push_back(string("http://") + getHostname() + '/');
+ allowlist.push_back(string("https://") + getHostname() + ':');
+ allowlist.push_back(string("http://") + getHostname() + ':');
+ }
+
+ if (!allowlist.empty()) {
+ for (const string& s : allowlist) {
+ if (boost::istarts_with(urlcopy, s)) {
+ return;
+ }
+ }
+ }
+
+ if (!redirectAllow.empty()) {
+ for (const string& s : redirectAllow) {
+ if (boost::istarts_with(urlcopy, s)) {
+ return;
+ }
+ }
+ }
+
+ m_log.warn("redirectLimit policy enforced, blocked redirect to (%s)", url);
+ throw agent_exception("Blocked unacceptable redirect location.");
+ }
+}
+
string AbstractSPRequest::getSecureHeader(const char* name) const
{
return getHeader(name);
@@ -294,50 +472,32 @@ void AbstractSPRequest::setAuthType(const char* authtype)
const char* AbstractSPRequest::getCookie(const char* name) const
{
- pair<bool, bool> sameSiteFallback = pair<bool, bool>(false, false);
- const PropertySet* props = getApplication().getPropertySet("Sessions");
- if (props) {
- sameSiteFallback = props->getBool("sameSiteFallback");
- }
- return HTTPRequest::getCookie(name, sameSiteFallback.first && sameSiteFallback.second);
+ bool sameSiteFallback = getRequestSettings().first->getBool("sameSiteFallback", false);
+ return HTTPRequest::getCookie(name, sameSiteFallback);
}
void AbstractSPRequest::setCookie(const char* name, const char* value, time_t expires, samesite_t sameSite)
{
+ bool sameSiteFallback = false;
+ if (sameSite == SAMESITE_NONE) {
+ sameSiteFallback = getRequestSettings().first->getBool("sameSiteFallback", false);
+ }
+
static const char* defProps="; path=/; HttpOnly";
static const char* sslProps="; path=/; secure; HttpOnly";
- const char* cookieProps = defProps;
- pair<bool,bool> sameSiteFallback = pair<bool,bool>(false, false);
-
- const PropertySet* props = getApplication().getPropertySet("Sessions");
- if (props) {
- if (sameSite == SAMESITE_NONE) {
- sameSiteFallback = props->getBool("sameSiteFallback");
- }
-
- pair<bool, const char*> p = props->getString("cookieProps");
- if (p.first) {
- if (!strcmp(p.second, "https"))
- cookieProps = sslProps;
- else if (strcmp(p.second, "http"))
- cookieProps = p.second;
- }
- }
+ const char* cookieProps = getRequestSettings().first->getString("cookieProps", defProps);
+ if (!strcmp(cookieProps, "https"))
+ cookieProps = sslProps;
+ else if (!strcmp(cookieProps, "http"))
+ cookieProps = defProps;
- if (cookieProps) {
- string decoratedValue(value ? value : "");
- if (!value) {
- decoratedValue += "; expires=Mon, 01 Jan 2001 00:00:00 GMT";
- }
- decoratedValue += cookieProps;
- HTTPResponse::setCookie(name, decoratedValue.c_str(), expires, sameSite,
- sameSiteFallback.first && sameSiteFallback.second);
- }
- else {
- HTTPResponse::setCookie(name, value, expires, sameSite,
- sameSiteFallback.first && sameSiteFallback.second);
+ string decoratedValue(value ? value : "");
+ if (!value) {
+ decoratedValue += "; expires=Mon, 01 Jan 2001 00:00:00 GMT";
}
+ decoratedValue += cookieProps;
+ HTTPResponse::setCookie(name, decoratedValue.c_str(), expires, sameSite, sameSiteFallback);
}
void AbstractSPRequest::log(Priority::Value level, const std::string& msg) const
diff --git a/shibsp/AbstractSPRequest.h b/shibsp/AbstractSPRequest.h
index 09cfc494..58ba818c 100644
--- a/shibsp/AbstractSPRequest.h
+++ b/shibsp/AbstractSPRequest.h
@@ -61,16 +61,19 @@ namespace shibsp {
// Virtual function overrides.
const Agent& getAgent() const;
- const ServiceProvider& getServiceProvider() const;
RequestMapper::Settings getRequestSettings() const;
- const Application& getApplication() const;
Session* getSession(bool checkTimeout=true, bool ignoreAddress=false, bool cache=true);
const char* getRequestURI() const;
const char* getRequestURL() const;
std::string getRemoteAddr() const;
const char* getParameter(const char* name) const;
std::vector<const char*>::size_type getParameters(const char* name, std::vector<const char*>& values) const;
+ std::string getCookieName(const char* prefix, time_t* lifetime) const;
+ std::pair<std::string,const char*> getCookieNameProps(const char* prefix, time_t* lifetime) const;
const char* getHandlerURL(const char* resource=nullptr) const;
+ std::string getNotificationURL(bool front, unsigned int index) const;
+ void limitRedirect(const char* url) const;
+
std::string getSecureHeader(const char* name) const;
const char* getCookie(const char* name) const;
void setAuthType(const char* authtype);
@@ -81,10 +84,8 @@ namespace shibsp {
private:
Category& m_log;
Agent& m_agent;
- ServiceProvider* m_sp; // TODO: remove
mutable RequestMapper* m_mapper;
mutable RequestMapper::Settings m_settings;
- mutable const Application* m_app; // TODO: remove
mutable bool m_sessionTried;
mutable Session* m_session;
std::string m_uri;
diff --git a/shibsp/Agent.cpp b/shibsp/Agent.cpp
index 5510d696..90422ca6 100644
--- a/shibsp/Agent.cpp
+++ b/shibsp/Agent.cpp
@@ -54,25 +54,25 @@ Agent::~Agent()
// TODO: we'll eventually copy/port in substantially similar versions of the old ServiceProvider
// method impls.
-pair<bool,long> Agent::doAuthentication(AgentRequest& request, bool handler) const
+pair<bool,long> Agent::doAuthentication(SPRequest& request, bool handler) const
{
pair<bool,long> foo;
return foo;
}
-pair<bool,long> Agent::doAuthorization(AgentRequest& request) const
+pair<bool,long> Agent::doAuthorization(SPRequest& request) const
{
pair<bool, long> foo;
return foo;
}
-pair<bool,long> Agent::doExport(AgentRequest& request, bool requireSession) const
+pair<bool,long> Agent::doExport(SPRequest& request, bool requireSession) const
{
pair<bool, long> foo;
return foo;
}
-pair<bool,long> Agent::doHandler(AgentRequest& request) const
+pair<bool,long> Agent::doHandler(SPRequest& request) const
{
pair<bool, long> foo;
return foo;
diff --git a/shibsp/Agent.h b/shibsp/Agent.h
index 408499cd..832a7178 100644
--- a/shibsp/Agent.h
+++ b/shibsp/Agent.h
@@ -32,7 +32,8 @@ namespace shibsp {
class SHIBSP_API RemotingService;
class SHIBSP_API RequestMapper;
class SHIBSP_API SessionCache;
- class SHIBSP_API AgentRequest;
+ //class SHIBSP_API AgentRequest;
+ class SHIBSP_API SPRequest;
#if defined (_MSC_VER)
#pragma warning( push )
@@ -96,7 +97,7 @@ namespace shibsp {
* @param handler true iff a request to a registered Handler location can be directly executed
* @return a pair containing a "request completed" indicator and a server-specific response code
*/
- virtual std::pair<bool,long> doAuthentication(AgentRequest& request, bool handler=false) const;
+ virtual std::pair<bool,long> doAuthentication(SPRequest& request, bool handler=false) const;
/**
* Enforces authorization requirements based on the authenticated session.
@@ -107,7 +108,7 @@ namespace shibsp {
* @param request SP request interface
* @return a pair containing a "request completed" indicator and a server-specific response code
*/
- virtual std::pair<bool,long> doAuthorization(AgentRequest& request) const;
+ virtual std::pair<bool,long> doAuthorization(SPRequest& request) const;
/**
* Publishes session contents to the request in the form of headers or environment variables.
@@ -119,7 +120,7 @@ namespace shibsp {
* @param requireSession set to true iff an error should result if no session exists
* @return a pair containing a "request completed" indicator and a server-specific response code
*/
- virtual std::pair<bool,long> doExport(AgentRequest& request, bool requireSession=true) const;
+ virtual std::pair<bool,long> doExport(SPRequest& request, bool requireSession=true) const;
/**
* Services requests for registered Handler locations.
@@ -130,7 +131,7 @@ namespace shibsp {
* @param request SP request interface
* @return a pair containing a "request completed" indicator and a server-specific response code
*/
- virtual std::pair<bool,long> doHandler(AgentRequest& request) const;
+ virtual std::pair<bool,long> doHandler(SPRequest& request) const;
protected:
/** The AuthTypes to "recognize" (defaults to "shibboleth"). */
diff --git a/shibsp/SPRequest.h b/shibsp/SPRequest.h
index cead45fd..fd067243 100644
--- a/shibsp/SPRequest.h
+++ b/shibsp/SPRequest.h
@@ -56,15 +56,6 @@ namespace shibsp {
*/
virtual const Agent& getAgent() const=0;
- /**
- * Returns the locked ServiceProvider processing the request.
- *
- * TODO: remove
- *
- * @return reference to ServiceProvider
- */
- virtual const ServiceProvider& getServiceProvider() const=0;
-
/**
* Returns RequestMapper Settings associated with the request, guaranteed
* to be valid for the request's duration.
@@ -73,15 +64,6 @@ namespace shibsp {
*/
virtual RequestMapper::Settings getRequestSettings() const=0;
- /**
- * Returns the Application governing the request.
- *
- * TODO: remove
- *
- * @return reference to Application
- */
- virtual const Application& getApplication() const=0;
-
/**
* Returns a locked Session associated with the request.
*
@@ -92,6 +74,24 @@ namespace shibsp {
*/
virtual Session* getSession(bool checkTimeout=true, bool ignoreAddress=false, bool cache=true)=0;
+ /**
+ * Returns the cookies name to use for this request.
+ *
+ * @param prefix a value to prepend to the base cookie name
+ * @param lifetime if non-null, will be populated with a suggested lifetime for the cookie, or 0 if session-bound
+ * @return the assigned cookie name to use
+ */
+ virtual std::string getCookieName(const char* prefix, time_t* lifetime=nullptr) const=0;
+
+ /**
+ * Returns the name and cookie properties to use for this request.
+ *
+ * @param prefix a value to prepend to the base cookie name
+ * @param lifetime if non-null, will be populated with a suggested lifetime for the cookie, or 0 if session-bound
+ * @return a pair containing the cookie name and the string to append to the cookie value
+ */
+ virtual std::pair<std::string,const char*> getCookieNameProps(const char* prefix, time_t* lifetime=nullptr) const=0;
+
/**
* Returns the effective base Handler URL for a resource,
* or the current request URL.
@@ -101,6 +101,24 @@ namespace shibsp {
*/
virtual const char* getHandlerURL(const char* resource=nullptr) const=0;
+ /**
+ * Returns the designated notification URL, or an empty string if no more locations are specified.
+ *
+ * @param front true iff front channel notification is desired, false iff back channel is desired
+ * @param index zero-based index of URL to return
+ * @return the designated URL, or an empty string
+ */
+ virtual std::string getNotificationURL(bool front, unsigned int index) const=0;
+
+ /**
+ * Checks a proposed redirect URL against policy settings for legal redirects,
+ * such as same-host restrictions or allowed domains, and raises an exception
+ * in the event of a violation.
+ *
+ * @param url an absolute URL to validate
+ */
+ virtual void limitRedirect(const char* url) const=0;
+
/**
* Returns a non-spoofable request header value, if possible.
* Platforms that support environment export can redirect header
diff --git a/shibsp/ServiceProvider.cpp b/shibsp/ServiceProvider.cpp
index 99aa1f33..2d041fd9 100644
--- a/shibsp/ServiceProvider.cpp
+++ b/shibsp/ServiceProvider.cpp
@@ -92,21 +92,21 @@ namespace shibsp {
}
void SHIBSP_DLLLOCAL clearHeaders(SPRequest& request) {
- const Application& app = request.getApplication();
- app.clearHeader(request, "Shib-Cookie-Name", "HTTP_SHIB_COOKIE_NAME");
- app.clearHeader(request, "Shib-Session-ID", "HTTP_SHIB_SESSION_ID");
- app.clearHeader(request, "Shib-Session-Index", "HTTP_SHIB_SESSION_INDEX");
- app.clearHeader(request, "Shib-Session-Expires", "HTTP_SHIB_SESSION_EXPIRES");
- app.clearHeader(request, "Shib-Session-Inactivity", "HTTP_SHIB_SESSION_INACTIVITY");
- app.clearHeader(request, "Shib-Identity-Provider", "HTTP_SHIB_IDENTITY_PROVIDER");
- app.clearHeader(request, "Shib-Authentication-Method", "HTTP_SHIB_AUTHENTICATION_METHOD");
- app.clearHeader(request, "Shib-Authentication-Instant", "HTTP_SHIB_AUTHENTICATION_INSTANT");
- app.clearHeader(request, "Shib-AuthnContext-Class", "HTTP_SHIB_AUTHNCONTEXT_CLASS");
- app.clearHeader(request, "Shib-AuthnContext-Decl", "HTTP_SHIB_AUTHNCONTEXT_DECL");
- app.clearHeader(request, "Shib-Assertion-Count", "HTTP_SHIB_ASSERTION_COUNT");
- app.clearHeader(request, "Shib-Handler", "HTTP_SHIB_HANDLER");
- app.clearAttributeHeaders(request);
+ request.clearHeader("Shib-Cookie-Name", "HTTP_SHIB_COOKIE_NAME");
+ request.clearHeader("Shib-Session-ID", "HTTP_SHIB_SESSION_ID");
+ request.clearHeader("Shib-Session-Index", "HTTP_SHIB_SESSION_INDEX");
+ request.clearHeader("Shib-Session-Expires", "HTTP_SHIB_SESSION_EXPIRES");
+ request.clearHeader("Shib-Session-Inactivity", "HTTP_SHIB_SESSION_INACTIVITY");
+ request.clearHeader("Shib-Identity-Provider", "HTTP_SHIB_IDENTITY_PROVIDER");
+ request.clearHeader("Shib-Authentication-Method", "HTTP_SHIB_AUTHENTICATION_METHOD");
+ request.clearHeader("Shib-Authentication-Instant", "HTTP_SHIB_AUTHENTICATION_INSTANT");
+ request.clearHeader("Shib-AuthnContext-Class", "HTTP_SHIB_AUTHNCONTEXT_CLASS");
+ request.clearHeader("Shib-AuthnContext-Decl", "HTTP_SHIB_AUTHNCONTEXT_DECL");
+ request.clearHeader("Shib-Assertion-Count", "HTTP_SHIB_ASSERTION_COUNT");
+ request.clearHeader("Shib-Handler", "HTTP_SHIB_HANDLER");
request.clearHeader("REMOTE_USER", "HTTP_REMOTE_USER");
+ // TODO: Redo the handling of attribute headers in the code, likely supplanting all of the above...
+ //request.clearAttributeHeaders();
}
void SHIBSP_DLLLOCAL exportAttributes(SPRequest& request, const Session* session, RequestMapper::Settings settings) {
@@ -129,7 +129,7 @@ namespace shibsp {
for (multimap<string,const Attribute*>::const_iterator a = attributes.begin(); a != attributes.end(); ++a) {
if (a->second->isInternal())
continue;
- string header(request.getApplication().getSecureHeader(request, a->first.c_str()));
+ string header(request.getSecureHeader(a->first.c_str()));
const vector<string>& vals = a->second->getSerializedValues();
for (vector<string>::const_iterator v = vals.begin(); v != vals.end(); ++v) {
if (!header.empty())
@@ -153,7 +153,7 @@ namespace shibsp {
}
}
}
- request.getApplication().setHeader(request, a->first.c_str(), header.c_str());
+ request.setHeader(a->first.c_str(), header.c_str());
}
}
else {
@@ -191,13 +191,14 @@ namespace shibsp {
}
}
}
- request.getApplication().setHeader(request, deduped->first.c_str(), header.c_str());
+ request.setHeader(deduped->first.c_str(), header.c_str());
}
}
// Check for REMOTE_USER.
bool remoteUserSet = false;
- const vector<string>& rmids = request.getApplication().getRemoteUserAttributeIds();
+ vector<string> dummy;
+ const vector<string>& rmids = dummy; // app.getRemoteUserAttributeIds(); TODO: re implement this elsewhere
for (vector<string>::const_iterator rmid = rmids.begin(); !remoteUserSet && rmid != rmids.end(); ++rmid) {
pair<multimap<string,const Attribute*>::const_iterator,multimap<string,const Attribute*>::const_iterator> matches =
attributes.equal_range(*rmid);
@@ -239,7 +240,6 @@ pair<bool,long> ServiceProvider::doAuthentication(SPRequest& request, bool handl
try {
RequestMapper::Settings settings = request.getRequestSettings();
- app = &(request.getApplication());
// If not SSL, check to see if we should block or redirect it.
if (!request.isSecure()) {
@@ -380,7 +380,6 @@ pair<bool,long> ServiceProvider::doAuthorization(SPRequest& request) const
try {
RequestMapper::Settings settings = request.getRequestSettings();
- app = &(request.getApplication());
// Three settings dictate how to proceed.
const char* authType = settings.first->getString("authType");
@@ -449,7 +448,6 @@ pair<bool,long> ServiceProvider::doExport(SPRequest& request, bool requireSessio
try {
RequestMapper::Settings settings = request.getRequestSettings();
- app = &(request.getApplication());
try {
session = request.getSession(false, false, false); // ignore timeout and do not cache
@@ -533,7 +531,6 @@ pair<bool,long> ServiceProvider::doHandler(SPRequest& request) const
try {
RequestMapper::Settings settings = request.getRequestSettings();
- app = &(request.getApplication());
// If not SSL, check to see if we should block or redirect it.
if (!request.isSecure()) {
diff --git a/shibsp/ServiceProvider.h b/shibsp/ServiceProvider.h
index 1b0382f4..d6017d68 100644
--- a/shibsp/ServiceProvider.h
+++ b/shibsp/ServiceProvider.h
@@ -24,11 +24,11 @@
#include <shibsp/util/PropertySet.h>
#include <set>
+#include <vector>
#include <xmltooling/Lockable.h>
namespace shibsp {
- class SHIBSP_API Application;
class SHIBSP_API Handler;
class SHIBSP_API ListenerService;
class SHIBSP_API Remoted;
@@ -81,14 +81,6 @@ namespace shibsp {
*/
virtual RequestMapper* getRequestMapper(bool required=true) const=0;
- /**
- * Returns an Application instance matching the specified ID.
- *
- * @param applicationId the ID of the application, or nullptr for the default
- * @return pointer to the application, or nullptr
- */
- virtual const Application* getApplication(const char* applicationId) const=0;
-
/**
* Enforces requirements for an authenticated session.
*
diff --git a/shibsp/SessionCache.h b/shibsp/SessionCache.h
index b604e748..29afcae8 100644
--- a/shibsp/SessionCache.h
+++ b/shibsp/SessionCache.h
@@ -33,8 +33,7 @@ namespace shibsp {
class SHIBSP_API Application;
class SHIBSP_API Attribute;
- class SHIBSP_API HTTPRequest;
- class SHIBSP_API HTTPResponse;
+ class SHIBSP_API SPRequest;
/**
* Encapsulates access to a user's security session.
@@ -59,11 +58,12 @@ namespace shibsp {
virtual const char* getID() const=0;
/**
- * Returns the session's application ID.
+ * Returns the session's "bucket" ID, i.e., a value separating sessions into
+ * specific buckets based on resources.
*
- * @return unique ID of application bound to session
+ * @return unique ID of session bucket
*/
- virtual const char* getApplicationID() const=0;
+ virtual const char* getBucketID() const=0;
/**
* Returns the session expiration.
@@ -158,9 +158,7 @@ namespace shibsp {
* <p>The SSO tokens and Attributes remain owned by the caller and are copied by the cache.</p>
*
* @param sessionID reference to string to capture newly inserted session ID
- * @param application reference to Application that owns the Session
- * @param httpRequest request that initiated session
- * @param httpResponse current response to client
+ * @param request request that initiated session
* @param expires expiration time of session
* @param issuer issuing metadata of assertion issuer, if known
* @param protocol protocol family used to initiate the session
@@ -174,9 +172,7 @@ namespace shibsp {
*/
virtual void insert(
std::string& sessionID,
- const Application& application,
- const xmltooling::HTTPRequest& httpRequest,
- xmltooling::HTTPResponse& httpResponse,
+ const SPRequest& request,
time_t expires,
const opensaml::saml2md::EntityDescriptor* issuer=nullptr,
const XMLCh* protocol=nullptr,
@@ -192,7 +188,6 @@ namespace shibsp {
/**
* Determines whether the Session bound to a client request matches a set of input criteria.
*
- * @param application reference to Application that owns the Session
* @param request request in which to locate Session
* @param issuer required source of session(s)
* @param nameid required name identifier
@@ -200,8 +195,7 @@ namespace shibsp {
* @return true iff the Session exists and matches the input criteria
*/
virtual bool matches(
- const Application& application,
- xmltooling::HTTPRequest& request,
+ const SPRequest& request,
const opensaml::saml2md::EntityDescriptor* issuer,
const opensaml::saml2::NameID& nameid,
const std::set<std::string>* indexes
@@ -217,7 +211,7 @@ namespace shibsp {
* <p>Until logout expiration, any attempt to create a session with the same parameters
* will be blocked by the cache.
*
- * @param application reference to Application that owns the session(s)
+ * @param bucketID bucket for session
* @param issuer source of session(s)
* @param nameid name identifier associated with the session(s) to terminate
* @param indexes indexes of sessions, or nullptr for all sessions associated with other parameters
@@ -225,7 +219,7 @@ namespace shibsp {
* @param sessions on exit, contains the IDs of the matching sessions found
*/
virtual std::vector<std::string>::size_type logout(
- const Application& application,
+ const char* bucketID,
const opensaml::saml2md::EntityDescriptor* issuer,
const opensaml::saml2::NameID& nameid,
const std::set<std::string>* indexes,
@@ -242,11 +236,10 @@ namespace shibsp {
/**
* Returns the ID of the session bound to the specified client request, if possible.
*
- * @param application reference to Application that owns the Session
- * @param request request from client containing session, or a reference to it
+ * @param request request from client containing session
* @return ID of session, if any known, or an empty string
*/
- virtual std::string active(const Application& application, const HTTPRequest& request)=0;
+ virtual std::string active(const SPRequest& request)=0;
/**
* Locates an existing session bound to a request.
@@ -257,59 +250,49 @@ namespace shibsp {
* <p>If a bound session is found to have expired, be invalid, etc., and if the request
* can be used to "clear" the session from subsequent client requests, then it may be cleared.</p>
*
- * @param application reference to Application that owns the Session
* @param request request from client bound to session
* @param client_addr network address of client (if known)
* @param timeout inactivity timeout to enforce (0 for none, nullptr to bypass check/update of last access)
* @return pointer to locked Session, or nullptr
*/
- virtual Session* find(
- const Application& application,
- HTTPRequest& request,
- const char* client_addr=nullptr,
- time_t* timeout=nullptr
- )=0;
+ virtual Session* find(SPRequest& request, const char* client_addr=nullptr, time_t* timeout=nullptr)=0;
/**
* Deletes an existing session bound to a request.
*
* <p>Revocation may be supported by some implementations.</p>
*
- * @param application reference to Application that owns the Session
- * @param request request from client containing session, or a reference to it
- * @param response optional response to client enabling removal of session or reference
+ * @param request request from client containing session
* @param revocationExp optional indicator for length of time to track revocation of this session
*/
- virtual void remove(
- const Application& application,
- const HTTPRequest& request,
- HTTPResponse* response=nullptr,
- time_t revocationExp=0
- )=0;
+ virtual void remove(SPRequest& request, time_t revocationExp=0)=0;
/**
* Locates an existing session by ID.
*
- * @param application reference to Application that owns the Session
+ * @param bucketID bucket for session
* @param key session key
* @return pointer to locked Session, or nullptr
*/
- virtual Session* find(const Application& application, const char* key)=0;
+ virtual Session* find(const char* bucketID, const char* key)=0;
/**
* Deletes an existing session.
*
* <p>Revocation may be supported by some implementations.</p>
*
- * @param application reference to Application that owns the Session
+ * @param bucketID bucket for session
* @param key session key
* @param revocationExp optional indicator for length of time to track revocation of this session
*/
- virtual void remove(const Application& application, const char* key, time_t revocationExp=0)=0;
+ virtual void remove(const char* bucketID, const char* key, time_t revocationExp=0)=0;
};
- /** SessionCache implementation backed by a StorageService. */
- #define STORAGESERVICE_SESSION_CACHE "StorageService"
+ /** SessionCache implementation backed by the file system. */
+ #define FILESYSTEM_SESSION_CACHE "filesystem"
+
+ /** SessionCache implementation backed by a hub-hosted StorageService. */
+ #define STORAGESERVICE_SESSION_CACHE "storage"
/**
* Registers SessionCache classes into the runtime.
diff --git a/shibsp/handler/AbstractHandler.h b/shibsp/handler/AbstractHandler.h
index e7c8d7e8..113dd752 100644
--- a/shibsp/handler/AbstractHandler.h
+++ b/shibsp/handler/AbstractHandler.h
@@ -36,8 +36,6 @@ namespace xmltooling {
namespace shibsp {
- class SHIBSP_API Application;
-
#if defined (_MSC_VER)
#pragma warning( push )
#pragma warning( disable : 4250 )
@@ -122,17 +120,10 @@ namespace shibsp {
/**
* Implements a mechanism to preserve form post data.
*
- * @param application the associated Application
- * @param request incoming HTTP request
- * @param response outgoing HTTP response
+ * @param request SP request
* @param relayState relay state information attached to current sequence, if any
*/
- virtual void preservePostData(
- const Application& application,
- const HTTPRequest& request,
- HTTPResponse& response,
- const char* relayState
- ) const;
+ virtual void preservePostData(SPRequest& request, const char* relayState) const;
/**
* Implements storage service and cookie mechanism to recover PostData.
@@ -140,33 +131,21 @@ namespace shibsp {
* <p>If a supported mechanism can be identified, the return value will be
* the recovered state information.
*
- * @param application the associated Application
* @param request incoming HTTP request
* @param response outgoing HTTP response
* @param relayState relay state information attached to current sequence, if any
* @return recovered form post data associated with request as a DDF list of string members
*/
- virtual DDF recoverPostData(
- const Application& application,
- const HTTPRequest& request,
- HTTPResponse& response,
- const char* relayState
- ) const;
+ virtual DDF recoverPostData(SPRequest& request, const char* relayState) const;
/**
* Post a redirect response with post data.
*
- * @param application the associated Application
* @param response outgoing HTTP response
* @param url action url for the form
* @param postData list of parameters to load into the form, as DDF string members
*/
- virtual long sendPostResponse(
- const Application& application,
- HTTPResponse& response,
- const char* url,
- DDF& postData
- ) const;
+ virtual long sendPostResponse(HTTPResponse& response, const char* url, DDF& postData) const;
/**
* Bitmask of property sources to read from
@@ -233,8 +212,8 @@ namespace shibsp {
virtual ~AbstractHandler();
private:
- std::string getPostCookieName(const Application& app, const char* relayState) const;
- DDF getPostData(const Application& application, const HTTPRequest& request) const;
+ std::string getPostCookieName(const SPRequest& request, const char* relayState) const;
+ DDF getPostData(const SPRequest& request) const;
};
#if defined (_MSC_VER)
diff --git a/shibsp/handler/AssertionConsumerService.h b/shibsp/handler/AssertionConsumerService.h
index a3c1255b..e52759ef 100644
--- a/shibsp/handler/AssertionConsumerService.h
+++ b/shibsp/handler/AssertionConsumerService.h
@@ -30,8 +30,6 @@
#include <shibsp/handler/AbstractHandler.h>
#include <shibsp/handler/RemotedHandler.h>
-#include <boost/scoped_ptr.hpp>
-
namespace shibsp {
class SHIBSP_API Attribute;
@@ -77,27 +75,19 @@ namespace shibsp {
/**
* Enforce address checking requirements.
*
- * @param application reference to application receiving message
- * @param httpRequest client request that initiated session
+ * @param request client request that initiated session
* @param issuedTo address for which security assertion was issued
*/
- void checkAddress(const Application& application, const HTTPRequest& httpRequest, const char* issuedTo) const;
+ void checkAddress(const SPRequest& request, const char* issuedTo) const;
/**
* Complete the client's transition back to the expected resource.
*
- * @param application reference to application receiving message
- * @param httpRequest client request that included message
- * @param httpResponse response to client
+ * @param request client request that included message
* @param relayState relay state token
*/
- virtual std::pair<bool,long> finalizeResponse(
- const Application& application,
- const HTTPRequest& httpRequest,
- HTTPResponse& httpResponse,
- std::string& relayState
- ) const;
+ virtual std::pair<bool,long> finalizeResponse(SPRequest& httpRequest, std::string& relayState) const;
#ifndef SHIBSP_LITE
/**
@@ -115,17 +105,13 @@ namespace shibsp {
* modifications to the request/response objects to reflect processing
* of the message.</p>
*
- * @param application reference to application receiving message
- * @param httpRequest client request that included message
- * @param httpResponse response to client
+ * @param request client request that included message
* @param policy the SecurityPolicy in effect, after having evaluated the message
* @param reserved ignore this parameter
* @param xmlObject a protocol-specific message object
*/
virtual void implementProtocol(
- const Application& application,
- const xmltooling::HTTPRequest& httpRequest,
- xmltooling::HTTPResponse& httpResponse,
+ SPRequest& httpRequest,
opensaml::SecurityPolicy& policy,
const PropertySet* reserved,
const xmltooling::XMLObject& xmlObject
@@ -149,7 +135,6 @@ namespace shibsp {
*
* <p>The caller must free the returned context handle.</p>
*
- * @param application reference to application receiving message
* @param request request delivering message, if any
* @param issuer source of SSO tokens
* @param protocol SSO protocol used
@@ -163,8 +148,7 @@ namespace shibsp {
* @param tokens available assertions, if any
*/
ResolutionContext* resolveAttributes(
- const Application& application,
- const xmltooling::GenericRequest* request=nullptr,
+ const SPRequest* request=nullptr,
const opensaml::saml2md::RoleDescriptor* issuer=nullptr,
const XMLCh* protocol=nullptr,
const xmltooling::XMLObject* protmsg=nullptr,
@@ -176,19 +160,12 @@ namespace shibsp {
const XMLCh* authncontext_decl=nullptr,
const std::vector<const opensaml::Assertion*>* tokens=nullptr
) const;
-
- public:
- const XMLCh* getProtocolFamily() const;
#endif
private:
- std::pair<bool,long> processMessage(
- const Application& application, const HTTPRequest& httpRequest, HTTPResponse& httpResponse
- ) const;
+ std::pair<bool,long> processMessage(const SPRequest& request) const;
std::pair<bool,long> sendRedirect(
- const Application& application,
- const HTTPRequest& request,
- HTTPResponse& response,
+ SPRequest& request,
const char* entityID,
const char* relayState
) const;
diff --git a/shibsp/handler/Handler.h b/shibsp/handler/Handler.h
index b9a25676..1e832770 100644
--- a/shibsp/handler/Handler.h
+++ b/shibsp/handler/Handler.h
@@ -1,21 +1,15 @@
/**
- * Licensed to the University Corporation for Advanced Internet
- * Development, Inc. (UCAID) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for
- * additional information regarding copyright ownership.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * UCAID licenses this file to you under the Apache License,
- * Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the
- * License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "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.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "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.
*/
/**
@@ -60,12 +54,9 @@ namespace shibsp {
* step.
*
* @param application the associated Application
- * @param request incoming HTTP request
- * @param response outgoing HTTP response
+ * @param request SP request
*/
- virtual void cleanRelayState(
- const Application& application, const HTTPRequest& request, HTTPResponse& response
- ) const;
+ virtual void cleanRelayState(SPRequest& request) const;
/**
* Implements various mechanisms to preserve RelayState,
@@ -74,13 +65,10 @@ namespace shibsp {
* <p>If a supported mechanism can be identified, the input parameter will be
* replaced with a suitable state key.
*
- * @param application the associated Application
* @param response outgoing HTTP response
* @param relayState RelayState token to supply with message
*/
- virtual void preserveRelayState(
- const Application& application, HTTPResponse& response, std::string& relayState
- ) const;
+ virtual void preserveRelayState(SPRequest& response, std::string& relayState) const;
/**
* Implements various mechanisms to recover RelayState,
@@ -89,19 +77,11 @@ namespace shibsp {
* <p>If a supported mechanism can be identified, the input parameter will be
* replaced with the recovered state information.
*
- * @param application the associated Application
- * @param request incoming HTTP request
- * @param response outgoing HTTP response
+ * @param request SP request
* @param relayState RelayState token supplied with message
* @param clear true iff the token state should be cleared
*/
- virtual void recoverRelayState(
- const Application& application,
- const HTTPRequest& request,
- HTTPResponse& response,
- std::string& relayState,
- bool clear=true
- ) const;
+ virtual void recoverRelayState(SPRequest& request, std::string& relayState, bool clear=true) const;
public:
virtual ~Handler();
diff --git a/shibsp/handler/LogoutHandler.h b/shibsp/handler/LogoutHandler.h
index 5658f62b..892f9e0d 100644
--- a/shibsp/handler/LogoutHandler.h
+++ b/shibsp/handler/LogoutHandler.h
@@ -83,45 +83,24 @@ namespace shibsp {
/**
* Perform front-channel logout notifications for an Application.
*
- * @param application the Application to notify
* @param request last request from browser
- * @param response response to use for next notification
* @param params map of query string parameters to preserve across this notification
* @return indicator of a completed response along with the status code to return from the handler
*/
std::pair<bool,long> notifyFrontChannel(
- const Application& application,
- const HTTPRequest& request,
- HTTPResponse& response,
- const std::map<std::string,std::string>* params=nullptr
+ SPRequest& request, const std::map<std::string,std::string>* params=nullptr
) const;
/**
* Perform back-channel logout notifications for an Application.
*
- * @param application the Application to notify
- * @param requestURL requestURL that resulted in method call
+ * @param request request resulting in method call
* @param sessions array of session keys being logged out
* @param local true iff the logout operation is local to the SP, false iff global
* @return true iff all notifications succeeded
*/
bool notifyBackChannel(
- const Application& application, const char* requestURL, const std::vector<std::string>& sessions, bool local
- ) const;
-
- /**
- * Sends a response template to the user agent informing it of the results of a logout attempt.
- *
- * @param application the Application to use in determining the logout template
- * @param request the HTTP client request to supply to the template
- * @param response the HTTP response to use
- * @param type designates the prefix of logout template name to use
- */
- std::pair<bool,long> sendLogoutPage(
- const Application& application,
- const HTTPRequest& request,
- HTTPResponse& response,
- const char* type
+ const SPRequest& request, const std::vector<std::string>& sessions, bool local
) const;
};
diff --git a/shibsp/handler/impl/AbstractHandler.cpp b/shibsp/handler/impl/AbstractHandler.cpp
index 3e240319..7347b588 100644
--- a/shibsp/handler/impl/AbstractHandler.cpp
+++ b/shibsp/handler/impl/AbstractHandler.cpp
@@ -21,12 +21,12 @@
#include "internal.h"
#include "exceptions.h"
+#include "Agent.h"
#include "AgentConfig.h"
-#include "Application.h"
-#include "ServiceProvider.h"
#include "SPRequest.h"
#include "handler/AbstractHandler.h"
#include "handler/LogoutHandler.h"
+#include "remoting/RemotingService.h"
#include "util/CGIParser.h"
#include "util/SPConstants.h"
#include "util/PathResolver.h"
@@ -44,6 +44,10 @@ using namespace xercesc;
using namespace boost;
using namespace std;
+#ifndef HAVE_STRCASECMP
+# define strcasecmp _stricmp
+#endif
+
namespace shibsp {
SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory SAML2ConsumerFactory;
SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory SAML2LogoutFactory;
@@ -118,26 +122,17 @@ void Handler::log(Priority::Value level, const string& msg) const
Category::getInstance(SHIBSP_LOGCAT ".Handler").log(level, msg);
}
-void Handler::cleanRelayState(
- const Application& application, const HTTPRequest& request, HTTPResponse& response
- ) const
+void Handler::cleanRelayState(SPRequest& request) const
{
- pair<bool,const char*> mech = getString("relayState");
- if (!mech.first) {
- // Check for setting on Sessions element.
- const PropertySet* sessionprop = application.getPropertySet("Sessions");
- if (sessionprop) {
- mech = sessionprop->getString("relayState");
- }
- }
+ const char* mech = request.getRequestSettings().first->getString("relayState");
int maxRSCookies = 20,purgedRSCookies = 0;
int maxOSCookies = 20,purgedOSCookies = 0;
- if (mech.first && !strncmp(mech.second, "cookie", 6)) {
- mech.second += 6;
- if (*mech.second == ':' && isdigit(*(++mech.second))) {
- maxRSCookies = maxOSCookies = atoi(mech.second);
+ if (mech && !strncmp(mech, "cookie", 6)) {
+ mech += 6;
+ if (*mech == ':' && isdigit(*(++mech))) {
+ maxRSCookies = maxOSCookies = atoi(mech);
if (maxRSCookies == 0) {
maxRSCookies = maxOSCookies = 20;
}
@@ -154,7 +149,7 @@ void Handler::cleanRelayState(
}
else {
// We're over the limit, so everything here and older gets cleaned up.
- response.setCookie(i->first.c_str(), nullptr, 0, HTTPResponse::SAMESITE_NONE);
+ request.setCookie(i->first.c_str(), nullptr, 0, HTTPResponse::SAMESITE_NONE);
++purgedRSCookies;
}
}
@@ -165,7 +160,7 @@ void Handler::cleanRelayState(
}
else {
// We're over the limit, so everything here and older gets cleaned up.
- response.setCookie(i->first.c_str(), nullptr, 0, HTTPResponse::SAMESITE_NONE);
+ request.setCookie(i->first.c_str(), nullptr, 0, HTTPResponse::SAMESITE_NONE);
++purgedOSCookies;
}
}
@@ -177,7 +172,7 @@ void Handler::cleanRelayState(
log(Priority::SHIB_DEBUG, string("purged ") + lexical_cast<string>(purgedOSCookies) + " stale request correlation cookie(s) from client");
}
-void Handler::preserveRelayState(const Application& application, HTTPResponse& response, string& relayState) const
+void Handler::preserveRelayState(SPRequest& request, string& relayState) const
{
// The empty string implies no state to deal with but we need to generate a correlation handle.
if (relayState.empty()) {
@@ -187,17 +182,12 @@ void Handler::preserveRelayState(const Application& application, HTTPResponse& r
}
// No setting means just pass state by value.
- pair<bool,const char*> mech = getString("relayState");
- if (!mech.first) {
- // Check for setting on Sessions element.
- const PropertySet* sessionprop = application.getPropertySet("Sessions");
- if (sessionprop)
- mech = sessionprop->getString("relayState");
- }
- if (!mech.first || !mech.second || !*mech.second)
+ const char* mech = request.getRequestSettings().first->getString("relayState");
+ if (!mech || !*mech) {
return;
+ }
- if (!strncmp(mech.second, "cookie", 6)) {
+ if (!strncmp(mech, "cookie", 6)) {
// Here we store the state in a cookie and send a fixed
// value so we can recognize it on the way back.
if (relayState.find("cookie:") != 0 && relayState.find("ss:") != 0) {
@@ -206,16 +196,16 @@ void Handler::preserveRelayState(const Application& application, HTTPResponse& r
generateRandomHex(rsKey, 4);
rsKey = lexical_cast<string>(time(nullptr)) + '_' + rsKey;
string shib_cookie_name = "_shibstate_" + rsKey;
- response.setCookie(shib_cookie_name.c_str(),
+ request.setCookie(shib_cookie_name.c_str(),
AgentConfig::getConfig().getURLEncoder().encode(relayState.c_str()).c_str(),
0, HTTPResponse::SAMESITE_NONE);
relayState = "cookie:" + rsKey;
}
}
- else if (!strncmp(mech.second, "ss:", 3)) {
+ else if (!strncmp(mech, "ss:", 3)) {
if (relayState.find("cookie:") != 0 && relayState.find("ss:") != 0) {
- mech.second+=3;
- if (*mech.second) {
+ mech+=3;
+ if (*mech) {
if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
#ifndef SHIBSP_LITE
StorageService* storage = application.getServiceProvider().getStorageService(mech.second);
@@ -246,13 +236,13 @@ void Handler::preserveRelayState(const Application& application, HTTPResponse& r
}
else if (SPConfig::getConfig().isEnabled(SPConfig::InProcess)) {
DDF out,in = DDF("set::RelayState").structure();
- in.addmember("id").string(mech.second);
+ in.addmember("id").string(mech);
in.addmember("value").unsafe_string(relayState.c_str());
DDFJanitor jin(in),jout(out);
- //out = application.getServiceProvider().getListenerService()->send(in);
+ out = request.getAgent().getRemotingService()->send(in);
if (!out.isstring())
throw IOException("StorageService-backed RelayState mechanism did not return a state key.");
- relayState = string(mech.second-3) + ':' + out.string();
+ relayState = string(mech-3) + ':' + out.string();
}
}
}
@@ -262,12 +252,8 @@ void Handler::preserveRelayState(const Application& application, HTTPResponse& r
}
}
-void Handler::recoverRelayState(
- const Application& application, const HTTPRequest& request, HTTPResponse& response, string& relayState, bool clear
- ) const
+void Handler::recoverRelayState(SPRequest& request, string& relayState, bool clear) const
{
- SPConfig& conf = SPConfig::getConfig();
-
// Sentry value that signifies it was only a correlation tool.
if (starts_with(relayState, "corr:")) {
relayState.clear();
@@ -283,7 +269,7 @@ void Handler::recoverRelayState(
string ssid = relayState.substr(3, key - state);
key++;
if (!ssid.empty() && *key) {
- if (conf.isEnabled(SPConfig::OutOfProcess)) {
+ if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
#ifndef SHIBSP_LITE
StorageService* storage = conf.getServiceProvider()->getStorageService(ssid.c_str());
if (storage) {
@@ -312,13 +298,13 @@ void Handler::recoverRelayState(
}
#endif
}
- else if (conf.isEnabled(SPConfig::InProcess)) {
+ else if (SPConfig::getConfig().isEnabled(SPConfig::InProcess)) {
DDF out,in = DDF("get::RelayState").structure();
in.addmember("id").string(ssid.c_str());
in.addmember("key").string(key);
in.addmember("clear").integer(clear ? 1 : 0);
DDFJanitor jin(in),jout(out);
- //out = application.getServiceProvider().getListenerService()->send(in);
+ out = request.getAgent().getRemotingService()->send(in);
if (!out.isstring()) {
log(Priority::SHIB_ERROR, "StorageService-backed RelayState mechanism did not return a state value.");
relayState.erase();
@@ -348,7 +334,7 @@ void Handler::recoverRelayState(
relayState = rscopy;
free(rscopy);
if (clear) {
- response.setCookie(relay_cookie.c_str(), nullptr, 0, HTTPResponse::SAMESITE_NONE);
+ request.setCookie(relay_cookie.c_str(), nullptr, 0, HTTPResponse::SAMESITE_NONE);
}
request.absolutize(relayState);
return;
@@ -360,11 +346,7 @@ void Handler::recoverRelayState(
// Check for "default" value (or the old "cookie" value that might come from stale bookmarks).
if (relayState.empty() || relayState == "default" || relayState == "cookie") {
- pair<bool,const char*> homeURL=application.getString("homeURL");
- if (homeURL.first)
- relayState = homeURL.second;
- else
- relayState = '/';
+ relayState = request.getRequestSettings().first->getString("homeURL", "/");
}
request.absolutize(relayState);
@@ -530,31 +512,26 @@ long AbstractHandler::sendMessage(
#endif
-void AbstractHandler::preservePostData(
- const Application& application, const HTTPRequest& request, HTTPResponse& response, const char* relayState
- ) const
+void AbstractHandler::preservePostData(SPRequest& request, const char* relayState) const
{
-#ifdef HAVE_STRCASECMP
- if (strcasecmp(request.getMethod(), "POST")) return;
-#else
- if (stricmp(request.getMethod(), "POST")) return;
-#endif
+ if (strcasecmp(request.getMethod(), "POST")) {
+ return;
+ }
// No specs mean no save.
- const PropertySet* props = application.getPropertySet("Sessions");
- pair<bool,const char*> mech = props ? props->getString("postData") : pair<bool,const char*>(false,nullptr);
- if (!mech.first) {
+ const char* mech = request.getRequestSettings().first->getString("postData");
+ if (!mech) {
m_log.info("postData property not supplied, form data will not be preserved across SSO");
return;
}
- DDF postData = getPostData(application, request);
+ DDF postData = getPostData(request);
if (postData.isnull())
return;
- if (strstr(mech.second,"ss:") == mech.second) {
- mech.second+=3;
- if (!*mech.second) {
+ if (strstr(mech, "ss:") == mech) {
+ mech+=3;
+ if (!*mech) {
postData.destroy();
throw ConfigurationException("Unsupported postData mechanism.");
}
@@ -585,15 +562,15 @@ void AbstractHandler::preservePostData(
else if (SPConfig::getConfig().isEnabled(SPConfig::InProcess)) {
DDF out,in = DDF("set::PostData").structure();
DDFJanitor jin(in),jout(out);
- in.addmember("id").string(mech.second);
+ in.addmember("id").string(mech);
in.add(postData);
- //out = application.getServiceProvider().getListenerService()->send(in);
+ out = request.getAgent().getRemotingService()->send(in);
if (!out.isstring())
throw IOException("StorageService-backed PostData mechanism did not return a state key.");
- postkey = string(mech.second-3) + ':' + out.string();
+ postkey = string(mech-3) + ':' + out.string();
}
- string shib_cookie = getPostCookieName(application, relayState);
+ string shib_cookie = getPostCookieName(request, relayState);
// Purge any cookies in excess of 25.
int maxCookies = 20,purgedCookies = 0;
@@ -609,7 +586,7 @@ void AbstractHandler::preservePostData(
}
else {
// We're over the limit, so everything here and older gets cleaned up.
- response.setCookie(i->first.c_str(), nullptr, 0, HTTPResponse::SAMESITE_NONE);
+ request.setCookie(i->first.c_str(), nullptr, 0, HTTPResponse::SAMESITE_NONE);
++purgedCookies;
}
}
@@ -619,7 +596,7 @@ void AbstractHandler::preservePostData(
log(Priority::SHIB_DEBUG, string("purged ") + lexical_cast<string>(purgedCookies) + " stale POST preservation cookie(s) from client");
// Set a cookie with key info.
- response.setCookie(shib_cookie.c_str(), postkey.c_str(), 0, HTTPResponse::SAMESITE_NONE);
+ request.setCookie(shib_cookie.c_str(), postkey.c_str(), 0, HTTPResponse::SAMESITE_NONE);
}
else {
postData.destroy();
@@ -627,11 +604,9 @@ void AbstractHandler::preservePostData(
}
}
-DDF AbstractHandler::recoverPostData(
- const Application& application, const HTTPRequest& request, HTTPResponse& response, const char* relayState
- ) const
+DDF AbstractHandler::recoverPostData(SPRequest& request, const char* relayState) const
{
- string shib_cookie = getPostCookieName(application, relayState);
+ string shib_cookie = getPostCookieName(request, relayState);
// First we need the post recovery cookie.
const char* cookie = request.getCookie(shib_cookie.c_str());
@@ -639,7 +614,7 @@ DDF AbstractHandler::recoverPostData(
return DDF();
// Clear the cookie.
- response.setCookie(shib_cookie.c_str(), nullptr, 0, HTTPResponse::SAMESITE_NONE);
+ request.setCookie(shib_cookie.c_str(), nullptr, 0, HTTPResponse::SAMESITE_NONE);
// Look for StorageService-backed state of the form "ss:SSID:key".
const char* state = cookie;
@@ -676,10 +651,10 @@ DDF AbstractHandler::recoverPostData(
DDFJanitor jin(in);
in.addmember("id").string(ssid.c_str());
in.addmember("key").string(key);
- //DDF out = application.getServiceProvider().getListenerService()->send(in);
- //if (out.islist())
- // return out;
- //out.destroy();
+ DDF out = request.getAgent().getRemotingService()->send(in);
+ if (out.islist())
+ return out;
+ out.destroy();
m_log.error("storageService-backed PostData mechanism did not return preserved data.");
}
}
@@ -688,9 +663,7 @@ DDF AbstractHandler::recoverPostData(
return DDF();
}
-long AbstractHandler::sendPostResponse(
- const Application& application, HTTPResponse& httpResponse, const char* url, DDF& postData
- ) const
+long AbstractHandler::sendPostResponse(HTTPResponse& httpResponse, const char* url, DDF& postData) const
{
HTTPResponse::sanitizeURL(url);
@@ -733,7 +706,7 @@ long AbstractHandler::sendPostResponse(
return 0;
}
-string AbstractHandler::getPostCookieName(const Application& app, const char* relayState) const
+string AbstractHandler::getPostCookieName(const SPRequest& request, const char* relayState) const
{
// Decorates the name of the cookie with the relay state key, if any.
// Doing so gives a better assurance that the recovered data really
@@ -746,18 +719,15 @@ string AbstractHandler::getPostCookieName(const Application& app, const char* re
if (pch)
return string("_shibpost_") + (pch + 1);
}
- return app.getCookieName("_shibpost_");
+ return request.getCookieName("_shibpost_");
}
-DDF AbstractHandler::getPostData(const Application& application, const HTTPRequest& request) const
+DDF AbstractHandler::getPostData(const SPRequest& request) const
{
string contentType = request.getContentType();
if (contentType.find("application/x-www-form-urlencoded") != string::npos) {
- const PropertySet* props = application.getPropertySet("Sessions");
- pair<bool,unsigned int> plimit = props ? props->getUnsignedInt("postLimit") : pair<bool,unsigned int>(false,0);
- if (!plimit.first)
- plimit.second = 1024 * 1024;
- if (plimit.second == 0 || request.getContentLength() <= plimit.second) {
+ unsigned int plimit = request.getRequestSettings().first->getUnsignedInt("postLimit", 1024 * 1024);
+ if (plimit == 0 || request.getContentLength() <= plimit) {
CGIParser cgi(request);
pair<CGIParser::walker,CGIParser::walker> params = cgi.getParameters(nullptr);
if (params.first == params.second)
diff --git a/shibsp/handler/impl/AdminLogoutInitiator.cpp b/shibsp/handler/impl/AdminLogoutInitiator.cpp
index dd977e47..adfa4066 100644
--- a/shibsp/handler/impl/AdminLogoutInitiator.cpp
+++ b/shibsp/handler/impl/AdminLogoutInitiator.cpp
@@ -26,7 +26,8 @@
#include "internal.h"
#include "exceptions.h"
-#include "Application.h"
+#include "Agent.h"
+#include "AgentConfig.h"
#include "ServiceProvider.h"
#include "SessionCache.h"
#include "handler/SecuredHandler.h"
@@ -59,7 +60,7 @@ namespace shibsp {
pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
private:
- pair<bool,long> doRequest(const Application& application, const HTTPRequest& request, HTTPResponse& httpResponse) const;
+ pair<bool,long> doRequest(SPRequest& request) const;
string m_appId;
#ifndef SHIBSP_LITE
@@ -126,7 +127,7 @@ pair<bool,long> AdminLogoutInitiator::run(SPRequest& request, bool isHandler) co
if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
// When out of process, we run natively.
- return doRequest(request.getApplication(), request, request);
+ return doRequest(request);
}
else {
// When not out of process, we remote the request.
@@ -169,19 +170,19 @@ void AdminLogoutInitiator::receive(DDF& in, ostream& out)
#endif
}
-pair<bool,long> AdminLogoutInitiator::doRequest(const Application& application, const HTTPRequest& httpRequest, HTTPResponse& httpResponse) const
+pair<bool,long> AdminLogoutInitiator::doRequest(SPRequest& request) const
{
- const char* sessionId = httpRequest.getParameter("session");
+ const char* sessionId = request.getParameter("session");
if (!sessionId || !*sessionId) {
// Something's horribly wrong.
m_log.error("no session parameter supplied for request");
istringstream msg("NO SESSION PARAMETER");
- return make_pair(true, httpResponse.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_BADREQUEST));
+ return make_pair(true, request.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_BADREQUEST));
}
Session* session = nullptr;
try {
- session = application.getServiceProvider().getSessionCache()->find(application, sessionId);
+ session = AgentConfig::getConfig().getAgent().getSessionCache()->find(request, sessionId);
}
catch (const std::exception& ex) {
m_log.error("error accessing designated session: %s", ex.what());
@@ -189,9 +190,10 @@ pair<bool,long> AdminLogoutInitiator::doRequest(const Application& application,
// With no session, we return a 404 after "revoking" the session just to be safe.
if (!session) {
- application.getServiceProvider().getSessionCache()->remove(application, sessionId);
+ AgentConfig::getConfig().getAgent().getSessionCache()->remove(
+ request.getRequestSettings().first->getString("sessionBucket", "default"), sessionId);
istringstream msg("NOT FOUND");
- return make_pair(true, httpResponse.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_NOTFOUND));
+ return make_pair(true, request.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_NOTFOUND));
}
time_t revocationExp = session->getExpiration();
@@ -200,38 +202,26 @@ pair<bool,long> AdminLogoutInitiator::doRequest(const Application& application,
bool doSAML = false;
-#ifndef SHIBSP_LITE
- if (XMLString::equals(session->getProtocol(), m_protocol.get())) {
- if (!session->getEntityID() || !session->getNameID()) {
- m_log.info("skipping SAML 2.0 logout attempt, no NameID or issuing entityID found in session");
- }
- else {
- doSAML = true;
- }
- }
- else {
- m_log.info("skipping global logout for non-SAML2 session");
- }
-#endif
-
// Do back channel notification.
vector<string> sessions(1, session->getID());
- if (!notifyBackChannel(application, httpRequest.getRequestURL(), sessions, true)) {
+ if (!notifyBackChannel(request, sessions, true)) {
sessionLocker.unlock();
session = nullptr;
- application.getServiceProvider().getSessionCache()->remove(application, sessionId, revocationExp);
+ AgentConfig::getConfig().getAgent().getSessionCache()->remove(
+ request.getRequestSettings().first->getString("sessionBucket", "default"), sessionId, revocationExp);
istringstream msg("PARTIAL");
- return make_pair(true, httpResponse.sendResponse(msg, 206)); // misuse of an HTTP code, but whatever
+ return make_pair(true, request.sendResponse(msg, 206)); // misuse of an HTTP code, but whatever
}
if (!doSAML) {
sessionLocker.unlock();
session = nullptr;
- application.getServiceProvider().getSessionCache()->remove(application, sessionId, revocationExp);
+ AgentConfig::getConfig().getAgent().getSessionCache()->remove(
+ request.getRequestSettings().first->getString("sessionBucket", "default"), sessionId, revocationExp);
istringstream msg("OK");
- return make_pair(true, httpResponse.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_OK));
+ return make_pair(true, request.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_OK));
}
#ifndef SHIBSP_LITE
diff --git a/shibsp/handler/impl/AssertionConsumerService.cpp b/shibsp/handler/impl/AssertionConsumerService.cpp
index c45e6249..720a8d36 100644
--- a/shibsp/handler/impl/AssertionConsumerService.cpp
+++ b/shibsp/handler/impl/AssertionConsumerService.cpp
@@ -26,17 +26,13 @@
#include "internal.h"
#include "exceptions.h"
-#include "Application.h"
#include "ServiceProvider.h"
#include "SPRequest.h"
#include "handler/AssertionConsumerService.h"
#include "util/CGIParser.h"
#include "util/SPConstants.h"
-# include <ctime>
-
-#include <xmltooling/XMLToolingConfig.h>
-#include <xmltooling/util/URLEncoder.h>
+#include <ctime>
using namespace shibspconstants;
using namespace shibsp;
@@ -77,13 +73,13 @@ pair<bool,long> AssertionConsumerService::run(SPRequest& request, bool isHandler
param = cgi.getParameters("target");
if (param.first != param.second && param.first->second)
target = param.first->second;
- return finalizeResponse(request.getApplication(), request, request, target);
+ return finalizeResponse(request, target);
}
}
if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
// When out of process, we run natively and directly process the message.
- return processMessage(request.getApplication(), request, request);
+ return processMessage(request);
}
else {
// When not out of process, we remote all the message processing.
@@ -99,6 +95,8 @@ pair<bool,long> AssertionConsumerService::run(SPRequest& request, bool isHandler
void AssertionConsumerService::receive(DDF& in, ostream& out)
{
+ /*
+
// Find application.
const char* aid = in["application_id"].string();
const Application* app = aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
@@ -121,11 +119,11 @@ void AssertionConsumerService::receive(DDF& in, ostream& out)
// which we capture in the facade and send back.
processMessage(*app, *req, *resp);
out << ret;
+
+ */
}
-pair<bool,long> AssertionConsumerService::processMessage(
- const Application& application, const HTTPRequest& httpRequest, HTTPResponse& httpResponse
- ) const
+pair<bool,long> AssertionConsumerService::processMessage(const SPRequest& httpRequest) const
{
#ifndef SHIBSP_LITE
// Locate policy key.
@@ -238,45 +236,38 @@ pair<bool,long> AssertionConsumerService::processMessage(
#endif
}
-pair<bool,long> AssertionConsumerService::finalizeResponse(
- const Application& application, const HTTPRequest& httpRequest, HTTPResponse& httpResponse, string& relayState
- ) const
+pair<bool,long> AssertionConsumerService::finalizeResponse(SPRequest& request, string& relayState) const
{
- DDF postData = recoverPostData(application, httpRequest, httpResponse, relayState.c_str());
+ DDF postData = recoverPostData(request, relayState.c_str());
DDFJanitor postjan(postData);
- recoverRelayState(application, httpRequest, httpResponse, relayState);
- application.limitRedirect(httpRequest, relayState.c_str());
+ recoverRelayState(request, relayState);
+ request.limitRedirect(relayState.c_str());
// Now redirect to the state value. By now, it should be set to *something* usable.
// First check for POST data.
if (!postData.islist()) {
m_log.debug("ACS returning via redirect to: %s", relayState.c_str());
- return make_pair(true, httpResponse.sendRedirect(relayState.c_str()));
+ return make_pair(true, request.sendRedirect(relayState.c_str()));
}
else {
m_log.debug("ACS returning via POST to: %s", relayState.c_str());
- return make_pair(true, sendPostResponse(application, httpResponse, relayState.c_str(), postData));
+ return make_pair(true, sendPostResponse(request, relayState.c_str(), postData));
}
}
-void AssertionConsumerService::checkAddress(const Application& application, const HTTPRequest& httpRequest, const char* issuedTo) const
+void AssertionConsumerService::checkAddress(const SPRequest& request, const char* issuedTo) const
{
if (!issuedTo || !*issuedTo)
return;
- const PropertySet* props = application.getPropertySet("Sessions");
- pair<bool,bool> checkAddress = props ? props->getBool("checkAddress") : make_pair(false,true);
- if (!checkAddress.first)
- checkAddress.second = true;
-
- if (checkAddress.second) {
+ if (request.getRequestSettings().first->getBool("checkAddress", true)) {
m_log.debug("checking client address");
- if (httpRequest.getRemoteAddr() != issuedTo) {
- throw XMLToolingException(
- "Your client's current address ($client_addr) differs from the one used when you authenticated "
- "to your identity provider. To correct this problem, you may need to bypass a proxy server. "
- "Please contact your local support staff or help desk for assistance.",
- namedparams(1, "client_addr", httpRequest.getRemoteAddr().c_str())
+ if (request.getRemoteAddr() != issuedTo) {
+ throw agent_exception(
+ string("Your client's current address (") + request.getRemoteAddr() +
+ ") differs from the one used when you authenticated to your home organization. "
+ "To correct this problem, you may need to bypass a proxy server. "
+ "Please contact your local support staff or help desk for assistance."
);
}
}
@@ -284,16 +275,6 @@ void AssertionConsumerService::checkAddress(const Application& application, cons
#ifndef SHIBSP_LITE
-const char* AssertionConsumerService::getProfile() const
-{
- return nullptr;
-}
-
-const XMLCh* AssertionConsumerService::getProtocolFamily() const
-{
- return m_decoder ? m_decoder->getProtocolFamily() : nullptr;
-}
-
namespace {
class SHIBSP_DLLLOCAL DummyContext : public ResolutionContext
{
diff --git a/shibsp/handler/impl/AssertionLookup.cpp b/shibsp/handler/impl/AssertionLookup.cpp
index 7fd58ef0..888377dd 100644
--- a/shibsp/handler/impl/AssertionLookup.cpp
+++ b/shibsp/handler/impl/AssertionLookup.cpp
@@ -26,7 +26,6 @@
#include "internal.h"
#include "exceptions.h"
-#include "Application.h"
#include "ServiceProvider.h"
#include "SessionCache.h"
#include "SPRequest.h"
@@ -64,7 +63,7 @@ namespace shibsp {
}
private:
- pair<bool,long> processMessage(const Application& application, HTTPRequest& httpRequest, HTTPResponse& httpResponse) const;
+ pair<bool,long> processMessage(SPRequest& request) const;
};
#if defined (_MSC_VER)
@@ -101,7 +100,7 @@ pair<bool,long> AssertionLookup::run(SPRequest& request, bool isHandler) const
try {
if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
// When out of process, we run natively and directly process the message.
- return processMessage(request.getApplication(), request, request);
+ return processMessage(request);
}
else {
// When not out of process, we remote all the message processing.
@@ -121,6 +120,7 @@ pair<bool,long> AssertionLookup::run(SPRequest& request, bool isHandler) const
void AssertionLookup::receive(DDF& in, ostream& out)
{
+ /*
// Find application.
const char* aid = in["application_id"].string();
const Application* app = aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
@@ -144,9 +144,10 @@ void AssertionLookup::receive(DDF& in, ostream& out)
// which we capture in the facade and send back.
processMessage(*app, *req, *resp);
out << ret;
+ */
}
-pair<bool,long> AssertionLookup::processMessage(const Application& application, HTTPRequest& httpRequest, HTTPResponse& httpResponse) const
+pair<bool,long> AssertionLookup::processMessage(SPRequest& request) const
{
#ifndef SHIBSP_LITE
const char* key = httpRequest.getParameter("key");
diff --git a/shibsp/handler/impl/AttributeCheckerHandler.cpp b/shibsp/handler/impl/AttributeCheckerHandler.cpp
index c1e5d5f0..d66d7070 100644
--- a/shibsp/handler/impl/AttributeCheckerHandler.cpp
+++ b/shibsp/handler/impl/AttributeCheckerHandler.cpp
@@ -26,8 +26,8 @@
#include "internal.h"
#include "AccessControl.h"
+#include "Agent.h"
#include "AgentConfig.h"
-#include "Application.h"
#include "exceptions.h"
#include "ServiceProvider.h"
#include "SessionCache.h"
@@ -79,7 +79,7 @@ namespace shibsp {
private:
void flushSession(SPRequest& request, time_t exp) const {
try {
- request.getApplication().getServiceProvider().getSessionCache()->remove(request.getApplication(), request, &request, exp);
+ request.getAgent().getSessionCache()->remove(request, exp);
}
catch (const std::exception&) {
}
@@ -137,14 +137,15 @@ pair<bool,long> AttributeCheckerHandler::run(SPRequest& request, bool isHandler)
// If the checking passes, we route to the return URL, target URL, or homeURL in that order.
const char* returnURL = request.getParameter("return");
const char* target = request.getParameter("target");
- if (!returnURL)
+ if (!returnURL) {
returnURL = target;
- if (returnURL)
- request.getApplication().limitRedirect(request, returnURL);
- else
- returnURL = request.getApplication().getString("homeURL").second;
- if (!returnURL)
- returnURL = "/";
+ }
+ if (returnURL) {
+ request.limitRedirect(returnURL);
+ }
+ else {
+ returnURL = request.getRequestSettings().first->getString("homeURL", "/");
+ }
Session* session = nullptr;
try {
@@ -188,15 +189,14 @@ pair<bool,long> AttributeCheckerHandler::run(SPRequest& request, bool isHandler)
ifstream infile(m_template.c_str());
if (infile) {
- const PropertySet* props = request.getApplication().getPropertySet("Errors");
- //TemplateParameters tp(nullptr, props, session);
-
+ /*
// If the externalParameters option isn't set, don't populate the request field.
pair<bool,bool> externalParameters =
props ? props->getBool("externalParameters") : pair<bool,bool>(false,false);
if (externalParameters.first && externalParameters.second) {
//tp.m_request = &request;
}
+ */
stringstream str;
//XMLToolingConfig::getConfig().getTemplateEngine()->run(infile, str, tp);
diff --git a/shibsp/handler/impl/DiscoveryFeed.cpp b/shibsp/handler/impl/DiscoveryFeed.cpp
index 72934ee6..45c4c466 100644
--- a/shibsp/handler/impl/DiscoveryFeed.cpp
+++ b/shibsp/handler/impl/DiscoveryFeed.cpp
@@ -26,7 +26,6 @@
#include "internal.h"
#include "AgentConfig.h"
-#include "Application.h"
#include "exceptions.h"
#include "ServiceProvider.h"
#include "SPRequest.h"
@@ -41,7 +40,6 @@
#include <xmltooling/util/Threads.h>
using namespace shibsp;
-using namespace xmltooling;
using namespace std;
namespace shibsp {
@@ -71,8 +69,8 @@ namespace shibsp {
void receive(DDF& in, ostream& out);
private:
- void feedToFile(const Application& application, string& cacheTag) const;
- void feedToStream(const Application& application, string& cacheTag, ostream& os) const;
+ void feedToFile(string& cacheTag) const;
+ void feedToStream(string& cacheTag, ostream& os) const;
string m_dir;
bool m_cacheToClient;
@@ -154,7 +152,7 @@ pair<bool,long> DiscoveryFeed::run(SPRequest& request, bool isHandler) const
if (m_dir.empty()) {
// The feed is directly returned.
stringstream buf;
- feedToStream(request.getApplication(), s, buf);
+ feedToStream(s, buf);
if (!s.empty()) {
if (m_cacheToClient) {
string etag = '"' + s + '"';
@@ -166,13 +164,12 @@ pair<bool,long> DiscoveryFeed::run(SPRequest& request, bool isHandler) const
}
else {
// Indirect the feed through a file.
- feedToFile(request.getApplication(), s);
+ feedToFile(s);
}
}
else {
// When not out of process, we remote all the message processing.
DDF out,in = DDF(m_address.c_str());
- in.addmember("application_id").string(request.getApplication().getId());
if (!s.empty())
in.addmember("cache_tag").string(s.c_str());
DDFJanitor jin(in), jout(out);
@@ -204,7 +201,8 @@ pair<bool,long> DiscoveryFeed::run(SPRequest& request, bool isHandler) const
return make_pair(true, request.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_NOTMODIFIED));
}
- string fname = m_dir + '/' + request.getApplication().getHash() + '_' + s + ".json";
+ // TODO: uniqueify name
+ string fname = m_dir + '/' + /* request.getApplication().getHash() + '_' + */ s + ".json";
ifstream feed(fname.c_str());
if (!feed)
throw ConfigurationException("Unable to access cached feed.");
@@ -224,15 +222,6 @@ pair<bool,long> DiscoveryFeed::run(SPRequest& request, bool isHandler) const
void DiscoveryFeed::receive(DDF& in, ostream& out)
{
- // Find application.
- const char* aid = in["application_id"].string();
- const Application* app=aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
- if (!app) {
- // Something's horribly wrong.
- m_log.error("couldn't find application (%s) for discovery feed request", aid ? aid : "(missing)");
- throw ConfigurationException("Unable to locate application for discovery feed request, deleted?");
- }
-
string cacheTag;
if (in["cache_tag"].string())
cacheTag = in["cache_tag"].string();
@@ -242,14 +231,14 @@ void DiscoveryFeed::receive(DDF& in, ostream& out)
if (!m_dir.empty()) {
// We're relaying the feed through a file.
- feedToFile(*app, cacheTag);
+ feedToFile(cacheTag);
if (!cacheTag.empty())
ret.string(cacheTag.c_str());
}
else {
// We're relaying the feed directly.
ostringstream os;
- feedToStream(*app, cacheTag, os);
+ feedToStream(cacheTag, os);
if (!cacheTag.empty())
ret.addmember("cache_tag").string(cacheTag.c_str());
string feed = os.str();
@@ -259,7 +248,7 @@ void DiscoveryFeed::receive(DDF& in, ostream& out)
out << ret;
}
-void DiscoveryFeed::feedToFile(const Application& application, string& cacheTag) const
+void DiscoveryFeed::feedToFile(string& cacheTag) const
{
#ifndef SHIBSP_LITE
m_log.debug("processing discovery feed request");
@@ -313,7 +302,7 @@ void DiscoveryFeed::feedToFile(const Application& application, string& cacheTag)
#endif
}
-void DiscoveryFeed::feedToStream(const Application& application, string& cacheTag, ostream& os) const
+void DiscoveryFeed::feedToStream(string& cacheTag, ostream& os) const
{
#ifndef SHIBSP_LITE
m_log.debug("processing discovery feed request");
diff --git a/shibsp/handler/impl/LocalLogoutInitiator.cpp b/shibsp/handler/impl/LocalLogoutInitiator.cpp
index 973de0a1..7ea1d017 100644
--- a/shibsp/handler/impl/LocalLogoutInitiator.cpp
+++ b/shibsp/handler/impl/LocalLogoutInitiator.cpp
@@ -26,7 +26,7 @@
#include "internal.h"
#include "exceptions.h"
-#include "Application.h"
+#include "Agent.h"
#include "ServiceProvider.h"
#include "SessionCache.h"
#include "SPRequest.h"
@@ -35,7 +35,6 @@
#include <mutex>
using namespace shibsp;
-using namespace xmltooling;
using namespace std;
namespace shibsp {
@@ -56,9 +55,7 @@ namespace shibsp {
pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
private:
- pair<bool,long> doRequest(
- const Application& application, const HTTPRequest& request, HTTPResponse& httpResponse, Session* session
- ) const;
+ pair<bool,long> doRequest(SPRequest& request, Session* session) const;
string m_appId;
};
@@ -112,7 +109,7 @@ pair<bool,long> LocalLogoutInitiator::run(SPRequest& request, bool isHandler) co
catch (const std::exception& ex) {
m_log.error("error accessing current session: %s", ex.what());
}
- return doRequest(request.getApplication(), request, request, session);
+ return doRequest(request, session);
}
else {
// When not out of process, we remote the request.
@@ -166,9 +163,7 @@ void LocalLogoutInitiator::receive(DDF& in, ostream& out)
#endif
}
-pair<bool,long> LocalLogoutInitiator::doRequest(
- const Application& application, const HTTPRequest& httpRequest, HTTPResponse& httpResponse, Session* session
- ) const
+pair<bool,long> LocalLogoutInitiator::doRequest(SPRequest& request, Session* session) const
{
if (session) {
// Guard the session in case of exception.
@@ -177,25 +172,27 @@ pair<bool,long> LocalLogoutInitiator::doRequest(
// Do back channel notification.
bool result;
vector<string> sessions(1, session->getID());
- result = notifyBackChannel(application, httpRequest.getRequestURL(), sessions, true);
+ result = notifyBackChannel(request, sessions, true);
time_t revocationExp = session->getExpiration();
locker.unlock(); // unlock the session
- application.getServiceProvider().getSessionCache()->remove(application, httpRequest, &httpResponse, revocationExp);
- if (!result)
- return sendLogoutPage(application, httpRequest, httpResponse, "partial");
+ request.getAgent().getSessionCache()->remove(request, revocationExp);
+ if (!result) {
+ //return sendLogoutPage(request, "partial");
+ }
}
// Route back to return location specified, or use the local template.
- const char* dest = httpRequest.getParameter("return");
+ const char* dest = request.getParameter("return");
if (dest) {
// Relative URLs get promoted, absolutes get validated.
if (*dest == '/') {
string d(dest);
- httpRequest.absolutize(d);
- return make_pair(true, httpResponse.sendRedirect(d.c_str()));
+ request.absolutize(d);
+ return make_pair(true, request.sendRedirect(d.c_str()));
}
- application.limitRedirect(httpRequest, dest);
- return make_pair(true, httpResponse.sendRedirect(dest));
+ request.limitRedirect(dest);
+ return make_pair(true, request.sendRedirect(dest));
}
- return sendLogoutPage(application, httpRequest, httpResponse, "local");
+
+ //return sendLogoutPage(application, httpRequest, httpResponse, "local");
}
diff --git a/shibsp/handler/impl/LogoutHandler.cpp b/shibsp/handler/impl/LogoutHandler.cpp
index b65b4b40..6c5bf989 100644
--- a/shibsp/handler/impl/LogoutHandler.cpp
+++ b/shibsp/handler/impl/LogoutHandler.cpp
@@ -27,7 +27,6 @@
#include "internal.h"
#include "exceptions.h"
#include "AgentConfig.h"
-#include "Application.h"
#include "ServiceProvider.h"
#include "SessionCache.h"
#include "SPRequest.h"
@@ -39,7 +38,6 @@
#include <boost/lexical_cast.hpp>
using namespace shibsp;
-using namespace boost;
using namespace std;
LogoutHandler::LogoutHandler() : m_initiator(true)
@@ -50,41 +48,6 @@ LogoutHandler::~LogoutHandler()
{
}
-pair<bool,long> LogoutHandler::sendLogoutPage(
- const Application& application, const HTTPRequest& request, HTTPResponse& response, const char* type
- ) const
-{
- string tname = string(type) + "Logout";
- const PropertySet* props = application.getPropertySet("Errors");
-
- pair<bool,const char*> prop = props ? props->getString(tname.c_str()) : pair<bool,const char*>(false,nullptr);
- if (!prop.first) {
- tname += ".html";
- prop.second = tname.c_str();
- }
- response.setContentType("text/html");
- response.setResponseHeader("Expires","Wed, 01 Jan 1997 12:00:00 GMT");
- response.setResponseHeader("Cache-Control","private,no-store,no-cache,max-age=0");
- string fname(prop.second);
- ifstream infile(AgentConfig::getConfig().getPathResolver().resolve(fname, PathResolver::SHIBSP_CFG_FILE).c_str());
- if (!infile)
- throw ConfigurationException("Unable to access HTML template.");
- //TemplateParameters tp;
-
- // If the externalParameters option isn't set, don't populate the request field.
- pair<bool,bool> externalParameters =
- props ? props->getBool("externalParameters") : pair<bool,bool>(false,false);
- if (externalParameters.first && externalParameters.second) {
- //tp.m_request = &request;
- }
-
- //tp.setPropertySet(props);
- //tp.m_map["logoutStatus"] = "Logout completed successfully."; // Backward compatibility.
- stringstream str;
- //XMLToolingConfig::getConfig().getTemplateEngine()->run(infile, str, tp);
- return make_pair(true,response.sendResponse(str));
-}
-
pair<bool,long> LogoutHandler::run(SPRequest& request, bool isHandler) const
{
// If we're inside a chain, do nothing.
@@ -96,7 +59,7 @@ pair<bool,long> LogoutHandler::run(SPRequest& request, bool isHandler) const
return make_pair(false,0L);
// Try another front-channel notification. No extra parameters and the session is implicit.
- return notifyFrontChannel(request.getApplication(), request, request);
+ return notifyFrontChannel(request);
}
void LogoutHandler::receive(DDF& in, ostream& out)
@@ -106,32 +69,21 @@ void LogoutHandler::receive(DDF& in, ostream& out)
if (in["notify"].integer() != 1)
throw RemotintgException("Unsupported operation.");
- // Find application.
- const char* aid=in["application_id"].string();
- const Application* app=aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
- if (!app) {
- // Something's horribly wrong.
- Category::getInstance(SHIBSP_LOGCAT ".Logout").error("couldn't find application (%s) for logout", aid ? aid : "(missing)");
- throw ConfigurationException("Unable to locate application for logout, deleted?");
- }
-
vector<string> sessions;
DDF s = in["sessions"];
DDF temp = s.first();
while (temp.isstring()) {
sessions.push_back(temp.string());
temp = s.next();
- if (notifyBackChannel(*app, in["url"].string(), sessions, in["local"].integer()==1))
- ret.integer(1);
+ //if (notifyBackChannel(*app, in["url"].string(), sessions, in["local"].integer()==1))
+ //ret.integer(1);
}
out << ret;
}
pair<bool,long> LogoutHandler::notifyFrontChannel(
- const Application& application,
- const HTTPRequest& request,
- HTTPResponse& response,
+ SPRequest& request,
const map<string,string>* params
) const
{
@@ -145,7 +97,7 @@ pair<bool,long> LogoutHandler::notifyFrontChannel(
param = request.getParameter("return");
// Fetch the next front notification URL and bump the index for the next round trip.
- string loc = application.getNotificationURL(request.getRequestURL(), true, index++);
+ string loc = request.getNotificationURL(true, index++);
if (loc.empty())
return make_pair(false,0L);
@@ -160,7 +112,7 @@ pair<bool,long> LogoutHandler::notifyFrontChannel(
string locstr(start, end ? end - start : strlen(start));
// Add a signal that we're coming back from notification and the next index.
- locstr = locstr + "?notifying=1&index=" + lexical_cast<string>(index);
+ locstr = locstr + "?notifying=1&index=" + boost::lexical_cast<string>(index);
// Add return if set.
if (param)
@@ -182,7 +134,7 @@ pair<bool,long> LogoutHandler::notifyFrontChannel(
// Add the notifier's return parameter to the destination location and redirect.
// This is NOT the same as the return parameter that might be embedded inside it ;-)
loc = loc + "&return=" + encoder.encode(locstr.c_str());
- return make_pair(true, response.sendRedirect(loc.c_str()));
+ return make_pair(true, request.sendRedirect(loc.c_str()));
}
#ifndef SHIBSP_LITE
@@ -217,9 +169,7 @@ namespace {
};
#endif
-bool LogoutHandler::notifyBackChannel(
- const Application& application, const char* requestURL, const vector<string>& sessions, bool local
- ) const
+bool LogoutHandler::notifyBackChannel(const SPRequest& request, const vector<string>& sessions, bool local) const
{
if (sessions.empty()) {
Category::getInstance(SHIBSP_LOGCAT ".Logout").error("no sessions supplied to back channel notification method");
@@ -227,7 +177,7 @@ bool LogoutHandler::notifyBackChannel(
}
unsigned int index = 0;
- string endpoint = application.getNotificationURL(requestURL, false, index++);
+ string endpoint = request.getNotificationURL(false, index++);
if (endpoint.empty())
return true;
@@ -267,11 +217,12 @@ bool LogoutHandler::notifyBackChannel(
}
// When not out of process, we remote the back channel work.
+ // TODO: remove anyway....
DDF out,in(m_address.c_str());
DDFJanitor jin(in), jout(out);
in.addmember("notify").integer(1);
- in.addmember("application_id").string(application.getId());
- in.addmember("url").string(requestURL);
+ //in.addmember("application_id").string(application.getId());
+ in.addmember("url").string(request.getRequestURL());
if (local)
in.addmember("local").integer(1);
DDF s = in.addmember("sessions").list();
diff --git a/shibsp/handler/impl/MetadataGenerator.cpp b/shibsp/handler/impl/MetadataGenerator.cpp
index 2687f5fd..9d493552 100644
--- a/shibsp/handler/impl/MetadataGenerator.cpp
+++ b/shibsp/handler/impl/MetadataGenerator.cpp
@@ -25,7 +25,6 @@
*/
#include "internal.h"
-#include "Application.h"
#include "exceptions.h"
#include "ServiceProvider.h"
#include "SPRequest.h"
@@ -58,7 +57,6 @@ namespace shibsp {
private:
pair<bool,long> processMessage(
- const Application& application,
const char* handlerURL,
const char* entityID,
HTTPResponse& httpResponse
@@ -348,12 +346,11 @@ pair<bool,long> MetadataGenerator::run(SPRequest& request, bool isHandler) const
try {
if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
// When out of process, we run natively and directly process the message.
- return processMessage(request.getApplication(), request.getHandlerURL(), request.getParameter("entityID"), request);
+ return processMessage(request.getHandlerURL(), request.getParameter("entityID"), request);
}
else {
// When not out of process, we remote all the message processing.
DDF out,in = DDF(m_address.c_str());
- in.addmember("application_id").string(request.getApplication().getId());
in.addmember("handler_url").string(request.getHandlerURL());
if (request.getParameter("entityID"))
in.addmember("entity_id").string(request.getParameter("entityID"));
@@ -372,16 +369,9 @@ pair<bool,long> MetadataGenerator::run(SPRequest& request, bool isHandler) const
void MetadataGenerator::receive(DDF& in, ostream& out)
{
- // Find application.
- const char* aid = in["application_id"].string();
+ /*
const char* hurl = in["handler_url"].string();
- const Application* app = aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
- if (!app) {
- // Something's horribly wrong.
- m_log.error("couldn't find application (%s) for metadata request", aid ? aid : "(missing)");
- throw ConfigurationException("Unable to locate application for metadata request, deleted?");
- }
- else if (!hurl) {
+ if (!hurl) {
throw ConfigurationException("Missing handler_url parameter in remoted method call.");
}
@@ -393,13 +383,12 @@ void MetadataGenerator::receive(DDF& in, ostream& out)
// Since we're remoted, the result should either be a throw, a false/0 return,
// which we just return as an empty structure, or a response/redirect,
// which we capture in the facade and send back.
- processMessage(*app, hurl, in["entity_id"].string(), *resp);
+ processMessage(hurl, in["entity_id"].string(), *resp);
out << ret;
+ */
}
-pair<bool,long> MetadataGenerator::processMessage(
- const Application& application, const char* handlerURL, const char* entityID, HTTPResponse& httpResponse
- ) const
+pair<bool,long> MetadataGenerator::processMessage(const char* handlerURL, const char* entityID, HTTPResponse& httpResponse) const
{
#ifndef SHIBSP_LITE
m_log.debug("processing metadata request");
diff --git a/shibsp/handler/impl/RemotedHandler.cpp b/shibsp/handler/impl/RemotedHandler.cpp
index cc129217..7327e7df 100644
--- a/shibsp/handler/impl/RemotedHandler.cpp
+++ b/shibsp/handler/impl/RemotedHandler.cpp
@@ -20,7 +20,6 @@
#include "internal.h"
#include "exceptions.h"
-#include "Application.h"
#include "ServiceProvider.h"
#include "SPRequest.h"
#include "handler/RemotedHandler.h"
@@ -314,7 +313,6 @@ DDF RemotedHandler::send(const SPRequest& request, DDF& in) const
DDF RemotedHandler::wrap(const SPRequest& request, const vector<string>* headers, bool certs) const
{
DDF in = DDF(m_address.c_str()).structure();
- in.addmember("application_id").string(request.getApplication().getId());
in.addmember("scheme").string(request.getScheme());
in.addmember("hostname").unsafe_string(request.getHostname());
in.addmember("port").integer(request.getPort());
diff --git a/shibsp/handler/impl/SAML2Logout.cpp b/shibsp/handler/impl/SAML2Logout.cpp
index 3d6d058e..59f54b7d 100644
--- a/shibsp/handler/impl/SAML2Logout.cpp
+++ b/shibsp/handler/impl/SAML2Logout.cpp
@@ -26,7 +26,6 @@
#include "internal.h"
#include "exceptions.h"
-#include "Application.h"
#include "ServiceProvider.h"
#include "SPRequest.h"
#include "handler/AbstractHandler.h"
@@ -36,7 +35,6 @@
#include <boost/scoped_ptr.hpp>
using namespace shibsp;
-using namespace xmltooling;
using namespace boost;
using namespace std;
@@ -57,7 +55,7 @@ namespace shibsp {
pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
private:
- pair<bool,long> doRequest(const Application& application, HTTPRequest& httpRequest, HTTPResponse& httpResponse) const;
+ pair<bool,long> doRequest(SPRequest& request) const;
};
#if defined (_MSC_VER)
@@ -146,7 +144,7 @@ pair<bool,long> SAML2Logout::run(SPRequest& request, bool isHandler) const
SPConfig& conf = SPConfig::getConfig();
if (conf.isEnabled(SPConfig::OutOfProcess)) {
// When out of process, we run natively and directly process the message.
- return doRequest(request.getApplication(), request, request);
+ return doRequest(request);
}
else {
// When not out of process, we remote all the message processing.
@@ -161,6 +159,7 @@ pair<bool,long> SAML2Logout::run(SPRequest& request, bool isHandler) const
void SAML2Logout::receive(DDF& in, ostream& out)
{
+ /*
// Find application.
const char* aid = in["application_id"].string();
const Application* app = aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
@@ -183,9 +182,10 @@ void SAML2Logout::receive(DDF& in, ostream& out)
// which we capture in the facade and send back.
doRequest(*app, *req, *resp);
out << ret;
+ */
}
-pair<bool,long> SAML2Logout::doRequest(const Application& application, HTTPRequest& request, HTTPResponse& response) const
+pair<bool,long> SAML2Logout::doRequest(SPRequest& request) const
{
#ifndef SHIBSP_LITE
// First capture the active session ID, if any.
diff --git a/shibsp/handler/impl/SAML2LogoutInitiator.cpp b/shibsp/handler/impl/SAML2LogoutInitiator.cpp
index b3975bdf..016ad037 100644
--- a/shibsp/handler/impl/SAML2LogoutInitiator.cpp
+++ b/shibsp/handler/impl/SAML2LogoutInitiator.cpp
@@ -26,16 +26,15 @@
#include "internal.h"
#include "exceptions.h"
-#include "Application.h"
+#include "Agent.h"
#include "ServiceProvider.h"
#include "SessionCache.h"
#include "handler/AbstractHandler.h"
#include "handler/LogoutInitiator.h"
+
#include <mutex>
using namespace shibsp;
-using namespace xmltooling;
-using namespace boost;
using namespace std;
namespace shibsp {
@@ -58,9 +57,7 @@ namespace shibsp {
pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
private:
- pair<bool,long> doRequest(
- const Application& application, const HTTPRequest& request, HTTPResponse& httpResponse, Session* session
- ) const;
+ pair<bool,long> doRequest(SPRequest& request, Session* session) const;
string m_appId;
bool m_deprecationSupport;
@@ -170,7 +167,7 @@ pair<bool,long> SAML2LogoutInitiator::run(SPRequest& request, bool isHandler) co
if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
// When out of process, we run natively.
- return doRequest(request.getApplication(), request, request, session);
+ return doRequest(request, session);
}
else {
// When not out of process, we remote the request.
@@ -236,20 +233,18 @@ void SAML2LogoutInitiator::receive(DDF& in, ostream& out)
#endif
}
-pair<bool,long> SAML2LogoutInitiator::doRequest(
- const Application& application, const HTTPRequest& httpRequest, HTTPResponse& httpResponse, Session* session
- ) const
+pair<bool,long> SAML2LogoutInitiator::doRequest(SPRequest& request, Session* session) const
{
unique_lock<Session> sessionLocker(*session, adopt_lock);
// Do back channel notification.
vector<string> sessions(1, session->getID());
- if (!notifyBackChannel(application, httpRequest.getRequestURL(), sessions, false)) {
+ if (!notifyBackChannel(request, sessions, false)) {
time_t revocationExp = session->getExpiration();
sessionLocker.unlock();
session = nullptr;
- application.getServiceProvider().getSessionCache()->remove(application, httpRequest, &httpResponse, revocationExp);
- return sendLogoutPage(application, httpRequest, httpResponse, "partial");
+ request.getAgent().getSessionCache()->remove(request, revocationExp);
+ //return sendLogoutPage(application, httpRequest, httpResponse, "partial");
}
#ifndef SHIBSP_LITE
diff --git a/shibsp/handler/impl/SAML2SessionInitiator.cpp b/shibsp/handler/impl/SAML2SessionInitiator.cpp
index 9135aba8..9bedb24f 100644
--- a/shibsp/handler/impl/SAML2SessionInitiator.cpp
+++ b/shibsp/handler/impl/SAML2SessionInitiator.cpp
@@ -25,7 +25,6 @@
*/
#include "internal.h"
-#include "Application.h"
#include "exceptions.h"
#include "ServiceProvider.h"
#include "handler/AbstractHandler.h"
@@ -33,8 +32,6 @@
#include "handler/SessionInitiator.h"
#include "util/SPConstants.h"
-#include <xercesc/util/XMLUniDefs.hpp>
-
#include <boost/scoped_ptr.hpp>
using namespace shibsp;
@@ -65,9 +62,7 @@ namespace shibsp {
private:
pair<bool,long> doRequest(
- const Application& application,
- const HTTPRequest* httpRequest,
- HTTPResponse& httpResponse,
+ SPRequest& request,
const char* entityID,
const XMLCh* acsIndex,
const char* attributeIndex,
@@ -201,7 +196,6 @@ pair<bool,long> SAML2SessionInitiator::run(SPRequest& request, string& entityID,
const char* requestTemplate = nullptr;
const char* outgoingBinding = nullptr;
bool isPassive=false,forceAuthn=false;
- const Application& app = request.getApplication();
// ECP means the ACS will be by value no matter what.
pair<bool,bool> acsByIndex = ECP ? make_pair(true,false) : getBool("acsByIndex");
@@ -210,7 +204,7 @@ pair<bool,long> SAML2SessionInitiator::run(SPRequest& request, string& entityID,
prop.second = request.getParameter("acsIndex");
if (prop.second && *prop.second) {
SPConfig::getConfig().deprecation().warn("Use of acsIndex when specifying response endpoint");
- ACS = app.getAssertionConsumerServiceByIndex(atoi(prop.second));
+ //ACS = app.getAssertionConsumerServiceByIndex(atoi(prop.second));
if (!ACS)
request.log(Priority::SHIB_WARN, "invalid acsIndex specified in request, using acsIndex property");
else if (ECP && !XMLString::equals(ACS->getString("Binding").second, nullptr)) {
@@ -224,8 +218,8 @@ pair<bool,long> SAML2SessionInitiator::run(SPRequest& request, string& entityID,
target = prop.second;
// Always need to recover target URL to compute handler below.
- recoverRelayState(app, request, request, target, false);
- app.limitRedirect(request, target.c_str());
+ recoverRelayState(request, target, false);
+ request.limitRedirect(target.c_str());
// Default is to allow externally supplied settings.
pair<bool,bool> externalInput = getBool("externalInput");
@@ -292,7 +286,7 @@ pair<bool,long> SAML2SessionInitiator::run(SPRequest& request, string& entityID,
pair<bool,unsigned int> index = getUnsignedInt("acsIndex", request, HANDLER_PROPERTY_MAP|HANDLER_PROPERTY_FIXED);
if (index.first) {
SPConfig::getConfig().deprecation().warn("Use of acsIndex when specifying response endpoint");
- ACS = app.getAssertionConsumerServiceByIndex(index.second);
+ //ACS = app.getAssertionConsumerServiceByIndex(index.second);
}
}
}
@@ -317,7 +311,7 @@ pair<bool,long> SAML2SessionInitiator::run(SPRequest& request, string& entityID,
}
return doRequest(
- app, &request, request, entityID.c_str(),
+ request, entityID.c_str(),
nullptr,
attributeIndex.first ? attributeIndex.second : nullptr,
false,
@@ -349,7 +343,7 @@ pair<bool,long> SAML2SessionInitiator::run(SPRequest& request, string& entityID,
}
return doRequest(
- app, &request, request, entityID.c_str(),
+ request, entityID.c_str(),
nullptr,
attributeIndex.first ? attributeIndex.second : nullptr,
false,
@@ -368,7 +362,6 @@ pair<bool,long> SAML2SessionInitiator::run(SPRequest& request, string& entityID,
// Remote the call.
DDF out,in = DDF(m_address.c_str()).structure();
DDFJanitor jin(in), jout(out);
- in.addmember("application_id").string(app.getId());
if (!entityID.empty())
in.addmember("entity_id").string(entityID.c_str());
if (isPassive)
@@ -438,13 +431,14 @@ pair<bool,long> SAML2SessionInitiator::unwrap(SPRequest& request, DDF& out) cons
// See if there's any response to send back.
if (!out["redirect"].isnull() || !out["response"].isnull()) {
// If so, we're responsible for handling the POST data, probably by dropping a cookie.
- preservePostData(request.getApplication(), request, request, out["RelayState"].string());
+ preservePostData(request, out["RelayState"].string());
}
return RemotedHandler::unwrap(request, out);
}
void SAML2SessionInitiator::receive(DDF& in, ostream& out)
{
+ /*
// Find application.
const char* aid = in["application_id"].string();
const Application* app = aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
@@ -489,12 +483,11 @@ void SAML2SessionInitiator::receive(DDF& in, ostream& out)
ret.structure();
ret.addmember("RelayState").unsafe_string(relayState.c_str());
out << ret;
+ */
}
pair<bool,long> SAML2SessionInitiator::doRequest(
- const Application& app,
- const HTTPRequest* httpRequest,
- HTTPResponse& httpResponse,
+ SPRequest& request,
const char* entityID,
const XMLCh* acsIndex,
const char* attributeIndex,
diff --git a/shibsp/handler/impl/SAMLDSSessionInitiator.cpp b/shibsp/handler/impl/SAMLDSSessionInitiator.cpp
index 132263df..2c2bf99f 100644
--- a/shibsp/handler/impl/SAMLDSSessionInitiator.cpp
+++ b/shibsp/handler/impl/SAMLDSSessionInitiator.cpp
@@ -19,17 +19,17 @@
*/
#include "internal.h"
-#include "Application.h"
#include "exceptions.h"
+#include "AgentConfig.h"
#include "handler/AbstractHandler.h"
#include "handler/SessionInitiator.h"
+#include "util/URLEncoder.h"
#include <boost/algorithm/string.hpp>
#include <xmltooling/XMLToolingConfig.h>
#include <xmltooling/util/URLEncoder.h>
using namespace shibsp;
-using namespace xmltooling;
using namespace boost;
using namespace std;
@@ -105,23 +105,22 @@ pair<bool,long> SAMLDSSessionInitiator::run(SPRequest& request, string& entityID
string target;
pair<bool,const char*> prop;
bool isPassive = false;
- const Application& app = request.getApplication();
pair<bool,const char*> discoveryURL = pair<bool,const char*>(false, nullptr);
if (isHandler) {
prop.second = request.getParameter("SAMLDS");
if (prop.second && !strcmp(prop.second,"1")) {
- XMLToolingException ex("No identity provider was selected by user.");
+ SessionException ex("No identity provider was selected by user.");
ex.addProperty("statusCode", "urn:oasis:names:tc:SAML:2.0:status:Requester");
ex.addProperty("statusCode2", "urn:oasis:names:tc:SAML:2.0:status:NoAvailableIDP");
- ex.raise();
+ throw ex;
}
prop = getString("target", request);
if (prop.first)
target = prop.second;
- recoverRelayState(app, request, request, target, false);
+ recoverRelayState(request, target, false);
pair<bool,bool> passopt = getBool("isPassive", request);
isPassive = passopt.first && passopt.second;
@@ -163,11 +162,11 @@ pair<bool,long> SAMLDSSessionInitiator::run(SPRequest& request, string& entityID
if (prop.second && *prop.second)
target = prop.second;
}
- preserveRelayState(app, request, target);
+ preserveRelayState(request, target);
if (!isHandler)
- preservePostData(app, request, request, target.c_str());
+ preservePostData(request, target.c_str());
- const URLEncoder* urlenc = XMLToolingConfig::getConfig().getURLEncoder();
+ const URLEncoder& urlenc = AgentConfig::getConfig().getURLEncoder();
if (isHandler) {
// Now the hard part. The base assumption is to append the entire query string, if any,
// to the self-link. But we want to replace target with the RelayState-preserved value
@@ -203,17 +202,17 @@ pair<bool,long> SAMLDSSessionInitiator::run(SPRequest& request, string& entityID
// Now append the sanitized target as needed.
if (!target.empty())
- returnURL = returnURL + "&target=" + urlenc->encode(target.c_str());
+ returnURL = returnURL + "&target=" + urlenc.encode(target.c_str());
}
else {
// For a virtual handler, we append target to the return link.
if (!target.empty())
- returnURL = returnURL + "&target=" + urlenc->encode(target.c_str());
+ returnURL = returnURL + "&target=" + urlenc.encode(target.c_str());
// Preserve designated request settings on the URL.
for (vector<string>::const_iterator opt = m_preservedOptions.begin(); opt != m_preservedOptions.end(); ++ opt) {
const char* optval = request.getRequestSettings().first->getString(opt->c_str());
if (optval)
- returnURL = returnURL + '&' + (*opt) + '=' + urlenc->encode(optval);
+ returnURL = returnURL + '&' + (*opt) + '=' + urlenc.encode(optval);
}
}
@@ -229,18 +228,18 @@ pair<bool,long> SAMLDSSessionInitiator::run(SPRequest& request, string& entityID
}
}
else {
- prop = app.getString("entityID");
+ prop.second = request.getRequestSettings().first->getString("entityID");
}
- string req=string(discoveryURL.second) + (strchr(discoveryURL.second,'?') ? '&' : '?') + "entityID=" + urlenc->encode(prop.second) +
- "&return=" + urlenc->encode(returnURL.c_str());
+ string req=string(discoveryURL.second) + (strchr(discoveryURL.second,'?') ? '&' : '?') + "entityID=" + urlenc.encode(prop.second) +
+ "&return=" + urlenc.encode(returnURL.c_str());
if (m_returnParam)
req = req + "&returnIDParam=" + m_returnParam;
if (isPassive)
req += "&isPassive=true";
prop = getString("discoveryPolicy");
if (prop.first)
- req += "&policy=" + urlenc->encode(prop.second);
+ req += "&policy=" + urlenc.encode(prop.second);
return make_pair(true, request.sendRedirect(req.c_str()));
}
diff --git a/shibsp/handler/impl/SessionHandler.cpp b/shibsp/handler/impl/SessionHandler.cpp
index 3e6591b0..41b92ef0 100644
--- a/shibsp/handler/impl/SessionHandler.cpp
+++ b/shibsp/handler/impl/SessionHandler.cpp
@@ -25,7 +25,6 @@
*/
#include "internal.h"
-#include "Application.h"
#include "exceptions.h"
#include "ServiceProvider.h"
#include "SessionCache.h"
diff --git a/shibsp/handler/impl/SessionInitiator.cpp b/shibsp/handler/impl/SessionInitiator.cpp
index b6ccde91..44dd7f02 100644
--- a/shibsp/handler/impl/SessionInitiator.cpp
+++ b/shibsp/handler/impl/SessionInitiator.cpp
@@ -26,12 +26,10 @@
#include "internal.h"
#include "exceptions.h"
-#include "Application.h"
#include "SPRequest.h"
#include "handler/SessionInitiator.h"
using namespace shibsp;
-using namespace xmltooling;
using namespace std;
SessionInitiator::SessionInitiator()
@@ -97,7 +95,7 @@ bool SessionInitiator::checkCompatibility(SPRequest& request, bool isHandler) co
pair<bool,long> SessionInitiator::run(SPRequest& request, bool isHandler) const
{
- cleanRelayState(request.getApplication(), request, request);
+ cleanRelayState(request);
const char* entityID = nullptr;
pair<bool,const char*> param = getString("entityIDParam");
@@ -150,8 +148,8 @@ pair<bool,long> SessionInitiator::run(SPRequest& request, bool isHandler) const
log(Priority::SHIB_INFO, "trapping SessionInitiator error condition and returning to target location");
flag = request.getParameter("target");
string target(flag ? flag : "");
- recoverRelayState(request.getApplication(), request, request, target, false);
- request.getApplication().limitRedirect(request, target.c_str());
+ recoverRelayState(request, target, false);
+ request.limitRedirect(target.c_str());
return make_pair(true, request.sendRedirect(target.c_str()));
}
}
diff --git a/shibsp/handler/impl/StatusHandler.cpp b/shibsp/handler/impl/StatusHandler.cpp
index beb7280a..112e962b 100644
--- a/shibsp/handler/impl/StatusHandler.cpp
+++ b/shibsp/handler/impl/StatusHandler.cpp
@@ -25,8 +25,8 @@
*/
#include "internal.h"
-#include "Application.h"
#include "exceptions.h"
+#include "Agent.h"
#include "ServiceProvider.h"
#include "SPRequest.h"
#include "handler/RemotedHandler.h"
@@ -66,7 +66,7 @@ namespace shibsp {
void receive(DDF& in, ostream& out);
private:
- pair<bool,long> processMessage(const Application& application, const HTTPRequest& httpRequest, HTTPResponse& httpResponse) const;
+ pair<bool,long> processMessage(SPRequest& request) const;
ostream& systemInfo(ostream& os) const;
};
@@ -238,7 +238,7 @@ pair<bool,long> StatusHandler::run(SPRequest& request, bool isHandler) const
if (target) {
// RequestMap query, so handle it inproc.
DummyRequest dummy(target);
- RequestMapper::Settings settings = request.getApplication().getServiceProvider().getRequestMapper()->getSettings(dummy);
+ RequestMapper::Settings settings = request.getAgent().getRequestMapper()->getSettings(dummy);
XMLDateTime now(time(nullptr), false);
now.parseDateTime();
auto_ptr_char timestamp(now.getFormattedString());
@@ -268,7 +268,7 @@ pair<bool,long> StatusHandler::run(SPRequest& request, bool isHandler) const
try {
if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
// When out of process, we run natively and directly process the message.
- return processMessage(request.getApplication(), request, request);
+ return processMessage(request);
}
else {
// When not out of process, we remote all the message processing.
@@ -320,6 +320,7 @@ pair<bool,long> StatusHandler::run(SPRequest& request, bool isHandler) const
void StatusHandler::receive(DDF& in, ostream& out)
{
+ /*
// Find application.
const char* aid = in["application_id"].string();
const Application* app = aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
@@ -340,11 +341,10 @@ void StatusHandler::receive(DDF& in, ostream& out)
// which we capture in the facade and send back.
processMessage(*app, *req, *resp);
out << ret;
+ */
}
-pair<bool,long> StatusHandler::processMessage(
- const Application& application, const HTTPRequest& httpRequest, HTTPResponse& httpResponse
- ) const
+pair<bool,long> StatusHandler::processMessage(SPRequest& request) const
{
#ifndef SHIBSP_LITE
m_log.debug("processing status request");
diff --git a/shibsp/impl/StorageServiceSessionCache.cpp b/shibsp/impl/StorageServiceSessionCache.cpp
index 1a44782b..26618c0c 100644
--- a/shibsp/impl/StorageServiceSessionCache.cpp
+++ b/shibsp/impl/StorageServiceSessionCache.cpp
@@ -34,15 +34,12 @@
#include "internal.h"
-#include "Application.h"
#include "exceptions.h"
-#include "ServiceProvider.h"
+#include "SPRequest.h"
#include "attribute/Attribute.h"
#include "handler/RemotedHandler.h"
#include "impl/StoredSession.h"
#include "impl/StorageServiceSessionCache.h"
-#include "io/HTTPRequest.h"
-#include "io/HTTPResponse.h"
#include "util/IPRange.h"
#include "util/SPConstants.h"
@@ -51,7 +48,6 @@
#include <boost/bind.hpp>
#include <xmltooling/security/DataSealer.h>
#include <xmltooling/util/Threads.h>
-#include <xmltooling/util/URLEncoder.h>
#include <xmltooling/util/XMLHelper.h>
#include <xercesc/util/XMLStringTokenizer.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
@@ -220,34 +216,24 @@ SSCache::~SSCache()
#endif
}
-unsigned long SSCache::getCacheTimeout(const Application& app) const
+unsigned long SSCache::getCacheTimeout(const SPRequest& request) const
{
// Computes offset for adjusting expiration of sessions.
// This can either be static, or dynamic based on the per-app session timeout or lifetime.
if (m_cacheTimeout)
return m_cacheTimeout;
- pair<bool, unsigned int> timeout = pair<bool, unsigned int>(false, 3600);
- const PropertySet* props = app.getPropertySet("Sessions");
- if (props) {
- timeout = props->getUnsignedInt("timeout");
- if (!timeout.first)
- timeout.second = 3600;
- }
+
+ unsigned int timeout = request.getRequestSettings().first->getUnsignedInt("timeout", 3600);
+
// As long as one of the two factors is set, add them together.
- if (timeout.second > 0 || m_cacheAllowance > 0)
- return timeout.second + m_cacheAllowance;
+ if (timeout > 0 || m_cacheAllowance > 0)
+ return timeout + m_cacheAllowance;
// If timeouts are off, and there's no cache slop set, then use the lifetime.
- timeout = pair<bool, unsigned int>(false, 28800);
- if (props) {
- timeout = props->getUnsignedInt("lifetime");
- if (!timeout.first || timeout.second == 0)
- timeout.second = 28800;
- }
- return timeout.second;
+ return request.getRequestSettings().first->getUnsignedInt("lifetime", 28800);
}
-string SSCache::active(const Application& app, const HTTPRequest& request)
+string SSCache::active(const SPRequest& request)
{
if (!m_inboundHeader.empty()) {
string session_id = request.getHeader(m_inboundHeader.c_str());
@@ -255,7 +241,7 @@ string SSCache::active(const Application& app, const HTTPRequest& request)
return session_id;
}
- const char* session_id = request.getCookie(app.getCookieName("_shibsession_").c_str());
+ const char* session_id = request.getCookie(getCookieName(request, "_shibsession_").c_str());
return (session_id ? session_id : "");
}
@@ -801,27 +787,42 @@ bool SSCache::stronglyMatches(const XMLCh* idp, const XMLCh* sp, const saml2::Na
#endif
-HTTPResponse::samesite_t SSCache::getSameSitePolicy(const Application& app) const
+HTTPResponse::samesite_t SSCache::getSameSitePolicy(const SPRequest& request) const
{
- const PropertySet* props = app.getPropertySet("Sessions");
- if (props) {
- pair<bool,const char*> sameSiteSession = props->getString("sameSiteSession");
- if (sameSiteSession.first) {
- if (!strcmp(sameSiteSession.second, "None")) {
- return HTTPResponse::SAMESITE_NONE;
- }
- else if (!strcmp(sameSiteSession.second, "Lax")) {
- return HTTPResponse::SAMESITE_LAX;
- }
- else if (!strcmp(sameSiteSession.second, "Strict")) {
- return HTTPResponse::SAMESITE_STRICT;
- }
+ const char* sameSiteSession = request.getRequestSettings().first->getString("sameSiteSession");
+ if (sameSiteSession) {
+ if (!strcmp(sameSiteSession, "None")) {
+ return HTTPResponse::SAMESITE_NONE;
+ }
+ else if (!strcmp(sameSiteSession, "Lax")) {
+ return HTTPResponse::SAMESITE_LAX;
+ }
+ else if (!strcmp(sameSiteSession, "Strict")) {
+ return HTTPResponse::SAMESITE_STRICT;
}
}
return HTTPResponse::SAMESITE_ABSENT;
}
-Session* SSCache::_find(const Application& app, const char* key, const char* recovery, const char* client_addr, time_t* timeout)
+string SSCache::getCookieName(const SPRequest& request, const char* prefix, time_t* lifetime) const
+{
+ if (lifetime)
+ *lifetime = 0;
+ if (!prefix)
+ prefix = "";
+ if (lifetime) {
+ unsigned int lt = request.getRequestSettings().first->getUnsignedInt("cookieLifetime", 0);
+ if (lt > 0)
+ *lifetime = lt;
+ }
+ const char* p = request.getRequestSettings().first->getString("cookieName");
+ if (p)
+ return string(prefix) + p;
+
+ return string(prefix); // TODO: implement some form of uniqueification for agent + getHash();
+}
+
+Session* SSCache::_find(const char* bucketID, const char* key, const char* recovery, const char* client_addr, time_t* timeout)
{
StoredSession* session=nullptr;
@@ -850,7 +851,7 @@ Session* SSCache::_find(const Application& app, const char* key, const char* rec
in.structure();
in.addmember("key").string(key);
in.addmember("sealed").string(recovery);
- in.addmember("application_id").string(app.getId());
+ in.addmember("bucket_id").string(bucketID);
if (timeout && *timeout) {
// On 64-bit Windows, time_t doesn't fit in a long, so I'm using ISO timestamps.
#ifndef HAVE_GMTIME_R
@@ -969,36 +970,37 @@ Session* SSCache::_find(const Application& app, const char* key, const char* rec
}
}
- if (!XMLString::equals(session->getApplicationID(), app.getId())) {
- m_log.warn("an application (%s) tried to access another application's session", app.getId());
+ if (!XMLString::equals(session->getBucketID(), bucketID)) {
+ m_log.warn("session did not contain the expected bucket identifier(%s)", bucketID);
session->unlock();
return nullptr;
}
// Verify currency and update the timestamp if indicated by caller.
try {
- session->validate(app, client_addr, timeout);
+ session->validate(bucketID, client_addr, timeout);
}
catch (...) {
session->unlock();
- remove(app, key);
+ remove(bucketID, key);
throw;
}
return session;
}
-Session* SSCache::find(const Application& app, HTTPRequest& request, const char* client_addr, time_t* timeout)
+Session* SSCache::find(SPRequest& request, const char* client_addr, time_t* timeout)
{
- string id = active(app, request);
+ string id = active(request);
if (id.empty())
return nullptr;
- HTTPResponse::samesite_t sameSitePolicy = getSameSitePolicy(app);
- const char* c = request.getCookie(app.getCookieName("_shibsealed_").c_str());
+ HTTPResponse::samesite_t sameSitePolicy = getSameSitePolicy(request);
+
+ const char* bucketID = request.getRequestSettings().first->getString("sessionBucket", "default");
try {
- Session* session = _find(app, id.c_str(), c, client_addr, timeout);
+ Session* session = _find(bucketID, id.c_str(), nullptr, client_addr, timeout);
if (session)
return session;
@@ -1006,8 +1008,7 @@ Session* SSCache::find(const Application& app, HTTPRequest& request, const char*
if (response) {
if (!m_outboundHeader.empty())
response->setResponseHeader(m_outboundHeader.c_str(), nullptr);
- response->setCookie(app.getCookieName("_shibsession_").c_str(), nullptr, 0, sameSitePolicy);
- response->setCookie(app.getCookieName("_shibsealed_").c_str(), nullptr, 0, sameSitePolicy);
+ response->setCookie(getCookieName(request, "_shibsession_").c_str(), nullptr, 0, sameSitePolicy);
}
}
catch (const std::exception&) {
@@ -1015,141 +1016,17 @@ Session* SSCache::find(const Application& app, HTTPRequest& request, const char*
if (response) {
if (!m_outboundHeader.empty())
response->setResponseHeader(m_outboundHeader.c_str(), nullptr);
- response->setCookie(app.getCookieName("_shibsession_").c_str(), nullptr, 0, sameSitePolicy);
- response->setCookie(app.getCookieName("_shibsealed_").c_str(), nullptr, 0, sameSitePolicy);
+ response->setCookie(getCookieName(request, "_shibsession_").c_str(), nullptr, 0, sameSitePolicy);
}
throw;
}
return nullptr;
}
-bool SSCache::recover(const Application& app, const char* key, const char* data)
-{
- if (!SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
- m_log.debug("remoting recovery of session from sealed cookie");
- // Remote the request.
- DDF in("recover::" STORAGESERVICE_SESSION_CACHE "::SessionCache"), out;
- DDFJanitor jin(in);
- in.structure();
- in.addmember("key").string(key);
- in.addmember("application_id").string(app.getId());
- in.addmember("sealed").string(data);
-
- //out = app.getServiceProvider().getListenerService()->send(in);
- if (!out.isint() || out.integer() != 1) {
- out.destroy();
- m_log.debug("recovery of session (%s) failed", key);
- return false;
- }
-
- out.destroy();
- m_log.debug("session (%s) recovered from sealed cookie", key);
- }
- else {
- // We're out of process, so we can recover the session.
-#ifndef SHIBSP_LITE
- const DataSealer* sealer = XMLToolingConfig::getConfig().getDataSealer();
- if (!sealer) {
- m_log.warn("can't attempt recovery of session (%s), no DataSealer configured", key);
- return false;
- }
-
- m_log.debug("checking for revocation of session (%s)", key);
- try {
- if (m_storage_lite->readString("Revoked", key) > 0) {
- m_log.warn("blocked recovery of revoked session (%s)", key);
- return false;
- }
- }
- catch (const std::exception& ex) {
- if (m_softRevocation)
- m_log.warn("ignoring failed check for revocation of session (%s): %s", ex.what());
- else {
- m_log.warn("check for revocation of session (%s) failed, treating as revoked: %s", ex.what());
- return false;
- }
- }
-
- m_log.debug("attempting recovery of session (%s)", key);
-
- DDF obj;
- DDFJanitor jobj(obj);
- string unwrapped;
-
- char* dup = nullptr;
- try {
- dup = strdup(data);
- XMLToolingConfig::getConfig().getURLEncoder()->decode(dup);
- unwrapped = sealer->unwrap(dup);
- free(dup);
-
- stringstream str(unwrapped);
- str >> obj;
- }
- catch (const std::exception& e) {
- if (dup)
- free(dup);
- m_log.error("failed to unwrap sealed session data with DataSealer: %s", e.what());
- return false;
- }
-
- if (!obj.isstruct() || !obj.name() || strcmp(obj.name(), key)) {
- m_log.info("recovered session data was invalid for session (%s)", key);
- return false;
- }
-
- scoped_ptr<saml2::NameID> nameidObject;
- const char* nameid = obj["nameid"].string();
- if (nameid) {
- // Parse and bind the document into an XMLObject.
- istringstream instr(nameid);
- DOMDocument* doc = XMLToolingConfig::getConfig().getParser().parse(instr);
- XercesJanitor<DOMDocument> janitor(doc);
- nameidObject.reset(saml2::NameIDBuilder::buildNameID());
- nameidObject->unmarshall(doc->getDocumentElement(), true);
- janitor.release();
- }
-
- m_log.debug("storing recovered session (%s)...", key);
- time_t now = time(nullptr);
- if (!m_storage->createText(key, "session", unwrapped.c_str(), now + getCacheTimeout(app))) {
- m_log.debug("recovered session (%s) matched existing record, likely a race condition");
- return true;
- }
-
- // Store the reverse mapping for logout.
- auto_ptr_char name(nameidObject ? nameidObject->getName() : nullptr);
- if (name.get() && *name.get() && m_reverseIndex
- && (m_excludedNames.size() == 0 || m_excludedNames.count(nameidObject->getName()) == 0)) {
- try {
- auto_ptr_XMLCh exp(obj["expires"].string());
- if (exp.get()) {
- XMLDateTime iso(exp.get());
- iso.parseDateTime();
- insert(key, iso.getEpoch(), name.get(), obj["session_index"].string());
- }
- }
- catch (const std::exception& ex) {
- m_log.error("error storing back mapping of NameID for logout: %s", ex.what());
- }
- }
-
- const char* pid = obj["entity_id"].string();
- const char* prot = obj["protocol"].string();
- m_log.info("session recovered: ID (%s) IdP (%s) Protocol(%s)",
- key, pid ? pid : "none", prot ? prot : "none");
-#else
- throw ConfigurationException("SessionCache recovery requires a DataSealer.");
-#endif
- }
-
- return true;
-}
-
-void SSCache::remove(const Application& app, const HTTPRequest& request, HTTPResponse* response, time_t revocationExp)
+void SSCache::remove(SPRequest& request, time_t revocationExp)
{
string session_id;
- string shib_cookie = app.getCookieName("_shibsession_");
+ string shib_cookie = getCookieName(request, "_shibsession_");
if (!m_inboundHeader.empty())
session_id = request.getHeader(m_inboundHeader.c_str());
@@ -1160,18 +1037,16 @@ void SSCache::remove(const Application& app, const HTTPRequest& request, HTTPRes
}
if (!session_id.empty()) {
- if (response) {
- if (!m_outboundHeader.empty())
- response->setResponseHeader(m_outboundHeader.c_str(), nullptr);
- HTTPResponse::samesite_t sameSitePolicy = getSameSitePolicy(app);
- response->setCookie(shib_cookie.c_str(), nullptr, 0, sameSitePolicy);
- response->setCookie(app.getCookieName("_shibsealed_").c_str(), nullptr, 0, sameSitePolicy);
- }
- remove(app, session_id.c_str(), revocationExp);
+ if (!m_outboundHeader.empty())
+ request.setResponseHeader(m_outboundHeader.c_str(), nullptr);
+ HTTPResponse::samesite_t sameSitePolicy = getSameSitePolicy(request);
+ request.setCookie(shib_cookie.c_str(), nullptr, 0, sameSitePolicy);
+ request.setCookie(request.getCookieName("_shibsealed_").c_str(), nullptr, 0, sameSitePolicy);
+ remove(request.getRequestSettings().first->getString("sessionBucket", "default"), session_id.c_str(), revocationExp);
}
}
-void SSCache::remove(const Application& app, const char* key, time_t revocationExp)
+void SSCache::remove(const char* bucketID, const char* key, time_t revocationExp)
{
// Take care of local copy.
if (inproc)
@@ -1210,7 +1085,7 @@ void SSCache::remove(const Application& app, const char* key, time_t revocationE
DDFJanitor jin(in);
in.structure();
in.addmember("key").string(key);
- in.addmember("application_id").string(app.getId());
+ in.addmember("bucket_id").string(bucketID);
//DDF out = app.getServiceProvider().getListenerService()->send(in);
//out.destroy();
diff --git a/shibsp/impl/StorageServiceSessionCache.h b/shibsp/impl/StorageServiceSessionCache.h
index f33f7daf..4c7745db 100644
--- a/shibsp/impl/StorageServiceSessionCache.h
+++ b/shibsp/impl/StorageServiceSessionCache.h
@@ -54,9 +54,7 @@ namespace shibsp {
void insert(
std::string& sessionID,
- const Application& app,
- const xmltooling::HTTPRequest& httpRequest,
- xmltooling::HTTPResponse& httpResponse,
+ const SPRequest& request,
time_t expires,
const opensaml::saml2md::EntityDescriptor* issuer=nullptr,
const XMLCh* protocol=nullptr,
@@ -69,52 +67,46 @@ namespace shibsp {
const std::vector<Attribute*>* attributes=nullptr
);
std::vector<std::string>::size_type logout(
- const Application& app,
+ const char* bucketID,
const opensaml::saml2md::EntityDescriptor* issuer,
const opensaml::saml2::NameID& nameid,
const std::set<std::string>* indexes,
time_t expires,
std::vector<std::string>& sessions
) {
- return _logout(app, issuer, nameid, indexes, expires, sessions, 0);
+ return _logout(bucketID, issuer, nameid, indexes, expires, sessions, 0);
}
bool matches(
- const Application& app,
- xmltooling::HTTPRequest& request,
+ const SPRequest& request,
const opensaml::saml2md::EntityDescriptor* issuer,
const opensaml::saml2::NameID& nameid,
const std::set<std::string>* indexes
);
#endif
- std::string active(const Application& app, const HTTPRequest& request);
- Session* find(const Application& app, HTTPRequest& request, const char* client_addr=nullptr, time_t* timeout=nullptr);
-
- void remove(
- const Application& app,
- const HTTPRequest& request,
- HTTPResponse* response=nullptr,
- time_t revocationExp=0
- );
+ std::string active(const SPRequest& request);
+ Session* find(SPRequest& request, const char* client_addr=nullptr, time_t* timeout=nullptr);
+
+ void remove(SPRequest& request, time_t revocationExp=0);
- Session* find(const Application& app, const char* key) {
- return _find(app, key, nullptr, nullptr, nullptr);
+ Session* find(const char* bucketID, const char* key) {
+ return _find(bucketID, key, nullptr, nullptr, nullptr);
}
- void remove(const Application& app, const char* key, time_t revocationExp=0);
+ void remove(const char* bucketID, const char* key, time_t revocationExp=0);
void test();
- unsigned long getCacheTimeout(const Application& app) const;
+ unsigned long getCacheTimeout(const SPRequest& request) const;
private:
// internal delegates of external methods
Session * _find(
- const Application& app,
+ const char* bucketID,
const char* key,
const char* recovery,
const char* client_addr,
time_t* timeout);
#ifndef SHIBSP_LITE
std::vector<std::string>::size_type _logout(
- const Application& app,
+ const char* bucketID,
const opensaml::saml2md::EntityDescriptor* issuer,
const opensaml::saml2::NameID& nameid,
const std::set<std::string>* indexes,
@@ -126,7 +118,6 @@ namespace shibsp {
// maintain back-mappings of NameID/SessionIndex -> session key
void insert(const char* key, time_t expires, const char* name, const char* index, short attempts=0);
bool stronglyMatches(const XMLCh* idp, const XMLCh* sp, const opensaml::saml2::NameID& n1, const opensaml::saml2::NameID& n2) const;
- LogoutEvent* newLogoutEvent(const Application& app) const;
xmltooling::StorageService* m_storage;
xmltooling::StorageService* m_storage_lite;
@@ -147,24 +138,14 @@ namespace shibsp {
// handle potentially inexact address comparisons
bool compareAddresses(const char* client_addr, const char* session_addr) const;
- HTTPResponse::samesite_t getSameSitePolicy(const Application& app) const;
+ HTTPResponse::samesite_t getSameSitePolicy(const SPRequest& request) const;
+ std::string getCookieName(const SPRequest& request, const char* prefix, time_t* lifetime=nullptr) const;
+
// management of buffered sessions
void dormant(const char* key);
static void* cleanup_fn(void*);
-#ifndef SHIBSP_LITE
- // persistence across nodes
- void persist(
- const Application& app,
- xmltooling::HTTPResponse& httpResponse,
- DDF& session,
- time_t expires,
- xmltooling::HTTPResponse::samesite_t sameSitePolicy
- ) const;
-#endif
- bool recover(const Application& app, const char* key, const char* data);
-
Category& m_log;
bool inproc;
bool shutdown;
diff --git a/shibsp/impl/StoredSession.cpp b/shibsp/impl/StoredSession.cpp
index ca89ae49..ecb8f032 100644
--- a/shibsp/impl/StoredSession.cpp
+++ b/shibsp/impl/StoredSession.cpp
@@ -26,7 +26,6 @@
#include "internal.h"
#include "exceptions.h"
-#include "ServiceProvider.h"
#include "attribute/Attribute.h"
#include "impl/StoredSession.h"
#include "impl/StorageServiceSessionCache.h"
@@ -118,7 +117,7 @@ void StoredSession::unmarshallAttributes() const
}
}
-void StoredSession::validate(const Application& app, const char* client_addr, time_t* timeout)
+void StoredSession::validate(const char* bucketID, const char* client_addr, time_t* timeout)
{
time_t now = time(nullptr);
@@ -156,7 +155,7 @@ void StoredSession::validate(const Application& app, const char* client_addr, ti
in.structure();
in.addmember("key").string(getID());
in.addmember("version").integer(m_obj["version"].integer());
- in.addmember("application_id").string(app.getId());
+ in.addmember("bucket_id").string(bucketID);
if (client_addr) // signals we need to bind an additional address to the session
in.addmember("client_addr").string(client_addr);
if (timeout && *timeout) {
@@ -317,211 +316,3 @@ void StoredSession::validate(const Application& app, const char* client_addr, ti
m_lastAccess = now;
}
-
-#ifndef SHIBSP_LITE
-
-void StoredSession::addAttributes(const vector<Attribute*>& attributes)
-{
- if (!m_cache->m_storage)
- throw ConfigurationException("Session modification requires a StorageService.");
-
- m_cache->m_log.debug("adding attributes to session (%s)", getID());
-
- int ver;
- short attempts = 0;
- do {
- DDF attr;
- DDF attrs = m_obj["attributes"];
- if (!attrs.islist())
- attrs = m_obj.addmember("attributes").list();
- for (vector<Attribute*>::const_iterator a=attributes.begin(); a!=attributes.end(); ++a) {
- attr = (*a)->marshall();
- attrs.add(attr);
- }
-
- // Tentatively increment the version.
- m_obj["version"].integer(m_obj["version"].integer()+1);
-
- ostringstream str;
- str << m_obj;
- string record(str.str());
-
- try {
- ver = m_cache->m_storage->updateText(getID(), "session", record.c_str(), 0, m_obj["version"].integer()-1);
- }
- catch (std::exception&) {
- // Roll back modification to record.
- m_obj["version"].integer(m_obj["version"].integer()-1);
- vector<Attribute*>::size_type count = attributes.size();
- while (count--)
- attrs.last().destroy();
- throw;
- }
-
- if (ver <= 0) {
- // Roll back modification to record.
- m_obj["version"].integer(m_obj["version"].integer()-1);
- vector<Attribute*>::size_type count = attributes.size();
- while (count--)
- attrs.last().destroy();
- }
- if (!ver) {
- // Fatal problem with update.
- throw IOException("Unable to update stored session.");
- }
- else if (ver < 0) {
- // Out of sync.
- if (++attempts > 10) {
- m_cache->m_log.error("failed to update stored session, update attempts exceeded limit");
- throw IOException("Unable to update stored session, exceeded retry limit.");
- }
- m_cache->m_log.warn("storage service indicates the record is out of sync, updating with a fresh copy...");
- ver = m_cache->m_storage->readText(getID(), "session", &record);
- if (!ver) {
- m_cache->m_log.error("readText failed on StorageService for session (%s)", getID());
- throw IOException("Unable to read back stored session.");
- }
-
- // Reset object.
- DDF newobj;
- istringstream in(record);
- in >> newobj;
-
- m_ids.clear();
- for_each(m_attributes.begin(), m_attributes.end(), xmltooling::cleanup<Attribute>());
- m_attributes.clear();
- m_attributeIndex.clear();
- newobj["version"].integer(ver);
- m_obj.destroy();
- m_obj = newobj;
-
- ver = -1;
- }
- } while (ver < 0); // negative indicates a sync issue so we retry
-
- // We own them now, so clean them up.
- for_each(attributes.begin(), attributes.end(), xmltooling::cleanup<Attribute>());
-}
-
-const Assertion* StoredSession::getAssertion(const char* id) const
-{
- if (!m_cache->m_storage)
- throw ConfigurationException("Assertion retrieval requires a StorageService.");
-
- map< string,boost::shared_ptr<Assertion> >::const_iterator i = m_tokens.find(id);
- if (i != m_tokens.end())
- return i->second.get();
-
- string tokenstr;
- if (!m_cache->m_storage->readText(getID(), id, &tokenstr))
- throw FatalProfileException("Assertion not found in cache.");
-
- // Parse and bind the document into an XMLObject.
- istringstream instr(tokenstr);
- DOMDocument* doc = XMLToolingConfig::getConfig().getParser().parse(instr);
- XercesJanitor<DOMDocument> janitor(doc);
- boost::shared_ptr<XMLObject> xmlObject(XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true));
- janitor.release();
-
- boost::shared_ptr<Assertion> token = dynamic_pointer_cast<Assertion,XMLObject>(xmlObject);
- if (!token)
- throw FatalProfileException("Request for cached assertion returned an unknown object type.");
-
- m_tokens[id] = token;
- return token.get();
-}
-
-void StoredSession::addAssertion(Assertion* assertion)
-{
- if (!m_cache->m_storage)
- throw ConfigurationException("Session modification requires a StorageService.");
- else if (!assertion)
- throw FatalProfileException("Unknown object type passed to session for storage.");
-
- auto_ptr_char id(assertion->getID());
- if (!id.get() || !*id.get())
- throw IOException("Assertion did not carry an ID.");
- else if (strlen(id.get()) > m_cache->m_storage->getCapabilities().getKeySize())
- throw IOException("Assertion ID ($1) exceeds allowable storage key size.", params(1, id.get()));
-
- m_cache->m_log.debug("adding assertion (%s) to session (%s)", id.get(), getID());
-
- time_t exp = 0;
- if (!m_cache->m_storage->readText(getID(), "session", nullptr, &exp) || exp == 0)
- throw IOException("Unable to load expiration time for stored session.");
-
- ostringstream tokenstr;
- tokenstr << *assertion;
- if (!m_cache->m_storage->createText(getID(), id.get(), tokenstr.str().c_str(), exp))
- throw IOException("Attempted to insert duplicate assertion ID into session.");
-
- int ver;
- short attempts = 0;
- do {
- DDF token = DDF(nullptr).string(id.get());
- m_obj["assertions"].add(token);
-
- // Tentatively increment the version.
- m_obj["version"].integer(m_obj["version"].integer() + 1);
-
- ostringstream str;
- str << m_obj;
- string record(str.str());
-
- try {
- ver = m_cache->m_storage->updateText(getID(), "session", record.c_str(), 0, m_obj["version"].integer()-1);
- }
- catch (std::exception&) {
- token.destroy();
- m_obj["version"].integer(m_obj["version"].integer() - 1);
- m_cache->m_storage->deleteText(getID(), id.get());
- throw;
- }
-
- if (ver <= 0) {
- token.destroy();
- m_obj["version"].integer(m_obj["version"].integer()-1);
- }
- if (!ver) {
- // Fatal problem with update.
- m_cache->m_log.error("updateText failed on StorageService for session (%s)", getID());
- m_cache->m_storage->deleteText(getID(), id.get());
- throw IOException("Unable to update stored session.");
- }
- else if (ver < 0) {
- // Out of sync.
- if (++attempts > 10) {
- m_cache->m_log.error("failed to update stored session, update attempts exceeded limit");
- throw IOException("Unable to update stored session, exceeded retry limit.");
- }
- m_cache->m_log.warn("storage service indicates the record is out of sync, updating with a fresh copy...");
- ver = m_cache->m_storage->readText(getID(), "session", &record);
- if (!ver) {
- m_cache->m_log.error("readText failed on StorageService for session (%s)", getID());
- m_cache->m_storage->deleteText(getID(), id.get());
- throw IOException("Unable to read back stored session.");
- }
-
- // Reset object.
- DDF newobj;
- istringstream in(record);
- in >> newobj;
-
- m_ids.clear();
- for_each(m_attributes.begin(), m_attributes.end(), xmltooling::cleanup<Attribute>());
- m_attributes.clear();
- m_attributeIndex.clear();
- newobj["version"].integer(ver);
- m_obj.destroy();
- m_obj = newobj;
-
- ver = -1;
- }
- } while (ver < 0); // negative indicates a sync issue so we retry
-
- m_ids.clear();
- delete assertion;
-}
-
-#endif
-
diff --git a/shibsp/impl/StoredSession.h b/shibsp/impl/StoredSession.h
index 44803b39..6637cf2e 100644
--- a/shibsp/impl/StoredSession.h
+++ b/shibsp/impl/StoredSession.h
@@ -27,7 +27,6 @@
#ifndef __shibsp_storedsession_h__
#define __shibsp_storedsession_h__
-#include "Application.h"
#include "SessionCache.h"
#include "remoting/ddf.h"
@@ -51,8 +50,8 @@ namespace shibsp {
const char* getID() const {
return m_obj.name();
}
- const char* getApplicationID() const {
- return m_obj["application_id"].string();
+ const char* getBucketID() const {
+ return m_obj["bucket_id"].string();
}
const char* getClientAddress() const {
return m_obj["client_addr"].first().string();
@@ -89,7 +88,7 @@ namespace shibsp {
}
const std::multimap<std::string, const Attribute*>& getIndexedAttributes() const;
- void validate(const Application& application, const char* client_addr, time_t* timeout);
+ void validate(const char* bucketID, const char* client_addr, time_t* timeout);
time_t getExpiration() const { return m_expires; }
time_t getLastAccess() const { return m_lastAccess; }
diff --git a/tests/impl/XMLAccessControlTests.cpp b/tests/impl/XMLAccessControlTests.cpp
index 72f55e46..a5385cc4 100644
--- a/tests/impl/XMLAccessControlTests.cpp
+++ b/tests/impl/XMLAccessControlTests.cpp
@@ -52,7 +52,7 @@ public:
const char* getID() const {
return nullptr;
}
- const char* getApplicationID() const {
+ const char* getBucketID() const {
return nullptr;
}
time_t getExpiration() const {
diff --git a/tests/impl/XMLRequestMapperTests.cpp b/tests/impl/XMLRequestMapperTests.cpp
index a57c313c..f2e4cd8f 100644
--- a/tests/impl/XMLRequestMapperTests.cpp
+++ b/tests/impl/XMLRequestMapperTests.cpp
@@ -53,7 +53,7 @@ public:
const char* getID() const {
return nullptr;
}
- const char* getApplicationID() const {
+ const char* getBucketID() const {
return nullptr;
}
time_t getExpiration() const {
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list