SOAP decoders.
authorScott Cantor <cantor.2@osu.edu>
Sun, 12 Nov 2006 00:07:53 +0000 (00:07 +0000)
committerScott Cantor <cantor.2@osu.edu>
Sun, 12 Nov 2006 00:07:53 +0000 (00:07 +0000)
saml/Makefile.am
saml/saml.vcproj
saml/saml1/binding/SAML1SOAPDecoder.h [new file with mode: 0644]
saml/saml1/binding/impl/SAML1SOAPDecoder.cpp [new file with mode: 0644]
saml/saml2/binding/SAML2SOAPDecoder.h [new file with mode: 0644]
saml/saml2/binding/impl/SAML2SOAPDecoder.cpp [new file with mode: 0644]
saml/util/SAMLConstants.cpp
saml/util/SAMLConstants.h

index f03cc16..70fe4a7 100644 (file)
@@ -76,7 +76,8 @@ saml1bindinclude_HEADERS = \
        saml1/binding/SAML1ArtifactDecoder.h \
        saml1/binding/SAML1ArtifactEncoder.h \
        saml1/binding/SAML1POSTDecoder.h \
-       saml1/binding/SAML1POSTEncoder.h
+       saml1/binding/SAML1POSTEncoder.h \
+       saml1/binding/SAML1SOAPDecoder.h
 
 saml2coreinclude_HEADERS = \
        saml2/core/Assertions.h \
@@ -91,7 +92,8 @@ saml2bindinclude_HEADERS = \
        saml2/binding/SAML2POSTEncoder.h \
        saml2/binding/SAML2Redirect.h \
        saml2/binding/SAML2RedirectDecoder.h \
-       saml2/binding/SAML2RedirectEncoder.h
+       saml2/binding/SAML2RedirectEncoder.h \
+       saml2/binding/SAML2SOAPDecoder.h
 
 saml2mdinclude_HEADERS = \
        saml2/metadata/AbstractMetadataProvider.h \
@@ -126,6 +128,7 @@ libsaml_la_SOURCES = \
        saml1/binding/impl/SAML1ArtifactEncoder.cpp \
        saml1/binding/impl/SAML1POSTDecoder.cpp \
        saml1/binding/impl/SAML1POSTEncoder.cpp \
+       saml1/binding/impl/SAML1SOAPDecoder.cpp \
        saml2/core/impl/Assertions20Impl.cpp \
        saml2/core/impl/Assertions20SchemaValidators.cpp \
        saml2/core/impl/Protocols20Impl.cpp \
@@ -149,6 +152,7 @@ libsaml_la_SOURCES = \
        saml2/binding/impl/SAML2Redirect.cpp \
        saml2/binding/impl/SAML2RedirectDecoder.cpp \
        saml2/binding/impl/SAML2RedirectEncoder.cpp \
+       saml2/binding/impl/SAML2SOAPDecoder.cpp \
        encryption/EncryptedKeyResolver.cpp \
        security/impl/TrustEngine.cpp \
        security/impl/AbstractPKIXTrustEngine.cpp \
index 2a461bf..f8190eb 100644 (file)
                                                        >\r
                                                </File>\r
                                                <File\r
+                                                       RelativePath=".\saml1\binding\impl\SAML1SOAPDecoder.cpp"\r
+                                                       >\r
+                                               </File>\r
+                                               <File\r
                                                        RelativePath=".\saml1\binding\impl\SAMLArtifactType0001.cpp"\r
                                                        >\r
                                                </File>\r
                                                        RelativePath=".\saml2\binding\impl\SAML2RedirectEncoder.cpp"\r
                                                        >\r
                                                </File>\r
+                                               <File\r
+                                                       RelativePath=".\saml2\binding\impl\SAML2SOAPDecoder.cpp"\r
+                                                       >\r
+                                               </File>\r
                                        </Filter>\r
                                </Filter>\r
                        </Filter>\r
                                                >\r
                                        </File>\r
                                        <File\r
