From 9d61992f725e8b73421e9262a711f4cbdd782b18 Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Thu, 9 Aug 2007 04:19:16 +0000 Subject: [PATCH] Multi-line svn commit, see body. Streamline SecurityPolicy methods and rule modification. Pass a protocol family string through from decoders and clients to policy rules. Add partial policy reset to avoid spurious message replay errors. Speed up message extraction rules by skipping incompatible protocols. --- saml/binding/SecurityPolicy.h | 73 ++++++------------------ saml/binding/SecurityPolicyRule.h | 18 +++++- saml/binding/impl/ClientCertAuthRule.cpp | 9 ++- saml/binding/impl/MessageFlowRule.cpp | 9 ++- saml/binding/impl/NullSecurityRule.cpp | 14 ++--- saml/binding/impl/SecurityPolicy.cpp | 20 +++---- saml/binding/impl/SimpleSigningRule.cpp | 9 ++- saml/binding/impl/XMLSigningRule.cpp | 9 ++- saml/saml1/binding/impl/SAML1MessageRule.cpp | 31 +++++----- saml/saml1/binding/impl/SAML1POSTDecoder.cpp | 7 ++- saml/saml1/binding/impl/SAML1SOAPClient.cpp | 8 ++- saml/saml1/binding/impl/SAML1SOAPDecoder.cpp | 16 +++++- saml/saml2/binding/impl/SAML2ArtifactDecoder.cpp | 6 +- saml/saml2/binding/impl/SAML2MessageRule.cpp | 25 ++++---- saml/saml2/binding/impl/SAML2POSTDecoder.cpp | 2 +- saml/saml2/binding/impl/SAML2RedirectDecoder.cpp | 2 +- saml/saml2/binding/impl/SAML2SOAPClient.cpp | 3 +- saml/saml2/binding/impl/SAML2SOAPDecoder.cpp | 5 +- samltest/saml1/binding/SAML1ArtifactTest.h | 5 +- samltest/saml1/binding/SAML1POSTTest.h | 3 +- samltest/saml2/binding/SAML2ArtifactTest.h | 5 +- samltest/saml2/binding/SAML2POSTTest.h | 6 +- samltest/saml2/binding/SAML2RedirectTest.h | 3 +- 23 files changed, 161 insertions(+), 127 deletions(-) diff --git a/saml/binding/SecurityPolicy.h b/saml/binding/SecurityPolicy.h index b9e323b..5f75c34 100644 --- a/saml/binding/SecurityPolicy.h +++ b/saml/binding/SecurityPolicy.h @@ -75,32 +75,8 @@ namespace opensaml { const xmltooling::QName* role=NULL, const xmltooling::TrustEngine* trustEngine=NULL, bool validate=true - ) : m_messageQName(NULL), m_messageID(NULL), m_issueInstant(0), - m_issuer(NULL), m_issuerRole(NULL), m_secure(false), m_matchingPolicy(NULL), - m_metadata(metadataProvider), m_role(NULL), m_trust(trustEngine), m_validate(validate) { - if (role) - m_role = new xmltooling::QName(*role); - } - - /** - * Constructor for policy using existing rules. The lifetime of the policy rules - * must be at least as long as the policy object. - * - * @param rules reference to array of policy rules to use - * @param metadataProvider locked MetadataProvider instance - * @param role identifies the role (generally IdP or SP) of the policy peer - * @param trustEngine TrustEngine to authenticate policy peer - * @param validate true iff XML parsing should be done with validation - */ - SecurityPolicy( - const std::vector& rules, - const saml2md::MetadataProvider* metadataProvider=NULL, - const xmltooling::QName* role=NULL, - const xmltooling::TrustEngine* trustEngine=NULL, - bool validate=true - ) : m_messageQName(NULL), m_messageID(NULL), m_issueInstant(0), - m_issuer(NULL), m_issuerRole(NULL), m_secure(false), m_matchingPolicy(NULL), - m_rules(rules), m_metadata(metadataProvider), m_role(NULL), m_trust(trustEngine), m_validate(validate) { + ) : m_messageID(NULL), m_issueInstant(0), m_issuer(NULL), m_issuerRole(NULL), m_secure(false), + m_matchingPolicy(NULL), m_metadata(metadataProvider), m_role(NULL), m_trust(trustEngine), m_validate(validate) { if (role) m_role = new xmltooling::QName(*role); } @@ -144,13 +120,14 @@ namespace opensaml { } /** - * Adds a SecurityPolicyRule to the policy. The lifetime of the policy rule - * must be at least as long as the policy object. + * Gets a mutable array of installed policy rules. + * + *

If adding rules, their lifetime must be at least as long as the policy object. * - * @param rule SecurityPolicyRule to add + * @return mutable array of rules */ - void addRule(const SecurityPolicyRule* rule) { - m_rules.push_back(rule); + std::vector& getRules() { + return m_rules; } /** @@ -198,26 +175,25 @@ namespace opensaml { * * @param message the incoming message * @param request the protocol request + * @param protocol the protocol family in use * * @throws BindingException raised if the message/request is invalid according to the supplied rules */ - void evaluate(const xmltooling::XMLObject& message, const xmltooling::GenericRequest* request=NULL); + void evaluate( + const xmltooling::XMLObject& message, const xmltooling::GenericRequest* request=NULL, const XMLCh* protocol=NULL + ); /** - * Resets the policy object and clears any per-message state. + * Resets the policy object and/or clears any per-message state. + * + *

Resets can be complete (the default) or merely clear the previous message ID and timestamp + * when evaluating multiple layers of a message. + * + * @param messageOnly true iff security and issuer state should be left in place */ - void reset(); + void reset(bool messageOnly=false); /** - * Returns the message element/type as determined by the registered policies. - * - * @return message element/type as determined by the registered policies - */ - const xmltooling::QName* getMessageQName() const { - return m_messageQName; - } - - /** * Returns the message identifier as determined by the registered policies. * * @return message identifier as determined by the registered policies @@ -263,16 +239,6 @@ namespace opensaml { } /** - * Sets the message element/type as determined by the registered policies. - * - * @param messageQName message element/type - */ - void setMessageQName(const xmltooling::QName* messageQName) { - delete m_messageQName; - m_messageQName = messageQName ? new xmltooling::QName(*messageQName) : NULL; - } - - /** * Sets the message identifier as determined by the registered policies. * * @param id message identifier @@ -383,7 +349,6 @@ namespace opensaml { private: // information extracted from message - xmltooling::QName* m_messageQName; XMLCh* m_messageID; time_t m_issueInstant; saml2::Issuer* m_issuer; diff --git a/saml/binding/SecurityPolicyRule.h b/saml/binding/SecurityPolicyRule.h index 129af0f..095e115 100644 --- a/saml/binding/SecurityPolicyRule.h +++ b/saml/binding/SecurityPolicyRule.h @@ -43,16 +43,28 @@ namespace opensaml { virtual ~SecurityPolicyRule() {} /** + * Returns the rule's class/type. + * + * @return the class/type of the object + */ + virtual const char* getType() const=0; + + /** * Evaluates the rule against the given request and message. * + *

An exception will be raised if the message is invalid according to + * a policy rule. + * * @param message the incoming message * @param request the protocol request + * @param protocol the protocol family in use * @param policy SecurityPolicy to provide various components and track message data - * - * @throws BindingException raised if the message/request is not acceptable to the policy rule */ virtual void evaluate( - const xmltooling::XMLObject& message, const xmltooling::GenericRequest* request, SecurityPolicy& policy + const xmltooling::XMLObject& message, + const xmltooling::GenericRequest* request, + const XMLCh* protocol, + SecurityPolicy& policy ) const=0; }; diff --git a/saml/binding/impl/ClientCertAuthRule.cpp b/saml/binding/impl/ClientCertAuthRule.cpp index b3ad352..f736092 100644 --- a/saml/binding/impl/ClientCertAuthRule.cpp +++ b/saml/binding/impl/ClientCertAuthRule.cpp @@ -44,7 +44,10 @@ namespace opensaml { ClientCertAuthRule(const DOMElement* e) {} virtual ~ClientCertAuthRule() {} - void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; + const char* getType() const { + return CLIENTCERTAUTH_POLICY_RULE; + } + void evaluate(const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy) const; }; SecurityPolicyRule* SAML_DLLLOCAL ClientCertAuthRuleFactory(const DOMElement* const & e) @@ -53,7 +56,9 @@ namespace opensaml { } }; -void ClientCertAuthRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const +void ClientCertAuthRule::evaluate( + const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy + ) const { Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.ClientCertAuth"); diff --git a/saml/binding/impl/MessageFlowRule.cpp b/saml/binding/impl/MessageFlowRule.cpp index af43c8e..a2e1ff6 100644 --- a/saml/binding/impl/MessageFlowRule.cpp +++ b/saml/binding/impl/MessageFlowRule.cpp @@ -40,7 +40,10 @@ namespace opensaml { MessageFlowRule(const DOMElement* e); virtual ~MessageFlowRule() {} - void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; + const char* getType() const { + return MESSAGEFLOW_POLICY_RULE; + } + void evaluate(const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy) const; private: bool m_checkReplay; @@ -69,7 +72,9 @@ MessageFlowRule::MessageFlowRule(const DOMElement* e) } } -void MessageFlowRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const +void MessageFlowRule::evaluate( + const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy + ) const { Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.MessageFlow"); log.debug("evaluating message flow policy (replay checking %s, expiration %lu)", m_checkReplay ? "on" : "off", m_expires); diff --git a/saml/binding/impl/NullSecurityRule.cpp b/saml/binding/impl/NullSecurityRule.cpp index f113234..7d984ab 100644 --- a/saml/binding/impl/NullSecurityRule.cpp +++ b/saml/binding/impl/NullSecurityRule.cpp @@ -37,7 +37,13 @@ namespace opensaml { NullSecurityRule(const DOMElement* e) : m_log(Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.NullSecurity")) {} virtual ~NullSecurityRule() {} - void evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; + const char* getType() const { + return NULLSECURITY_POLICY_RULE; + } + void evaluate(const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy) const { + m_log.warn("security enforced using NULL policy rule, be sure you know what you're doing"); + policy.setSecure(true); + } private: Category& m_log; @@ -48,9 +54,3 @@ namespace opensaml { return new NullSecurityRule(e); } }; - -void NullSecurityRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const -{ - m_log.warn("security enforced using NULL policy rule, be sure you know what you're doing"); - policy.setSecure(true); -} diff --git a/saml/binding/impl/SecurityPolicy.cpp b/saml/binding/impl/SecurityPolicy.cpp index d2b3bc3..343687d 100644 --- a/saml/binding/impl/SecurityPolicy.cpp +++ b/saml/binding/impl/SecurityPolicy.cpp @@ -57,26 +57,26 @@ SecurityPolicy::IssuerMatchingPolicy SecurityPolicy::m_defaultMatching; SecurityPolicy::~SecurityPolicy() { - reset(); + reset(false); } -void SecurityPolicy::reset() +void SecurityPolicy::reset(bool messageOnly) { - delete m_messageQName; XMLString::release(&m_messageID); - delete m_issuer; - m_messageQName=NULL; m_messageID=NULL; m_issueInstant=0; - m_issuer=NULL; - m_issuerRole=NULL; - m_secure=false; + if (!messageOnly) { + delete m_issuer; + m_issuer=NULL; + m_issuerRole=NULL; + m_secure=false; + } } -void SecurityPolicy::evaluate(const XMLObject& message, const GenericRequest* request) +void SecurityPolicy::evaluate(const XMLObject& message, const GenericRequest* request, const XMLCh* protocol) { for (vector::const_iterator i=m_rules.begin(); i!=m_rules.end(); ++i) - (*i)->evaluate(message,request,*this); + (*i)->evaluate(message,request,protocol,*this); } void SecurityPolicy::setIssuer(const Issuer* issuer) diff --git a/saml/binding/impl/SimpleSigningRule.cpp b/saml/binding/impl/SimpleSigningRule.cpp index 32ef466..9255cef 100644 --- a/saml/binding/impl/SimpleSigningRule.cpp +++ b/saml/binding/impl/SimpleSigningRule.cpp @@ -49,7 +49,10 @@ namespace opensaml { SimpleSigningRule(const DOMElement* e); virtual ~SimpleSigningRule() {} - void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; + const char* getType() const { + return SIMPLESIGNING_POLICY_RULE; + } + void evaluate(const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy) const; private: // Appends a raw parameter=value pair to the string. @@ -89,7 +92,9 @@ SimpleSigningRule::SimpleSigningRule(const DOMElement* e) : m_errorsFatal(false) } } -void SimpleSigningRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const +void SimpleSigningRule::evaluate( + const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy + ) const { Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.SimpleSigning"); diff --git a/saml/binding/impl/XMLSigningRule.cpp b/saml/binding/impl/XMLSigningRule.cpp index f5a3027..9fe67c1 100644 --- a/saml/binding/impl/XMLSigningRule.cpp +++ b/saml/binding/impl/XMLSigningRule.cpp @@ -47,7 +47,10 @@ namespace opensaml { XMLSigningRule(const DOMElement* e); virtual ~XMLSigningRule() {} - void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; + const char* getType() const { + return XMLSIGNING_POLICY_RULE; + } + void evaluate(const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy) const; private: bool m_errorsFatal; @@ -69,7 +72,9 @@ XMLSigningRule::XMLSigningRule(const DOMElement* e) : m_errorsFatal(false) } } -void XMLSigningRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const +void XMLSigningRule::evaluate( + const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy + ) const { Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.XMLSigning"); diff --git a/saml/saml1/binding/impl/SAML1MessageRule.cpp b/saml/saml1/binding/impl/SAML1MessageRule.cpp index 665b912..c9604c7 100644 --- a/saml/saml1/binding/impl/SAML1MessageRule.cpp +++ b/saml/saml1/binding/impl/SAML1MessageRule.cpp @@ -48,7 +48,10 @@ namespace opensaml { SAML1MessageRule(const DOMElement* e) {} virtual ~SAML1MessageRule() {} - void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; + const char* getType() const { + return SAML1MESSAGE_POLICY_RULE; + } + void evaluate(const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy) const; }; SecurityPolicyRule* SAML_DLLLOCAL SAML1MessageRuleFactory(const DOMElement* const & e) @@ -57,17 +60,20 @@ namespace opensaml { } }; -void SAML1MessageRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const +void SAML1MessageRule::evaluate( + const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy + ) const { - Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.SAML1Message"); - - const QName& q = message.getElementQName(); - policy.setMessageQName(&q); - + // Only handle SAML 1.x protocol and SAML 1.x messages. + if (!XMLString::equals(protocol, samlconstants::SAML11_PROTOCOL_ENUM) && + !XMLString::equals(protocol, samlconstants::SAML10_PROTOCOL_ENUM)) + return; + const QName& q = message.getElementQName(); if (!XMLString::equals(q.getNamespaceURI(), samlconstants::SAML1P_NS) && - !XMLString::equals(q.getNamespaceURI(), samlconstants::SAML1_NS)) { + !XMLString::equals(q.getNamespaceURI(), samlconstants::SAML1_NS)) return; - } + + Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.SAML1Message"); try { const RootObject& samlRoot = dynamic_cast(message); @@ -76,7 +82,6 @@ void SAML1MessageRule::evaluate(const XMLObject& message, const GenericRequest* log.debug("extracting issuer from message"); - const XMLCh* protocol = NULL; const saml1::Assertion* a = NULL; // Handle assertions directly. @@ -93,12 +98,8 @@ void SAML1MessageRule::evaluate(const XMLObject& message, const GenericRequest* if (a) { policy.setIssuer(a->getIssuer()); - pair minor = a->getMinorVersion(); - protocol = (minor.first && minor.second==0) ? - samlconstants::SAML10_PROTOCOL_ENUM : samlconstants::SAML11_PROTOCOL_ENUM; } - - if (!protocol) { + else { log.warn("issuer identity not extracted"); return; } diff --git a/saml/saml1/binding/impl/SAML1POSTDecoder.cpp b/saml/saml1/binding/impl/SAML1POSTDecoder.cpp index c700433..a454a6f 100644 --- a/saml/saml1/binding/impl/SAML1POSTDecoder.cpp +++ b/saml/saml1/binding/impl/SAML1POSTDecoder.cpp @@ -111,7 +111,12 @@ XMLObject* SAML1POSTDecoder::decode( SchemaValidators.validate(xmlObject.get()); // Run through the policy. - policy.evaluate(*response, &genericRequest); + pair minor = response->getMinorVersion(); + policy.evaluate( + *response, + &genericRequest, + (minor.first && minor.second==0) ? samlconstants::SAML10_PROTOCOL_ENUM : samlconstants::SAML11_PROTOCOL_ENUM + ); // Check recipient URL. auto_ptr_char recipient(response->getRecipient()); diff --git a/saml/saml1/binding/impl/SAML1SOAPClient.cpp b/saml/saml1/binding/impl/SAML1SOAPClient.cpp index 07e4121..9984d2b 100644 --- a/saml/saml1/binding/impl/SAML1SOAPClient.cpp +++ b/saml/saml1/binding/impl/SAML1SOAPClient.cpp @@ -61,7 +61,13 @@ Response* SAML1SOAPClient::receiveSAML() if (m_correlate && response->getInResponseTo() && !XMLString::equals(m_correlate, response->getInResponseTo())) throw SecurityPolicyException("InResponseTo attribute did not correlate with the Request ID."); - m_soaper.getPolicy().evaluate(*response); + m_soaper.getPolicy().reset(true); + pair minor = response->getMinorVersion(); + m_soaper.getPolicy().evaluate( + *response, + NULL, + (minor.first && minor.second==0) ? samlconstants::SAML10_PROTOCOL_ENUM : samlconstants::SAML11_PROTOCOL_ENUM + ); if (!m_soaper.getPolicy().isSecure()) { SecurityPolicyException ex("Security policy could not authenticate the message."); diff --git a/saml/saml1/binding/impl/SAML1SOAPDecoder.cpp b/saml/saml1/binding/impl/SAML1SOAPDecoder.cpp index 47f2c60..4d88e7d 100644 --- a/saml/saml1/binding/impl/SAML1SOAPDecoder.cpp +++ b/saml/saml1/binding/impl/SAML1SOAPDecoder.cpp @@ -105,8 +105,18 @@ XMLObject* SAML1SOAPDecoder::decode( Request* request = dynamic_cast(body->getUnknownXMLObjects().front()); if (request) { // Run through the policy at two layers. - policy.evaluate(*env, &genericRequest); - policy.evaluate(*request, &genericRequest); + pair minor = request->getMinorVersion(); + policy.evaluate( + *env, + &genericRequest, + (minor.first && minor.second==0) ? samlconstants::SAML10_PROTOCOL_ENUM : samlconstants::SAML11_PROTOCOL_ENUM + ); + policy.reset(true); + policy.evaluate( + *request, + &genericRequest, + (minor.first && minor.second==0) ? samlconstants::SAML10_PROTOCOL_ENUM : samlconstants::SAML11_PROTOCOL_ENUM + ); xmlObject.release(); body->detach(); // frees Envelope request->detach(); // frees Body @@ -114,5 +124,5 @@ XMLObject* SAML1SOAPDecoder::decode( } } - throw BindingException("SOAP Envelope did not contain a SAML Request."); + throw BindingException("SOAP Envelope did not contain a SAML 1.x Request."); } diff --git a/saml/saml2/binding/impl/SAML2ArtifactDecoder.cpp b/saml/saml2/binding/impl/SAML2ArtifactDecoder.cpp index 553d8a5..ae7545a 100644 --- a/saml/saml2/binding/impl/SAML2ArtifactDecoder.cpp +++ b/saml/saml2/binding/impl/SAML2ArtifactDecoder.cpp @@ -152,11 +152,13 @@ XMLObject* SAML2ArtifactDecoder::decode( m_artifactResolver->resolve(*(artifact2.get()), dynamic_cast(*roledesc), policy) ); - // The policy should be enforced against the ArtifactResponse by the resolve step. + // The policy should be enforced against the ArtifactResponse by the resolve step. + // Reset only the message state. + policy.reset(true); // Extract payload and check that message. XMLObject* payload = response->getPayload(); - policy.evaluate(*payload, &genericRequest); + policy.evaluate(*payload, &genericRequest, samlconstants::SAML20P_NS); // Return the payload only. response.release(); diff --git a/saml/saml2/binding/impl/SAML2MessageRule.cpp b/saml/saml2/binding/impl/SAML2MessageRule.cpp index 76649b1..1c921f4 100644 --- a/saml/saml2/binding/impl/SAML2MessageRule.cpp +++ b/saml/saml2/binding/impl/SAML2MessageRule.cpp @@ -45,7 +45,10 @@ namespace opensaml { SAML2MessageRule(const DOMElement* e) {} virtual ~SAML2MessageRule() {} - void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; + const char* getType() const { + return SAML2MESSAGE_POLICY_RULE; + } + void evaluate(const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy) const; }; SecurityPolicyRule* SAML_DLLLOCAL SAML2MessageRuleFactory(const DOMElement* const & e) @@ -54,18 +57,20 @@ namespace opensaml { } }; -void SAML2MessageRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const +void SAML2MessageRule::evaluate( + const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy + ) const { - Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.SAML2Message"); - - const QName& q = message.getElementQName(); - policy.setMessageQName(&q); - + // Only handle SAML 2.0 protocol and 2.0 messages. + if (!XMLString::equals(protocol, samlconstants::SAML20P_NS)) + return; + const QName& q = message.getElementQName(); if (!XMLString::equals(q.getNamespaceURI(), samlconstants::SAML20P_NS)&& - !XMLString::equals(q.getNamespaceURI(), samlconstants::SAML20_NS)) { + !XMLString::equals(q.getNamespaceURI(), samlconstants::SAML20_NS)) return; - } + Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.SAML2Message"); + try { const saml2::RootObject& samlRoot = dynamic_cast(message); policy.setMessageID(samlRoot.getID()); @@ -116,7 +121,7 @@ void SAML2MessageRule::evaluate(const XMLObject& message, const GenericRequest* } log.debug("matched message issuer against metadata, searching for applicable role..."); - const RoleDescriptor* roledesc=entity->getRoleDescriptor(*policy.getRole(), samlconstants::SAML20P_NS); + const RoleDescriptor* roledesc=entity->getRoleDescriptor(*policy.getRole(), protocol); if (!roledesc) { log.warn("unable to find compatible role (%s) in metadata", policy.getRole()->toString().c_str()); return; diff --git a/saml/saml2/binding/impl/SAML2POSTDecoder.cpp b/saml/saml2/binding/impl/SAML2POSTDecoder.cpp index cdb8060..d3047ed 100644 --- a/saml/saml2/binding/impl/SAML2POSTDecoder.cpp +++ b/saml/saml2/binding/impl/SAML2POSTDecoder.cpp @@ -124,7 +124,7 @@ XMLObject* SAML2POSTDecoder::decode( SchemaValidators.validate(xmlObject.get()); // Run through the policy. - policy.evaluate(*root, &genericRequest); + policy.evaluate(*root, &genericRequest, samlconstants::SAML20P_NS); // Check destination URL. auto_ptr_char dest(request ? request->getDestination() : response->getDestination()); diff --git a/saml/saml2/binding/impl/SAML2RedirectDecoder.cpp b/saml/saml2/binding/impl/SAML2RedirectDecoder.cpp index 2728f9d..4a725bc 100644 --- a/saml/saml2/binding/impl/SAML2RedirectDecoder.cpp +++ b/saml/saml2/binding/impl/SAML2RedirectDecoder.cpp @@ -138,7 +138,7 @@ XMLObject* SAML2RedirectDecoder::decode( SchemaValidators.validate(xmlObject.get()); // Run through the policy. - policy.evaluate(*root, &genericRequest); + policy.evaluate(*root, &genericRequest, samlconstants::SAML20P_NS); // Check destination URL. auto_ptr_char dest(request ? request->getDestination() : response->getDestination()); diff --git a/saml/saml2/binding/impl/SAML2SOAPClient.cpp b/saml/saml2/binding/impl/SAML2SOAPClient.cpp index af55891..08cba6d 100644 --- a/saml/saml2/binding/impl/SAML2SOAPClient.cpp +++ b/saml/saml2/binding/impl/SAML2SOAPClient.cpp @@ -61,7 +61,8 @@ StatusResponseType* SAML2SOAPClient::receiveSAML() if (m_correlate && response->getInResponseTo() && !XMLString::equals(m_correlate, response->getInResponseTo())) throw SecurityPolicyException("InResponseTo attribute did not correlate with the Request ID."); - m_soaper.getPolicy().evaluate(*response); + m_soaper.getPolicy().reset(true); + m_soaper.getPolicy().evaluate(*response, NULL, samlconstants::SAML20P_NS); if (!m_soaper.getPolicy().isSecure()) { SecurityPolicyException ex("Security policy could not authenticate the message."); annotateException(&ex, m_soaper.getPolicy().getIssuerMetadata(), response->getStatus()); // throws it diff --git a/saml/saml2/binding/impl/SAML2SOAPDecoder.cpp b/saml/saml2/binding/impl/SAML2SOAPDecoder.cpp index a0111e5..8879499 100644 --- a/saml/saml2/binding/impl/SAML2SOAPDecoder.cpp +++ b/saml/saml2/binding/impl/SAML2SOAPDecoder.cpp @@ -105,8 +105,9 @@ XMLObject* SAML2SOAPDecoder::decode( RequestAbstractType* request = dynamic_cast(body->getUnknownXMLObjects().front()); if (request) { // Run through the policy at two layers. - policy.evaluate(*env, &genericRequest); - policy.evaluate(*request, &genericRequest); + policy.evaluate(*env, &genericRequest, samlconstants::SAML20P_NS); + policy.reset(true); + policy.evaluate(*request, &genericRequest, samlconstants::SAML20P_NS); xmlObject.release(); body->detach(); // frees Envelope request->detach(); // frees Body diff --git a/samltest/saml1/binding/SAML1ArtifactTest.h b/samltest/saml1/binding/SAML1ArtifactTest.h index 8503a64..5f2dfca 100644 --- a/samltest/saml1/binding/SAML1ArtifactTest.h +++ b/samltest/saml1/binding/SAML1ArtifactTest.h @@ -39,7 +39,8 @@ public: void testSAML1Artifact() { try { QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME); - SecurityPolicy policy(m_rules1, m_metadata, &idprole, m_trust, false); + SecurityPolicy policy(m_metadata, &idprole, m_trust, false); + policy.getRules().assign(m_rules1.begin(), m_rules1.end()); // Read message to use from file. string path = data_path + "saml1/binding/SAML1Assertion.xml"; @@ -131,7 +132,7 @@ public: TSM_ASSERT("Retrieved credential was null", cred!=NULL); response->marshall((DOMDocument*)NULL,&sigs,cred); SchemaValidators.validate(response.get()); - policy.evaluate(*(response.get()), this); + policy.evaluate(*(response.get()), this, samlconstants::SAML11_PROTOCOL_ENUM); return response.release(); } diff --git a/samltest/saml1/binding/SAML1POSTTest.h b/samltest/saml1/binding/SAML1POSTTest.h index 6b8230d..9750b3d 100644 --- a/samltest/saml1/binding/SAML1POSTTest.h +++ b/samltest/saml1/binding/SAML1POSTTest.h @@ -34,7 +34,8 @@ public: void testSAML1POST() { try { QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME); - SecurityPolicy policy(m_rules1, m_metadata, &idprole, m_trust, false); + SecurityPolicy policy(m_metadata, &idprole, m_trust, false); + policy.getRules().assign(m_rules1.begin(), m_rules1.end()); // Read message to use from file. string path = data_path + "saml1/binding/SAML1Response.xml"; diff --git a/samltest/saml2/binding/SAML2ArtifactTest.h b/samltest/saml2/binding/SAML2ArtifactTest.h index 9482d40..329af90 100644 --- a/samltest/saml2/binding/SAML2ArtifactTest.h +++ b/samltest/saml2/binding/SAML2ArtifactTest.h @@ -38,7 +38,8 @@ public: void testSAML2Artifact() { try { QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME); - SecurityPolicy policy(m_rules2, m_metadata, &idprole, m_trust, false); + SecurityPolicy policy(m_metadata, &idprole, m_trust, false); + policy.getRules().assign(m_rules2.begin(), m_rules2.end()); // Read message to use from file. string path = data_path + "saml2/binding/SAML2Response.xml"; @@ -134,7 +135,7 @@ public: sc->setValue(StatusCode::SUCCESS); response->marshall(); SchemaValidators.validate(response.get()); - policy.evaluate(*(response.get()), this); + policy.evaluate(*(response.get()), this, samlconstants::SAML20P_NS); return response.release(); } }; diff --git a/samltest/saml2/binding/SAML2POSTTest.h b/samltest/saml2/binding/SAML2POSTTest.h index c2998df..bbdd504 100644 --- a/samltest/saml2/binding/SAML2POSTTest.h +++ b/samltest/saml2/binding/SAML2POSTTest.h @@ -34,7 +34,8 @@ public: void testSAML2POST() { try { QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME); - SecurityPolicy policy(m_rules2, m_metadata, &idprole, m_trust, false); + SecurityPolicy policy(m_metadata, &idprole, m_trust, false); + policy.getRules().assign(m_rules2.begin(), m_rules2.end()); // Read message to use from file. string path = data_path + "saml2/binding/SAML2Response.xml"; @@ -106,7 +107,8 @@ public: void testSAML2POSTSimpleSign() { try { QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME); - SecurityPolicy policy(m_rules2, m_metadata, &idprole, m_trust, false); + SecurityPolicy policy(m_metadata, &idprole, m_trust, false); + policy.getRules().assign(m_rules2.begin(), m_rules2.end()); // Read message to use from file. string path = data_path + "saml2/binding/SAML2Response.xml"; diff --git a/samltest/saml2/binding/SAML2RedirectTest.h b/samltest/saml2/binding/SAML2RedirectTest.h index cab8d6a..80dce5f 100644 --- a/samltest/saml2/binding/SAML2RedirectTest.h +++ b/samltest/saml2/binding/SAML2RedirectTest.h @@ -34,7 +34,8 @@ public: void testSAML2Redirect() { try { QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME); - SecurityPolicy policy(m_rules2, m_metadata, &idprole, m_trust, false); + SecurityPolicy policy(m_metadata, &idprole, m_trust, false); + policy.getRules().assign(m_rules2.begin(), m_rules2.end()); // Read message to use from file. string path = data_path + "saml2/binding/SAML2Response.xml"; -- 2.1.4