[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