[shibboleth-sp2] 53/119: FastCGI support.

Ferenc Wágner wferi-guest at moszumanska.debian.org
Tue Jan 26 21:29:49 UTC 2016


This is an automated email from the git hooks/post-receive script.

wferi-guest pushed a commit to annotated tag 1.3.1
in repository shibboleth-sp2.

commit 7b6c3eac8b177baf7be67165c241f2584bf4be0a
Author: Scott Cantor <cantor.2 at osu.edu>
Date:   Fri Sep 14 19:03:08 2007 +0000

    FastCGI support.
---
 Shibboleth.dsw             |  62 +++++---
 fastcgi/.gitignore         |   5 +
 fastcgi/shibauthorizer.cpp | 350 +++++++++++++++++++++++++++++++++++++++++++++
 fastcgi/shibauthorizer.dsp |  90 ++++++++++++
 fastcgi/shibresponder.cpp  | 350 +++++++++++++++++++++++++++++++++++++++++++++
 fastcgi/shibresponder.dsp  |  90 ++++++++++++
 6 files changed, 929 insertions(+), 18 deletions(-)

diff --git a/Shibboleth.dsw b/Shibboleth.dsw
index 24656f0..ff84911 100644
--- a/Shibboleth.dsw
+++ b/Shibboleth.dsw
@@ -3,7 +3,7 @@ Microsoft Developer Studio Workspace File, Format Version 6.00
 
 ###############################################################################
 
-Project: "adfs"=.\adfs\adfs.dsp - Package Owner=<4>
+Project: "adfs"=".\adfs\adfs.dsp" - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -21,7 +21,7 @@ Package=<4>
 
 ###############################################################################
 
-Project: "isapi_shib"=.\isapi_shib\isapi_shib.dsp - Package Owner=<4>
+Project: "isapi_shib"=".\isapi_shib\isapi_shib.dsp" - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -39,7 +39,7 @@ Package=<4>
 
 ###############################################################################
 
-Project: "mod_shib13"=.\apache\mod_shib13.dsp - Package Owner=<4>
+Project: "mod_shib13"=".\apache\mod_shib13.dsp" - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -57,7 +57,7 @@ Package=<4>
 
 ###############################################################################
 
-Project: "mod_shib20"=.\apache\mod_shib20.dsp - Package Owner=<4>
+Project: "mod_shib20"=".\apache\mod_shib20.dsp" - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -75,7 +75,7 @@ Package=<4>
 
 ###############################################################################
 
-Project: "mod_shib22"=.\apache\mod_shib22.dsp - Package Owner=<4>
+Project: "mod_shib22"=".\apache\mod_shib22.dsp" - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -93,7 +93,7 @@ Package=<4>
 
 ###############################################################################
 
-Project: "nsapi_shib"=.\nsapi_shib\nsapi_shib.dsp - Package Owner=<4>
+Project: "nsapi_shib"=".\nsapi_shib\nsapi_shib.dsp" - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -111,7 +111,7 @@ Package=<4>
 
 ###############################################################################
 
-Project: "oncrpc"=.\oncrpc\oncrpc.dsp - Package Owner=<4>
+Project: "oncrpc"=".\oncrpc\oncrpc.dsp" - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -123,7 +123,7 @@ Package=<4>
 
 ###############################################################################
 
-Project: "posttest"=.\posttest\posttest.dsp - Package Owner=<4>
+Project: "posttest"=".\posttest\posttest.dsp" - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -138,7 +138,7 @@ Package=<4>
 
 ###############################################################################
 
-Project: "shar"=.\shar\shar.dsp - Package Owner=<4>
+Project: "shar"=".\shar\shar.dsp" - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -159,7 +159,7 @@ Package=<4>
 
 ###############################################################################
 
-Project: "shib"=.\shib\shib.dsp - Package Owner=<4>
+Project: "shib"=".\shib\shib.dsp" - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -189,6 +189,36 @@ Package=<4>
 
 ###############################################################################
 
+Project: "shibauthorizer"=".\fastcgi\shibauthorizer.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name shibtarget
+    End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "shibresponder"=".\fastcgi\shibresponder.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name shibtarget
+    End Project Dependency
+}}}
+
+###############################################################################
+
 Project: "shibtarget"=".\shib-target\shibtarget.dsp" - Package Owner=<4>
 
 Package=<5>
