Move Shib constants to new lib, fixed symbol conflicts.
[shibboleth/cpp-sp.git] / isapi_shib / isapi_shib.cpp
index 37740f3..dda800d 100644 (file)
 
 #include "config_win32.h"
 
+#define _CRT_NONSTDC_NO_DEPRECATE 1
+#define _CRT_SECURE_NO_DEPRECATE 1
+
 // SAML Runtime
 #include <saml/saml.h>
 #include <shib/shib.h>
-#include <shib/shib-threads.h>
 #include <shib-target/shib-target.h>
+#include <shibsp/SPConfig.h>
 
 #include <ctime>
 #include <fstream>
 #include <httpfilt.h>
 #include <httpext.h>
 
-using namespace std;
-using namespace saml;
-using namespace shibboleth;
+using namespace shibsp;
 using namespace shibtarget;
+using namespace xmltooling;
+using namespace std;
 
 // globals
 namespace {
@@ -71,7 +74,7 @@ namespace {
             if (p.get()) m_port=p.get();
             if (p2.get()) m_sslport=p2.get();
             DOMNodeList* nlist=e->getElementsByTagNameNS(shibtarget::XML::SHIBTARGET_NS,Alias);
-            for (int i=0; nlist && i<nlist->getLength(); i++) {
+            for (unsigned int i=0; nlist && i<nlist->getLength(); i++) {
                 if (nlist->item(i)->hasChildNodes()) {
                     auto_ptr_char alias(nlist->item(i)->getFirstChild()->getNodeValue());
                     m_aliases.insert(alias.get());
@@ -86,7 +89,6 @@ namespace {
     ShibTargetConfig* g_Config = NULL;
     map<string,site_t> g_Sites;
     bool g_bNormalizeRequest = true;
-    string g_unsetHeaderValue;
 }
 
 BOOL LogEvent(
@@ -153,13 +155,14 @@ extern "C" BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer)
         if (!config)
             config=SHIB_CONFIG;
         g_Config=&ShibTargetConfig::getConfig();
-        g_Config->setFeatures(
-            ShibTargetConfig::Listener |
-            ShibTargetConfig::Metadata |
-            ShibTargetConfig::AAP |
-            ShibTargetConfig::RequestMapper |
-            ShibTargetConfig::LocalExtensions |
-            ShibTargetConfig::Logging
+        SPConfig::getConfig().setFeatures(
+            SPConfig::Listener |
+            SPConfig::Caching |
+            SPConfig::Metadata |
+            SPConfig::AAP |
+            SPConfig::RequestMapper |
+            SPConfig::InProcess |
+            SPConfig::Logging
             );
         if (!g_Config->init(schemadir)) {
             g_Config=NULL;
@@ -176,12 +179,9 @@ extern "C" BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer)
         
         // Access the implementation-specifics for site mappings.
         IConfig* conf=g_Config->getINI();
-        Locker locker(conf);
-        const IPropertySet* props=conf->getPropertySet("Local");
+        saml::Locker locker(conf);
+        const PropertySet* props=conf->getPropertySet("Local");
         if (props) {
-            pair<bool,const char*> unsetValue=props->getString("unsetHeaderValue");
-            if (unsetValue.first)
-                g_unsetHeaderValue = unsetValue.second;
             const DOMElement* impl=saml::XML::getFirstChildElement(
                 props->getElement(),shibtarget::XML::SHIBTARGET_NS,Implementation
                 );
@@ -391,6 +391,8 @@ public:
 
   virtual void log(ShibLogLevel level, const string &msg) {
     ShibTarget::log(level,msg);
+    if (level == LogLevelError)
+        LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, msg.c_str());
   }
   virtual string getCookies() const {
     dynabuf buf(128);
@@ -400,7 +402,7 @@ public:
   
   virtual void clearHeader(const string &name) {
     string hdr = (name=="REMOTE_USER" ? "remote-user" : name) + ":";
-    m_pn->SetHeader(m_pfc, const_cast<char*>(hdr.c_str()), const_cast<char*>(g_unsetHeaderValue.c_str()));
+    m_pn->SetHeader(m_pfc, const_cast<char*>(hdr.c_str()), "");
   }
   virtual void setHeader(const string &name, const string &value) {
     string hdr = name + ":";
@@ -423,7 +425,7 @@ public:
     const string& msg,
     int code=200,
     const string& content_type="text/html",
-    const Iterator<header_t>& headers=EMPTY(header_t)) {
+    const saml::Iterator<header_t>& headers=EMPTY(header_t)) {
     string hdr = string ("Connection: close\r\nContent-type: ") + content_type + "\r\n";
     while (headers.hasNext()) {
         const header_t& h=headers.next();
@@ -464,8 +466,8 @@ public:
     // Set the cookie for later.  Use it during the redirect.
     m_cookie += "Set-Cookie: " + name + "=" + value + "\r\n";
   }
-  virtual string getArgs(void) { throw runtime_error("getArgs not implemented"); }
-  virtual string getPostData(void) { throw runtime_error("getPostData not implemented"); }
+  virtual const char* getQueryString() const { throw runtime_error("getQueryString not implemented"); }
+  virtual const char* getRequestBody() const { throw runtime_error("getRequestBody not implemented"); }
 };
 
 DWORD WriteClientError(PHTTP_FILTER_CONTEXT pfc, const char* msg)
@@ -535,7 +537,7 @@ extern "C" DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc, DWORD notificat
         else
             return WriteClientError(pfc,"Shibboleth Filter detected unexpected IIS error.");
     }
-    catch (SAMLException& e) {
+    catch (saml::SAMLException& e) {
         LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, e.what());
         return WriteClientError(pfc,"Shibboleth Filter caught an exception, check Event Log for details.");
     }
@@ -573,9 +575,11 @@ class ShibTargetIsapiE : public ShibTarget
 {
   LPEXTENSION_CONTROL_BLOCK m_lpECB;
   string m_cookie;
+  mutable string m_body;
+  mutable bool m_gotBody;
   
 public:
-  ShibTargetIsapiE(LPEXTENSION_CONTROL_BLOCK lpECB, const site_t& site) {
+  ShibTargetIsapiE(LPEXTENSION_CONTROL_BLOCK lpECB, const site_t& site) : m_gotBody(false) {
     dynabuf ssl(5);
     GetServerVariable(lpECB,"HTTPS",ssl,5);
     bool SSL=(ssl=="on" || ssl=="ON");
@@ -668,36 +672,40 @@ public:
     // Set the cookie for later.  Use it during the redirect.
     m_cookie += "Set-Cookie: " + name + "=" + value + "\r\n";
   }
-  virtual string getArgs(void) {
-    return string(m_lpECB->lpszQueryString ? m_lpECB->lpszQueryString : "");
+  virtual const char* getQueryString() const {
+    return m_lpECB->lpszQueryString;
   }
-  virtual string getPostData(void) {
+  virtual const char* getRequestBody() const {
+    if (m_gotBody)
+        return m_body.c_str();
     if (m_lpECB->cbTotalBytes > 1024*1024) // 1MB?
-      throw FatalProfileException("Blocked too-large a submission to profile endpoint.");
+        throw saml::SAMLException("Size of POST request body exceeded limit.");
     else if (m_lpECB->cbTotalBytes != m_lpECB->cbAvailable) {
-      string cgistr;
+      m_gotBody=true;
       char buf[8192];
       DWORD datalen=m_lpECB->cbTotalBytes;
       while (datalen) {
         DWORD buflen=8192;
         BOOL ret = m_lpECB->ReadClient(m_lpECB->ConnID, buf, &buflen);
         if (!ret || !buflen)
-          throw FatalProfileException("Error reading profile submission from browser.");
-        cgistr.append(buf, buflen);
+            throw saml::SAMLException("Error reading POST request body from browser.");
+        m_body.append(buf, buflen);
         datalen-=buflen;
       }
-      return cgistr;
     }
-    else
-      return string(reinterpret_cast<char*>(m_lpECB->lpbData),m_lpECB->cbAvailable);
+    else {
+        m_gotBody=true;
+        m_body.assign(reinterpret_cast<char*>(m_lpECB->lpbData),m_lpECB->cbAvailable);
+    }
+    return m_body.c_str();
   }
   virtual void* sendPage(
     const string &msg,
     int code=200,
     const string& content_type="text/html",
-    const Iterator<header_t>& headers=EMPTY(header_t)) {
+    const saml::Iterator<header_t>& headers=EMPTY(header_t)) {
     string hdr = string ("Connection: close\r\nContent-type: ") + content_type + "\r\n";
-    for (int k = 0; k < headers.size(); k++) {
+    for (unsigned int k = 0; k < headers.size(); k++) {
       hdr += headers[k].first + ": " + headers[k].second + "\r\n";
     }
     hdr += "\r\n";
@@ -777,7 +785,7 @@ extern "C" DWORD WINAPI HttpExtensionProc(LPEXTENSION_CONTROL_BLOCK lpECB)
         else
             return WriteClientError(lpECB,"Server detected unexpected IIS error.");
     }
-    catch (SAMLException& e) {
+    catch (saml::SAMLException& e) {
         LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, e.what());
         return WriteClientError(lpECB,"Shibboleth Extension caught an exception, check Event Log for details.");
     }