string g_ServerName;
string g_ServerScheme;
string g_unsetHeaderValue;
+ string g_spoofKey;
bool g_checkSpoofing = true;
bool g_catchAll = false;
return REQ_ABORTED;
}
- g_Config->RequestMapperManager.registerFactory(XML_REQUEST_MAPPER,&SunRequestMapFactory);
+ g_Config->RequestMapperManager.registerFactory(NATIVE_REQUEST_MAPPER,&SunRequestMapFactory);
try {
if (!g_Config->instantiate(pblock_findval("shib-config",pb), true))
ServiceProvider* sp=g_Config->getServiceProvider();
Locker locker(sp);
- const PropertySet* props=sp->getPropertySet("Local");
+ const PropertySet* props=sp->getPropertySet("InProcess");
if (props) {
pair<bool,const char*> unsetValue=props->getString("unsetHeaderValue");
if (unsetValue.first)
g_unsetHeaderValue = unsetValue.second;
pair<bool,bool> flag=props->getBool("checkSpoofing");
g_checkSpoofing = !flag.first || flag.second;
+ if (g_checkSpoofing) {
+ unsetValue=props->getString("spoofKey");
+ if (unsetValue.first)
+ g_spoofKey = unsetValue.second;
+ }
flag=props->getBool("catchAll");
g_catchAll = flag.first && flag.second;
}
}
// See if this is the first time we've run.
- qstr = pblock_findval("auth-type", rq->vars);
- if (qstr && !strcmp(qstr, "shibboleth"))
- m_firsttime = false;
+ if (!g_spoofKey.empty()) {
+ qstr = pblock_findval("Shib-Spoof-Check", rq->headers);
+ if (qstr && g_spoofKey == qstr)
+ m_firsttime = false;
+ }
if (!m_firsttime || rq->orig_rq)
log(SPDebug, "nsapi_shib function running more than once");
}
return pblock_findval("method", m_rq->reqpb);
}
string getContentType() const {
- char* content_type = "";
- request_header("content-type", &content_type, m_sn, m_rq);
- return content_type;
+ char* content_type = NULL;
+ if (request_header("content-type", &content_type, m_sn, m_rq) != REQ_PROCEED)
+ return "";
+ return content_type ? content_type : "";
}
long getContentLength() const {
if (m_gotBody)
return m_body.length();
- char* content_length="";
- request_header("content-length", &content_length, m_sn, m_rq);
- return atoi(content_length);
+ char* content_length=NULL;
+ if (request_header("content-length", &content_length, m_sn, m_rq) != REQ_PROCEED)
+ return 0;
+ return content_length ? atoi(content_length) : 0;
}
string getRemoteAddr() const {
- return pblock_findval("ip", m_sn->client);
+ string ret = AbstractSPRequest::getRemoteAddr();
+ return ret.empty() ? pblock_findval("ip", m_sn->client) : ret;
}
void log(SPLogLevel level, const string& msg) const {
AbstractSPRequest::log(level,msg);
if (m_gotBody)
return m_body.c_str();
char* content_length=NULL;
- if (request_header("content-length", &content_length, m_sn, m_rq)!=REQ_PROCEED || atoi(content_length) > 1024*1024) // 1MB?
+ if (request_header("content-length", &content_length, m_sn, m_rq) != REQ_PROCEED || !content_length) {
+ m_gotBody = true;
+ return NULL;
+ }
+ else if (atoi(content_length) > 1024*1024) // 1MB?
throw opensaml::SecurityPolicyException("Blocked request body exceeding 1M size limit.");
else {
char ch=IO_EOF+1;
if (m_allhttp.count(cginame) > 0)
throw opensaml::SecurityPolicyException("Attempt to spoof header ($1) was detected.", params(1, rawname));
}
- param_free(pblock_remove(rawname, m_rq->headers));
- pblock_nvinsert(rawname, g_unsetHeaderValue.c_str(), m_rq->headers);
+ if (strcmp(rawname, "REMOTE_USER") == 0) {
+ param_free(pblock_remove("remote-user", m_rq->headers));
+ pblock_nvinsert("remote-user", g_unsetHeaderValue.c_str(), m_rq->headers);
+ }
+ else {
+ param_free(pblock_remove(rawname, m_rq->headers));
+ pblock_nvinsert(rawname, g_unsetHeaderValue.c_str(), m_rq->headers);
+ }
}
void setHeader(const char* name, const char* value) {
param_free(pblock_remove(name, m_rq->headers));
}
void setRemoteUser(const char* user) {
pblock_nvinsert("auth-user", user, m_rq->vars);
+ param_free(pblock_remove("remote-user", m_rq->headers));
+ pblock_nvinsert("remote-user", user, m_rq->headers);
}
string getRemoteUser() const {
const char* ru = pblock_findval("auth-user", m_rq->vars);
return ru ? ru : "";
}
+ void setContentType(const char* type) {
+ // iPlanet seems to have a case folding problem.
+ param_free(pblock_remove("content-type", m_rq->srvhdrs));
+ setResponseHeader("Content-Type", type);
+ }
void setResponseHeader(const char* name, const char* value) {
pblock_nvinsert(name, value, m_rq->srvhdrs);
}
// Check user authentication
pair<bool,long> res = stn.getServiceProvider().doAuthentication(stn);
+ // If directed, install a spoof key to recognize when we've already cleared headers.
+ if (!g_spoofKey.empty()) {
+ param_free(pblock_remove("Shib-Spoof-Check", rq->headers));
+ pblock_nvinsert("Shib-Spoof-Check", g_spoofKey.c_str(), rq->headers);
+ }
if (res.first) return (int)res.second;
// user authN was okay -- export the assertions now
param_free(pblock_remove("auth-user",rq->vars));
+
// This seems to be required in order to eventually set
// the auth-user var.
pblock_nvinsert("auth-type","shibboleth",rq->vars);
+
res = stn.getServiceProvider().doExport(stn);
if (res.first) return (int)res.second;
return WriteClientError(sn, rq, FUNC, "Shibboleth handler threw an exception, see web server log for error.");
}
catch (...) {
+ log_error(LOG_FAILURE,FUNC,sn,rq,"unknown exception caught in Shibboleth handler");
if (g_catchAll)
return WriteClientError(sn, rq, FUNC, "Shibboleth handler threw an unknown exception.");
throw;