/*
* 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
/**
* isapi_shib.cpp
- *
+ *
* Shibboleth ISAPI filter
*/
static const XMLCh sslport[] = UNICODE_LITERAL_7(s,s,l,p,o,r,t);
static const XMLCh scheme[] = UNICODE_LITERAL_6(s,c,h,e,m,e);
static const XMLCh id[] = UNICODE_LITERAL_2(i,d);
- static const XMLCh ISAPI[] = UNICODE_LITERAL_5(I,S,A,P,I);
static const XMLCh Alias[] = UNICODE_LITERAL_5(A,l,i,a,s);
- static const XMLCh normalizeRequest[] = UNICODE_LITERAL_16(n,o,r,m,a,l,i,z,e,R,e,q,u,e,s,t);
static const XMLCh Site[] = UNICODE_LITERAL_4(S,i,t,e);
struct site_t {
char* m_user;
bool m_checked;
};
-
+
HINSTANCE g_hinstDLL;
SPConfig* g_Config = NULL;
map<string,site_t> g_Sites;
LPCSTR message)
{
LPCSTR messages[] = {message, NULL};
-
+
HANDLE hElog = RegisterEventSource(lpUNCServerName, "Shibboleth ISAPI Filter");
BOOL res = ReportEvent(hElog, wType, 0, dwEventID, lpUserSid, 1, 0, messages, NULL);
return (DeregisterEventSource(hElog) && res);
{
if (!pVer)
return FALSE;
-
+
if (!g_Config) {
LogEvent(NULL, EVENTLOG_ERROR_TYPE, 2100, NULL,
"Extension mode startup not possible, is the DLL loaded as a filter?");
"Filter startup failed to load configuration, check native log for details.");
return FALSE;
}
-
+
// Access implementation-specifics and site mappings.
ServiceProvider* sp=g_Config->getServiceProvider();
Locker locker(sp);
else {
m_port = atoi(site.m_port.c_str());
}
-
+
// Scheme may come from site def or be derived from IIS.
m_scheme=site.m_scheme;
if (m_scheme.empty() || !g_bNormalizeRequest)
m_hostname = var;
if (site.m_name!=m_hostname && site.m_aliases.find(m_hostname)==site.m_aliases.end())
m_hostname=site.m_name;
-
+
if (!pfc->pFilterContext) {
pfc->pFilterContext = pfc->AllocMem(pfc, sizeof(context_t), NULL);
if (static_cast<context_t*>(pfc->pFilterContext)) {
static_cast<context_t*>(pfc->pFilterContext)->m_user = NULL;
static_cast<context_t*>(pfc->pFilterContext)->m_checked = false;
}
- }
+ }
}
~ShibTargetIsapiF() { }
const vector<string>& getClientCertificates() const {
return g_NoCerts;
}
-
+
// The filter never processes the POST, so stub these methods.
const char* getQueryString() const { throw IOException("getQueryString not implemented"); }
const char* getRequestBody() const { throw IOException("getRequestBody not implemented"); }
map<string,site_t>::const_iterator map_i=g_Sites.find(static_cast<char*>(buf));
if (map_i==g_Sites.end())
return SF_STATUS_REQ_NEXT_NOTIFICATION;
-
+
ostringstream threadid;
threadid << "[" << getpid() << "] isapi_shib" << '\0';
xmltooling::NDC ndc(threadid.str().c_str());
return WriteClientError(pfc,"Shibboleth Filter reached unreachable code, save my walrus!");
}
-
+
/****************************************************************************/
// ISAPI Extension
int m_port;
string m_scheme,m_hostname,m_uri;
mutable string m_remote_addr,m_remote_user;
-
+
public:
ShibTargetIsapiE(LPEXTENSION_CONTROL_BLOCK lpECB, const site_t& site)
: AbstractSPRequest(SHIBSP_LOGCAT".ISAPI"), m_lpECB(lpECB), m_gotBody(false) {
* the server is set up for proper PATH_INFO handling, or "IIS sucks rabid weasels mode",
* which is the default. No perfect way to tell, but we can take a good guess by checking
* whether the URL is a substring of the PATH_INFO:
- *
+ *
* e.g. for /Shibboleth.sso/SAML/POST
- *
+ *
* Bad mode (default):
* URL: /Shibboleth.sso
* PathInfo: /Shibboleth.sso/SAML/POST
- *
+ *
* Good mode:
* URL: /Shibboleth.sso
* PathInfo: /SAML/POST
*/
-
+
string uri;
// Clearly we're only in bad mode if path info exists at all.
else {
uri = url;
}
-
+
// For consistency with Apache, let's add the query string.
if (lpECB->lpszQueryString && *(lpECB->lpszQueryString)) {
uri += '?';
ShibTargetIsapiE ste(lpECB, map_i->second);
pair<bool,long> res = ste.getServiceProvider().doHandler(ste);
if (res.first) return res.second;
-
+
return WriteClientError(lpECB, "Shibboleth Extension failed to process request");
}
<documentation>The string value to match.</documentation>
</annotation>
</attribute>
- <attribute name="ignoreCase" type="boolean" default="false">
+ <attribute name="ignoreCase" type="boolean">
<annotation>
<documentation>
A boolean flag indicating whether case should be ignored when evaluating the match.
</annotation>
</element>
</choice>
- <attribute name="language" type="string" default="javascript">
+ <attribute name="language" type="string">
<annotation>
<documentation>
The JSR-233 name for the scripting language that will be used. By default "javascript" is
<documentation>The ID of the attribute whose value should be matched.</documentation>
</annotation>
</attribute>
- <attribute name="minimum" type="nonNegativeInteger" default="0">
+ <attribute name="minimum" type="nonNegativeInteger">
<annotation>
<documentation>Minimum number of values an attribute may have.</documentation>
</annotation>
</attribute>
- <attribute name="maximum" type="positiveInteger" default="2147483647">
+ <attribute name="maximum" type="positiveInteger">
<annotation>
<documentation>Maximum number of values an attribute may have.</documentation>
</annotation>
<complexType>\r
<attribute name="address" type="conf:string" use="required"/>\r
<attribute name="port" type="unsignedInt" use="required"/>\r
- <attribute name="acl" type="conf:listOfStrings" default="127.0.0.1"/>\r
+ <attribute name="acl" type="conf:listOfStrings"/>\r
</complexType>\r
</element>\r
<element name="Listener" type="conf:PluggableType"/>\r
<any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>\r
</sequence>\r
<attribute name="path" type="anyURI" use="required"/>\r
- <attribute name="fatal" type="boolean" default="true"/>\r
+ <attribute name="fatal" type="boolean"/>\r
<anyAttribute namespace="##any" processContents="lax"/>\r
</complexType>\r
</element>\r
<any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>\r
</sequence>\r
<attribute name="id" type="ID" use="required"/>\r
- <attribute name="cleanupInterval" type="unsignedInt" default="900"/>\r
+ <attribute name="cleanupInterval" type="unsignedInt"/>\r
<anyAttribute namespace="##any" processContents="lax"/>\r
</restriction>\r
</complexContent>\r
<any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>\r
</sequence>\r
<attribute name="StorageService" type="IDREF"/>\r
- <attribute name="cacheTimeout" type="unsignedInt" default="28800"/>\r
+ <attribute name="cacheTimeout" type="unsignedInt"/>\r
<anyAttribute namespace="##any" processContents="lax"/>\r
</restriction>\r
</complexContent>\r
<sequence/>\r
<attribute name="StorageService" type="IDREF"/>\r
<attribute name="context" type="conf:string"/>\r
- <attribute name="artifactTTL" type="unsignedInt" default="180"/>\r
+ <attribute name="artifactTTL" type="unsignedInt"/>\r
</complexType>\r
</element>\r
\r
</element>\r
<any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>\r
</sequence>\r
- <attribute name="normalizeRequest" type="boolean" default="true"/>\r
+ <attribute name="normalizeRequest" type="boolean"/>\r
<anyAttribute namespace="##other" processContents="lax"/>\r
</complexType>\r
</element>\r
</choice>\r
</sequence>\r
<attribute name="regex" type="conf:string" use="required"/>\r
- <attribute name="ignoreCase" type="boolean" default="true"/>\r
+ <attribute name="ignoreCase" type="boolean"/>\r
<attribute name="applicationId" type="conf:string"/>\r
<attributeGroup ref="conf:ContentSettings"/>\r
</complexType>\r
<element ref="conf:Query" minOccurs="0" maxOccurs="unbounded"/>\r
</sequence>\r
<attribute name="regex" type="conf:string" use="required"/>\r
- <attribute name="ignoreCase" type="boolean" default="true"/>\r
+ <attribute name="ignoreCase" type="boolean"/>\r
<attribute name="applicationId" type="conf:string"/>\r
<attributeGroup ref="conf:ContentSettings"/>\r
</complexType>\r
</element>\r
\r
<attributeGroup name="ApplicationGroup">\r
- <attribute name="homeURL" type="anyURI" default="/"/>\r
+ <attribute name="homeURL" type="anyURI"/>\r
<attribute name="REMOTE_USER" type="conf:listOfStrings"/>\r
<attribute name="unsetHeaders" type="conf:listOfStrings"/>\r
<attribute name="metadataAttributePrefix" type="conf:string"/>\r
</element>\r
</choice>\r
<attribute name="handlerURL" type="anyURI"/>\r
- <attribute name="handlerSSL" type="boolean" default="true"/>\r
+ <attribute name="handlerSSL" type="boolean"/>\r
<attribute name="exportLocation" type="conf:string"/>\r
- <attribute name="exportACL" type="conf:listOfStrings" default="127.0.0.1"/>\r
+ <attribute name="exportACL" type="conf:listOfStrings"/>\r
<attribute name="cookieName" type="conf:string"/>\r
<attribute name="cookieProps" type="conf:string"/>\r
<attribute name="cookieLifetime" type="unsignedInt"/>\r
- <attribute name="idpHistory" type="boolean" default="false"/>\r
+ <attribute name="idpHistory" type="boolean"/>\r
<attribute name="idpHistoryDays" type="unsignedInt"/>\r
- <attribute name="lifetime" type="unsignedInt" default="28800"/>\r
- <attribute name="timeout" type="unsignedInt" default="3600"/>\r
+ <attribute name="lifetime" type="unsignedInt"/>\r
+ <attribute name="timeout" type="unsignedInt"/>\r
<attribute name="maxTimeSinceAuthn" type="unsignedInt"/>\r
- <attribute name="checkAddress" type="boolean" default="true"/>\r
- <attribute name="consistentAddress" type="boolean" default="true"/>\r
+ <attribute name="checkAddress" type="boolean"/>\r
+ <attribute name="consistentAddress" type="boolean"/>\r
<anyAttribute namespace="##other" processContents="lax"/>\r
</complexType>\r
</element>\r
<element name="Rule" type="conf:PluggableType" minOccurs="1" maxOccurs="unbounded"/>\r
</sequence>\r
<attribute name="id" type="conf:string" use="required"/>\r
- <attribute name="validate" type="boolean" default="false"/>\r
+ <attribute name="validate" type="boolean"/>\r
<anyAttribute namespace="##any" processContents="lax"/>\r
</complexType>\r
</element>\r
m_sessionTried = true;
// Need address checking and timeout settings.
- time_t timeout=0;
+ time_t timeout=3600;
if (checkTimeout || !ignoreAddress) {
const PropertySet* props=getApplication().getPropertySet("Sessions");
if (props) {
#endif
throw ConfigurationException("Target resource was not an absolute URL.");
- bool ssl_only=false;
+ bool ssl_only=true;
const char* handler=NULL;
const PropertySet* props=m_app->getPropertySet("Sessions");
if (props) {
const PropertySet* sessionProps=application.getPropertySet("Sessions");
pair<bool,bool> idpHistory=sessionProps->getBool("idpHistory");
- if (!idpHistory.first || idpHistory.second) {
+ if (idpHistory.first && idpHistory.second) {
pair<bool,const char*> cookieProps=sessionProps->getString("cookieProps");
if (!cookieProps.first)
cookieProps.second=defProps;
#endif
SSCache::SSCache(const DOMElement* e)
- : m_log(Category::getInstance(SHIBSP_LOGCAT".SessionCache")), inproc(true), m_cacheTimeout(3600),
+ : m_log(Category::getInstance(SHIBSP_LOGCAT".SessionCache")), inproc(true), m_cacheTimeout(28800),
#ifndef SHIBSP_LITE
m_storage(NULL), m_storage_lite(NULL),
#endif
if (tag && *tag) {
m_cacheTimeout = XMLString::parseInt(tag);
if (!m_cacheTimeout)
- m_cacheTimeout=3600;
+ m_cacheTimeout=28800;
}
if (inproc) {
const XMLCh* tag=e->getAttributeNS(NULL,inprocTimeout);
static const XMLCh cleanupInterval[] = UNICODE_LITERAL_15(c,l,e,a,n,u,p,I,n,t,e,r,v,a,l);
const XMLCh* tag=m_root ? m_root->getAttributeNS(NULL,cleanupInterval) : NULL;
int rerun_timer = 900;
- if (tag && *tag)
+ if (tag && *tag) {
rerun_timer = XMLString::parseInt(tag);
- if (rerun_timer <= 0)
- rerun_timer = 900;
+ if (rerun_timer <= 0)
+ rerun_timer = 900;
+ }
mutex->lock();