From eaa32d56f698e6aca3d8a0685b1d07f4f494b21f Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Thu, 3 Jan 2008 21:00:49 +0000 Subject: [PATCH 1/1] Move settings from Policy to RelyingParty to allow per-RP values. --- configs/shibboleth2.xml.in | 20 +++++++++++--------- schemas/shibboleth-2.0-native-sp-config.xsd | 12 ++++++------ .../resolver/impl/QueryAttributeResolver.cpp | 7 ++----- shibsp/binding/impl/SOAPClient.cpp | 14 ++++++++------ shibsp/handler/impl/MetadataGenerator.cpp | 3 +-- shibsp/handler/impl/SAML1Consumer.cpp | 5 +++-- shibsp/handler/impl/SAML2Consumer.cpp | 17 +++++++++++++++-- 7 files changed, 46 insertions(+), 32 deletions(-) diff --git a/configs/shibboleth2.xml.in b/configs/shibboleth2.xml.in index bd35126..3bd41eb 100644 --- a/configs/shibboleth2.xml.in +++ b/configs/shibboleth2.xml.in @@ -201,7 +201,16 @@ styleSheet="/shibboleth-sp/main.css"/> - + @@ -276,14 +285,7 @@ - + diff --git a/schemas/shibboleth-2.0-native-sp-config.xsd b/schemas/shibboleth-2.0-native-sp-config.xsd index 54bdd2b..652024e 100644 --- a/schemas/shibboleth-2.0-native-sp-config.xsd +++ b/schemas/shibboleth-2.0-native-sp-config.xsd @@ -662,6 +662,12 @@ + + + + + + @@ -681,12 +687,6 @@ - - - - - - diff --git a/shibsp/attribute/resolver/impl/QueryAttributeResolver.cpp b/shibsp/attribute/resolver/impl/QueryAttributeResolver.cpp index e6ccb70..46f46aa 100644 --- a/shibsp/attribute/resolver/impl/QueryAttributeResolver.cpp +++ b/shibsp/attribute/resolver/impl/QueryAttributeResolver.cpp @@ -272,9 +272,6 @@ bool QueryResolver::SAML1Query(QueryContext& ctx) const shibsp::SecurityPolicy policy(application); MetadataCredentialCriteria mcc(*AA); shibsp::SOAPClient soaper(policy); - const PropertySet* policySettings = - application.getServiceProvider().getPolicySettings(application.getString("policyId").second); - pair signedAssertions = policySettings->getBool("signedAssertions"); auto_ptr_XMLCh binding(samlconstants::SAML1_BINDING_SOAP); saml1p::Response* response=NULL; @@ -333,6 +330,7 @@ bool QueryResolver::SAML1Query(QueryContext& ctx) const auto_ptr wrapper(response); saml1::Assertion* newtoken = assertions.front(); + pair signedAssertions = application.getRelyingParty(ctx.getEntityDescriptor())->getBool("signedAssertions"); if (!newtoken->getSignature() && signedAssertions.first && signedAssertions.second) { m_log.error("assertion unsigned, rejecting it based on signedAssertions policy"); return true; @@ -405,10 +403,9 @@ bool QueryResolver::SAML2Query(QueryContext& ctx) const shibsp::SecurityPolicy policy(application); MetadataCredentialCriteria mcc(*AA); shibsp::SOAPClient soaper(policy); - const PropertySet* policySettings = application.getServiceProvider().getPolicySettings(application.getString("policyId").second); - pair signedAssertions = policySettings->getBool("signedAssertions"); const PropertySet* relyingParty = application.getRelyingParty(ctx.getEntityDescriptor()); + pair signedAssertions = relyingParty->getBool("signedAssertions"); pair encryption = relyingParty->getString("encryption"); auto_ptr_XMLCh binding(samlconstants::SAML20_BINDING_SOAP); diff --git a/shibsp/binding/impl/SOAPClient.cpp b/shibsp/binding/impl/SOAPClient.cpp index ac4a438..63e7405 100644 --- a/shibsp/binding/impl/SOAPClient.cpp +++ b/shibsp/binding/impl/SOAPClient.cpp @@ -109,13 +109,13 @@ void SOAPClient::prepareTransport(SOAPTransport& transport) Category& log=Category::getInstance(SHIBSP_LOGCAT".SOAPClient"); log.debug("prepping SOAP transport for use by application (%s)", m_app.getId()); - pair flag = m_settings->getBool("requireConfidentiality"); + pair flag = m_relyingParty->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"); + flag = m_relyingParty->getBool("requireTransportAuth"); forceTransportAuthentication(!flag.first || flag.second); opensaml::SOAPClient::prepareTransport(transport); @@ -169,14 +169,16 @@ void SOAPClient::prepareTransport(SOAPTransport& transport) } } - transport.setConnectTimeout(m_settings->getUnsignedInt("connectTimeout").second); - transport.setTimeout(m_settings->getUnsignedInt("timeout").second); + pair timeout = m_relyingParty->getUnsignedInt("connectTimeout"); + transport.setConnectTimeout(timeout.first ? timeout.second : 10); + timeout = m_relyingParty->getUnsignedInt("timeout"); + transport.setTimeout(timeout.first ? timeout.second : 20); m_app.getServiceProvider().setTransportOptions(m_app.getString("policyId").second, transport); HTTPSOAPTransport* http = dynamic_cast(&transport); if (http) { - flag = m_settings->getBool("chunkedEncoding"); - http->useChunkedEncoding(!flag.first || flag.second); + flag = m_relyingParty->getBool("chunkedEncoding"); + http->useChunkedEncoding(flag.first && flag.second); http->setRequestHeader("User-Agent", PACKAGE_NAME); http->setRequestHeader(PACKAGE_NAME, PACKAGE_VERSION); } diff --git a/shibsp/handler/impl/MetadataGenerator.cpp b/shibsp/handler/impl/MetadataGenerator.cpp index ca5c926..3cdbc98 100644 --- a/shibsp/handler/impl/MetadataGenerator.cpp +++ b/shibsp/handler/impl/MetadataGenerator.cpp @@ -223,8 +223,7 @@ pair MetadataGenerator::processMessage(const Application& application prop = application.getRelyingParty(NULL)->getString("signing"); if (prop.first && (!strcmp(prop.second,"true") || !strcmp(prop.second,"front"))) role->AuthnRequestsSigned(true); - pair flagprop = - application.getServiceProvider().getPolicySettings(application.getString("policyId").second)->getBool("signedAssertions"); + pair flagprop = application.getRelyingParty(NULL)->getBool("signedAssertions"); if (flagprop.first && flagprop.second) role->WantAssertionsSigned(true); diff --git a/shibsp/handler/impl/SAML1Consumer.cpp b/shibsp/handler/impl/SAML1Consumer.cpp index 4bcc88c..7788b7e 100644 --- a/shibsp/handler/impl/SAML1Consumer.cpp +++ b/shibsp/handler/impl/SAML1Consumer.cpp @@ -152,7 +152,8 @@ void SAML1Consumer::implementProtocol( BrowserSSOProfileValidator ssoValidator(application.getAudiences(), now); // With this flag on, we ignore any unsigned assertions. - pair flag = settings->getBool("signedAssertions"); + const EntityDescriptor* entity = policy.getIssuerMetadata() ? dynamic_cast(policy.getIssuerMetadata()->getParent()) : NULL; + pair flag = application.getRelyingParty(entity)->getBool("signedAssertions"); // authnskew allows rejection of SSO if AuthnInstant is too old. const PropertySet* sessionProps = application.getPropertySet("Sessions"); @@ -273,7 +274,7 @@ void SAML1Consumer::implementProtocol( httpRequest, httpResponse, now + lifetime.second, - policy.getIssuerMetadata() ? dynamic_cast(policy.getIssuerMetadata()->getParent()) : NULL, + entity, (!response->getMinorVersion().first || response->getMinorVersion().second==1) ? samlconstants::SAML11_PROTOCOL_ENUM : samlconstants::SAML10_PROTOCOL_ENUM, nameid.get(), diff --git a/shibsp/handler/impl/SAML2Consumer.cpp b/shibsp/handler/impl/SAML2Consumer.cpp index d8fc3ec..cc2118c 100644 --- a/shibsp/handler/impl/SAML2Consumer.cpp +++ b/shibsp/handler/impl/SAML2Consumer.cpp @@ -138,7 +138,12 @@ void SAML2Consumer::implementProtocol( BrowserSSOProfileValidator ssoValidator(application.getAudiences(), now, dest.substr(0,dest.find('?')).c_str()); // With this flag on, we ignore any unsigned assertions. - pair flag = settings->getBool("signedAssertions"); + const EntityDescriptor* entity = NULL; + pair flag = make_pair(false,false); + if (alreadySecured && policy.getIssuerMetadata()) { + entity = dynamic_cast(policy.getIssuerMetadata()->getParent()); + flag = application.getRelyingParty(entity)->getBool("signedAssertions"); + } // authnskew allows rejection of SSO if AuthnInstant is too old. const PropertySet* sessionProps = application.getPropertySet("Sessions"); @@ -168,6 +173,14 @@ void SAML2Consumer::implementProtocol( if (!alreadySecured && !policy.isAuthenticated()) throw SecurityPolicyException("Unable to establish security of incoming assertion."); + // If we hadn't established Issuer yet, redo the signedAssertions check. + if (!entity && policy.getIssuerMetadata()) { + entity = dynamic_cast(policy.getIssuerMetadata()->getParent()); + flag = application.getRelyingParty(entity)->getBool("signedAssertions"); + if (!(*a)->getSignature() && flag.first && flag.second) + throw SecurityPolicyException("The incoming assertion was unsigned, violating local security policy."); + } + // Now do profile and core semantic validation to ensure we can use it for SSO. ssoValidator.validateAssertion(*(*a)); @@ -359,7 +372,7 @@ void SAML2Consumer::implementProtocol( httpRequest, httpResponse, sessionExp, - policy.getIssuerMetadata() ? dynamic_cast(policy.getIssuerMetadata()->getParent()) : NULL, + entity, samlconstants::SAML20P_NS, ssoName, ssoStatement->getAuthnInstant() ? ssoStatement->getAuthnInstant()->getRawData() : NULL, -- 2.1.4