* TLS client authentication SecurityPolicyRule
*/
+#ifndef __saml_certrule_h__
+#define __saml_certrule_h__
+
#include <saml/binding/SecurityPolicyRule.h>
ClientCertAuthRule(const DOMElement* e) {}
virtual ~ClientCertAuthRule() {}
- bool evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
+ void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
};
};
+
+#endif /* __saml_certrule_h__ */
* SAML replay and freshness checking SecurityPolicyRule
*/
+#ifndef __saml_flowrule_h__
+#define __saml_flowrule_h__
+
#include <saml/binding/SecurityPolicyRule.h>
MessageFlowRule(const DOMElement* e);
virtual ~MessageFlowRule() {}
- bool evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
+ void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
/**
* Controls whether rule executes replay checking.
};
};
+
+#endif /* __saml_flowrule_h__ */
const saml2md::MetadataProvider* metadataProvider=NULL,
const xmltooling::QName* role=NULL,
const xmltooling::TrustEngine* trustEngine=NULL
- ) : m_messageQName(NULL), m_messageID(NULL), m_issueInstant(0), m_issuer(NULL), m_issuerRole(NULL),
+ ) : 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) {
if (role)
m_role = new xmltooling::QName(*role);
const saml2md::MetadataProvider* metadataProvider=NULL,
const xmltooling::QName* role=NULL,
const xmltooling::TrustEngine* trustEngine=NULL
- ) : m_messageQName(NULL), m_messageID(NULL), m_issueInstant(0), m_issuer(NULL), m_issuerRole(NULL),
+ ) : 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) {
if (role)
m_role = new xmltooling::QName(*role);
*
* @param message the incoming message
* @param request the protocol request
- *
- * @throws BindingException thrown if the request/message do not meet the requirements of this policy
+ *
+ * @throws BindingException raised if the message/request is invalid according to the supplied rules
*/
void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request=NULL);
}
/**
+ * Returns the security status as determined by the registered policies.
+ *
+ * @return true iff a SecurityPolicyRule has indicated the issuer/message has been authenticated
+ */
+ bool isSecure() const {
+ return m_secure;
+ }
+
+ /**
* Sets the message element/type as determined by the registered policies.
*
* @param messageQName message element/type
* @param issuerRole metadata for the role the issuer is operating in
*/
void setIssuerMetadata(const saml2md::RoleDescriptor* issuerRole);
+
+ /**
+ * Sets the security status as determined by the registered policies.
+ *
+ * @param secure indicates whether the issuer/message has been authenticated
+ */
+ void setSecure(bool secure) {
+ m_secure = secure;
+ }
/** Allows override of rules for comparing saml2:Issuer information. */
class SAML_API IssuerMatchingPolicy {
time_t m_issueInstant;
saml2::Issuer* m_issuer;
const saml2md::RoleDescriptor* m_issuerRole;
+ bool m_secure;
// components governing policy rules
IssuerMatchingPolicy* m_matchingPolicy;
/**
* Evaluates the rule against the given request and message.
*
- * <p>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 is invalid in some way
+ *
+ * @throws BindingException raised if the message/request is not acceptable to the policy rule
*/
- virtual bool evaluate(
+ virtual void evaluate(
const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy
) const=0;
};
* Blob-oriented signature checking SecurityPolicyRule
*/
+#ifndef __saml_simplesignrule_h__
+#define __saml_simplesignrule_h__
+
#include <saml/binding/SecurityPolicyRule.h>
SimpleSigningRule(const DOMElement* e) {}
virtual ~SimpleSigningRule() {}
- bool evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
+ void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
};
};
+
+#endif /* __saml_simplesignrule_h__ */
* XML Signature checking SecurityPolicyRule
*/
+#ifndef __saml_xmlsignrule_h__
+#define __saml_xmlsignrule_h__
+
#include <saml/binding/SecurityPolicyRule.h>
XMLSigningRule(const DOMElement* e) {}
virtual ~XMLSigningRule() {}
- bool evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
+ void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
};
};
+
+#endif /* __saml_xmlsignrule_h__ */
/**
* ClientCertAuthRule.cpp
*
- * XML Signature checking SecurityPolicyRule
+ * TLS client authentication SecurityPolicyRule
*/
#include "internal.h"
}
};
-bool ClientCertAuthRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const
+void 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 false;
+ return;
}
else if (!policy.getIssuerMetadata()) {
log.debug("ignoring message, no issuer metadata supplied");
- return false;
+ return;
}
const X509TrustEngine* x509trust;
if (!(x509trust=dynamic_cast<const X509TrustEngine*>(policy.getTrustEngine()))) {
log.debug("ignoring message, no X509TrustEngine supplied");
- return false;
+ return;
}
const std::vector<XSECCryptoX509*>& chain = request->getClientCertificates();
if (chain.empty()) {
log.debug("ignoring message, no client certificates in request");
- return false;
+ return;
}
if (!x509trust->validate(chain.front(), chain, *(policy.getIssuerMetadata()), true,
policy.getMetadataProvider()->getKeyResolver())) {
log.error("unable to verify certificate chain with supplied trust engine");
- return false;
+ return;
}
log.debug("client certificate verified against message issuer");
- return true;
+ policy.setSecure(true);
}
}
}
-bool MessageFlowRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const
+void 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);
throw BindingException("Rejecting replayed message ID ($1).", params(1,temp.get()));
}
}
-
- return true;
}
issuer->setName(parent->getEntityID());
m_policy.setIssuer(issuer);
m_policy.setIssuerMetadata(m_peer);
+ m_policy.setSecure(true);
}
}
m_policy.evaluate(*(env.get()));
m_issueInstant=0;
m_issuer=NULL;
m_issuerRole=NULL;
+ m_secure=false;
}
void SecurityPolicy::evaluate(const XMLObject& message, const GenericRequest* request)
};
-bool SimpleSigningRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const
+void 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 false;
+ return;
}
else if (!policy.getTrustEngine()) {
log.debug("ignoring message, no TrustEngine supplied");
- return false;
+ return;
}
const HTTPRequest* httpRequest = dynamic_cast<const HTTPRequest*>(request);
if (!request || !httpRequest) {
log.debug("ignoring message, no HTTP protocol request available");
- return false;
+ return;
}
const char* signature = request->getParameter("Signature");
if (!signature) {
log.debug("ignoring unsigned message");
- return false;
+ return;
}
const char* sigAlgorithm = request->getParameter("SigAlg");
if (!sigAlgorithm) {
log.error("SigAlg parameter not found, no way to verify the signature");
- return false;
+ return;
}
string input;
*(policy.getIssuerMetadata()), policy.getMetadataProvider()->getKeyResolver()
)) {
log.error("unable to verify message signature with supplied trust engine");
- return false;
+ return;
}
log.debug("signature verified against message issuer");
- return true;
+ policy.setSecure(true);
}
}
};
-bool XMLSigningRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const
+void 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 false;
+ return;
}
else if (!policy.getTrustEngine()) {
log.debug("ignoring message, no TrustEngine supplied");
- return false;
+ return;
}
const SignableObject* signable = dynamic_cast<const SignableObject*>(&message);
if (!signable || !signable->getSignature()) {
log.debug("ignoring unsigned or unrecognized message");
- return false;
+ return;
}
log.debug("validating signature profile");
}
catch (ValidationException& ve) {
log.error("signature profile failed to validate: %s", ve.what());
- return false;
+ return;
}
if (!policy.getTrustEngine()->validate(
*(signable->getSignature()), *(policy.getIssuerMetadata()), policy.getMetadataProvider()->getKeyResolver()
)) {
log.error("unable to verify message signature with supplied trust engine");
- return false;
+ return;
}
log.debug("signature verified against message issuer");
- return true;
+ policy.setSecure(true);
}
* SAML 1.x message extraction rule
*/
+#ifndef __saml_1msgrule_h__
+#define __saml_1msgrule_h__
+
#include <saml/binding/SecurityPolicyRule.h>
SAML1MessageRule(const DOMElement* e) {}
virtual ~SAML1MessageRule() {}
- bool evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
+ void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
};
};
};
+
+#endif /* __saml_1msgrule_h__ */
}
};
-bool SAML1MessageRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const
+void SAML1MessageRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const
{
Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.SAML1Message");
if (!protocol) {
log.warn("issuer identity not extracted");
- return false;
+ return;
}
if (log.isDebugEnabled()) {
if (!entity) {
auto_ptr_char temp(policy.getIssuer()->getName());
log.warn("no metadata found, can't establish identity of issuer (%s)", temp.get());
- return false;
+ return;
}
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 false;
+ return;
}
policy.setIssuerMetadata(roledesc);
- return true;
}
}
catch (bad_cast&) {
// Just trap it.
log.warn("caught a bad_cast while examining message");
}
-
- return false;
}
* SAML 2.0 message extraction rule
*/
+#ifndef __saml_2msgrule_h__
+#define __saml_2msgrule_h__
+
#include <saml/binding/SecurityPolicyRule.h>
SAML2MessageRule(const DOMElement* e) {}
virtual ~SAML2MessageRule() {}
- bool evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
+ void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
};
};
};
+
+#endif /* __saml_2msgrule_h__ */
}
};
-bool SAML2MessageRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const
+void SAML2MessageRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const
{
Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.SAML2Message");
if (!policy.getIssuer()) {
log.warn("issuer identity not extracted");
- return false;
+ return;
}
if (log.isDebugEnabled()) {
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 false;
+ return;
}
log.debug("searching metadata for message issuer...");
if (!entity) {
auto_ptr_char temp(policy.getIssuer()->getName());
log.warn("no metadata found, can't establish identity of issuer (%s)", temp.get());
- return false;
+ return;
}
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 false;
+ return;
}
policy.setIssuerMetadata(roledesc);
- return true;
}
}
catch (bad_cast&) {
// Just trap it.
log.warn("caught a bad_cast while examining message");
}
-
- return false;
}
// Test the results.\r
TSM_ASSERT_EQUALS("TARGET was not the expected result.", relayState, "state");\r
TSM_ASSERT("SAML Response not decoded successfully.", response.get());\r
- TSM_ASSERT("Message was not verified.", policy.getIssuer()!=NULL);\r
+ TSM_ASSERT("Message was not verified.", policy.isSecure());\r
auto_ptr_char entityID(policy.getIssuer()->getName());\r
TSM_ASSERT("Issuer was not expected.", !strcmp(entityID.get(),"https://idp.example.org/"));\r
TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);\r
// Test the results.
TSM_ASSERT_EQUALS("TARGET was not the expected result.", relayState, "state");
TSM_ASSERT("SAML Response not decoded successfully.", response.get());
- TSM_ASSERT("Message was not verified.", policy.getIssuer()!=NULL);
+ TSM_ASSERT("Message was not verified.", policy.isSecure());\r
auto_ptr_char entityID(policy.getIssuer()->getName());
TSM_ASSERT("Issuer was not expected.", !strcmp(entityID.get(),"https://idp.example.org/"));
TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);
// Trigger a replay.
- policy.reset();\r
+ policy.reset();
TSM_ASSERT_THROWS("Did not catch the replay.", decoder->decode(relayState,*this,policy), BindingException);
}
catch (XMLToolingException& ex) {
// Test the results.\r
TSM_ASSERT_EQUALS("RelayState was not the expected result.", relayState, "state");\r
TSM_ASSERT("SAML Response not decoded successfully.", response.get());\r
- TSM_ASSERT("Message was not verified.", policy.getIssuer()!=NULL);\r
+ TSM_ASSERT("Message was not verified.", policy.isSecure());\r
auto_ptr_char entityID(policy.getIssuer()->getName());\r
TSM_ASSERT("Issuer was not expected.", !strcmp(entityID.get(),"https://idp.example.org/"));\r
TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);\r
// Test the results.
TSM_ASSERT_EQUALS("RelayState was not the expected result.", relayState, "state");
TSM_ASSERT("SAML Response not decoded successfully.", response.get());
- TSM_ASSERT("Message was not verified.", policy.getIssuer()!=NULL);
+ TSM_ASSERT("Message was not verified.", policy.isSecure());\r
auto_ptr_char entityID(policy.getIssuer()->getName());
TSM_ASSERT("Issuer was not expected.", !strcmp(entityID.get(),"https://idp.example.org/"));
TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);
// Trigger a replay.
- policy.reset();\r
+ policy.reset();
TSM_ASSERT_THROWS("Did not catch the replay.", decoder->decode(relayState,*this,policy), BindingException);
}
catch (XMLToolingException& ex) {
// Test the results.
TSM_ASSERT_EQUALS("RelayState was not the expected result.", relayState, "state");
TSM_ASSERT("SAML Response not decoded successfully.", response.get());
- TSM_ASSERT("Message was not verified.", policy.getIssuer()!=NULL);
+ TSM_ASSERT("Message was not verified.", policy.isSecure());\r
auto_ptr_char entityID(policy.getIssuer()->getName());
TSM_ASSERT("Issuer was not expected.", !strcmp(entityID.get(),"https://idp.example.org/"));
TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);
// Trigger a replay.
- policy.reset();\r
+ policy.reset();
TSM_ASSERT_THROWS("Did not catch the replay.", decoder->decode(relayState,*this,policy), BindingException);
}
catch (XMLToolingException& ex) {
// Test the results.
TSM_ASSERT_EQUALS("RelayState was not the expected result.", relayState, "state");
TSM_ASSERT("SAML Response not decoded successfully.", response.get());
- TSM_ASSERT("Message was not verified.", policy.getIssuer()!=NULL);
+ TSM_ASSERT("Message was not verified.", policy.isSecure());\r
auto_ptr_char entityID(policy.getIssuer()->getName());
TSM_ASSERT("Issuer was not expected.", !strcmp(entityID.get(),"https://idp.example.org/"));
TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);
// Trigger a replay.
- policy.reset();\r
+ policy.reset();
TSM_ASSERT_THROWS("Did not catch the replay.", decoder->decode(relayState,*this,policy), BindingException);
}
catch (XMLToolingException& ex) {