@@ -207,7 +237,7 @@ Package=<4>
 
 ###############################################################################
 
-Project: "shibtest"=.\shibtest\shibtest.dsp - Package Owner=<4>
+Project: "shibtest"=".\shibtest\shibtest.dsp" - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -225,7 +255,7 @@ Package=<4>
 
 ###############################################################################
 
-Project: "siterefresh"=.\siterefresh\siterefresh.dsp - Package Owner=<4>
+Project: "siterefresh"=".\siterefresh\siterefresh.dsp" - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -243,7 +273,7 @@ Package=<4>
 
 ###############################################################################
 
-Project: "testclient"=.\shar\testclient.dsp - Package Owner=<4>
+Project: "testclient"=".\shar\testclient.dsp" - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -264,7 +294,7 @@ Package=<4>
 
 ###############################################################################
 
-Project: "xmlproviders"=.\xmlproviders\xmlproviders.dsp - Package Owner=<4>
+Project: "xmlproviders"=".\xmlproviders\xmlproviders.dsp" - Package Owner=<4>
 
 Package=<5>
 {{{
@@ -286,10 +316,6 @@ Global:
 
 Package=<5>
 {{{
-    begin source code control
-    "$/NSAPI", WNAAAAAA
-    ..\..\..\..\documents and settings\cantor.2\my documents\projects\nsapi
-    end source code control
 }}}
 
 Package=<3>
diff --git a/fastcgi/.gitignore b/fastcgi/.gitignore
new file mode 100644
index 0000000..3f85816
--- /dev/null
+++ b/fastcgi/.gitignore
@@ -0,0 +1,5 @@
+/shibresponder___Win32_Debug
+/shibauthorizer___Win32_Release
+/shibauthorizer___Win32_Debug
+/shibresponder___Win32_Release
+/*.plg
diff --git a/fastcgi/shibauthorizer.cpp b/fastcgi/shibauthorizer.cpp
new file mode 100644
index 0000000..db16d85
--- /dev/null
+++ b/fastcgi/shibauthorizer.cpp
@@ -0,0 +1,350 @@
+/*
+ *  Copyright 2001-2007 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* shibauthorizer.cpp - Shibboleth FastCGI Authorizer
+
+   Andre Cruz
+*/
+
+// SAML Runtime
+#include <saml/saml.h>
+#include <shib-target/shib-target.h>
+
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# include <sys/mman.h>
+#endif
+#include <fcgio.h>
+
+using namespace shibtarget;
+using namespace saml;
+using namespace std;
+
+typedef enum {
+    SHIB_RETURN_OK,
+    SHIB_RETURN_KO,
+    SHIB_RETURN_DONE
+} shib_return_t;
+
+class ShibTargetFCGIAuth : public ShibTarget
+{
+    FCGX_Request* m_req;
+    string m_cookie;
+public:
+    map<string,string> m_headers;
+
+    ShibTargetFCGIAuth(FCGX_Request* req) : m_req(req) {
+        char* server_name_str = FCGX_GetParam("SHIBSP_SERVER_NAME", req->envp);
+        if (!server_name_str || !*server_name_str)
+            server_name_str = FCGX_GetParam("SERVER_NAME", req->envp);
+
+        char* server_port_str = FCGX_GetParam("SHIBSP_SERVER_PORT", req->envp);
+        if (!server_port_str || !*server_port_str)
+            server_port_str = FCGX_GetParam("SERVER_PORT", req->envp);
+        int server_port = strtol(server_port_str, &server_port_str, 10);
+        if (*server_port_str) {
+            cerr << "can't parse SERVER_PORT (" << FCGX_GetParam("SERVER_PORT", req->envp) << ")" << endl;
+            throw SAMLException("Unable to determine server port.");
+        }
+
+        char* server_scheme_str = FCGX_GetParam("SHIBSP_SERVER_SCHEME", req->envp);
+        if (!server_scheme_str || !*server_scheme_str)
+            server_scheme_str = (server_port == 443 || server_port == 8443) ? "https" : "http";
+
+        char* request_uri_str = FCGX_GetParam("REQUEST_URI", req->envp);
+        char* content_type_str = FCGX_GetParam("CONTENT_TYPE", req->envp);
+        char* remote_addr_str = FCGX_GetParam("REMOTE_ADDR", req->envp);
+        char* request_method_str = FCGX_GetParam("REQUEST_METHOD", req->envp);
+
+        init(server_scheme_str,
+             server_name_str,
+             server_port,
+             request_uri_str,
+             content_type_str ? content_type_str : "",
+             remote_addr_str,
+             request_method_str
+             );
+    }
+
+    ~ShibTargetFCGIAuth() { }
+
+    virtual void log(ShibLogLevel level, const string& msg) {
+        ShibTarget::log(level,msg);
+        if (level == LogLevelError)
+            cerr << "shib: " << msg;
+    }
+  
+    virtual string getCookies(void) const {
+        char* cookie = FCGX_GetParam("HTTP_COOKIE", m_req->envp);
+        return cookie ? cookie : "";
+    }
+  
+    virtual void setCookie(const string &name, const string &value) {
+        m_cookie += "Set-Cookie: " + name + "=" + value + "\r\n";
+    }
+
+      virtual string getArgs(void) {
+        char* args = FCGX_GetParam("QUERY_STRING", m_req->envp);
+        return args ? args : "";
+    }
+
+    virtual string getPostData(void) {
+        throw SAMLException("getPostData not implemented by FastCGI authorizer.");
+    }
+
+    virtual void clearHeader(const string& name) {
+        // no need, since request headers turn into actual environment variables
+    }
+  
+    virtual void setHeader(const string& name, const string &value) {
+        m_headers[name] = value;
+    }
+
+    virtual string getHeader(const string& name) {
+        if (m_headers.find(name) != m_headers.end())
+            return m_headers[name];
+        else
+            return "";
+    }
+
+    virtual void setRemoteUser(const string& user) {
+        m_headers["REMOTE_USER"] = user;
+    }
+
+    virtual string getRemoteUser(void) {
+        if (m_headers.find("REMOTE_USER") != m_headers.end())
+            return m_headers["REMOTE_USER"];
+        else {
+            char* remote_user = FCGX_GetParam("REMOTE_USER", m_req->envp);
+            if (remote_user)
+                return remote_user;
+        }
+        return "";
+    }
+
+    virtual void* sendPage(
+        const string& msg,
+        int code=200,
+        const string& content_type="text/html",
+        const Iterator<header_t>& headers=EMPTY(header_t)) {
+
+        string hdr = m_cookie + "Connection: close\r\nContent-type: " + content_type + "\r\n";
+        while (headers.hasNext()) {
+            const header_t& h=headers.next();
+            hdr += h.first + ": " + h.second + "\r\n";
+        }
+
+        // We can't return 200 OK here or else the filter is bypassed
+        // so custom Shib errors will get turned into a generic page.
+        const char* codestr="Status: 500 Server Error";
+        switch (code) {
+            case 403:   codestr="Status: 403 Forbidden"; break;
+            case 404:   codestr="Status: 404 Not Found"; break;
+        }
+
+        cout << codestr << "\r\n" << hdr << "\r\n" << msg;
+        return (void*)SHIB_RETURN_DONE;
+    }
+
+    virtual void* sendRedirect(const string& url) {
+        cout << "Status: 302 Please Wait" << "\r\n"
+             << "Location: " << url << "\r\n"
+             <<  m_cookie << "\r\n"
+             << "<HTML><BODY>Redirecting...</BODY></HTML>";
+        return (void*)SHIB_RETURN_DONE;
+    }
+
+    virtual void* returnDecline(void) { 
+        return (void*)SHIB_RETURN_KO;
+    }
+
+    virtual void* returnOK(void) {
+        return (void*)SHIB_RETURN_OK;
+    }
+};
+
+static void print_ok(const map<string,string>& headers)
+{
+    cout << "Status: 200 OK" << "\r\n";
+    for (map<string,string>::const_iterator iter = headers.begin(); iter != headers.end(); iter++) {
+        cout << "Variable-" << iter->first << ": " << iter->second << "\r\n";
+    }
+    cout << "\r\n";
+}
+
+static void print_error(const char* msg)
+{
+    cout << "Status: 500 Server Error" << "\r\n\r\n" << msg;
+}
+
+int main(void)
+{
+    char* shib_config = getenv("SHIB_CONFIG");
+    char* shib_schema = getenv("SHIB_SCHEMA");
+    if ((shib_config == NULL) || (shib_schema == NULL)) {
+      cerr << "SHIB_CONFIG or SHIB_SCHEMA not initialized!" << endl;
+      exit(1);
+    }
+    cerr << "SHIB_CONFIG = " << shib_config << endl
+         << "SHIB_SCHEMA = " << shib_schema << endl;
+
+    ShibTargetConfig* g_Config;
+
+    try {
+        g_Config = &ShibTargetConfig::getConfig();
+        g_Config->setFeatures(
+            ShibTargetConfig::Listener |
+            ShibTargetConfig::Metadata |
+            ShibTargetConfig::AAP |
+            ShibTargetConfig::RequestMapper |
+            ShibTargetConfig::LocalExtensions |
+            ShibTargetConfig::Logging
+            );
+        if (!g_Config->init(shib_schema)) {
+            cerr << "failed to initialize Shibboleth libraries" << endl;
+            exit(1);
+        }
+        
+        if (!g_Config->load(shib_config)) {
+            cerr << "failed to load Shibboleth configuration" << endl;
+            exit(1);
+        }
+    }
+    catch (...) {
+        cerr << "exception while initializing Shibboleth configuration" << endl;
+        exit(1);
+    }
+
+    streambuf* cout_streambuf = cout.rdbuf();
+    streambuf* cerr_streambuf = cerr.rdbuf();
+
+    FCGX_Request request;
+
+    FCGX_Init();
+    FCGX_InitRequest(&request, 0, 0);
+    
+    cout << "Shibboleth initialization complete. Starting request loop." << endl;
+    while (FCGX_Accept_r(&request) == 0)
+    {
+        // Note that the default bufsize (0) will cause the use of iostream
+        // methods that require positioning (such as peek(), seek(),
+        // unget() and putback()) to fail (in favour of more efficient IO).
+        fcgi_streambuf cout_fcgi_streambuf(request.out);
+        fcgi_streambuf cerr_fcgi_streambuf(request.err);
+
+        cout.rdbuf(&cout_fcgi_streambuf);
+        cerr.rdbuf(&cerr_fcgi_streambuf);
+
+        try {
+            saml::NDC ndc("FastCGI shibauthorizer");
+            ShibTargetFCGIAuth sta(&request);
+          
+            pair<bool,void*> res = sta.doCheckAuthN();
+            if (res.first) {
+#ifdef _DEBUG
+                cerr << "shib: doCheckAuthN handled the request" << endl;
+#endif
+                switch((int)res.second) {
+                    case SHIB_RETURN_OK:
+                        print_ok(sta.m_headers);
+                        continue;
+              
+                    case SHIB_RETURN_KO:
+                        print_ok(sta.m_headers);
+                        continue;
+
+                    case SHIB_RETURN_DONE:
+                        continue;
+              
+                    default:
+                        cerr << "shib: doCheckAuthN returned an unexpected result: " << (int)res.second << endl;
+                        print_error("<html><body>FastCGI Shibboleth authorizer returned an unexpected result.</body></html>");
+                        continue;
+                }
+            }
+          
+            res = sta.doExportAssertions();
+            if (res.first) {
+#ifdef _DEBUG
+                cerr << "shib: doExportAssertions handled request" << endl;
+#endif
+                switch((int)res.second) {
+                    case SHIB_RETURN_OK:
+                        print_ok(sta.m_headers);
+                        continue;
+              
+                    case SHIB_RETURN_KO:
+                        print_ok(sta.m_headers);
+                        continue;
+
+                    case SHIB_RETURN_DONE:
+                        continue;
+              
+                    default:
+                        cerr << "shib: doExportAssertions returned an unexpected result: " << (int)res.second << endl;
+                        print_error("<html><body>FastCGI Shibboleth authorizer returned an unexpected result.</body></html>");
+                        continue;
+                }
+            }
+
+            res = sta.doCheckAuthZ();
+            if (res.first) {
+#ifdef _DEBUG
+                cerr << "shib: doCheckAuthZ handled request" << endl;
+#endif
+                switch((int)res.second) {
+                    case SHIB_RETURN_OK:
+                        print_ok(sta.m_headers);
+                        continue;
+              
+                    case SHIB_RETURN_KO:
+                        print_ok(sta.m_headers);
+                        continue;
+
+                    case SHIB_RETURN_DONE:
+                        continue;
+              
+                    default:
+                        cerr << "shib: doCheckAuthZ returned an unexpected result: " << (int)res.second << endl;
+                        print_error("<html><body>FastCGI Shibboleth authorizer returned an unexpected result.</body></html>");
+                        continue;
+                }
+            }
+
+            print_ok(sta.m_headers);
+          
+        }
+        catch (SAMLException& e) {
+            cerr << "shib: FastCGI authorizer caught an exception: " << e.what() << endl;
+            print_error("<html><body>FastCGI Shibboleth authorizer caught an exception, check log for details.</body></html>");
+        }
+
+        // If the output streambufs had non-zero bufsizes and
+        // were constructed outside of the accept loop (i.e.
+        // their destructor won't be called here), they would
+        // have to be flushed here.
+    }
+    cout << "Request loop ended." << endl;
+
+    cout.rdbuf(cout_streambuf);
+    cerr.rdbuf(cerr_streambuf);
+
+    if (g_Config)
+        g_Config->shutdown();
+ 
+    return 0;
+}
diff --git a/fastcgi/shibauthorizer.dsp b/fastcgi/shibauthorizer.dsp
new file mode 100644
index 0000000..0d030a2
--- /dev/null
+++ b/fastcgi/shibauthorizer.dsp
@@ -0,0 +1,90 @@
+# Microsoft Developer Studio Project File - Name="shibauthorizer" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=shibauthorizer - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "shibauthorizer.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "shibauthorizer.mak" CFG="shibauthorizer - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "shibauthorizer - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "shibauthorizer - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "shibauthorizer - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "shibauthorizer___Win32_Release"
+# PROP Intermediate_Dir "shibauthorizer___Win32_Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "." /I ".." /I "..\..\cpp-opensaml1" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 xerces-c_2.lib saml_5.lib libfcgi.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\cpp-opensaml1\saml\Release" /libpath:"\fcgi-2.4.0\libfcgi\Release"
+
+!ELSEIF  "$(CFG)" == "shibauthorizer - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "shibauthorizer___Win32_Debug"
+# PROP BASE Intermediate_Dir "shibauthorizer___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "shibauthorizer___Win32_Debug"
+# PROP Intermediate_Dir "shibauthorizer___Win32_Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /I "." /I ".." /I "..\..\cpp-opensaml1" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 xerces-c_2D.lib saml_5D.lib libfcgi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\cpp-opensaml1\saml\Debug" /libpath:"\fcgi-2.4.0\libfcgi\Debug"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "shibauthorizer - Win32 Release"
+# Name "shibauthorizer - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\shibauthorizer.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/fastcgi/shibresponder.cpp b/fastcgi/shibresponder.cpp
new file mode 100644
index 0000000..682dcd5
--- /dev/null
+++ b/fastcgi/shibresponder.cpp
@@ -0,0 +1,350 @@
+/*
+ *  Copyright 2001-2007 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* shibresponder.cpp - Shibboleth FastCGI Responder/Handler
+
+   Andre Cruz
+*/
+
+// SAML Runtime
+#include <saml/saml.h>
+#include <shib-target/shib-target.h>
+
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# include <sys/mman.h>
+#endif
+#include <fcgio.h>
+
+using namespace shibtarget;
+using namespace saml;
+using namespace std;
+
+typedef enum {
+    SHIB_RETURN_OK,
+    SHIB_RETURN_KO,
+    SHIB_RETURN_DONE
+} shib_return_t;
+
+class ShibTargetFCGI : public ShibTarget
+{
+    FCGX_Request* m_req;
+    char* m_body;
+    string m_cookie;
+    map<string, string> m_headers;
+
+public:
+    ShibTargetFCGI(FCGX_Request* req, char* post_data) : m_req(req), m_body(post_data) {
+
+        char* server_name_str = FCGX_GetParam("SHIBSP_SERVER_NAME", req->envp);
+        if (!server_name_str || !*server_name_str)
+            server_name_str = FCGX_GetParam("SERVER_NAME", req->envp);
+
+        char* server_port_str = FCGX_GetParam("SHIBSP_SERVER_PORT", req->envp);
+        if (!server_port_str || !*server_port_str)
+            server_port_str = FCGX_GetParam("SERVER_PORT", req->envp);
+        int server_port = strtol(server_port_str, &server_port_str, 10);
+        if (*server_port_str) {
+            cerr << "can't parse SERVER_PORT (" << FCGX_GetParam("SERVER_PORT", req->envp) << ")" << endl;
+            throw SAMLException("Unable to determine server port.");
+        }
+
+        char* server_scheme_str = FCGX_GetParam("SHIBSP_SERVER_SCHEME", req->envp);
+        if (!server_scheme_str || !*server_scheme_str)
+            server_scheme_str = (server_port == 443 || server_port == 8443) ? "https" : "http";
+
+        char* request_uri_str = FCGX_GetParam("REQUEST_URI", req->envp);
+        char* content_type_str = FCGX_GetParam("CONTENT_TYPE", req->envp);
+        char* remote_addr_str = FCGX_GetParam("REMOTE_ADDR", req->envp);
+        char* request_method_str = FCGX_GetParam("REQUEST_METHOD", req->envp);
+
+#ifdef _DEBUG
+        cerr << "server_name = " << server_name_str << endl
+             << "server_port = " << server_port << endl
+             << "request_uri_str = " << request_uri_str << endl
+             << "content_type = " << content_type_str << endl
+             << "remote_address = " << remote_addr_str << endl
+             << "request_method = " << request_method_str << endl;
+#endif
+
+        init(server_scheme_str,
+             server_name_str,
+             server_port,
+             request_uri_str,
+             content_type_str ? content_type_str : "",
+             remote_addr_str,
+             request_method_str
+             );
+    }
+
+    ~ShibTargetFCGI() { }
+
+    virtual void log(ShibLogLevel level, const string& msg) {
+        ShibTarget::log(level,msg);
+    
+        if (level == LogLevelError)
+            cerr << "shib: " << msg;
+    }
+  
+    virtual string getCookies(void) const {
+        char * cookie = FCGX_GetParam("HTTP_COOKIE", m_req->envp);
+        return cookie ? cookie : "";
+    }
+  
+    virtual void setCookie(const string& name, const string& value) {
+        m_cookie += "Set-Cookie: " + name + "=" + value + "\r\n";
+    }
+
+    virtual string getArgs(void) {
+        char * args = FCGX_GetParam("QUERY_STRING", m_req->envp);
+        return args ? args : "";
+    }
+
+    virtual string getPostData(void) {
+        return m_body ? m_body : "";
+    }
+
+    virtual void clearHeader(const string &name) {
+        throw SAMLException("clearHeader not implemented by FastCGI responder.");
+    }
+  
+    virtual void setHeader(const string &name, const string &value) {
+        throw SAMLException("setHeader not implemented by FastCGI responder.");
+    }
+
+    virtual string getHeader(const string &name) {
+        throw SAMLException("getHeader not implemented by FastCGI responder.");
+    }
+
+    virtual void setRemoteUser(const string &user) {
+        throw SAMLException("setRemoteUser not implemented by FastCGI responder.");
+    }
+
+    virtual string getRemoteUser(void) {
+        throw SAMLException("getRemoteUser not implemented by FastCGI responder.");
+    }
+
+    virtual void* sendPage(
+        const string& msg,
+        int code=200,
+        const string& content_type="text/html",
+        const Iterator<header_t>& headers=EMPTY(header_t)) {
+
+        string hdr = string ("Connection: close\r\nContent-type: ") + content_type + "\r\n" + m_cookie;
+        while (headers.hasNext()) {
+            const header_t& h=headers.next();
+            hdr += h.first + ": " + h.second + "\r\n";
+        }
+
+        const char* codestr="Status: 200 OK";
+        switch (code) {
+            case 500:   codestr="Status: 500 Server Error"; break;
+            case 403:   codestr="Status: 403 Forbidden"; break;
+            case 404:   codestr="Status: 404 Not Found"; break;
+        }
+
+        cout << codestr << "\r\n" << hdr << m_cookie << "\r\n" << msg;
+        return (void*)SHIB_RETURN_DONE;
+    }
+
+    virtual void* sendRedirect(const string& url) {
+        cout << "Status: 302 Please Wait" << "\r\n" << "Location: " << url << "\r\n" << m_cookie << "\r\n"
+            << "<HTML><BODY>Redirecting...</BODY></HTML>";
+        return (void*)SHIB_RETURN_DONE;
+    }
+
+    virtual void* returnDecline(void) { 
+        return (void*)SHIB_RETURN_KO;
+    }
+
+    virtual void* returnOK(void) {
+        return (void*)SHIB_RETURN_OK;
+    }
+};
+
+// Maximum number of bytes allowed to be read from stdin
+static const unsigned long STDIN_MAX = 1000000;
+
+static long gstdin(FCGX_Request* request, char** content)
+{
+    char* clenstr = FCGX_GetParam("CONTENT_LENGTH", request->envp);
+    unsigned long clen = STDIN_MAX;
+
+    if (clenstr) {
+        clen = strtol(clenstr, &clenstr, 10);
+        if (*clenstr) {
+            cerr << "can't parse CONTENT_LENGTH (" << FCGX_GetParam("CONTENT_LENGTH", request->envp) << ")" << endl;
+            clen = STDIN_MAX;
+        }
+
+        // *always* put a cap on the amount of data that will be read
+        if (clen > STDIN_MAX)
+            clen = STDIN_MAX;
+
+        *content = new char[clen];
+
+        cin.read(*content, clen);
+        clen = cin.gcount();
+    }
+    else {
+        // *never* read stdin when CONTENT_LENGTH is missing or unparsable
+        *content = 0;
+        clen = 0;
+    }
+
+    // Chew up any remaining stdin - this shouldn't be necessary
+    // but is because mod_fastcgi doesn't handle it correctly.
+
+    // ignore() doesn't set the eof bit in some versions of glibc++
+    // so use gcount() instead of eof()...
+    do cin.ignore(1024); while (cin.gcount() == 1024);
+
+    return clen;
+}
+
+static void print_ok() {
+    cout << "Status: 200 OK" << "\r\n\r\n";
+}
+
+static void print_error(const char* msg) {
+    cout << "Status: 500 Server Error" << "\r\n\r\n" << msg;
+}
+
+int main(void)
+{
+    char* shib_config = getenv("SHIB_CONFIG");
+    char* shib_schema = getenv("SHIB_SCHEMA");
+    if ((shib_config == NULL) || (shib_schema == NULL)) {
+        cerr << "SHIB_CONFIG or SHIB_SCHEMA not set." << endl;
+        exit(1);
+    }
+    cerr << "SHIB_CONFIG = " << shib_config << endl
+         << "SHIB_SCHEMA = " << shib_schema << endl;
+
+    ShibTargetConfig* g_Config;
+
+    try {
+        g_Config = &ShibTargetConfig::getConfig();
+        g_Config->setFeatures(
+            ShibTargetConfig::Listener |
+            ShibTargetConfig::Metadata |
+            ShibTargetConfig::RequestMapper |
+            ShibTargetConfig::LocalExtensions |
+            ShibTargetConfig::Logging
+            );
+        if (!g_Config->init(shib_schema)) {
+            cerr << "failed to initialize Shibboleth libraries" << endl;
+            exit(1);
+        }
+        
+        if (!g_Config->load(shib_config)) {
+            cerr << "failed to load Shibboleth configuration" << endl;
+            exit(1);
+        }
+    }
+    catch (...) {
+        cerr << "exception while initializing Shibboleth configuration" << endl;
+        exit(1);
+    }
+
+    streambuf* cin_streambuf  = cin.rdbuf();
+    streambuf* cout_streambuf = cout.rdbuf();
+    streambuf* cerr_streambuf = cerr.rdbuf();
+
+    FCGX_Request request;
+
+    FCGX_Init();
+    FCGX_InitRequest(&request, 0, 0);
+    
+    cout << "Shibboleth initialization complete. Starting request loop." << endl;
+    while (FCGX_Accept_r(&request) == 0) {
+        // Note that the default bufsize (0) will cause the use of iostream
+        // methods that require positioning (such as peek(), seek(),
+        // unget() and putback()) to fail (in favour of more efficient IO).
+        fcgi_streambuf cin_fcgi_streambuf(request.in);
+        fcgi_streambuf cout_fcgi_streambuf(request.out);
+        fcgi_streambuf cerr_fcgi_streambuf(request.err);
+
+        cin.rdbuf(&cin_fcgi_streambuf);
+        cout.rdbuf(&cout_fcgi_streambuf);
+        cerr.rdbuf(&cerr_fcgi_streambuf);
+
+        // Although FastCGI supports writing before reading,
+        // many http clients (browsers) don't support it (so
+        // the connection deadlocks until a timeout expires!).
+        char* content;
+        gstdin(&request, &content);
+
+        try {
+            saml::NDC ndc("FastCGI shibresponder");
+            ShibTargetFCGI stf(&request, content);
+          
+            pair<bool,void*> res = stf.doHandler();
+            if (res.first) {
+#ifdef _DEBUG
+                cerr << "shib: doHandler handled the request" << endl;
+#endif
+                switch((int)res.second) {
+                    case SHIB_RETURN_OK:
+                        print_ok();
+                        break;
+              
+                    case SHIB_RETURN_KO:
+                        cerr << "shib: doHandler failed to handle the request" << endl;
+                        print_error("<html><body>FastCGI Shibboleth responder should only be used for Shibboleth protocol requests.</body></html>");
+                        break;
+
+                    case SHIB_RETURN_DONE:
+                        // response already handled
+                        break;
+              
+                    default:
+                        cerr << "shib: doHandler returned an unexpected result: " << (int)res.second << endl;
+                        print_error("<html><body>FastCGI Shibboleth responder returned an unexpected result.</body></html>");
+                        break;
+                }
+            }
+            else {
+                cerr << "shib: doHandler failed to handle request." << endl;
+                print_error("<html><body>FastCGI Shibboleth responder failed to process request.</body></html>");
+            }          
+          
+        }
+        catch (SAMLException& e) {
+            cerr << "shib: FastCGI responder caught an exception: " << e.what() << endl;
+            print_error("<html><body>FastCGI Shibboleth responder caught an exception, check log for details.</body></html>");
+        }
+
+        delete[] content;
+
+        // If the output streambufs had non-zero bufsizes and
+        // were constructed outside of the accept loop (i.e.
+        // their destructor won't be called here), they would
+        // have to be flushed here.
+    }
+
+    cout << "Request loop ended." << endl;
+
+    cin.rdbuf(cin_streambuf);
+    cout.rdbuf(cout_streambuf);
+    cerr.rdbuf(cerr_streambuf);
+
+    if (g_Config)
+        g_Config->shutdown();
+ 
+    return 0;
+}
diff --git a/fastcgi/shibresponder.dsp b/fastcgi/shibresponder.dsp
new file mode 100644
index 0000000..dca121e
--- /dev/null
+++ b/fastcgi/shibresponder.dsp
@@ -0,0 +1,90 @@
+# Microsoft Developer Studio Project File - Name="shibresponder" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=shibresponder - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "shibresponder.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "shibresponder.mak" CFG="shibresponder - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "shibresponder - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "shibresponder - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "shibresponder - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "shibresponder___Win32_Release"
+# PROP Intermediate_Dir "shibresponder___Win32_Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "." /I ".." /I "..\..\cpp-opensaml1" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 xerces-c_2.lib saml_5.lib libfcgi.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\cpp-opensaml1\saml\Release" /libpath:"\fcgi-2.4.0\libfcgi\Release"
+
+!ELSEIF  "$(CFG)" == "shibresponder - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "shibresponder___Win32_Debug"
+# PROP BASE Intermediate_Dir "shibresponder___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "shibresponder___Win32_Debug"
+# PROP Intermediate_Dir "shibresponder___Win32_Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ  /c
+# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /I "." /I ".." /I "..\..\cpp-opensaml1" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ  /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 xerces-c_2D.lib saml_5D.lib libfcgi.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\cpp-opensaml1\saml\Debug" /libpath:"\fcgi-2.4.0\libfcgi\Debug"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "shibresponder - Win32 Release"
+# Name "shibresponder - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\shibresponder.cpp
+# End Source File
+# End Target
+# End Project

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-shibboleth/shibboleth-sp2.git



More information about the Pkg-shibboleth-devel mailing list