m_dc = (shib_dir_config*)ap_get_module_config(req->per_dir_config, &mod_shib);
m_rc = (shib_request_config*)ap_get_module_config(req->request_config, &mod_shib);
m_req = req;
-
- init(
- m_sc->szScheme ? m_sc->szScheme : ap_http_method(req),
- ap_get_server_name(req),
- (int)ap_get_server_port(req),
- req->unparsed_uri
- );
}
virtual ~ShibTargetApache() {}
~htAccessControl() {}
Lockable* lock() {return this;}
void unlock() {}
- bool authorized(SPRequest& request, Session* session) const;
+ bool authorized(const SPRequest& request, const Session* session) const;
};
AccessControl* htAccessFactory(const DOMElement* const & e)
return grps;
}
-bool htAccessControl::authorized(SPRequest& request, Session* session) const
+bool htAccessControl::authorized(const SPRequest& request, const Session* session) const
{
// Make sure the object is our type.
- ShibTargetApache* sta=dynamic_cast<ShibTargetApache*>(&request);
+ const ShibTargetApache* sta=dynamic_cast<const ShibTargetApache*>(&request);
if (!sta)
throw ConfigurationException("Request wrapper object was not of correct type.");
}
}
else {
- saml::Iterator<shibboleth::IAAP*> provs=dynamic_cast<const IApplication&>(request.getSPApplication()).getAAPProviders();
+ saml::Iterator<shibboleth::IAAP*> provs=dynamic_cast<const IApplication&>(request.getApplication()).getAAPProviders();
shibboleth::AAP wrapper(provs,w);
if (wrapper.fail()) {
request.log(SPRequest::SPWarn, string("htAccessControl plugin didn't recognize require rule: ") + w);
exit(1);
}
- IConfig* conf=g_Config->getINI();
+ ServiceProvider* conf=SPConfig::getConfig().getServiceProvider();
xmltooling::Locker locker(conf);
const PropertySet* props=conf->getPropertySet("Local");
if (props) {
}
// Access the implementation-specifics for site mappings.
- IConfig* conf=g_Config->getINI();
+ ServiceProvider* conf=SPConfig::getConfig().getServiceProvider();
xmltooling::Locker locker(conf);
const PropertySet* props=conf->getPropertySet("Local");
if (props) {
m_hostname = var;
if (site.m_name!=m_hostname && site.m_aliases.find(m_hostname)==site.m_aliases.end())
m_hostname=site.m_name;
-
- init(m_scheme.c_str(), m_hostname.c_str(), m_port, m_uri.c_str());
}
~ShibTargetIsapiF() { }
m_pfc->WriteClient(m_pfc, (LPVOID)redmsg, &resplen, 0);
return SF_STATUS_REQ_FINISHED;
}
- // XXX: We might not ever hit the 'decline' status in this filter.
- //long returnDecline(void) { }
- long returnOK(void) {
+ long returnDecline() {
+ return SF_STATUS_REQ_NEXT_NOTIFICATION;
+ }
+ long returnOK() {
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
m_uri += '?';
m_uri += lpECB->lpszQueryString;
}
-
- init(
- m_scheme.c_str(),
- m_hostname.c_str(),
- m_port,
- m_uri.c_str()
- );
}
~ShibTargetIsapiE() { }
g_Config = NULL;
}
-extern "C" NSAPI_PUBLIC int nsapi_shib_init(pblock* pb, Session* sn, Request* rq)
+extern "C" NSAPI_PUBLIC int nsapi_shib_init(pblock* pb, ::Session* sn, Request* rq)
{
// Save off a default hostname for this virtual server.
char* name=pblock_findval("server-name",pb);
daemon_atrestart(nsapi_shib_exit,NULL);
- IConfig* conf=g_Config->getINI();
+ ServiceProvider* conf=SPConfig::getConfig().getServiceProvider();
Locker locker(conf);
const PropertySet* props=conf->getPropertySet("Local");
if (props) {
vector<XSECCryptoX509*> m_certs;
public:
- ShibTargetNSAPI(pblock* pb, Session* sn, Request* rq) : m_gotBody(false) {
+ ShibTargetNSAPI(pblock* pb, ::Session* sn, Request* rq) : m_gotBody(false) {
m_pb = pb;
m_sn = sn;
m_rq = rq;
#endif
// In other cases, we're going to rely on the initialization process...
host=g_ServerName.c_str();
-
- init(
- security_active ? "https" : "http",
- host,
- server_portnum,
- url.c_str()
- );
}
~ShibTargetNSAPI() {}
}
pblock* m_pb;
- Session* m_sn;
+ ::Session* m_sn;
Request* m_rq;
};
/********************************************************************************/
-int WriteClientError(Session* sn, Request* rq, char* func, char* msg)
+int WriteClientError(::Session* sn, Request* rq, char* func, char* msg)
{
log_error(LOG_FAILURE,func,sn,rq,msg);
protocol_status(sn,rq,PROTOCOL_SERVER_ERROR,msg);
#undef FUNC
#define FUNC "shibboleth"
-extern "C" NSAPI_PUBLIC int nsapi_shib(pblock* pb, Session* sn, Request* rq)
+extern "C" NSAPI_PUBLIC int nsapi_shib(pblock* pb, ::Session* sn, Request* rq)
{
ostringstream threadid;
threadid << "[" << getpid() << "] nsapi_shib" << '\0';
#undef FUNC
#define FUNC "shib_handler"
-extern "C" NSAPI_PUBLIC int shib_handler(pblock* pb, Session* sn, Request* rq)
+extern "C" NSAPI_PUBLIC int shib_handler(pblock* pb, ::Session* sn, Request* rq)
{
ostringstream threadid;
threadid << "[" << getpid() << "] shib_handler" << '\0';
if (!shar_checkonly) {
// Run the listener.
- if (!conf.getINI()->getListenerService()->run(&shibd_shutdown)) {
+ if (!SPConfig::getConfig().getServiceProvider()->getListenerService()->run(&shibd_shutdown)) {
fprintf(stderr, "listener failed to enter listen loop\n");
return -3;
}
}
// Run the listener
- if (!conf.getINI()->getListenerService()->run(&shibd_shutdown)) {
+ if (!SPConfig::getConfig().getServiceProvider()->getListenerService()->run(&shibd_shutdown)) {
fprintf(stderr, "listener failed to enter listen loop\n");
return -3;
}
DDFJanitor injan(in);
in.integer(atol(argv[1]));
- DDF out=conf.getINI()->getListenerService()->send(in);
+ DDF out=SPConfig::getConfig().getServiceProvider()->getListenerService()->send(in);
DDFJanitor outjan(out);
cerr << argv[1] << " -> " << out.integer() << "\n";
*/
#include "internal.h"
+#include <shibsp/SPConfig.h>
#include <saml/binding/SAMLArtifact.h>
using namespace shibsp;
pair<bool,const char*> signingCred=credUse ? credUse->getString("Signing") : pair<bool,const char*>(false,NULL);
if (signRequest.first && signRequest.second && signingCred.first) {
if (request->getMinorVersion()==1) {
- CredentialResolver* cr=ShibTargetConfig::getConfig().getINI()->getCredentialResolver(signingCred.second);
+ CredentialResolver* cr=SPConfig::getConfig().getServiceProvider()->getCredentialResolver(signingCred.second);
if (cr) {
xmltooling::Locker locker(cr);
request->sign(cr->getKey(),cr->getCertificates(),signatureAlg.second,digestAlg.second);
#include "internal.h"
+#include <shibsp/SPConfig.h>
#include <xmltooling/security/OpenSSLTrustEngine.h>
#include <xmltooling/signature/OpenSSLCredentialResolver.h>
const PropertySet* credUse=ctx->getCredentialUse();
pair<bool,const char*> TLS=credUse ? credUse->getString("TLS") : pair<bool,const char*>(false,NULL);
if (TLS.first) {
- OpenSSLCredentialResolver* cr=dynamic_cast<OpenSSLCredentialResolver*>(ShibTargetConfig::getConfig().getINI()->getCredentialResolver(TLS.second));
+ OpenSSLCredentialResolver* cr=dynamic_cast<OpenSSLCredentialResolver*>(SPConfig::getConfig().getServiceProvider()->getCredentialResolver(TLS.second));
if (cr) {
xmltooling::Locker locker(cr);
cr->attach(reinterpret_cast<SSL_CTX*>(ssl_ctx));
os << *tokens;
in.addmember("tokens.unfiltered").string(os.str().c_str());
- out=ShibTargetConfig::getConfig().getINI()->getListenerService()->send(in);
+ out=SPConfig::getConfig().getServiceProvider()->getListenerService()->send(in);
if (out["key"].isstring())
return out["key"].string();
throw opensaml::RetryableProfileException("A remoted cache insertion operation did not return a usable session key.");
in.addmember("client_address").string(client_addr);
try {
- out=ShibTargetConfig::getConfig().getINI()->getListenerService()->send(in);
+ out=SPConfig::getConfig().getServiceProvider()->getListenerService()->send(in);
if (!out.isstruct()) {
out.destroy();
return NULL;
in.addmember("application_id").string(application->getId());
in.addmember("client_address").string(client_addr);
- ShibTargetConfig::getConfig().getINI()->getListenerService()->send(in);
+ SPConfig::getConfig().getServiceProvider()->getListenerService()->send(in);
}
/*
// Sign it?
if (signRequest.first && signRequest.second && signingCred.first) {
if (req->getMinorVersion()==1) {
- CredentialResolver* cr=ShibTargetConfig::getConfig().getINI()->getCredentialResolver(signingCred.second);
+ CredentialResolver* cr=SPConfig::getConfig().getServiceProvider()->getCredentialResolver(signingCred.second);
if (cr) {
xmltooling::Locker locker(cr);
req->sign(cr->getKey(),cr->getCertificates(),signatureAlg.second,digestAlg.second);
SAMLConfig::getConfig().conn_timeout = m_AAConnectTimeout;
// Register for remoted messages.
- ListenerService* listener=ShibTargetConfig::getConfig().getINI()->getListenerService(false);
+ ListenerService* listener=SPConfig::getConfig().getServiceProvider()->getListenerService(false);
if (listener && SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
restoreInsert=listener->regListener("SessionCache::insert",this);
restoreFind=listener->regListener("SessionCache::find",this);
cleanup_thread->join(NULL);
// Unregister remoted messages.
- ListenerService* listener=ShibTargetConfig::getConfig().getINI()->getListenerService(false);
+ ListenerService* listener=SPConfig::getConfig().getServiceProvider()->getListenerService(false);
if (listener && SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
listener->unregListener("SessionCache::insert",this,restoreInsert);
listener->unregListener("SessionCache::find",this,restoreFind);
#endif
// Find application.
- xmltooling::Locker confLocker(ShibTargetConfig::getConfig().getINI());
+ xmltooling::Locker confLocker(SPConfig::getConfig().getServiceProvider());
const char* aid=in["application_id"].string();
- const IApplication* app=aid ? dynamic_cast<const IApplication*>(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.
m_log->error("couldn't find application (%s) for session", aid ? aid : "(missing)");
m_log->error("cache store returned failure during search");
return NULL;
}
- const IApplication* eapp=dynamic_cast<const IApplication*>(ShibTargetConfig::getConfig().getINI()->getApplication(appid.c_str()));
+ const IApplication* eapp=dynamic_cast<const IApplication*>(SPConfig::getConfig().getServiceProvider()->getApplication(appid.c_str()));
if (!eapp) {
// Something's horribly wrong.
m_log->error("couldn't find application (%s) for session", appid.c_str());
auto_ptr_XMLCh src(config);
dummy->setAttributeNS(NULL,path,src.get());
- m_ini=dynamic_cast<IConfig*>(SPConfig::getConfig().ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER,dummy));
- m_ini->init();
+ auto_ptr<ServiceProvider> sp(SPConfig::getConfig().ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER,dummy));
+ sp->init();
- pair<bool,unsigned int> skew=m_ini->getUnsignedInt("clockSkew");
+ pair<bool,unsigned int> skew=sp->getUnsignedInt("clockSkew");
SAMLConfig::getConfig().clock_skew_secs=skew.first ? skew.second : 180;
if (skew.first)
XMLToolingConfig::getConfig().clock_skew_secs=skew.second;
+ SPConfig::getConfig().setServiceProvider(sp.release());
m_tranLog=new FixedContextCategory(SHIBTRAN_LOGCAT);
m_tranLog->info("opened transaction log");
delete m_tranLogLock;
m_tranLogLock = NULL;
//delete m_tranLog; // This is crashing for some reason, but we're shutting down anyway.
- delete m_ini;
- m_ini = NULL;
+ SPConfig::getConfig().term();
ShibConfig::getConfig().term();
SAMLConfig::getConfig().term();
- SPConfig::getConfig().term();
log.info("library shutdown complete");
}
string dupresource;
const char* resource=NULL;
const IHandler* ACS=NULL;
- const IApplication* app=st->getApplication();
+ const IApplication& app=dynamic_cast<const IApplication&>(st->getApplication());
if (isHandler) {
/*
*/
const char* option=st->getParameter("acsIndex");
if (option)
- ACS=app->getAssertionConsumerServiceByIndex(atoi(option));
+ ACS=app.getAssertionConsumerServiceByIndex(atoi(option));
option=st->getParameter("providerId");
resource=st->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
// Here we actually use metadata to invoke the SSO service directly.
// The only currently understood binding is the Shibboleth profile.
- MetadataProvider* m=app->getMetadataProvider();
+ MetadataProvider* m=app.getMetadataProvider();
xmltooling::Locker locker(m);
const EntityDescriptor* entity=m->getEntityDescriptor(option);
if (!entity)
);
auto_ptr_char dest(ep->getLocation());
return ShibAuthnRequest(
- st,ACS ? ACS : app->getDefaultAssertionConsumerService(),dest.get(),resource,app->getString("providerId").second
+ st,ACS ? ACS : app.getDefaultAssertionConsumerService(),dest.get(),resource,app.getString("providerId").second
);
}
}
resource=st->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 XMLCh*> wayfBinding=getProperties()->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);
+ return ShibAuthnRequest(st,ACS,wayfURL.second,resource,app.getString("providerId").second);
else if (!strcmp(getProperties()->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=st->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=app->getCookieNameProps("_shibstate_");
+ pair<string,const char*> shib_cookie=app.getCookieNameProps("_shibstate_");
string stateval = opensaml::SAMLConfig::getConfig().getURLEncoder()->encode(resource) + shib_cookie.second;
st->setCookie(shib_cookie.first.c_str(),stateval.c_str());
return make_pair(true, st->sendRedirect(wayfURL.second));
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=st->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->getApplication()->getCookieNameProps("_shibstate_");
+ pair<string,const char*> shib_cookie=st->getApplication().getCookieNameProps("_shibstate_");
string stateval = urlenc->encode(target) + shib_cookie.second;
st->setCookie(shib_cookie.first.c_str(),stateval.c_str());
req+="&target=cookie";
// Register for remoted messages.
if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess))
- ShibTargetConfig::getConfig().getINI()->getListenerService()->regListener(m_address.c_str(),this);
+ SPConfig::getConfig().getServiceProvider()->getListenerService()->regListener(m_address.c_str(),this);
}
SAML1Consumer::~SAML1Consumer()
{
- ListenerService* listener=ShibTargetConfig::getConfig().getINI()->getListenerService(false);
+ ListenerService* listener=SPConfig::getConfig().getServiceProvider()->getListenerService(false);
if (listener && SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess))
listener->unregListener(m_address.c_str(),this);
counter--;
// Find application.
const char* aid=in["application_id"].string();
- const IApplication* app=aid ? dynamic_cast<const IApplication*>(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("application: %s", app->getId());
// Access the application config.
- STConfig& stc=static_cast<STConfig&>(ShibTargetConfig::getConfig());
- IConfig* conf=stc.getINI();
+ IConfig* conf=dynamic_cast<IConfig*>(SPConfig::getConfig().getServiceProvider());
xmltooling::Locker confLocker(conf);
auto_ptr_XMLCh wrecipient(recipient);
in.addmember("recipient").string(recipient.c_str());
// Add remaining parameters.
- in.addmember("application_id").string(st->getApplication()->getId());
+ in.addmember("application_id").string(st->getApplication().getId());
in.addmember("client_address").string(st->getRemoteAddr().c_str());
- out=st->getConfig()->getListenerService()->send(in);
+ out=st->getServiceProvider().getListenerService()->send(in);
if (!out["key"].isstring())
throw opensaml::FatalProfileException("Remote processing of SAML 1.x Browser profile did not return a usable session key.");
string key=out["key"].string();
const char* target=st->getParameter("TARGET");
if (target && !strcmp(target,"default")) {
- pair<bool,const char*> homeURL=st->getApplication()->getString("homeURL");
+ pair<bool,const char*> homeURL=st->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->getApplication()->getCookieNameProps("_shibstate_");
+ pair<string,const char*> relay_cookie = st->getApplication().getCookieNameProps("_shibstate_");
const char* relay_state = st->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=st->getApplication().getString("homeURL");
target=homeURL.first ? homeURL.second : "/";
}
else {
}
// We've got a good session, set the session cookie.
- pair<string,const char*> shib_cookie=st->getApplication()->getCookieNameProps("_shibsession_");
+ pair<string,const char*> shib_cookie=st->getApplication().getCookieNameProps("_shibsession_");
key += shib_cookie.second;
st->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=st->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).
pair<bool,long> ShibLogout::run(ShibTarget* st, bool isHandler) const
{
// Recover the session key.
- pair<string,const char*> shib_cookie = st->getApplication()->getCookieNameProps("_shibsession_");
+ pair<string,const char*> shib_cookie = st->getApplication().getCookieNameProps("_shibsession_");
const char* session_id = st->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().c_str());
+ // TODO: port to new cache API
+ //st->getServiceProvider().getSessionCache()->remove(session_id,st->getApplication(),st->getRemoteAddr().c_str());
}
catch (exception& e) {
st->log(SPRequest::SPError, string("logout processing failed with exception: ") + e.what());
if (!ret)
ret=getProperties()->getString("ResponseLocation").second;
if (!ret)
- ret=st->getApplication()->getString("homeURL").second;
+ ret=st->getApplication().getString("homeURL").second;
if (!ret)
ret="/";
return make_pair(true, st->sendRedirect(ret));
}
};
- class ShibTargetPriv
- {
- public:
- ShibTargetPriv();
- ~ShibTargetPriv();
-
- // Helper functions
- void get_application(ShibTarget* st, const string& protocol, const string& hostname, int port, const string& uri);
- long sendError(ShibTarget* st, const char* page, ExtTemplateParameters& tp, const XMLToolingException* ex=NULL);
- void clearHeaders(ShibTarget* st);
-
- private:
- friend class ShibTarget;
- RequestMapper::Settings m_settings;
- const IApplication *m_app;
-
- ISessionCacheEntry* m_cacheEntry;
-
- ShibTargetConfig* m_Config;
-
- IConfig* m_conf;
- RequestMapper* m_mapper;
- };
+ long _sendError(SPRequest* st, const char* page, ExtTemplateParameters& tp, const XMLToolingException* ex=NULL);
static const XMLCh SessionInitiator[] = UNICODE_LITERAL_16(S,e,s,s,i,o,n,I,n,i,t,i,a,t,o,r);
static const XMLCh DiagnosticService[] = UNICODE_LITERAL_17(D,i,a,g,n,o,s,t,i,c,S,e,r,v,i,c,e);
* Shib Target implementation
*/
-ShibTarget::ShibTarget() : m_priv(new ShibTargetPriv()) {}
-
-ShibTarget::ShibTarget(const IApplication *app) : m_priv(new ShibTargetPriv())
-{
- m_priv->m_app = app;
-}
-
-ShibTarget::~ShibTarget(void)
-{
- delete m_priv;
-}
-
-void ShibTarget::init(
- const char* scheme,
- const char* hostname,
- int port,
- const char* uri
- )
-{
- if (m_priv->m_app)
- throw XMLToolingException("Request initialization occurred twice!");
-
- m_priv->m_Config = &ShibTargetConfig::getConfig();
- m_priv->get_application(this, scheme, hostname, port, uri);
- AbstractSPRequest::m_app = m_priv->m_app;
-}
// These functions implement the server-agnostic shibboleth engine
#endif
const char* procState = "Request Processing Error";
- const char* targetURL = m_url.c_str();
+ string targetURL = getRequestURL();
ExtTemplateParameters tp;
try {
- if (!m_priv->m_app)
- throw ConfigurationException("System uninitialized, application did not supply request information.");
+ RequestMapper::Settings settings = getRequestSettings();
+ const IApplication& app = dynamic_cast<const IApplication&>(getApplication());
// If not SSL, check to see if we should block or redirect it.
if (!strcmp("http",getScheme())) {
- pair<bool,const char*> redirectToSSL = m_priv->m_settings.first->getString("redirectToSSL");
+ pair<bool,const char*> redirectToSSL = settings.first->getString("redirectToSSL");
if (redirectToSSL.first) {
if (!strcasecmp("GET",getMethod()) || !strcasecmp("HEAD",getMethod())) {
// Compute the new target URL
return make_pair(true, sendRedirect(redirectURL.c_str()));
}
else {
- tp.m_map["requestURL"] = m_url.substr(0,m_url.find('?'));
- return make_pair(true,m_priv->sendError(this,"ssl", tp));
+ tp.m_map["requestURL"] = targetURL.substr(0,targetURL.find('?'));
+ return make_pair(true,_sendError(this, "ssl", tp));
}
}
}
- string hURL = getHandlerURL(targetURL);
- const char* handlerURL=hURL.c_str();
+ const char* handlerURL=getHandlerURL(targetURL.c_str());
if (!handlerURL)
throw ConfigurationException("Cannot determine handler from resource URL, check configuration.");
// If the request URL contains the handler base URL for this application, either dispatch
// directly (mainly Apache 2.0) or just pass back control.
- if (strstr(targetURL,handlerURL)) {
+ if (strstr(targetURL.c_str(),handlerURL)) {
if (handler)
return doHandler();
else
}
// Three settings dictate how to proceed.
- pair<bool,const char*> authType = m_priv->m_settings.first->getString("authType");
- pair<bool,bool> requireSession = m_priv->m_settings.first->getBool("requireSession");
- pair<bool,const char*> requireSessionWith = m_priv->m_settings.first->getString("requireSessionWith");
+ pair<bool,const char*> authType = settings.first->getString("authType");
+ pair<bool,bool> requireSession = settings.first->getBool("requireSession");
+ pair<bool,const char*> requireSessionWith = settings.first->getString("requireSessionWith");
// If no session is required AND the AuthType (an Apache-derived concept) isn't shibboleth,
// then we ignore this request and consider it unprotected. Apache might lie to us if
return make_pair(true,returnDecline());
// Fix for secadv 20050901
- m_priv->clearHeaders(this);
+ clearHeaders();
- pair<string,const char*> shib_cookie = m_priv->m_app->getCookieNameProps("_shibsession_");
+ pair<string,const char*> shib_cookie = app.getCookieNameProps("_shibsession_");
const char* session_id = getCookie(shib_cookie.first.c_str());
if (!session_id || !*session_id) {
// No session. Maybe that's acceptable?
procState = "Session Initiator Error";
const IHandler* initiator=NULL;
if (requireSessionWith.first) {
- initiator=m_priv->m_app->getSessionInitiatorById(requireSessionWith.second);
+ initiator=app.getSessionInitiatorById(requireSessionWith.second);
if (!initiator)
throw ConfigurationException(
"No session initiator found with id ($1), check requireSessionWith command.",
);
}
else {
- initiator=m_priv->m_app->getDefaultSessionInitiator();
+ initiator=app.getDefaultSessionInitiator();
if (!initiator)
throw ConfigurationException("No default session initiator found, check configuration.");
}
}
procState = "Session Processing Error";
+ const Session* session=NULL;
try {
- m_priv->m_cacheEntry=m_priv->m_conf->getSessionCache()->find(
- session_id,
- m_priv->m_app,
- getRemoteAddr().c_str()
- );
+ session=getSession();
// Make a localized exception throw if the session isn't valid.
- if (!m_priv->m_cacheEntry)
+ if (!session)
throw RetryableProfileException("Session no longer valid.");
}
catch (exception& e) {
- log(SPError, string("session processing failed: ") + e.what());
+ log(SPWarn, string("session processing failed: ") + e.what());
// If no session is required, bail now.
if ((!requireSession.first || !requireSession.second) && !requireSessionWith.first)
procState = "Session Initiator Error";
const IHandler* initiator=NULL;
if (requireSessionWith.first) {
- initiator=m_priv->m_app->getSessionInitiatorById(requireSessionWith.second);
+ initiator=app.getSessionInitiatorById(requireSessionWith.second);
if (!initiator)
throw ConfigurationException(
"No session initiator found with id ($1), check requireSessionWith command.",
);
}
else {
- initiator=m_priv->m_app->getDefaultSessionInitiator();
+ initiator=app.getDefaultSessionInitiator();
if (!initiator)
throw ConfigurationException("No default session initiator found, check configuration.");
}
catch (XMLToolingException& e) {
tp.m_map["errorType"] = procState;
tp.m_map["errorText"] = e.what();
- if (targetURL)
- tp.m_map["requestURL"] = m_url.substr(0,m_url.find('?'));
- return make_pair(true,m_priv->sendError(this, "session", tp, &e));
+ tp.m_map["requestURL"] = targetURL.substr(0,targetURL.find('?'));
+ return make_pair(true,_sendError(this, "session", tp, &e));
}
#ifndef _DEBUG
catch (...) {
tp.m_map["errorType"] = procState;
tp.m_map["errorText"] = "Caught an unknown exception.";
- if (targetURL)
- tp.m_map["requestURL"] = m_url.substr(0,m_url.find('?'));
- return make_pair(true,m_priv->sendError(this, "session", tp));
+ tp.m_map["requestURL"] = targetURL.substr(0,targetURL.find('?'));
+ return make_pair(true,_sendError(this, "session", tp));
}
#endif
}
xmltooling::NDC ndc("doHandler");
#endif
+ const IApplication* app=NULL;
ExtTemplateParameters tp;
const char* procState = "Shibboleth Handler Error";
- const char* targetURL = m_url.c_str();
+ string targetURL = getRequestURL();
try {
- if (!m_priv->m_app)
- throw ConfigurationException("System uninitialized, application did not supply request information.");
+ RequestMapper::Settings settings = getRequestSettings();
+ app = dynamic_cast<const IApplication*>(&getApplication());
- string hURL = getHandlerURL(targetURL);
- const char* handlerURL=hURL.c_str();
+ const char* handlerURL=getHandlerURL(targetURL.c_str());
if (!handlerURL)
throw ConfigurationException("Cannot determine handler from resource URL, check configuration.");
// Make sure we only process handler requests.
- if (!strstr(targetURL,handlerURL))
+ if (!strstr(targetURL.c_str(),handlerURL))
return make_pair(true, returnDecline());
- const PropertySet* sessionProps=m_priv->m_app->getPropertySet("Sessions");
+ const PropertySet* sessionProps=app->getPropertySet("Sessions");
if (!sessionProps)
throw ConfigurationException("Unable to map request to application session settings, check configuration.");
// We dispatch based on our path info. We know the request URL begins with or equals the handler URL,
// so the path info is the next character (or null).
- const IHandler* handler=m_priv->m_app->getHandler(targetURL + strlen(handlerURL));
+ const IHandler* handler=app->getHandler(targetURL.c_str() + strlen(handlerURL));
if (!handler)
throw opensaml::BindingException("Shibboleth handler invoked at an unconfigured location.");
catch (MetadataException& e) {
tp.m_map["errorText"] = e.what();
// See if a metadata error page is installed.
- const PropertySet* props=m_priv->m_app->getPropertySet("Errors");
+ const PropertySet* props=app->getPropertySet("Errors");
if (props) {
pair<bool,const char*> p=props->getString("metadata");
if (p.first) {
tp.m_map["errorType"] = procState;
- if (targetURL)
- tp.m_map["requestURL"] = targetURL;
- return make_pair(true,m_priv->sendError(this, "metadata", tp));
+ tp.m_map["requestURL"] = targetURL.substr(0,targetURL.find('?'));
+ return make_pair(true,_sendError(this, "metadata", tp));
}
}
throw;
catch (XMLToolingException& e) {
tp.m_map["errorType"] = procState;
tp.m_map["errorText"] = e.what();
- if (targetURL)
- tp.m_map["requestURL"] = m_url.substr(0,m_url.find('?'));
- return make_pair(true,m_priv->sendError(this, "session", tp, &e));
+ tp.m_map["requestURL"] = targetURL.substr(0,targetURL.find('?'));
+ return make_pair(true,_sendError(this, "session", tp, &e));
}
#ifndef _DEBUG
catch (...) {
tp.m_map["errorType"] = procState;
tp.m_map["errorText"] = "Caught an unknown exception.";
- if (targetURL)
- tp.m_map["requestURL"] = m_url.substr(0,m_url.find('?'));
- return make_pair(true,m_priv->sendError(this, "session", tp));
+ tp.m_map["requestURL"] = targetURL.substr(0,targetURL.find('?'));
+ return make_pair(true,_sendError(this, "session", tp));
}
#endif
}
xmltooling::NDC ndc("doCheckAuthZ");
#endif
+ const IApplication* app=NULL;
ExtTemplateParameters tp;
const char* procState = "Authorization Processing Error";
- const char* targetURL = m_url.c_str();
+ string targetURL = getRequestURL();
try {
- if (!m_priv->m_app)
- throw ConfigurationException("System uninitialized, application did not supply request information.");
+ RequestMapper::Settings settings = getRequestSettings();
+ app = dynamic_cast<const IApplication*>(&getApplication());
// Three settings dictate how to proceed.
- pair<bool,const char*> authType = m_priv->m_settings.first->getString("authType");
- pair<bool,bool> requireSession = m_priv->m_settings.first->getBool("requireSession");
- pair<bool,const char*> requireSessionWith = m_priv->m_settings.first->getString("requireSessionWith");
+ pair<bool,const char*> authType = settings.first->getString("authType");
+ pair<bool,bool> requireSession = settings.first->getBool("requireSession");
+ pair<bool,const char*> requireSessionWith = settings.first->getString("requireSessionWith");
// If no session is required AND the AuthType (an Apache-derived concept) isn't shibboleth,
// then we ignore this request and consider it unprotected. Apache might lie to us if
return make_pair(true,returnDecline());
// Do we have an access control plugin?
- if (m_priv->m_settings.second) {
-
- if (!m_priv->m_cacheEntry) {
- // No data yet, so we may need to try and get the session.
- pair<string,const char*> shib_cookie=m_priv->m_app->getCookieNameProps("_shibsession_");
- const char *session_id = getCookie(shib_cookie.first.c_str());
- try {
- if (session_id && *session_id) {
- m_priv->m_cacheEntry=m_priv->m_conf->getSessionCache()->find(
- session_id,
- m_priv->m_app,
- getRemoteAddr().c_str()
- );
- }
- }
- catch (exception&) {
- log(SPError, "doCheckAuthZ: unable to obtain session information to pass to access control provider");
- }
- }
+ if (settings.second) {
+ const Session* session =NULL;
+ pair<string,const char*> shib_cookie=app->getCookieNameProps("_shibsession_");
+ const char *session_id = getCookie(shib_cookie.first.c_str());
+ try {
+ if (session_id && *session_id) {
+ session = getSession();
+ }
+ }
+ catch (exception&) {
+ log(SPWarn, "doCheckAuthZ: unable to obtain session information to pass to access control provider");
+ }
- xmltooling::Locker acllock(m_priv->m_settings.second);
- /* TODO: port
- if (m_priv->m_settings.second->authorized(this,m_priv->m_cacheEntry)) {
+ xmltooling::Locker acllock(settings.second);
+ if (settings.second->authorized(*this,session)) {
// Let the caller decide how to proceed.
- log(LogLevelDebug, "doCheckAuthZ: access control provider granted access");
+ log(SPDebug, "doCheckAuthZ: access control provider granted access");
return make_pair(false,0);
}
else {
- log(LogLevelWarn, "doCheckAuthZ: access control provider denied access");
- if (targetURL)
- tp.m_map["requestURL"] = targetURL;
- return make_pair(true,m_priv->sendError(this, "access", tp));
+ log(SPWarn, "doCheckAuthZ: access control provider denied access");
+ tp.m_map["requestURL"] = targetURL;
+ return make_pair(true,_sendError(this, "access", tp));
}
- */
return make_pair(false,0);
}
else
catch (exception& e) {
tp.m_map["errorType"] = procState;
tp.m_map["errorText"] = e.what();
- if (targetURL)
- tp.m_map["requestURL"] = m_url.substr(0,m_url.find('?'));
- return make_pair(true,m_priv->sendError(this, "access", tp));
+ tp.m_map["requestURL"] = targetURL.substr(0,targetURL.find('?'));
+ return make_pair(true,_sendError(this, "access", tp));
}
#ifndef _DEBUG
catch (...) {
tp.m_map["errorType"] = procState;
tp.m_map["errorText"] = "Caught an unknown exception.";
- if (targetURL)
- tp.m_map["requestURL"] = m_url.substr(0,m_url.find('?'));
- return make_pair(true,m_priv->sendError(this, "access", tp));
+ tp.m_map["requestURL"] = targetURL.substr(0,targetURL.find('?'));
+ return make_pair(true,_sendError(this, "access", tp));
}
#endif
}
xmltooling::NDC ndc("doExportAssertions");
#endif
+ const IApplication* app=NULL;
ExtTemplateParameters tp;
const char* procState = "Attribute Processing Error";
- const char* targetURL = m_url.c_str();
+ string targetURL = getRequestURL();
try {
- if (!m_priv->m_app)
- throw ConfigurationException("System uninitialized, application did not supply request information.");
+ RequestMapper::Settings settings = getRequestSettings();
+ app = dynamic_cast<const IApplication*>(&getApplication());
- if (!m_priv->m_cacheEntry) {
- // No data yet, so we need to get the session. This can only happen
- // if the call to doCheckAuthn doesn't happen in the same object lifetime.
- pair<string,const char*> shib_cookie=m_priv->m_app->getCookieNameProps("_shibsession_");
- const char *session_id = getCookie(shib_cookie.first.c_str());
- try {
- if (session_id && *session_id) {
- m_priv->m_cacheEntry=m_priv->m_conf->getSessionCache()->find(
- session_id,
- m_priv->m_app,
- getRemoteAddr().c_str()
- );
- }
- }
- catch (exception&) {
- log(SPError, "unable to obtain session information to export into request headers");
- // If we have to have a session, then this is a fatal error.
- if (requireSession)
- throw;
- }
+ const Session* session=NULL;
+ pair<string,const char*> shib_cookie=app->getCookieNameProps("_shibsession_");
+ const char *session_id = getCookie(shib_cookie.first.c_str());
+ try {
+ if (session_id && *session_id) {
+ session = getSession();
+ }
+ }
+ catch (exception&) {
+ log(SPWarn, "unable to obtain session information to export into request headers");
+ // If we have to have a session, then this is a fatal error.
+ if (requireSession)
+ throw;
}
// Still no data?
- if (!m_priv->m_cacheEntry) {
+ if (!session) {
if (requireSession)
throw RetryableProfileException("Unable to obtain session information for request.");
else
return make_pair(false,0); // just bail silently
}
+ /*
+ TODO: port to new cache API
// Extract data from session.
- pair<const char*,const SAMLSubject*> sub=m_priv->m_cacheEntry->getSubject(false,true);
- pair<const char*,const SAMLResponse*> unfiltered=m_priv->m_cacheEntry->getTokens(true,false);
- pair<const char*,const SAMLResponse*> filtered=m_priv->m_cacheEntry->getTokens(false,true);
+ pair<const char*,const SAMLSubject*> sub=m_cacheEntry->getSubject(false,true);
+ pair<const char*,const SAMLResponse*> unfiltered=m_cacheEntry->getTokens(true,false);
+ pair<const char*,const SAMLResponse*> filtered=m_cacheEntry->getTokens(false,true);
// Maybe export the tokens.
- pair<bool,bool> exp=m_priv->m_settings.first->getBool("exportAssertion");
+ pair<bool,bool> exp=m_settings.first->getBool("exportAssertion");
if (exp.first && exp.second && unfiltered.first && *unfiltered.first) {
unsigned int outlen;
XMLByte* serialized =
}
// Export the SAML AuthnMethod and the origin site name, and possibly the NameIdentifier.
- setHeader("Shib-Origin-Site", m_priv->m_cacheEntry->getProviderId());
- setHeader("Shib-Identity-Provider", m_priv->m_cacheEntry->getProviderId());
- setHeader("Shib-Authentication-Method", m_priv->m_cacheEntry->getAuthnContext());
+ setHeader("Shib-Origin-Site", m_cacheEntry->getProviderId());
+ setHeader("Shib-Identity-Provider", m_cacheEntry->getProviderId());
+ setHeader("Shib-Authentication-Method", m_cacheEntry->getAuthnContext());
// Get the AAP providers, which contain the attribute policy info.
- Iterator<IAAP*> provs=m_priv->m_app->getAAPProviders();
+ Iterator<IAAP*> provs=m_app->getAAPProviders();
// Export NameID?
while (provs.hasNext()) {
}
}
- setHeader("Shib-Application-ID", m_priv->m_app->getId());
+ setHeader("Shib-Application-ID", m_app->getId());
// Export the attributes.
Iterator<SAMLAssertion*> a_iter(filtered.second ? filtered.second->getAssertions() : EMPTY(SAMLAssertion*));
}
}
}
+ */
return make_pair(false,0);
}
catch (XMLToolingException& e) {
tp.m_map["errorType"] = procState;
tp.m_map["errorText"] = e.what();
- if (targetURL)
- tp.m_map["requestURL"] = m_url.substr(0,m_url.find('?'));
- return make_pair(true,m_priv->sendError(this, "rm", tp, &e));
+ tp.m_map["requestURL"] = targetURL.substr(0,targetURL.find('?'));
+ return make_pair(true,_sendError(this, "rm", tp, &e));
}
#ifndef _DEBUG
catch (...) {
tp.m_map["errorType"] = procState;
tp.m_map["errorText"] = "Caught an unknown exception.";
- if (targetURL)
- tp.m_map["requestURL"] = m_url.substr(0,m_url.find('?'));
- return make_pair(true,m_priv->sendError(this, "rm", tp));
+ tp.m_map["requestURL"] = targetURL.substr(0,targetURL.find('?'));
+ return make_pair(true,_sendError(this, "rm", tp));
}
#endif
}
-const IApplication* ShibTarget::getApplication() const
-{
- return m_priv->m_app;
-}
-
-const IConfig* ShibTarget::getConfig() const
-{
- return m_priv->m_conf;
-}
-
-long ShibTarget::returnDecline(void)
-{
- return NULL;
-}
-
-long ShibTarget::returnOK(void)
-{
- return NULL;
-}
-
/*************************************************************************
* Shib Target Private implementation
*/
-ShibTargetPriv::ShibTargetPriv()
- : m_app(NULL), m_mapper(NULL), m_conf(NULL), m_Config(NULL), m_cacheEntry(NULL) {}
-
-ShibTargetPriv::~ShibTargetPriv()
-{
- if (m_cacheEntry) {
- m_cacheEntry->unlock();
- m_cacheEntry = NULL;
- }
-
- if (m_mapper) {
- m_mapper->unlock();
- m_mapper = NULL;
- }
-
- if (m_conf) {
- m_conf->unlock();
- m_conf = NULL;
- }
-
- m_app = NULL;
- m_Config = NULL;
-}
-
-void ShibTargetPriv::get_application(ShibTarget* st, const string& protocol, const string& hostname, int port, const string& uri)
-{
- if (m_app)
- return;
-
- // XXX: Do we need to keep conf and mapper locked while we hold m_app?
- // TODO: No, should be able to hold the conf but release the mapper.
-
- // We lock the configuration system for the duration.
- m_conf=m_Config->getINI();
- m_conf->lock();
-
- // Map request to application and content settings.
- m_mapper=m_conf->getRequestMapper();
- m_mapper->lock();
-
- // Obtain the application settings from the parsed URL
- m_settings = m_mapper->getSettings(*st);
-
- // Now find the application from the URL settings
- pair<bool,const char*> application_id=m_settings.first->getString("applicationId");
- m_app=dynamic_cast<const IApplication*>(m_conf->getApplication(application_id.second));
- if (!m_app) {
- m_mapper->unlock();
- m_mapper = NULL;
- m_conf->unlock();
- m_conf = NULL;
- throw ConfigurationException("Unable to map request to application settings, check configuration.");
- }
-
- // Compute the full target URL
- st->m_url = protocol + "://" + hostname;
- if ((protocol == "http" && port != 80) || (protocol == "https" && port != 443)) {
- ostringstream portstr;
- portstr << port;
- st->m_url += ":" + portstr.str();
- }
- st->m_url += uri;
-}
-
-long ShibTargetPriv::sendError(
- ShibTarget* st, const char* page, ExtTemplateParameters& tp, const XMLToolingException* ex
+long shibtarget::_sendError(
+ SPRequest* st, const char* page, ExtTemplateParameters& tp, const XMLToolingException* ex
)
{
st->setContentType("text/html");
st->setResponseHeader("Cache-Control","private,no-store,no-cache");
TemplateEngine* engine = XMLToolingConfig::getConfig().getTemplateEngine();
- const PropertySet* props=m_app->getPropertySet("Errors");
+ const PropertySet* props=st->getApplication().getPropertySet("Errors");
if (props) {
pair<bool,const char*> p=props->getString(page);
if (p.first) {
}
}
- string errstr = string("sendError could not process error template (") + page + ") for application (";
- errstr += m_app->getId();
- errstr += ")";
+ string errstr = string("sendError could not process error template (") + page + ")";
st->log(SPRequest::SPError, errstr);
istringstream msg("Internal Server Error. Please contact the site administrator.");
return st->sendError(msg);
}
-void ShibTargetPriv::clearHeaders(ShibTarget* st)
+void ShibTarget::clearHeaders()
{
// Clear invariant stuff.
- st->clearHeader("Shib-Origin-Site");
- st->clearHeader("Shib-Identity-Provider");
- st->clearHeader("Shib-Authentication-Method");
- st->clearHeader("Shib-NameIdentifier-Format");
- st->clearHeader("Shib-Attributes");
- st->clearHeader("Shib-Application-ID");
+ clearHeader("Shib-Origin-Site");
+ clearHeader("Shib-Identity-Provider");
+ clearHeader("Shib-Authentication-Method");
+ clearHeader("Shib-NameIdentifier-Format");
+ clearHeader("Shib-Attributes");
+ clearHeader("Shib-Application-ID");
// Clear out the list of mapped attributes
- Iterator<IAAP*> provs=m_app->getAAPProviders();
+ Iterator<IAAP*> provs=dynamic_cast<const IApplication&>(getApplication()).getAAPProviders();
while (provs.hasNext()) {
IAAP* aap=provs.next();
xmltooling::Locker locker(aap);
while (rules.hasNext()) {
const char* header=rules.next()->getHeader();
if (header)
- st->clearHeader(header);
+ clearHeader(header);
}
}
}
// New headers
#include <shibsp/AbstractSPRequest.h>
#include <shibsp/Application.h>
+#include <shibsp/RequestMapper.h>
#include <shibsp/ServiceProvider.h>
#include <shibsp/remoting/ListenerService.h>
class SHIBTARGET_EXPORTS ShibTargetConfig
{
public:
- ShibTargetConfig() : m_ini(NULL) {}
+ ShibTargetConfig() {}
virtual ~ShibTargetConfig() {}
virtual bool init(const char* schemadir) = 0;
virtual bool load(const char* config) = 0;
virtual void shutdown() = 0;
- virtual IConfig* getINI() const {return m_ini;}
-
static ShibTargetConfig& getConfig();
-
- protected:
- IConfig* m_ini;
};
class ShibTargetPriv;
class SHIBTARGET_EXPORTS ShibTarget : public shibsp::AbstractSPRequest {
public:
- ShibTarget(const IApplication* app);
- virtual ~ShibTarget(void);
-
- // These next two APIs are used to obtain the module-specific "OK"
- // and "Decline" results. OK means "we believe that this request
- // should be accepted". Declined means "we believe that this is
- // not a shibbolized request so we have no comment".
-
- virtual long returnDecline();
- virtual long returnOK();
+ virtual ~ShibTarget() {}
//
// Note: Subclasses need not implement anything below this line
std::pair<bool,long> doCheckAuthZ();
std::pair<bool,long> doExportAssertions(bool requireSession = true);
- // Basic request access in case any plugins need the info
- virtual const IConfig* getConfig() const;
- virtual const IApplication* getApplication() const;
-
protected:
- ShibTarget();
-
- // Internal APIs
-
- // Initialize the request from the parsed URL
- // scheme == http, https, etc
- // hostname == server name
- // port == server port
- // uri == resource path
- // method == GET, POST, etc.
- void init(
- const char* scheme,
- const char* hostname,
- int port,
- const char* uri
- );
+ ShibTarget() {}
private:
- mutable ShibTargetPriv* m_priv;
- friend class ShibTargetPriv;
+ void clearHeaders();
};
}
#include "internal.h"
#include "AbstractSPRequest.h"
#include "Application.h"
+#include "ServiceProvider.h"
+#include "SessionCache.h"
#include "util/CGIParser.h"
#include <log4cpp/Category.hh>
using namespace log4cpp;
using namespace std;
-AbstractSPRequest::AbstractSPRequest(const Application* app)
- : m_app(app), m_log(&Category::getInstance(SHIBSP_LOGCAT)), m_parser(NULL)
+AbstractSPRequest::AbstractSPRequest()
+ : m_sp(NULL), m_mapper(NULL), m_app(NULL), m_session(NULL), m_log(&Category::getInstance(SHIBSP_LOGCAT)), m_parser(NULL)
{
- if (m_app)
- return;
+ m_sp=SPConfig::getConfig().getServiceProvider();
+ m_sp->lock();
}
AbstractSPRequest::~AbstractSPRequest()
{
+ if (m_session)
+ m_session->unlock();
+ if (m_mapper)
+ m_mapper->unlock();
+ if (m_sp)
+ m_sp->unlock();
delete m_parser;
}
+RequestMapper::Settings AbstractSPRequest::getRequestSettings() const
+{
+ if (m_mapper)
+ return m_settings;
+
+ // Map request to application and content settings.
+ m_mapper=m_sp->getRequestMapper();
+ m_mapper->lock();
+ return m_settings = m_mapper->getSettings(*this);
+
+}
+
+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").second);
+ if (!m_app)
+ throw ConfigurationException("Unable to map request to application settings, check configuration.");
+ }
+ return *m_app;
+}
+
+const char* AbstractSPRequest::getRequestURL() const {
+ if (m_url.empty()) {
+ // Compute the full target URL
+ int port = getPort();
+ const char* scheme = getScheme();
+ m_url = string(scheme) + "://" + getHostname();
+ if ((!strcmp(scheme,"http") && port!=80) || (!strcmp(scheme,"https") && port!=443)) {
+ ostringstream portstr;
+ portstr << port;
+ m_url += ":" + portstr.str();
+ }
+ scheme = getRequestURI();
+ if (scheme)
+ m_url += scheme;
+ }
+ return m_url.c_str();
+}
+
const char* AbstractSPRequest::getParameter(const char* name) const
{
if (!m_parser)
class SHIBSP_API AbstractSPRequest : public virtual SPRequest
{
protected:
- /**
- * Constructor
- *
- * @param app pointer to effective Application, if known
- */
- AbstractSPRequest(const Application* app=NULL);
+ AbstractSPRequest();
public:
virtual ~AbstractSPRequest();
- const char* getRequestURL() const {
- return m_url.c_str();
+ const ServiceProvider& getServiceProvider() const {
+ return *m_sp;
}
+
+ RequestMapper::Settings getRequestSettings() const;
+
+ const Application& getApplication() const;
- const Application& getSPApplication() const {
- return *m_app;
+ const Session* getSession() const {
+ return m_session;
}
+ const char* getRequestURL() const;
+
const char* getParameter(const char* name) const;
std::vector<const char*>::size_type getParameters(const char* name, std::vector<const char*>& values) const;
bool isPriorityEnabled(SPLogLevel level) const;
- protected:
- /** Holds effective Application. */
- const Application* m_app;
-
- /** Complete "canonical" request URL. */
- std::string m_url;
-
private:
+ ServiceProvider* m_sp;
+ mutable RequestMapper* m_mapper;
+ mutable RequestMapper::Settings m_settings;
+ mutable const Application* m_app;
+ mutable Session* m_session;
+ mutable std::string m_url;
void* m_log; // declared void* to avoid log4cpp header conflicts in Apache
mutable std::string m_handlerURL;
mutable std::map<std::string,std::string> m_cookieMap;
* @param session active user session, if any
* @return true iff access should be granted
*/
- virtual bool authorized(SPRequest& request, Session* session) const=0;
+ virtual bool authorized(const SPRequest& request, const Session* session) const=0;
};
/**
#ifndef __shibsp_req_h__
#define __shibsp_req_h__
-#include <shibsp/base.h>
+#include <shibsp/RequestMapper.h>
#include <saml/binding/HTTPRequest.h>
#include <saml/binding/HTTPResponse.h>
namespace shibsp {
class SHIBSP_API Application;
+ class SHIBSP_API ServiceProvider;
+ class SHIBSP_API Session;
/**
* Interface to server request being processed
virtual ~SPRequest() {}
/**
+ * Returns the locked ServiceProvider processing the request.
+ *
+ * @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.
+ *
+ * @return copy of settings
+ */
+ virtual RequestMapper::Settings getRequestSettings() const=0;
+
+ /**
* Returns the Application governing the request.
*
* @return reference to Application
*/
- virtual const Application& getSPApplication() const=0;
-
+ virtual const Application& getApplication() const=0;
+
+ /**
+ * Returns a locked Session associated with the request.
+ *
+ * @return pointer to Session, or NULL
+ */
+ virtual const Session* getSession() const=0;
+
/**
* Returns the effective base Handler URL for a resource,
* or the current request URL.
* @return true iff logging level is enabled
*/
virtual bool isPriorityEnabled(SPLogLevel level) const=0;
+
+ /**
+ * Indicates that processing was declined, meaning no action is required during this phase of processing.
+ *
+ * @return a status code to pass back to the server-specific layer
+ */
+ virtual long returnDecline()=0;
+
+ /**
+ * Indicates that processing was completed.
+ *
+ * @return a status code to pass back to the server-specific layer
+ */
+ virtual long returnOK()=0;
};
};
namespace shibsp {
+ class SHIBSP_API Application;
+
class SHIBSP_API Session : public virtual xmltooling::Lockable
{
MAKE_NONCOPYABLE(Session);
public:
/**
* Constructor
+ *
+ * @param e root of DOM to configure cache
*/
SessionCache(const xercesc::DOMElement* e);
virtual ~SessionCache();
+ /** TODO: just a stub for now */
+ virtual Session* find(const char* key, const Application& app, const char* address)=0;
};
};
Lockable* lock() {return this;}\r
void unlock() {}\r
\r
- bool authorized(SPRequest& request, Session* session) const;\r
+ bool authorized(const SPRequest& request, const Session* session) const;\r
\r
private:\r
string m_alias;\r
Lockable* lock() {return this;}\r
void unlock() {}\r
\r
- bool authorized(SPRequest& request, Session* session) const;\r
+ bool authorized(const SPRequest& request, const Session* session) const;\r
\r
private:\r
enum operator_t { OP_NOT, OP_AND, OP_OR } m_op;\r
delete m_rootAuthz;\r
}\r
\r
- bool authorized(SPRequest& request, Session* session) const;\r
+ bool authorized(const SPRequest& request, const Session* session) const;\r
\r
protected:\r
pair<bool,DOMElement*> load();\r
}\r
}\r
\r
-bool Rule::authorized(SPRequest& request, Session* session) const\r
+bool Rule::authorized(const SPRequest& request, const Session* session) const\r
{\r
/*\r
TODO: port...\r
for_each(m_operands.begin(),m_operands.end(),xmltooling::cleanup<AccessControl>());\r
}\r
\r
-bool Operator::authorized(SPRequest& request, Session* session) const\r
+bool Operator::authorized(const SPRequest& request, const Session* session) const\r
{\r
switch (m_op) {\r
case OP_NOT:\r
return make_pair(false,(DOMElement*)NULL);\r
}\r
\r
-bool XMLAccessControl::authorized(SPRequest& request, Session* session) const\r
+bool XMLAccessControl::authorized(const SPRequest& request, const Session* session) const\r
{\r
return m_rootAuthz ? m_rootAuthz->authorized(request,session) : false;\r
}\r
\r
void unlock() {}\r
\r
- bool authorized(SPRequest& request, Session* session) const {\r
+ bool authorized(const SPRequest& request, const Session* session) const {\r
return false;\r
}\r
};\r
auto_ptr_XMLCh recip(r_param);
- IConfig* ini=ShibTargetConfig::getConfig().getINI();
- xmltooling::Locker locker(ini);
+ ServiceProvider* sp=SPConfig::getConfig().getServiceProvider();
+ xmltooling::Locker locker(sp);
- const IApplication* app=dynamic_cast<const IApplication*>(ini->getApplication(a_param));
+ const IApplication* app=dynamic_cast<const IApplication*>(sp->getApplication(a_param));
if (!app) {
throw ConfigurationException("Unable to locate application for new session, deleted?");
}
if (!conf.init(path) || !conf.load(config))
return -10;
- IConfig* ini=ShibTargetConfig::getConfig().getINI();
- xmltooling::Locker locker(ini);
+ ServiceProvider* sp=SPConfig::getConfig().getServiceProvider();
+ xmltooling::Locker locker(sp);
try {
- const IApplication* app=dynamic_cast<const IApplication*>(ini->getApplication(a_param));
+ const IApplication* app=dynamic_cast<const IApplication*>(sp->getApplication(a_param));
if (!app)
throw SAMLException("specified <Application> section not found in configuration");