Solaris port fixes.
[shibboleth/sp.git] / shibsp / handler / impl / RemotedHandler.cpp
index a66e073..238f1e3 100644 (file)
  */
 
 #include "internal.h"
+#include "Application.h"
 #include "exceptions.h"
 #include "ServiceProvider.h"
 #include "handler/RemotedHandler.h"
 
 #include <algorithm>
-#include <log4cpp/Category.hh>
-#include <saml/util/CGIParser.h>
 #include <xmltooling/unicode.h>
-#include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>
-#include <xsec/enc/XSECCryptoException.hpp>
-#include <xsec/framework/XSECException.hpp>
-#include <xsec/framework/XSECProvider.hpp>
+
+#ifndef SHIBSP_LITE
+# include "util/CGIParser.h"
+# include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>
+# include <xsec/enc/XSECCryptoException.hpp>
+# include <xsec/framework/XSECException.hpp>
+# include <xsec/framework/XSECProvider.hpp>
+#endif
 
 using namespace shibsp;
 using namespace opensaml;
 using namespace xmltooling;
-using namespace log4cpp;
 using namespace xercesc;
 using namespace std;
 
+#ifndef SHIBSP_LITE
 namespace shibsp {
-    class SHIBSP_DLLLOCAL RemotedRequest : public virtual opensaml::HTTPRequest 
+    class SHIBSP_DLLLOCAL RemotedRequest : public virtual HTTPRequest 
     {
         DDF& m_input;
         mutable CGIParser* m_parser;
@@ -108,7 +111,7 @@ namespace shibsp {
         }
     };
 
-    class SHIBSP_DLLLOCAL RemotedResponse : public virtual opensaml::HTTPResponse 
+    class SHIBSP_DLLLOCAL RemotedResponse : public virtual HTTPResponse 
     {
         DDF& m_output;
     public:
@@ -149,11 +152,15 @@ std::vector<const char*>::size_type RemotedRequest::getParameters(const char* na
 const std::vector<XSECCryptoX509*>& RemotedRequest::getClientCertificates() const
 {
     if (m_certs.empty()) {
-        DDF cert = m_input["certificates"].first();
-        while (cert.isstring()) {
+        DDF certs = m_input["certificates"];
+        DDF cert = certs.first();
+        while (cert.string()) {
             try {
                 auto_ptr<XSECCryptoX509> x509(XSECPlatformUtils::g_cryptoProvider->X509());
-                x509->loadX509Base64Bin(cert.string(), cert.strlen());
+                if (strstr(cert.string(), "BEGIN"))
+                    x509->loadX509PEM(cert.string(), cert.strlen());
+                else
+                    x509->loadX509Base64Bin(cert.string(), cert.strlen());
                 m_certs.push_back(x509.release());
             }
             catch(XSECException& e) {
@@ -163,7 +170,7 @@ const std::vector<XSECCryptoX509*>& RemotedRequest::getClientCertificates() cons
             catch(XSECCryptoException& e) {
                 Category::getInstance(SHIBSP_LOGCAT".SPRequest").error("XML-Security exception loading client certificate: %s", e.getMsg());
             }
-            cert = cert.next();
+            cert = certs.next();
         }
     }
     return m_certs;
@@ -199,9 +206,10 @@ long RemotedResponse::sendRedirect(const char* url)
     if (!m_output.isstruct())
         m_output.structure();
     m_output.addmember("redirect").string(url);
-    return HTTPResponse::SAML_HTTP_STATUS_MOVED;
+    return HTTPResponse::XMLTOOLING_HTTP_STATUS_MOVED;
 }
 
+#endif
 
 void RemotedHandler::setAddress(const char* address)
 {
@@ -209,7 +217,7 @@ void RemotedHandler::setAddress(const char* address)
         throw ConfigurationException("Cannot register a remoting address twice for the same Handler.");
     m_address = address;
     SPConfig& conf = SPConfig::getConfig();
-    if (conf.isEnabled(SPConfig::OutOfProcess)) {
+    if (!conf.isEnabled(SPConfig::InProcess)) {
         ListenerService* listener = conf.getServiceProvider()->getListenerService(false);
         if (listener)
             listener->regListener(m_address.c_str(),this);
@@ -222,13 +230,14 @@ RemotedHandler::~RemotedHandler()
 {
     SPConfig& conf = SPConfig::getConfig();
     ListenerService* listener=conf.getServiceProvider()->getListenerService(false);
-    if (listener && conf.isEnabled(SPConfig::OutOfProcess))
+    if (listener && conf.isEnabled(SPConfig::OutOfProcess) && !conf.isEnabled(SPConfig::InProcess))
         listener->unregListener(m_address.c_str(),this);
 }
 
 DDF RemotedHandler::wrap(const SPRequest& request, const vector<string>* headers, bool certs) const
 {
     DDF in = DDF(m_address.c_str()).structure();
+    in.addmember("application_id").string(request.getApplication().getId());
     in.addmember("scheme").string(request.getScheme());
     in.addmember("hostname").string(request.getHostname());
     in.addmember("port").integer(request.getPort());
@@ -253,6 +262,7 @@ DDF RemotedHandler::wrap(const SPRequest& request, const vector<string>* headers
     }
 
     if (certs) {
+#ifndef SHIBSP_LITE
         const vector<XSECCryptoX509*>& xvec = request.getClientCertificates();
         if (!xvec.empty()) {
             DDF clist = in.addmember("certificates").list();
@@ -261,6 +271,16 @@ DDF RemotedHandler::wrap(const SPRequest& request, const vector<string>* headers
                 clist.add(x509);
             }
         }
+#else
+        const vector<string>& xvec = request.getClientCertificates();
+        if (!xvec.empty()) {
+            DDF clist = in.addmember("certificates").list();
+            for (vector<string>::const_iterator x = xvec.begin(); x!=xvec.end(); ++x) {
+                DDF x509 = DDF(NULL).string(x->c_str());
+                clist.add(x509);
+            }
+        }
+#endif
     }
 
     return in;
@@ -269,10 +289,17 @@ DDF RemotedHandler::wrap(const SPRequest& request, const vector<string>* headers
 pair<bool,long> RemotedHandler::unwrap(SPRequest& request, DDF& out) const
 {
     DDF h = out["headers"];
-    h = h.first();
-    while (h.isstring()) {
-        request.setResponseHeader(h.name(), h.string());
-        h = h.next();
+    DDF hdr = h.first();
+    while (hdr.isstring()) {
+#ifdef HAVE_STRCASECMP
+        if (!strcasecmp(hdr.name(), "Content-Type"))
+#else
+        if (!stricmp(hdr.name(), "Content-Type"))
+#endif
+            request.setContentType(hdr.string());
+        else
+            request.setResponseHeader(hdr.name(), hdr.string());
+        hdr = h.next();
     }
     h = out["redirect"];
     if (h.isstring())
@@ -280,17 +307,25 @@ pair<bool,long> RemotedHandler::unwrap(SPRequest& request, DDF& out) const
     h = out["response"];
     if (h.isstruct()) {
         istringstream s(h["data"].string());
-        return make_pair(true, static_cast<GenericResponse&>(request).sendResponse(s, h["status"].integer()));
+        return make_pair(true, request.sendResponse(s, h["status"].integer()));
     }
-    return make_pair(false,0);
+    return make_pair(false,0L);
 }
 
 HTTPRequest* RemotedHandler::getRequest(DDF& in) const
 {
+#ifndef SHIBSP_LITE
     return new RemotedRequest(in);
+#else
+    throw ConfigurationException("Cannot process message using lite version of shibsp library.");
+#endif
 }
 
 HTTPResponse* RemotedHandler::getResponse(DDF& out) const
 {
+#ifndef SHIBSP_LITE
     return new RemotedResponse(out);
+#else
+    throw ConfigurationException("Cannot process message using lite version of shibsp library.");
+#endif
 }