Add Destination check.
authorcantor <cantor@fb386ef7-a10c-0410-8ebf-fd3f8e989ab0>
Wed, 7 Nov 2007 17:49:39 +0000 (17:49 +0000)
committercantor <cantor@fb386ef7-a10c-0410-8ebf-fd3f8e989ab0>
Wed, 7 Nov 2007 17:49:39 +0000 (17:49 +0000)
git-svn-id: https://svn.middleware.georgetown.edu/cpp-opensaml2/trunk@335 fb386ef7-a10c-0410-8ebf-fd3f8e989ab0

saml/saml2/binding/impl/SAML2ECPDecoder.cpp

index 9d4e2fd..bc6187b 100644 (file)
@@ -26,6 +26,7 @@
 #include "saml2/core/Protocols.h"
 
 #include <xmltooling/logging.h>
+#include <xmltooling/io/HTTPRequest.h>
 #include <xmltooling/soap/SOAP.h>
 #include <xmltooling/util/NDC.h>
 #include <xmltooling/validation/ValidatorSuite.h>
@@ -71,6 +72,9 @@ XMLObject* SAML2ECPDecoder::decode(
     Category& log = Category::getInstance(SAML_LOGCAT".MessageDecoder.SAML2ECP");
 
     log.debug("validating input");
+    const HTTPRequest* httpRequest=dynamic_cast<const HTTPRequest*>(&genericRequest);
+    if (!httpRequest)
+        throw BindingException("Unable to cast request object to HTTPRequest type.");
     string s = genericRequest.getContentType();
     if (s.find("application/vnd.paos+xml") == string::npos) {
         log.warn("ignoring incorrect content type (%s)", s.c_str() ? s.c_str() : "none");
@@ -106,7 +110,20 @@ XMLObject* SAML2ECPDecoder::decode(
             policy.reset(true);
             extractMessageDetails(*response, genericRequest, samlconstants::SAML20P_NS, policy);
             policy.evaluate(*response, &genericRequest);
-            
+
+            // Check destination URL.
+            auto_ptr_char dest(response->getDestination());
+            const char* dest2 = httpRequest->getRequestURL();
+            const char* delim = strchr(dest2, '?');
+            if (response->getSignature() && (!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() && *dest.get() && ((delim && strncmp(dest.get(), dest2, delim - dest2)) || (!delim && strcmp(dest.get(),dest2)))) {
+                log.error("PAOS response targeted at (%s), but delivered to (%s)", dest.get(), dest2);
+                throw BindingException("SAML message delivered with PAOS to incorrect server URL.");
+            }
+
             // Check for RelayState header.
             if (env->getHeader()) {
                 const vector<XMLObject*>& blocks = const_cast<const Header*>(env->getHeader())->getUnknownXMLObjects();