SAML 2 SSO validator.
authorScott Cantor <cantor.2@osu.edu>
Sat, 17 Mar 2007 23:46:20 +0000 (23:46 +0000)
committerScott Cantor <cantor.2@osu.edu>
Sat, 17 Mar 2007 23:46:20 +0000 (23:46 +0000)
saml/Makefile.am
saml/saml.vcproj
saml/saml1/profile/AssertionValidator.h
saml/saml2/profile/AssertionValidator.h
saml/saml2/profile/BrowserSSOProfileValidator.cpp [new file with mode: 0644]
saml/saml2/profile/BrowserSSOProfileValidator.h [new file with mode: 0644]

index 3ad4d76..aed243e 100644 (file)
@@ -96,7 +96,8 @@ saml2mdinclude_HEADERS = \
        saml2/metadata/ObservableMetadataProvider.h
 
 saml2profinclude_HEADERS = \
-       saml2/profile/AssertionValidator.h
+       saml2/profile/AssertionValidator.h \
+       saml2/profile/BrowserSSOProfileValidator.h
 
 noinst_HEADERS = \
        internal.h
@@ -158,6 +159,7 @@ libsaml_la_SOURCES = \
        saml2/binding/impl/SAML2SOAPClient.cpp \
        saml2/binding/impl/SAML2MessageRule.cpp \
        saml2/profile/AssertionValidator.cpp \
+       saml2/profile/BrowserSSOProfileValidator.cpp \
        encryption/EncryptedKeyResolver.cpp \
        signature/ContentReference.cpp \
        signature/SignatureProfileValidator.cpp \
index 200de7a..f601468 100644 (file)
                                                        />\r
                                                </FileConfiguration>\r
                                        </File>\r
+                                       <File\r
+                                               RelativePath=".\saml2\profile\BrowserSSOProfileValidator.cpp"\r
+                                               >\r
+                                               <FileConfiguration\r
+                                                       Name="Debug|Win32"\r
+                                                       >\r
+                                                       <Tool\r
+                                                               Name="VCCLCompilerTool"\r
+                                                               ObjectFile="$(IntDir)\$(InputName)1.obj"\r
+                                                               XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"\r
+                                                       />\r
+                                               </FileConfiguration>\r
+                                               <FileConfiguration\r
+                                                       Name="Release|Win32"\r
+                                                       >\r
+                                                       <Tool\r
+                                                               Name="VCCLCompilerTool"\r
+                                                               ObjectFile="$(IntDir)\$(InputName)1.obj"\r
+                                                               XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"\r
+                                                       />\r
+                                               </FileConfiguration>\r
+                                       </File>\r
                                </Filter>\r
                        </Filter>\r
                        <Filter\r
                                                RelativePath=".\saml2\profile\AssertionValidator.h"\r
                                                >\r
                                        </File>\r
+                                       <File\r
+                                               RelativePath=".\saml2\profile\BrowserSSOProfileValidator.h"\r
+                                               >\r
+                                       </File>\r
                                </Filter>\r
                        </Filter>\r
                        <Filter\r
index 68c29c4..72477ad 100644 (file)
@@ -44,7 +44,8 @@ namespace opensaml {
              * @param audiences set of audience values representing recipient
              * @param ts        timestamp to evaluate assertion conditions, or 0 to bypass check
              */
-            AssertionValidator(const std::vector<const XMLCh*>& audiences, time_t ts=0) : m_ts(ts), m_audiences(audiences) {}
+            AssertionValidator(const std::vector<const XMLCh*>& audiences, time_t ts=0) : m_audiences(audiences), m_ts(ts) {}
+
             virtual ~AssertionValidator() {}
     
             void validate(const xmltooling::XMLObject* xmlObject) const;
@@ -66,9 +67,12 @@ namespace opensaml {
              */
             virtual bool validateCondition(const Condition* condition) const;
 
-        private:
-            time_t m_ts;
+        protected:
+            /** Set of audience values representing recipient. */
             const std::vector<const XMLCh*>& m_audiences;
+
+            /** Timestamp to evaluate assertion conditions. */
+            time_t m_ts;
         };
         
     };
index 0c03284..f1276bd 100644 (file)
@@ -44,7 +44,8 @@ namespace opensaml {
              * @param audiences set of audience values representing recipient
              * @param ts        timestamp to evaluate assertion conditions, or 0 to bypass check
              */
-            AssertionValidator(const std::vector<const XMLCh*>& audiences, time_t ts=0) : m_ts(ts), m_audiences(audiences) {}
+            AssertionValidator(const std::vector<const XMLCh*>& audiences, time_t ts=0) : m_audiences(audiences), m_ts(ts) {}
+
             virtual ~AssertionValidator() {}
     
             void validate(const xmltooling::XMLObject* xmlObject) const;
@@ -59,16 +60,19 @@ namespace opensaml {
             /**
              * Condition validation.
              *
-             * <p>Base class version only understands AudienceRestrictionConditions.
+             * <p>Base class version only understands AudienceRestrictions.
              * 
              * @param condition condition to validate
              * @return true iff condition was understood
              */
             virtual bool validateCondition(const Condition* condition) const;
 
-        private:
-            time_t m_ts;
+        protected:
+            /** Set of audience values representing recipient. */
             const std::vector<const XMLCh*>& m_audiences;
+
+            /** Timestamp to evaluate assertion conditions. */
+            time_t m_ts;
         };
         
     };
