From: Scott Cantor Date: Sun, 11 Mar 2007 05:50:09 +0000 (+0000) Subject: Streamline setIssuer call in policy. X-Git-Tag: 2.0-alpha1~68 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fcpp-opensaml.git;a=commitdiff_plain;h=a66789863e59746d4215de44d9758c40d2b477c6 Streamline setIssuer call in policy. --- diff --git a/saml/binding/SecurityPolicy.h b/saml/binding/SecurityPolicy.h index 2fcdbb7..1c02ab8 100644 --- a/saml/binding/SecurityPolicy.h +++ b/saml/binding/SecurityPolicy.h @@ -292,11 +292,17 @@ namespace opensaml { /** * Sets the issuer of the message as determined by the registered policies. - * The policy object takes ownership of the Issuer object. * * @param issuer issuer of the message */ - void setIssuer(saml2::Issuer* issuer); + void setIssuer(const saml2::Issuer* issuer); + + /** + * Sets the issuer of the message as determined by the registered policies. + * + * @param issuer issuer of the message + */ + void setIssuer(const XMLCh* issuer); /** * Sets the metadata for the role the issuer is operating in. @@ -333,6 +339,19 @@ namespace opensaml { * @return true iff the operands match */ virtual bool issuerMatches(const saml2::Issuer* issuer1, const saml2::Issuer* issuer2) const; + + /** + * Returns true iff the two operands "match". Applications can override this method to + * support non-standard issuer matching for complex policies. + * + *

The default implementation does a basic comparison of the XML content, treating + * an unsupplied Format as an "entityID". + * + * @param issuer1 the first Issuer to match + * @param issuer2 the second Issuer to match + * @return true iff the operands match + */ + virtual bool issuerMatches(const saml2::Issuer* issuer1, const XMLCh* issuer2) const; }; /** diff --git a/saml/binding/impl/SOAPClient.cpp b/saml/binding/impl/SOAPClient.cpp index 22e4f8a..79e1c51 100644 --- a/saml/binding/impl/SOAPClient.cpp +++ b/saml/binding/impl/SOAPClient.cpp @@ -81,9 +81,7 @@ soap11::Envelope* SOAPClient::receive() // Set issuer based on peer identity. EntityDescriptor* parent = dynamic_cast(m_peer->getParent()); if (parent) { - Issuer* issuer = IssuerBuilder::buildIssuer(); - issuer->setName(parent->getEntityID()); - m_policy.setIssuer(issuer); + m_policy.setIssuer(parent->getEntityID()); m_policy.setIssuerMetadata(m_peer); m_policy.setSecure(true); } diff --git a/saml/binding/impl/SecurityPolicy.cpp b/saml/binding/impl/SecurityPolicy.cpp index ef98f7b..bfdeb90 100644 --- a/saml/binding/impl/SecurityPolicy.cpp +++ b/saml/binding/impl/SecurityPolicy.cpp @@ -77,13 +77,27 @@ void SecurityPolicy::evaluate(const XMLObject& message, const GenericRequest* re (*i)->evaluate(message,request,*this); } -void SecurityPolicy::setIssuer(saml2::Issuer* issuer) +void SecurityPolicy::setIssuer(const Issuer* issuer) { - if (!getIssuerMatchingPolicy().issuerMatches(issuer, m_issuer)) + if (!getIssuerMatchingPolicy().issuerMatches(m_issuer, issuer)) throw SecurityPolicyException("A rule supplied an Issuer that conflicts with previous results."); - delete m_issuer; - m_issuer=issuer; + if (!m_issuer) { + m_issuerRole = NULL; + m_issuer=issuer->cloneIssuer(); + } +} + +void SecurityPolicy::setIssuer(const XMLCh* issuer) +{ + if (!getIssuerMatchingPolicy().issuerMatches(m_issuer, issuer)) + throw SecurityPolicyException("A rule supplied an Issuer that conflicts with previous results."); + + if (!m_issuer && issuer && *issuer) { + m_issuerRole = NULL; + m_issuer = IssuerBuilder::buildIssuer(); + m_issuer->setName(issuer); + } } void SecurityPolicy::setIssuerMetadata(const RoleDescriptor* issuerRole) @@ -121,3 +135,28 @@ bool SecurityPolicy::IssuerMatchingPolicy::issuerMatches(const Issuer* issuer1, return true; } + +bool SecurityPolicy::IssuerMatchingPolicy::issuerMatches(const Issuer* issuer1, const XMLCh* issuer2) const +{ + // NULL matches anything for the purposes of this interface. + if (!issuer1 || !issuer2 || !*issuer2) + return true; + + const XMLCh* op1=issuer1->getName(); + if (!op1 || !XMLString::equals(op1,issuer2)) + return false; + + op1=issuer1->getFormat(); + if (op1 && *op1 && !XMLString::equals(op1, NameIDType::ENTITY)) + return false; + + op1=issuer1->getNameQualifier(); + if (op1 && *op1) + return false; + + op1=issuer1->getSPNameQualifier(); + if (op1 && *op1) + return false; + + return true; +} diff --git a/saml/saml1/binding/impl/SAML1MessageRule.cpp b/saml/saml1/binding/impl/SAML1MessageRule.cpp index a022c11..e7897f5 100644 --- a/saml/saml1/binding/impl/SAML1MessageRule.cpp +++ b/saml/saml1/binding/impl/SAML1MessageRule.cpp @@ -91,15 +91,8 @@ void SAML1MessageRule::evaluate(const XMLObject& message, const GenericRequest* a = assertions.front(); } - if (a && a->getIssuer()) { - if (!policy.getIssuer() || policy.getIssuer()->getFormat() || - !XMLString::equals(policy.getIssuer()->getName(), a->getIssuer())) { - // We either have a conflict, or a first-time set of Issuer. - auto_ptr issuer(saml2::IssuerBuilder::buildIssuer()); - issuer->setName(a->getIssuer()); - policy.setIssuer(issuer.get()); - issuer.release(); // owned by policy now - } + if (a) { + policy.setIssuer(a->getIssuer()); pair minor = a->getMinorVersion(); protocol = (minor.first && minor.second==0) ? samlconstants::SAML10_PROTOCOL_ENUM : samlconstants::SAML11_PROTOCOL_ENUM; @@ -111,7 +104,7 @@ void SAML1MessageRule::evaluate(const XMLObject& message, const GenericRequest* } if (log.isDebugEnabled()) { - auto_ptr_char iname(policy.getIssuer()->getName()); + auto_ptr_char iname(a->getIssuer()); log.debug("message from (%s)", iname.get()); } @@ -122,9 +115,9 @@ void SAML1MessageRule::evaluate(const XMLObject& message, const GenericRequest* if (policy.getMetadataProvider() && policy.getRole()) { log.debug("searching metadata for message issuer..."); - const EntityDescriptor* entity = policy.getMetadataProvider()->getEntityDescriptor(policy.getIssuer()->getName()); + const EntityDescriptor* entity = policy.getMetadataProvider()->getEntityDescriptor(a->getIssuer()); if (!entity) { - auto_ptr_char temp(policy.getIssuer()->getName()); + auto_ptr_char temp(a->getIssuer()); log.warn("no metadata found, can't establish identity of issuer (%s)", temp.get()); return; } diff --git a/saml/saml2/binding/impl/SAML2MessageRule.cpp b/saml/saml2/binding/impl/SAML2MessageRule.cpp index 26a2ba4..55caab5 100644 --- a/saml/saml2/binding/impl/SAML2MessageRule.cpp +++ b/saml/saml2/binding/impl/SAML2MessageRule.cpp @@ -72,32 +72,27 @@ void SAML2MessageRule::evaluate(const XMLObject& message, const GenericRequest* policy.setIssueInstant(samlRoot.getIssueInstantEpoch()); log.debug("extracting issuer from message"); - Issuer* issuer = samlRoot.getIssuer(); - if (issuer && issuer->getName()) { - auto_ptr copy(issuer->cloneIssuer()); - policy.setIssuer(copy.get()); - copy.release(); + const Issuer* issuer = samlRoot.getIssuer(); + if (issuer) { + policy.setIssuer(issuer); } else if (XMLString::equals(q.getLocalPart(), Response::LOCAL_NAME)) { // No issuer in the message, so we have to try the Response approach. const vector& assertions = dynamic_cast(samlRoot).getAssertions(); if (!assertions.empty()) { issuer = assertions.front()->getIssuer(); - if (issuer && issuer->getName()) { - auto_ptr copy(issuer->cloneIssuer()); - policy.setIssuer(copy.get()); - copy.release(); - } + if (issuer) + policy.setIssuer(issuer); } } - if (!policy.getIssuer()) { + if (!issuer) { log.warn("issuer identity not extracted"); return; } if (log.isDebugEnabled()) { - auto_ptr_char iname(policy.getIssuer()->getName()); + auto_ptr_char iname(issuer->getName()); log.debug("message from (%s)", iname.get()); } @@ -107,15 +102,15 @@ void SAML2MessageRule::evaluate(const XMLObject& message, const GenericRequest* } if (policy.getMetadataProvider() && policy.getRole()) { - if (policy.getIssuer()->getFormat() && !XMLString::equals(policy.getIssuer()->getFormat(), saml2::NameIDType::ENTITY)) { + if (issuer->getFormat() && !XMLString::equals(issuer->getFormat(), NameIDType::ENTITY)) { log.warn("non-system entity issuer, skipping metadata lookup"); return; } log.debug("searching metadata for message issuer..."); - const EntityDescriptor* entity = policy.getMetadataProvider()->getEntityDescriptor(policy.getIssuer()->getName()); + const EntityDescriptor* entity = policy.getMetadataProvider()->getEntityDescriptor(issuer->getName()); if (!entity) { - auto_ptr_char temp(policy.getIssuer()->getName()); + auto_ptr_char temp(issuer->getName()); log.warn("no metadata found, can't establish identity of issuer (%s)", temp.get()); return; }