<pathentry include="C:/cxxtest" kind="inc" path="" system="true"/>\r
<pathentry kind="out" path=""/>\r
<pathentry kind="con" path="org.eclipse.cdt.make.core.DISCOVERED_SCANNER_INFO"/>\r
-<pathentry excluding="util/|saml1/|signature/|saml2/|encryption/|security/|security/impl/|saml1/binding/|saml1/binding/impl/|saml2/binding/|saml2/binding/impl/|binding/|binding/impl/" kind="src" path="saml"/>\r
+<pathentry excluding="util/|saml1/|signature/|saml2/|encryption/|security/|security/impl/|saml1/binding/|saml1/binding/impl/|saml2/binding/|saml2/binding/impl/|binding/|binding/impl/|zlib/" kind="src" path="saml"/>\r
<pathentry excluding="impl/" kind="src" path="saml/binding"/>\r
<pathentry kind="src" path="saml/binding/impl"/>\r
<pathentry excluding="impl/" kind="src" path="saml/saml1/core"/>\r
<pathentry kind="src" path="samltest/security"/>\r
<pathentry kind="src" path="samltest/saml1/binding"/>\r
<pathentry kind="src" path="samltest/saml2/binding"/>\r
+<pathentry kind="src" path="saml/zlib"/>\r
</item>\r
</data>\r
</cdtproject>\r
/opensaml.spec
/pkginfo
/stamp-h1
+/.settings
binding/MessageDecoder.h \
binding/MessageEncoder.h \
binding/MessageFlowRule.h \
- binding/MessageRoutingRule.h \
- binding/MessageSigningRule.h \
binding/SAMLArtifact.h \
binding/SecurityPolicy.h \
binding/SecurityPolicyRule.h \
binding/SimpleSigningRule.h \
- binding/URLEncoder.h
+ binding/URLEncoder.h \
+ binding/XMLSigningRule.h
encinclude_HEADERS = \
encryption/EncryptedKeyResolver.h
binding/impl/MessageDecoder.cpp \
binding/impl/MessageEncoder.cpp \
binding/impl/MessageFlowRule.cpp \
- binding/impl/MessageRoutingRule.cpp \
- binding/impl/MessageSigningRule.cpp \
binding/impl/SAMLArtifact.cpp \
binding/impl/SecurityPolicy.cpp \
binding/impl/SimpleSigningRule.cpp \
binding/impl/URLEncoder.cpp \
+ binding/impl/XMLSigningRule.cpp \
saml1/core/impl/AssertionsImpl.cpp \
saml1/core/impl/AssertionsSchemaValidators.cpp \
saml1/core/impl/ProtocolsImpl.cpp \
+++ /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/binding/MessageRoutingRule.h
- *
- * Routing rule that enforces message delivery to an intended destination
- */
-
-#include <saml/binding/SecurityPolicyRule.h>
-
-
-namespace opensaml {
- /**
- * Routing rule that enforces message delivery to an intended destination
- *
- * Subclasses can provide support for additional message types
- * by overriding the destination derivation method.
- */
- class SAML_API MessageRoutingRule : public SecurityPolicyRule
- {
- public:
- /**
- * Constructor.
- *
- * If an XML attribute named mandatory is set to "true" or "1", then
- * a destination address <strong>MUST</strong> be present in the message.
- *
- * @param e DOM tree to initialize rule
- */
- MessageRoutingRule(const DOMElement* e);
- virtual ~MessageRoutingRule() {}
-
- std::pair<saml2::Issuer*,const saml2md::RoleDescriptor*> evaluate(
- const GenericRequest& request,
- const xmltooling::XMLObject& message,
- const saml2md::MetadataProvider* metadataProvider,
- const xmltooling::QName* role,
- const TrustEngine* trustEngine
- ) const;
-
- /**
- * Controls whether rule insists on presence of destination address in
- * the message.
- *
- * @param mandatory flag value to set
- */
- void setMandatory(bool mandatory) {
- m_mandatory = mandatory;
- }
-
- protected:
- /**
- * Examines the message and/or its contents and extracts the destination
- * address/URL, if specified.
- *
- * @param message message to examine
- * @return the destination address/URL, or NULL
- */
- virtual const XMLCh* getDestination(const xmltooling::XMLObject& message) const;
-
- private:
- bool m_mandatory;
- };
-
-};
/**
* 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
+ */
+ SecurityPolicy(
+ const saml2md::MetadataProvider* metadataProvider=NULL,
+ const xmltooling::QName* role=NULL,
+ const TrustEngine* trustEngine=NULL
+ ) : m_issuer(NULL), m_issuerRole(NULL), m_matchingPolicy(NULL), m_metadata(metadataProvider),
+ m_role(role ? *role : xmltooling::QName()), m_trust(trustEngine) {
+ }
+
+ /**
+ * Constructor for policy using existing rules.
+ *
* @param rules reference to array of policy rules to use
* @param metadataProvider locked MetadataProvider instance
* @param role identifies the role (generally IdP or SP) of the policy peer
const saml2md::MetadataProvider* metadataProvider=NULL,
const xmltooling::QName* role=NULL,
const TrustEngine* trustEngine=NULL
- ) : m_issuer(NULL), m_issuerRole(NULL), m_rules(rules), m_metadata(metadataProvider),
+ ) : m_issuer(NULL), m_issuerRole(NULL), m_matchingPolicy(NULL), m_rules(rules), m_metadata(metadataProvider),
m_role(role ? *role : xmltooling::QName()), m_trust(trustEngine) {
}
+
virtual ~SecurityPolicy();
/**
}
/**
+ * Sets a locked MetadataProvider for the policy.
+ *
+ * @param metadata a locked MetadataProvider or NULL
+ */
+ void setMetadataProvider(const saml2md::MetadataProvider* metadata) {
+ m_metadata = metadata;
+ }
+
+ /**
+ * Sets a peer role element/type for to the policy.
+ *
+ * @param role the peer role element/type or NULL
+ */
+ void setRole(const xmltooling::QName* role) {
+ m_role = (role ? *role : xmltooling::QName());
+ }
+
+ /**
+ * Sets a TrustEngine for the policy.
+ *
+ * @param trust a TrustEngine or NULL
+ */
+ void setTrustEngine(const TrustEngine* trust) {
+ m_trust = trust;
+ }
+
+ /**
* Evaluates the rule against the given request and message,
* possibly populating issuer information in the policy object.
*
* @param issuerRole metadata for the role the issuer is operating in
*/
void setIssuerMetadata(const saml2md::RoleDescriptor* issuerRole);
+
+ /** Allows override of rules for comparing saml2:Issuer information. */
+ class SAML_API IssuerMatchingPolicy {
+ MAKE_NONCOPYABLE(IssuerMatchingPolicy);
+ public:
+ IssuerMatchingPolicy() {}
+ virtual ~IssuerMatchingPolicy() {}
+
+ /**
+ * Returns true iff the two operands "match". Applications can override this method to
+ * support non-standard issuer matching for complex policies.
+ *
+ * <p>The default implementation does a basic comparison of the XML content, treating
+ * an unsupplied Format as an "entityID".
+ *
+ * @param issuer1 the first Issuer to match
+ * @param issuer2 the second Issuer to match
+ * @return true iff the operands match
+ */
+ virtual bool issuerMatches(const saml2::Issuer* issuer1, const saml2::Issuer* issuer2) const;
+ };
- protected:
/**
- * Returns true iff the two operands "match". Applications can override this method to
- * support non-standard issuer matching for complex policies.
+ * Returns the IssuerMatchingPolicy in effect.
*
- * <p>The default implementation does a basic comparison of the XML content, treating
- * an unsupplied Format as "entityID".
+ * @return the effective IssuerMatchingPolicy
+ */
+ const IssuerMatchingPolicy* getIssuerMatchingPolicy() const {
+ return m_matchingPolicy ? m_matchingPolicy : &m_defaultMatching;
+ }
+
+ /**
+ * Sets the IssuerMatchingPolicy in effect. Setting no policy will
+ * cause the simple, default approach to be used.
*
- * @param issuer1 the first Issuer to match
- * @param issuer2 the second Issuer to match
- * @return true iff the operands match
+ * <p>The matching object will be freed by the SecurityPolicy.
+ *
+ * @param matchingPolicy the IssuerMatchingPolicy to use
*/
- virtual bool issuerMatches(const saml2::Issuer* issuer1, const saml2::Issuer* issuer2) const;
+ void getIssuerMatchingPolicy(IssuerMatchingPolicy* matchingPolicy) {
+ delete m_matchingPolicy;
+ m_matchingPolicy = matchingPolicy;
+ }
+
+ protected:
+ /** A shared matching object that just supports the default matching rules. */
+ static IssuerMatchingPolicy m_defaultMatching;
private:
saml2::Issuer* m_issuer;
const saml2md::RoleDescriptor* m_issuerRole;
+ IssuerMatchingPolicy* m_matchingPolicy;
std::vector<const SecurityPolicyRule*> m_rules;
const saml2md::MetadataProvider* m_metadata;
xmltooling::QName m_role;
#define MESSAGEFLOW_POLICY_RULE "org.opensaml.binding.MessageFlowRule"
/**
- * SecurityPolicyRule for ensuring messages are delivered to the right place.
+ * SecurityPolicyRule for protocol message "blob" signing.
*
- * <p>Enforcement is mandatory and the message must be explicitly addressed,
- * unless a "mandatory" XML attribute is set to "0" or "false" when instantiating
- * the policy rule.
+ * Allows the message issuer to be authenticated using a non-XML digital signature
+ * over the message body. The transport layer is not considered.
*/
- #define MESSAGEROUTING_POLICY_RULE "org.opensaml.binding.MessageRoutingRule"
+ #define SIMPLESIGNING_POLICY_RULE "org.opensaml.binding.SimpleSigningRule"
/**
* SecurityPolicyRule for protocol message XML signing.
* Allows the message issuer to be authenticated using an XML digital signature
* over the message. The transport layer is not considered.
*/
- #define MESSAGESIGNING_POLICY_RULE "org.opensaml.binding.MessageSigningRule"
-
- /**
- * SecurityPolicyRule for protocol message "blob" signing.
- *
- * Allows the message issuer to be authenticated using a non-XML digital signature
- * over the message body. The transport layer is not considered.
- */
- #define SIMPLESIGNING_POLICY_RULE "org.opensaml.binding.SimpleSigningRule"
+ #define XMLSIGNING_POLICY_RULE "org.opensaml.binding.XMLSigningRule"
};
#endif /* __saml_secrule_h__ */
*/
/**
- * @file saml/binding/MessageSigningRule.h
+ * @file saml/binding/XMLSigningRule.h
*
* XML Signature checking SecurityPolicyRule
*/
* Subclasses can provide support for additional message types
* by overriding the issuer derivation method.
*/
- class SAML_API MessageSigningRule : public SecurityPolicyRule
+ class SAML_API XMLSigningRule : public SecurityPolicyRule
{
public:
- MessageSigningRule(const DOMElement* e) {}
- virtual ~MessageSigningRule() {}
+ XMLSigningRule(const DOMElement* e) {}
+ virtual ~XMLSigningRule() {}
std::pair<saml2::Issuer*,const saml2md::RoleDescriptor*> evaluate(
const GenericRequest& request,
+++ /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.
- */
-
-/**
- * MessageRoutingRule.cpp
- *
- * XML Signature checking SecurityPolicyRule
- */
-
-#include "internal.h"
-#include "exceptions.h"
-#include "binding/HTTPRequest.h"
-#include "binding/MessageRoutingRule.h"
-#include "saml1/core/Protocols.h"
-#include "saml2/core/Protocols.h"
-
-#include <xmltooling/util/NDC.h>
-#include <xmltooling/util/ReplayCache.h>
-#include <log4cpp/Category.hh>
-
-using namespace opensaml;
-using namespace xmltooling;
-using namespace log4cpp;
-using namespace std;
-
-namespace opensaml {
- SecurityPolicyRule* SAML_DLLLOCAL MessageRoutingRuleFactory(const DOMElement* const & e)
- {
- return new MessageRoutingRule(e);
- }
-};
-
-static const XMLCh mandatory[] = UNICODE_LITERAL_9(m,a,n,d,a,t,o,r,y);
-
-MessageRoutingRule::MessageRoutingRule(const DOMElement* e) : m_mandatory(false)
-{
- if (e) {
- const XMLCh* attr = e->getAttributeNS(NULL, mandatory);
- if (attr && (*attr==chLatin_t || *attr==chDigit_1))
- m_mandatory = true;
- }
-}
-
-pair<saml2::Issuer*,const saml2md::RoleDescriptor*> MessageRoutingRule::evaluate(
- const GenericRequest& request,
- const XMLObject& message,
- const saml2md::MetadataProvider* metadataProvider,
- const QName* role,
- const opensaml::TrustEngine* trustEngine
- ) const
-{
- Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.MessageRouting");
- log.debug("evaluating message routing policy");
-
- try {
- const char* to = dynamic_cast<const HTTPRequest&>(request).getRequestURL();
- if (!to || !*to) {
- if (m_mandatory)
- throw BindingException("Unable to determine delivery location.");
- log.debug("unable to determine delivery location, ignoring message");
- return pair<saml2::Issuer*,const saml2md::RoleDescriptor*>(NULL,NULL);
- }
- auto_ptr_char dest(getDestination(message));
- if (dest.get() && *dest.get()) {
- if (!XMLString::equals(to, dest.get())) {
- log.error("Message intended for (%s), but delivered to (%s)", dest.get(), to);
- throw BindingException("Message delivered to incorrect address.");
- }
- }
- else if (m_mandatory)
- throw BindingException("Message did not contain intended address.");
- }
- catch (bad_cast&) {
- throw BindingException("Message was not of a recognized type.");
- }
- return pair<saml2::Issuer*,const saml2md::RoleDescriptor*>(NULL,NULL);
-}
-
-const XMLCh* MessageRoutingRule::getDestination(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)) {
- const saml2p::StatusResponseType* response = dynamic_cast<const saml2p::StatusResponseType*>(&message);
- if (response)
- return response->getDestination();
- return dynamic_cast<const saml2p::RequestAbstractType&>(message).getDestination();
- }
- else if (XMLString::equals(ns, samlconstants::SAML1P_NS)) {
- // Should be a samlp:Response, at least in OpenSAML.
- return dynamic_cast<const saml1p::Response&>(message).getRecipient();
- }
- }
- return NULL;
-}
namespace opensaml {
SAML_DLLLOCAL PluginManager<SecurityPolicyRule,const DOMElement*>::Factory MessageFlowRuleFactory;
- SAML_DLLLOCAL PluginManager<SecurityPolicyRule,const DOMElement*>::Factory MessageRoutingRuleFactory;
- SAML_DLLLOCAL PluginManager<SecurityPolicyRule,const DOMElement*>::Factory MessageSigningRuleFactory;
SAML_DLLLOCAL PluginManager<SecurityPolicyRule,const DOMElement*>::Factory SimpleSigningRuleFactory;
+ SAML_DLLLOCAL PluginManager<SecurityPolicyRule,const DOMElement*>::Factory XMLSigningRuleFactory;
};
void SAML_API opensaml::registerSecurityPolicyRules()
{
SAMLConfig& conf=SAMLConfig::getConfig();
conf.SecurityPolicyRuleManager.registerFactory(MESSAGEFLOW_POLICY_RULE, MessageFlowRuleFactory);
- conf.SecurityPolicyRuleManager.registerFactory(MESSAGEROUTING_POLICY_RULE, MessageRoutingRuleFactory);
- conf.SecurityPolicyRuleManager.registerFactory(MESSAGESIGNING_POLICY_RULE, MessageSigningRuleFactory);
conf.SecurityPolicyRuleManager.registerFactory(SIMPLESIGNING_POLICY_RULE, SimpleSigningRuleFactory);
+ conf.SecurityPolicyRuleManager.registerFactory(XMLSIGNING_POLICY_RULE, XMLSigningRuleFactory);
}
+SecurityPolicy::IssuerMatchingPolicy SecurityPolicy::m_defaultMatching;
+
SecurityPolicy::~SecurityPolicy()
{
+ delete m_matchingPolicy;
delete m_issuer;
}
// Make sure returned issuer doesn't conflict.
if (ident.first) {
- if (!issuerMatches(ident.first, m_issuer)) {
+ if (!(m_matchingPolicy ? m_matchingPolicy : &m_defaultMatching)->issuerMatches(ident.first, m_issuer)) {
delete ident.first;
throw BindingException("Policy rules returned differing Issuers.");
}
void SecurityPolicy::setIssuer(saml2::Issuer* issuer)
{
- if (!issuerMatches(issuer, m_issuer)) {
+ if (!((m_matchingPolicy ? m_matchingPolicy : &m_defaultMatching))->issuerMatches(issuer, m_issuer)) {
delete issuer;
throw BindingException("Externally provided Issuer conflicts with policy results.");
}
m_issuerRole=issuerRole;
}
-bool SecurityPolicy::issuerMatches(const Issuer* issuer1, const Issuer* issuer2) const
+bool SecurityPolicy::IssuerMatchingPolicy::issuerMatches(const Issuer* issuer1, const Issuer* issuer2) const
{
// NULL matches anything for the purposes of this interface.
if (!issuer1 || !issuer2)
*/
/**
- * MessageSigningRule.cpp
+ * XMLSigningRule.cpp
*
* XML Signature checking SecurityPolicyRule
*/
#include "internal.h"
#include "exceptions.h"
#include "RootObject.h"
-#include "binding/MessageSigningRule.h"
+#include "binding/XMLSigningRule.h"
#include "saml1/core/Assertions.h"
#include "saml1/core/Protocols.h"
#include "saml2/core/Protocols.h"
using namespace std;
namespace opensaml {
- SecurityPolicyRule* SAML_DLLLOCAL MessageSigningRuleFactory(const DOMElement* const & e)
+ SecurityPolicyRule* SAML_DLLLOCAL XMLSigningRuleFactory(const DOMElement* const & e)
{
- return new MessageSigningRule(e);
+ return new XMLSigningRule(e);
}
};
-pair<saml2::Issuer*,const saml2md::RoleDescriptor*> MessageSigningRule::evaluate(
+pair<saml2::Issuer*,const saml2md::RoleDescriptor*> XMLSigningRule::evaluate(
const GenericRequest& request,
const XMLObject& message,
const MetadataProvider* metadataProvider,
const opensaml::TrustEngine* trustEngine
) const
{
- Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.MessageSigning");
+ 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);
return ret;
}
-pair<saml2::Issuer*,const XMLCh*> MessageSigningRule::getIssuerAndProtocol(const XMLObject& message) const
+pair<saml2::Issuer*,const XMLCh*> XMLSigningRule::getIssuerAndProtocol(const XMLObject& message) const
{
// We just let any bad casts throw here.
>\r
</File>\r
<File\r
- RelativePath=".\binding\impl\MessageRoutingRule.cpp"\r
- >\r
- </File>\r
- <File\r
- RelativePath=".\binding\impl\MessageSigningRule.cpp"\r
- >\r
- </File>\r
- <File\r
RelativePath=".\binding\impl\SAMLArtifact.cpp"\r
>\r
</File>\r
RelativePath=".\binding\impl\URLEncoder.cpp"\r
>\r
</File>\r
+ <File\r
+ RelativePath=".\binding\impl\XMLSigningRule.cpp"\r
+ >\r
+ </File>\r
</Filter>\r
</Filter>\r
<Filter\r
>\r
</File>\r
<File\r
- RelativePath=".\binding\MessageRoutingRule.h"\r
- >\r
- </File>\r
- <File\r
- RelativePath=".\binding\MessageSigningRule.h"\r
- >\r
- </File>\r
- <File\r
RelativePath=".\binding\SAMLArtifact.h"\r
>\r
</File>\r
RelativePath=".\binding\URLEncoder.h"\r
>\r
</File>\r
+ <File\r
+ RelativePath=".\binding\XMLSigningRule.h"\r
+ >\r
+ </File>\r
</Filter>\r
<Filter\r
Name="zlib"\r
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(genericRequest, *response);
}
auto_ptr<XMLObject> xmlObject(XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true));
janitor.release();
- saml2::RootObject* root = dynamic_cast<saml2::RootObject*>(xmlObject.get());
- if (!root)
- throw BindingException("XML content for SAML 2.0 HTTP-POST Decoder must be a SAML 2.0 protocol message.");
+ saml2::RootObject* root = NULL;
+ StatusResponseType* response = NULL;
+ RequestAbstractType* request = dynamic_cast<RequestAbstractType*>(xmlObject.get());
+ if (!request) {
+ response = dynamic_cast<StatusResponseType*>(xmlObject.get());
+ if (!response)
+ throw BindingException("XML content for SAML 2.0 HTTP-POST Decoder must be a SAML 2.0 protocol message.");
+ root = static_cast<saml2::RootObject*>(response);
+ }
+ else {
+ 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(genericRequest, *root);
}
const Issuer* claimedIssuer = root->getIssuer();
if (!claimedIssuer) {
// Check for assertions.
- const Response* assbag = dynamic_cast<Response*>(root);
+ const Response* assbag = dynamic_cast<Response*>(response);
if (assbag) {
const vector<Assertion*>& assertions=assbag->getAssertions();
if (!assertions.empty())
auto_ptr<XMLObject> xmlObject(XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true));
janitor.release();
- saml2::RootObject* root = dynamic_cast<saml2::RootObject*>(xmlObject.get());
- if (!root)
- throw BindingException("XML content for SAML 2.0 HTTP-POST Decoder must be a SAML 2.0 protocol message.");
+ saml2::RootObject* root = NULL;
+ StatusResponseType* response = NULL;
+ RequestAbstractType* request = dynamic_cast<RequestAbstractType*>(xmlObject.get());
+ if (!request) {
+ response = dynamic_cast<StatusResponseType*>(xmlObject.get());
+ if (!response)
+ throw BindingException("XML content for SAML 2.0 HTTP-POST Decoder must be a SAML 2.0 protocol message.");
+ root = static_cast<saml2::RootObject*>(response);
+ }
+ else {
+ 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("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(genericRequest, *root);
}
m_trust = SAMLConfig::getConfig().TrustEngineManager.newPlugin(EXPLICIT_KEY_SAMLTRUSTENGINE, NULL);\r
\r
m_rules.push_back(SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(MESSAGEFLOW_POLICY_RULE,NULL));\r
- m_rules.push_back(SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(MESSAGEROUTING_POLICY_RULE,NULL));\r
- m_rules.push_back(SAMLConfig::getConfig().SecurityPolicyRuleManager.newPlugin(MESSAGESIGNING_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
}\r
catch (XMLToolingException& ex) {\r
TS_TRACE(ex.what());\r