shibboleth.logger \
accessError.html \
rmError.html \
- shireError.html \
+ sessionError.html \
shar.key \
shar.crt
shibboleth.logger \
accessError.html \
rmError.html \
- shireError.html \
+ sessionError.html \
AAP.xml.in \
IQ-sites.xml.in \
IQ-trust.xml.in \
-<ShibbolethTargetConfig xmlns="urn:mace:shibboleth:target:config:1.0"
+<SPConfig xmlns="urn:mace:shibboleth:target:config:1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:mace:shibboleth:target:config:1.0 @-PKGXMLDIR-@/shibboleth-targetconfig-1.0.xsd"
logger="@-PKGSYSCONFDIR-@/shibboleth.logger" clockSkew="180">
<Library path="@-LIBEXECDIR-@/xmlproviders.so" fatal="true"/>
</Extensions>
- <SHAR logger="@-PKGSYSCONFDIR-@/shar.logger">
+ <Global logger="@-PKGSYSCONFDIR-@/shar.logger">
<!--
<Extensions>
</Extensions>
-->
- <!-- only one listener can be defined. -->
+ <!-- Only one listener can be defined. -->
<UnixListener address="/tmp/shar-socket"/>
<!-- <TCPListener address="127.0.0.1" port="12345" acl="127.0.0.1"/> -->
strictValidity - if we have expired attrs, and can't get new ones, keep using them?
propagateErrors - suppress errors while getting attrs or let user see them?
retryInterval - if propagateErrors is false and query fails, how long to wait before trying again
+ Only one session cache can be defined.
-->
<MemorySessionCache cleanupInterval="300" cacheTimeout="3600" AATimeout="30" AAConnectTimeout="15"
defaultLifetime="1800" retryInterval="300" strictValidity="false" propagateErrors="true"/>
<Argument>--datadir=@-PREFIX-@/data</Argument>
</MySQLSessionCache>
-->
- </SHAR>
+
+ <!-- Default replay cache is in-memory. -->
+ <!--
+ <MySQLReplayCache>
+ <Argument>--language=@-PREFIX-@/share/english</Argument>
+ <Argument>--datadir=@-PREFIX-@/data</Argument>
+ </MySQLReplayCache>
+ -->
+ </Global>
- <SHIRE logger="@-PKGSYSCONFDIR-@/shire.logger">
+ <Local logger="@-PKGSYSCONFDIR-@/shire.logger">
<!--
To customize behavior, map hostnames and path components to applicationId and other settings.
Can be either a pointer to an external file or an inline configuration.
-->
- <!--
- <RequestMapProvider type="edu.internet2.middleware.shibboleth.target.provider.XMLRequestMap"
- uri="@-PKGSYSCONFDIR-@/applications.xml"/>
- -->
-
- <RequestMapProvider type="edu.internet2.middleware.shibboleth.target.provider.XMLRequestMap">
+ <RequestMapProvider type="edu.internet2.middleware.shibboleth.sp.provider.XMLRequestMapProvider">
<RequestMap applicationId="default">
<!--
This requires a session for documents in /secure on the containing host with http and
https on the default ports. Note that the name and port in the <Host> elements MUST match
- Apache's ServerName and Port directives or the IIS Site mapping in the <ISAPI> element
+ Apache's ServerName and Port directives or the IIS Site name in the <ISAPI> element
below.
-->
<Host name="localhost">
<Implementation>
<ISAPI normalizeRequest="true">
<!--
- Maps IIS IID values to the host scheme/name/port. The name is required so that
+ Maps IIS Instance ID values to the host scheme/name/port. The name is required so that
the proper <Host> in the request map above is found without having to cover every
possible DNS/IP combination the user might enter. The port and scheme can
usually be omitted, so the HTTP request's port and scheme will be used.
+
+ <Alias> elements can specify alternate permissible client-specified server names.
+ If a client request uses such a name, normalized redirects will use it, but the
+ request map processing is still based on the default name attribute for the
+ site. This reduces duplicate data entry in the request map for every legal
+ hostname a site might permit. In the example below, only localhost needs a
+ <Host> element in the map, but localhost.localdomain could be used by a client
+ and those requests will map to localhost for configuration settings.
-->
- <Site id="1" name="localhost"/>
+ <Site id="1" name="localhost">
+ <Alias>localhost.localdomain</Alias>
+ </Site>
</ISAPI>
</Implementation>
- </SHIRE>
+ </Local>
<Applications xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
id="default" providerId="https://example.org/shibboleth/target">
<!--
You should customize these pages! You can add attributes with values that can be plugged
- into your templates.
+ into your templates. You can remove the access attribute to cause the module to return a
+ standard 403 Forbidden error code if authorization fails, and then customize that condition
+ using your web server.
-->
- <Errors shire="@-PKGSYSCONFDIR-@/shireError.html"
+ <Errors session="@-PKGSYSCONFDIR-@/sessionError.html"
rm="@-PKGSYSCONFDIR-@/rmError.html"
access="@-PKGSYSCONFDIR-@/accessError.html"
supportContact="root@localhost"
<!-- Indicates what credentials to use when communicating -->
<CredentialUse TLS="defcreds" Signing="defcreds">
- <!-- RelyingParty elements customize credentials for specific origins or federations -->
+ <!-- RelyingParty elements customize credentials for specific IdPs or federations -->
<!--
<RelyingParty Name="urn:mace:inqueue" TLS="inqueuecreds" Signing="inqueuecreds"/>
-->
-->
<!-- AAP can be inline or in a separate file -->
- <AAPProvider type="edu.internet2.middleware.shibboleth.target.provider.XMLAAP" uri="@-PKGSYSCONFDIR-@/AAP.xml"/>
+ <AAPProvider type="edu.internet2.middleware.shibboleth.aap.provider.XMLAAP" uri="@-PKGSYSCONFDIR-@/AAP.xml"/>
<!-- Metadata consists of site/operational metadata, trust, revocation providers. Can be external or inline. -->
<!-- Dummy metadata for private testing, delete when deploying. -->
- <FederationProvider type="edu.internet2.middleware.shibboleth.common.provider.XMLMetadata">
+ <FederationProvider type="edu.internet2.middleware.shibboleth.metadata.provider.XMLMetadata">
<EntityDescriptor entityID="https://example.org/shibboleth" xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
<IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol urn:mace:shibboleth:1.0">
<Extensions>
</FederationProvider>
<!-- InQueue pilot federation, delete for production deployments. -->
- <FederationProvider type="edu.internet2.middleware.shibboleth.common.provider.XMLMetadata"
+ <FederationProvider type="edu.internet2.middleware.shibboleth.metadata.provider.XMLMetadata"
uri="@-PKGSYSCONFDIR-@/IQ-sites.xml"/>
- <TrustProvider type="edu.internet2.middleware.shibboleth.common.provider.XMLTrust"
+ <TrustProvider type="edu.internet2.middleware.shibboleth.trust.provider.XMLTrust"
uri="@-PKGSYSCONFDIR-@/IQ-trust.xml"/>
<!--
Revocation using X.509 CRLs is an optional feature in some trust metadata or you may
uri="@-PKGSYSCONFDIR-@/IQ-trust.xml"/>
-->
- <!-- zero or more SAML Audience condition matches -->
+ <!-- zero or more SAML Audience condition matches (mainly Shib 1.1 compatibility) -->
<saml:Audience>urn:mace:inqueue</saml:Audience>
<!--
</Credentials>
</CredentialsProvider>
-</ShibbolethTargetConfig>
+</SPConfig>
elementFormDefault="qualified"
attributeFormDefault="unqualified"
blockDefault="substitution"
- version="1.0">
+ version="1.1">
<import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsig-core-schema.xsd"/>
<import namespace="urn:oasis:names:tc:SAML:1.0:assertion" schemaLocation="cs-sstc-schema-assertion-1.1.xsd"/>
</annotation>
<complexType name="PluggableType">
- <complexContent>
- <extension base="anyType">
+ <complexContent>
+ <restriction base="anyType">
+ <sequence>
+ <any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
<attribute name="type" type="string" use="required"/>
- </extension>
- </complexContent>
+ <attribute name="uri" type="anyURI" use="optional"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </restriction>
+ </complexContent>
</complexType>
- <element name="ShibbolethTargetConfig">
+ <element name="ShibbolethTargetConfig" type="conf:SPConfigType"/>
+ <element name="SPConfig" type="conf:SPConfigType"/>
+ <complexType name="SPConfigType">
<annotation>
- <documentation>Outer element of configuration file</documentation>
+ <documentation>Root element of configuration file</documentation>
</annotation>
- <complexType>
- <sequence>
- <element ref="conf:Extensions" minOccurs="0"/>
- <element ref="conf:SHAR" minOccurs="0"/>
- <element ref="conf:SHIRE" minOccurs="0"/>
- <element ref="conf:Applications"/>
- <element name="CredentialsProvider" type="conf:PluggableType" minOccurs="0" maxOccurs="unbounded"/>
- </sequence>
- <attribute name="logger" type="anyURI" use="optional"/>
- <attribute name="clockSkew" type="unsignedInt" use="optional"/>
- <anyAttribute namespace="##other" processContents="lax"/>
- </complexType>
- </element>
+ <sequence>
+ <element ref="conf:Extensions" minOccurs="0"/>
+ <choice minOccurs="0">
+ <element name="Global" type="conf:GlobalConfigurationType"/>
+ <element name="SHAR" type="conf:GlobalConfigurationType"/>
+ </choice>
+ <choice minOccurs="0">
+ <element name="Local" type="conf:LocalConfigurationType"/>
+ <element name="SHIRE" type="conf:LocalConfigurationType"/>
+ </choice>
+ <element ref="conf:Applications"/>
+ <element name="CredentialsProvider" type="conf:PluggableType" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="logger" type="anyURI" use="optional"/>
+ <attribute name="clockSkew" type="unsignedInt" use="optional"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </complexType>
<element name="Extensions">
<annotation>
<element name="Library" minOccurs="0" maxOccurs="unbounded">
<complexType>
<complexContent>
- <extension base="anyType">
+ <restriction base="anyType">
+ <sequence>
+ <any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
<attribute name="path" type="anyURI" use="required"/>
<attribute name="fatal" type="boolean" use="optional"/>
- </extension>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </restriction>
</complexContent>
</complexType>
</element>
</complexType>
</element>
- <element name="SHAR">
+ <complexType name="GlobalConfigurationType">
<annotation>
- <documentation>Container for SHAR configuration</documentation>
+ <documentation>Container for global (server independent) configuration</documentation>
</annotation>
- <complexType>
- <sequence>
- <element ref="conf:Extensions" minOccurs="0"/>
- <choice>
- <element name="UnixListener">
- <complexType>
- <complexContent>
- <extension base="anyType">
- <attribute name="address" type="string" use="required"/>
- </extension>
- </complexContent>
- </complexType>
- </element>
- <element name="TCPListener">
- <complexType>
- <complexContent>
- <extension base="anyType">
- <attribute name="address" type="string" use="required"/>
- <attribute name="port" type="unsignedInt" use="required"/>
- <attribute name="acl" use="optional" default="127.0.0.1">
- <simpleType>
- <list itemType="string"/>
- </simpleType>
- </attribute>
- </extension>
- </complexContent>
- </complexType>
- </element>
- <element name="Listener" type="conf:PluggableType"/>
- </choice>
- <choice>
- <element name="MemorySessionCache">
- <complexType mixed="false">
- <complexContent>
- <restriction base="anyType">
- <sequence/>
- <attributeGroup ref="conf:SessionCacheProperties"/>
- <anyAttribute namespace="##other" processContents="lax"/>
- </restriction>
- </complexContent>
- </complexType>
- </element>
- <element name="MySQLSessionCache">
- <complexType mixed="false">
- <complexContent>
- <restriction base="anyType">
- <sequence>
- <element name="Argument" type="string" minOccurs="0" maxOccurs="unbounded"/>
- </sequence>
- <attributeGroup ref="conf:SessionCacheProperties"/>
- <attribute name="mysqlTimeout" type="unsignedInt" use="optional" default="14400"/>
- <anyAttribute namespace="##other" processContents="lax"/>
- </restriction>
- </complexContent>
- </complexType>
- </element>
- <element name="SessionCache">
- <complexType>
- <complexContent>
- <extension base="conf:PluggableType">
- <attributeGroup ref="conf:SessionCacheProperties"/>
- </extension>
- </complexContent>
- </complexType>
- </element>
- </choice>
- <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
- </sequence>
- <attribute name="logger" type="anyURI" use="optional"/>
- <anyAttribute namespace="##other" processContents="lax"/>
- </complexType>
- </element>
+ <sequence>
+ <element ref="conf:Extensions" minOccurs="0"/>
+ <choice>
+ <element name="UnixListener">
+ <complexType mixed="false">
+ <complexContent>
+ <restriction base="anyType">
+ <attribute name="address" type="string" use="required"/>
+ </restriction>
+ </complexContent>
+ </complexType>
+ </element>
+ <element name="TCPListener">
+ <complexType mixed="false">
+ <complexContent>
+ <restriction base="anyType">
+ <attribute name="address" type="string" use="required"/>
+ <attribute name="port" type="unsignedInt" use="required"/>
+ <attribute name="acl" use="optional" default="127.0.0.1">
+ <simpleType>
+ <list itemType="string"/>
+ </simpleType>
+ </attribute>
+ </restriction>
+ </complexContent>
+ </complexType>
+ </element>
+ <element name="Listener" type="conf:PluggableType"/>
+ </choice>
+ <choice>
+ <element name="MemorySessionCache">
+ <complexType mixed="false">
+ <complexContent>
+ <restriction base="anyType">
+ <attributeGroup ref="conf:SessionCacheProperties"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </restriction>
+ </complexContent>
+ </complexType>
+ </element>
+ <element name="MySQLSessionCache">
+ <complexType>
+ <sequence>
+ <element name="Argument" type="string" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attributeGroup ref="conf:SessionCacheProperties"/>
+ <attribute name="mysqlTimeout" type="unsignedInt" use="optional" default="14400"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </complexType>
+ </element>
+ <element name="SessionCache">
+ <complexType>
+ <complexContent>
+ <extension base="conf:PluggableType">
+ <attributeGroup ref="conf:SessionCacheProperties"/>
+ </extension>
+ </complexContent>
+ </complexType>
+ </element>
+ </choice>
+ <choice minOccurs="0">
+ <element name="MySQLReplayCache">
+ <complexType>
+ <sequence>
+ <element name="Argument" type="string" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </complexType>
+ </element>
+ <element name="ReplayCache" type="conf:PluggableType"/>
+ </choice>
+ <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="logger" type="anyURI" use="optional"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </complexType>
<attributeGroup name="SessionCacheProperties">
<attribute name="cleanupInterval" type="unsignedInt" use="optional" default="300"/>
<attribute name="propagateErrors" type="boolean" use="optional" default="false"/>
</attributeGroup>
- <element name="SHIRE">
+ <complexType name="LocalConfigurationType">
<annotation>
<documentation>
- Container for configuration glue between target library and the surrounding application environment.
+ Container for configuration of locally integrated or platform-specific
+ features (e.g. web server filters)
</documentation>
</annotation>
- <complexType>
- <sequence>
- <element ref="conf:Extensions" minOccurs="0"/>
- <element name="RequestMapProvider" type="conf:PluggableType" minOccurs="0"/>
- <element name="Implementation" minOccurs="0">
- <complexType>
- <choice maxOccurs="unbounded">
- <element ref="conf:ISAPI"/>
- <element ref="conf:NSAPI"/>
- <element ref="conf:Java"/>
- <any namespace="##other" processContents="lax"/>
- </choice>
- </complexType>
- </element>
- <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
- </sequence>
- <attribute name="logger" type="anyURI" use="optional"/>
- <anyAttribute namespace="##other" processContents="lax"/>
- </complexType>
- </element>
+ <sequence>
+ <element ref="conf:Extensions" minOccurs="0"/>
+ <element name="RequestMapProvider" type="conf:PluggableType" minOccurs="0"/>
+ <element name="Implementation" minOccurs="0">
+ <complexType>
+ <choice maxOccurs="unbounded">
+ <element ref="conf:ISAPI"/>
+ <element ref="conf:NSAPI"/>
+ <element ref="conf:Java"/>
+ <any namespace="##other" processContents="lax"/>
+ </choice>
+ </complexType>
+ </element>
+ <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="logger" type="anyURI" use="optional"/>
+ <anyAttribute namespace="##other" processContents="lax"/>
+ </complexType>
<element name="ISAPI">
<complexType>
<sequence>
<element name="Site" maxOccurs="unbounded">
- <complexType>
+ <complexType mixed="false">
<complexContent>
- <extension base="anyType">
+ <restriction base="anyType">
+ <sequence>
+ <element name="Alias" type="string" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
<attribute name="id" type="unsignedInt" use="required"/>
<attribute name="name" type="string" use="required"/>
<attribute name="port" type="unsignedInt" use="optional"/>
<attribute name="scheme" type="string" use="optional"/>
- </extension>
+ </restriction>
</complexContent>
</complexType>
</element>
</sequence>
<attribute name="id" type="string" fixed="default"/>
<attribute name="providerId" type="anyURI" use="required"/>
- <attribute name="signRequest" type="boolean" use="optional" default="false"/>
- <attribute name="signedResponse" type="boolean" use="optional" default="false"/>
- <attribute name="signedAssertions" type="boolean" use="optional" default="false"/>
<anyAttribute namespace="##other" processContents="lax"/>
</complexType>
</element>
</sequence>
<attribute name="id" type="string" use="required"/>
<attribute name="providerId" type="anyURI" use="optional"/>
- <attribute name="signRequest" type="boolean" use="optional" default="false"/>
- <attribute name="signedResponse" type="boolean" use="optional" default="false"/>
- <attribute name="signedAssertions" type="boolean" use="optional" default="false"/>
<anyAttribute namespace="##other" processContents="lax"/>
</complexType>
</element>
<documentation>Container for specifying app session establishment and policy</documentation>
</annotation>
<complexType>
- <complexContent>
- <extension base="anyType">
- <attribute name="wayfURL" type="anyURI" use="required"/>
- <attribute name="shireURL" type="anyURI" use="required"/>
- <attribute name="shireSSL" type="boolean" use="optional"/>
- <attribute name="cookieName" type="string" use="optional"/>
- <attribute name="cookieProps" type="string" use="optional"/>
- <attribute name="lifetime" type="unsignedInt" use="optional"/>
- <attribute name="timeout" type="unsignedInt" use="optional"/>
- <attribute name="checkAddress" type="boolean" use="optional"/>
- <attribute name="oldAuthnRequest" type="boolean" use="optional"/>
- </extension>
- </complexContent>
+ <attribute name="wayfURL" type="anyURI" use="optional"/>
+ <!-- deprecated --> <attribute name="shireURL" type="anyURI" use="optional"/>
+ <attribute name="shireSSL" type="boolean" use="optional"/>
+ <attribute name="cookieName" type="string" use="optional"/>
+ <attribute name="cookieProps" type="string" use="optional"/>
+ <attribute name="lifetime" type="unsignedInt" use="optional"/>
+ <attribute name="timeout" type="unsignedInt" use="optional"/>
+ <attribute name="checkAddress" type="boolean" use="optional"/>
+ <attribute name="oldAuthnRequest" type="boolean" use="optional"/>
+ <anyAttribute namespace="##any" processContents="lax"/>
</complexType>
</element>
</annotation>
<complexType>
<complexContent>
- <extension base="anyType">
- <attribute name="shire" type="anyURI" use="required"/>
+ <restriction base="anyType">
+ <!-- deprecated --> <attribute name="shire" type="anyURI" use="optional"/>
+ <attribute name="session" type="anyURI" use="optional"/>
<attribute name="rm" type="anyURI" use="required"/>
- <attribute name="access" type="anyURI" use="required"/>
+ <attribute name="access" type="anyURI" use="optional"/>
<attribute name="supportContact" type="string" use="optional"/>
<attribute name="logoLocation" type="anyURI" use="optional"/>
<attribute name="styleSheet" type="anyURI" use="optional"/>
- </extension>
+ <anyAttribute namespace="##any" processContents="lax"/>
+ </restriction>
</complexContent>
</complexType>
</element>
+ <attributeGroup name="CredentialUseGroup">
+ <attribute name="TLS" type="string" use="required"/>
+ <attribute name="Signing" type="string" use="required"/>
+ <attribute name="signRequest" type="boolean" use="optional" default="false"/>
+ <attribute name="signedResponse" type="boolean" use="optional" default="false"/>
+ <attribute name="signedAssertions" type="boolean" use="optional" default="false"/>
+ </attributeGroup>
+
<element name="CredentialUse">
<annotation>
<documentation>Container for specifying credentials to use</documentation>
<complexType>
<sequence>
<element name="RelyingParty" minOccurs="0" maxOccurs="unbounded">
- <complexType>
+ <complexType mixed="false">
<complexContent>
- <extension base="anyType">
+ <restriction base="anyType">
<attribute name="Name" type="string" use="required"/>
- <attribute name="TLS" type="string" use="required"/>
- <attribute name="Signing" type="string" use="required"/>
- </extension>
+ <attributeGroup ref="conf:CredentialUseGroup"/>
+ </restriction>
</complexContent>
</complexType>
</element>
<any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
- <attribute name="TLS" type="string" use="required"/>
- <attribute name="Signing" type="string" use="required"/>
+ <attributeGroup ref="conf:CredentialUseGroup"/>
<anyAttribute namespace="##other" processContents="lax"/>
</complexType>
</element>
return false;
}
-#ifndef _DEBUG
try {
-#endif
// Register plugin types.
#ifndef WIN32
samlConf.getPlugMgr().regFactory(shibtarget::XML::UnixListenerType,&UnixListenerFactory);
#endif
samlConf.getPlugMgr().regFactory(shibtarget::XML::TCPListenerType,&TCPListenerFactory);
samlConf.getPlugMgr().regFactory(shibtarget::XML::MemorySessionCacheType,&MemoryCacheFactory);
+ samlConf.getPlugMgr().regFactory(shibtarget::XML::LegacyRequestMapType,&XMLRequestMapFactory);
samlConf.getPlugMgr().regFactory(shibtarget::XML::RequestMapType,&XMLRequestMapFactory);
//shibConf.getPlugMgr().regFactory(shibtarget::XML::htaccessType,&htaccessFactory);
saml::XML::registerSchema(ShibTargetConfig::SHIBTARGET_NS,shibtarget::XML::SHIBTARGET_SCHEMA_ID);
m_tranLogLock = Mutex::create();
m_rpcpool = new RPCHandlePool;
-#ifndef _DEBUG
}
+ catch (SAMLException& ex) {
+ log.fatalStream() << "caught exception while loading/initializing configuration: " << ex.what() << CategoryStream::ENDLINE;
+ shutdown();
+ return false;
+ }
+#ifndef _DEBUG
catch (...) {
log.fatal("caught exception while loading/initializing configuration");
shutdown();
{
public:
XMLApplication(const IConfig*, const Iterator<ICredentials*>& creds, const DOMElement* e, const XMLApplication* base=NULL);
- ~XMLApplication();
+ ~XMLApplication() { cleanup(); }
// IPropertySet
pair<bool,bool> getBool(const char* name, const char* ns=NULL) const;
Iterator<ITrust*> getTrustProviders() const;
Iterator<IRevocation*> getRevocationProviders() const;
Iterator<const XMLCh*> getAudiences() const;
- const char* getTLSCred(const IEntityDescriptor* provider) const {return getCredentialUse(provider).first.c_str();}
- const char* getSigningCred(const IEntityDescriptor* provider) const {return getCredentialUse(provider).second.c_str();}
+ const IPropertySet* getCredentialUse(const IEntityDescriptor* provider) const;
const SAMLBrowserProfile* getBrowserProfile() const {return m_profile;}
const SAMLBinding* getBinding(const XMLCh* binding) const
{return XMLString::compareString(SAMLBinding::SOAP,binding) ? NULL : m_binding;}
short acceptNode(const DOMNode* node) const;
private:
+ void cleanup();
const IConfig* m_ini; // this is ok because its locking scope includes us
const XMLApplication* m_base;
vector<SAMLAttributeDesignator*> m_designators;
vector<ITrust*> m_trusts;
vector<IRevocation*> m_revocations;
vector<const XMLCh*> m_audiences;
- pair<string,string> m_credDefault;
ShibBrowserProfile* m_profile;
SAMLBinding* m_binding;
ShibHTTPHook* m_bindingHook;
+ XMLPropertySet* m_credDefault;
#ifdef HAVE_GOOD_STL
- map<xstring,pair<string,string> > m_credMap;
+ map<xstring,XMLPropertySet*> m_credMap;
#else
- map<const XMLCh*,pair<string,string> > m_credMap;
+ map<const XMLCh*,XMLPropertySet*> m_credMap;
#endif
- const pair<string,string>& getCredentialUse(const IEntityDescriptor* provider) const;
};
// Top-level configuration implementation
delete j->second;
}
-void XMLPropertySet::load(const DOMElement* e, Category& log, DOMNodeFilter* filter)
+void XMLPropertySet::load(
+ const DOMElement* e,
+ Category& log,
+ DOMNodeFilter* filter,
+ const std::map<std::string,std::string>* remapper
+ )
{
#ifdef _DEBUG
saml::NDC ndc("load");
if (val && *val) {
auto_ptr_char ns(a->getNamespaceURI());
auto_ptr_char name(a->getLocalName());
+ const char* realname=name.get();
+ if (remapper) {
+ map<string,string>::const_iterator remap=remapper->find(realname);
+ if (remap!=remapper->end()) {
+ log.debug("remapping property (%s) to (%s)",realname,remap->second.c_str());
+ realname=remap->second.c_str();
+ }
+ }
if (ns.get()) {
- m_map[string("{") + ns.get() + '}' + name.get()]=pair<char*,const XMLCh*>(val,a->getNodeValue());
- log.debug("added property {%s}%s (%s)",ns.get(),name.get(),val);
+ m_map[string("{") + ns.get() + '}' + realname]=pair<char*,const XMLCh*>(val,a->getNodeValue());
+ log.debug("added property {%s}%s (%s)",ns.get(),realname,val);
}
else {
- m_map[name.get()]=pair<char*,const XMLCh*>(val,a->getNodeValue());
- log.debug("added property %s (%s)",name.get(),val);
+ m_map[realname]=pair<char*,const XMLCh*>(val,a->getNodeValue());
+ log.debug("added property %s (%s)",realname,val);
}
}
}
while (e) {
auto_ptr_char ns(e->getNamespaceURI());
auto_ptr_char name(e->getLocalName());
+ const char* realname=name.get();
+ if (remapper) {
+ map<string,string>::const_iterator remap=remapper->find(realname);
+ if (remap!=remapper->end()) {
+ log.debug("remapping property set (%s) to (%s)",realname,remap->second.c_str());
+ realname=remap->second.c_str();
+ }
+ }
string key;
if (ns.get())
- key=string("{") + ns.get() + '}' + name.get();
+ key=string("{") + ns.get() + '}' + realname;
else
- key=name.get();
+ key=realname;
if (m_nested.find(key)!=m_nested.end())
log.warn("load() skipping duplicate property set: %s",key.c_str());
else {
XMLPropertySet* set=new XMLPropertySet();
- set->load(e,log,filter);
+ set->load(e,log,filter,remapper);
m_nested[key]=set;
log.debug("added nested property set: %s",key.c_str());
}
}
XMLApplication::XMLApplication(const IConfig* ini, const Iterator<ICredentials*>& creds, const DOMElement* e, const XMLApplication* base)
- : m_ini(ini), m_base(base), m_profile(NULL), m_binding(NULL), m_bindingHook(NULL)
+ : m_ini(ini), m_base(base), m_profile(NULL), m_binding(NULL), m_bindingHook(NULL), m_credDefault(NULL)
{
#ifdef _DEBUG
NDC ndc("XMLApplication");
try {
// First load any property sets.
- load(e,log,this);
+ map<string,string> root_remap;
+ root_remap["shire"]="session";
+ load(e,log,this,&root_remap);
+ const IPropertySet* propcheck=getPropertySet("Errors");
+ if (propcheck && !propcheck->getString("session").first)
+ throw MalformedException("<Errors> element requires 'session' (or deprecated 'shire') attribute");
ShibTargetConfig& conf=ShibTargetConfig::getConfig();
SAMLConfig& shibConf=SAMLConfig::getConfig();
// Finally, load credential mappings.
const DOMElement* cu=saml::XML::getFirstChildElement(e,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(CredentialUse));
if (cu) {
- auto_ptr_char TLS(cu->getAttributeNS(NULL,SHIBT_L(TLS)));
- auto_ptr_char Signing(cu->getAttributeNS(NULL,SHIBT_L(Signing)));
- m_credDefault.first=TLS.get();
- m_credDefault.second=Signing.get();
+ m_credDefault=new XMLPropertySet();
+ m_credDefault->load(cu,log,this);
cu=saml::XML::getFirstChildElement(cu,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(RelyingParty));
while (cu) {
- auto_ptr_char TLS2(cu->getAttributeNS(NULL,SHIBT_L(TLS)));
- auto_ptr_char Signing2(cu->getAttributeNS(NULL,SHIBT_L(Signing)));
- m_credMap[cu->getAttributeNS(NULL,SHIBT_L(Name))]=pair<string,string>(TLS2.get(),Signing2.get());
+ XMLPropertySet* rp=new XMLPropertySet();
+ rp->load(cu,log,this);
+ m_credMap[cu->getAttributeNS(NULL,SHIBT_L(Name))]=rp;
cu=saml::XML::getNextSiblingElement(cu,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(RelyingParty));
}
}
}
catch (SAMLException& e) {
log.errorStream() << "Error while processing applicaton element: " << e.what() << CategoryStream::ENDLINE;
- this->~XMLApplication();
+ cleanup();
throw;
}
#ifndef _DEBUG
catch (...) {
log.error("Unexpected error while processing application element");
- this->~XMLApplication();
+ cleanup();
throw;
}
#endif
}
-XMLApplication::~XMLApplication()
+void XMLApplication::cleanup()
{
delete m_bindingHook;
delete m_binding;
delete m_profile;
+ delete m_credDefault;
+#ifdef HAVE_GOOD_STL
+ map<xstring,XMLPropertySet*>::iterator c=m_credMap.begin();
+#else
+ map<const XMLCh*,XMLPropertySet*>::iterator c=m_credMap.begin();
+#endif
+ while (c!=m_credMap.end()) {
+ delete c->second;
+ c++;
+ }
Iterator<SAMLAttributeDesignator*> i(m_designators);
while (i.hasNext())
delete i.next();
if (!XMLString::compareString(name,SHIBT_L(Application)) ||
!XMLString::compareString(name,SHIBT_L(AAPProvider)) ||
!XMLString::compareString(name,SHIBT_L(CredentialUse)) ||
+ !XMLString::compareString(name,SHIBT_L(RelyingParty)) ||
!XMLString::compareString(name,SHIBT_L(FederationProvider)) ||
!XMLString::compareString(name,SHIBT_L(RevocationProvider)) ||
!XMLString::compareString(name,SHIBT_L(TrustProvider)))
return (m_audiences.empty() && m_base) ? m_base->getAudiences() : m_audiences;
}
-const pair<string,string>& XMLApplication::getCredentialUse(const IEntityDescriptor* provider) const
+const IPropertySet* XMLApplication::getCredentialUse(const IEntityDescriptor* provider) const
{
- if (m_credDefault.first.empty() && m_base)
+ if (!m_credDefault && m_base)
return m_base->getCredentialUse(provider);
#ifdef HAVE_GOOD_STL
- map<xstring,pair<string,string> >::const_iterator i=m_credMap.find(provider->getId());
+ map<xstring,XMLPropertySet*>::const_iterator i=m_credMap.find(provider->getId());
if (i!=m_credMap.end())
return i->second;
const IEntitiesDescriptor* group=provider->getEntitiesDescriptor();
group=group->getEntitiesDescriptor();
}
#else
- map<const XMLCh*,pair<string,string> >::const_iterator i=m_credMap.begin();
+ map<const XMLCh*,XMLPropertySet*>::const_iterator i=m_credMap.begin();
for (; i!=m_credMap.end(); i++) {
if (!XMLString::compareString(i->first,provider->getId()))
return i->second;
!XMLString::compareString(name,SHIBT_L(Implementation)) ||
!XMLString::compareString(name,SHIBT_L(Listener)) ||
!XMLString::compareString(name,SHIBT_L(MemorySessionCache)) ||
+ !XMLString::compareString(name,SHIBT_L(MySQLReplayCache)) ||
!XMLString::compareString(name,SHIBT_L(MySQLSessionCache)) ||
!XMLString::compareString(name,SHIBT_L(RequestMap)) ||
!XMLString::compareString(name,SHIBT_L(RequestMapProvider)) ||
+ !XMLString::compareString(name,SHIBT_L(ReplayCache)) ||
!XMLString::compareString(name,SHIBT_L(SessionCache)) ||
!XMLString::compareString(name,SHIBT_L(TCPListener)) ||
!XMLString::compareString(name,SHIBT_L(UnixListener)))
Category& log=Category::getInstance("shibtarget.XMLConfig");
try {
- if (!saml::XML::isElementNamed(ReloadableXMLFileImpl::m_root,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(ShibbolethTargetConfig))) {
- log.error("Construction requires a valid configuration file: (conf:ShibbolethTargetConfig as root element)");
- throw MalformedException("Construction requires a valid configuration file: (conf:ShibbolethTargetConfig as root element)");
+ if (!saml::XML::isElementNamed(ReloadableXMLFileImpl::m_root,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(ShibbolethTargetConfig)) &&
+ !saml::XML::isElementNamed(ReloadableXMLFileImpl::m_root,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(SPConfig))) {
+ log.error("Construction requires a valid configuration file: (conf:SPConfig as root element)");
+ throw MalformedException("Construction requires a valid configuration file: (conf:SPConfig as root element)");
}
SAMLConfig& shibConf=SAMLConfig::getConfig();
ShibTargetConfig& conf=ShibTargetConfig::getConfig();
const DOMElement* SHAR=saml::XML::getFirstChildElement(ReloadableXMLFileImpl::m_root,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(SHAR));
+ if (!SHAR)
+ SHAR=saml::XML::getFirstChildElement(ReloadableXMLFileImpl::m_root,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Global));
const DOMElement* SHIRE=saml::XML::getFirstChildElement(ReloadableXMLFileImpl::m_root,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(SHIRE));
+ if (!SHIRE)
+ SHIRE=saml::XML::getFirstChildElement(ReloadableXMLFileImpl::m_root,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Local));
// Initialize log4cpp manually in order to redirect log messages as soon as possible.
if (conf.isEnabled(ShibTargetConfig::Logging)) {
const XMLCh* logger=NULL;
- if (conf.isEnabled(ShibTargetConfig::SHARExtensions))
+ if (conf.isEnabled(ShibTargetConfig::GlobalExtensions))
logger=SHAR->getAttributeNS(NULL,SHIBT_L(logger));
- else if (conf.isEnabled(ShibTargetConfig::SHIREExtensions))
+ else if (conf.isEnabled(ShibTargetConfig::LocalExtensions))
logger=SHIRE->getAttributeNS(NULL,SHIBT_L(logger));
if (!logger || !*logger)
logger=ReloadableXMLFileImpl::m_root->getAttributeNS(NULL,SHIBT_L(logger));
}
// First load any property sets.
- load(ReloadableXMLFileImpl::m_root,log,this);
+ map<string,string> root_remap;
+ root_remap["SHAR"]="Global";
+ root_remap["SHIRE"]="Local";
+ load(ReloadableXMLFileImpl::m_root,log,this,&root_remap);
// Much of the processing can only occur on the first instantiation.
if (first) {
}
}
- if (conf.isEnabled(ShibTargetConfig::SHARExtensions)) {
+ if (conf.isEnabled(ShibTargetConfig::GlobalExtensions)) {
exts=saml::XML::getFirstChildElement(SHAR,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Extensions));
if (exts) {
exts=saml::XML::getFirstChildElement(exts,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Library));
auto_ptr_char path(exts->getAttributeNS(NULL,SHIBT_L(path)));
try {
SAMLConfig::getConfig().saml_register_extension(path.get(),exts);
- log.debug("loaded SHAR extension library %s",path.get());
+ log.debug("loaded Global extension library %s",path.get());
}
catch (SAMLException& e) {
const XMLCh* fatal=exts->getAttributeNS(NULL,SHIBT_L(fatal));
if (fatal && (*fatal==chLatin_t || *fatal==chDigit_1)) {
- log.fatal("unable to load mandatory SHAR extension library %s: %s", path.get(), e.what());
+ log.fatal("unable to load mandatory Global extension library %s: %s", path.get(), e.what());
throw;
}
else
- log.crit("unable to load optional SHAR extension library %s: %s", path.get(), e.what());
+ log.crit("unable to load optional Global extension library %s: %s", path.get(), e.what());
}
exts=saml::XML::getNextSiblingElement(exts,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Library));
}
}
}
- if (conf.isEnabled(ShibTargetConfig::SHIREExtensions)) {
+ if (conf.isEnabled(ShibTargetConfig::LocalExtensions)) {
exts=saml::XML::getFirstChildElement(SHIRE,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Extensions));
if (exts) {
exts=saml::XML::getFirstChildElement(exts,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Library));
auto_ptr_char path(exts->getAttributeNS(NULL,SHIBT_L(path)));
try {
SAMLConfig::getConfig().saml_register_extension(path.get(),exts);
- log.debug("loaded SHIRE extension library %s",path.get());
+ log.debug("loaded Local extension library %s",path.get());
}
catch (SAMLException& e) {
const XMLCh* fatal=exts->getAttributeNS(NULL,SHIBT_L(fatal));
if (fatal && (*fatal==chLatin_t || *fatal==chDigit_1)) {
- log.fatal("unable to load mandatory SHIRE extension library %s: %s", path.get(), e.what());
+ log.fatal("unable to load mandatory Local extension library %s: %s", path.get(), e.what());
throw;
}
else
- log.crit("unable to load optional SHIRE extension library %s: %s", path.get(), e.what());
+ log.crit("unable to load optional Local extension library %s: %s", path.get(), e.what());
}
exts=saml::XML::getNextSiblingElement(exts,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(Library));
}
}
}
- // For now, just default the replay cache.
- // TODO: make it configurable/pluggable
- m_outer->m_replayCache=IReplayCache::getInstance();
+ // Replay cache.
+ exts=saml::XML::getFirstChildElement(SHAR,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(MySQLReplayCache));
+ if (exts) {
+ log.info("building Replay Cache of type %s...",shibtarget::XML::MySQLReplayCacheType);
+ m_outer->m_replayCache=IReplayCache::getInstance(shibtarget::XML::MySQLSessionCacheType,exts);
+ }
+ else {
+ exts=saml::XML::getFirstChildElement(SHAR,ShibTargetConfig::SHIBTARGET_NS,SHIBT_L(ReplayCache));
+ if (exts) {
+ auto_ptr_char type(exts->getAttributeNS(NULL,SHIBT_L(type)));
+ log.info("building Replay Cache of type %s...",type.get());
+ m_outer->m_replayCache=IReplayCache::getInstance(type.get(),exts);
+ }
+ else {
+ // OpenSAML default provider.
+ log.info("building default Replay Cache...");
+ m_outer->m_replayCache=IReplayCache::getInstance();
+ }
+ }
}
}
}
catch (SAMLException& e) {
log.errorStream() << "Error while loading SP configuration: " << e.what() << CategoryStream::ENDLINE;
- this->~XMLConfigImpl();
throw;
}
#ifndef _DEBUG
catch (...) {
log.error("Unexpected error while loading SP configuration");
- this->~XMLConfigImpl();
throw;
}
#endif
virtual saml::Iterator<shibboleth::ITrust*> getTrustProviders() const=0;
virtual saml::Iterator<shibboleth::IRevocation*> getRevocationProviders() const=0;
virtual saml::Iterator<const XMLCh*> getAudiences() const=0;
- virtual const char* getTLSCred(const shibboleth::IEntityDescriptor* provider) const=0;
- virtual const char* getSigningCred(const shibboleth::IEntityDescriptor* provider) const=0;
+ virtual const IPropertySet* getCredentialUse(const shibboleth::IEntityDescriptor* provider) const=0;
+
// caller is borrowing object, must use within scope of config lock
virtual const saml::SAMLBrowserProfile* getBrowserProfile() const=0;
virtual const saml::SAMLBinding* getBinding(const XMLCh* binding) const=0;
+
// caller is given ownership of object, must use and delete within scope of config lock
virtual saml::SAMLBrowserProfile::ArtifactMapper* getArtifactMapper() const=0;
+
virtual ~IApplication() {}
};
Credentials = 16,
AAP = 32,
RequestMapper = 64,
- SHARExtensions = 128,
- SHIREExtensions = 256,
+ GlobalExtensions = 128,
+ LocalExtensions = 256,
Logging = 512
};
void setFeatures(long enabled) {m_features = enabled;}