#include <ctime>
#include <saml/SAMLConfig.h>
#include <saml/binding/URLEncoder.h>
+#include <saml/saml2/metadata/Metadata.h>
+#include <saml/saml2/metadata/EndpointManager.h>
#include <saml/util/CommonDomainCookie.h>
+#include <shibsp/AbstractHandler.h>
#include <shibsp/SPConfig.h>
#ifdef HAVE_UNISTD_H
using namespace shibtarget;
using namespace shibboleth;
using namespace saml;
+using namespace opensaml::saml2md;
using namespace log4cpp;
using namespace std;
using opensaml::CommonDomainCookie;
using opensaml::URLEncoder;
+#if defined (_MSC_VER)
+ #pragma warning( push )
+ #pragma warning( disable : 4250 )
+#endif
+
namespace {
- class SessionInitiator : virtual public IHandler
+ class SessionInitiator : public AbstractHandler
{
public:
- SessionInitiator(const DOMElement* e) {}
+ SessionInitiator(const DOMElement* e) : AbstractHandler(e) {}
~SessionInitiator() {}
- pair<bool,void*> run(ShibTarget* st, bool isHandler=true) const;
- pair<bool,void*> ShibAuthnRequest(
- ShibTarget* st,
- const IHandler* shire,
+ pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
+ pair<bool,long> ShibAuthnRequest(
+ SPRequest& request,
+ const Handler* shire,
const char* dest,
const char* target,
const char* providerId
) const;
};
- class SAML1Consumer : virtual public IHandler, public virtual Remoted
+ class SAML1Consumer : public AbstractHandler, public virtual Remoted
{
public:
SAML1Consumer(const DOMElement* e);
~SAML1Consumer();
- pair<bool,void*> run(ShibTarget* st, bool isHandler=true) const;
+ pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
DDF receive(const DDF& in);
private:
string m_address;
int SAML1Consumer::counter = 0;
- class ShibLogout : virtual public IHandler
+ class ShibLogout : public AbstractHandler
{
public:
- ShibLogout(const DOMElement* e) {}
+ ShibLogout(const DOMElement* e) : AbstractHandler(e) {}
~ShibLogout() {}
- pair<bool,void*> run(ShibTarget* st, bool isHandler=true) const;
+ pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
};
}
+#if defined (_MSC_VER)
+ #pragma warning( pop )
+#endif
-IPlugIn* ShibSessionInitiatorFactory(const DOMElement* e)
+Handler* ShibSessionInitiatorFactory(const DOMElement* const & e)
{
return new SessionInitiator(e);
}
-IPlugIn* SAML1POSTFactory(const DOMElement* e)
+Handler* SAML1POSTFactory(const DOMElement* const & e)
{
return new SAML1Consumer(e);
}
-IPlugIn* SAML1ArtifactFactory(const DOMElement* e)
+Handler* SAML1ArtifactFactory(const DOMElement* const & e)
{
return new SAML1Consumer(e);
}
-IPlugIn* ShibLogoutFactory(const DOMElement* e)
+Handler* ShibLogoutFactory(const DOMElement* const & e)
{
return new ShibLogout(e);
}
-pair<bool,void*> SessionInitiator::run(ShibTarget* st, bool isHandler) const
+pair<bool,long> SessionInitiator::run(SPRequest& request, bool isHandler) const
{
string dupresource;
const char* resource=NULL;
- const IHandler* ACS=NULL;
- const IApplication* app=st->getApplication();
+ const Handler* ACS=NULL;
+ const IApplication& app=dynamic_cast<const IApplication&>(request.getApplication());
if (isHandler) {
/*
* acsIndex optional index of an ACS to use on the way back in
* providerId optional direct invocation of a specific IdP
*/
- const char* option=st->getRequestParameter("acsIndex");
+ const char* option=request.getParameter("acsIndex");
if (option)
- ACS=app->getAssertionConsumerServiceByIndex(atoi(option));
- option=st->getRequestParameter("providerId");
+ ACS=app.getAssertionConsumerServiceByIndex(atoi(option));
+ option=request.getParameter("providerId");
- resource=st->getRequestParameter("target");
+ resource=request.getParameter("target");
if (!resource || !*resource) {
- pair<bool,const char*> home=app->getString("homeURL");
+ pair<bool,const char*> home=app.getString("homeURL");
if (home.first)
resource=home.second;
else
- throw FatalProfileException("Session initiator requires a target parameter or a homeURL application property.");
+ throw opensaml::FatalProfileException("Session initiator requires a target parameter or a homeURL application property.");
}
else if (!option) {
dupresource=resource;
if (option) {
// Here we actually use metadata to invoke the SSO service directly.
// The only currently understood binding is the Shibboleth profile.
- Metadata m(app->getMetadataProviders());
- const IEntityDescriptor* entity=m.lookup(option);
+
+ MetadataProvider* m=app.getMetadataProvider();
+ xmltooling::Locker locker(m);
+ const EntityDescriptor* entity=m->getEntityDescriptor(option);
if (!entity)
- throw MetadataException("Session initiator unable to locate metadata for provider ($1).", params(1,option));
- const IIDPSSODescriptor* role=entity->getIDPSSODescriptor(Constants::SHIB_NS);
+ throw MetadataException("Session initiator unable to locate metadata for provider ($1).", xmltooling::params(1,option));
+ const IDPSSODescriptor* role=entity->getIDPSSODescriptor(shibspconstants::SHIB1_PROTOCOL_ENUM);
if (!role)
throw MetadataException(
- "Session initiator unable to locate a Shibboleth-aware identity provider role for provider ($1).", params(1,option)
+ "Session initiator unable to locate a Shibboleth-aware identity provider role for provider ($1).",
+ xmltooling::params(1,option)
);
- const IEndpointManager* SSO=role->getSingleSignOnServiceManager();
- const IEndpoint* ep=SSO->getEndpointByBinding(Constants::SHIB_AUTHNREQUEST_PROFILE_URI);
+ const EndpointType* ep=EndpointManager<SingleSignOnService>(role->getSingleSignOnServices()).getByBinding(
+ shibspconstants::SHIB1_AUTHNREQUEST_PROFILE_URI
+ );
if (!ep)
throw MetadataException(
- "Session initiator unable to locate compatible SSO service for provider ($1).", params(1,option)
+ "Session initiator unable to locate compatible SSO service for provider ($1).", xmltooling::params(1,option)
);
auto_ptr_char dest(ep->getLocation());
return ShibAuthnRequest(
- st,ACS ? ACS : app->getDefaultAssertionConsumerService(),dest.get(),resource,app->getString("providerId").second
+ request,ACS ? ACS : app.getDefaultAssertionConsumerService(),dest.get(),resource,app.getString("providerId").second
);
}
}
else {
// We're running as a "virtual handler" from within the filter.
// The target resource is the current one and everything else is defaulted.
- resource=st->getRequestURL();
+ resource=request.getRequestURL();
}
- if (!ACS) ACS=app->getDefaultAssertionConsumerService();
+ if (!ACS) ACS=app.getDefaultAssertionConsumerService();
// For now, we only support external session initiation via a wayfURL
- pair<bool,const char*> wayfURL=getProperties()->getString("wayfURL");
+ pair<bool,const char*> wayfURL=getString("wayfURL");
if (!wayfURL.first)
throw ConfigurationException("Session initiator is missing wayfURL property.");
- pair<bool,const XMLCh*> wayfBinding=getProperties()->getXMLString("wayfBinding");
- if (!wayfBinding.first || !XMLString::compareString(wayfBinding.second,Constants::SHIB_AUTHNREQUEST_PROFILE_URI))
+ pair<bool,const XMLCh*> wayfBinding=getXMLString("wayfBinding");
+ if (!wayfBinding.first || !XMLString::compareString(wayfBinding.second,shibspconstants::SHIB1_AUTHNREQUEST_PROFILE_URI))
// Standard Shib 1.x
- return ShibAuthnRequest(st,ACS,wayfURL.second,resource,app->getString("providerId").second);
- else if (!XMLString::compareString(wayfBinding.second,Constants::SHIB_LEGACY_AUTHNREQUEST_PROFILE_URI))
- // Shib pre-1.2
- return ShibAuthnRequest(st,ACS,wayfURL.second,resource,NULL);
- else if (!strcmp(getProperties()->getString("wayfBinding").second,"urn:mace:shibboleth:1.0:profiles:EAuth")) {
+ return ShibAuthnRequest(request,ACS,wayfURL.second,resource,app.getString("providerId").second);
+ else if (!strcmp(getString("wayfBinding").second,"urn:mace:shibboleth:1.0:profiles:EAuth")) {
// TODO: Finalize E-Auth profile URI
- pair<bool,bool> localRelayState=st->getConfig()->getPropertySet("InProcess")->getBool("localRelayState");
+ pair<bool,bool> localRelayState=request.getServiceProvider().getPropertySet("InProcess")->getBool("localRelayState");
if (!localRelayState.first || !localRelayState.second)
throw ConfigurationException("E-Authn requests cannot include relay state, so localRelayState must be enabled.");
// Here we store the state in a cookie.
- pair<string,const char*> shib_cookie=st->getCookieNameProps("_shibstate_");
- st->setCookie(shib_cookie.first,opensaml::SAMLConfig::getConfig().getURLEncoder()->encode(resource) + shib_cookie.second);
- return make_pair(true, st->sendRedirect(wayfURL.second));
+ pair<string,const char*> shib_cookie=app.getCookieNameProps("_shibstate_");
+ string stateval = opensaml::SAMLConfig::getConfig().getURLEncoder()->encode(resource) + shib_cookie.second;
+ request.setCookie(shib_cookie.first.c_str(),stateval.c_str());
+ return make_pair(true, request.sendRedirect(wayfURL.second));
}
- throw UnsupportedProfileException("Unsupported WAYF binding ($1).", params(1,getProperties()->getString("wayfBinding").second));
+ throw opensaml::BindingException("Unsupported WAYF binding ($1).", xmltooling::params(1,getString("wayfBinding").second));
}
// Handles Shib 1.x AuthnRequest profile.
-pair<bool,void*> SessionInitiator::ShibAuthnRequest(
- ShibTarget* st,
- const IHandler* shire,
+pair<bool,long> SessionInitiator::ShibAuthnRequest(
+ SPRequest& request,
+ const Handler* shire,
const char* dest,
const char* target,
const char* providerId
{
// Compute the ACS URL. We add the ACS location to the base handlerURL.
// Legacy configs will not have the Location property specified, so no suffix will be added.
- string ACSloc=st->getHandlerURL(target);
- pair<bool,const char*> loc=shire ? shire->getProperties()->getString("Location") : pair<bool,const char*>(false,NULL);
+ string ACSloc=request.getHandlerURL(target);
+ pair<bool,const char*> loc=shire ? shire->getString("Location") : pair<bool,const char*>(false,NULL);
if (loc.first) ACSloc+=loc.second;
URLEncoder* urlenc = opensaml::SAMLConfig::getConfig().getURLEncoder();
string req=string(dest) + "?shire=" + urlenc->encode(ACSloc.c_str()) + "&time=" + timebuf;
// How should the resource value be preserved?
- pair<bool,bool> localRelayState=st->getConfig()->getPropertySet("InProcess")->getBool("localRelayState");
+ pair<bool,bool> localRelayState=request.getServiceProvider().getPropertySet("InProcess")->getBool("localRelayState");
if (!localRelayState.first || !localRelayState.second) {
// The old way, just send it along.
req+="&target=" + urlenc->encode(target);
else {
// Here we store the state in a cookie and send a fixed
// value to the IdP so we can recognize it on the way back.
- pair<string,const char*> shib_cookie=st->getCookieNameProps("_shibstate_");
- st->setCookie(shib_cookie.first,urlenc->encode(target) + shib_cookie.second);
+ pair<string,const char*> shib_cookie=request.getApplication().getCookieNameProps("_shibstate_");
+ string stateval = urlenc->encode(target) + shib_cookie.second;
+ request.setCookie(shib_cookie.first.c_str(),stateval.c_str());
req+="&target=cookie";
}
if (providerId)
req+="&providerId=" + urlenc->encode(providerId);
- return make_pair(true, st->sendRedirect(req));
+ return make_pair(true, request.sendRedirect(req.c_str()));
}
-SAML1Consumer::SAML1Consumer(const DOMElement* e)
+SAML1Consumer::SAML1Consumer(const DOMElement* e) : AbstractHandler(e)
{
m_address += ('A' + (counter++));
m_address += "::SAML1Consumer::run";
// Register for remoted messages.
- if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
- ListenerService* listener=ShibTargetConfig::getConfig().getINI()->getListener();
- if (listener)
- listener->regListener(m_address.c_str(),this);
- else
- throw ListenerException("Plugin requires a Listener service");
- }
+ if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess))
+ SPConfig::getConfig().getServiceProvider()->getListenerService()->regListener(m_address.c_str(),this);
}
SAML1Consumer::~SAML1Consumer()
{
- ListenerService* listener=ShibTargetConfig::getConfig().getINI()->getListener();
+ ListenerService* listener=SPConfig::getConfig().getServiceProvider()->getListenerService(false);
if (listener && SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess))
listener->unregListener(m_address.c_str(),this);
counter--;
DDF SAML1Consumer::receive(const DDF& in)
{
#ifdef _DEBUG
- saml::NDC ndc("receive");
+ xmltooling::NDC ndc("receive");
#endif
Category& log=Category::getInstance(SHIBT_LOGCAT".SAML1Consumer");
// Find application.
const char* aid=in["application_id"].string();
- const IApplication* app=aid ? ShibTargetConfig::getConfig().getINI()->getApplication(aid) : NULL;
+ const IApplication* app=aid ? dynamic_cast<const IApplication*>(SPConfig::getConfig().getServiceProvider()->getApplication(aid)) : NULL;
if (!app) {
// Something's horribly wrong.
log.error("couldn't find application (%s) for new session", aid ? aid : "(missing)");
log.debug("recipient: %s", recipient);
log.debug("application: %s", app->getId());
- // Access the application config. It's already locked behind us.
- STConfig& stc=static_cast<STConfig&>(ShibTargetConfig::getConfig());
- IConfig* conf=stc.getINI();
+ // Access the application config.
+ ServiceProvider* conf=SPConfig::getConfig().getServiceProvider();
+ xmltooling::Locker confLocker(conf);
auto_ptr_XMLCh wrecipient(recipient);
}
// Supports either version...
- pair<bool,unsigned int> version=getProperties()->getUnsignedInt("MinorVersion","urn:oasis:names:tc:SAML:1.0:protocol");
+ pair<bool,unsigned int> version=getUnsignedInt("MinorVersion","urn:oasis:names:tc:SAML:1.0:protocol");
if (!version.first)
version.second=1;
- const IRoleDescriptor* role=NULL;
- Metadata m(app->getMetadataProviders());
+ const EntityDescriptor* provider=NULL;
+ const RoleDescriptor* role=NULL;
+ MetadataProvider* m=app->getMetadataProvider();
+ xmltooling::Locker locker(m);
SAMLBrowserProfile::BrowserProfileResponse bpr;
try {
bpr=app->getBrowserProfile()->receive(
samlResponse,
wrecipient.get(),
- checkReplay.second ? conf->getReplayCache() : NULL,
+ NULL,
version.second
);
}
SAMLart,
wrecipient.get(),
artifactMapper.get(),
- checkReplay.second ? conf->getReplayCache() : NULL,
+ NULL,
version.second
);
}
// Try and map to metadata (again).
- // Once the metadata layer is in the SAML core, the repetition should be fixed.
- const IEntityDescriptor* provider=m.lookup(bpr.assertion->getIssuer());
+ // Once the metadata layer is in the SAML core, the repetition will be fixed.
+ provider=m->getEntityDescriptor(bpr.assertion->getIssuer());
if (!provider && bpr.authnStatement->getSubject()->getNameIdentifier() &&
bpr.authnStatement->getSubject()->getNameIdentifier()->getNameQualifier())
- provider=m.lookup(bpr.authnStatement->getSubject()->getNameIdentifier()->getNameQualifier());
+ provider=m->getEntityDescriptor(bpr.authnStatement->getSubject()->getNameIdentifier()->getNameQualifier());
if (provider) {
- const IIDPSSODescriptor* IDP=provider->getIDPSSODescriptor(
- version.second==1 ? saml::XML::SAML11_PROTOCOL_ENUM : saml::XML::SAML10_PROTOCOL_ENUM
+ role=provider->getIDPSSODescriptor(
+ version.second==1 ? samlconstants::SAML11_PROTOCOL_ENUM : samlconstants::SAML10_PROTOCOL_ENUM
);
- role=IDP;
}
// This isn't likely, since the profile must have found a role.
// Verify the client address matches authentication
auto_ptr_char this_ip(wip);
if (strcmp(client_address, this_ip.get())) {
- FatalProfileException ex(
- SESSION_E_ADDRESSMISMATCH,
+ opensaml::FatalProfileException ex(
"Your client's current address ($1) 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.",
- params(1,client_address)
+ xmltooling::params(1,client_address)
);
annotateException(&ex,role); // throws it
}
}
}
}
- catch (SAMLException&) {
+ catch (exception&) {
bpr.clear();
throw;
}
throw;
#else
SAMLException e("An unexpected error occurred while creating your session.");
- annotateException(&e,role);
+ shibboleth::annotateException(&e,role);
#endif
}
// It passes all our tests -- create a new session.
log.info("creating new session");
- DDF out;
- try {
- // Insert into cache.
- auto_ptr_char authContext(bpr.authnStatement->getAuthMethod());
- string key=conf->getSessionCache()->insert(
- app,
- role->getEntityDescriptor(),
- client_address,
- bpr.authnStatement->getSubject(),
- authContext.get(),
- bpr.response
- );
- // objects owned by cache now
- log.debug("new session id: %s", key.c_str());
- auto_ptr_char oname(role->getEntityDescriptor()->getId());
- out=DDF(NULL).structure();
- out.addmember("key").string(key.c_str());
- out.addmember("provider_id").string(oname.get());
- }
- catch (...) {
-#ifdef _DEBUG
- throw;
-#else
- SAMLException e("An unexpected error occurred while creating your session.");
- annotateException(&e,role);
-#endif
- }
+ // Insert into cache.
+ auto_ptr_char authContext(bpr.authnStatement->getAuthMethod());
+ string key=dynamic_cast<ISessionCache*>(conf->getSessionCache())->insert(
+ app,
+ role,
+ client_address,
+ bpr.authnStatement->getSubject(),
+ authContext.get(),
+ bpr.response
+ );
+ // objects owned by cache now
+ log.debug("new session id: %s", key.c_str());
+ auto_ptr_char oname(provider->getEntityID());
+ DDF out=DDF(NULL).structure();
+ out.addmember("key").string(key.c_str());
+ out.addmember("provider_id").string(oname.get());
return out;
}
-pair<bool,void*> SAML1Consumer::run(ShibTarget* st, bool isHandler) const
+pair<bool,long> SAML1Consumer::run(SPRequest& request, bool isHandler) const
{
DDF in,out;
DDFJanitor jin(in),jout(out);
- pair<bool,const XMLCh*> binding=getProperties()->getXMLString("Binding");
+ pair<bool,const XMLCh*> binding=getXMLString("Binding");
if (!binding.first || !XMLString::compareString(binding.second,SAMLBrowserProfile::BROWSER_POST)) {
#ifdef HAVE_STRCASECMP
- if (strcasecmp(st->getRequestMethod(), "POST")) {
+ if (strcasecmp(request.getMethod(), "POST")) {
#else
- if (_stricmp(st->getRequestMethod(), "POST")) {
+ if (_stricmp(request.getMethod(), "POST")) {
#endif
- st->log(ShibTarget::LogLevelInfo, "SAML 1.x Browser/POST handler ignoring non-POST request");
- return pair<bool,void*>(false,NULL);
+ request.log(SPRequest::SPInfo, "SAML 1.x Browser/POST handler ignoring non-POST request");
+ return pair<bool,long>(false,NULL);
}
#ifdef HAVE_STRCASECMP
- if (!st->getContentType() || strcasecmp(st->getContentType(),"application/x-www-form-urlencoded")) {
+ if (strcasecmp(request.getContentType().c_str(),"application/x-www-form-urlencoded")) {
#else
- if (!st->getContentType() || _stricmp(st->getContentType(),"application/x-www-form-urlencoded")) {
+ if (_stricmp(request.getContentType().c_str(),"application/x-www-form-urlencoded")) {
#endif
- st->log(ShibTarget::LogLevelInfo, "SAML 1.x Browser/POST handler ignoring submission with unknown content-type.");
- return pair<bool,void*>(false,NULL);
+ request.log(SPRequest::SPInfo, "SAML 1.x Browser/POST handler ignoring submission with unknown content-type.");
+ return pair<bool,long>(false,0);
}
- const char* samlResponse = st->getRequestParameter("SAMLResponse");
+ const char* samlResponse = request.getParameter("SAMLResponse");
if (!samlResponse) {
- st->log(ShibTarget::LogLevelInfo, "SAML 1.x Browser/POST handler ignoring request with no SAMLResponse parameter.");
- return pair<bool,void*>(false,NULL);
+ request.log(SPRequest::SPInfo, "SAML 1.x Browser/POST handler ignoring request with no SAMLResponse parameter.");
+ return pair<bool,long>(false,0);
}
in=DDF(m_address.c_str()).structure();
}
else if (!XMLString::compareString(binding.second,SAMLBrowserProfile::BROWSER_ARTIFACT)) {
#ifdef HAVE_STRCASECMP
- if (strcasecmp(st->getRequestMethod(), "GET")) {
+ if (strcasecmp(request.getMethod(), "GET")) {
#else
- if (_stricmp(st->getRequestMethod(), "GET")) {
+ if (_stricmp(request.getMethod(), "GET")) {
#endif
- st->log(ShibTarget::LogLevelInfo, "SAML 1.x Browser/Artifact handler ignoring non-GET request");
- return pair<bool,void*>(false,NULL);
+ request.log(SPRequest::SPInfo, "SAML 1.x Browser/Artifact handler ignoring non-GET request");
+ return pair<bool,long>(false,0);
}
- const char* SAMLart=st->getRequestParameter("SAMLart");
- if (!SAMLart) {
- st->log(ShibTarget::LogLevelInfo, "SAML 1.x Browser/Artifact handler ignoring request with no SAMLart parameter.");
- return pair<bool,void*>(false,NULL);
+ vector<const char*> arts;
+ if (request.getParameters("SAMLart",arts)==0) {
+ request.log(SPRequest::SPInfo, "SAML 1.x Browser/Artifact handler ignoring request with no SAMLart parameter.");
+ return pair<bool,long>(false,0);
}
in=DDF(m_address.c_str()).structure();
DDF artlist=in.addmember("SAMLart").list();
- while (SAMLart) {
- artlist.add(DDF(NULL).string(SAMLart));
- SAMLart=st->getRequestParameter("SAMLart",artlist.integer());
- }
+ for (vector<const char*>::const_iterator a=arts.begin(); a!=arts.end(); ++a)
+ artlist.add(DDF(NULL).string(*a));
}
// Compute the endpoint location.
- string hURL=st->getHandlerURL(st->getRequestURL());
- pair<bool,const char*> loc=getProperties()->getString("Location");
+ string hURL=request.getHandlerURL(request.getRequestURL());
+ pair<bool,const char*> loc=getString("Location");
string recipient=loc.first ? hURL + loc.second : hURL;
in.addmember("recipient").string(recipient.c_str());
// Add remaining parameters.
- in.addmember("application_id").string(st->getApplication()->getId());
- in.addmember("client_address").string(st->getRemoteAddr());
+ in.addmember("application_id").string(request.getApplication().getId());
+ in.addmember("client_address").string(request.getRemoteAddr().c_str());
- out=st->getConfig()->getListener()->send(in);
+ out=request.getServiceProvider().getListenerService()->send(in);
if (!out["key"].isstring())
- throw FatalProfileException("Remote processing of SAML 1.x Browser profile did not return a usable session key.");
+ throw opensaml::FatalProfileException("Remote processing of SAML 1.x Browser profile did not return a usable session key.");
string key=out["key"].string();
- st->log(ShibTarget::LogLevelDebug, string("profile processing succeeded, new session created (") + key + ")");
+ request.log(SPRequest::SPDebug, string("profile processing succeeded, new session created (") + key + ")");
- const char* target=st->getRequestParameter("TARGET");
+ const char* target=request.getParameter("TARGET");
if (target && !strcmp(target,"default")) {
- pair<bool,const char*> homeURL=st->getApplication()->getString("homeURL");
+ pair<bool,const char*> homeURL=request.getApplication().getString("homeURL");
target=homeURL.first ? homeURL.second : "/";
}
else if (!target || !strcmp(target,"cookie")) {
// Pull the target value from the "relay state" cookie.
- pair<string,const char*> relay_cookie = st->getCookieNameProps("_shibstate_");
- const char* relay_state = st->getCookie(relay_cookie.first);
+ pair<string,const char*> relay_cookie = request.getApplication().getCookieNameProps("_shibstate_");
+ const char* relay_state = request.getCookie(relay_cookie.first.c_str());
if (!relay_state || !*relay_state) {
// No apparent relay state value to use, so fall back on the default.
- pair<bool,const char*> homeURL=st->getApplication()->getString("homeURL");
+ pair<bool,const char*> homeURL=request.getApplication().getString("homeURL");
target=homeURL.first ? homeURL.second : "/";
}
else {
free(rscopy);
target=hURL.c_str();
}
- st->setCookie(relay_cookie.first,relay_cookie.second);
+ request.setCookie(relay_cookie.first.c_str(),relay_cookie.second);
}
// We've got a good session, set the session cookie.
- pair<string,const char*> shib_cookie=st->getCookieNameProps("_shibsession_");
- st->setCookie(shib_cookie.first, key + shib_cookie.second);
+ pair<string,const char*> shib_cookie=request.getApplication().getCookieNameProps("_shibsession_");
+ key += shib_cookie.second;
+ request.setCookie(shib_cookie.first.c_str(), key.c_str());
const char* providerId=out["provider_id"].string();
if (providerId) {
- const PropertySet* sessionProps=st->getApplication()->getPropertySet("Sessions");
+ const PropertySet* sessionProps=request.getApplication().getPropertySet("Sessions");
pair<bool,bool> idpHistory=sessionProps->getBool("idpHistory");
if (!idpHistory.first || idpHistory.second) {
// Set an IdP history cookie locally (essentially just a CDC).
- CommonDomainCookie cdc(st->getCookie(CommonDomainCookie::CDCName));
+ CommonDomainCookie cdc(request.getCookie(CommonDomainCookie::CDCName));
// Either leave in memory or set an expiration.
pair<bool,unsigned int> days=sessionProps->getUnsignedInt("idpHistoryDays");
- if (!days.first || days.second==0)
- st->setCookie(CommonDomainCookie::CDCName,string(cdc.set(providerId)) + shib_cookie.second);
- else {
- time_t now=time(NULL) + (days.second * 24 * 60 * 60);
+ if (!days.first || days.second==0) {
+ key = string(cdc.set(providerId)) + shib_cookie.second;
+ request.setCookie(CommonDomainCookie::CDCName, key.c_str());
+ }
+ else {
+ time_t now=time(NULL) + (days.second * 24 * 60 * 60);
#ifdef HAVE_GMTIME_R
- struct tm res;
- struct tm* ptime=gmtime_r(&now,&res);
+ struct tm res;
+ struct tm* ptime=gmtime_r(&now,&res);
#else
- struct tm* ptime=gmtime(&now);
+ struct tm* ptime=gmtime(&now);
#endif
- char timebuf[64];
- strftime(timebuf,64,"%a, %d %b %Y %H:%M:%S GMT",ptime);
- st->setCookie(
- CommonDomainCookie::CDCName,
- string(cdc.set(providerId)) + shib_cookie.second + "; expires=" + timebuf
- );
+ char timebuf[64];
+ strftime(timebuf,64,"%a, %d %b %Y %H:%M:%S GMT",ptime);
+ key = string(cdc.set(providerId)) + shib_cookie.second + "; expires=" + timebuf;
+ request.setCookie(CommonDomainCookie::CDCName, key.c_str());
}
}
}
// Now redirect to the target.
- return make_pair(true, st->sendRedirect(target));
+ return make_pair(true, request.sendRedirect(target));
}
-pair<bool,void*> ShibLogout::run(ShibTarget* st, bool isHandler) const
+pair<bool,long> ShibLogout::run(SPRequest& request, bool isHandler) const
{
// Recover the session key.
- pair<string,const char*> shib_cookie = st->getCookieNameProps("_shibsession_");
- const char* session_id = st->getCookie(shib_cookie.first);
+ pair<string,const char*> shib_cookie = request.getApplication().getCookieNameProps("_shibsession_");
+ const char* session_id = request.getCookie(shib_cookie.first.c_str());
// Logout is best effort.
if (session_id && *session_id) {
try {
- st->getConfig()->getSessionCache()->remove(session_id,st->getApplication(),st->getRemoteAddr());
+ // TODO: port to new cache API
+ //request.getServiceProvider().getSessionCache()->remove(session_id,request.getApplication(),request.getRemoteAddr().c_str());
}
- catch (SAMLException& e) {
- st->log(ShibTarget::LogLevelError, string("logout processing failed with exception: ") + e.what());
+ catch (exception& e) {
+ request.log(SPRequest::SPError, string("logout processing failed with exception: ") + e.what());
}
#ifndef _DEBUG
catch (...) {
- st->log(ShibTarget::LogLevelError, "logout processing failed with unknown exception");
+ request.log(SPRequest::SPError, "logout processing failed with unknown exception");
}
#endif
// We send the cookie property alone, which acts as an empty value.
- st->setCookie(shib_cookie.first,shib_cookie.second);
+ request.setCookie(shib_cookie.first.c_str(),shib_cookie.second);
}
- const char* ret=st->getRequestParameter("return");
+ const char* ret=request.getParameter("return");
if (!ret)
- ret=getProperties()->getString("ResponseLocation").second;
+ ret=getString("ResponseLocation").second;
if (!ret)
- ret=st->getApplication()->getString("homeURL").second;
+ ret=request.getApplication().getString("homeURL").second;
if (!ret)
ret="/";
- return make_pair(true, st->sendRedirect(ret));
+ return make_pair(true, request.sendRedirect(ret));
}