Try to use that class in the apache2 world.
uncomment the default applications.xml in the .ini file
add more debugging in the shib-config.
note: this breaks apache2 completely!
modshibdir = $(libexecdir)
modshib_LTLIBRARIES = mod_shib.la
-mod_shib_la_SOURCES = mod_shib.cpp
+mod_shib_la_SOURCES = mod_shib.cpp cgiparse.cpp
+noinst_HEADERS = cgiparse.h
AM_CXXFLAGS = $(APXS2_CFLAGS) -I$(APXS2_INCLUDE) $(RPC_CFLAGS)
--- /dev/null
+/*
+ * The Shibboleth License, Version 1.
+ * Copyright (c) 2002
+ * University Corporation for Advanced Internet Development, Inc.
+ * All rights reserved
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution, if any, must include
+ * the following acknowledgment: "This product includes software developed by
+ * the University Corporation for Advanced Internet Development
+ * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
+ * may appear in the software itself, if and wherever such third-party
+ * acknowledgments normally appear.
+ *
+ * Neither the name of Shibboleth nor the names of its contributors, nor
+ * Internet2, nor the University Corporation for Advanced Internet Development,
+ * Inc., nor UCAID may be used to endorse or promote products derived from this
+ * software without specific prior written permission. For written permission,
+ * please contact shibboleth@shibboleth.org
+ *
+ * Products derived from this software may not be called Shibboleth, Internet2,
+ * UCAID, or the University Corporation for Advanced Internet Development, nor
+ * may Shibboleth appear in their name, without prior written permission of the
+ * University Corporation for Advanced Internet Development.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
+ * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* cgiparse.cpp - URL-encoded parameter parsing
+
+ Scott Cantor
+ 7/6/03
+
+ Derek Atkins <derek@ihtfp.com>
+ 2004-02-25
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <map>
+
+#include "cgiparse.h"
+
+using namespace shibtarget;
+using namespace std;
+
+class CgiParseImpl {
+public:
+ CgiParseImpl(string& cgi);
+ ~CgiParseImpl() {};
+ const char * get_value(const string& name) const;
+
+private:
+ map<string,string> kvp_map;
+};
+
+
+namespace {
+
+/* Parsing routines modified from NCSA source. */
+char *makeword(char *line, char stop)
+{
+ int x = 0,y;
+ char *word = (char *) malloc(sizeof(char) * (strlen(line) + 1));
+
+ for(x=0;((line[x]) && (line[x] != stop));x++)
+ word[x] = line[x];
+
+ word[x] = '\0';
+ if(line[x])
+ ++x;
+ y=0;
+
+ while(line[y++] = line[x++]);
+ return word;
+}
+
+char *fmakeword(char stop, int *cl, const char** ppch)
+{
+ int wsize;
+ char *word;
+ int ll;
+
+ wsize = 1024;
+ ll=0;
+ word = (char *) malloc(sizeof(char) * (wsize + 1));
+
+ while(1)
+ {
+ word[ll] = *((*ppch)++);
+ if(ll==wsize-1)
+ {
+ word[ll+1] = '\0';
+ wsize+=1024;
+ word = (char *)realloc(word,sizeof(char)*(wsize+1));
+ }
+ --(*cl);
+ if((word[ll] == stop) || word[ll] == EOF || (!(*cl)))
+ {
+ if(word[ll] != stop)
+ ll++;
+ word[ll] = '\0';
+ return word;
+ }
+ ++ll;
+ }
+}
+
+char x2c(char *what)
+{
+ register char digit;
+
+ digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0'));
+ digit *= 16;
+ digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0'));
+ return(digit);
+}
+
+void unescape_url(char *url)
+{
+ register int x,y;
+
+ for(x=0,y=0;url[y];++x,++y)
+ {
+ if((url[x] = url[y]) == '%')
+ {
+ url[x] = x2c(&url[y+1]);
+ y+=2;
+ }
+ }
+ url[x] = '\0';
+}
+
+void plustospace(char *str)
+{
+ register int x;
+
+ for(x=0;str[x];x++)
+ if(str[x] == '+') str[x] = ' ';
+}
+
+}; // end of private namespace
+
+CgiParseImpl::CgiParseImpl(string& cgi)
+{
+ int cl;
+ const char* pch;
+
+#if 0
+ /* Verify method and content type. */
+ if(!stricmp(lpECB->lpszMethod,"POST"))
+ {
+ if (stricmp(lpECB->lpszContentType,"application/x-www-form-urlencoded"))
+ return NULL;
+ pch=lpECB->lpbData;
+ cl=lpECB->cbAvailable;
+ }
+ else if (!stricmp(lpECB->lpszMethod,"GET"))
+ {
+ pch=lpECB->lpszQueryString;
+ cl=strlen(pch);
+ }
+ else
+ return NULL;
+#endif
+
+ pch = cgi.c_str();
+ cl = strlen(pch);
+
+ while (cl && pch)
+ {
+ char *name;
+ char *value;
+ value=fmakeword('&',&cl,&pch);
+ plustospace(value);
+ unescape_url(value);
+ name=makeword(value,'=');
+
+ kvp_map[name]=value;
+ free(name);
+ free(value);
+ }
+}
+
+
+const char *
+CgiParseImpl::get_value(const string& name) const
+{
+ map<string,string>::const_iterator i=kvp_map.find(name);
+ if (i==kvp_map.end())
+ return NULL;
+
+ return i->second.c_str();
+}
+
+CgiParse*
+CgiParse::ParseCGI(string& cgi)
+{
+ return (CgiParse*)(new CgiParseImpl(cgi));
+}
--- /dev/null
+/*
+ * The Shibboleth License, Version 1.
+ * Copyright (c) 2002
+ * University Corporation for Advanced Internet Development, Inc.
+ * All rights reserved
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution, if any, must include
+ * the following acknowledgment: "This product includes software developed by
+ * the University Corporation for Advanced Internet Development
+ * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
+ * may appear in the software itself, if and wherever such third-party
+ * acknowledgments normally appear.
+ *
+ * Neither the name of Shibboleth nor the names of its contributors, nor
+ * Internet2, nor the University Corporation for Advanced Internet Development,
+ * Inc., nor UCAID may be used to endorse or promote products derived from this
+ * software without specific prior written permission. For written permission,
+ * please contact shibboleth@shibboleth.org
+ *
+ * Products derived from this software may not be called Shibboleth, Internet2,
+ * UCAID, or the University Corporation for Advanced Internet Development, nor
+ * may Shibboleth appear in their name, without prior written permission of the
+ * University Corporation for Advanced Internet Development.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
+ * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* cgiparse.h - URL-encoded parameter parsing
+
+ Scott Cantor
+ 7/6/03
+
+ Derek Atkins <derek@ihtfp.com>
+ 2004-02-25
+*/
+
+#ifndef __CGIPARSE__
+#define __CGIPARSE__
+
+#include <string>
+
+namespace shibtarget {
+
+ class CgiParse {
+ public:
+ virtual ~CgiParse() { };
+ virtual const char * get_value(const std::string& name) const = 0;
+
+ const char * get_value(const char* name) const {
+ std::string val(name ? name : "");
+ return get_value(val);
+ };
+
+ static CgiParse* ParseCGI(std::string& input);
+ };
+}
+
+#endif /* __CGIPARSE__ */
//-- do we still need this? #undef _XOPEN_SOURCE // bombs on solaris
#include <apreq_params.h>
+#include "cgiparse.h"
+
#include <unistd.h> // for getpid()
using namespace std;
ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,0,r,
"shire_post_handler() Beginning SHIRE POST processing");
+ CgiParse* cgi = NULL;
+
try {
string sslonly;
if (!ini.get_tag(application_id, "shireSSLOnly", true, &sslonly))
throw ShibTargetException (SHIBRPC_OK,
"blocked too-large a post to SHIRE POST processor");
+ ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,0,r,
+ "shire_post_handler() about to run setup_client_block");
+
// Read the posted data
- apreq_request_t *ap_req = apreq_request(r, NULL);
- if (!ap_req)
- throw ShibTargetException (SHIBRPC_OK,
- apr_psprintf(r->pool, "apreq_request() failed"));
+ if (ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))
+ throw ShibTargetException (SHIBRPC_OK, "CGI setup_client_block failed");
+
+ ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,0,r,
+ "shire_post_handler() about to run should_client_block");
+
+ if (!ap_should_client_block(r))
+ throw ShibTargetException (SHIBRPC_OK, "CGI should_client_block failed");
+
+ long length = r->remaining;
+ if (length > 1024*1024)
+ throw ShibTargetException (SHIBRPC_OK, "CGI length too long...");
+
+ ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,0,r,
+ "shire_post_handler() about to read using get_client_block");
+ string cgistr;
+ char buff[BUFSIZ];
+ //ap_hard_timeout("[mod_shib] CGI Parser", r);
+
+ while (ap_get_client_block(r, buff, sizeof(buff)) > 0)
+ cgistr += buff;
+
+ //ap_kill_timeout(r);
+
+ ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,0,r,
+ "shire_post_handler() about to parse cgi...");
+
+ cgi = CgiParse::ParseCGI(cgistr);
+
+ ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,0,r,
+ "shire_post_handler() CGI parsed...");
+
+ if (!cgi)
+ throw ShibTargetException (SHIBRPC_OK, "CgiParse failed");
// Make sure the target parameter exists
- apreq_param_t *param = apreq_param(ap_req, "TARGET");
- const char *target = param ? apreq_param_value(param) : NULL;
+ const string target_str = cgi->get_value("TARGET");
+
+ ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,0,r,
+ "shire_post_handler() obtained target string from CGI...");
+
+ const char *target = target_str.c_str();
+
+ ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,0,r,
+ "shire_post_handler() obtained target...");
+
if (!target || *target == '\0')
// invalid post
throw ShibTargetException (SHIBRPC_OK,
"SHIRE POST failed to find TARGET");
+ ap_log_rerror(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,0,r,
+ "shire_post_handler() obtained target...");
+
// Make sure the SAML Response parameter exists
- param = apreq_param(ap_req, "SAMLResponse");
- const char *post = param ? apreq_param_value(param) : NULL;
+ const string poststr = cgi->get_value("SAMLResponse");
+ const char *post = poststr.c_str();
if (!post || *post == '\0')
// invalid post
throw ShibTargetException (SHIBRPC_OK,
// ... and redirect to the target
char* redir=apr_pstrcat(r->pool,url_encode(r,target),NULL);
apr_table_setn(r->headers_out, "Location", target);
+ delete cgi;
return HTTP_MOVED_TEMPORARILY;
} catch (ShibTargetException &e) {
markupProcessor.insert ("errorType", "SHIRE Processing Error");
markupProcessor.insert ("errorText", e.what());
markupProcessor.insert ("errorDesc", "An error occurred while processing your request.");
+ if (cgi) delete cgi;
return shib_error_page (r, shireError.c_str(), markupProcessor);
}
catch (...) {
markupProcessor.insert ("errorType", "SHIRE Processing Error");
markupProcessor.insert ("errorText", "Unexpected Exception");
markupProcessor.insert ("errorDesc", "An error occurred while processing your request.");
+ if (cgi) delete cgi;
return shib_error_page (r, shireError.c_str(), markupProcessor);
}
[shire]
logger=@-PKGSYSCONFDIR-@/shire.logger
-#applicationMap=@-PKGSYSCONFDIR-@/applications.xml
+applicationMap=@-PKGSYSCONFDIR-@/applications.xml
[shar]
logger=@-PKGSYSCONFDIR-@/shar.logger
delete iter;
}
- if (app == SHIBTARGET_SHIRE && ini->get_tag(app, SHIBTARGET_TAG_APPMAPPER, false, &tag)) {
- saml::XML::registerSchema(shibtarget::XML::APPMAP_NS,shibtarget::XML::APPMAP_SCHEMA_ID);
- try {
+ log.debug("about to test for AppMapper -- are we SHIRE...");
+ if (app == SHIBTARGET_SHIRE) {
+ log.debug("yep, we're a shire -- try loading the map...");
+ if (ini->get_tag(app, SHIBTARGET_TAG_APPMAPPER, false, &tag)) {
+ log.debug("loading Application Mapper");
+ saml::XML::registerSchema(shibtarget::XML::APPMAP_NS,shibtarget::XML::APPMAP_SCHEMA_ID);
+ try {
auto_ptr_XMLCh src(tag.c_str());
dummy->setAttributeNS(NULL,shibboleth::XML::Literals::url,src.get());
m_applicationMapper=new XMLApplicationMapper(dummy);
dynamic_cast<XMLApplicationMapper*>(m_applicationMapper)->getImplementation();
- }
- catch (exception& e) {
+ }
+ catch (exception& e) {
log.crit("caught exception while loading URL->Application mapping file (%s)", e.what());
- }
- catch (...) {
+ }
+ catch (...) {
log.crit("caught unknown exception while loading URL->Application mapping file");
+ }
}
}