<item id="org.eclipse.cdt.core.pathentry">
<pathentry kind="out" path=""/>
-<pathentry kind="src" path="apache"/>
-<pathentry kind="src" path="isapi_shib"/>
-<pathentry kind="src" path="nsapi_shib"/>
-<pathentry kind="src" path="odbc-store"/>
-<pathentry excluding="util/|impl/|security/|metadata/|remoting/|remoting/impl/|attribute/" kind="src" path="shibsp"/>
+<pathentry excluding="util/|impl/|security/|metadata/|remoting/|remoting/impl/|attribute/|binding/|binding/impl/" kind="src" path="shibsp"/>
<pathentry kind="src" path="shibsp/attribute"/>
+<pathentry excluding="impl/" kind="src" path="shibsp/binding"/>
+<pathentry kind="src" path="shibsp/binding/impl"/>
<pathentry kind="src" path="shibsp/impl"/>
<pathentry kind="src" path="shibsp/metadata"/>
<pathentry excluding="impl/" kind="src" path="shibsp/remoting"/>
<pathentry kind="src" path="shibsp/security"/>
<pathentry kind="src" path="shibsp/util"/>
<pathentry kind="src" path="shibd"/>
+<pathentry kind="src" path="apache"/>
+<pathentry kind="src" path="isapi_shib"/>
+<pathentry kind="src" path="nsapi_shib"/>
+<pathentry kind="src" path="odbc-store"/>
<pathentry kind="src" path="util"/>
</item>
</data>
Resource requests are mapped in the Local section into an applicationId that
points into to this section.
-->
- <Applications id="default" providerId="https://sp.example.org/shibboleth"
+ <Applications id="default" policyId="default" providerId="https://sp.example.org/shibboleth"
homeURL="https://sp.example.org/index.html">
<!--
impact on the security of the SP. Stealing cookies/sessions is much easier with this
disabled.
-->
- <Sessions lifetime="7200" timeout="3600" checkAddress="false"
+ <Sessions lifetime="28800" timeout="3600" checkAddress="false"
handlerURL="/Shibboleth.sso" handlerSSL="false" idpHistory="true" idpHistoryDays="7">
<!--
</CredentialResolver>
</Credentials>
- <!-- Each policy defines a set of rules to use to secure SAML (and other) messages. -->
- <SecurityPolicies default="full">
- <!-- The predefined policy handles SAML 1 and 2 protocols and permits signing and TLS. -->
- <Policy id="full">
+ <!-- Each policy defines a set of rules to use to secure SAML and SOAP messages. -->
+ <SecurityPolicies>
+ <!-- The predefined policy handles SAML 1 and 2 protocols and permits signing and client TLS. -->
+ <Policy id="default"
+ validate="false"
+ signedAssertions="false"
+ requireConfidentiality="true"
+ requireTransportAuth="true"
+ connectTimeout="15" timeout="30"
+ >
<Rule type="SAML1Message"/>
<Rule type="SAML2Message"/>
<Rule type="MessageFlow" checkReplay="true" expires="60"/>
<element ref="conf:Credentials" minOccurs="0"/>
<element ref="conf:SecurityPolicies"/>
</sequence>
- <attribute name="logger" type="anyURI" use="optional"/>
- <attribute name="clockSkew" type="unsignedInt" use="optional"/>
+ <attribute name="logger" type="anyURI"/>
+ <attribute name="clockSkew" type="unsignedInt"/>
<anyAttribute namespace="##other" processContents="lax"/>
</complexType>\r
</element>\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" use="optional"/>\r
+ <attribute name="fatal" type="boolean" default="true"/>\r
</restriction>\r
</complexContent>\r
</complexType>\r
<any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>\r
</sequence>\r
<attribute name="id" type="conf:string" use="required"/>\r
- <attribute name="cleanupInterval" type="unsignedInt" use="optional" default="900"/>\r
+ <attribute name="cleanupInterval" type="unsignedInt" default="900"/>\r
<anyAttribute namespace="##any" processContents="lax"/>\r
</restriction>\r
</complexContent>\r
<sequence>\r
<any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>\r
</sequence>\r
- <attribute name="cacheTimeout" type="unsignedInt" use="optional" default="28800"/>\r
+ <attribute name="cacheTimeout" type="unsignedInt" default="28800"/>\r
<anyAttribute namespace="##any" processContents="lax"/>\r
</restriction>\r
</complexContent>\r
<complexType>
<attribute name="address" type="conf:string" use="required"/>
<attribute name="port" type="unsignedInt" use="required"/>
- <attribute name="acl" type="conf:listOfStrings" use="optional" default="127.0.0.1"/>
+ <attribute name="acl" type="conf:listOfStrings" default="127.0.0.1"/>
</complexType>
</element>
<element name="Listener" type="conf:PluggableType"/>
<element ref="conf:ReplayCache" minOccurs="0"/>
<any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
- <attribute name="logger" type="anyURI" use="optional"/>
+ <attribute name="logger" type="anyURI"/>
<anyAttribute namespace="##other" processContents="lax"/>\r
</complexType>\r
</element>\r
</element>
<any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
- <attribute name="logger" type="anyURI" use="optional"/>
- <attribute name="localRelayState" type="boolean" use="optional" default="false"/>
+ <attribute name="logger" type="anyURI"/>
+ <attribute name="localRelayState" type="boolean" default="false"/>
<anyAttribute namespace="##other" processContents="lax"/>\r
</complexType>\r
</element>\r
</sequence>\r
<attribute name="id" type="unsignedInt" use="required"/>\r
<attribute name="name" type="conf:string" use="required"/>\r
- <attribute name="port" type="unsignedInt" use="optional"/>\r
- <attribute name="sslport" type="unsignedInt" use="optional"/>\r
- <attribute name="scheme" type="conf:string" use="optional"/>\r
+ <attribute name="port" type="unsignedInt"/>\r
+ <attribute name="sslport" type="unsignedInt"/>\r
+ <attribute name="scheme" type="conf:string"/>\r
</complexType>\r
</element>\r
<any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>\r
</sequence>\r
- <attribute name="normalizeRequest" type="boolean" use="optional"/>\r
+ <attribute name="normalizeRequest" type="boolean" default="true"/>\r
<anyAttribute namespace="##other" processContents="lax"/>\r
</complexType>\r
</element>\r
</element>\r
\r
<attributeGroup name="ContentSettings">\r
- <attribute name="authType" type="conf:string" use="optional"/>\r
- <attribute name="requireSession" type="boolean" use="optional"/>\r
- <attribute name="requireSessionWith" type="conf:string" use="optional"/>\r
- <attribute name="exportAssertion" type="boolean" use="optional"/>\r
- <attribute name="redirectToSSL" type="unsignedInt" use="optional"/>\r
+ <attribute name="authType" type="conf:string"/>\r
+ <attribute name="requireSession" type="boolean"/>\r
+ <attribute name="requireSessionWith" type="conf:string"/>\r
+ <attribute name="exportAssertion" type="boolean"/>\r
+ <attribute name="redirectToSSL" type="unsignedInt"/>\r
<anyAttribute namespace="##other" processContents="lax"/>\r
</attributeGroup>\r
<element name="AccessControlProvider" type="conf:PluggableType"/>\r
</choice>\r
<element ref="conf:Path" minOccurs="0" maxOccurs="unbounded"/>\r
</sequence>\r
- <attribute name="scheme" use="optional">\r
+ <attribute name="scheme">\r
<simpleType>\r
<restriction base="conf:string">\r
<enumeration value="http"/>\r
</simpleType>\r
</attribute>\r
<attribute name="name" type="conf:string" use="required"/>\r
- <attribute name="port" type="unsignedInt" use="optional"/>\r
- <attribute name="applicationId" type="conf:string" use="optional"/>\r
+ <attribute name="port" type="unsignedInt"/>\r
+ <attribute name="applicationId" type="conf:string"/>\r
<attributeGroup ref="conf:ContentSettings"/>\r
</complexType>\r
</element>\r
<element ref="conf:Path" minOccurs="0" maxOccurs="unbounded"/>\r
</sequence>\r
<attribute name="name" type="conf:string" use="required"/>\r
- <attribute name="applicationId" type="conf:string" use="optional"/>\r
+ <attribute name="applicationId" type="conf:string"/>\r
<attributeGroup ref="conf:ContentSettings"/>\r
</complexType>\r
</element>\r
</sequence>\r
<attribute name="id" type="conf:string" fixed="default"/>\r
<attribute name="providerId" type="anyURI" use="required"/>\r
- <attribute name="homeURL" type="anyURI" use="optional"/>\r
+ <attribute name="policyId" type="conf:string" use="required"/>\r
+ <attribute name="homeURL" type="anyURI"/>\r
<anyAttribute namespace="##other" processContents="lax"/>\r
</complexType>\r
</element>\r
<element name="TrustEngine" type="conf:PluggableType" minOccurs="0"/>\r
</sequence>\r
<attribute name="id" type="conf:string" use="required"/>\r
- <attribute name="providerId" type="anyURI" use="optional"/>\r
- <attribute name="homeURL" type="anyURI" use="optional"/>\r
+ <attribute name="providerId" type="anyURI"/>\r
+ <attribute name="policyId" type="conf:string"/>\r
+ <attribute name="homeURL" type="anyURI"/>\r
<anyAttribute namespace="##other" processContents="lax"/>\r
</complexType>\r
</element>\r
</complexType>\r
</element>\r
</choice>\r
- <attribute name="handlerURL" type="anyURI" use="optional"/>\r
- <attribute name="handlerSSL" type="boolean" use="optional" default="true"/>\r
- <attribute name="cookieName" type="conf:string" use="optional"/>\r
- <attribute name="cookieProps" type="conf:string" use="optional"/>\r
- <attribute name="idpHistory" type="boolean" use="optional" default="true"/>\r
- <attribute name="idpHistoryDays" type="unsignedInt" use="optional"/>\r
- <attribute name="lifetime" type="unsignedInt" use="optional"/>\r
- <attribute name="timeout" type="unsignedInt" use="optional"/>\r
- <attribute name="checkAddress" type="boolean" use="optional"/>\r
- <attribute name="consistentAddress" type="boolean" use="optional" default="true"/>\r
- <attribute name="validate" type="boolean" use="optional"/>\r
+ <attribute name="handlerURL" type="anyURI"/>\r
+ <attribute name="handlerSSL" type="boolean" default="true"/>\r
+ <attribute name="cookieName" type="conf:string"/>\r
+ <attribute name="cookieProps" type="conf:string"/>\r
+ <attribute name="idpHistory" type="boolean" default="true"/>\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="checkAddress" type="boolean" default="true"/>\r
+ <attribute name="consistentAddress" type="boolean" default="true"/>\r
<anyAttribute namespace="##other" processContents="lax"/>\r
</complexType>\r
</element>\r
</sequence>\r
<attribute name="Location" type="anyURI" use="required"/>\r
<attribute name="Binding" type="anyURI" use="required"/>\r
- <attribute name="wayfURL" type="anyURI" use="optional"/>\r
- <attribute name="wayfBinding" type="anyURI" use="optional"/>\r
- <attribute name="checkCDC" type="anyURI" use="optional"/>\r
- <attribute name="isDefault" type="boolean" use="optional"/>\r
- <attribute name="id" type="conf:string" use="optional"/>\r
+ <attribute name="wayfURL" type="anyURI"/>\r
+ <attribute name="wayfBinding" type="anyURI"/>\r
+ <attribute name="isDefault" type="boolean"/>\r
+ <attribute name="id" type="conf:string"/>\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="session" type="anyURI" use="required"/>\r
- <attribute name="metadata" type="anyURI" use="optional"/>\r
- <attribute name="rm" type="anyURI" use="optional"/>\r
- <attribute name="access" type="anyURI" use="optional"/>\r
- <attribute name="ssl" type="anyURI" use="optional"/>\r
- <attribute name="supportContact" type="conf:string" use="optional"/>\r
- <attribute name="logoLocation" type="anyURI" use="optional"/>\r
- <attribute name="styleSheet" type="anyURI" use="optional"/>\r
+ <attribute name="metadata" type="anyURI"/>\r
+ <attribute name="rm" type="anyURI"/>\r
+ <attribute name="access" type="anyURI"/>\r
+ <attribute name="ssl" type="anyURI"/>\r
+ <attribute name="supportContact" type="conf:string"/>\r
+ <attribute name="logoLocation" type="anyURI"/>\r
+ <attribute name="styleSheet" type="anyURI"/>\r
<anyAttribute namespace="##any" processContents="lax"/>\r
</complexType>\r
</element>\r
\r
<attributeGroup name="CredentialUseGroup">\r
- <attribute name="TLS" type="conf:string" use="optional"/>\r
- <attribute name="Signing" type="conf:string" use="optional"/>\r
- <attribute name="signRequest" type="boolean" use="optional" default="false"/>\r
- <attribute name="signatureAlg" type="anyURI" use="optional"/>\r
- <attribute name="signedAssertions" type="boolean" use="optional" default="false"/>\r
- <attribute name="authType" use="optional">\r
+ <attribute name="TLS" type="conf:string"/>\r
+ <attribute name="Signing" type="conf:string"/>\r
+ <attribute name="signRequest" type="boolean" default="false"/>\r
+ <attribute name="signatureAlg" type="anyURI"/>\r
+ <attribute name="authType">\r
<simpleType>\r
<restriction base="conf:string">\r
<enumeration value="basic"/>\r
</restriction>\r
</simpleType>\r
</attribute>\r
- <attribute name="authUsername" use="optional"/>\r
- <attribute name="authPassword" use="optional"/>\r
+ <attribute name="authUsername"/>\r
+ <attribute name="authPassword"/>\r
</attributeGroup>\r
\r
<element name="CredentialUse">\r
<element name="Rule" type="conf:PluggableType" minOccurs="1" maxOccurs="unbounded"/>
</sequence>
<attribute name="id" type="conf:string" use="required"/>\r
+ <attribute name="validate" type="boolean" default="false"/>\r
+ <attribute name="signedAssertions" type="boolean" default="false"/>\r
+ <attribute name="requireConfidentiality" type="boolean" default="true"/>\r
+ <attribute name="requireTransportAuth" type="boolean" default="true"/>\r
+ <attribute name="connectTimeout" type="unsignedShort" default="15"/>\r
+ <attribute name="timeout" type="unsignedShort" default="30"/>\r
+ <anyAttribute namespace="##any" processContents="lax"/>\r
</complexType>\r
</element>\r
</sequence>\r
- <attribute name="default" type="conf:string" use="required"/>\r
</complexType>\r
</element>\r
\r
attrincludedir = $(includedir)/shibsp/attribute
+bindincludedir = $(includedir)/shibsp/binding
+
mdincludedir = $(includedir)/shibsp/metadata
remincludedir = $(includedir)/shibsp/remoting
attribute/ScopedAttribute.h \
attribute/SimpleAttribute.h
+bindinclude_HEADERS = \
+ binding/SOAPClient.h
+
mdinclude_HEADERS = \
metadata/MetadataExt.h
SessionCache.cpp \
SPConfig.cpp \
attribute/Attribute.cpp \
+ binding/impl/SOAPClient.cpp \
impl/RemotedSessionCache.cpp \
impl/StorageServiceSessionCache.cpp \
impl/XMLAccessControl.cpp \
virtual xmlsignature::CredentialResolver* getCredentialResolver(const char* id) const=0;
/**
+ * Returns the security policy settings for an identified policy.
+ *
+ * @param id identifies the policy to return
+ * @return a PropertySet
+ */
+ virtual const PropertySet* getPolicySettings(const char* id) const=0;
+
+ /**
* Returns the security policy rules for an identified policy.
*
- * @param id identifies the policy rules to return, or NULL for the default policy
+ * @param id identifies the policy to return
* @return an array of policy rules
*/
- virtual std::vector<const opensaml::SecurityPolicyRule*>& getPolicyRules(const char* id=NULL) const=0;
+ virtual const std::vector<const opensaml::SecurityPolicyRule*>& getPolicyRules(const char* id) const=0;
/**
* Returns a RequestMapper instance.
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * @file shibsp/binding/SOAPClient.h
+ *
+ * Specialized SOAPClient for SP environment.
+ */
+
+#ifndef __shibsp_soap11client_h__
+#define __shibsp_soap11client_h__
+
+#include <shibsp/Application.h>
+#include <saml/binding/SOAPClient.h>
+
+namespace shibsp {
+
+ /**
+ * Specialized SOAPClient for SP environment.
+ */
+ class SHIBSP_API SOAPClient : public opensaml::SOAPClient
+ {
+ public:
+ /**
+ * Creates a SOAP client instance for an Application to use.
+ *
+ * @param application reference to Application
+ * @param policy reference to (empty) SecurityPolicy to apply
+ */
+ SOAPClient(const Application& application, opensaml::SecurityPolicy& policy);
+
+ virtual ~SOAPClient() {
+ if (m_credResolver)
+ m_credResolver->unlock();
+ }
+
+ /**
+ * Override handles message signing for SAML payloads.
+ *
+ * @param env SOAP envelope to send
+ * @param peer peer to send message to, expressed in TrustEngine terms
+ * @param endpoint URL of endpoint to recieve message
+ */
+ void send(const soap11::Envelope& env, const xmltooling::KeyInfoSource& peer, const char* endpoint);
+
+ void reset();
+
+ protected:
+ /**
+ * Override prepares transport by applying policy settings from Application.
+ *
+ * @param transport reference to transport layer
+ */
+ void prepareTransport(const xmltooling::SOAPTransport& transport);
+
+ /** Application supplied to client. */
+ const Application& m_app;
+
+ /** Properties associated with the Application's security policy. */
+ const PropertySet* m_settings;
+
+ /** CredentialUse properties, set after transport prep. */
+ const PropertySet* m_credUse;
+
+ /** Locked CredentialResolver for transport, set after transport prep. */
+ xmlsignature::CredentialResolver* m_credResolver;
+ };
+
+};
+
+#endif /* __shibsp_soap11client_h__ */
--- /dev/null
+/*
+ * 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.
+ */
+
+/**
+ * SOAPClient.cpp
+ *
+ * Specialized SOAPClient for SP environment.
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "ServiceProvider.h"
+#include "binding/SOAPClient.h"
+
+#include <log4cpp/Category.hh>
+#include <saml/saml2/metadata/Metadata.h>
+#include <xmltooling/soap/SOAP.h>
+#include <xmltooling/soap/HTTPSOAPTransport.h>
+#include <xmltooling/util/NDC.h>
+
+using namespace shibsp;
+using namespace opensaml::saml2md;
+using namespace xmlsignature;
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+SOAPClient::SOAPClient(const Application& application, opensaml::SecurityPolicy& policy)
+ : opensaml::SOAPClient(policy), m_app(application), m_settings(NULL), m_credUse(NULL), m_credResolver(NULL)
+{
+ SPConfig& conf = SPConfig::getConfig();
+ pair<bool,const char*> policyId = m_app.getString("policyId");
+ m_settings = conf.getServiceProvider()->getPolicySettings(policyId.second);
+ const vector<const opensaml::SecurityPolicyRule*>& rules = conf.getServiceProvider()->getPolicyRules(policyId.second);
+ for (vector<const opensaml::SecurityPolicyRule*>::const_iterator rule=rules.begin(); rule!=rules.end(); ++rule)
+ policy.addRule(*rule);
+ policy.setMetadataProvider(application.getMetadataProvider());
+ policy.setTrustEngine(application.getTrustEngine());
+}
+
+namespace {
+ class SHIBSP_DLLLOCAL _addcert : public binary_function<X509Data*,XSECCryptoX509*,void> {
+ public:
+ void operator()(X509Data* bag, XSECCryptoX509* cert) const {
+ safeBuffer& buf=cert->getDEREncodingSB();
+ X509Certificate* x=X509CertificateBuilder::buildX509Certificate();
+ x->setValue(buf.sbStrToXMLCh());
+ bag->getX509Certificates().push_back(x);
+ }
+ };
+};
+
+void SOAPClient::send(const soap11::Envelope& env, const KeyInfoSource& peer, const char* endpoint)
+{
+ if (!m_peer)
+ m_peer = dynamic_cast<const RoleDescriptor*>(&peer);
+
+ if (m_peer) {
+ const EntityDescriptor* entity = m_peer ? dynamic_cast<const EntityDescriptor*>(m_peer->getParent()) : NULL;
+ m_credUse = entity ? m_app.getCredentialUse(entity) : NULL;
+ }
+
+ // Check for message signing requirements.
+ if (m_credUse) {
+ pair<bool,bool> flag = m_credUse->getBool("signRequests");
+ if (flag.first && flag.second) {
+ CredentialResolver* cr=NULL;
+ pair<bool,const char*> cred = m_credUse->getString("Signing");
+ if (cred.first && (cr==SPConfig::getConfig().getServiceProvider()->getCredentialResolver(cred.second))) {
+ // Looks like we're supposed to sign, so check for message.
+ const vector<XMLObject*>& bodies=const_cast<const soap11::Body*>(env.getBody())->getUnknownXMLObjects();
+ if (!bodies.empty()) {
+ opensaml::SignableObject* msg = dynamic_cast<opensaml::SignableObject*>(bodies.front());
+ if (msg) {
+ // Build a Signature.
+ Signature* sig = SignatureBuilder::buildSignature();
+ msg->setSignature(sig);
+ pair<bool,const XMLCh*> alg = m_credUse->getXMLString("sigAlgorithm");
+ if (alg.first)
+ sig->setSignatureAlgorithm(alg.second);
+ Locker locker(cr);
+ sig->setSigningKey(cr->getKey());
+
+ // Build KeyInfo.
+ const vector<XSECCryptoX509*>& certs = cr->getCertificates();
+ if (!certs.empty()) {
+ KeyInfo* keyInfo=KeyInfoBuilder::buildKeyInfo();
+ sig->setKeyInfo(keyInfo);
+ X509Data* x509Data=X509DataBuilder::buildX509Data();
+ keyInfo->getX509Datas().push_back(x509Data);
+ for_each(certs.begin(),certs.end(),bind1st(_addcert(),x509Data));
+ }
+
+ // Sign it. The marshalling step in the base class should be a no-op.
+ vector<Signature*> sigs(1,sig);
+ env.marshall((DOMDocument*)NULL,&sigs);
+ }
+ }
+ }
+ }
+ }
+
+ opensaml::SOAPClient::send(env, peer, endpoint);
+}
+
+void SOAPClient::prepareTransport(const SOAPTransport& transport)
+{
+#ifdef _DEBUG
+ xmltooling::NDC("prepareTransport");
+#endif
+ Category& log=Category::getInstance(SHIBSP_LOGCAT".SOAPClient");
+ log.debug("prepping SOAP transport for use by application (%s)", m_app.getId());
+
+ pair<bool,bool> flag = m_settings->getBool("requireConfidentiality");
+ if ((!flag.first || flag.second) && !transport.isConfidential())
+ throw opensaml::BindingException("Transport confidentiality required, but not available.");
+
+ flag = m_settings->getBool("validate");
+ setValidating(flag.first && flag.second);
+ flag = m_settings->getBool("requireTransportAuth");
+ forceTransportAuthentication(!flag.first || flag.second);
+
+ opensaml::SOAPClient::prepareTransport(transport);
+
+ if (!m_credUse) {
+ const EntityDescriptor* entity = m_peer ? dynamic_cast<const EntityDescriptor*>(m_peer->getParent()) : NULL;
+ m_credUse = entity ? m_app.getCredentialUse(entity) : NULL;
+ }
+ if (m_credUse) {
+ pair<bool,const char*> authType=m_credUse->getString("authType");
+ if (authType.first) {
+ SOAPTransport::transport_auth_t type=SOAPTransport::transport_auth_none;
+ pair<bool,const char*> username=m_credUse->getString("authUsername");
+ pair<bool,const char*> password=m_credUse->getString("authPassword");
+ if (!username.first || !password.first)
+ log.error("transport authType (%s) specified but authUsername or authPassword was missing", authType.second);
+ else if (!strcmp(authType.second,"basic"))
+ type = SOAPTransport::transport_auth_basic;
+ else if (!strcmp(authType.second,"digest"))
+ type = SOAPTransport::transport_auth_digest;
+ else if (!strcmp(authType.second,"ntlm"))
+ type = SOAPTransport::transport_auth_ntlm;
+ else if (!strcmp(authType.second,"gss"))
+ type = SOAPTransport::transport_auth_gss;
+ else
+ log.error("unknown authType (%s) specified in CredentialUse element", authType.second);
+ if (type > SOAPTransport::transport_auth_none) {
+ if (transport.setAuth(type,username.second,password.second))
+ log.debug("configured for transport authentication (method=%s, username=%s)", authType.second, username.second);
+ else
+ log.error("failed to configure transport authentication (method=%s)", authType.second);
+ }
+ }
+
+ authType = m_credUse->getString("TLS");
+ if (authType.first) {
+ m_credResolver = SPConfig::getConfig().getServiceProvider()->getCredentialResolver(authType.second);
+ if (m_credResolver) {
+ m_credResolver->lock();
+ if (!transport.setCredentialResolver(m_credResolver)) {
+ m_credResolver->unlock();
+ m_credResolver = NULL;
+ log.error("failed to load CredentialResolver into SOAPTransport");
+ }
+ }
+ else {
+ log.error("unable to access CredentialResolver (%s)", authType.second);
+ }
+ }
+ }
+
+ transport.setConnectTimeout(m_settings->getUnsignedInt("connectTimeout").second);
+ transport.setTimeout(m_settings->getUnsignedInt("timeout").second);
+
+ const HTTPSOAPTransport* http = dynamic_cast<const HTTPSOAPTransport*>(&transport);
+ if (http)
+ http->setRequestHeader("Shibboleth", PACKAGE_VERSION);
+}
+
+void SOAPClient::reset()
+{
+ m_credUse = NULL;
+ if (m_credResolver)
+ m_credResolver->unlock();
+ m_credResolver = NULL;
+ opensaml::SOAPClient::reset();
+}
\ No newline at end of file
RequestMapper* m_requestMapper;\r
map<string,Application*> m_appmap;\r
map<string,CredentialResolver*> m_credResolverMap;\r
- map< string,vector<const SecurityPolicyRule*> > m_policyMap;\r
- string m_policyDefault;\r
+ map< string,pair< PropertySet*,vector<const SecurityPolicyRule*> > > m_policyMap;\r
\r
// Provides filter to exclude special config elements.\r
short acceptNode(const DOMNode* node) const;\r
return NULL;\r
}\r
\r
- vector<const SecurityPolicyRule*>& getPolicyRules(const char* id=NULL) const {\r
- if (!id)\r
- id = m_impl->m_policyDefault.c_str();\r
- if (m_impl->m_policyMap.count(id))\r
- return m_impl->m_policyMap[id];\r
+ const PropertySet* getPolicySettings(const char* id) const {\r
+ map<string,pair<PropertySet*,vector<const SecurityPolicyRule*> > >::const_iterator i = m_impl->m_policyMap.find(id);\r
+ if (i!=m_impl->m_policyMap.end())\r
+ return i->second.first;\r
+ throw ConfigurationException("Security Policy ($1) not found, check <SecurityPolicies> element.", params(1,id));\r
+ }\r
+\r
+ const vector<const SecurityPolicyRule*>& getPolicyRules(const char* id) const {\r
+ map<string,pair<PropertySet*,vector<const SecurityPolicyRule*> > >::const_iterator i = m_impl->m_policyMap.find(id);\r
+ if (i!=m_impl->m_policyMap.end())\r
+ return i->second.second;\r
throw ConfigurationException("Security Policy ($1) not found, check <SecurityPolicies> element.", params(1,id));\r
}\r
\r
static const XMLCh Applications[] = UNICODE_LITERAL_12(A,p,p,l,i,c,a,t,i,o,n,s);\r
static const XMLCh Credentials[] = UNICODE_LITERAL_11(C,r,e,d,e,n,t,i,a,l,s);\r
static const XMLCh CredentialUse[] = UNICODE_LITERAL_13(C,r,e,d,e,n,t,i,a,l,U,s,e);\r
- static const XMLCh _default[] = UNICODE_LITERAL_7(d,e,f,a,u,l,t);\r
static const XMLCh fatal[] = UNICODE_LITERAL_5(f,a,t,a,l);\r
static const XMLCh _Handler[] = UNICODE_LITERAL_7(H,a,n,d,l,e,r);\r
static const XMLCh _id[] = UNICODE_LITERAL_2(i,d);\r
static const XMLCh _MetadataProvider[] = UNICODE_LITERAL_16(M,e,t,a,d,a,t,a,P,r,o,v,i,d,e,r);\r
static const XMLCh _path[] = UNICODE_LITERAL_4(p,a,t,h);\r
static const XMLCh _type[] = UNICODE_LITERAL_4(t,y,p,e);\r
+\r
+ class SHIBSP_DLLLOCAL PolicyNodeFilter : public DOMNodeFilter\r
+ {\r
+ public:\r
+ short acceptNode(const DOMNode* node) const {\r
+ if (XMLHelper::isNodeNamed(node,shibspconstants::SHIB2SPCONFIG_NS,Rule))\r
+ return FILTER_REJECT;\r
+ return FILTER_ACCEPT;\r
+ }\r
+ };\r
};\r
\r
namespace shibsp {\r
// Load security policies.\r
child = XMLHelper::getLastChildElement(e,SecurityPolicies);\r
if (child) {\r
- auto_ptr_char def(child->getAttributeNS(NULL,_default));\r
- m_policyDefault = def.get();\r
+ PolicyNodeFilter filter;\r
child = XMLHelper::getFirstChildElement(child,Policy);\r
while (child) {\r
auto_ptr_char id(child->getAttributeNS(NULL,_id));\r
- vector<const SecurityPolicyRule*>& rules = m_policyMap[id.get()];\r
+ pair< PropertySet*,vector<const SecurityPolicyRule*> >& rules = m_policyMap[id.get()];\r
+ rules.first = NULL;\r
+ auto_ptr<DOMPropertySet> settings(new DOMPropertySet());\r
+ settings->load(child, log, &filter);\r
+ rules.first = settings.release();\r
const DOMElement* rule = XMLHelper::getFirstChildElement(child,Rule);\r
while (rule) {\r
auto_ptr_char type(rule->getAttributeNS(NULL,_type));\r
try {\r
- rules.push_back(samlConf.SecurityPolicyRuleManager.newPlugin(type.get(),rule));\r
+ rules.second.push_back(samlConf.SecurityPolicyRuleManager.newPlugin(type.get(),rule));\r
}\r
catch (exception& ex) {\r
log.crit("error instantiating policy rule (%s) in policy (%s): %s", type.get(), id.get(), ex.what());\r
}\r
child = XMLHelper::getNextSiblingElement(child,Policy);\r
}\r
- if (!m_policyMap.count(m_policyDefault))\r
- throw ConfigurationException("Default security policy ($1) not found in conf:SecurityPolicies element.", params(1,m_policyDefault.c_str()));\r
}\r
\r
// Load the default application. This actually has a fixed ID of "default". ;-)\r
{\r
for_each(m_appmap.begin(),m_appmap.end(),cleanup_pair<string,Application>());\r
for_each(m_credResolverMap.begin(),m_credResolverMap.end(),cleanup_pair<string,CredentialResolver>());\r
- for (map< string,vector<const SecurityPolicyRule*> >::iterator i=m_policyMap.begin(); i!=m_policyMap.end(); ++i)\r
- for_each(i->second.begin(), i->second.end(), xmltooling::cleanup<SecurityPolicyRule>());\r
+ for (map< string,pair<PropertySet*,vector<const SecurityPolicyRule*> > >::iterator i=m_policyMap.begin(); i!=m_policyMap.end(); ++i) {\r
+ delete i->second.first;\r
+ for_each(i->second.second.begin(), i->second.second.end(), xmltooling::cleanup<SecurityPolicyRule>());\r
+ }\r
delete m_requestMapper;\r
if (m_document)\r
m_document->release();\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4cppD.lib xerces-c_2D.lib saml2D.lib xmltooling1D.lib wsock32.lib libeay32_0_9_8D.lib ssleay32_0_9_8D.lib"\r
+ AdditionalDependencies="log4cppD.lib xerces-c_2D.lib xsec_1D.lib saml2D.lib xmltooling1D.lib wsock32.lib libeay32_0_9_8D.lib ssleay32_0_9_8D.lib"\r
OutputFile="$(OutDir)\$(ProjectName)1_0D.dll"\r
LinkIncremental="2"\r
AdditionalLibraryDirectories=""..\..\cpp-opensaml1\saml\Debug";"..\..\cpp-opensaml2\Debug";"..\..\cpp-xmltooling\Debug""\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="log4cpp.lib xerces-c_2.lib saml2.lib xmltooling1.lib wsock32.lib libeay32_0_9_8.lib ssleay32_0_9_8.lib"\r
+ AdditionalDependencies="log4cpp.lib xerces-c_2.lib xsec_1.lib saml2.lib xmltooling1.lib wsock32.lib libeay32_0_9_8.lib ssleay32_0_9_8.lib"\r
OutputFile="$(OutDir)\$(ProjectName)1_0.dll"\r
LinkIncremental="1"\r
AdditionalLibraryDirectories=""..\..\cpp-opensaml1\saml\Release";"..\..\cpp-opensaml2\Release";"..\..\cpp-xmltooling\Release""\r
>\r
</File>\r
</Filter>\r
+ <Filter\r
+ Name="binding"\r
+ >\r
+ <Filter\r
+ Name="impl"\r
+ >\r
+ <File\r
+ RelativePath=".\binding\impl\SOAPClient.cpp"\r
+ >\r
+ </File>\r
+ </Filter>\r
+ </Filter>\r
</Filter>\r
<Filter\r
Name="Header Files"\r
>\r
</File>\r
</Filter>\r
+ <Filter\r
+ Name="binding"\r
+ >\r
+ <File\r
+ RelativePath=".\binding\SOAPClient.h"\r
+ >\r
+ </File>\r
+ </Filter>\r
</Filter>\r
<Filter\r
Name="Resource Files"\r
#include <shibsp/exceptions.h>\r
#include <shibsp/SPConfig.h>\r
#include <shibsp/ServiceProvider.h>\r
+#include <shibsp/binding/SOAPClient.h>\r
#include <shibsp/util/SPConstants.h>\r
\r
#include <saml/binding/SecurityPolicy.h>\r
}\r
\r
ServiceProvider* sp=conf.getServiceProvider();\r
- xmltooling::Locker locker(sp);\r
+ sp->lock();\r
\r
try {\r
const Application* app=sp->getApplication(a_param);\r
else\r
throw MetadataException("No AttributeAuthority role found in metadata.");\r
\r
- QName role(samlconstants::SAML20P_NS, AttributeAuthorityDescriptor::LOCAL_NAME);\r
- SecurityPolicy policy(sp->getPolicyRules(), m, &role, app->getTrustEngine());\r
+ SecurityPolicy policy;\r
+ shibsp::SOAPClient soaper(*app,policy);\r
\r
if (ver == v20) {\r
auto_ptr_XMLCh binding(samlconstants::SAML20_BINDING_SOAP);\r
- SAML2SOAPClient soaper(policy,true);\r
opensaml::saml2p::StatusResponseType* srt=NULL;\r
const vector<AttributeService*>& endpoints=AA->getAttributeServices();\r
for (vector<AttributeService*>::const_iterator ep=endpoints.begin(); !srt && ep!=endpoints.end(); ++ep) {\r
subject->setNameID(nameid);\r
query->setSubject(subject);\r
query->setIssuer(iss);\r
- auto_ptr<opensaml::saml2p::AttributeQuery> wrapper(query);\r
- soaper.sendSAML(query, *AA, loc.get());\r
- wrapper.release(); // freed by SOAP client\r
- srt = soaper.receiveSAML();\r
+ SAML2SOAPClient client(soaper);\r
+ client.sendSAML(query, *AA, loc.get());\r
+ srt = client.receiveSAML();\r
}\r
catch (exception& ex) {\r
cerr << ex.what() << endl;\r
}\r
else {\r
auto_ptr_XMLCh binding(samlconstants::SAML1_BINDING_SOAP);\r
- SAML1SOAPClient soaper(policy,true);\r
const opensaml::saml1p::Response* response=NULL;\r
const vector<AttributeService*>& endpoints=AA->getAttributeServices();\r
for (vector<AttributeService*>::const_iterator ep=endpoints.begin(); !response && ep!=endpoints.end(); ++ep) {\r
query->setSubject(subject);\r
query->setResource(issuer.get());\r
request->setMinorVersion(ver==v11 ? 1 : 0);\r
- auto_ptr<Request> wrapper(request);\r
- soaper.sendSAML(request, *AA, loc.get());\r
- wrapper.release(); // freed by SOAP client\r
- response = soaper.receiveSAML();\r
+ SAML1SOAPClient client(soaper);\r
+ client.sendSAML(request, *AA, loc.get());\r
+ response = client.receiveSAML();\r
}\r
catch (exception& ex) {\r
cerr << ex.what() << endl;\r
cerr << ex.what() << endl;\r
}\r
\r
+ sp->unlock();\r
conf.term();\r
return 0;\r
}\r