Add logging when catching unknown errors.
[shibboleth/sp.git] / isapi_shib / isapi_shib.cpp
index 6b66058..e04bdcd 100644 (file)
@@ -54,7 +54,7 @@ using namespace std;
 // globals
 namespace {
     static const XMLCh path[] =             UNICODE_LITERAL_4(p,a,t,h);
-    static const XMLCh validate[] = UNICODE_LITERAL_8(v,a,l,i,d,a,t,e);
+    static const XMLCh validate[] =         UNICODE_LITERAL_8(v,a,l,i,d,a,t,e);
     static const XMLCh name[] =             UNICODE_LITERAL_4(n,a,m,e);
     static const XMLCh port[] =             UNICODE_LITERAL_4(p,o,r,t);
     static const XMLCh sslport[] =          UNICODE_LITERAL_7(s,s,l,p,o,r,t);
@@ -96,6 +96,7 @@ namespace {
     bool g_bNormalizeRequest = true;
     string g_unsetHeaderValue;
     bool g_checkSpoofing = true;
+    bool g_catchAll = false;
     vector<string> g_NoCerts;
 }
 
@@ -201,9 +202,11 @@ extern "C" BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer)
         pair<bool,const char*> unsetValue=props->getString("unsetHeaderValue");
         if (unsetValue.first)
             g_unsetHeaderValue = unsetValue.second;
-        pair<bool,bool> checkSpoofing=props->getBool("checkSpoofing");
-        if (checkSpoofing.first && !checkSpoofing.second)
-            g_checkSpoofing = false;
+        pair<bool,bool> flag=props->getBool("checkSpoofing");
+        g_checkSpoofing = !flag.first || flag.second;
+        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);
@@ -350,7 +353,7 @@ class ShibTargetIsapiF : public AbstractSPRequest
 {
   PHTTP_FILTER_CONTEXT m_pfc;
   PHTTP_FILTER_PREPROC_HEADERS m_pn;
-  map<string,string> m_headers;
+  multimap<string,string> m_headers;
   int m_port;
   string m_scheme,m_hostname,m_uri;
   mutable string m_remote_addr,m_content_type,m_method;
@@ -470,13 +473,13 @@ public:
   void setResponseHeader(const char* name, const char* value) {
     // Set for later.
     if (value)
-        m_headers[name] = value;
+        m_headers.insert(make_pair(name,value));
     else
         m_headers.erase(name);
   }
   long sendResponse(istream& in, long status) {
     string hdr = string("Connection: close\r\n");
-    for (map<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)
+    for (multimap<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)
         hdr += i->first + ": " + i->second + "\r\n";
     hdr += "\r\n";
     const char* codestr="200 OK";
@@ -501,7 +504,7 @@ public:
       "Content-Length: 40\r\n"
       "Expires: 01-Jan-1997 12:00:00 GMT\r\n"
       "Cache-Control: private,no-store,no-cache\r\n";
-    for (map<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)
+    for (multimap<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)
         hdr += i->first + ": " + i->second + "\r\n";
     hdr += "\r\n";
     m_pfc->ServerSupportFunction(m_pfc, SF_REQ_SEND_RESPONSE_HEADER, "302 Please Wait", (DWORD)hdr.c_str(), 0);
@@ -597,11 +600,12 @@ extern "C" DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc, DWORD notificat
         LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, e.what());
         return WriteClientError(pfc,"Shibboleth Filter caught an exception, check Event Log for details.");
     }
-#ifndef _DEBUG
     catch(...) {
-        return WriteClientError(pfc,"Shibboleth Filter caught an unknown exception.");
+        LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, "Shibboleth Filter threw an unknown exception.");
+        if (g_catchAll)
+            return WriteClientError(pfc,"Shibboleth Filter threw an unknown exception.");
+        throw;
     }
-#endif
 
     return WriteClientError(pfc,"Shibboleth Filter reached unreachable code, save my walrus!");
 }
@@ -630,7 +634,7 @@ DWORD WriteClientError(LPEXTENSION_CONTROL_BLOCK lpECB, const char* msg)
 class ShibTargetIsapiE : public AbstractSPRequest
 {
   LPEXTENSION_CONTROL_BLOCK m_lpECB;
-  map<string,string> m_headers;
+  multimap<string,string> m_headers;
   mutable vector<string> m_certs;
   mutable string m_body;
   mutable bool m_gotBody;
@@ -773,7 +777,7 @@ public:
   void setResponseHeader(const char* name, const char* value) {
     // Set for later.
     if (value)
-        m_headers[name] = value;
+        m_headers.insert(make_pair(name,value));
     else
         m_headers.erase(name);
   }
@@ -806,7 +810,7 @@ public:
   }
   long sendResponse(istream& in, long status) {
     string hdr = string("Connection: close\r\n");
-    for (map<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)
+    for (multimap<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)
         hdr += i->first + ": " + i->second + "\r\n";
     hdr += "\r\n";
     const char* codestr="200 OK";
@@ -830,7 +834,7 @@ public:
       "Content-Length: 40\r\n"
       "Expires: 01-Jan-1997 12:00:00 GMT\r\n"
       "Cache-Control: private,no-store,no-cache\r\n";
-    for (map<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)
+    for (multimap<string,string>::const_iterator i=m_headers.begin(); i!=m_headers.end(); ++i)
         hdr += i->first + ": " + i->second + "\r\n";
     hdr += "\r\n";
     m_lpECB->ServerSupportFunction(m_lpECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, "302 Moved", 0, (LPDWORD)hdr.c_str());
@@ -914,11 +918,12 @@ extern "C" DWORD WINAPI HttpExtensionProc(LPEXTENSION_CONTROL_BLOCK lpECB)
         LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, e.what());
         return WriteClientError(lpECB,"Shibboleth Extension caught an exception, check Event Log for details.");
     }
-#ifndef _DEBUG
     catch(...) {
-        return WriteClientError(lpECB,"Shibboleth Extension caught an unknown exception.");
+        LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, "Shibboleth Extension threw an unknown exception.");
+        if (g_catchAll)
+            return WriteClientError(lpECB,"Shibboleth Extension threw an unknown exception.");
+        throw;
     }
-#endif
 
     // If we get here we've got an error.
     return HSE_STATUS_ERROR;