Multi-line svn commit, see body.
authorScott Cantor <cantor.2@osu.edu>
Mon, 17 Sep 2007 02:06:13 +0000 (02:06 +0000)
committerScott Cantor <cantor.2@osu.edu>
Mon, 17 Sep 2007 02:06:13 +0000 (02:06 +0000)
Refactor message extraction into decoders and clients.
Remove security checks from SOAP clients.

32 files changed:
saml/Makefile.am
saml/binding/MessageDecoder.h
saml/binding/SecurityPolicy.h
saml/binding/SecurityPolicyRule.h
saml/binding/impl/ClientCertAuthRule.cpp
saml/binding/impl/MessageFlowRule.cpp
saml/binding/impl/NullSecurityRule.cpp
saml/binding/impl/SOAPClient.cpp
saml/binding/impl/SecurityPolicy.cpp
saml/binding/impl/SimpleSigningRule.cpp
saml/binding/impl/XMLSigningRule.cpp
saml/saml.vcproj
saml/saml1/binding/SAML1MessageDecoder.h [new file with mode: 0644]
saml/saml1/binding/impl/SAML1ArtifactDecoder.cpp
saml/saml1/binding/impl/SAML1MessageDecoder.cpp [new file with mode: 0644]
saml/saml1/binding/impl/SAML1MessageRule.cpp [deleted file]
saml/saml1/binding/impl/SAML1POSTDecoder.cpp
saml/saml1/binding/impl/SAML1SOAPClient.cpp
saml/saml1/binding/impl/SAML1SOAPDecoder.cpp
saml/saml2/binding/SAML2MessageDecoder.h [new file with mode: 0644]
saml/saml2/binding/impl/SAML2ArtifactDecoder.cpp
saml/saml2/binding/impl/SAML2MessageDecoder.cpp [moved from saml/saml2/binding/impl/SAML2MessageRule.cpp with 77% similarity]
saml/saml2/binding/impl/SAML2POSTDecoder.cpp
saml/saml2/binding/impl/SAML2RedirectDecoder.cpp
saml/saml2/binding/impl/SAML2SOAPClient.cpp
saml/saml2/binding/impl/SAML2SOAPDecoder.cpp
samltest/binding.h
samltest/saml1/binding/SAML1ArtifactTest.h
samltest/saml1/binding/SAML1POSTTest.h
samltest/saml2/binding/SAML2ArtifactTest.h
samltest/saml2/binding/SAML2POSTTest.h
samltest/saml2/binding/SAML2RedirectTest.h

index cc42f95..5b934a9 100644 (file)
@@ -64,6 +64,7 @@ saml1coreinclude_HEADERS = \
 saml1bindinclude_HEADERS = \
        saml1/binding/SAMLArtifactType0001.h \
        saml1/binding/SAMLArtifactType0002.h \
+       saml1/binding/SAML1MessageDecoder.h \
        saml1/binding/SAML1SOAPClient.h
 
 saml1profinclude_HEADERS = \
@@ -77,6 +78,7 @@ saml2coreinclude_HEADERS = \
 saml2bindinclude_HEADERS = \
        saml2/binding/SAML2Artifact.h \
        saml2/binding/SAML2ArtifactType0004.h \
+       saml2/binding/SAML2MessageDecoder.h \
        saml2/binding/SAML2Redirect.h \
        saml2/binding/SAML2SOAPClient.h
        
@@ -120,12 +122,12 @@ libsaml_la_SOURCES = \
        saml1/binding/impl/SAMLArtifactType0002.cpp \
        saml1/binding/impl/SAML1ArtifactDecoder.cpp \
        saml1/binding/impl/SAML1ArtifactEncoder.cpp \
+       saml1/binding/impl/SAML1MessageDecoder.cpp \
        saml1/binding/impl/SAML1POSTDecoder.cpp \
        saml1/binding/impl/SAML1POSTEncoder.cpp \
        saml1/binding/impl/SAML1SOAPDecoder.cpp \
        saml1/binding/impl/SAML1SOAPEncoder.cpp \
        saml1/binding/impl/SAML1SOAPClient.cpp \
-       saml1/binding/impl/SAML1MessageRule.cpp \
        saml1/profile/AssertionValidator.cpp \
        saml1/profile/BrowserSSOProfileValidator.cpp \
        saml2/core/impl/Assertions.cpp \
@@ -147,6 +149,7 @@ libsaml_la_SOURCES = \
        saml2/binding/impl/SAML2ArtifactType0004.cpp \
        saml2/binding/impl/SAML2ArtifactDecoder.cpp \
        saml2/binding/impl/SAML2ArtifactEncoder.cpp \
+    saml2/binding/impl/SAML2MessageDecoder.cpp \
        saml2/binding/impl/SAML2POSTDecoder.cpp \
        saml2/binding/impl/SAML2POSTEncoder.cpp \
        saml2/binding/impl/SAML2Redirect.cpp \
@@ -155,7 +158,6 @@ libsaml_la_SOURCES = \
        saml2/binding/impl/SAML2SOAPDecoder.cpp \
        saml2/binding/impl/SAML2SOAPEncoder.cpp \
        saml2/binding/impl/SAML2SOAPClient.cpp \
-       saml2/binding/impl/SAML2MessageRule.cpp \
        saml2/profile/Assertion20Validator.cpp \
        saml2/profile/BrowserSSOProfile20Validator.cpp \
        encryption/EncryptedKeyResolver.cpp \
index d3fcc9e..746e8a1 100644 (file)
@@ -152,6 +152,21 @@ namespace opensaml {
 
         /** Pointer to an ArtifactResolver implementation. */
         const ArtifactResolver* m_artifactResolver;
+
+        /**
+         * Extracts policy-relevant message details.
+         * 
+         * @param message   the incoming message
+         * @param request   the protocol request
+         * @param protocol  the protocol family in use
+         * @param policy    SecurityPolicy to provide various components and track message data
+         */
+        virtual void extractMessageDetails (
+            const xmltooling::XMLObject& message,
+            const xmltooling::GenericRequest& genericRequest,
+            const XMLCh* protocol,
+            SecurityPolicy& policy
+            ) const=0;
     };
 
     /**
index 5f75c34..5f696a9 100644 (file)
@@ -75,7 +75,7 @@ namespace opensaml {
             const xmltooling::QName* role=NULL,
             const xmltooling::TrustEngine* trustEngine=NULL,
             bool validate=true
-            ) : m_messageID(NULL), m_issueInstant(0), m_issuer(NULL), m_issuerRole(NULL), m_secure(false),
+            ) : m_messageID(NULL), m_issueInstant(0), m_issuer(NULL), m_issuerRole(NULL), m_authenticated(false),
                 m_matchingPolicy(NULL), m_metadata(metadataProvider), m_role(NULL), m_trust(trustEngine), m_validate(validate) {
             if (role)
                 m_role = new xmltooling::QName(*role);
@@ -175,12 +175,11 @@ namespace opensaml {
          * 
          * @param message           the incoming message
          * @param request           the protocol request
-         * @param protocol          the protocol family in use
          *
          * @throws BindingException raised if the message/request is invalid according to the supplied rules
          */
         void evaluate(
-            const xmltooling::XMLObject& message, const xmltooling::GenericRequest* request=NULL, const XMLCh* protocol=NULL
+            const xmltooling::XMLObject& message, const xmltooling::GenericRequest* request=NULL
             );
 
         /**
@@ -230,12 +229,12 @@ namespace opensaml {
         }
 
         /**
-         * Returns the security status as determined by the registered policies.
+         * Returns the authentication status of the message as determined by the registered policies.
          * 
          * @return true iff a SecurityPolicyRule has indicated the issuer/message has been authenticated 
          */
