static const XMLCh sslport[] = UNICODE_LITERAL_7(s,s,l,p,o,r,t);
static const XMLCh scheme[] = UNICODE_LITERAL_6(s,c,h,e,m,e);
static const XMLCh id[] = UNICODE_LITERAL_2(i,d);
- static const XMLCh Implementation[] = UNICODE_LITERAL_14(I,m,p,l,e,m,e,n,t,a,t,i,o,n);
static const XMLCh ISAPI[] = UNICODE_LITERAL_5(I,S,A,P,I);
static const XMLCh Alias[] = UNICODE_LITERAL_5(A,l,i,a,s);
static const XMLCh normalizeRequest[] = UNICODE_LITERAL_16(n,o,r,m,a,l,i,z,e,R,e,q,u,e,s,t);
string m_scheme,m_port,m_sslport,m_name;
set<string> m_aliases;
};
+
+ struct context_t {
+ char* m_user;
+ bool m_checked;
+ };
HINSTANCE g_hinstDLL;
SPConfig* g_Config = NULL;
return TRUE;
}
- LPCSTR schemadir=getenv("SHIBSP_SCHEMAS");
- if (!schemadir)
- schemadir=SHIBSP_SCHEMAS;
- LPCSTR config=getenv("SHIBSP_CONFIG");
- if (!config)
- config=SHIBSP_CONFIG;
g_Config=&SPConfig::getConfig();
g_Config->setFeatures(
SPConfig::Listener |
SPConfig::Logging |
SPConfig::Handlers
);
- if (!g_Config->init(schemadir)) {
+ if (!g_Config->init()) {
g_Config=NULL;
LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,
"Filter startup failed during library initialization, check native log for help.");
return FALSE;
}
+ LPCSTR config=getenv("SHIBSP_CONFIG");
+ if (!config)
+ config=SHIBSP_CONFIG;
+
try {
DOMDocument* dummydoc=XMLToolingConfig::getConfig().getParser().newDocument();
XercesJanitor<DOMDocument> docjanitor(dummydoc);
return FALSE;
}
- // Access the implementation-specifics for site mappings.
+ // Access implementation-specifics and site mappings.
ServiceProvider* sp=g_Config->getServiceProvider();
Locker locker(sp);
const PropertySet* props=sp->getPropertySet("InProcess");
flag=props->getBool("catchAll");
g_catchAll = flag.first && flag.second;
- const DOMElement* impl=XMLHelper::getFirstChildElement(props->getElement(),Implementation);
- if (impl && (impl=XMLHelper::getFirstChildElement(impl,ISAPI))) {
- const XMLCh* flag=impl->getAttributeNS(NULL,normalizeRequest);
- g_bNormalizeRequest=(!flag || !*flag || *flag==chDigit_1 || *flag==chLatin_t);
- impl=XMLHelper::getFirstChildElement(impl,Site);
- while (impl) {
- auto_ptr_char id(impl->getAttributeNS(NULL,id));
+ props = props->getPropertySet("ISAPI");
+ if (props) {
+ flag = props->getBool("normalizeRequest");
+ g_bNormalizeRequest = !flag.first || flag.second;
+ const DOMElement* child = XMLHelper::getFirstChildElement(props->getElement(),Site);
+ while (child) {
+ auto_ptr_char id(child->getAttributeNS(NULL,id));
if (id.get())
- g_Sites.insert(pair<string,site_t>(id.get(),site_t(impl)));
- impl=XMLHelper::getNextSiblingElement(impl,Site);
+ g_Sites.insert(pair<string,site_t>(id.get(),site_t(child)));
+ child=XMLHelper::getNextSiblingElement(child,Site);
}
}
}
PHTTP_FILTER_PREPROC_HEADERS m_pn;
multimap<string,string> m_headers;
int m_port;
- string m_scheme,m_hostname,m_uri;
+ string m_scheme,m_hostname;
mutable string m_remote_addr,m_content_type,m_method;
dynabuf m_allhttp;
public:
ShibTargetIsapiF(PHTTP_FILTER_CONTEXT pfc, PHTTP_FILTER_PREPROC_HEADERS pn, const site_t& site)
- : m_pfc(pfc), m_pn(pn), m_allhttp(4096) {
+ : AbstractSPRequest(SHIBSP_LOGCAT".ISAPI"), m_pfc(pfc), m_pn(pn), m_allhttp(4096) {
// URL path always come from IIS.
dynabuf var(256);
GetHeader(pn,pfc,"url",var,256,false);
- m_uri = var;
+ setRequestURI(var);
// Port may come from IIS or from site def.
if (!g_bNormalizeRequest || (pfc->fIsSecurePort && site.m_sslport.empty()) || (!pfc->fIsSecurePort && site.m_port.empty())) {
m_hostname = var;
if (site.m_name!=m_hostname && site.m_aliases.find(m_hostname)==site.m_aliases.end())
m_hostname=site.m_name;
+
+ if (!pfc->pFilterContext) {
+ pfc->pFilterContext = pfc->AllocMem(pfc, sizeof(context_t), NULL);
+ if (static_cast<context_t*>(pfc->pFilterContext)) {
+ static_cast<context_t*>(pfc->pFilterContext)->m_user = NULL;
+ static_cast<context_t*>(pfc->pFilterContext)->m_checked = false;
+ }
+ }
}
~ShibTargetIsapiF() { }
int getPort() const {
return m_port;
}
- const char* getRequestURI() const {
- return m_uri.c_str();
- }
const char* getMethod() const {
if (m_method.empty()) {
dynabuf var(5);
LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, msg.c_str());
}
void clearHeader(const char* rawname, const char* cginame) {
- if (g_checkSpoofing) {
+ if (g_checkSpoofing && m_pfc->pFilterContext && !static_cast<context_t*>(m_pfc->pFilterContext)->m_checked) {
if (m_allhttp.empty())
GetServerVariable(m_pfc,"ALL_HTTP",m_allhttp,4096);
if (strstr(m_allhttp, cginame))
}
void setRemoteUser(const char* user) {
setHeader("remote-user", user);
+ if (m_pfc->pFilterContext) {
+ if (!user || !*user)
+ static_cast<context_t*>(m_pfc->pFilterContext)->m_user = NULL;
+ else if (static_cast<context_t*>(m_pfc->pFilterContext)->m_user = (char*)m_pfc->AllocMem(m_pfc, sizeof(char) * (strlen(user) + 1), NULL))
+ strcpy(static_cast<context_t*>(m_pfc->pFilterContext)->m_user, user);
+ }
}
string getRemoteUser() const {
return getHeader("remote-user");
extern "C" DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc, DWORD notificationType, LPVOID pvNotification)
{
// Is this a log notification?
- if (notificationType==SF_NOTIFY_LOG)
- {
- if (pfc->pFilterContext)
- ((PHTTP_FILTER_LOG)pvNotification)->pszClientUserName=static_cast<LPCSTR>(pfc->pFilterContext);
+ if (notificationType==SF_NOTIFY_LOG) {
+ if (pfc->pFilterContext && static_cast<context_t*>(pfc->pFilterContext)->m_user)
+ ((PHTTP_FILTER_LOG)pvNotification)->pszClientUserName=static_cast<context_t*>(pfc->pFilterContext)->m_user;
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
// "false" because we don't override the Shib settings
pair<bool,long> res = stf.getServiceProvider().doAuthentication(stf);
+ if (pfc->pFilterContext)
+ static_cast<context_t*>(pfc->pFilterContext)->m_checked = true;
if (res.first) return res.second;
// "false" because we don't override the Shib settings
mutable string m_remote_addr,m_remote_user;
public:
- ShibTargetIsapiE(LPEXTENSION_CONTROL_BLOCK lpECB, const site_t& site) : m_lpECB(lpECB), m_gotBody(false) {
+ ShibTargetIsapiE(LPEXTENSION_CONTROL_BLOCK lpECB, const site_t& site)
+ : AbstractSPRequest(SHIBSP_LOGCAT".ISAPI"), m_lpECB(lpECB), m_gotBody(false) {
dynabuf ssl(5);
GetServerVariable(lpECB,"HTTPS",ssl,5);
bool SSL=(ssl=="on" || ssl=="ON");
* PathInfo: /SAML/POST
*/
+ string uri;
+
// Clearly we're only in bad mode if path info exists at all.
if (lpECB->lpszPathInfo && *(lpECB->lpszPathInfo)) {
if (strstr(lpECB->lpszPathInfo,url))
// Pretty good chance we're in bad mode, unless the PathInfo repeats the path itself.
- m_uri = lpECB->lpszPathInfo;
+ uri = lpECB->lpszPathInfo;
else {
- m_uri = url;
- m_uri += lpECB->lpszPathInfo;
+ uri = url;
+ uri += lpECB->lpszPathInfo;
}
}
else {
- m_uri = url;
+ uri = url;
}
// For consistency with Apache, let's add the query string.
if (lpECB->lpszQueryString && *(lpECB->lpszQueryString)) {
- m_uri += '?';
- m_uri += lpECB->lpszQueryString;
+ uri += '?';
+ uri += lpECB->lpszQueryString;
}
+
+ setRequestURI(uri.c_str());
}
~ShibTargetIsapiE() { }
int getPort() const {
return m_port;
}
- const char* getRequestURI() const {
- return m_uri.c_str();
- }
const char* getMethod() const {
return m_lpECB->lpszMethod;
}
// Match site instance to host name, skip if no match.
map<string,site_t>::const_iterator map_i=g_Sites.find(static_cast<char*>(buf));
if (map_i==g_Sites.end())
- return WriteClientError(lpECB, "Shibboleth Extension not configured for this web site.");
+ return WriteClientError(lpECB, "Shibboleth Extension not configured for web site (check <ISAPI> mappings in configuration).");
ShibTargetIsapiE ste(lpECB, map_i->second);
pair<bool,long> res = ste.getServiceProvider().doHandler(ste);