/*
- * Copyright 2001-2005 Internet2
+ * 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.
* Shibboleth ISAPI filter
*/
+#define SHIBSP_LITE
#include "config_win32.h"
#define _CRT_NONSTDC_NO_DEPRECATE 1
#include <shibsp/AbstractSPRequest.h>
#include <shibsp/SPConfig.h>
+#include <shibsp/ServiceProvider.h>
+#include <xmltooling/unicode.h>
+#include <xmltooling/XMLToolingConfig.h>
#include <xmltooling/util/NDC.h>
+#include <xmltooling/util/XMLConstants.h>
+#include <xmltooling/util/XMLHelper.h>
+#include <xercesc/util/XMLUniDefs.hpp>
-// SAML Runtime
-#include <saml/saml.h>
-#include <shib/shib.h>
-#include <shib-target/shib-target.h>
-
+#include <set>
#include <sstream>
#include <fstream>
#include <process.h>
+#include <windows.h>
#include <httpfilt.h>
#include <httpext.h>
using namespace shibsp;
using namespace xmltooling;
+using namespace xercesc;
using namespace std;
// globals
namespace {
+ static const XMLCh path[] = UNICODE_LITERAL_4(p,a,t,h);
+ static const XMLCh validate[] = UNICODE_LITERAL_8(v,a,l,i,d,a,t,e);
static const XMLCh name[] = UNICODE_LITERAL_4(n,a,m,e);
static const XMLCh port[] = UNICODE_LITERAL_4(p,o,r,t);
static const XMLCh sslport[] = UNICODE_LITERAL_7(s,s,l,p,o,r,t);
};
HINSTANCE g_hinstDLL;
- shibtarget::ShibTargetConfig* g_Config = NULL;
+ SPConfig* g_Config = NULL;
map<string,site_t> g_Sites;
bool g_bNormalizeRequest = true;
}
return TRUE;
}
-#ifndef _DEBUG
- try
- {
-#endif
- LPCSTR schemadir=getenv("SHIBSCHEMAS");
- if (!schemadir)
- schemadir=SHIB_SCHEMAS;
- LPCSTR config=getenv("SHIBCONFIG");
- if (!config)
- config=SHIB_CONFIG;
- g_Config=&shibtarget::ShibTargetConfig::getConfig();
- SPConfig::getConfig().setFeatures(
- SPConfig::Listener |
- SPConfig::Caching |
- SPConfig::Metadata |
- SPConfig::AAP |
- SPConfig::RequestMapping |
- SPConfig::InProcess |
- SPConfig::Logging
- );
- if (!g_Config->init(schemadir)) {
- g_Config=NULL;
- LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,
- "Filter startup failed during library initialization, check native log for help.");
- return FALSE;
- }
- else if (!g_Config->load(config)) {
- g_Config=NULL;
- LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,
- "Filter startup failed to load configuration, check native log for help.");
- return FALSE;
- }
-
- // Access the implementation-specifics for site mappings.
- ServiceProvider* conf=SPConfig::getConfig().getServiceProvider();
- xmltooling::Locker locker(conf);
- const PropertySet* props=conf->getPropertySet("Local");
- if (props) {
- const DOMElement* impl=XMLHelper::getFirstChildElement(props->getElement(),Implementation);
- if (impl && (impl=XMLHelper::getFirstChildElement(impl,ISAPI))) {
- const XMLCh* flag=impl->getAttributeNS(NULL,normalizeRequest);
- g_bNormalizeRequest=(!flag || !*flag || *flag==chDigit_1 || *flag==chLatin_t);
- impl=XMLHelper::getFirstChildElement(impl,Site);
- while (impl) {
- auto_ptr_char id(impl->getAttributeNS(NULL,id));
- if (id.get())
- g_Sites.insert(pair<string,site_t>(id.get(),site_t(impl)));
- impl=XMLHelper::getNextSiblingElement(impl,Site);
- }
- }
- }
-#ifndef _DEBUG
+ LPCSTR schemadir=getenv("SHIBSP_SCHEMAS");
+ if (!schemadir)
+ schemadir=SHIBSP_SCHEMAS;
+ LPCSTR config=getenv("SHIBSP_CONFIG");
+ if (!config)
+ config=SHIBSP_CONFIG;
+ g_Config=&SPConfig::getConfig();
+ g_Config->setFeatures(
+ SPConfig::Listener |
+ SPConfig::Caching |
+ SPConfig::RequestMapping |
+ SPConfig::InProcess |
+ SPConfig::Logging
+ );
+ if (!g_Config->init(schemadir)) {
+ g_Config=NULL;
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,
+ "Filter startup failed during library initialization, check native log for help.");
+ return FALSE;
}
- catch (...)
- {
- LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, "Filter startup failed with an exception.");
+
+ try {
+ DOMDocument* dummydoc=XMLToolingConfig::getConfig().getParser().newDocument();
+ XercesJanitor<DOMDocument> docjanitor(dummydoc);
+ DOMElement* dummy = dummydoc->createElementNS(NULL,path);
+ auto_ptr_XMLCh src(config);
+ dummy->setAttributeNS(NULL,path,src.get());
+ dummy->setAttributeNS(NULL,validate,xmlconstants::XML_ONE);
+
+ g_Config->setServiceProvider(g_Config->ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER,dummy));
+ g_Config->getServiceProvider()->init();
+ }
+ catch (exception& ex) {
+ g_Config->term();
+ g_Config=NULL;
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL, ex.what());
+ LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,
+ "Filter startup failed to load configuration, check native log for details.");
return FALSE;
}
-#endif
+
+ // Access the implementation-specifics for site mappings.
+ ServiceProvider* sp=g_Config->getServiceProvider();
+ xmltooling::Locker locker(sp);
+ const PropertySet* props=sp->getPropertySet("Local");
+ if (props) {
+ const DOMElement* impl=XMLHelper::getFirstChildElement(props->getElement(),Implementation);
+ if (impl && (impl=XMLHelper::getFirstChildElement(impl,ISAPI))) {
+ const XMLCh* flag=impl->getAttributeNS(NULL,normalizeRequest);
+ g_bNormalizeRequest=(!flag || !*flag || *flag==chDigit_1 || *flag==chLatin_t);
+ impl=XMLHelper::getFirstChildElement(impl,Site);
+ while (impl) {
+ auto_ptr_char id(impl->getAttributeNS(NULL,id));
+ if (id.get())
+ g_Sites.insert(pair<string,site_t>(id.get(),site_t(impl)));
+ impl=XMLHelper::getNextSiblingElement(impl,Site);
+ }
+ }
+ }
pVer->dwFilterVersion=HTTP_FILTER_REVISION;
strncpy(pVer->lpszFilterDesc,"Shibboleth ISAPI Filter",SF_MAX_FILTER_DESC_LEN);
extern "C" BOOL WINAPI TerminateFilter(DWORD)
{
if (g_Config)
- g_Config->shutdown();
+ g_Config->term();
g_Config = NULL;
LogEvent(NULL, EVENTLOG_INFORMATION_TYPE, 7701, NULL, "Filter shut down...");
return TRUE;
PHTTP_FILTER_CONTEXT m_pfc;
PHTTP_FILTER_PREPROC_HEADERS m_pn;
map<string,string> m_headers;
- vector<XSECCryptoX509*> m_certs;
+ vector<string> m_certs;
int m_port;
string m_scheme,m_hostname,m_uri;
mutable string m_remote_addr,m_content_type,m_method;
hdr += "\r\n";
const char* codestr="200 OK";
switch (status) {
- case SAML_HTTP_STATUS_FORBIDDEN:codestr="403 Forbidden"; break;
- case SAML_HTTP_STATUS_NOTFOUND: codestr="404 Not Found"; break;
- case SAML_HTTP_STATUS_ERROR: codestr="500 Server Error"; break;
+ case XMLTOOLING_HTTP_STATUS_FORBIDDEN:codestr="403 Forbidden"; break;
+ case XMLTOOLING_HTTP_STATUS_NOTFOUND: codestr="404 Not Found"; break;
+ case XMLTOOLING_HTTP_STATUS_ERROR: codestr="500 Server Error"; break;
}
m_pfc->ServerSupportFunction(m_pfc, SF_REQ_SEND_RESPONSE_HEADER, (void*)codestr, (DWORD)hdr.c_str(), 0);
char buf[1024];
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
- const vector<XSECCryptoX509*>& getClientCertificates() const {
+ const vector<string>& getClientCertificates() const {
return m_certs;
}
// The filter never processes the POST, so stub these methods.
- const char* getQueryString() const { throw runtime_error("getQueryString not implemented"); }
- const char* getRequestBody() const { throw runtime_error("getRequestBody not implemented"); }
+ const char* getQueryString() const { throw IOException("getQueryString not implemented"); }
+ const char* getRequestBody() const { throw IOException("getRequestBody not implemented"); }
};
DWORD WriteClientError(PHTTP_FILTER_CONTEXT pfc, const char* msg)
{
LPEXTENSION_CONTROL_BLOCK m_lpECB;
map<string,string> m_headers;
- vector<XSECCryptoX509*> m_certs;
+ vector<string> m_certs;
mutable string m_body;
mutable bool m_gotBody;
int m_port;
if (m_gotBody)
return m_body.c_str();
if (m_lpECB->cbTotalBytes > 1024*1024) // 1MB?
- throw opensaml::BindingException("Size of POST request body exceeded limit.");
- else if (m_lpECB->cbTotalBytes != m_lpECB->cbAvailable) {
+ throw opensaml::SecurityPolicyException("Size of request body exceeded 1M size limit.");
+ else if (m_lpECB->cbTotalBytes > m_lpECB->cbAvailable) {
m_gotBody=true;
char buf[8192];
DWORD datalen=m_lpECB->cbTotalBytes;
DWORD buflen=8192;
BOOL ret = m_lpECB->ReadClient(m_lpECB->ConnID, buf, &buflen);
if (!ret || !buflen)
- throw saml::SAMLException("Error reading POST request body from browser.");
+ throw IOException("Error reading request body from browser.");
m_body.append(buf, buflen);
datalen-=buflen;
}
}
- else {
+ else if (m_lpECB->cbAvailable) {
m_gotBody=true;
m_body.assign(reinterpret_cast<char*>(m_lpECB->lpbData),m_lpECB->cbAvailable);
}
hdr += "\r\n";
const char* codestr="200 OK";
switch (status) {
- case SAML_HTTP_STATUS_FORBIDDEN:codestr="403 Forbidden"; break;
- case SAML_HTTP_STATUS_NOTFOUND: codestr="404 Not Found"; break;
- case SAML_HTTP_STATUS_ERROR: codestr="500 Server Error"; break;
+ case XMLTOOLING_HTTP_STATUS_FORBIDDEN:codestr="403 Forbidden"; break;
+ case XMLTOOLING_HTTP_STATUS_NOTFOUND: codestr="404 Not Found"; break;
+ case XMLTOOLING_HTTP_STATUS_ERROR: codestr="500 Server Error"; break;
}
m_lpECB->ServerSupportFunction(m_lpECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, (void*)codestr, 0, (LPDWORD)hdr.c_str());
char buf[1024];
return HSE_STATUS_SUCCESS;
}
- const vector<XSECCryptoX509*>& getClientCertificates() const {
+ const vector<string>& getClientCertificates() const {
return m_certs;
}