saml1/binding/SAML1POSTEncoder.h \
saml1/binding/SAML1SOAPDecoder.h \
saml1/binding/SAML1SOAPEncoder.h \
- saml1/binding/SAML1SOAPClient.h
+ saml1/binding/SAML1SOAPClient.h \
+ saml1/binding/SAML1MessageRule.h
saml2coreinclude_HEADERS = \
saml2/core/Assertions.h \
saml2/binding/SAML2RedirectEncoder.h \
saml2/binding/SAML2SOAPDecoder.h \
saml2/binding/SAML2SOAPEncoder.h \
- saml2/binding/SAML2SOAPClient.h
+ saml2/binding/SAML2SOAPClient.h \
+ saml1/binding/SAML2MessageRule.h
saml2mdinclude_HEADERS = \
saml2/metadata/AbstractMetadataProvider.h \
saml1/binding/impl/SAML1SOAPDecoder.cpp \
saml1/binding/impl/SAML1SOAPEncoder.cpp \
saml1/binding/impl/SAML1SOAPClient.cpp \
+ saml1/binding/impl/SAML1MessageRule.cpp \
saml2/core/impl/Assertions20Impl.cpp \
saml2/core/impl/Assertions20SchemaValidators.cpp \
saml2/core/impl/Protocols20Impl.cpp \
saml2/binding/impl/SAML2SOAPDecoder.cpp \
saml2/binding/impl/SAML2SOAPEncoder.cpp \
saml2/binding/impl/SAML2SOAPClient.cpp \
+ saml2/binding/impl/SAML2MessageRule.cpp \
encryption/EncryptedKeyResolver.cpp \
signature/ContentReference.cpp \
signature/SignatureProfileValidator.cpp \
#include "binding/MessageDecoder.h"
#include "binding/MessageEncoder.h"
#include "binding/SAMLArtifact.h"
+#include "binding/SecurityPolicyRule.h"
#include "binding/URLEncoder.h"
#include "saml1/core/Assertions.h"
#include "saml1/core/Protocols.h"
ClientCertAuthRule(const DOMElement* e) {}
virtual ~ClientCertAuthRule() {}
- std::pair<saml2::Issuer*,const saml2md::RoleDescriptor*> evaluate(
- const xmltooling::XMLObject& message,
- const GenericRequest* request,
- const saml2md::MetadataProvider* metadataProvider,
- const xmltooling::QName* role,
- const xmltooling::TrustEngine* trustEngine
- ) const;
-
- protected:
- /**
- * Examines the message and/or its contents and extracts the issuer's claimed
- * identity along with a protocol identifier. The two together can be used to
- * locate metadata to use in validating the signature. Conventions may be needed
- * to properly encode non-SAML2 issuer information into a compatible form.
- *
- * <p>The caller is responsible for freeing the Issuer object.
- *
- * @param message message to examine
- * @return a pair consisting of a SAML 2.0 Issuer object and a protocol constant.
- */
- virtual std::pair<saml2::Issuer*,const XMLCh*> getIssuerAndProtocol(const xmltooling::XMLObject& message) const;
+ void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
};
};
/**
* SAML replay and freshness checking SecurityPolicyRule
*
- * Subclasses can provide support for additional message types
- * by overriding the main method and then calling the check method.
+ * Some form of message rule to extract ID and timestamp must be
+ * run prior to this rule.
*/
class SAML_API MessageFlowRule : public SecurityPolicyRule
{
MessageFlowRule(const DOMElement* e);
virtual ~MessageFlowRule() {}
- std::pair<saml2::Issuer*,const saml2md::RoleDescriptor*> evaluate(
- const xmltooling::XMLObject& message,
- const GenericRequest* request,
- const saml2md::MetadataProvider* metadataProvider,
- const xmltooling::QName* role,
- const xmltooling::TrustEngine* trustEngine
- ) const;
+ void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
/**
* Controls whether rule executes replay checking.
void setExpires(time_t expires) {
m_expires = expires;
}
-
- protected:
- /**
- * Performs the check.
- *
- * @param id message identifier
- * @param issueInstant timestamp of protocol message
- *
- * @exception BindingException raised if a check fails
- */
- void check(const XMLCh* id, time_t issueInstant) const;
private:
bool m_checkReplay;
#ifndef __saml_secpol_h__
#define __saml_secpol_h__
-#include <saml/binding/SecurityPolicyRule.h>
+#include <saml/binding/GenericRequest.h>
+
+#include <ctime>
#include <vector>
+#include <xmltooling/XMLObject.h>
+#include <xmltooling/security/TrustEngine.h>
#if defined (_MSC_VER)
#pragma warning( push )
namespace opensaml {
+ namespace saml2 {
+ class SAML_API Issuer;
+ };
namespace saml2md {
class SAML_API MetadataProvider;
+ class SAML_API RoleDescriptor;
};
+ class SAML_API SecurityPolicyRule;
+
/**
* A policy used to verify the security of an incoming message.
*
public:
/**
* Constructor for policy.
- *
+ *
* @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
const saml2md::MetadataProvider* metadataProvider=NULL,
const xmltooling::QName* role=NULL,
const xmltooling::TrustEngine* trustEngine=NULL
- ) : m_issuer(NULL), m_issuerRole(NULL), m_matchingPolicy(NULL), m_metadata(metadataProvider),
- m_role(role ? *role : xmltooling::QName()), m_trust(trustEngine) {
+ ) : m_messageQName(NULL), m_messageID(NULL), m_issueInstant(0), m_issuer(NULL), m_issuerRole(NULL),
+ 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_issuer(NULL), m_issuerRole(NULL), m_matchingPolicy(NULL), m_rules(rules), m_metadata(metadataProvider),
- m_role(role ? *role : xmltooling::QName()), m_trust(trustEngine) {
+ ) : m_messageQName(NULL), m_messageID(NULL), m_issueInstant(0), m_issuer(NULL), m_issuerRole(NULL),
+ m_matchingPolicy(NULL), m_rules(rules), m_metadata(metadataProvider), m_role(NULL), m_trust(trustEngine) {
+ if (role)
+ m_role = new xmltooling::QName(*role);
}
virtual ~SecurityPolicy();
* @return the peer role element/type, or an empty QName
*/
const xmltooling::QName* getRole() const {
- return &m_role;
+ return m_role;
}
/**
* @param role the peer role element/type or NULL
*/
void setRole(const xmltooling::QName* role) {
- m_role = (role ? *role : xmltooling::QName());
+ delete m_role;
+ m_role = role ? new xmltooling::QName(*role) : NULL;
}
/**
/**
* Evaluates the policy against the given request and message,
- * possibly populating issuer information in the policy object.
+ * possibly populating message information in the policy object.
*
* @param message the incoming message
* @param request the protocol request
void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request=NULL);
/**
+ * Resets the policy object and clears any per-message state.
+ */
+ void reset();
+
+ /**
+ * 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
+ */
+ const XMLCh* getMessageID() const {
+ return m_messageID;
+ }
+
+ /**
+ * Returns the message timestamp as determined by the registered policies.
+ *
+ * @return message timestamp as determined by the registered policies
+ */
+ time_t getIssueInstant() const {
+ return m_issueInstant;
+ }
+
+ /**
* Gets the issuer of the message as determined by the registered policies.
*
* @return issuer of the message as determined by the registered policies
}
/**
- * Sets the issuer of the message as determined by external factors.
+ * 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
+ */
+ void setMessageID(const XMLCh* id) {
+ XMLString::release(&m_messageID);
+ m_messageID = XMLString::replicate(id);
+ }
+
+ /**
+ * Sets the message timestamp as determined by the registered policies.
+ *
+ * @param issueInstant message timestamp
+ */
+ void setIssueInstant(time_t issueInstant) {
+ m_issueInstant = issueInstant;
+ }
+
+ /**
+ * 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
static IssuerMatchingPolicy m_defaultMatching;
private:
+ // information extracted from message
+ xmltooling::QName* m_messageQName;
+ XMLCh* m_messageID;
+ time_t m_issueInstant;
saml2::Issuer* m_issuer;
const saml2md::RoleDescriptor* m_issuerRole;
+ // components governing policy rules
IssuerMatchingPolicy* m_matchingPolicy;
std::vector<const SecurityPolicyRule*> m_rules;
const saml2md::MetadataProvider* m_metadata;
- xmltooling::QName m_role;
+ xmltooling::QName* m_role;
const xmltooling::TrustEngine* m_trust;
};
#ifndef __saml_secrule_h__
#define __saml_secrule_h__
-#include <saml/binding/GenericRequest.h>
-#include <xmltooling/XMLObject.h>
-#include <xmltooling/security/TrustEngine.h>
+#include <saml/binding/SecurityPolicy.h>
namespace opensaml {
- namespace saml2 {
- class SAML_API Issuer;
- };
- namespace saml2md {
- class SAML_API MetadataProvider;
- class SAML_API RoleDescriptor;
- };
/**
* A rule that a protocol request and message must meet in order to be valid and secure.
* Evaluates the rule against the given request and message. If an Issuer is
* returned, the caller is responsible for freeing the Issuer object.
*
- * @param message the incoming message
- * @param request the protocol request
- * @param metadataProvider locked MetadataProvider instance to authenticate the message
- * @param role identifies the role (generally IdP or SP) of the peer who issued the message
- * @param trustEngine TrustEngine to authenticate the message
- * @param extractor MessageExtractor to use in examining message
- * @return the identity of the message issuer, in two forms, or NULL
+ * @param message the incoming message
+ * @param request the protocol request
+ * @param policy SecurityPolicy to provide various components and track message data
*
* @throws BindingException thrown if the request/message do not meet the requirements of this rule
*/
- virtual std::pair<saml2::Issuer*,const saml2md::RoleDescriptor*> evaluate(
- const xmltooling::XMLObject& message,
- const GenericRequest* request,
- const saml2md::MetadataProvider* metadataProvider,
- const xmltooling::QName* role,
- const xmltooling::TrustEngine* trustEngine
+ virtual void evaluate(
+ const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy
) const=0;
};
void SAML_API registerSecurityPolicyRules();
/**
+ * SecurityPolicyRule for processing SAML 1.x messages.
+ *
+ * Extracts message ID, timestamp, and issuer information.
+ */
+ #define SAML1MESSAGE_POLICY_RULE "org.opensaml.saml1.binding.SAML1MessageRule"
+
+ /**
+ * SecurityPolicyRule for processing SAML 2.0 messages.
+ *
+ * Extracts message ID, timestamp, and issuer information.
+ */
+ #define SAML2MESSAGE_POLICY_RULE "org.opensaml.saml2.binding.SAML2MessageRule"
+
+ /**
* SecurityPolicyRule for TLS client certificate authentication.
*
- * Requires that messages carry information about the issuer, and then
- * evaluates the claimed certificates against the issuer's metadata.
+ * Evaluates client certificates against the issuer's metadata.
*/
#define CLIENTCERTAUTH_POLICY_RULE "org.opensaml.binding.ClientCertAuthRule"
/**
* Blob-oriented signature checking SecurityPolicyRule for
* bindings that support non-XML signature techniques.
- *
- * Subclasses can provide support for additional message types
- * by overriding the issuer derivation method.
*/
class SAML_API SimpleSigningRule : public SecurityPolicyRule
{
SimpleSigningRule(const DOMElement* e) {}
virtual ~SimpleSigningRule() {}
- std::pair<saml2::Issuer*,const saml2md::RoleDescriptor*> evaluate(
- const xmltooling::XMLObject& message,
- const GenericRequest* request,
- const saml2md::MetadataProvider* metadataProvider,
- const xmltooling::QName* role,
- const xmltooling::TrustEngine* trustEngine
- ) const;
-
- protected:
- /**
- * Examines the message and/or its contents and extracts the issuer's claimed
- * identity along with a protocol identifier. The two together can be used to
- * locate metadata to use in validating the signature. Conventions may be needed
- * to properly encode non-SAML2 issuer information into a compatible form.
- *
- * <p>The caller is responsible for freeing the Issuer object.
- *
- * @param message message to examine
- * @return a pair consisting of a SAML 2.0 Issuer object and a protocol constant.
- */
- virtual std::pair<saml2::Issuer*,const XMLCh*> getIssuerAndProtocol(const xmltooling::XMLObject& message) const;
+ void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
};
};
namespace opensaml {
/**
* XML Signature checking SecurityPolicyRule
- *
- * Subclasses can provide support for additional message types
- * by overriding the issuer derivation method.
*/
class SAML_API XMLSigningRule : public SecurityPolicyRule
{
XMLSigningRule(const DOMElement* e) {}
virtual ~XMLSigningRule() {}
- std::pair<saml2::Issuer*,const saml2md::RoleDescriptor*> evaluate(
- const xmltooling::XMLObject& message,
- const GenericRequest* request,
- const saml2md::MetadataProvider* metadataProvider,
- const xmltooling::QName* role,
- const xmltooling::TrustEngine* trustEngine
- ) const;
-
- protected:
- /**
- * Examines the message and/or its contents and extracts the issuer's claimed
- * identity along with a protocol identifier. The two together can be used to
- * locate metadata to use in validating the signature. Conventions may be needed
- * to properly encode non-SAML2 issuer information into a compatible form.
- *
- * <p>The caller is responsible for freeing the Issuer object.
- *
- * @param message message to examine
- * @return a pair consisting of a SAML 2.0 Issuer object and a protocol constant.
- */
- virtual std::pair<saml2::Issuer*,const XMLCh*> getIssuerAndProtocol(const xmltooling::XMLObject& message) const;
+ void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
};
};
#include "saml2/metadata/MetadataProvider.h"
#include <xmltooling/security/X509TrustEngine.h>
-#include <xmltooling/util/NDC.h>
#include <xmltooling/util/ReplayCache.h>
#include <log4cpp/Category.hh>
}
};
-pair<saml2::Issuer*,const RoleDescriptor*> ClientCertAuthRule::evaluate(
- const XMLObject& message,
- const GenericRequest* request,
- const MetadataProvider* metadataProvider,
- const QName* role,
- const TrustEngine* trustEngine
- ) 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");
- pair<saml2::Issuer*,const RoleDescriptor*> ret = pair<saml2::Issuer*,const RoleDescriptor*>(NULL,NULL);
if (!request) {
log.debug("ignoring message, no protocol request available");
- return ret;
- }
-
+ return;
+ }
+ else if (!policy.getIssuerMetadata()) {
+ log.debug("ignoring message, no issuer metadata supplied");
+ return;
+ }
+
const X509TrustEngine* x509trust;
- if (!metadataProvider || !role || !(x509trust=dynamic_cast<const X509TrustEngine*>(trustEngine))) {
- log.debug("ignoring message, no metadata or X509TrustEngine supplied");
- return ret;
+ if (!(x509trust=dynamic_cast<const X509TrustEngine*>(policy.getTrustEngine()))) {
+ log.debug("ignoring message, no X509TrustEngine supplied");
+ return;
}
const std::vector<XSECCryptoX509*>& chain = request->getClientCertificates();
if (chain.empty()) {
log.debug("ignoring message, no client certificates in request");
- return ret;
+ return;
}
- try {
- log.debug("extracting issuer from message");
- pair<saml2::Issuer*,const XMLCh*> issuerInfo = getIssuerAndProtocol(message);
-
- auto_ptr<saml2::Issuer> issuer(issuerInfo.first);
- if (!issuerInfo.first || !issuerInfo.second ||
- (issuer->getFormat() && !XMLString::equals(issuer->getFormat(), saml2::NameIDType::ENTITY))) {
- log.warn("issuer identity not estabished, or was not an entityID");
- return ret;
- }
-
- log.debug("searching metadata for message issuer...");
- const EntityDescriptor* entity = metadataProvider->getEntityDescriptor(issuer->getName());
- if (!entity) {
- auto_ptr_char temp(issuer->getName());
- log.warn("no metadata found, can't establish identity of issuer (%s)", temp.get());
- return ret;
- }
-
- log.debug("matched message issuer against metadata, searching for applicable role...");
- const RoleDescriptor* roledesc=entity->getRoleDescriptor(*role, issuerInfo.second);
- if (!roledesc) {
- log.warn("unable to find compatible role (%s) in metadata", role->toString().c_str());
- return ret;
- }
-
- if (!x509trust->validate(chain.front(), chain, *roledesc, true, metadataProvider->getKeyResolver())) {
- log.error("unable to verify certificate chain with supplied trust engine");
- return ret;
- }
-
- if (log.isDebugEnabled()) {
- auto_ptr_char iname(entity->getEntityID());
- log.debug("message from (%s), signature verified", iname.get());
- }
-
- ret.first = issuer.release();
- ret.second = roledesc;
+ if (!x509trust->validate(chain.front(), chain, *(policy.getIssuerMetadata()), true,
+ policy.getMetadataProvider()->getKeyResolver())) {
+ log.error("unable to verify certificate chain with supplied trust engine");
+ return;
}
- catch (bad_cast&) {
- // Just trap it.
- log.warn("caught a bad_cast while extracting issuer");
- }
- return ret;
-}
-
-pair<saml2::Issuer*,const XMLCh*> ClientCertAuthRule::getIssuerAndProtocol(const XMLObject& message) const
-{
- // We just let any bad casts throw here.
-
- // Shortcuts some of the casting.
- const XMLCh* ns = message.getElementQName().getNamespaceURI();
- if (ns) {
- if (XMLString::equals(ns, samlconstants::SAML20P_NS)) {
- // 2.0 namespace should be castable to a specialized 2.0 root.
- const saml2::RootObject& root = dynamic_cast<const saml2::RootObject&>(message);
- saml2::Issuer* issuer = root.getIssuer();
- if (issuer && issuer->getName())
- return make_pair(issuer->cloneIssuer(), samlconstants::SAML20P_NS);
- }
- }
- return pair<saml2::Issuer*,const XMLCh*>(NULL,NULL);
+
+ log.debug("client certificate verified against message issuer");
}
#include "internal.h"
#include "exceptions.h"
-#include "RootObject.h"
#include "binding/MessageFlowRule.h"
-#include "util/SAMLConstants.h"
-#include <xmltooling/util/NDC.h>
-#include <xmltooling/util/ReplayCache.h>
#include <log4cpp/Category.hh>
+#include <xmltooling/util/ReplayCache.h>
+#include <xercesc/util/XMLUniDefs.hpp>
using namespace opensaml;
using namespace xmltooling;
}
}
-pair<saml2::Issuer*,const saml2md::RoleDescriptor*> MessageFlowRule::evaluate(
- const XMLObject& message,
- const GenericRequest* request,
- const saml2md::MetadataProvider* metadataProvider,
- const QName* role,
- const TrustEngine* trustEngine
- ) 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");
+ log.debug("evaluating message flow policy (replay checking %s, expiration %lu)", m_checkReplay ? "on" : "off", m_expires);
- try {
- const XMLCh* ns = message.getElementQName().getNamespaceURI();
- if (ns && (XMLString::equals(ns, samlconstants::SAML20P_NS) || XMLString::equals(ns, samlconstants::SAML1P_NS))) {
- const RootObject& obj = dynamic_cast<const RootObject&>(message);
- check(obj.getID(), obj.getIssueInstantEpoch());
- }
- else {
- log.debug("ignoring unrecognized message type");
- }
- }
- catch (bad_cast&) {
- log.warn("caught a bad_cast while extracting issuer");
+ time_t issueInstant = policy.getIssueInstant();
+ if (issueInstant == 0) {
+ log.error("unknown message timestamp");
+ throw BindingException("Message rejected, no timestamp available.");
}
- return pair<saml2::Issuer*,const saml2md::RoleDescriptor*>(NULL,NULL);
-}
-
-void MessageFlowRule::check(const XMLCh* id, time_t issueInstant) 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);
time_t skew = XMLToolingConfig::getConfig().clock_skew_secs;
time_t now = time(NULL);
// Check replay.
if (m_checkReplay) {
+ const XMLCh* id = policy.getMessageID();
ReplayCache* replayCache = XMLToolingConfig::getConfig().getReplayCache();
if (!replayCache)
- throw BindingException("No ReplayCache instance available.");
+ throw BindingException("Message rejected, no ReplayCache instance available.");
else if (!id)
- throw BindingException("Message did not contain an identifier.");
- auto_ptr_char temp(id);
+ throw BindingException("Message rejected, did not contain an identifier.");
+ auto_ptr_char temp(id);
if (!replayCache->check("SAML", temp.get(), issueInstant + skew + m_expires)) {
log.error("replay detected of message ID (%s)", temp.get());
throw BindingException("Rejecting replayed message ID ($1).", params(1,temp.get()));
#include "internal.h"
#include "exceptions.h"
-#include "binding/SecurityPolicy.h"
-#include "saml1/core/Assertions.h"
-#include "saml1/core/Protocols.h"
+#include "binding/SecurityPolicyRule.h"
#include "saml2/core/Assertions.h"
-#include "saml2/core/Protocols.h"
using namespace opensaml::saml2md;
using namespace opensaml::saml2;
namespace opensaml {
SAML_DLLLOCAL PluginManager<SecurityPolicyRule,const DOMElement*>::Factory ClientCertAuthRuleFactory;
SAML_DLLLOCAL PluginManager<SecurityPolicyRule,const DOMElement*>::Factory MessageFlowRuleFactory;
+ SAML_DLLLOCAL PluginManager<SecurityPolicyRule,const DOMElement*>::Factory SAML1MessageRuleFactory;
+ SAML_DLLLOCAL PluginManager<SecurityPolicyRule,const DOMElement*>::Factory SAML2MessageRuleFactory;
SAML_DLLLOCAL PluginManager<SecurityPolicyRule,const DOMElement*>::Factory SimpleSigningRuleFactory;
SAML_DLLLOCAL PluginManager<SecurityPolicyRule,const DOMElement*>::Factory XMLSigningRuleFactory;
};
SAMLConfig& conf=SAMLConfig::getConfig();
conf.SecurityPolicyRuleManager.registerFactory(CLIENTCERTAUTH_POLICY_RULE, ClientCertAuthRuleFactory);
conf.SecurityPolicyRuleManager.registerFactory(MESSAGEFLOW_POLICY_RULE, MessageFlowRuleFactory);
+ conf.SecurityPolicyRuleManager.registerFactory(SAML1MESSAGE_POLICY_RULE, SAML1MessageRuleFactory);
+ conf.SecurityPolicyRuleManager.registerFactory(SAML2MESSAGE_POLICY_RULE, SAML2MessageRuleFactory);
conf.SecurityPolicyRuleManager.registerFactory(SIMPLESIGNING_POLICY_RULE, SimpleSigningRuleFactory);
conf.SecurityPolicyRuleManager.registerFactory(XMLSIGNING_POLICY_RULE, XMLSigningRuleFactory);
}
SecurityPolicy::~SecurityPolicy()
{
- delete m_matchingPolicy;
+ reset();
+}
+
+void SecurityPolicy::reset()
+{
+ 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;
}
void SecurityPolicy::evaluate(const XMLObject& message, const GenericRequest* request)
{
- for (vector<const SecurityPolicyRule*>::const_iterator i=m_rules.begin(); i!=m_rules.end(); ++i) {
-
- // Run the rule...
- pair<Issuer*,const RoleDescriptor*> ident = (*i)->evaluate(message,request,m_metadata,&m_role,m_trust);
-
- // Make sure returned issuer doesn't conflict.
-
- if (ident.first) {
- if (!getIssuerMatchingPolicy().issuerMatches(ident.first, m_issuer)) {
- delete ident.first;
- throw BindingException("Policy rules returned differing Issuers.");
- }
- delete m_issuer;
- m_issuer=ident.first;
- }
-
- if (ident.second) {
- if (m_issuerRole && ident.second!=m_issuerRole)
- throw BindingException("Policy rules returned differing issuer RoleDescriptors.");
- m_issuerRole=ident.second;
- }
- }
+ for (vector<const SecurityPolicyRule*>::const_iterator i=m_rules.begin(); i!=m_rules.end(); ++i)
+ (*i)->evaluate(message,request,*this);
}
void SecurityPolicy::setIssuer(saml2::Issuer* issuer)
{
if (!getIssuerMatchingPolicy().issuerMatches(issuer, m_issuer)) {
delete issuer;
- throw BindingException("Externally provided Issuer conflicts with policy results.");
+ throw BindingException("A rule supplied an Issuer that conflicts with previous results.");
}
delete m_issuer;
void SecurityPolicy::setIssuerMetadata(const RoleDescriptor* issuerRole)
{
if (issuerRole && m_issuerRole && issuerRole!=m_issuerRole)
- throw BindingException("Externally provided RoleDescriptor conflicts with policy results.");
+ throw BindingException("A rule supplied a RoleDescriptor that conflicts with previous results.");
m_issuerRole=issuerRole;
}
#include "exceptions.h"
#include "binding/HTTPRequest.h"
#include "binding/SimpleSigningRule.h"
-#include "saml2/core/Protocols.h"
+#include "saml2/core/Assertions.h"
#include "saml2/metadata/Metadata.h"
#include "saml2/metadata/MetadataProvider.h"
#include <log4cpp/Category.hh>
-#include <xmltooling/util/NDC.h>
-#include <xmltooling/util/ReplayCache.h>
-#include <xsec/enc/XSECCryptoException.hpp>
-#include <xsec/enc/XSECCryptoProvider.hpp>
-#include <xsec/framework/XSECException.hpp>
using namespace opensaml::saml2md;
using namespace opensaml;
};
-pair<saml2::Issuer*,const RoleDescriptor*> SimpleSigningRule::evaluate(
- const XMLObject& message,
- const GenericRequest* request,
- const MetadataProvider* metadataProvider,
- const QName* role,
- const TrustEngine* trustEngine
- ) 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");
- pair<saml2::Issuer*,const RoleDescriptor*> ret = pair<saml2::Issuer*,const RoleDescriptor*>(NULL,NULL);
-
+ if (!policy.getIssuerMetadata()) {
+ log.debug("ignoring message, no issuer metadata supplied");
+ return;
+ }
+ else if (!policy.getTrustEngine()) {
+ log.debug("ignoring message, no TrustEngine supplied");
+ return;
+ }
+
const HTTPRequest* httpRequest = dynamic_cast<const HTTPRequest*>(request);
if (!request || !httpRequest) {
log.debug("ignoring message, no HTTP protocol request available");
- return ret;
+ return;
}
- if (!metadataProvider || !role || !trustEngine) {
- log.debug("ignoring message, no metadata supplied");
- return ret;
- }
-
const char* signature = request->getParameter("Signature");
if (!signature) {
log.debug("ignoring unsigned message");
- return ret;
+ return;
}
const char* sigAlgorithm = request->getParameter("SigAlg");
if (!sigAlgorithm) {
log.error("SigAlg parameter not found, no way to verify the signature");
- return ret;
+ return;
}
- try {
- log.debug("extracting issuer from message");
- pair<saml2::Issuer*,const XMLCh*> issuerInfo = getIssuerAndProtocol(message);
-
- auto_ptr<saml2::Issuer> issuer(issuerInfo.first);
- if (!issuerInfo.first || !issuerInfo.second ||
- (issuer->getFormat() && !XMLString::equals(issuer->getFormat(), saml2::NameIDType::ENTITY))) {
- log.warn("issuer identity not estabished, or was not an entityID");
- return ret;
- }
-
- log.debug("searching metadata for message issuer...");
- const EntityDescriptor* entity = metadataProvider->getEntityDescriptor(issuer->getName());
- if (!entity) {
- auto_ptr_char temp(issuer->getName());
- log.warn("no metadata found, can't establish identity of issuer (%s)", temp.get());
- return ret;
- }
-
- log.debug("matched message issuer against metadata, searching for applicable role...");
- const RoleDescriptor* roledesc=entity->getRoleDescriptor(*role, issuerInfo.second);
- if (!roledesc) {
- log.warn("unable to find compatible role (%s) in metadata", role->toString().c_str());
- return ret;
- }
-
- string input;
- const char* pch;
- if (!strcmp(httpRequest->getMethod(), "GET")) {
- // We have to construct a string containing the signature input by accessing the
- // request directly. We can't use the decoded parameters because we need the raw
- // data and URL-encoding isn't canonical.
- pch = httpRequest->getQueryString();
- if (!appendParameter(input, pch, "SAMLRequest="))
- appendParameter(input, pch, "SAMLResponse=");
- appendParameter(input, pch, "RelayState=");
- appendParameter(input, pch, "SigAlg=");
- }
+ string input;
+ const char* pch;
+ if (!strcmp(httpRequest->getMethod(), "GET")) {
+ // We have to construct a string containing the signature input by accessing the
+ // request directly. We can't use the decoded parameters because we need the raw
+ // data and URL-encoding isn't canonical.
+ pch = httpRequest->getQueryString();
+ if (!appendParameter(input, pch, "SAMLRequest="))
+ appendParameter(input, pch, "SAMLResponse=");
+ appendParameter(input, pch, "RelayState=");
+ appendParameter(input, pch, "SigAlg=");
+ }
+ else {
+ // With POST, the input string is concatenated from the decoded form controls.
+ // GET should be this way too, but I messed up the spec, sorry.
+ pch = httpRequest->getParameter("SAMLRequest");
+ if (pch)
+ input = string("SAMLRequest=") + pch;
else {
- // With POST, the input string is concatenated from the decoded form controls.
- // GET should be this way too, but I messed up the spec, sorry.
- pch = httpRequest->getParameter("SAMLRequest");
- if (pch)
- input = string("SAMLRequest=") + pch;
- else {
- pch = httpRequest->getParameter("SAMLResponse");
- input = string("SAMLResponse=") + pch;
- }
- pch = httpRequest->getParameter("RelayState");
- if (pch)
- input = input + "&RelayState=" + pch;
- input = input + "&SigAlg=" + sigAlgorithm;
+ pch = httpRequest->getParameter("SAMLResponse");
+ input = string("SAMLResponse=") + pch;
}
+ pch = httpRequest->getParameter("RelayState");
+ if (pch)
+ input = input + "&RelayState=" + pch;
+ input = input + "&SigAlg=" + sigAlgorithm;
+ }
- // Check for KeyInfo, but defensively (we might be able to run without it).
- KeyInfo* keyInfo=NULL;
- pch = request->getParameter("KeyInfo");
- if (pch) {
- try {
- istringstream kstrm(pch);
- DOMDocument* doc = XMLToolingConfig::getConfig().getParser().parse(kstrm);
- XercesJanitor<DOMDocument> janitor(doc);
- XMLObject* kxml = XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true);
- janitor.release();
- if (!(keyInfo=dynamic_cast<KeyInfo*>(kxml)))
- delete kxml;
- }
- catch (XMLToolingException& ex) {
- log.warn("Failed to load KeyInfo from message: %s", ex.what());
- }
- }
-
- auto_ptr<KeyInfo> kjanitor(keyInfo);
- auto_ptr_XMLCh alg(sigAlgorithm);
-
- if (!trustEngine->validate(alg.get(), signature, keyInfo, input.c_str(), input.length(), *roledesc, metadataProvider->getKeyResolver())) {
- log.error("unable to verify signature on message with supplied trust engine");
- return ret;
+ // Check for KeyInfo, but defensively (we might be able to run without it).
+ KeyInfo* keyInfo=NULL;
+ pch = request->getParameter("KeyInfo");
+ if (pch) {
+ try {
+ istringstream kstrm(pch);
+ DOMDocument* doc = XMLToolingConfig::getConfig().getParser().parse(kstrm);
+ XercesJanitor<DOMDocument> janitor(doc);
+ XMLObject* kxml = XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true);
+ janitor.release();
+ if (!(keyInfo=dynamic_cast<KeyInfo*>(kxml)))
+ delete kxml;
}
-
- if (log.isDebugEnabled()) {
- auto_ptr_char iname(entity->getEntityID());
- log.debug("message from (%s), signature verified", iname.get());
+ catch (XMLToolingException& ex) {
+ log.warn("Failed to load KeyInfo from message: %s", ex.what());
}
-
- ret.first = issuer.release();
- ret.second = roledesc;
}
- catch (bad_cast&) {
- // Just trap it.
- log.warn("caught a bad_cast while extracting issuer");
+
+ auto_ptr<KeyInfo> kjanitor(keyInfo);
+ auto_ptr_XMLCh alg(sigAlgorithm);
+
+ if (!policy.getTrustEngine()->validate(
+ alg.get(), signature, keyInfo, input.c_str(), input.length(),
+ *(policy.getIssuerMetadata()), policy.getMetadataProvider()->getKeyResolver()
+ )) {
+ log.error("unable to verify message signature with supplied trust engine");
+ return;
}
- return ret;
-}
-
-pair<saml2::Issuer*,const XMLCh*> SimpleSigningRule::getIssuerAndProtocol(const XMLObject& message) const
-{
- // We just let any bad casts throw here.
- // Shortcuts some of the casting.
- const XMLCh* ns = message.getElementQName().getNamespaceURI();
- if (ns) {
- if (XMLString::equals(ns, samlconstants::SAML20P_NS)) {
- // 2.0 namespace should be castable to a specialized 2.0 root.
- const saml2::RootObject& root = dynamic_cast<const saml2::RootObject&>(message);
- saml2::Issuer* issuer = root.getIssuer();
- if (issuer && issuer->getName())
- return make_pair(issuer->cloneIssuer(), samlconstants::SAML20P_NS);
-
- // No issuer in the message, so we have to try the Response approach.
- const vector<saml2::Assertion*>& assertions = dynamic_cast<const saml2p::Response&>(message).getAssertions();
- if (!assertions.empty()) {
- issuer = assertions.front()->getIssuer();
- if (issuer && issuer->getName())
- return make_pair(issuer->cloneIssuer(), samlconstants::SAML20P_NS);
- }
- }
- }
- return pair<saml2::Issuer*,const XMLCh*>(NULL,NULL);
+ log.debug("signature verified against message issuer");
}
#include "internal.h"
#include "exceptions.h"
#include "binding/XMLSigningRule.h"
-#include "saml1/core/Assertions.h"
-#include "saml1/core/Protocols.h"
-#include "saml2/core/Protocols.h"
+#include "saml2/core/Assertions.h"
#include "saml2/metadata/Metadata.h"
#include "saml2/metadata/MetadataProvider.h"
#include "signature/SignatureProfileValidator.h"
-#include <xmltooling/util/NDC.h>
-#include <xmltooling/util/ReplayCache.h>
#include <log4cpp/Category.hh>
using namespace opensaml::saml2md;
}
};
-pair<saml2::Issuer*,const RoleDescriptor*> XMLSigningRule::evaluate(
- const XMLObject& message,
- const GenericRequest* request,
- const MetadataProvider* metadataProvider,
- const QName* role,
- const TrustEngine* trustEngine
- ) 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");
- pair<saml2::Issuer*,const RoleDescriptor*> ret = pair<saml2::Issuer*,const RoleDescriptor*>(NULL,NULL);
+ if (!policy.getIssuerMetadata()) {
+ log.debug("ignoring message, no issuer metadata supplied");
+ return;
+ }
+ else if (!policy.getTrustEngine()) {
+ log.debug("ignoring message, no TrustEngine supplied");
+ return;
+ }
- if (!metadataProvider || !role || !trustEngine) {
- log.debug("ignoring message, no metadata or trust information supplied");
- return ret;
+ const SignableObject* signable = dynamic_cast<const SignableObject*>(&message);
+ if (!signable || !signable->getSignature()) {
+ log.debug("ignoring unsigned or unrecognized message");
+ return;
}
+ log.debug("validating signature profile");
try {
- const SignableObject* signable = dynamic_cast<const SignableObject*>(&message);
- if (!signable || !signable->getSignature()) {
- log.debug("ignoring unsigned or unrecognized message");
- return ret;
- }
-
- log.debug("validating signature profile");
- try {
- SignatureProfileValidator sigval;
- sigval.validate(signable->getSignature());
- }
- catch (ValidationException& ve) {
- log.error("signature profile failed to validate: %s", ve.what());
- return ret;
- }
-
-
- log.debug("extracting issuer from message");
- pair<saml2::Issuer*,const XMLCh*> issuerInfo = getIssuerAndProtocol(message);
-
- auto_ptr<saml2::Issuer> issuer(issuerInfo.first);
- if (!issuerInfo.first || !issuerInfo.second ||
- (issuer->getFormat() && !XMLString::equals(issuer->getFormat(), saml2::NameIDType::ENTITY))) {
- log.warn("issuer identity not estabished, or was not an entityID");
- return ret;
- }
-
- log.debug("searching metadata for message issuer...");
- const EntityDescriptor* entity = metadataProvider->getEntityDescriptor(issuer->getName());
- if (!entity) {
- auto_ptr_char temp(issuer->getName());
- log.warn("no metadata found, can't establish identity of issuer (%s)", temp.get());
- return ret;
- }
-
- log.debug("matched message issuer against metadata, searching for applicable role...");
- const RoleDescriptor* roledesc=entity->getRoleDescriptor(*role, issuerInfo.second);
- if (!roledesc) {
- log.warn("unable to find compatible role (%s) in metadata", role->toString().c_str());
- return ret;
- }
-
- if (!trustEngine->validate(*(signable->getSignature()), *roledesc, metadataProvider->getKeyResolver())) {
- log.error("unable to verify signature on message with supplied trust engine");
- return ret;
- }
-
- if (log.isDebugEnabled()) {
- auto_ptr_char iname(entity->getEntityID());
- log.debug("message from (%s), signature verified", iname.get());
- }
-
- ret.first = issuer.release();
- ret.second = roledesc;
+ SignatureProfileValidator sigval;
+ sigval.validate(signable->getSignature());
}
- catch (bad_cast&) {
- // Just trap it.
- log.warn("caught a bad_cast while extracting issuer");
+ catch (ValidationException& ve) {
+ log.error("signature profile failed to validate: %s", ve.what());
+ return;
}
- return ret;
-}
-
-pair<saml2::Issuer*,const XMLCh*> XMLSigningRule::getIssuerAndProtocol(const XMLObject& message) const
-{
- // We just let any bad casts throw here.
- saml2::Issuer* issuer;
-
- // Shortcuts some of the casting.
- const XMLCh* ns = message.getElementQName().getNamespaceURI();
- if (ns) {
- if (XMLString::equals(ns, samlconstants::SAML20P_NS) || XMLString::equals(ns, samlconstants::SAML20_NS)) {
- // 2.0 namespace should be castable to a specialized 2.0 root.
- const saml2::RootObject& root = dynamic_cast<const saml2::RootObject&>(message);
- issuer = root.getIssuer();
- if (issuer && issuer->getName()) {
- return make_pair(issuer->cloneIssuer(), samlconstants::SAML20P_NS);
- }
-
- // No issuer in the message, so we have to try the Response approach.
- const vector<saml2::Assertion*>& assertions = dynamic_cast<const saml2p::Response&>(message).getAssertions();
- if (!assertions.empty()) {
- issuer = assertions.front()->getIssuer();
- if (issuer && issuer->getName())
- return make_pair(issuer->cloneIssuer(), samlconstants::SAML20P_NS);
- }
- }
- else if (XMLString::equals(ns, samlconstants::SAML1P_NS)) {
- // Should be a samlp:Response, at least in OpenSAML.
- const vector<saml1::Assertion*>& assertions = dynamic_cast<const saml1p::Response&>(message).getAssertions();
- if (!assertions.empty()) {
- const saml1::Assertion* a = assertions.front();
- if (a->getIssuer()) {
- issuer = saml2::IssuerBuilder::buildIssuer();
- issuer->setName(a->getIssuer());
- pair<bool,int> minor = a->getMinorVersion();
- return make_pair(
- issuer,
- (minor.first && minor.second==0) ? samlconstants::SAML10_PROTOCOL_ENUM : samlconstants::SAML11_PROTOCOL_ENUM
- );
- }
- }
- }
+ if (!policy.getTrustEngine()->validate(
+ *(signable->getSignature()), *(policy.getIssuerMetadata()), policy.getMetadataProvider()->getKeyResolver()
+ )) {
+ log.error("unable to verify message signature with supplied trust engine");
+ return;
}
- return pair<saml2::Issuer*,const XMLCh*>(NULL,NULL);
+
+ log.debug("signature verified against message issuer");
}
>\r
</File>\r
<File\r
+ RelativePath=".\saml1\binding\impl\SAML1MessageRule.cpp"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\saml1\binding\impl\SAML1POSTDecoder.cpp"\r
>\r
</File>\r
</FileConfiguration>\r
</File>\r
<File\r
+ RelativePath=".\saml2\binding\impl\SAML2MessageRule.cpp"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\saml2\binding\impl\SAML2POSTDecoder.cpp"\r
>\r
</File>\r
>\r
</File>\r
<File\r
+ RelativePath=".\saml1\binding\SAML1MessageRule.h"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\saml1\binding\SAML1POSTDecoder.h"\r
>\r
</File>\r
>\r
</File>\r
<File\r
+ RelativePath=".\saml2\binding\SAML2MessageRule.h"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\saml2\binding\SAML2POSTDecoder.h"\r
>\r
</File>\r
--- /dev/null
+/*
+ * Copyright 2001-2006 Internet2
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file saml/saml1/binding/SAML1MessageRule.h
+ *
+ * SAML 1.x message extraction rule
+ */
+
+#include <saml/binding/SecurityPolicyRule.h>
+
+
+namespace opensaml {
+ namespace saml1p {
+ /**
+ * SAML 1.x message extraction rule
+ */
+ class SAML_API SAML1MessageRule : public SecurityPolicyRule
+ {
+ public:
+ SAML1MessageRule(const DOMElement* e) {}
+ virtual ~SAML1MessageRule() {}
+
+ void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
+ };
+ };
+};
auto_ptr_char issuer(provider->getEntityID());
log.debug("lookup succeeded, artifact issued by (%s)", issuer.get());
}
+
+ // Mock up an Issuer object for the policy.
+ auto_ptr<saml2::Issuer> issuer(saml2::IssuerBuilder::buildIssuer());
+ issuer->setName(provider->getEntityID());
+ policy.setIssuer(issuer.get());
+ issuer.release(); // owned by policy now
log.debug("attempting to find artifact issuing role...");
const RoleDescriptor* roledesc=provider->getRoleDescriptor(*(policy.getRole()), samlconstants::SAML11_PROTOCOL_ENUM);
if (!roledesc || !dynamic_cast<const IDPSSODescriptor*>(roledesc)) {
log.error("unable to find compatible SAML role (%s) in metadata", policy.getRole()->toString().c_str());
for_each(artifacts.begin(), artifacts.end(), xmltooling::cleanup<SAMLArtifact>());
- BindingException ex("Unable to find compatible metadata role for artifact issuer.");
- annotateException(&ex,provider); // throws it
+ throw BindingException("Unable to find compatible metadata role for artifact issuer.");
}
+ policy.setIssuerMetadata(roledesc);
try {
auto_ptr<Response> response(
for_each(artifacts.begin(), artifacts.end(), xmltooling::cleanup<SAMLArtifact>());
return response.release();
}
- catch (XMLToolingException& ex) {
+ catch (XMLToolingException&) {
for_each(artifacts.begin(), artifacts.end(), xmltooling::cleanup<SAMLArtifact>());
- annotateException(&ex,roledesc,false);
throw;
}
}
--- /dev/null
+/*
+ * Copyright 2001-2006 Internet2
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * SAML1MessageRule.cpp
+ *
+ * SAML 1.x message extraction rule
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "RootObject.h"
+#include "saml1/binding/SAML1MessageRule.h"
+#include "saml1/core/Assertions.h"
+#include "saml1/core/Protocols.h"
+#include "saml2/core/Assertions.h"
+#include "saml2/metadata/Metadata.h"
+#include "saml2/metadata/MetadataProvider.h"
+#include "util/SAMLConstants.h"
+
+#include <log4cpp/Category.hh>
+
+using namespace opensaml::saml2md;
+using namespace opensaml::saml1p;
+using namespace opensaml;
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+namespace opensaml {
+ SecurityPolicyRule* SAML_DLLLOCAL SAML1MessageRuleFactory(const DOMElement* const & e)
+ {
+ return new SAML1MessageRule(e);
+ }
+};
+
+void SAML1MessageRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const
+{
+ Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.SAML1Message");
+
+ const QName& q = message.getElementQName();
+ policy.setMessageQName(&q);
+
+ try {
+ const RootObject& samlRoot = dynamic_cast<const RootObject&>(message);
+ policy.setMessageID(samlRoot.getID());
+ policy.setIssueInstant(samlRoot.getIssueInstantEpoch());
+
+ if (!XMLString::equals(q.getNamespaceURI(), samlconstants::SAML1P_NS)) {
+ log.warn("not a SAML 1.x protocol message");
+ throw BindingException("Message was not a recognized SAML 1.x protocol element.");
+ }
+
+ log.debug("extracting issuer from message");
+
+ // Only samlp:Response is known to carry issuer (via payload) in standard SAML 1.x.
+ const XMLCh* protocol = NULL;
+ if (XMLString::equals(q.getLocalPart(), Response::LOCAL_NAME)) {
+ // Should be a samlp:Response.
+ const vector<saml1::Assertion*>& assertions = dynamic_cast<const saml1p::Response&>(samlRoot).getAssertions();
+ if (!assertions.empty()) {
+ const saml1::Assertion* a = assertions.front();
+ if (a->getIssuer()) {
+ auto_ptr<saml2::Issuer> issuer(saml2::IssuerBuilder::buildIssuer());
+ issuer->setName(a->getIssuer());
+ policy.setIssuer(issuer.get());
+ issuer.release(); // owned by policy now
+ pair<bool,int> minor = a->getMinorVersion();
+ protocol = (minor.first && minor.second==0) ?
+ samlconstants::SAML10_PROTOCOL_ENUM : samlconstants::SAML11_PROTOCOL_ENUM;
+ }
+ }
+ }
+
+ if (!protocol) {
+ log.warn("issuer identity not extracted");
+ return;
+ }
+
+ if (log.isDebugEnabled()) {
+ auto_ptr_char iname(policy.getIssuer()->getName());
+ log.debug("message from (%s)", iname.get());
+ }
+
+ if (policy.getMetadataProvider() && policy.getRole()) {
+ log.debug("searching metadata for message issuer...");
+ const EntityDescriptor* entity = policy.getMetadataProvider()->getEntityDescriptor(policy.getIssuer()->getName());
+ if (!entity) {
+ auto_ptr_char temp(policy.getIssuer()->getName());
+ log.warn("no metadata found, can't establish identity of issuer (%s)", temp.get());
+ 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;
+ }
+ policy.setIssuerMetadata(roledesc);
+ }
+ }
+ catch (bad_cast&) {
+ // Just trap it.
+ log.warn("caught a bad_cast while examining message");
+ }
+}
if (!response)
throw BindingException("Decoded message was not a SAML 1.x Response.");
- try {
- if (!m_validate)
- SchemaValidators.validate(xmlObject.get());
-
- // Check recipient URL.
- auto_ptr_char recipient(response->getRecipient());
- const char* recipient2 = httpRequest->getRequestURL();
- if (!recipient.get() || !*(recipient.get())) {
- log.error("response missing Recipient attribute");
- throw BindingException("SAML response did not contain Recipient attribute identifying intended destination.");
- }
- else if (!recipient2 || !*recipient2 || strcmp(recipient.get(),recipient2)) {
- log.error("POST targeted at (%s), but delivered to (%s)", recipient.get(), recipient2 ? recipient2 : "none");
- throw BindingException("SAML message delivered with POST to incorrect server URL.");
- }
-
- // Run through the policy.
- policy.evaluate(*response, &genericRequest);
+ if (!m_validate)
+ SchemaValidators.validate(xmlObject.get());
+
+ // Check recipient URL.
+ auto_ptr_char recipient(response->getRecipient());
+ const char* recipient2 = httpRequest->getRequestURL();
+ if (!recipient.get() || !*(recipient.get())) {
+ log.error("response missing Recipient attribute");
+ throw BindingException("SAML response did not contain Recipient attribute identifying intended destination.");
}
- catch (XMLToolingException& ex) {
- // This is just to maximize the likelihood of attaching a source to the message for support purposes.
- if (policy.getIssuerMetadata())
- annotateException(&ex,policy.getIssuerMetadata()); // throws it
-
- // Check for an Issuer.
- const EntityDescriptor* provider=NULL;
- const vector<Assertion*>& assertions=const_cast<const Response*>(response)->getAssertions();
- if (!assertions.empty() || !policy.getMetadataProvider() ||
- !(provider=policy.getMetadataProvider()->getEntityDescriptor(assertions.front()->getIssuer(), false))) {
- // Just record it.
- auto_ptr_char iname(assertions.front()->getIssuer());
- if (iname.get())
- ex.addProperty("entityID", iname.get());
- throw;
- }
- if (policy.getRole()) {
- pair<bool,int> minor = response->getMinorVersion();
- const RoleDescriptor* roledesc=provider->getRoleDescriptor(
- *(policy.getRole()),
- (minor.first && minor.second==0) ? samlconstants::SAML10_PROTOCOL_ENUM : samlconstants::SAML11_PROTOCOL_ENUM
- );
- if (roledesc) annotateException(&ex,roledesc); // throws it
- }
- annotateException(&ex,provider); // throws it
+ else if (!recipient2 || !*recipient2 || strcmp(recipient.get(),recipient2)) {
+ log.error("POST targeted at (%s), but delivered to (%s)", recipient.get(), recipient2 ? recipient2 : "none");
+ throw BindingException("SAML message delivered with POST to incorrect server URL.");
}
+
+ // Run through the policy.
+ policy.evaluate(*response, &genericRequest);
- xmlObject.release();
- return response;
+ return xmlObject.release();
}
--- /dev/null
+/*
+ * Copyright 2001-2006 Internet2
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file saml/saml2/binding/SAML2MessageRule.h
+ *
+ * SAML 2.0 message extraction rule
+ */
+
+#include <saml/binding/SecurityPolicyRule.h>
+
+
+namespace opensaml {
+ namespace saml2p {
+ /**
+ * SAML 2.0 message extraction rule
+ */
+ class SAML_API SAML2MessageRule : public SecurityPolicyRule
+ {
+ public:
+ SAML2MessageRule(const DOMElement* e) {}
+ virtual ~SAML2MessageRule() {}
+
+ void evaluate(const xmltooling::XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
+ };
+ };
+};
auto_ptr_char issuer(provider->getEntityID());
log.debug("lookup succeeded, artifact issued by (%s)", issuer.get());
}
+
+ // Mock up an Issuer object for the policy.
+ auto_ptr<Issuer> issuer(IssuerBuilder::buildIssuer());
+ issuer->setName(provider->getEntityID());
+ policy.setIssuer(issuer.get());
+ issuer.release(); // owned by policy now
log.debug("attempting to find artifact issuing role...");
const RoleDescriptor* roledesc=provider->getRoleDescriptor(*(policy.getRole()), samlconstants::SAML20P_NS);
if (!roledesc || !dynamic_cast<const SSODescriptorType*>(roledesc)) {
log.error("unable to find compatible SAML role (%s) in metadata", policy.getRole()->toString().c_str());
- BindingException ex("Unable to find compatible metadata role for artifact issuer.");
- annotateException(&ex,provider); // throws it
+ throw BindingException("Unable to find compatible metadata role for artifact issuer.");
}
+ policy.setIssuerMetadata(roledesc);
- try {
- auto_ptr<ArtifactResponse> response(
- m_artifactResolver->resolve(*(artifact2.get()), dynamic_cast<const SSODescriptorType&>(*roledesc), policy)
- );
-
- policy.evaluate(*(response.get()), &genericRequest);
+ auto_ptr<ArtifactResponse> response(
+ m_artifactResolver->resolve(*(artifact2.get()), dynamic_cast<const SSODescriptorType&>(*roledesc), policy)
+ );
+
+ policy.evaluate(*(response.get()), &genericRequest);
- // Extract payload and check that message.
- XMLObject* payload = response->getPayload();
- policy.evaluate(*payload, &genericRequest);
+ // Extract payload and check that message.
+ XMLObject* payload = response->getPayload();
+ policy.evaluate(*payload, &genericRequest);
- // Return the payload only.
- response.release();
- payload->detach();
- return payload;
- }
- catch (XMLToolingException& ex) {
- annotateException(&ex,roledesc,false);
- throw;
- }
+ // Return the payload only.
+ response.release();
+ payload->detach();
+ return payload;
}
--- /dev/null
+/*
+ * Copyright 2001-2006 Internet2
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * SAML1MessageRule.cpp
+ *
+ * SAML 1.x message extraction rule
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "saml2/binding/SAML2MessageRule.h"
+#include "saml2/core/Protocols.h"
+#include "saml2/metadata/Metadata.h"
+#include "saml2/metadata/MetadataProvider.h"
+#include "util/SAMLConstants.h"
+
+#include <log4cpp/Category.hh>
+
+using namespace opensaml::saml2md;
+using namespace opensaml::saml2p;
+using namespace opensaml::saml2;
+using namespace opensaml;
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+namespace opensaml {
+ SecurityPolicyRule* SAML_DLLLOCAL SAML2MessageRuleFactory(const DOMElement* const & e)
+ {
+ return new SAML2MessageRule(e);
+ }
+};
+
+void SAML2MessageRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const
+{
+ Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.SAML2Message");
+
+ const QName& q = message.getElementQName();
+ policy.setMessageQName(&q);
+
+ try {
+ const opensaml::RootObject& samlRoot = dynamic_cast<const opensaml::RootObject&>(message);
+ policy.setMessageID(samlRoot.getID());
+ policy.setIssueInstant(samlRoot.getIssueInstantEpoch());
+
+ if (!XMLString::equals(q.getNamespaceURI(), samlconstants::SAML20P_NS)) {
+ log.warn("not a SAML 2.0 protocol message");
+ throw BindingException("Message was not a recognized SAML 2.0 protocol element.");
+ }
+
+ log.debug("extracting issuer from message");
+ const saml2::RootObject& saml2Root = dynamic_cast<const saml2::RootObject&>(samlRoot);
+ Issuer* issuer = saml2Root.getIssuer();
+ if (issuer && issuer->getName()) {
+ auto_ptr<Issuer> copy(issuer->cloneIssuer());
+ policy.setIssuer(copy.get());
+ copy.release();
+ }
+ else {
+ // No issuer in the message, so we have to try the Response approach.
+ const vector<Assertion*>& assertions = dynamic_cast<const Response&>(saml2Root).getAssertions();
+ if (!assertions.empty()) {
+ issuer = assertions.front()->getIssuer();
+ if (issuer && issuer->getName()) {
+ auto_ptr<Issuer> copy(issuer->cloneIssuer());
+ policy.setIssuer(copy.get());
+ copy.release();
+ }
+ }
+ }
+
+ if (!policy.getIssuer()) {
+ log.warn("issuer identity not extracted");
+ return;
+ }
+
+ if (log.isDebugEnabled()) {
+ auto_ptr_char iname(policy.getIssuer()->getName());
+ log.debug("message from (%s)", iname.get());
+ }
+
+ 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;
+ }
+
+ log.debug("searching metadata for message issuer...");
+ const EntityDescriptor* entity = policy.getMetadataProvider()->getEntityDescriptor(policy.getIssuer()->getName());
+ if (!entity) {
+ auto_ptr_char temp(policy.getIssuer()->getName());
+ log.warn("no metadata found, can't establish identity of issuer (%s)", temp.get());
+ 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;
+ }
+ policy.setIssuerMetadata(roledesc);
+ }
+ }
+ catch (bad_cast&) {
+ // Just trap it.
+ log.warn("caught a bad_cast while examining message");
+ }
+}
root = static_cast<saml2::RootObject*>(request);
}
- try {
- if (!m_validate)
- SchemaValidators.validate(xmlObject.get());
-
- // Check destination URL.
- auto_ptr_char dest(request ? request->getDestination() : response->getDestination());
- const char* dest2 = httpRequest->getRequestURL();
- if ((root->getSignature() || httpRequest->getParameter("Signature")) && !dest.get() || !*(dest.get())) {
- log.error("signed SAML message missing Destination attribute");
- throw BindingException("Signed SAML message missing Destination attribute identifying intended destination.");
- }
- else if (dest.get() && (!dest2 || !*dest2 || strcmp(dest.get(),dest2))) {
- log.error("POST targeted at (%s), but delivered to (%s)", dest.get(), dest2 ? dest2 : "none");
- throw BindingException("SAML message delivered with POST to incorrect server URL.");
- }
-
- // Run through the policy.
- policy.evaluate(*root, &genericRequest);
- }
- catch (XMLToolingException& ex) {
- // This is just to maximize the likelihood of attaching a source to the message for support purposes.
- if (policy.getIssuerMetadata())
- annotateException(&ex,policy.getIssuerMetadata()); // throws it
-
- const Issuer* claimedIssuer = root->getIssuer();
- if (!claimedIssuer) {
- // Check for assertions.
- const Response* assbag = dynamic_cast<Response*>(response);
- if (assbag) {
- const vector<Assertion*>& assertions=assbag->getAssertions();
- if (!assertions.empty())
- claimedIssuer = assertions.front()->getIssuer();
- }
- }
+ if (!m_validate)
+ SchemaValidators.validate(xmlObject.get());
- if (!claimedIssuer || !claimedIssuer->getName())
- throw;
- const EntityDescriptor* provider=NULL;
- if (!policy.getMetadataProvider() ||
- !(provider=policy.getMetadataProvider()->getEntityDescriptor(claimedIssuer->getName(), false))) {
- // Just record it.
- auto_ptr_char iname(claimedIssuer->getName());
- if (iname.get())
- ex.addProperty("entityID", iname.get());
- throw;
- }
-
- if (policy.getRole()) {
- const RoleDescriptor* roledesc=provider->getRoleDescriptor(*(policy.getRole()), samlconstants::SAML20P_NS);
- if (roledesc) annotateException(&ex,roledesc); // throws it
- }
- annotateException(&ex,provider); // throws it
+ // Check destination URL.
+ auto_ptr_char dest(request ? request->getDestination() : response->getDestination());
+ const char* dest2 = httpRequest->getRequestURL();
+ if ((root->getSignature() || httpRequest->getParameter("Signature")) && !dest.get() || !*(dest.get())) {
+ log.error("signed SAML message missing Destination attribute");
+ throw BindingException("Signed SAML message missing Destination attribute identifying intended destination.");
}
-
+ else if (dest.get() && (!dest2 || !*dest2 || strcmp(dest.get(),dest2))) {
+ log.error("POST targeted at (%s), but delivered to (%s)", dest.get(), dest2 ? dest2 : "none");
+ throw BindingException("SAML message delivered with POST to incorrect server URL.");
+ }
+
+ // Run through the policy.
+ policy.evaluate(*root, &genericRequest);
return xmlObject.release();
}
root = static_cast<saml2::RootObject*>(request);
}
+ if (!m_validate)
+ SchemaValidators.validate(xmlObject.get());
- try {
- if (!m_validate)
- SchemaValidators.validate(xmlObject.get());
-
- // Check destination URL.
- auto_ptr_char dest(request ? request->getDestination() : response->getDestination());
- const char* dest2 = httpRequest->getRequestURL();
- if ((root->getSignature() || httpRequest->getParameter("Signature")) && !dest.get() || !*(dest.get())) {
- log.error("signed SAML message missing Destination attribute");
- throw BindingException("Signed SAML message missing Destination attribute identifying intended destination.");
- }
- else if (dest.get() && (!dest2 || !*dest2 || strcmp(dest.get(),dest2))) {
- log.error("Redirect targeted at (%s), but delivered to (%s)", dest.get(), dest2 ? dest2 : "none");
- throw BindingException("SAML message delivered with Redirect to incorrect server URL.");
- }
-
- // Run through the policy.
- policy.evaluate(*root, &genericRequest);
+ // Check destination URL.
+ auto_ptr_char dest(request ? request->getDestination() : response->getDestination());
+ const char* dest2 = httpRequest->getRequestURL();
+ if ((root->getSignature() || httpRequest->getParameter("Signature")) && !dest.get() || !*(dest.get())) {
+ log.error("signed SAML message missing Destination attribute");
+ throw BindingException("Signed SAML message missing Destination attribute identifying intended destination.");
}
- catch (XMLToolingException& ex) {
- // This is just to maximize the likelihood of attaching a source to the message for support purposes.
- if (policy.getIssuerMetadata())
- annotateException(&ex,policy.getIssuerMetadata()); // throws it
-
- const Issuer* claimedIssuer = root->getIssuer();
- if (!claimedIssuer || !claimedIssuer->getName())
- throw;
- const EntityDescriptor* provider=NULL;
- if (!policy.getMetadataProvider() ||
- !(provider=policy.getMetadataProvider()->getEntityDescriptor(claimedIssuer->getName(), false))) {
- // Just record it.
- auto_ptr_char iname(claimedIssuer->getName());
- if (iname.get())
- ex.addProperty("entityID", iname.get());
- throw;
- }
-
- if (policy.getRole()) {
- const RoleDescriptor* roledesc=provider->getRoleDescriptor(*(policy.getRole()), samlconstants::SAML20P_NS);
- if (roledesc) annotateException(&ex,roledesc); // throws it
- }
- annotateException(&ex,provider); // throws it
+ else if (dest.get() && (!dest2 || !*dest2 || strcmp(dest.get(),dest2))) {
+ log.error("Redirect targeted at (%s), but delivered to (%s)", dest.get(), dest2 ? dest2 : "none");
+ throw BindingException("SAML message delivered with Redirect to incorrect server URL.");
}
+ // Run through the policy.
+ policy.evaluate(*root, &genericRequest);
+
return xmlObject.release();
}
/** SAML 1.x Metadata Profile QName prefix ("saml1md") */
extern SAML_API const XMLCh SAML1MD_PREFIX[];
+#ifndef SAML10_PROTOCOL_ENUM
/** SAML 1.0 Protocol Enumeration constant ("urn:oasis:names:tc:SAML:1.0:protocol") */
#define SAML10_PROTOCOL_ENUM SAML1P_NS
+#endif
/** SAML 1.1 Protocol Enumeration constant ("urn:oasis:names:tc:SAML:1.1:protocol") */
extern SAML_API const XMLCh SAML11_PROTOCOL_ENUM[];
#include <saml/binding/HTTPResponse.h>\r
#include <saml/binding/MessageDecoder.h>\r
#include <saml/binding/MessageEncoder.h>\r
+#include <saml/binding/SecurityPolicyRule.h>\r
#include <saml/binding/URLEncoder.h>\r
#include <saml/saml2/metadata/Metadata.h>\r
#include <saml/saml2/metadata/MetadataProvider.h>\r
map<string,string> m_headers;\r
string m_method,m_url,m_query;\r
vector<XSECCryptoX509*> m_clientCerts;\r
- vector<const SecurityPolicyRule*> m_rules;\r
+ vector<const SecurityPolicyRule*> m_rules1;\r
+ vector<const SecurityPolicyRule*> m_rules2;\r
\r
public:\r
void setUp() {\r
\r
m_trust = XMLToolingConfig::getConfig().TrustEngineManager.newPlugin(EXPLICIT_KEY_TRUSTENGINE, NULL);\r
\r
- m_rules.push_back(SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(MESSAGEFLOW_POLICY_RULE,NULL));\r
- m_rules.push_back(SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(SIMPLESIGNING_POLICY_RULE,NULL));\r
- m_rules.push_back(SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(XMLSIGNING_POLICY_RULE,NULL));\r
+ m_rules1.push_back(SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(SAML1MESSAGE_POLICY_RULE,NULL));\r
+ m_rules1.push_back(SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(MESSAGEFLOW_POLICY_RULE,NULL));\r
+ m_rules1.push_back(SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(SIMPLESIGNING_POLICY_RULE,NULL));\r
+ m_rules1.push_back(SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(XMLSIGNING_POLICY_RULE,NULL));\r
+\r
+ m_rules2.push_back(SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(SAML2MESSAGE_POLICY_RULE,NULL));\r
+ m_rules2.push_back(SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(MESSAGEFLOW_POLICY_RULE,NULL));\r
+ m_rules2.push_back(SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(SIMPLESIGNING_POLICY_RULE,NULL));\r
+ m_rules2.push_back(SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(XMLSIGNING_POLICY_RULE,NULL));\r
}\r
catch (XMLToolingException& ex) {\r
TS_TRACE(ex.what());\r
}\r
\r
void tearDown() {\r
- for_each(m_rules.begin(), m_rules.end(), xmltooling::cleanup<SecurityPolicyRule>());\r
- m_rules.clear();\r
+ for_each(m_rules1.begin(), m_rules1.end(), xmltooling::cleanup<SecurityPolicyRule>());\r
+ m_rules1.clear();\r
+ for_each(m_rules2.begin(), m_rules2.end(), xmltooling::cleanup<SecurityPolicyRule>());\r
+ m_rules2.clear();\r
delete m_creds;\r
delete m_metadata;\r
delete m_trust;\r
void testSAML1Artifact() {\r
try {\r
QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME);\r
- SecurityPolicy policy(m_rules, m_metadata, &idprole, m_trust);\r
+ SecurityPolicy policy(m_rules1, m_metadata, &idprole, m_trust);\r
\r
// Read message to use from file.\r
string path = data_path + "saml1/binding/SAML1Assertion.xml";\r
TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);\r
\r
// Trigger a replay.\r
+ policy.reset();\r
TSM_ASSERT_THROWS("Did not catch the replay.", decoder->decode(relayState,*this,policy), BindingException);\r
}\r
catch (XMLToolingException& ex) {\r
void testSAML1POST() {
try {
QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME);
- SecurityPolicy policy(m_rules, m_metadata, &idprole, m_trust);
+ SecurityPolicy policy(m_rules1, m_metadata, &idprole, m_trust);
// Read message to use from file.
string path = data_path + "saml1/binding/SAML1Response.xml";
TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);
// Trigger a replay.
+ policy.reset();\r
TSM_ASSERT_THROWS("Did not catch the replay.", decoder->decode(relayState,*this,policy), BindingException);
}
catch (XMLToolingException& ex) {
void testSAML2Artifact() {\r
try {\r
QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME);\r
- SecurityPolicy policy(m_rules, m_metadata, &idprole, m_trust);\r
+ SecurityPolicy policy(m_rules2, m_metadata, &idprole, m_trust);\r
\r
// Read message to use from file.\r
string path = data_path + "saml2/binding/SAML2Response.xml";\r
TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);\r
\r
// Trigger a replay.\r
+ policy.reset();\r
TSM_ASSERT_THROWS("Did not catch the replay.", decoder->decode(relayState,*this,policy), BindingException);\r
}\r
catch (XMLToolingException& ex) {\r
void testSAML2POST() {
try {
QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME);
- SecurityPolicy policy(m_rules, m_metadata, &idprole, m_trust);
+ SecurityPolicy policy(m_rules2, m_metadata, &idprole, m_trust);
// Read message to use from file.
string path = data_path + "saml2/binding/SAML2Response.xml";
TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);
// Trigger a replay.
+ policy.reset();\r
TSM_ASSERT_THROWS("Did not catch the replay.", decoder->decode(relayState,*this,policy), BindingException);
}
catch (XMLToolingException& ex) {
void testSAML2POSTSimpleSign() {
try {
QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME);
- SecurityPolicy policy(m_rules, m_metadata, &idprole, m_trust);
+ SecurityPolicy policy(m_rules2, m_metadata, &idprole, m_trust);
// Read message to use from file.
string path = data_path + "saml2/binding/SAML2Response.xml";
TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);
// Trigger a replay.
+ policy.reset();\r
TSM_ASSERT_THROWS("Did not catch the replay.", decoder->decode(relayState,*this,policy), BindingException);
}
catch (XMLToolingException& ex) {
void testSAML2Redirect() {
try {
QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME);
- SecurityPolicy policy(m_rules, m_metadata, &idprole, m_trust);
+ SecurityPolicy policy(m_rules2, m_metadata, &idprole, m_trust);
// Read message to use from file.
string path = data_path + "saml2/binding/SAML2Response.xml";
TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);
// Trigger a replay.
+ policy.reset();\r
TSM_ASSERT_THROWS("Did not catch the replay.", decoder->decode(relayState,*this,policy), BindingException);
}
catch (XMLToolingException& ex) {