Change base class hook.
[shibboleth/sp.git] / nsapi_shib / nsapi_shib.cpp
index 6cc2710..8914e7e 100644 (file)
 #ifdef WIN32
 # define _CRT_NONSTDC_NO_DEPRECATE 1
 # define _CRT_SECURE_NO_DEPRECATE 1
+# define _CRT_RAND_S
 #endif
 
+#include <shibsp/exceptions.h>
 #include <shibsp/AbstractSPRequest.h>
 #include <shibsp/RequestMapper.h>
 #include <shibsp/SPConfig.h>
 #include <shibsp/ServiceProvider.h>
+
+#include <set>
+#include <memory>
+#include <fstream>
+#include <sstream>
+#include <stdexcept>
 #include <xmltooling/XMLToolingConfig.h>
 #include <xmltooling/util/NDC.h>
 #include <xmltooling/util/Threads.h>
 #include <xmltooling/util/XMLHelper.h>
 #include <xercesc/util/XMLUniDefs.hpp>
 
-#include <memory>
-#include <fstream>
-#include <sstream>
-#include <stdexcept>
-
 #ifdef WIN32
 # include <process.h>
 # define XP_WIN32
@@ -82,6 +85,16 @@ 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);
+
+    void _my_invalid_parameter_handler(
+       const wchar_t * expression,
+       const wchar_t * function,
+       const wchar_t * file,
+       unsigned int line,
+       uintptr_t pReserved
+       ) {
+        return;
+    }
 }
 
 PluginManager<RequestMapper,string,const xercesc::DOMElement*>::Factory SunRequestMapFactory;
@@ -155,18 +168,39 @@ extern "C" NSAPI_PUBLIC int nsapi_shib_init(pblock* pb, ::Session* sn, Request*
     Locker locker(sp);
     const PropertySet* props=sp->getPropertySet("InProcess");
     if (props) {
+        pair<bool,bool> flag=props->getBool("checkSpoofing");
+        g_checkSpoofing = !flag.first || flag.second;
+        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,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;
+#ifdef WIN32
+            else {
+                _invalid_parameter_handler old = _set_invalid_parameter_handler(_my_invalid_parameter_handler);
+                unsigned int randkey=0,randkey2=0,randkey3=0,randkey4=0;
+                if (rand_s(&randkey) == 0 && rand_s(&randkey2) == 0 && rand_s(&randkey3) == 0 && rand_s(&randkey4) == 0) {
+                    _set_invalid_parameter_handler(old);
+                    ostringstream keystr;
+                    keystr << randkey << randkey2 << randkey3 << randkey4;
+                    g_spoofKey = keystr.str();
+                }
+                else {
+                    _set_invalid_parameter_handler(old);
+                    pblock_nvinsert("error", "module failed to generate a random anti-spoofing key (if this is Windows 2000 set one manually)", pb);
+                    locker.assign(); // pops lock on SP config
+                    g_Config->term();
+                    g_Config=NULL;
+                    return REQ_ABORTED;
+                }
+            }
+#endif
         }
-        flag=props->getBool("catchAll");
-        g_catchAll = flag.first && flag.second;
     }
     return REQ_PROCEED;
 }
@@ -388,6 +422,7 @@ public:
       setResponseHeader("Content-Type", type);
   }
   void setResponseHeader(const char* name, const char* value) {
+    HTTPResponse::setResponseHeader(name, value);
     pblock_nvinsert(name, value, m_rq->srvhdrs);
   }
 
@@ -406,6 +441,7 @@ public:
     return REQ_EXIT;
   }
   long sendRedirect(const char* url) {
+    HTTPResponse::sendRedirect(url);
     param_free(pblock_remove("content-type", m_rq->srvhdrs));
     pblock_nninsert("content-length", 0, m_rq->srvhdrs);
     pblock_nvinsert("expires", "01-Jan-1997 12:00:00 GMT", m_rq->srvhdrs);