From 632fdee22ac4b756eaa3158217b9acd6c831e7be Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Tue, 12 Dec 2006 04:22:41 +0000 Subject: [PATCH] Return results from policy rules. --- saml/binding/ClientCertAuthRule.h | 2 +- saml/binding/MessageFlowRule.h | 2 +- saml/binding/SecurityPolicyRule.h | 12 ++++++++---- saml/binding/SimpleSigningRule.h | 2 +- saml/binding/XMLSigningRule.h | 2 +- saml/binding/impl/ClientCertAuthRule.cpp | 13 +++++++------ saml/binding/impl/MessageFlowRule.cpp | 4 +++- saml/binding/impl/SimpleSigningRule.cpp | 15 ++++++++------- saml/binding/impl/XMLSigningRule.cpp | 13 +++++++------ saml/saml1/binding/SAML1MessageRule.h | 2 +- saml/saml1/binding/impl/SAML1MessageRule.cpp | 11 +++++++---- saml/saml2/binding/SAML2MessageRule.h | 2 +- saml/saml2/binding/impl/SAML2MessageRule.cpp | 13 ++++++++----- 13 files changed, 54 insertions(+), 39 deletions(-) diff --git a/saml/binding/ClientCertAuthRule.h b/saml/binding/ClientCertAuthRule.h index 737e52b..6d94823 100644 --- a/saml/binding/ClientCertAuthRule.h +++ b/saml/binding/ClientCertAuthRule.h @@ -33,6 +33,6 @@ namespace opensaml { ClientCertAuthRule(const DOMElement* e) {} virtual ~ClientCertAuthRule() {} - void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; + bool evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; }; }; diff --git a/saml/binding/MessageFlowRule.h b/saml/binding/MessageFlowRule.h index accd60c..fc3e816 100644 --- a/saml/binding/MessageFlowRule.h +++ b/saml/binding/MessageFlowRule.h @@ -36,7 +36,7 @@ namespace opensaml { MessageFlowRule(const DOMElement* e); virtual ~MessageFlowRule() {} - void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; + bool evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; /** * Controls whether rule executes replay checking. diff --git a/saml/binding/SecurityPolicyRule.h b/saml/binding/SecurityPolicyRule.h index f15d263..68760f7 100644 --- a/saml/binding/SecurityPolicyRule.h +++ b/saml/binding/SecurityPolicyRule.h @@ -43,16 +43,20 @@ namespace opensaml { virtual ~SecurityPolicyRule() {} /** - * Evaluates the rule against the given request and message. If an Issuer is - * returned, the caller is responsible for freeing the Issuer object. + * Evaluates the rule against the given request and message. + * + *

Exceptions should be reserved for fatal request processing errors; + * otherwise rules should return false to indicate they were not applicable + * or unsuccessful. * * @param message the incoming message * @param request the protocol request * @param policy SecurityPolicy to provide various components and track message data + * @return true iff the rule ran successfully, false otherwise * - * @throws BindingException thrown if the request/message do not meet the requirements of this rule + * @throws BindingException thrown if the request/message is invalid in some way */ - virtual void evaluate( + virtual bool evaluate( const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy ) const=0; }; diff --git a/saml/binding/SimpleSigningRule.h b/saml/binding/SimpleSigningRule.h index ac82b33..b8a42a4 100644 --- a/saml/binding/SimpleSigningRule.h +++ b/saml/binding/SimpleSigningRule.h @@ -34,7 +34,7 @@ namespace opensaml { SimpleSigningRule(const DOMElement* e) {} virtual ~SimpleSigningRule() {} - void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; + bool evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; }; }; diff --git a/saml/binding/XMLSigningRule.h b/saml/binding/XMLSigningRule.h index 0469914..0b65c62 100644 --- a/saml/binding/XMLSigningRule.h +++ b/saml/binding/XMLSigningRule.h @@ -33,7 +33,7 @@ namespace opensaml { XMLSigningRule(const DOMElement* e) {} virtual ~XMLSigningRule() {} - void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; + bool evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; }; }; diff --git a/saml/binding/impl/ClientCertAuthRule.cpp b/saml/binding/impl/ClientCertAuthRule.cpp index 6337b19..aaa3c8c 100644 --- a/saml/binding/impl/ClientCertAuthRule.cpp +++ b/saml/binding/impl/ClientCertAuthRule.cpp @@ -43,37 +43,38 @@ namespace opensaml { } }; -void ClientCertAuthRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const +bool ClientCertAuthRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const { Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.ClientCertAuth"); log.debug("evaluating client certificate authentication policy"); if (!request) { log.debug("ignoring message, no protocol request available"); - return; + return false; } else if (!policy.getIssuerMetadata()) { log.debug("ignoring message, no issuer metadata supplied"); - return; + return false; } const X509TrustEngine* x509trust; if (!(x509trust=dynamic_cast(policy.getTrustEngine()))) { log.debug("ignoring message, no X509TrustEngine supplied"); - return; + return false; } const std::vector& chain = request->getClientCertificates(); if (chain.empty()) { log.debug("ignoring message, no client certificates in request"); - return; + return false; } if (!x509trust->validate(chain.front(), chain, *(policy.getIssuerMetadata()), true, policy.getMetadataProvider()->getKeyResolver())) { log.error("unable to verify certificate chain with supplied trust engine"); - return; + return false; } log.debug("client certificate verified against message issuer"); + return true; } diff --git a/saml/binding/impl/MessageFlowRule.cpp b/saml/binding/impl/MessageFlowRule.cpp index ce04682..b5e0882 100644 --- a/saml/binding/impl/MessageFlowRule.cpp +++ b/saml/binding/impl/MessageFlowRule.cpp @@ -56,7 +56,7 @@ MessageFlowRule::MessageFlowRule(const DOMElement* e) } } -void MessageFlowRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const +bool MessageFlowRule::evaluate(const XMLObject& message, const GenericRequest* request, 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); @@ -94,4 +94,6 @@ void MessageFlowRule::evaluate(const XMLObject& message, const GenericRequest* r throw BindingException("Rejecting replayed message ID ($1).", params(1,temp.get())); } } + + return true; } diff --git a/saml/binding/impl/SimpleSigningRule.cpp b/saml/binding/impl/SimpleSigningRule.cpp index 394802b..1079e88 100644 --- a/saml/binding/impl/SimpleSigningRule.cpp +++ b/saml/binding/impl/SimpleSigningRule.cpp @@ -62,36 +62,36 @@ namespace opensaml { }; -void SimpleSigningRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const +bool SimpleSigningRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const { Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.SimpleSigning"); log.debug("evaluating simple signing policy"); if (!policy.getIssuerMetadata()) { log.debug("ignoring message, no issuer metadata supplied"); - return; + return false; } else if (!policy.getTrustEngine()) { log.debug("ignoring message, no TrustEngine supplied"); - return; + return false; } const HTTPRequest* httpRequest = dynamic_cast(request); if (!request || !httpRequest) { log.debug("ignoring message, no HTTP protocol request available"); - return; + return false; } const char* signature = request->getParameter("Signature"); if (!signature) { log.debug("ignoring unsigned message"); - return; + return false; } const char* sigAlgorithm = request->getParameter("SigAlg"); if (!sigAlgorithm) { log.error("SigAlg parameter not found, no way to verify the signature"); - return; + return false; } string input; @@ -148,8 +148,9 @@ void SimpleSigningRule::evaluate(const XMLObject& message, const GenericRequest* *(policy.getIssuerMetadata()), policy.getMetadataProvider()->getKeyResolver() )) { log.error("unable to verify message signature with supplied trust engine"); - return; + return false; } log.debug("signature verified against message issuer"); + return true; } diff --git a/saml/binding/impl/XMLSigningRule.cpp b/saml/binding/impl/XMLSigningRule.cpp index 029f14c..8675fc6 100644 --- a/saml/binding/impl/XMLSigningRule.cpp +++ b/saml/binding/impl/XMLSigningRule.cpp @@ -43,24 +43,24 @@ namespace opensaml { } }; -void XMLSigningRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const +bool XMLSigningRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const { Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.XMLSigning"); log.debug("evaluating message signing policy"); if (!policy.getIssuerMetadata()) { log.debug("ignoring message, no issuer metadata supplied"); - return; + return false; } else if (!policy.getTrustEngine()) { log.debug("ignoring message, no TrustEngine supplied"); - return; + return false; } const SignableObject* signable = dynamic_cast(&message); if (!signable || !signable->getSignature()) { log.debug("ignoring unsigned or unrecognized message"); - return; + return false; } log.debug("validating signature profile"); @@ -70,15 +70,16 @@ void XMLSigningRule::evaluate(const XMLObject& message, const GenericRequest* re } catch (ValidationException& ve) { log.error("signature profile failed to validate: %s", ve.what()); - return; + return false; } if (!policy.getTrustEngine()->validate( *(signable->getSignature()), *(policy.getIssuerMetadata()), policy.getMetadataProvider()->getKeyResolver() )) { log.error("unable to verify message signature with supplied trust engine"); - return; + return false; } log.debug("signature verified against message issuer"); + return true; } diff --git a/saml/saml1/binding/SAML1MessageRule.h b/saml/saml1/binding/SAML1MessageRule.h index 0027921..ad3f685 100644 --- a/saml/saml1/binding/SAML1MessageRule.h +++ b/saml/saml1/binding/SAML1MessageRule.h @@ -34,7 +34,7 @@ namespace opensaml { SAML1MessageRule(const DOMElement* e) {} virtual ~SAML1MessageRule() {} - void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; + bool evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; }; }; }; diff --git a/saml/saml1/binding/impl/SAML1MessageRule.cpp b/saml/saml1/binding/impl/SAML1MessageRule.cpp index 3d70d87..c821225 100644 --- a/saml/saml1/binding/impl/SAML1MessageRule.cpp +++ b/saml/saml1/binding/impl/SAML1MessageRule.cpp @@ -47,7 +47,7 @@ namespace opensaml { } }; -void SAML1MessageRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const +bool SAML1MessageRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const { Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.SAML1Message"); @@ -87,7 +87,7 @@ void SAML1MessageRule::evaluate(const XMLObject& message, const GenericRequest* if (!protocol) { log.warn("issuer identity not extracted"); - return; + return false; } if (log.isDebugEnabled()) { @@ -101,20 +101,23 @@ void SAML1MessageRule::evaluate(const XMLObject& message, const GenericRequest* if (!entity) { auto_ptr_char temp(policy.getIssuer()->getName()); log.warn("no metadata found, can't establish identity of issuer (%s)", temp.get()); - return; + return false; } log.debug("matched message issuer against metadata, searching for applicable role..."); 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; + return false; } policy.setIssuerMetadata(roledesc); + return true; } } catch (bad_cast&) { // Just trap it. log.warn("caught a bad_cast while examining message"); } + + return false; } diff --git a/saml/saml2/binding/SAML2MessageRule.h b/saml/saml2/binding/SAML2MessageRule.h index 20e785e..1d5a6ba 100644 --- a/saml/saml2/binding/SAML2MessageRule.h +++ b/saml/saml2/binding/SAML2MessageRule.h @@ -34,7 +34,7 @@ namespace opensaml { SAML2MessageRule(const DOMElement* e) {} virtual ~SAML2MessageRule() {} - void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; + bool evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const; }; }; }; diff --git a/saml/saml2/binding/impl/SAML2MessageRule.cpp b/saml/saml2/binding/impl/SAML2MessageRule.cpp index fe604c2..fc297cf 100644 --- a/saml/saml2/binding/impl/SAML2MessageRule.cpp +++ b/saml/saml2/binding/impl/SAML2MessageRule.cpp @@ -45,7 +45,7 @@ namespace opensaml { } }; -void SAML2MessageRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const +bool SAML2MessageRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const { Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.SAML2Message"); @@ -85,7 +85,7 @@ void SAML2MessageRule::evaluate(const XMLObject& message, const GenericRequest* if (!policy.getIssuer()) { log.warn("issuer identity not extracted"); - return; + return false; } if (log.isDebugEnabled()) { @@ -96,7 +96,7 @@ 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)) { log.warn("non-system entity issuer, skipping metadata lookup"); - return; + return false; } log.debug("searching metadata for message issuer..."); @@ -104,20 +104,23 @@ void SAML2MessageRule::evaluate(const XMLObject& message, const GenericRequest* if (!entity) { auto_ptr_char temp(policy.getIssuer()->getName()); log.warn("no metadata found, can't establish identity of issuer (%s)", temp.get()); - return; + return false; } log.debug("matched message issuer against metadata, searching for applicable role..."); const RoleDescriptor* roledesc=entity->getRoleDescriptor(*policy.getRole(), samlconstants::SAML20P_NS); if (!roledesc) { log.warn("unable to find compatible role (%s) in metadata", policy.getRole()->toString().c_str()); - return; + return false; } policy.setIssuerMetadata(roledesc); + return true; } } catch (bad_cast&) { // Just trap it. log.warn("caught a bad_cast while examining message"); } + + return false; } -- 2.1.4