-        bool isSecure() const {
-            return m_secure;
+        bool isAuthenticated() const {
+            return m_authenticated;
         }
 
         /**
@@ -279,12 +278,12 @@ namespace opensaml {
         void setIssuerMetadata(const saml2md::RoleDescriptor* issuerRole);
 
         /**
-         * Sets the security status as determined by the registered policies.
+         * Sets the authentication status of the message as determined by the registered policies.
          * 
-         * @param secure indicates whether the issuer/message has been authenticated
+         * @param auth indicates whether the issuer/message has been authenticated
          */
-        void setSecure(bool secure) {
-            m_secure = secure;
+        void setAuthenticated(bool auth) {
+            m_authenticated = auth;
         }
         
         /** Allows override of rules for comparing saml2:Issuer information. */
@@ -353,7 +352,7 @@ namespace opensaml {
         time_t m_issueInstant;
         saml2::Issuer* m_issuer;
         const saml2md::RoleDescriptor* m_issuerRole;
-        bool m_secure;
+        bool m_authenticated;
         
         // components governing policy rules
         IssuerMatchingPolicy* m_matchingPolicy;
index 095e115..f8d11e8 100644 (file)
@@ -57,13 +57,11 @@ namespace opensaml {
          * 
          * @param message   the incoming message
          * @param request   the protocol request
-         * @param protocol  the protocol family in use
          * @param policy    SecurityPolicy to provide various components and track message data
          */
         virtual void evaluate(
             const xmltooling::XMLObject& message,
             const xmltooling::GenericRequest* request,
-            const XMLCh* protocol,
             SecurityPolicy& policy
             ) const=0;
     };
@@ -74,20 +72,6 @@ namespace opensaml {
     void SAML_API registerSecurityPolicyRules();
 
     /**
-     * SecurityPolicyRule for processing SAML 1.x messages.
-     * 
-     * Extracts message ID, timestamp, and issuer information.
-     */
-    #define SAML1MESSAGE_POLICY_RULE  "SAML1Message"
-
-    /**
-     * SecurityPolicyRule for processing SAML 2.0 messages.
-     * 
-     * Extracts message ID, timestamp, and issuer information.
-     */
-    #define SAML2MESSAGE_POLICY_RULE  "SAML2Message"
-
-    /**
      * SecurityPolicyRule for TLS client certificate authentication.
      * 
      * Evaluates client certificates against the issuer's metadata.
index f736092..262d2a7 100644 (file)
@@ -47,7 +47,7 @@ namespace opensaml {
         const char* getType() const {
             return CLIENTCERTAUTH_POLICY_RULE;
         }
-        void evaluate(const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy) const;
+        void evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
     };
 
     SecurityPolicyRule* SAML_DLLLOCAL ClientCertAuthRuleFactory(const DOMElement* const & e)
@@ -56,9 +56,7 @@ namespace opensaml {
     }
 };
 
-void ClientCertAuthRule::evaluate(
-    const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy
-    ) const
+void ClientCertAuthRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const
 {
     Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.ClientCertAuth");
     
@@ -92,5 +90,5 @@ void ClientCertAuthRule::evaluate(
     }
     
     log.debug("client certificate verified against message issuer");
-    policy.setSecure(true);
+    policy.setAuthenticated(true);
 }
index a2e1ff6..2d78a4a 100644 (file)
@@ -43,7 +43,7 @@ namespace opensaml {
         const char* getType() const {
             return MESSAGEFLOW_POLICY_RULE;
         }
-        void evaluate(const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy) const;
+        void evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
     
     private:
         bool m_checkReplay;
@@ -72,9 +72,7 @@ MessageFlowRule::MessageFlowRule(const DOMElement* e)
     }
 }
 
-void MessageFlowRule::evaluate(
-    const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy
-    ) const
+void MessageFlowRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const
 {
     Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.MessageFlow");
     log.debug("evaluating message flow policy (replay checking %s, expiration %lu)", m_checkReplay ? "on" : "off", m_expires);
index 7d984ab..74c3fd6 100644 (file)
@@ -40,9 +40,9 @@ namespace opensaml {
         const char* getType() const {
             return NULLSECURITY_POLICY_RULE;
         }
-        void evaluate(const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy) const {
+        void evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const {
             m_log.warn("security enforced using NULL policy rule, be sure you know what you're doing");
-            policy.setSecure(true);
+            policy.setAuthenticated(true);
         }
 
     private:
index 73081ec..e67dbac 100644 (file)
@@ -51,7 +51,14 @@ void SOAPClient::send(const soap11::Envelope& env, const char* from, MetadataCre
     else
         m_policy.setRole(&role);
 
-    auto_ptr_char pn(dynamic_cast<const EntityDescriptor*>(m_peer->getParent())->getEntityID());
+    // Establish the "expected" issuer identity.
+    const XMLCh* entityID = dynamic_cast<const EntityDescriptor*>(m_peer->getParent())->getEntityID();
+    m_policy.setIssuer(entityID);
+    if (!m_policy.getIssuerMetadata())
+        m_policy.setIssuerMetadata(m_peer);
+
+    // Call the base class.
+    auto_ptr_char pn(entityID);
     soap11::SOAPClient::send(env, SOAPTransport::Address(from, pn.get(), endpoint));
 }
 
@@ -76,12 +83,12 @@ soap11::Envelope* SOAPClient::receive()
 {
     auto_ptr<soap11::Envelope> env(soap11::SOAPClient::receive());
     if (env.get()) {
-        if (m_peer && m_transport->isSecure()) {
-            // Set issuer based on peer identity.
-            m_policy.setIssuer(dynamic_cast<EntityDescriptor*>(m_peer->getParent())->getEntityID());
-            m_policy.setIssuerMetadata(m_peer);
-            m_policy.setSecure(true);
+        if (m_peer && m_transport->isAuthenticated()) {
+            // Set flag based on peer identity.
+            m_policy.setAuthenticated(true);
         }
+
+        // Run policy against SOAP layer.
         m_policy.evaluate(*(env.get()));
     }
     return env.release();
index 343687d..2bae01d 100644 (file)
@@ -35,8 +35,6 @@ namespace opensaml {
     SAML_DLLLOCAL PluginManager<SecurityPolicyRule,string,const DOMElement*>::Factory ClientCertAuthRuleFactory;
     SAML_DLLLOCAL PluginManager<SecurityPolicyRule,string,const DOMElement*>::Factory MessageFlowRuleFactory;
     SAML_DLLLOCAL PluginManager<SecurityPolicyRule,string,const DOMElement*>::Factory NullSecurityRuleFactory;
-    SAML_DLLLOCAL PluginManager<SecurityPolicyRule,string,const DOMElement*>::Factory SAML1MessageRuleFactory;
-    SAML_DLLLOCAL PluginManager<SecurityPolicyRule,string,const DOMElement*>::Factory SAML2MessageRuleFactory;
     SAML_DLLLOCAL PluginManager<SecurityPolicyRule,string,const DOMElement*>::Factory SimpleSigningRuleFactory;
     SAML_DLLLOCAL PluginManager<SecurityPolicyRule,string,const DOMElement*>::Factory XMLSigningRuleFactory;
 };
@@ -47,8 +45,6 @@ void SAML_API opensaml::registerSecurityPolicyRules()
     conf.SecurityPolicyRuleManager.registerFactory(CLIENTCERTAUTH_POLICY_RULE, ClientCertAuthRuleFactory);
     conf.SecurityPolicyRuleManager.registerFactory(MESSAGEFLOW_POLICY_RULE, MessageFlowRuleFactory);
     conf.SecurityPolicyRuleManager.registerFactory(NULLSECURITY_POLICY_RULE, NullSecurityRuleFactory);
-    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);
 }
@@ -69,14 +65,14 @@ void SecurityPolicy::reset(bool messageOnly)
         delete m_issuer;
         m_issuer=NULL;
         m_issuerRole=NULL;
-        m_secure=false;
+        m_authenticated=false;
     }
 }
 
-void SecurityPolicy::evaluate(const XMLObject& message, const GenericRequest* request, const XMLCh* protocol)
+void SecurityPolicy::evaluate(const XMLObject& message, const GenericRequest* request)
 {
     for (vector<const SecurityPolicyRule*>::const_iterator i=m_rules.begin(); i!=m_rules.end(); ++i)
-        (*i)->evaluate(message,request,protocol,*this);
+        (*i)->evaluate(message,request,*this);
 }
 
 void SecurityPolicy::setIssuer(const Issuer* issuer)
index 9255cef..bca976d 100644 (file)
@@ -52,7 +52,7 @@ namespace opensaml {
         const char* getType() const {
             return SIMPLESIGNING_POLICY_RULE;
         }
-        void evaluate(const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy) const;
+        void evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
 
     private:
         // Appends a raw parameter=value pair to the string.
@@ -92,9 +92,7 @@ SimpleSigningRule::SimpleSigningRule(const DOMElement* e) : m_errorsFatal(false)
     }
 }
 
-void SimpleSigningRule::evaluate(
-    const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy
-    ) const
+void SimpleSigningRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const
 {
     Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.SimpleSigning");
     
@@ -209,5 +207,5 @@ void SimpleSigningRule::evaluate(
     }
 
     log.debug("signature verified against message issuer");
-    policy.setSecure(true);
+    policy.setAuthenticated(true);
 }
index 9fe67c1..b76e2b6 100644 (file)
@@ -50,7 +50,7 @@ namespace opensaml {
         const char* getType() const {
             return XMLSIGNING_POLICY_RULE;
         }
-        void evaluate(const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy) const;
+        void evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const;
 
     private:
         bool m_errorsFatal;
@@ -72,9 +72,7 @@ XMLSigningRule::XMLSigningRule(const DOMElement* e) : m_errorsFatal(false)
     }
 }
 
-void XMLSigningRule::evaluate(
-    const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy
-    ) const
+void XMLSigningRule::evaluate(const XMLObject& message, const GenericRequest* request, SecurityPolicy& policy) const
 {
     Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.XMLSigning");
     
@@ -116,5 +114,5 @@ void XMLSigningRule::evaluate(
     }
 
     log.debug("signature verified against message issuer");
-    policy.setSecure(true);
+    policy.setAuthenticated(true);
 }
index 72a4a19..d37a29e 100644 (file)
                                                        >\r
                                                </File>\r
                                                <File\r
-                                                       RelativePath=".\saml1\binding\impl\SAML1MessageRule.cpp"\r
+                                                       RelativePath=".\saml1\binding\impl\SAML1MessageDecoder.cpp"\r
                                                        >\r
                                                </File>\r
                                                <File\r
                                                        </FileConfiguration>\r
                                                </File>\r
                                                <File\r
-                                                       RelativePath=".\saml2\binding\impl\SAML2MessageRule.cpp"\r
+                                                       RelativePath=".\saml2\binding\impl\SAML2MessageDecoder.cpp"\r
                                                        >\r
                                                </File>\r
                                                <File\r
                                        Name="binding"\r
                                        >\r
                                        <File\r
+                                               RelativePath=".\saml1\binding\SAML1MessageDecoder.h"\r
+                                               >\r
+                                       </File>\r
+                                       <File\r
                                                RelativePath=".\saml1\binding\SAML1SOAPClient.h"\r
                                                >\r
                                        </File>\r
                                                >\r
                                        </File>\r
                                        <File\r
+                                               RelativePath=".\saml2\binding\SAML2MessageDecoder.h"\r
+                                               >\r
+                                       </File>\r
+                                       <File\r
                                                RelativePath=".\saml2\binding\SAML2Redirect.h"\r
                                                >\r
                                        </File>\r
diff --git a/saml/saml1/binding/SAML1MessageDecoder.h b/saml/saml1/binding/SAML1MessageDecoder.h
new file mode 100644 (file)
index 0000000..d84338c
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *  Copyright 2001-2007 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/SAML1MessageDecoder.h
+ * 
+ * Base class for SAML 1.x MessageDecoders.
+ */
+
+#ifndef __saml1_msgdecoder_h__
+#define __saml1_msgdecoder_h__
+
+#include <saml/binding/MessageDecoder.h>
+
+namespace opensaml {
+
+    namespace saml1p {
+        
+        /**
+         *  Base class for SAML 1.x MessageDecoders.
+         */
+        class SAML_API SAML1MessageDecoder : public MessageDecoder
+        {
+        protected:
+            SAML1MessageDecoder() {}
+            virtual ~SAML1MessageDecoder() {}
+
+        public:
+            void extractMessageDetails (
+                const xmltooling::XMLObject& message,
+                const xmltooling::GenericRequest& genericRequest,
+                const XMLCh* protocol,
+                SecurityPolicy& policy
+                ) const;
+        };
+    };
+};
+
+#endif /* __saml1_msgdecoder_h__ */
index aa5c478..87b6f8c 100644 (file)
@@ -22,8 +22,8 @@
 
 #include "internal.h"
 #include "exceptions.h"
-#include "binding/MessageDecoder.h"
 #include "binding/SAMLArtifact.h"
+#include "saml1/binding/SAML1MessageDecoder.h"
 #include "saml1/core/Protocols.h"
 #include "saml2/metadata/Metadata.h"
 #include "saml2/metadata/MetadataProvider.h"
@@ -42,7 +42,7 @@ using namespace std;
 
 namespace opensaml {
     namespace saml1p {              
-        class SAML_DLLLOCAL SAML1ArtifactDecoder : public MessageDecoder
+        class SAML_DLLLOCAL SAML1ArtifactDecoder : public SAML1MessageDecoder
         {
         public:
             SAML1ArtifactDecoder() {}
@@ -134,12 +134,6 @@ XMLObject* SAML1ArtifactDecoder::decode(
         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)
@@ -149,6 +143,8 @@ XMLObject* SAML1ArtifactDecoder::decode(
         for_each(artifacts.begin(), artifacts.end(), xmltooling::cleanup<SAMLArtifact>());
         throw BindingException("Unable to find compatible metadata role for artifact issuer.");
     }
+    // Set Issuer for the policy.
+    policy.setIssuer(provider->getEntityID());
     policy.setIssuerMetadata(roledesc);
     
     try {
diff --git a/saml/saml1/binding/impl/SAML1MessageDecoder.cpp b/saml/saml1/binding/impl/SAML1MessageDecoder.cpp
new file mode 100644 (file)
index 0000000..7a59796
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ *  Copyright 2001-2007 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.
+ */
+
+/**
+ * SAML1MessageDecoder.cpp
+ * 
+ * Base class for SAML 1.x MessageDecoders.
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "saml1/binding/SAML1MessageDecoder.h"
+#include "saml1/core/Assertions.h"
+#include "saml1/core/Protocols.h"
+#include "saml2/metadata/Metadata.h"
+#include "saml2/metadata/MetadataProvider.h"
+
+#include <xmltooling/logging.h>
+
+using namespace opensaml::saml2md;
+using namespace opensaml::saml1p;
+using namespace opensaml::saml1;
+using namespace opensaml;
+using namespace xmltooling::logging;
+using namespace xmltooling;
+using namespace std;
+
+void SAML1MessageDecoder::extractMessageDetails(
+    const XMLObject& message, const GenericRequest& req, const XMLCh* protocol, SecurityPolicy& policy
+    ) const
+{
+    // Only handle SAML 1.x protocol messages.
+    const QName& q = message.getElementQName();
+    if (!XMLString::equals(q.getNamespaceURI(), samlconstants::SAML1P_NS))
+        return;
+
+    Category& log = Category::getInstance(SAML_LOGCAT".MessageDecoder.SAML1");
+
+    const Request* request=NULL;
+    const Response* response=NULL;
+    if (XMLString::equals(q.getLocalPart(), Request::LOCAL_NAME))
+        request = dynamic_cast<const Request*>(&message);
+    if (!request && XMLString::equals(q.getLocalPart(), Response::LOCAL_NAME))
+        response = dynamic_cast<const Response*>(&message);
+
+    if (!request && !response) {
+        log.warn("decoder cannot extract details from non-SAML 1.x protocol message");
+        return;
+    }
+
+    const RootObject* root = request ? static_cast<const RootObject*>(request) : static_cast<const RootObject*>(response);
+
+    // Extract message details.
+    policy.setMessageID(root->getID());
+    policy.setIssueInstant(root->getIssueInstantEpoch());
+
+    if (request) {
+        log.warn("issuer identity not extracted, only responses with assertions carry issuer information in standard SAML 1.x");
+        return;
+    }
+
+    log.debug("extracting issuer from SAML 1.x Response");
+    const vector<saml1::Assertion*>& assertions = response->getAssertions();
+    if (assertions.empty()) {
+        log.warn("issuer identity not extracted from response (no assertions were present)");
+        return;
+    }
+
+    const XMLCh* issuer = assertions.front()->getIssuer();
+    policy.setIssuer(issuer);
+    if (log.isDebugEnabled()) {
+        auto_ptr_char iname(issuer);
+        log.debug("response from (%s)", iname.get());
+    }
+
+    if (policy.getIssuerMetadata()) {
+        log.debug("metadata for issuer already set, leaving in place");
+        return;
+    }
+
+    if (policy.getMetadataProvider() && policy.getRole()) {
+        log.debug("searching metadata for response issuer...");
+        const EntityDescriptor* entity = policy.getMetadataProvider()->getEntityDescriptor(issuer);
+        if (entity) {
+            log.debug("matched response issuer against metadata, searching for applicable role...");
+            const RoleDescriptor* roledesc=entity->getRoleDescriptor(*policy.getRole(), protocol);
+            if (roledesc)
+                policy.setIssuerMetadata(roledesc);
+            else if (log.isWarnEnabled())
+                log.warn("unable to find compatible role (%s) in metadata", policy.getRole()->toString().c_str());
+        }
+        else if (log.isWarnEnabled()) {
+            auto_ptr_char iname(issuer);
+            log.warn("no metadata found, can't establish identity of issuer (%s)", iname.get());
+        }
+    }
+}
diff --git a/saml/saml1/binding/impl/SAML1MessageRule.cpp b/saml/saml1/binding/impl/SAML1MessageRule.cpp
deleted file mode 100644 (file)
index 309f175..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- *  Copyright 2001-2007 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 "binding/SecurityPolicyRule.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 <xmltooling/logging.h>
-
-using namespace opensaml::saml2md;
-using namespace opensaml::saml1p;
-using namespace opensaml;
-using namespace xmltooling::logging;
-using namespace xmltooling;
-using namespace std;
-
-namespace opensaml {
-
-    class SAML_DLLLOCAL SAML1MessageRule : public SecurityPolicyRule
-    {
-    public:
-        SAML1MessageRule(const DOMElement* e) {}
-        virtual ~SAML1MessageRule() {}
-        
-        const char* getType() const {
-            return SAML1MESSAGE_POLICY_RULE;
-        }
-        void evaluate(const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy) const;
-    };
-
-    SecurityPolicyRule* SAML_DLLLOCAL SAML1MessageRuleFactory(const DOMElement* const & e)
-    {
-        return new SAML1MessageRule(e);
-    }
-};
-
-void SAML1MessageRule::evaluate(
-    const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy
-    ) const
-{
-    // Only handle SAML 1.x messages.
-    const QName& q = message.getElementQName();
-    if (!XMLString::equals(q.getNamespaceURI(), samlconstants::SAML1P_NS) &&
-        !XMLString::equals(q.getNamespaceURI(), samlconstants::SAML1_NS))
-        return;
-    
-    Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.SAML1Message");
-    
-    try {
-        const RootObject& samlRoot = dynamic_cast<const RootObject&>(message);
-        policy.setMessageID(samlRoot.getID());
-        policy.setIssueInstant(samlRoot.getIssueInstantEpoch());
-
-        log.debug("extracting issuer from message");
-
-        const saml1::Assertion* a = NULL;
-
-        // Handle assertions directly.
-        if (XMLString::equals(q.getLocalPart(), saml1::Assertion::LOCAL_NAME))
-            a = dynamic_cast<const saml1::Assertion*>(&samlRoot);
-            
-        // Only samlp:Response is known to carry issuer (via payload) in standard SAML 1.x.
-        if (!a && 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())
-                a = assertions.front();
-        }
-
-        if (a) {
-            policy.setIssuer(a->getIssuer());
-        }
-        else {
-            log.warn("issuer identity not extracted");
-            return;
-        }
-
-        if (log.isDebugEnabled()) {
-            auto_ptr_char iname(a->getIssuer());
-            log.debug("message from (%s)", iname.get());
-        }
-        
-        if (policy.getIssuerMetadata()) {
-            log.debug("metadata for issuer already set, leaving in place");
-            return;
-        }
-        
-        if (policy.getMetadataProvider() && policy.getRole()) {
-            log.debug("searching metadata for message issuer...");
-            const EntityDescriptor* entity = policy.getMetadataProvider()->getEntityDescriptor(a->getIssuer());
-            if (!entity) {
-                auto_ptr_char temp(a->getIssuer());
-                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");
-    }
-}
index a454a6f..92a28b7 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "internal.h"
 #include "exceptions.h"
-#include "binding/MessageDecoder.h"
+#include "saml1/binding/SAML1MessageDecoder.h"
 #include "saml1/core/Assertions.h"
 #include "saml1/core/Protocols.h"
 #include "saml2/metadata/Metadata.h"
@@ -44,7 +44,7 @@ using namespace std;
 
 namespace opensaml {
     namespace saml1p {              
-        class SAML_DLLLOCAL SAML1POSTDecoder : public MessageDecoder
+        class SAML_DLLLOCAL SAML1POSTDecoder : public SAML1MessageDecoder
         {
         public:
             SAML1POSTDecoder() {}
@@ -108,15 +108,18 @@ XMLObject* SAML1POSTDecoder::decode(
         throw BindingException("Decoded message was not a SAML 1.x Response.");
 
     if (!policy.getValidating())
-        SchemaValidators.validate(xmlObject.get());
-
-    // Run through the policy.
+        SchemaValidators.validate(response);
+    
     pair<bool,int> minor = response->getMinorVersion();
-    policy.evaluate(
+    extractMessageDetails(
         *response,
-        &genericRequest,
-        (minor.first && minor.second==0) ? samlconstants::SAML10_PROTOCOL_ENUM : samlconstants::SAML11_PROTOCOL_ENUM
+        genericRequest,
+        (minor.first && minor.second==0) ? samlconstants::SAML10_PROTOCOL_ENUM : samlconstants::SAML11_PROTOCOL_ENUM,
+        policy
         );
+
+    // Run through the policy.
+    policy.evaluate(*response,&genericRequest);
     
     // Check recipient URL.
     auto_ptr_char recipient(response->getRecipient());
index 9a6527b..7f8b319 100644 (file)
@@ -62,20 +62,13 @@ Response* SAML1SOAPClient::receiveSAML()
                     throw SecurityPolicyException("InResponseTo attribute did not correlate with the Request ID.");
                 
                 m_soaper.getPolicy().reset(true);
-                pair<bool,int> minor = response->getMinorVersion();
-                m_soaper.getPolicy().evaluate(
-                    *response,
-                    NULL,
-                    (minor.first && minor.second==0) ? samlconstants::SAML10_PROTOCOL_ENUM : samlconstants::SAML11_PROTOCOL_ENUM
-                    );
-                
-                if (!m_soaper.getPolicy().isSecure()) {
-                    SecurityPolicyException ex("Security policy could not authenticate the message.");
-                    if (m_soaper.getPolicy().getIssuerMetadata())
-                        annotateException(&ex, m_soaper.getPolicy().getIssuerMetadata());   // throws it
-                    else
-                        ex.raise();
-                }
+
+                // Extract Response details and run policy against it.
+                // We don't pull Issuer out of any assertions because some profiles may permit
+                // alternate issuers at that layer.
+                m_soaper.getPolicy().setMessageID(response->getResponseID());
+                m_soaper.getPolicy().setIssueInstant(response->getIssueInstantEpoch());
+                m_soaper.getPolicy().evaluate(*response);
                 
                 // Check Status.
                 Status* status = response->getStatus();
index 4d88e7d..971d700 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "internal.h"
 #include "exceptions.h"
-#include "binding/MessageDecoder.h"
+#include "saml1/binding/SAML1MessageDecoder.h"
 #include "saml1/core/Protocols.h"
 
 #include <xmltooling/logging.h>
@@ -39,7 +39,7 @@ using namespace std;
 
 namespace opensaml {
     namespace saml1p {              
-        class SAML_DLLLOCAL SAML1SOAPDecoder : public MessageDecoder
+        class SAML_DLLLOCAL SAML1SOAPDecoder : public SAML1MessageDecoder
         {
         public:
             SAML1SOAPDecoder() {}
@@ -106,17 +106,23 @@ XMLObject* SAML1SOAPDecoder::decode(
         if (request) {
             // Run through the policy at two layers.
             pair<bool,int> minor = request->getMinorVersion();
-            policy.evaluate(
+            extractMessageDetails(
                 *env,
-                &genericRequest,
-                (minor.first && minor.second==0) ? samlconstants::SAML10_PROTOCOL_ENUM : samlconstants::SAML11_PROTOCOL_ENUM
+                genericRequest,
+                (minor.first && minor.second==0) ? samlconstants::SAML10_PROTOCOL_ENUM : samlconstants::SAML11_PROTOCOL_ENUM,
+                policy
                 );
+            policy.evaluate(*env,&genericRequest);
+
+            // Reset, extract, and run again.
             policy.reset(true);
-            policy.evaluate(
+            extractMessageDetails(
                 *request,
-                &genericRequest,
-                (minor.first && minor.second==0) ? samlconstants::SAML10_PROTOCOL_ENUM : samlconstants::SAML11_PROTOCOL_ENUM
+                genericRequest,
+                (minor.first && minor.second==0) ? samlconstants::SAML10_PROTOCOL_ENUM : samlconstants::SAML11_PROTOCOL_ENUM,
+                policy
                 );
+            policy.evaluate(*request,&genericRequest);
             xmlObject.release();
             body->detach(); // frees Envelope
             request->detach();   // frees Body
diff --git a/saml/saml2/binding/SAML2MessageDecoder.h b/saml/saml2/binding/SAML2MessageDecoder.h
new file mode 100644 (file)
index 0000000..a81cfcb
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *  Copyright 2001-2007 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/SAML2MessageDecoder.h
+ * 
+ * Base class for SAML 2.0 MessageDecoders.
+ */
+
+#ifndef __saml2_msgdecoder_h__
+#define __saml2_msgdecoder_h__
+
+#include <saml/binding/MessageDecoder.h>
+
+namespace opensaml {
+
+    namespace saml2p {
+        
+        /**
+         *  Base class for SAML 2.0 MessageDecoders.
+         */
+        class SAML_API SAML2MessageDecoder : public MessageDecoder
+        {
+        protected:
+            SAML2MessageDecoder() {}
+            virtual ~SAML2MessageDecoder() {}
+
+        public:
+            void extractMessageDetails (
+                const xmltooling::XMLObject& message,
+                const xmltooling::GenericRequest& genericRequest,
+                const XMLCh* protocol,
+                SecurityPolicy& policy
+                ) const;
+        };
+    };
+};
+
+#endif /* __saml2_msgdecoder_h__ */
index ae7545a..1bb7af2 100644 (file)
@@ -22,8 +22,8 @@
 
 #include "internal.h"
 #include "exceptions.h"
-#include "binding/MessageDecoder.h"
 #include "saml2/binding/SAML2Artifact.h"
+#include "saml2/binding/SAML2MessageDecoder.h"
 #include "saml2/core/Protocols.h"
 #include "saml2/metadata/Metadata.h"
 #include "saml2/metadata/MetadataProvider.h"
@@ -43,7 +43,7 @@ using namespace std;
 
 namespace opensaml {
     namespace saml2p {              
-        class SAML_DLLLOCAL SAML2ArtifactDecoder : public MessageDecoder
+        class SAML_DLLLOCAL SAML2ArtifactDecoder : public SAML2MessageDecoder
         {
         public:
             SAML2ArtifactDecoder() {}
@@ -133,18 +133,14 @@ XMLObject* SAML2ArtifactDecoder::decode(
         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());
         throw BindingException("Unable to find compatible metadata role for artifact issuer.");
     }
+    // Set issuer into policy.
+    policy.setIssuer(provider->getEntityID());
     policy.setIssuerMetadata(roledesc);
     
     log.debug("calling ArtifactResolver...");
@@ -156,9 +152,10 @@ XMLObject* SAML2ArtifactDecoder::decode(
     // Reset only the message state.
     policy.reset(true);
 
-    // Extract payload and check that message.
+    // Now extract details from the payload and check that message.
     XMLObject* payload = response->getPayload();
-    policy.evaluate(*payload, &genericRequest, samlconstants::SAML20P_NS);
+    extractMessageDetails(*payload, genericRequest, samlconstants::SAML20P_NS, policy);
+    policy.evaluate(*payload, &genericRequest);
 
     // Return the payload only.
     response.release();
  */
 
 /**
- * SAML2MessageRule.cpp
+ * SAML2MessageDecoder.cpp
  * 
- * SAML 2.0 message extraction rule
+ * Base class for SAML 2.0 MessageDecoders.
  */
 
 #include "internal.h"
 #include "exceptions.h"
-#include "binding/SecurityPolicyRule.h"
+#include "saml2/binding/SAML2MessageDecoder.h"
 #include "saml2/core/Protocols.h"
 #include "saml2/metadata/Metadata.h"
 #include "saml2/metadata/MetadataProvider.h"
@@ -38,43 +38,23 @@ using namespace xmltooling::logging;
 using namespace xmltooling;
 using namespace std;
 
-namespace opensaml {
-    class SAML_DLLLOCAL SAML2MessageRule : public SecurityPolicyRule
-    {
-    public:
-        SAML2MessageRule(const DOMElement* e) {}
-        virtual ~SAML2MessageRule() {}
-        
-        const char* getType() const {
-            return SAML2MESSAGE_POLICY_RULE;
-        }
-        void evaluate(const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy) const;
-    };
-
-    SecurityPolicyRule* SAML_DLLLOCAL SAML2MessageRuleFactory(const DOMElement* const & e)
-    {
-        return new SAML2MessageRule(e);
-    }
-};
-
-void SAML2MessageRule::evaluate(
-    const XMLObject& message, const GenericRequest* request, const XMLCh* protocol, SecurityPolicy& policy
+void SAML2MessageDecoder::extractMessageDetails(
+    const XMLObject& message, const GenericRequest& request, const XMLCh* protocol, SecurityPolicy& policy
     ) const
 {
     // Only handle SAML 2.0 messages.
     const QName& q = message.getElementQName();
-    if (!XMLString::equals(q.getNamespaceURI(), samlconstants::SAML20P_NS)&&
-        !XMLString::equals(q.getNamespaceURI(), samlconstants::SAML20_NS))
+    if (!XMLString::equals(q.getNamespaceURI(), samlconstants::SAML20P_NS))
         return;
 
-    Category& log=Category::getInstance(SAML_LOGCAT".SecurityPolicyRule.SAML2Message");
-    
+    Category& log = Category::getInstance(SAML_LOGCAT".MessageDecoder.SAML2");
+
     try {
         const saml2::RootObject& samlRoot = dynamic_cast<const saml2::RootObject&>(message);
         policy.setMessageID(samlRoot.getID());
         policy.setIssueInstant(samlRoot.getIssueInstantEpoch());
 
-        log.debug("extracting issuer from message");
+        log.debug("extracting issuer from SAML 2.0 protocol message");
         const Issuer* issuer = samlRoot.getIssuer();
         if (issuer) {
             policy.setIssuer(issuer);
@@ -129,6 +109,6 @@ void SAML2MessageRule::evaluate(
     }
     catch (bad_cast&) {
         // Just trap it.
-        log.warn("caught a bad_cast while examining message");
+        log.warn("caught a bad_cast while extracting message details");
     }
 }
index 8595e7e..5438199 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "internal.h"
 #include "exceptions.h"
-#include "binding/MessageDecoder.h"
+#include "saml2/binding/SAML2MessageDecoder.h"
 #include "saml2/core/Protocols.h"
 #include "saml2/metadata/Metadata.h"
 #include "saml2/metadata/MetadataProvider.h"
@@ -43,7 +43,7 @@ using namespace std;
 
 namespace opensaml {
     namespace saml2p {              
-        class SAML_DLLLOCAL SAML2POSTDecoder : public MessageDecoder
+        class SAML_DLLLOCAL SAML2POSTDecoder : public SAML2MessageDecoder
         {
         public:
             SAML2POSTDecoder() {}
@@ -121,10 +121,11 @@ XMLObject* SAML2POSTDecoder::decode(
     }
     
     if (!policy.getValidating())
-        SchemaValidators.validate(xmlObject.get());
+        SchemaValidators.validate(root);
 
     // Run through the policy.
-    policy.evaluate(*root, &genericRequest, samlconstants::SAML20P_NS);
+    extractMessageDetails(*root, genericRequest, samlconstants::SAML20P_NS, policy);
+    policy.evaluate(*root, &genericRequest);
     
     // Check destination URL.
     auto_ptr_char dest(request ? request->getDestination() : response->getDestination());
index a5e599d..b43589c 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "internal.h"
 #include "exceptions.h"
-#include "binding/MessageDecoder.h"
+#include "saml2/binding/SAML2MessageDecoder.h"
 #include "saml2/binding/SAML2Redirect.h"
 #include "saml2/core/Protocols.h"
 #include "saml2/metadata/Metadata.h"
@@ -45,7 +45,7 @@ using namespace std;
 
 namespace opensaml {
     namespace saml2p {              
-        class SAML_DLLLOCAL SAML2RedirectDecoder : public MessageDecoder
+        class SAML_DLLLOCAL SAML2RedirectDecoder : public SAML2MessageDecoder
         {
         public:
             SAML2RedirectDecoder() {}
@@ -135,10 +135,11 @@ XMLObject* SAML2RedirectDecoder::decode(
     }
     
     if (!policy.getValidating())
-        SchemaValidators.validate(xmlObject.get());
+        SchemaValidators.validate(root);
     
     // Run through the policy.
-    policy.evaluate(*root, &genericRequest, samlconstants::SAML20P_NS);
+    extractMessageDetails(*root, genericRequest, samlconstants::SAML20P_NS, policy);
+    policy.evaluate(*root, &genericRequest);
 
     // Check destination URL.
     auto_ptr_char dest(request ? request->getDestination() : response->getDestination());
index 626b607..7c94c5d 100644 (file)
 #include "saml2/binding/SAML2SOAPClient.h"
 #include "saml2/core/Protocols.h"
 #include "saml2/metadata/Metadata.h"
+#include "saml2/metadata/MetadataProvider.h"
 
 #include <xmltooling/logging.h>
 #include <xmltooling/soap/SOAP.h>
 
+using namespace opensaml::saml2;
 using namespace opensaml::saml2p;
 using namespace opensaml::saml2md;
 using namespace opensaml;
@@ -56,17 +58,24 @@ StatusResponseType* SAML2SOAPClient::receiveSAML()
             // Check for SAML Response.
             StatusResponseType* response = dynamic_cast<StatusResponseType*>(body->getUnknownXMLObjects().front());
             if (response) {
-                
                 // Check InResponseTo.
                 if (m_correlate && response->getInResponseTo() && !XMLString::equals(m_correlate, response->getInResponseTo()))
                     throw SecurityPolicyException("InResponseTo attribute did not correlate with the Request ID.");
 
-                m_soaper.getPolicy().reset(true);
-                m_soaper.getPolicy().evaluate(*response, NULL, samlconstants::SAML20P_NS);
-                if (!m_soaper.getPolicy().isSecure()) {
-                    SecurityPolicyException ex("Security policy could not authenticate the message.");
-                    annotateException(&ex, m_soaper.getPolicy().getIssuerMetadata(), response->getStatus());   // throws it
-                }
+                SecurityPolicy& policy = m_soaper.getPolicy();
+                policy.reset(true);
+
+                // Extract Response details.
+                policy.setMessageID(response->getID());
+                policy.setIssueInstant(response->getIssueInstantEpoch());
+
+                // Extract and re-verify Issuer if present.
+                const Issuer* issuer = response->getIssuer();
+                if (issuer)
+                    policy.setIssuer(issuer);   // This will throw if it conflicts with the known peer identity.
+
+                // Now run the policy.
+                policy.evaluate(*response);
 
                 // Check Status.
                 Status* status = response->getStatus();
@@ -74,7 +83,7 @@ StatusResponseType* SAML2SOAPClient::receiveSAML()
                     const XMLCh* code = status->getStatusCode() ? status->getStatusCode()->getValue() : NULL;
                     if (code && !XMLString::equals(code,StatusCode::SUCCESS) && handleError(*status)) {
                         BindingException ex("SAML response contained an error.");
-                        annotateException(&ex, m_soaper.getPolicy().getIssuerMetadata(), status);   // throws it
+                        annotateException(&ex, policy.getIssuerMetadata(), status);   // throws it
                     }
                 }
                 
index 8879499..8325d33 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "internal.h"
 #include "exceptions.h"
-#include "binding/MessageDecoder.h"
+#include "saml2/binding/SAML2MessageDecoder.h"
 #include "saml2/core/Protocols.h"
 
 #include <xmltooling/logging.h>
@@ -39,7 +39,7 @@ using namespace std;
 
 namespace opensaml {
     namespace saml2p {              
-        class SAML_DLLLOCAL SAML2SOAPDecoder : public MessageDecoder
+        class SAML_DLLLOCAL SAML2SOAPDecoder : public SAML2MessageDecoder
         {
         public:
             SAML2SOAPDecoder() {}
@@ -105,9 +105,11 @@ XMLObject* SAML2SOAPDecoder::decode(
         RequestAbstractType* request = dynamic_cast<RequestAbstractType*>(body->getUnknownXMLObjects().front());
         if (request) {
             // Run through the policy at two layers.
-            policy.evaluate(*env, &genericRequest, samlconstants::SAML20P_NS);
+            extractMessageDetails(*env, genericRequest, samlconstants::SAML20P_NS, policy);
+            policy.evaluate(*env, &genericRequest);
             policy.reset(true);
-            policy.evaluate(*request, &genericRequest, samlconstants::SAML20P_NS);
+            extractMessageDetails(*request, genericRequest, samlconstants::SAML20P_NS, policy);
+            policy.evaluate(*request, &genericRequest);
             xmlObject.release();
             body->detach(); // frees Envelope
             request->detach();   // frees Body
index cdaa3bc..3564bb1 100644 (file)
@@ -41,8 +41,7 @@ protected:
     map<string,string> m_headers;\r
     string m_method,m_url,m_query;\r
     vector<XSECCryptoX509*> m_clientCerts;\r
-    vector<const SecurityPolicyRule*> m_rules1;\r
-    vector<const SecurityPolicyRule*> m_rules2;\r
+    vector<const SecurityPolicyRule*> m_rules;\r
 \r
 public:\r
     void setUp() {\r
@@ -81,15 +80,9 @@ public:
                 \r
             m_trust = XMLToolingConfig::getConfig().TrustEngineManager.newPlugin(EXPLICIT_KEY_TRUSTENGINE, NULL);\r
 \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
+            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
         }\r
         catch (XMLToolingException& ex) {\r
             TS_TRACE(ex.what());\r
@@ -100,10 +93,8 @@ public:
     }\r
     \r
     void tearDown() {\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
+        for_each(m_rules.begin(), m_rules.end(), xmltooling::cleanup<SecurityPolicyRule>());\r
+        m_rules.clear();\r
         delete m_creds;\r
         delete m_metadata;\r
         delete m_trust;\r
index 5f2dfca..ae593b1 100644 (file)
@@ -40,7 +40,7 @@ public:
         try {\r
             QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME);\r
             SecurityPolicy policy(m_metadata, &idprole, m_trust, false);\r
-            policy.getRules().assign(m_rules1.begin(), m_rules1.end());\r
+            policy.getRules().assign(m_rules.begin(), m_rules.end());\r
 \r
             // Read message to use from file.\r
             string path = data_path + "saml1/binding/SAML1Assertion.xml";\r
@@ -83,7 +83,7 @@ public:
             // Test the results.\r
             TSM_ASSERT_EQUALS("TARGET was not the expected result.", relayState, "state");\r
             TSM_ASSERT("SAML Response not decoded successfully.", response.get());\r
-            TSM_ASSERT("Message was not verified.", policy.isSecure());\r
+            TSM_ASSERT("Message was not verified.", policy.isAuthenticated());\r
             auto_ptr_char entityID(policy.getIssuer()->getName());\r
             TSM_ASSERT("Issuer was not expected.", !strcmp(entityID.get(),"https://idp.example.org/"));\r
             TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);\r
@@ -132,7 +132,7 @@ public:
         TSM_ASSERT("Retrieved credential was null", cred!=NULL);\r
         response->marshall((DOMDocument*)NULL,&sigs,cred);\r
         SchemaValidators.validate(response.get());\r
-        policy.evaluate(*(response.get()), this, samlconstants::SAML11_PROTOCOL_ENUM);\r
+        policy.evaluate(*(response.get()), this);\r
         return response.release();\r
     }\r
 \r
index 9750b3d..2621fa2 100644 (file)
@@ -35,7 +35,7 @@ public:
         try {
             QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME);
             SecurityPolicy policy(m_metadata, &idprole, m_trust, false);
-            policy.getRules().assign(m_rules1.begin(), m_rules1.end());
+            policy.getRules().assign(m_rules.begin(), m_rules.end());
 
             // Read message to use from file.
             string path = data_path + "saml1/binding/SAML1Response.xml";
@@ -90,7 +90,7 @@ public:
             // Test the results.
             TSM_ASSERT_EQUALS("TARGET was not the expected result.", relayState, "state");
             TSM_ASSERT("SAML Response not decoded successfully.", response.get());
-            TSM_ASSERT("Message was not verified.", policy.isSecure());
+            TSM_ASSERT("Message was not verified.", policy.isAuthenticated());
             auto_ptr_char entityID(policy.getIssuer()->getName());
             TSM_ASSERT("Issuer was not expected.", !strcmp(entityID.get(),"https://idp.example.org/"));
             TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);
index 329af90..46c33b0 100644 (file)
@@ -39,7 +39,7 @@ public:
         try {
             QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME);
             SecurityPolicy policy(m_metadata, &idprole, m_trust, false);
-            policy.getRules().assign(m_rules2.begin(), m_rules2.end());
+            policy.getRules().assign(m_rules.begin(), m_rules.end());
 
             // Read message to use from file.
             string path = data_path + "saml2/binding/SAML2Response.xml";
@@ -85,7 +85,7 @@ public:
             // Test the results.
             TSM_ASSERT_EQUALS("RelayState was not the expected result.", relayState, "state");
             TSM_ASSERT("SAML Response not decoded successfully.", response.get());
-            TSM_ASSERT("Message was not verified.", policy.isSecure());
+            TSM_ASSERT("Message was not verified.", policy.isAuthenticated());
             auto_ptr_char entityID(policy.getIssuer()->getName());
             TSM_ASSERT("Issuer was not expected.", !strcmp(entityID.get(),"https://idp.example.org/"));
             TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);
@@ -135,7 +135,7 @@ public:
         sc->setValue(StatusCode::SUCCESS);
         response->marshall();
         SchemaValidators.validate(response.get());
-        policy.evaluate(*(response.get()), this, samlconstants::SAML20P_NS);
+        policy.evaluate(*(response.get()), this);
         return response.release();
     }
 };
index bbdd504..1b4a05f 100644 (file)
@@ -35,7 +35,7 @@ public:
         try {
             QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME);
             SecurityPolicy policy(m_metadata, &idprole, m_trust, false);
-            policy.getRules().assign(m_rules2.begin(), m_rules2.end());
+            policy.getRules().assign(m_rules.begin(), m_rules.end());
 
             // Read message to use from file.
             string path = data_path + "saml2/binding/SAML2Response.xml";
@@ -89,7 +89,7 @@ public:
             // Test the results.
             TSM_ASSERT_EQUALS("RelayState was not the expected result.", relayState, "state");
             TSM_ASSERT("SAML Response not decoded successfully.", response.get());
-            TSM_ASSERT("Message was not verified.", policy.isSecure());
+            TSM_ASSERT("Message was not verified.", policy.isAuthenticated());
             auto_ptr_char entityID(policy.getIssuer()->getName());
             TSM_ASSERT("Issuer was not expected.", !strcmp(entityID.get(),"https://idp.example.org/"));
             TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);
@@ -108,7 +108,7 @@ public:
         try {
             QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME);
             SecurityPolicy policy(m_metadata, &idprole, m_trust, false);
-            policy.getRules().assign(m_rules2.begin(), m_rules2.end());
+            policy.getRules().assign(m_rules.begin(), m_rules.end());
 
             // Read message to use from file.
             string path = data_path + "saml2/binding/SAML2Response.xml";
@@ -162,7 +162,7 @@ public:
             // Test the results.
             TSM_ASSERT_EQUALS("RelayState was not the expected result.", relayState, "state");
             TSM_ASSERT("SAML Response not decoded successfully.", response.get());
-            TSM_ASSERT("Message was not verified.", policy.isSecure());
+            TSM_ASSERT("Message was not verified.", policy.isAuthenticated());
             auto_ptr_char entityID(policy.getIssuer()->getName());
             TSM_ASSERT("Issuer was not expected.", !strcmp(entityID.get(),"https://idp.example.org/"));
             TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);
index 80dce5f..8a78a0e 100644 (file)
@@ -35,7 +35,7 @@ public:
         try {
             QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME);
             SecurityPolicy policy(m_metadata, &idprole, m_trust, false);
-            policy.getRules().assign(m_rules2.begin(), m_rules2.end());
+            policy.getRules().assign(m_rules.begin(), m_rules.end());
 
             // Read message to use from file.
             string path = data_path + "saml2/binding/SAML2Response.xml";
@@ -81,7 +81,7 @@ public:
             // Test the results.
             TSM_ASSERT_EQUALS("RelayState was not the expected result.", relayState, "state");
             TSM_ASSERT("SAML Response not decoded successfully.", response.get());
-            TSM_ASSERT("Message was not verified.", policy.isSecure());
+            TSM_ASSERT("Message was not verified.", policy.isAuthenticated());
             auto_ptr_char entityID(policy.getIssuer()->getName());
             TSM_ASSERT("Issuer was not expected.", !strcmp(entityID.get(),"https://idp.example.org/"));
             TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);