diff --git a/saml/saml2/profile/BrowserSSOProfileValidator.cpp b/saml/saml2/profile/BrowserSSOProfileValidator.cpp
new file mode 100644 (file)
index 0000000..ef43724
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *  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.
+ */
+
+/**
+ * BrowserSSOProfileValidator.cpp
+ * 
+ * SAML 2.0 Browser SSO Profile Assertion Validator
+ */
+
+#include "internal.h"
+#include "saml2/core/Assertions.h"
+#include "binding/HTTPRequest.h"
+#include "saml2/profile/BrowserSSOProfileValidator.h"
+
+#include <log4cpp/Category.hh>
+#include <xmltooling/util/NDC.h>
+
+using namespace opensaml::saml2;
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+void BrowserSSOProfileValidator::validateAssertion(const Assertion& assertion) const
+{
+#ifdef _DEBUG
+    xmltooling::NDC ndc("validate");
+#endif
+    Category& log = Category::getInstance(SAML_LOGCAT".AssertionValidator");
+
+    // The assertion MUST have proper confirmation requirements.
+    const Subject* subject = assertion.getSubject();
+    if (subject) {
+        const vector<SubjectConfirmation*>& confs = subject->getSubjectConfirmations();
+        for (vector<SubjectConfirmation*>::const_iterator sc = confs.begin(); sc!=confs.end(); ++sc) {
+            if (XMLString::equals((*sc)->getMethod(), SubjectConfirmation::BEARER)) {
+                const SubjectConfirmationDataType* data = dynamic_cast<const SubjectConfirmationDataType*>((*sc)->getSubjectConfirmationData());
+                
+                if (m_destination) {
+                    if (!XMLString::equals(m_destination, data ? data->getRecipient() : NULL)) {
+                        log.error("bearer confirmation failed with recipient mismatch");
+                        continue;
+                    }
+                }
+
+                if (m_requestID) {
+                    if (!XMLString::equals(m_requestID, data ? data->getInResponseTo() : NULL)) {
+                        log.error("bearer confirmation failed with request correlation mismatch");
+                        continue;
+                    }
+                }
+
+                if (m_ts) {
+                    if (!data || !data->getNotOnOrAfter()) {
+                        log.error("bearer confirmation missing NotOnOrAfter attribute");
+                        continue;
+                    }
+                    else if (data->getNotOnOrAfterEpoch() <= m_ts - XMLToolingConfig::getConfig().clock_skew_secs) {
+                        log.error("bearer confirmation has expired");
+                        continue;
+                    }
+                }
+
+                // Save off client address.
+                if (data) {
+                    auto_ptr_char ip(data->getAddress());
+                    if (ip.get())
+                        m_address = ip.get();
+                }
+
+                // Pass up for additional checking.
+                AssertionValidator::validateAssertion(assertion);
+            }
+        }
+    }
+}
diff --git a/saml/saml2/profile/BrowserSSOProfileValidator.h b/saml/saml2/profile/BrowserSSOProfileValidator.h
new file mode 100644 (file)
index 0000000..1a8a0c3
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ *  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/profile/BrowserSSOProfileValidator.h
+ * 
+ * SAML 2.0 Browser SSO Profile Assertion Validator 
+ */
+
+#ifndef __saml2_ssoval_h__
+#define __saml2_ssoval_h__
+
+#include <saml/saml2/profile/AssertionValidator.h>
+
+namespace opensaml {
+    
+    namespace saml2 {
+        
+        /**
+         * SAML 2.0 Browser SSO Profile Assertion Validator
+         *
+         * <p>In addition to standard core requirements for validity, SSO assertions
+         * <strong>MUST</strong> have NotBefore/NotOnOrAfter attributes and each subject statement
+         * <strong>MUST</strong> be confirmable via bearer method.
+         */
+        class SAML_API BrowserSSOProfileValidator : public AssertionValidator
+        {
+        public:
+            /**
+             * Constructor
+             * 
+             * @param audiences     set of audience values representing recipient
+             * @param ts            timestamp to evaluate assertion conditions, or 0 to bypass check
+             * @param destination   server location to which assertion was delivered, or 0 to bypass check
+             * @param requestID     ID of request that resulted in assertion, or NULL if unsolicited
+             */
+            BrowserSSOProfileValidator(
+                const std::vector<const XMLCh*>& audiences,
+                time_t ts=0,
+                const XMLCh* destination=NULL,
+                const XMLCh* requestID=NULL
+                ) : AssertionValidator(audiences, ts), m_destination(destination), m_requestID(requestID) {
+            }
+            virtual ~BrowserSSOProfileValidator() {}
+    
+            void validateAssertion(const Assertion& assertion) const;
+
+            /**
+             * Return address information from the confirmed bearer SubjectConfirmation, if any.
+             *
+             * @return  address information
+             */
+            const char* getAddress() const {
+                return m_address.c_str();
+            }
+        
+        protected:
+            /** Server location to which assertion was delivered. */
+            const XMLCh* m_destination;
+
+            /** ID of request that resulted in assertions. */
+            const XMLCh* m_requestID;
+
+        private:
+            /** Address in confirmed bearer SubjectConfirmationData. */
+            mutable std::string m_address;
+        };
+        
+    };
+};
+
+#endif /* __saml2_ssoval_h__ */