Next integration phase, metadata and trust conversion.
[shibboleth/cpp-sp.git] / isapi_shib / isapi_shib.cpp
index ec34ff8..0636687 100644 (file)
 
 #include "config_win32.h"
 
+#define _CRT_NONSTDC_NO_DEPRECATE 1
+#define _CRT_SECURE_NO_DEPRECATE 1
+
+#include <shibsp/SPConfig.h>
+
 // SAML Runtime
 #include <saml/saml.h>
 #include <shib/shib.h>
-#include <shib/shib-threads.h>
 #include <shib-target/shib-target.h>
 
 #include <ctime>
 #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 +75,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());
@@ -152,13 +156,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;
@@ -175,8 +180,8 @@ 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) {
             const DOMElement* impl=saml::XML::getFirstChildElement(
                 props->getElement(),shibtarget::XML::SHIBTARGET_NS,Implementation
@@ -397,7 +402,7 @@ public:
   }
   
   virtual void clearHeader(const string &name) {
-    string hdr = name + ":";
+    string hdr = (name=="REMOTE_USER" ? "remote-user" : name) + ":";
     m_pn->SetHeader(m_pfc, const_cast<char*>(hdr.c_str()), "");
   }
   virtual void setHeader(const string &name, const string &value) {
@@ -421,7 +426,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();
@@ -462,8 +467,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)
@@ -531,15 +536,19 @@ extern "C" DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc, DWORD notificat
         if (e==ERROR_NO_DATA)
             return WriteClientError(pfc,"A required variable or header was empty.");
         else
-            return WriteClientError(pfc,"Server detected unexpected IIS error.");
+            return WriteClientError(pfc,"Shibboleth Filter detected unexpected IIS error.");
+    }
+    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.");
     }
 #ifndef _DEBUG
     catch(...) {
-        return WriteClientError(pfc,"Server caught an unknown exception.");
+        return WriteClientError(pfc,"Shibboleth Filter caught an unknown exception.");
     }
 #endif
 
-    return WriteClientError(pfc,"Server reached unreachable code, save my walrus!");
+    return WriteClientError(pfc,"Shibboleth Filter reached unreachable code, save my walrus!");
 }
         
 
@@ -567,9 +576,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");
@@ -662,36 +673,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";
@@ -771,9 +786,13 @@ extern "C" DWORD WINAPI HttpExtensionProc(LPEXTENSION_CONTROL_BLOCK lpECB)
         else
             return WriteClientError(lpECB,"Server detected unexpected IIS error.");
     }
+    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.");
+    }
 #ifndef _DEBUG
     catch(...) {
-        return WriteClientError(lpECB,"Server caught an unknown exception.");
+        return WriteClientError(lpECB,"Shibboleth Extension caught an unknown exception.");
     }
 #endif