Added redirectToSSL option to block non-SSL access.
[shibboleth/sp.git] / nsapi_shib / nsapi_shib.cpp
index b7424c6..0cfd095 100644 (file)
    12/13/04
 */
 
-#include "config_win32.h"
+#if defined (_MSC_VER) || defined(__BORLANDC__)
+# include "config_win32.h"
+#else
+# include "config.h"
+#endif
+
+#ifdef WIN32
+# define _CRT_NONSTDC_NO_DEPRECATE 1
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+
 
 // SAML Runtime
 #include <saml/saml.h>
@@ -116,10 +126,11 @@ extern "C" NSAPI_PUBLIC int nsapi_shib_init(pblock* pb, Session* sn, Request* rq
         g_Config=&ShibTargetConfig::getConfig();
         g_Config->setFeatures(
             ShibTargetConfig::Listener |
+            ShibTargetConfig::Caching |
             ShibTargetConfig::Metadata |
             ShibTargetConfig::AAP |
             ShibTargetConfig::RequestMapper |
-            ShibTargetConfig::LocalExtensions |
+            ShibTargetConfig::InProcess |
             ShibTargetConfig::Logging
             );
         if (!g_Config->init(schemadir)) {
@@ -155,8 +166,10 @@ extern "C" NSAPI_PUBLIC int nsapi_shib_init(pblock* pb, Session* sn, Request* rq
 
 class ShibTargetNSAPI : public ShibTarget
 {
+    mutable string m_body;
+    mutable bool m_gotBody;
 public:
-  ShibTargetNSAPI(pblock* pb, Session* sn, Request* rq) {
+  ShibTargetNSAPI(pblock* pb, Session* sn, Request* rq) : m_gotBody(false) {
     m_pb = pb;
     m_sn = sn;
     m_rq = rq;
@@ -210,31 +223,31 @@ public:
     string cookie = name + '=' + value;
     pblock_nvinsert("Set-Cookie", cookie.c_str(), m_rq->srvhdrs);
   }
-  virtual string getArgs(void) { 
-    const char *q = pblock_findval("query", m_rq->reqpb);
-    return string(q ? q : "");
+  virtual const char* getQueryString() const { 
+    return pblock_findval("query", m_rq->reqpb);
   }
-  virtual string getPostData(void) {
+  virtual const char* getRequestBody() const {
+    if (m_gotBody)
+        return m_body.c_str();
     char* content_length=NULL;
     if (request_header("content-length", &content_length, m_sn, m_rq)!=REQ_PROCEED ||
          atoi(content_length) > 1024*1024) // 1MB?
-      throw FatalProfileException("Blocked too-large a submission to profile endpoint.");
+      throw SAMLException("Blocked POST request body exceeding size limit.");
     else {
       char ch=IO_EOF+1;
       int cl=atoi(content_length);
-      string cgistr;
+      m_gotBody=true;
       while (cl && ch != IO_EOF) {
         ch=netbuf_getc(m_sn->inbuf);
-      
         // Check for error.
         if(ch==IO_ERROR)
           break;
-        cgistr += ch;
+        m_body += ch;
         cl--;
       }
       if (cl)
-        throw FatalProfileException("Error reading profile submission from browser.");
-      return cgistr;
+        throw SAMLException("Error reading POST request body from browser.");
+      return m_body.c_str();
     }
   }
   virtual void clearHeader(const string &name) {
@@ -287,6 +300,7 @@ public:
     pblock_nvinsert("expires", "01-Jan-1997 12:00:00 GMT", m_rq->srvhdrs);
     pblock_nvinsert("cache-control", "private,no-store,no-cache", m_rq->srvhdrs);
     pblock_nvinsert("location", url.c_str(), m_rq->srvhdrs);
+    pblock_nvinsert("connection","close",m_rq->srvhdrs);
     protocol_status(m_sn, m_rq, PROTOCOL_REDIRECT, NULL);
     protocol_start_response(m_sn, m_rq);
     return (void*)REQ_ABORTED;
@@ -464,13 +478,27 @@ pair<bool,const XMLCh*> SunRequestMapper::getXMLString(const char* name, const c
 
 pair<bool,unsigned int> SunRequestMapper::getUnsignedInt(const char* name, const char* ns) const
 {
+    ShibTargetNSAPI* stn=reinterpret_cast<ShibTargetNSAPI*>(m_stKey->getData());
     const IPropertySet* s=reinterpret_cast<const IPropertySet*>(m_propsKey->getData());
+    if (stn && !ns && name) {
+        // Override int properties.
+        const char* param=pblock_findval(name,stn->m_pb);
+        if (param)
+            return pair<bool,unsigned int>(true,strtol(param,NULL,10));
+    }
     return s ? s->getUnsignedInt(name,ns) : pair<bool,unsigned int>(false,0);
 }
 
 pair<bool,int> SunRequestMapper::getInt(const char* name, const char* ns) const
 {
+    ShibTargetNSAPI* stn=reinterpret_cast<ShibTargetNSAPI*>(m_stKey->getData());
     const IPropertySet* s=reinterpret_cast<const IPropertySet*>(m_propsKey->getData());
+    if (stn && !ns && name) {
+        // Override int properties.
+        const char* param=pblock_findval(name,stn->m_pb);
+        if (param)
+            return pair<bool,int>(true,atoi(param));
+    }
     return s ? s->getInt(name,ns) : pair<bool,int>(false,0);
 }