#include "Application.h"
#include "exceptions.h"
#include "ServiceProvider.h"
-#include "SessionCache.h"
+#include "SessionCacheEx.h"
#include "TransactionLog.h"
#include "attribute/Attribute.h"
#include "remoting/ListenerService.h"
namespace shibsp {
class StoredSession;
- class SSCache : public SessionCache
+ class SSCache : public SessionCacheEx
#ifndef SHIBSP_LITE
,public virtual Remoted
#endif
void receive(DDF& in, ostream& out);
void insert(
- time_t expires,
const Application& application,
const HTTPRequest& httpRequest,
HTTPResponse& httpResponse,
+ time_t expires,
const saml2md::EntityDescriptor* issuer=NULL,
const XMLCh* protocol=NULL,
const saml2::NameID* nameid=NULL,
const vector<Attribute*>* attributes=NULL
);
vector<string>::size_type logout(
+ const Application& application,
const saml2md::EntityDescriptor* issuer,
const saml2::NameID& nameid,
const set<string>* indexes,
time_t expires,
- const Application& application,
vector<string>& sessions
);
bool matches(
+ const Application& application,
const xmltooling::HTTPRequest& request,
const saml2md::EntityDescriptor* issuer,
const saml2::NameID& nameid,
- const set<string>* indexes,
- const Application& application
+ const set<string>* indexes
);
#endif
- Session* find(const char* key, const Application& application, const char* client_addr=NULL, time_t* timeout=NULL);
- void remove(const char* key, const Application& application);
+ Session* find(const Application& application, const char* key, const char* client_addr=NULL, time_t* timeout=NULL);
+ void remove(const Application& application, const char* key);
void test();
- string active(const xmltooling::HTTPRequest& request, const Application& application) const {
+ string active(const Application& application, const xmltooling::HTTPRequest& request) {
pair<string,const char*> shib_cookie = application.getCookieNameProps("_shibsession_");
const char* session_id = request.getCookie(shib_cookie.first.c_str());
return (session_id ? session_id : "");
}
- Session* find(const HTTPRequest& request, const Application& application, const char* client_addr=NULL, time_t* timeout=NULL) {
- string id = active(request, application);
+ Session* find(const Application& application, const HTTPRequest& request, const char* client_addr=NULL, time_t* timeout=NULL) {
+ string id = active(application, request);
if (!id.empty())
- return find(id.c_str(), application, client_addr, timeout);
+ return find(application, id.c_str(), client_addr, timeout);
return NULL;
}
- void remove(const HTTPRequest& request, HTTPResponse* response, const Application& application) {
+ void remove(const Application& application, const HTTPRequest& request, HTTPResponse* response=NULL) {
pair<string,const char*> shib_cookie = application.getCookieNameProps("_shibsession_");
const char* session_id = request.getCookie(shib_cookie.first.c_str());
if (session_id && *session_id) {
if (response)
response->setCookie(shib_cookie.first.c_str(), shib_cookie.second);
- remove(session_id, application);
+ remove(application, session_id);
}
}
}
void SSCache::insert(
- time_t expires,
const Application& application,
const HTTPRequest& httpRequest,
HTTPResponse& httpResponse,
+ time_t expires,
const saml2md::EntityDescriptor* issuer,
const XMLCh* protocol,
const saml2::NameID* nameid,
istringstream pstr(pending);
pstr >> pendobj;
// IdP.SP.index contains logout expiration, if any.
- DDF deadmenwalking = pendobj[issuer ? entity_id.get() : "_shibnull"][application.getString("entityID").second];
+ DDF deadmenwalking = pendobj[issuer ? entity_id.get() : "_shibnull"][application.getRelyingParty(issuer)->getString("entityID").second];
const char* logexpstr = deadmenwalking[session_index ? index.get() : "_shibnull"].string();
if (!logexpstr && session_index) // we tried an exact session match, now try for NULL
logexpstr = deadmenwalking["_shibnull"].string();
}
const char* pid = obj["entity_id"].string();
- m_log.info("new session created: SessionID (%s) IdP (%s) Address (%s)", key.get(), pid ? pid : "none", httpRequest.getRemoteAddr().c_str());
+ const char* prot = obj["protocol"].string();
+ m_log.info("new session created: ID (%s) IdP (%s) Protocol(%s) Address (%s)",
+ key.get(), pid ? pid : "none", prot ? prot : "none", httpRequest.getRemoteAddr().c_str());
// Transaction Logging
TransactionLog* xlog = application.getServiceProvider().getTransactionLog();
httpRequest.getRemoteAddr() <<
") with (NameIdentifier: " <<
(nameid ? name.get() : "none") <<
+ ") using (Protocol: " <<
+ (prot ? prot : "none") <<
")";
if (attributes) {
}
pair<string,const char*> shib_cookie = application.getCookieNameProps("_shibsession_");
- string k(key.get());\r
+ string k(key.get());
k += shib_cookie.second;
httpResponse.setCookie(shib_cookie.first.c_str(), k.c_str());
}
bool SSCache::matches(
+ const Application& application,
const xmltooling::HTTPRequest& request,
const saml2md::EntityDescriptor* issuer,
const saml2::NameID& nameid,
- const set<string>* indexes,
- const Application& application
+ const set<string>* indexes
)
{
auto_ptr_char entityID(issuer ? issuer->getEntityID() : NULL);
try {
- Session* session = find(request, application);
+ Session* session = find(application, request);
if (session) {
Locker locker(session, false);
if (XMLString::equals(session->getEntityID(), entityID.get()) && session->getNameID() &&
- stronglyMatches(issuer->getEntityID(), application.getXMLString("entityID").second, nameid, *session->getNameID())) {
+ stronglyMatches(issuer->getEntityID(), application.getRelyingParty(issuer)->getXMLString("entityID").second, nameid, *session->getNameID())) {
return (!indexes || indexes->empty() || (session->getSessionIndex() ? (indexes->count(session->getSessionIndex())>0) : false));
}
}
}
vector<string>::size_type SSCache::logout(
+ const Application& application,
const saml2md::EntityDescriptor* issuer,
const saml2::NameID& nameid,
const set<string>* indexes,
time_t expires,
- const Application& application,
vector<string>& sessionsKilled
)
{
}
// Structure is keyed by the IdP and SP, with a member per session index containing the expiration.
- DDF root = obj.addmember(issuer ? entityID.get() : "_shibnull").addmember(application.getString("entityID").second);
+ DDF root = obj.addmember(issuer ? entityID.get() : "_shibnull").addmember(application.getRelyingParty(issuer)->getString("entityID").second);
if (indexes) {
for (set<string>::const_iterator x = indexes->begin(); x!=indexes->end(); ++x)
root.addmember(x->c_str()).string(timebuf);
ver = m_storage->updateText("Logout", name.get(), lout.str().c_str(), max(expires, oldexp), ver);
if (ver <= 0) {
// Out of sync, or went missing, so retry.
- return logout(issuer, nameid, indexes, expires, application, sessionsKilled);
+ return logout(application, issuer, nameid, indexes, expires, sessionsKilled);
}
}
else if (!m_storage->createText("Logout", name.get(), lout.str().c_str(), expires)) {
// Hit a dup, so just retry, hopefully hitting the other branch.
- return logout(issuer, nameid, indexes, expires, application, sessionsKilled);
+ return logout(application, issuer, nameid, indexes, expires, sessionsKilled);
}
obj.destroy();
// Fetch the session for comparison.
Session* session = NULL;
try {
- session = find(key.string(), application);
+ session = find(application, key.string());
}
catch (exception& ex) {
m_log.error("error locating session (%s): %s", key.string(), ex.what());
// Same issuer?
if (XMLString::equals(session->getEntityID(), entityID.get())) {
// Same NameID?
- if (stronglyMatches(issuer->getEntityID(), application.getXMLString("entityID").second, nameid, *session->getNameID())) {
+ if (stronglyMatches(issuer->getEntityID(), application.getRelyingParty(issuer)->getXMLString("entityID").second, nameid, *session->getNameID())) {
sessionsKilled.push_back(key.string());
key.destroy();
}
#endif
-Session* SSCache::find(const char* key, const Application& application, const char* client_addr, time_t* timeout)
+Session* SSCache::find(const Application& application, const char* key, const char* client_addr, time_t* timeout)
{
#ifdef _DEBUG
xmltooling::NDC ndc("find");
if (timeout && *timeout > 0 && now - lastAccess >= *timeout) {
m_log.info("session timed out (ID: %s)", key);
- remove(key, application);
- RetryableProfileException ex("Your session has expired, and you must re-authenticate.");
+ remove(application, key);
const char* eid = obj["entity_id"].string();
if (!eid) {
obj.destroy();
- throw ex;
+ throw RetryableProfileException("Your session has expired, and you must re-authenticate.");
}
string eid2(eid);
obj.destroy();
- MetadataProvider* m=application.getMetadataProvider();
- Locker locker(m);
- annotateException(&ex,m->getEntityDescriptor(MetadataProvider::Criteria(eid2.c_str(),NULL,NULL,false)).first); // throws it
+ throw RetryableProfileException("Your session has expired, and you must re-authenticate.", namedparams(1, "entityID", eid2.c_str()));
}
if (timeout) {
}
catch (...) {
session->unlock();
- remove(key, application);
+ remove(application, key);
throw;
}
return session;
}
-void SSCache::remove(const char* key, const Application& application)
+void SSCache::remove(const Application& application, const char* key)
{
#ifdef _DEBUG
xmltooling::NDC ndc("remove");
if (timeout > 0 && now - lastAccess >= timeout) {
m_log.info("session timed out (ID: %s)", key);
- remove(key,*app);
+ remove(*app, key);
throw RetryableProfileException("Your session has expired, and you must re-authenticate.");
}
if (!app)
throw ConfigurationException("Application not found, check configuration?");
- remove(key,*app);
+ remove(*app, key);
DDF ret(NULL);
DDFJanitor jan(ret);
out << ret;