map<string,site_t> g_Sites;
bool g_bNormalizeRequest = true;
string g_unsetHeaderValue,g_spoofKey;
+ set<string> g_allowedSchemes;
bool g_checkSpoofing = true;
bool g_catchAll = true;
bool g_bSafeHeaderNames = false;
flag=props->getBool("catchAll");
g_catchAll = !flag.first || flag.second;
- pair<bool,const char*> unsetValue=props->getString("unsetHeaderValue");
- if (unsetValue.first)
- g_unsetHeaderValue = unsetValue.second;
+ pair<bool,const char*> str=props->getString("unsetHeaderValue");
+ if (str.first)
+ g_unsetHeaderValue = str.second;
+
+ str=props->getString("allowedSchemes");
+ if (str.first) {
+ string schemes=str.second;
+ unsigned int j=0;
+ for (unsigned int i=0; i < schemes.length(); i++) {
+ if (schemes.at(i)==' ') {
+ g_allowedSchemes.insert(schemes.substr(j, i-j));
+ j = i+1;
+ }
+ }
+ g_allowedSchemes.insert(schemes.substr(j, schemes.length()-j));
+ }
+
if (g_checkSpoofing) {
- unsetValue = props->getString("spoofKey");
- if (unsetValue.first)
- g_spoofKey = unsetValue.second;
+ str = props->getString("spoofKey");
+ if (str.first)
+ g_spoofKey = str.second;
else {
LogEvent(NULL, EVENTLOG_WARNING_TYPE, 2100, NULL,
"Filter generating a pseudorandom anti-spoofing key, consider setting spoofKey yourself.");
}
}
}
+ if (g_allowedSchemes.empty()) {
+ g_allowedSchemes.insert("https");
+ g_allowedSchemes.insert("http");
+ }
}
catch (exception&) {
LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, "Filter startup failed with an exception.");
dynabuf m_allhttp;
bool m_firsttime;
+ void checkString(const string& s, const char* msg) {
+ string::const_iterator e = s.end();
+ for (string::const_iterator i=s.begin(); i!=e; ++i) {
+ if (iscntrl(*i))
+ throw FatalProfileException(msg);
+ }
+ }
+
public:
ShibTargetIsapiF(PHTTP_FILTER_CONTEXT pfc, PHTTP_FILTER_PREPROC_HEADERS pn, const site_t& site)
: m_pfc(pfc), m_pn(pn), m_allhttp(4096), m_firsttime(true) {
int code=200,
const string& content_type="text/html",
const Iterator<header_t>& headers=EMPTY(header_t)) {
+ checkString(content_type, "Detected control character in a response header.");
string hdr = string ("Connection: close\r\nContent-type: ") + content_type + "\r\n";
while (headers.hasNext()) {
const header_t& h=headers.next();
+ checkString(h.first, "Detected control character in a response header.");
+ checkString(h.second, "Detected control character in a response header.");
hdr += h.first + ": " + h.second + "\r\n";
}
hdr += "\r\n";
return (void*)SF_STATUS_REQ_FINISHED;
}
virtual void* sendRedirect(const string& url) {
+ checkString(url, "Detected control character in an attempted redirect.");
+ if (g_allowedSchemes.find(url.substr(0, url.find(':'))) == g_allowedSchemes.end())
+ throw FatalProfileException("Invalid scheme in attempted redirect.");
// XXX: Don't support the httpRedirect option, yet.
string hdrs=m_cookie + string("Location: ") + url + "\r\n"
"Content-Type: text/html\r\n"
LPEXTENSION_CONTROL_BLOCK m_lpECB;
string m_cookie;
+ void checkString(const string& s, const char* msg) {
+ string::const_iterator e = s.end();
+ for (string::const_iterator i=s.begin(); i!=e; ++i) {
+ if (iscntrl(*i))
+ throw FatalProfileException(msg);
+ }
+ }
+
public:
ShibTargetIsapiE(LPEXTENSION_CONTROL_BLOCK lpECB, const site_t& site) {
dynabuf ssl(5);
int code=200,
const string& content_type="text/html",
const Iterator<header_t>& headers=EMPTY(header_t)) {
+ checkString(content_type, "Detected control character in a response header.");
string hdr = m_cookie + "Connection: close\r\nContent-type: " + content_type + "\r\n";
for (int k = 0; k < headers.size(); k++) {
+ checkString(headers[k].first, "Detected control character in a response header.");
+ checkString(headers[k].second, "Detected control character in a response header.");
hdr += headers[k].first + ": " + headers[k].second + "\r\n";
}
hdr += "\r\n";
}
virtual void* sendRedirect(const string& url) {
// XXX: Don't support the httpRedirect option, yet.
+ checkString(url, "Detected control character in an attempted redirect.");
+ if (g_allowedSchemes.find(url.substr(0, url.find(':'))) == g_allowedSchemes.end())
+ throw FatalProfileException("Invalid scheme in attempted redirect.");
string hdrs = m_cookie + "Location: " + url + "\r\n"
"Content-Type: text/html\r\n"
"Content-Length: 40\r\n"