+                                               RelativePath=".\saml1\binding\SAML1SOAPDecoder.h"\r
+                                               >\r
+                                       </File>\r
+                                       <File\r
                                                RelativePath=".\saml1\binding\SAMLArtifactType0001.h"\r
                                                >\r
                                        </File>\r
                                                RelativePath=".\saml2\binding\SAML2RedirectEncoder.h"\r
                                                >\r
                                        </File>\r
+                                       <File\r
+                                               RelativePath=".\saml2\binding\SAML2SOAPDecoder.h"\r
+                                               >\r
+                                       </File>\r
                                </Filter>\r
                        </Filter>\r
                        <Filter\r
diff --git a/saml/saml1/binding/SAML1SOAPDecoder.h b/saml/saml1/binding/SAML1SOAPDecoder.h
new file mode 100644 (file)
index 0000000..152da25
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  Copyright 2001-2006 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file saml/saml1/binding/SAML1SOAPDecoder.h
+ * 
+ * SAML 1.x SOAP binding message decoder
+ */
+
+#include <saml/binding/MessageDecoder.h>
+#include <saml/saml1/core/Protocols.h>
+
+
+namespace opensaml {
+    namespace saml1p {
+
+        /**
+         * SAML 1.x SOAP binding message decoder
+         */
+        class SAML_API SAML1SOAPDecoder : public MessageDecoder
+        {
+        public:
+            SAML1SOAPDecoder(const DOMElement* e);
+            virtual ~SAML1SOAPDecoder() {}
+            
+            Request* decode(
+                std::string& relayState,
+                const GenericRequest& genericRequest,
+                SecurityPolicy& policy
+                ) const;
+        };                
+
+    };
+};
diff --git a/saml/saml1/binding/impl/SAML1SOAPDecoder.cpp b/saml/saml1/binding/impl/SAML1SOAPDecoder.cpp
new file mode 100644 (file)
index 0000000..6df390b
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ *  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.
+ */
+
+/**
+ * SAML1SOAPDecoder.cpp
+ * 
+ * SAML 1.x SOAP binding message decoder
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "saml1/binding/SAML1SOAPDecoder.h"
+
+#include <log4cpp/Category.hh>
+#include <xmltooling/soap/SOAP.h>
+#include <xmltooling/util/NDC.h>
+#include <xmltooling/validation/ValidatorSuite.h>
+
+using namespace opensaml::saml1p;
+using namespace opensaml;
+using namespace soap11;
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+namespace opensaml {
+    namespace saml1p {              
+        MessageDecoder* SAML_DLLLOCAL SAML1SOAPDecoderFactory(const DOMElement* const & e)
+        {
+            return new SAML1SOAPDecoder(e);
+        }
+    };
+};
+
+SAML1SOAPDecoder::SAML1SOAPDecoder(const DOMElement* e) {}
+
+Request* SAML1SOAPDecoder::decode(
+    string& relayState,
+    const GenericRequest& genericRequest,
+    SecurityPolicy& policy
+    ) const
+{
+#ifdef _DEBUG
+    xmltooling::NDC ndc("decode");
+#endif
+    Category& log = Category::getInstance(SAML_LOGCAT".MessageDecoder.SAML1SOAP");
+
+    log.debug("validating input");
+    string s = genericRequest.getContentType();
+    if (s != "text/xml") {
+        log.warn("ignoring incorrect Content Type (%s)", s.c_str() ? s.c_str() : "none");
+        return NULL;
+    }
+
+    const char* data = genericRequest.getRequestBody();
+    if (!data) {
+        log.warn("empty request body");
+        return NULL;
+    }
+    istringstream is(data);
+    
+    // Parse and bind the document into an XMLObject.
+    DOMDocument* doc = (m_validate ? XMLToolingConfig::getConfig().getValidatingParser()
+        : XMLToolingConfig::getConfig().getParser()).parse(is); 
+    XercesJanitor<DOMDocument> janitor(doc);
+    auto_ptr<XMLObject> xmlObject(XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true));
+    janitor.release();
+
+    Envelope* env = dynamic_cast<Envelope*>(xmlObject.get());
+    if (!env)
+        throw BindingException("Decoded message was not a SOAP 1.1 Envelope.");
+
+    if (!m_validate)
+        SchemaValidators.validate(env);
+    
+    Body* body = env->getBody();
+    if (body && body->hasChildren()) {
+        Request* request = dynamic_cast<Request*>(body->getXMLObjects().front());
+        if (request) {
+            // Run through the policy at two layers.
+            policy.evaluate(genericRequest, *env);
+            policy.evaluate(genericRequest, *request);
+            xmlObject.release();
+            body->detach(); // frees Envelope
+            request->detach();   // frees Body
+            return request;
+        }
+    }
+    
+    throw BindingException("SOAP Envelope did not contain a SAML Request.");
+}
diff --git a/saml/saml2/binding/SAML2SOAPDecoder.h b/saml/saml2/binding/SAML2SOAPDecoder.h
new file mode 100644 (file)
index 0000000..5043852
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  Copyright 2001-2006 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file saml/saml2/binding/SAML2SOAPDecoder.h
+ * 
+ * SAML 2.0 SOAP binding message decoder
+ */
+
+#include <saml/binding/MessageDecoder.h>
+#include <saml/saml2/core/Protocols.h>
+
+
+namespace opensaml {
+    namespace saml2p {
+
+        /**
+         * SAML 2.0 SOAP binding message decoder
+         */
+        class SAML_API SAML2SOAPDecoder : public MessageDecoder
+        {
+        public:
+            SAML2SOAPDecoder(const DOMElement* e);
+            virtual ~SAML2SOAPDecoder() {}
+            
+            RequestAbstractType* decode(
+                std::string& relayState,
+                const GenericRequest& genericRequest,
+                SecurityPolicy& policy
+                ) const;
+        };                
+
+    };
+};
diff --git a/saml/saml2/binding/impl/SAML2SOAPDecoder.cpp b/saml/saml2/binding/impl/SAML2SOAPDecoder.cpp
new file mode 100644 (file)
index 0000000..3a100a6
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ *  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.
+ */
+
+/**
+ * SAML2SOAPDecoder.cpp
+ * 
+ * SAML 2.0 SOAP binding message decoder
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "saml2/binding/SAML2SOAPDecoder.h"
+
+#include <log4cpp/Category.hh>
+#include <xmltooling/soap/SOAP.h>
+#include <xmltooling/util/NDC.h>
+#include <xmltooling/validation/ValidatorSuite.h>
+
+using namespace opensaml::saml2p;
+using namespace opensaml;
+using namespace soap11;
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+namespace opensaml {
+    namespace saml2p {              
+        MessageDecoder* SAML_DLLLOCAL SAML2SOAPDecoderFactory(const DOMElement* const & e)
+        {
+            return new SAML2SOAPDecoder(e);
+        }
+    };
+};
+
+SAML2SOAPDecoder::SAML2SOAPDecoder(const DOMElement* e) {}
+
+RequestAbstractType* SAML2SOAPDecoder::decode(
+    string& relayState,
+    const GenericRequest& genericRequest,
+    SecurityPolicy& policy
+    ) const
+{
+#ifdef _DEBUG
+    xmltooling::NDC ndc("decode");
+#endif
+    Category& log = Category::getInstance(SAML_LOGCAT".MessageDecoder.SAML2SOAP");
+
+    log.debug("validating input");
+    string s = genericRequest.getContentType();
+    if (s != "text/xml") {
+        log.warn("ignoring incorrect Content Type (%s)", s.c_str() ? s.c_str() : "none");
+        return NULL;
+    }
+
+    const char* data = genericRequest.getRequestBody();
+    if (!data) {
+        log.warn("empty request body");
+        return NULL;
+    }
+    istringstream is(data);
+    
+    // Parse and bind the document into an XMLObject.
+    DOMDocument* doc = (m_validate ? XMLToolingConfig::getConfig().getValidatingParser()
+        : XMLToolingConfig::getConfig().getParser()).parse(is); 
+    XercesJanitor<DOMDocument> janitor(doc);
+    auto_ptr<XMLObject> xmlObject(XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true));
+    janitor.release();
+
+    Envelope* env = dynamic_cast<Envelope*>(xmlObject.get());
+    if (!env)
+        throw BindingException("Decoded message was not a SOAP 1.1 Envelope.");
+
+    if (!m_validate)
+        SchemaValidators.validate(env);
+    
+    Body* body = env->getBody();
+    if (body && body->hasChildren()) {
+        RequestAbstractType* request = dynamic_cast<RequestAbstractType*>(body->getXMLObjects().front());
+        if (request) {
+            // Run through the policy at two layers.
+            policy.evaluate(genericRequest, *env);
+            policy.evaluate(genericRequest, *request);
+            xmlObject.release();
+            body->detach(); // frees Envelope
+            request->detach();   // frees Body
+            return request;
+        }
+    }
+    
+    throw BindingException("SOAP Envelope did not contain a SAML Request.");
+}
index 8bf84ce..1069ea4 100644 (file)
@@ -177,10 +177,14 @@ const XMLCh samlconstants::SAML20P_THIRDPARTY_EXT_NS[] = // urn:oasis:names:tc:S
 
 const XMLCh samlconstants::SAML20P_THIRDPARTY_EXT_PREFIX[] = UNICODE_LITERAL_6(t,h,r,p,t,y);
 
+const char samlconstants::SAML1_BINDING_SOAP[] = "urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding";
+
 const char samlconstants::SAML1_PROFILE_BROWSER_ARTIFACT[] = "urn:oasis:names:tc:SAML:1.0:profiles:artifact-01";
 
 const char samlconstants::SAML1_PROFILE_BROWSER_POST[] = "urn:oasis:names:tc:SAML:1.0:profiles:browser-post";
 
+const char samlconstants::SAML20_BINDING_SOAP[] = "urn:oasis:names:tc:SAML:2.0:bindings:SOAP";
+
 const char samlconstants::SAML20_BINDING_HTTP_ARTIFACT[] = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact";
 
 const char samlconstants::SAML20_BINDING_HTTP_POST[] = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST";
index 17de531..edb7207 100644 (file)
@@ -123,12 +123,18 @@ namespace samlconstants {
     /** SAML Third-Party Request Protocol Extension QName prefix ("query") */
     extern SAML_API const XMLCh SAML20P_THIRDPARTY_EXT_PREFIX[];
 
-    /** SAML 1.x Browser Artifact profile ("urn:oasis:names:tc:SAML:1.0:profiles:artifact-01")*/
+    /** SAML 1.x SOAP binding ("urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding") */
+    extern SAML_API const char SAML1_BINDING_SOAP[];
+
+    /** SAML 1.x Browser Artifact profile ("urn:oasis:names:tc:SAML:1.0:profiles:artifact-01") */
     extern SAML_API const char SAML1_PROFILE_BROWSER_ARTIFACT[];
 
     /** SAML 1.x Browser POST profile ("urn:oasis:names:tc:SAML:1.0:profiles:browser-post") */
     extern SAML_API const char SAML1_PROFILE_BROWSER_POST[];
     
+    /** SAML 2.0 SOAP binding ("urn:oasis:names:tc:SAML:2.0:bindings:SOAP") */
+    extern SAML_API const char SAML20_BINDING_SOAP[];
+
     /** SAML 2.0 HTTP-Artifact binding ("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact") */
     extern SAML_API const char SAML20_BINDING_HTTP_ARTIFACT[];