DDF AbstractHandler::recoverPostData( const Application& application, const HTTPRequest& request, HTTPResponse& response, const char* relayState ) const { // First we need the post recovery cookie. pair<string,const char*> shib_cookie = getPostCookieNameProps(application, relayState); const char* cookie = request.getCookie(shib_cookie.first.c_str()); if (!cookie || !*cookie) return DDF(); // Clear the cookie. string exp(shib_cookie.second); exp += "; expires=Mon, 01 Jan 2001 00:00:00 GMT"; response.setCookie(shib_cookie.first.c_str(), exp.c_str()); // Look for StorageService-backed state of the form "ss:SSID:key". const char* state = cookie; if (strstr(state, "ss:") == state) { state += 3; const char* key = strchr(state, ':'); if (key) { string ssid = string(cookie).substr(3, key - state); key++; if (!ssid.empty() && *key) { SPConfig& conf = SPConfig::getConfig(); if (conf.isEnabled(SPConfig::OutOfProcess)) { #ifndef SHIBSP_LITE StorageService* storage = conf.getServiceProvider()->getStorageService(ssid.c_str()); if (storage) { if (storage->readString("PostData", key, &ssid) > 0) { storage->deleteString("PostData", key); istringstream inret(ssid); DDF ret; inret >> ret; return ret; } else { m_log.error("failed to recover form post data using key (%s)", key); } }
void AbstractHandler::recoverRelayState( const Application& application, const HTTPRequest& request, HTTPResponse& response, string& relayState, bool clear ) const { SPConfig& conf = SPConfig::getConfig(); // Look for StorageService-backed state of the form "ss:SSID:key". const char* state = relayState.c_str(); if (strstr(state,"ss:")==state) { state += 3; const char* key = strchr(state,':'); if (key) { string ssid = relayState.substr(3, key - state); key++; if (!ssid.empty() && *key) { if (conf.isEnabled(SPConfig::OutOfProcess)) { #ifndef SHIBSP_LITE StorageService* storage = conf.getServiceProvider()->getStorageService(ssid.c_str()); if (storage) { ssid = key; if (storage->readString("RelayState",ssid.c_str(),&relayState)>0) { if (clear) storage->deleteString("RelayState",ssid.c_str()); return; } else relayState.erase(); } else { m_log.error("Storage-backed RelayState with invalid StorageService ID (%s)", ssid.c_str()); relayState.erase(); } #endif } else if (conf.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); if (!out.isstring()) { m_log.error("StorageService-backed RelayState mechanism did not return a state value."); relayState.erase(); } else { relayState = out.string(); return; } } } } } // Look for cookie-backed state of the form "cookie:key". if (strstr(state,"cookie:")==state) { state += 7; if (*state) { // Pull the value from the "relay state" cookie. pair<string,const char*> relay_cookie = application.getCookieNameProps("_shibstate_"); relay_cookie.first = string("_shibstate_") + state; state = request.getCookie(relay_cookie.first.c_str()); if (state && *state) { // URL-decode the value. char* rscopy=strdup(state); XMLToolingConfig::getConfig().getURLEncoder()->decode(rscopy); relayState = rscopy; free(rscopy); if (clear) { string exp(relay_cookie.second); exp += "; expires=Mon, 01 Jan 2001 00:00:00 GMT"; response.setCookie(relay_cookie.first.c_str(), exp.c_str()); } return; } } relayState.erase(); } // 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 { // Compute a URL to the root of the site. int port = request.getPort(); const char* scheme = request.getScheme(); relayState = string(scheme) + "://" + request.getHostname(); if ((!strcmp(scheme,"http") && port!=80) || (!strcmp(scheme,"https") && port!=443)) { ostringstream portstr; portstr << port; relayState += ":" + portstr.str(); } relayState += '/'; } } }