X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=shibsp%2Fattribute%2Fresolver%2Fimpl%2FQueryAttributeResolver.cpp;h=8a594cbd9b06dba93a3f85233481f679ded20479;hb=7b31214f32c9e83d9976210f8bebaf24a328c21d;hp=b4cdaa29f0d944b544cf20a5b9fab5bc14212689;hpb=bd74808060d4fed18b78e172e06dcc86c14bcbc0;p=shibboleth%2Fsp.git diff --git a/shibsp/attribute/resolver/impl/QueryAttributeResolver.cpp b/shibsp/attribute/resolver/impl/QueryAttributeResolver.cpp index b4cdaa2..8a594cb 100644 --- a/shibsp/attribute/resolver/impl/QueryAttributeResolver.cpp +++ b/shibsp/attribute/resolver/impl/QueryAttributeResolver.cpp @@ -74,7 +74,7 @@ namespace shibsp { const Application& application, const EntityDescriptor* issuer, const XMLCh* protocol, - const NameID* nameid, + const NameID* nameid=NULL, const XMLCh* authncontext_class=NULL, const XMLCh* authncontext_decl=NULL, const vector* tokens=NULL, @@ -121,10 +121,10 @@ namespace shibsp { if (m_entity) return m_entity; if (m_session && m_session->getEntityID()) { - m_metadata = m_app.getMetadataProvider(); + m_metadata = m_app.getMetadataProvider(false); if (m_metadata) { m_metadata->lock(); - return m_entity = m_metadata->getEntityDescriptor(m_session->getEntityID()); + return m_entity = m_metadata->getEntityDescriptor(MetadataProvider::Criteria(m_session->getEntityID())).first; } } return NULL; @@ -181,7 +181,7 @@ namespace shibsp { const Application& application, const EntityDescriptor* issuer, const XMLCh* protocol, - const NameID* nameid, + const NameID* nameid=NULL, const XMLCh* authncontext_class=NULL, const XMLCh* authncontext_decl=NULL, const vector* tokens=NULL, @@ -216,11 +216,6 @@ namespace shibsp { }; -void SHIBSP_API shibsp::registerAttributeResolvers() -{ - SPConfig::getConfig().AttributeResolverManager.registerFactory(QUERY_ATTRIBUTE_RESOLVER, QueryResolverFactory); -} - QueryResolver::QueryResolver(const DOMElement* e) : m_log(Category::getInstance(SHIBSP_LOGCAT".AttributeResolver")) { #ifdef _DEBUG @@ -261,18 +256,18 @@ bool QueryResolver::SAML1Query(QueryContext& ctx) const #endif int version = XMLString::equals(ctx.getProtocol(), samlconstants::SAML11_PROTOCOL_ENUM) ? 1 : 0; - const AttributeAuthorityDescriptor* AA = ctx.getEntityDescriptor()->getAttributeAuthorityDescriptor(ctx.getProtocol()); + const AttributeAuthorityDescriptor* AA = + find_if(ctx.getEntityDescriptor()->getAttributeAuthorityDescriptors(), isValidForProtocol(ctx.getProtocol())); if (!AA) { m_log.warn("no SAML 1.%d AttributeAuthority role found in metadata", version); return false; } - shibsp::SecurityPolicy policy(ctx.getApplication()); + const Application& application = ctx.getApplication(); + const PropertySet* relyingParty = application.getRelyingParty(ctx.getEntityDescriptor()); + shibsp::SecurityPolicy policy(application); MetadataCredentialCriteria mcc(*AA); shibsp::SOAPClient soaper(policy); - const PropertySet* policySettings = - ctx.getApplication().getServiceProvider().getPolicySettings(ctx.getApplication().getString("policyId").second); - pair signedAssertions = policySettings->getBool("signedAssertions"); auto_ptr_XMLCh binding(samlconstants::SAML1_BINDING_SOAP); saml1p::Response* response=NULL; @@ -282,7 +277,6 @@ bool QueryResolver::SAML1Query(QueryContext& ctx) const if (!XMLString::equals((*ep)->getBinding(),binding.get())) continue; auto_ptr_char loc((*ep)->getLocation()); - auto_ptr_XMLCh issuer(ctx.getApplication().getString("entityID").second); NameIdentifier* nameid = NameIdentifierBuilder::buildNameIdentifier(); nameid->setName(ctx.getNameID()->getName()); nameid->setFormat(ctx.getNameID()->getFormat()); @@ -291,7 +285,7 @@ bool QueryResolver::SAML1Query(QueryContext& ctx) const subject->setNameIdentifier(nameid); saml1p::AttributeQuery* query = saml1p::AttributeQueryBuilder::buildAttributeQuery(); query->setSubject(subject); - query->setResource(issuer.get()); + query->setResource(relyingParty->getXMLString("entityID").second); for (vector::const_iterator ad = m_SAML1Designators.begin(); ad!=m_SAML1Designators.end(); ++ad) query->getAttributeDesignators().push_back((*ad)->cloneAttributeDesignator()); Request* request = RequestBuilder::buildRequest(); @@ -299,7 +293,7 @@ bool QueryResolver::SAML1Query(QueryContext& ctx) const request->setMinorVersion(version); SAML1SOAPClient client(soaper, false); - client.sendSAML(request, mcc, loc.get()); + client.sendSAML(request, application.getId(), mcc, loc.get()); response = client.receiveSAML(); } catch (exception& ex) { @@ -331,16 +325,27 @@ bool QueryResolver::SAML1Query(QueryContext& ctx) const auto_ptr wrapper(response); saml1::Assertion* newtoken = assertions.front(); + pair signedAssertions = relyingParty->getBool("requireSignedAssertions"); if (!newtoken->getSignature() && signedAssertions.first && signedAssertions.second) { m_log.error("assertion unsigned, rejecting it based on signedAssertions policy"); return true; } try { + // We're going to insist that the assertion issuer is the same as the peer. + // Reset the policy's message bits and extract them from the assertion. + policy.reset(true); + policy.setMessageID(newtoken->getAssertionID()); + policy.setIssueInstant(newtoken->getIssueInstantEpoch()); + policy.setIssuer(newtoken->getIssuer()); policy.evaluate(*newtoken); - if (!policy.isSecure()) + + // Now we can check the security status of the policy. + if (!policy.isAuthenticated()) throw SecurityPolicyException("Security of SAML 1.x query result not established."); - saml1::AssertionValidator tokval(ctx.getApplication().getAudiences(), time(NULL)); + + // Lastly, check it over. + saml1::AssertionValidator tokval(relyingParty->getXMLString("entityID").second, application.getAudiences(), time(NULL)); tokval.validateAssertion(*newtoken); } catch (exception& ex) { @@ -354,15 +359,15 @@ bool QueryResolver::SAML1Query(QueryContext& ctx) const // Finally, extract and filter the result. try { - AttributeExtractor* extractor = ctx.getApplication().getAttributeExtractor(); + AttributeExtractor* extractor = application.getAttributeExtractor(); if (extractor) { Locker extlocker(extractor); - extractor->extractAttributes(ctx.getApplication(), AA, *newtoken, ctx.getResolvedAttributes()); + extractor->extractAttributes(application, AA, *newtoken, ctx.getResolvedAttributes()); } - AttributeFilter* filter = ctx.getApplication().getAttributeFilter(); + AttributeFilter* filter = application.getAttributeFilter(); if (filter) { - BasicFilteringContext fc(ctx.getApplication(), ctx.getResolvedAttributes(), AA, ctx.getClassRef(), ctx.getDeclRef()); + BasicFilteringContext fc(application, ctx.getResolvedAttributes(), AA, ctx.getClassRef(), ctx.getDeclRef()); Locker filtlocker(filter); filter->filterAttributes(fc, ctx.getResolvedAttributes()); } @@ -382,20 +387,20 @@ bool QueryResolver::SAML2Query(QueryContext& ctx) const xmltooling::NDC ndc("query"); #endif - const AttributeAuthorityDescriptor* AA = ctx.getEntityDescriptor()->getAttributeAuthorityDescriptor(samlconstants::SAML20P_NS); + const AttributeAuthorityDescriptor* AA = + find_if(ctx.getEntityDescriptor()->getAttributeAuthorityDescriptors(), isValidForProtocol(samlconstants::SAML20P_NS)); if (!AA) { m_log.warn("no SAML 2 AttributeAuthority role found in metadata"); return false; } - shibsp::SecurityPolicy policy(ctx.getApplication()); + const Application& application = ctx.getApplication(); + shibsp::SecurityPolicy policy(application); MetadataCredentialCriteria mcc(*AA); shibsp::SOAPClient soaper(policy); - const PropertySet* policySettings = - ctx.getApplication().getServiceProvider().getPolicySettings(ctx.getApplication().getString("policyId").second); - pair signedAssertions = policySettings->getBool("signedAssertions"); - const PropertySet* relyingParty = ctx.getApplication().getRelyingParty(ctx.getEntityDescriptor()); + const PropertySet* relyingParty = application.getRelyingParty(ctx.getEntityDescriptor()); + pair signedAssertions = relyingParty->getBool("requireSignedAssertions"); pair encryption = relyingParty->getString("encryption"); auto_ptr_XMLCh binding(samlconstants::SAML20_BINDING_SOAP); @@ -406,8 +411,6 @@ bool QueryResolver::SAML2Query(QueryContext& ctx) const if (!XMLString::equals((*ep)->getBinding(),binding.get())) continue; auto_ptr_char loc((*ep)->getLocation()); - auto_ptr_XMLCh issuer(ctx.getApplication().getString("entityID").second); - auto_ptr subject(saml2::SubjectBuilder::buildSubject()); // Encrypt the NameID? @@ -416,7 +419,7 @@ bool QueryResolver::SAML2Query(QueryContext& ctx) const MetadataCredentialCriteria mcc(*AA); encrypted->encrypt( *ctx.getNameID(), - *(ctx.getApplication().getMetadataProvider()), + *(application.getMetadataProvider()), mcc, false, relyingParty->getXMLString("encryptionAlg").second @@ -430,13 +433,13 @@ bool QueryResolver::SAML2Query(QueryContext& ctx) const saml2p::AttributeQuery* query = saml2p::AttributeQueryBuilder::buildAttributeQuery(); query->setSubject(subject.release()); Issuer* iss = IssuerBuilder::buildIssuer(); - iss->setName(issuer.get()); + iss->setName(relyingParty->getXMLString("entityID").second); query->setIssuer(iss); for (vector::const_iterator ad = m_SAML2Designators.begin(); ad!=m_SAML2Designators.end(); ++ad) query->getAttributes().push_back((*ad)->cloneAttribute()); SAML2SOAPClient client(soaper, false); - client.sendSAML(query, mcc, loc.get()); + client.sendSAML(query, application.getId(), mcc, loc.get()); srt = client.receiveSAML(); } catch (exception& ex) { @@ -480,10 +483,20 @@ bool QueryResolver::SAML2Query(QueryContext& ctx) const } try { + // We're going to insist that the assertion issuer is the same as the peer. + // Reset the policy's message bits and extract them from the assertion. + policy.reset(true); + policy.setMessageID(newtoken->getID()); + policy.setIssueInstant(newtoken->getIssueInstantEpoch()); + policy.setIssuer(newtoken->getIssuer()); policy.evaluate(*newtoken); - if (!policy.isSecure()) + + // Now we can check the security status of the policy. + if (!policy.isAuthenticated()) throw SecurityPolicyException("Security of SAML 2.0 query result not established."); - saml2::AssertionValidator tokval(ctx.getApplication().getAudiences(), time(NULL)); + + // Lastly, check it over. + saml2::AssertionValidator tokval(relyingParty->getXMLString("entityID").second, application.getAudiences(), time(NULL)); tokval.validateAssertion(*newtoken); } catch (exception& ex) { @@ -497,15 +510,15 @@ bool QueryResolver::SAML2Query(QueryContext& ctx) const // Finally, extract and filter the result. try { - AttributeExtractor* extractor = ctx.getApplication().getAttributeExtractor(); + AttributeExtractor* extractor = application.getAttributeExtractor(); if (extractor) { Locker extlocker(extractor); - extractor->extractAttributes(ctx.getApplication(), AA, *newtoken, ctx.getResolvedAttributes()); + extractor->extractAttributes(application, AA, *newtoken, ctx.getResolvedAttributes()); } - AttributeFilter* filter = ctx.getApplication().getAttributeFilter(); + AttributeFilter* filter = application.getAttributeFilter(); if (filter) { - BasicFilteringContext fc(ctx.getApplication(), ctx.getResolvedAttributes(), AA, ctx.getClassRef(), ctx.getDeclRef()); + BasicFilteringContext fc(application, ctx.getResolvedAttributes(), AA, ctx.getClassRef(), ctx.getDeclRef()); Locker filtlocker(filter); filter->filterAttributes(fc, ctx.getResolvedAttributes()); }