[cpp-sp] branch main updated: Start fleshing out support code for remoting.

Scott Cantor cantor.2 at osu.edu
Fri Jan 17 20:11:40 UTC 2025


This is an automated email from the git hooks/post-receive script.

scantor pushed a commit to branch main
in repository cpp-sp.

View the commit online:
http://git.shibboleth.net/view/?p=cpp-sp.git;a=commit;h=b91e5ba2c1e417dbcf09e4a7948b8c161f122a13

The following commit(s) were added to refs/heads/main by this push:
     new b91e5ba2 Start fleshing out support code for remoting.
b91e5ba2 is described below

commit b91e5ba2c1e417dbcf09e4a7948b8c161f122a13
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Fri Jan 17 15:11:35 2025 -0500

    Start fleshing out support code for remoting.
---
 config_win32.h                                     |   7 +-
 configure.ac                                       |   8 +-
 shibsp/Agent.h                                     |   2 +-
 shibsp/AgentConfig.h                               |   6 +
 shibsp/Makefile.am                                 |   8 +-
 shibsp/impl/AgentConfig.cpp                        |   3 +
 shibsp/impl/DefaultAgent.cpp                       |  10 +-
 shibsp/logging/Priority.h                          |   2 +-
 shibsp/remoting/RemotingService.h                  |  10 +-
 shibsp/remoting/SecretSource.h                     |  66 ++
 shibsp/remoting/ddf.h                              |   8 +-
 .../remoting/impl/AbstractHTTPRemotingService.cpp  | 125 ++++
 shibsp/remoting/impl/AbstractHTTPRemotingService.h |  88 +++
 ...tingService.cpp => AbstractRemotingService.cpp} |  27 +-
 shibsp/remoting/impl/AbstractRemotingService.h     |  55 ++
 shibsp/remoting/impl/RemotingService.cpp           |  14 +-
 shibsp/remoting/impl/SecretSource.cpp              | 121 ++++
 shibsp/remoting/impl/SocketListener.cpp            | 686 ---------------------
 shibsp/remoting/impl/SocketListener.h              | 105 ----
 shibsp/remoting/impl/TCPListener.cpp               | 339 ----------
 shibsp/remoting/impl/UnixListener.cpp              | 191 ------
 shibsp/remoting/impl/ddf.cpp                       |  56 +-
 22 files changed, 525 insertions(+), 1412 deletions(-)

diff --git a/config_win32.h b/config_win32.h
index 7c0bf92f..57e7e627 100644
--- a/config_win32.h
+++ b/config_win32.h
@@ -45,11 +45,8 @@
 /* Define to 1 if you have the `dmallocxx' library (-ldmallocxx). */
 /* #undef HAVE_LIBDMALLOCXX */
 
-/* Define if log4shib library is used. */
-#define SHIBSP_LOG4SHIB 1
-
-/* Define if log4cpp library is used. */
-/* #undef SHIBSP_LOG4CPP */
+/* Define to 1 if libcurl library is available. */
+/* #undef HAVE_LIBCURL */
 
 /* Define to 1 if you have the <memory.h> header file. */
 #define HAVE_MEMORY_H 1
diff --git a/configure.ac b/configure.ac
index e28832b6..45c5f895 100644
--- a/configure.ac
+++ b/configure.ac
@@ -84,14 +84,9 @@ AX_CXX_COMPILE_STDCXX([17],,[optional])
 
 # Boost
 BOOST_REQUIRE
-BOOST_BIND
-BOOST_LAMBDA
-BOOST_POINTER_CONTAINER
 BOOST_PROPERTYTREE
-BOOST_SMART_PTR
 BOOST_STRING_ALGO
 BOOST_TEST
-BOOST_TUPLE
 
 ## Use Boost for regex?
 AC_ARG_ENABLE([boost-regex],
@@ -109,6 +104,9 @@ else
     AC_DEFINE([SHIBSP_USE_BOOST_REGEX],[1],[Define if using Boost for regular expressions.])
 fi
 
+AX_PKG_CHECK_MODULES([libcurl],,[libcurl >= 7.4.2],
+    [AC_DEFINE([HAVE_LIBCURL],[1],[Define to 1 if libcurl library is available.])])
+
 # Thank you Solaris, really.
 AC_MSG_CHECKING(for ctime_r)
 if test -z "$ac_cv_ctime_args"; then
diff --git a/shibsp/Agent.h b/shibsp/Agent.h
index 375e6306..c33d12b5 100644
--- a/shibsp/Agent.h
+++ b/shibsp/Agent.h
@@ -78,7 +78,7 @@ namespace shibsp {
          * @param required  true iff an exception should be thrown if no RemotingService is available
          * @return  a RemotingService
          */
-        virtual RemotingService* getRemotingService(bool required=true) const=0;
+        virtual const RemotingService* getRemotingService(bool required=true) const=0;
         
         /**
          * Returns a RequestMapper instance.
diff --git a/shibsp/AgentConfig.h b/shibsp/AgentConfig.h
index 22e1d6a4..367261ef 100644
--- a/shibsp/AgentConfig.h
+++ b/shibsp/AgentConfig.h
@@ -36,6 +36,7 @@ namespace shibsp {
     class SHIBSP_API PathResolver;
     class SHIBSP_API RemotingService;
     class SHIBSP_API RequestMapper;
+    class SHIBSP_API SecretSource;
     class SHIBSP_API SessionCache;
     class SHIBSP_API URLEncoder;
 
@@ -118,6 +119,11 @@ namespace shibsp {
          */
         PluginManager<RequestMapper,std::string,boost::property_tree::ptree&> RequestMapperManager;
 
+        /**
+         * Manages factories for SecretSource plugins.
+         */
+        PluginManager<SecretSource,std::string,boost::property_tree::ptree&> SecretSourceManager;
+
         /**
          * Manages factories for SessionCache plugins.
          */
diff --git a/shibsp/Makefile.am b/shibsp/Makefile.am
index 3cb99420..5b36d307 100644
--- a/shibsp/Makefile.am
+++ b/shibsp/Makefile.am
@@ -66,7 +66,8 @@ iisinclude_HEADERS = \
 
 reminclude_HEADERS = \
 	remoting/ddf.h \
-	remoting/RemotingService.h
+	remoting/RemotingService.h \
+	remoting/SecretSource.h
 
 sessioninclude_HEADERS = \
 	session/SessionCache.h
@@ -88,6 +89,8 @@ noinst_HEADERS = \
 	logging/impl/AbstractLoggingService.h \
 	logging/impl/LoggingServiceSPI.h \
 	logging/impl/StringUtil.h \
+	remoting/impl/AbstractRemotingService.h \
+	remoting/impl/AbstractHTTPRemotingService.h \
         util/Date.h \
 	util/Misc.h
 
@@ -128,6 +131,9 @@ libshibsp_la_SOURCES = \
 	platform/iis/ModuleConfig.cpp \
 	remoting/impl/ddf.cpp \
 	remoting/impl/RemotingService.cpp \
+	remoting/impl/AbstractRemotingService.cpp \
+	remoting/impl/AbstractHTTPRemotingService.cpp \
+	remoting/impl/SecretSource.cpp \
 	session/impl/AbstractSessionCache.cpp \
 	util/BoostPropertySet.cpp \
 	util/CGIParser.cpp \
diff --git a/shibsp/impl/AgentConfig.cpp b/shibsp/impl/AgentConfig.cpp
index e074232d..17e07790 100644
--- a/shibsp/impl/AgentConfig.cpp
+++ b/shibsp/impl/AgentConfig.cpp
@@ -30,6 +30,7 @@
 #include "io/HTTPResponse.h"
 #include "logging/LoggingService.h"
 #include "remoting/RemotingService.h"
+#include "remoting/SecretSource.h"
 #include "session/SessionCache.h"
 #include "util/Misc.h"
 #include "util/PathResolver.h"
@@ -227,6 +228,7 @@ bool AgentInternalConfig::_init(const char* inst_prefix, const char* config_file
         */
 
         registerHandlers();
+        registerSecretSources();
         registerRemotingServices();
         registerSessionCaches();
         registerAgents();
@@ -304,6 +306,7 @@ void AgentInternalConfig::_term()
     AgentManager.deregisterFactories();
     SessionCacheManager.deregisterFactories();
     RemotingServiceManager.deregisterFactories();
+    SecretSourceManager.deregisterFactories();
     HandlerManager.deregisterFactories();
     RequestMapperManager.deregisterFactories();
     AccessControlManager.deregisterFactories();
diff --git a/shibsp/impl/DefaultAgent.cpp b/shibsp/impl/DefaultAgent.cpp
index 952a417e..4d05dfdc 100644
--- a/shibsp/impl/DefaultAgent.cpp
+++ b/shibsp/impl/DefaultAgent.cpp
@@ -57,7 +57,7 @@ namespace {
 
         // Agent services.
 
-        RemotingService* getRemotingService(bool required = true) const {
+        const RemotingService* getRemotingService(bool required = true) const {
             if (required && !m_remotingService)
                 throw ConfigurationException("No ListenerService available.");
             return m_remotingService.get();
@@ -140,7 +140,13 @@ void DefaultAgent::doRemotingService()
 {
     boost::optional<ptree&> child = m_pt.get_child_optional("remoting");
     if (child) {
-        string t(child->get("type", HTTP_REMOTING_SERVICE));
+        string t(child->get("type",
+#ifdef WIN32
+            WIN_HTTP_REMOTING_SERVICE
+#else
+            CURL_HTTP_REMOTING_SERVICE
+#endif
+        ));
         m_log.info("building RemotingService of type %s...", t.c_str());
         m_remotingService.reset(AgentConfig::getConfig().RemotingServiceManager.newPlugin(t.c_str(), *child, true));
     } else {
diff --git a/shibsp/logging/Priority.h b/shibsp/logging/Priority.h
index fd1602e8..bc94d0a7 100644
--- a/shibsp/logging/Priority.h
+++ b/shibsp/logging/Priority.h
@@ -32,7 +32,7 @@ namespace shibsp {
      * Enumerates levels of logging we support.
      */
     class SHIBSP_API Priority {
-        public:
+    public:
 
         /**
          * Predefined Levels of Priorities.
diff --git a/shibsp/remoting/RemotingService.h b/shibsp/remoting/RemotingService.h
index dcacaf98..3c0ce021 100644
--- a/shibsp/remoting/RemotingService.h
+++ b/shibsp/remoting/RemotingService.h
@@ -34,6 +34,7 @@ namespace shibsp {
      */
     class SHIBSP_API RemotingService
     {
+        MAKE_NONCOPYABLE(RemotingService);
     protected:
         RemotingService();
     public:
@@ -45,7 +46,7 @@ namespace shibsp {
          * @param in    input message to send
          * @return      response from remote service
          */
-        virtual DDF send(const DDF& in)=0;
+        virtual DDF send(const DDF& in) const=0;
     };
 
     /**
@@ -53,8 +54,11 @@ namespace shibsp {
      */
     void SHIBSP_API registerRemotingServices();
 
-    /** RemotingService based on an HTTP transport layer */
-    #define HTTP_REMOTING_SERVICE "HTTP"
+    /** RemotingService based on HTTP using Curl library. */
+    #define CURL_HTTP_REMOTING_SERVICE "CurlHTTP"
+
+    /** RemotingService based on HTTP using WinHTTP library. */
+    #define WIN_HTTP_REMOTING_SERVICE "WinHTTP"
 };
 
 #endif /* __shibsp_remotingservice_h__ */
diff --git a/shibsp/remoting/SecretSource.h b/shibsp/remoting/SecretSource.h
new file mode 100644
index 00000000..a1288a51
--- /dev/null
+++ b/shibsp/remoting/SecretSource.h
@@ -0,0 +1,66 @@
+/**
+ * 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 shibsp/remoting/SecretSource.h
+ *
+ * Interface to obtain secrets for RemotingService authentication.
+ */
+
+#ifndef __shibsp_secretsource_h__
+#define __shibsp_secretsource_h__
+
+#include <shibsp/base.h>
+
+#include <string>
+
+namespace shibsp {
+
+    /**
+     * Interface to a source of secrets.
+     */
+    class SHIBSP_API SecretSource
+    {
+        MAKE_NONCOPYABLE(SecretSource);
+    protected:
+        SecretSource();
+    public:
+        virtual ~SecretSource();
+
+        /**
+         * Obtains a secret, which may contain binary data but may not contain nulls.
+         * 
+         * <p>Not all implementations support keyed/multiple secrets. Failure
+         * to obtain the specified secret will result in an exception.</p>
+         * 
+         * @param key an identifier defining which secret to access
+         * 
+         * @return a secret
+         */
+        virtual std::string getSecret(const char* key) const=0;
+    };
+
+    /**
+     * Registers RemotingService classes into the runtime.
+     */
+    void SHIBSP_API registerSecretSources();
+
+    /** RemotingService based on a local file. */
+    #define FILE_SECRET_SOURCE "File"
+
+    /** RemotingService based on an environment variable. */
+    #define ENV_SECRET_SOURCE "Env"
+};
+
+#endif /* __shibsp_secretsource_h__ */
diff --git a/shibsp/remoting/ddf.h b/shibsp/remoting/ddf.h
index c634a132..7bc1e914 100644
--- a/shibsp/remoting/ddf.h
+++ b/shibsp/remoting/ddf.h
@@ -34,6 +34,10 @@ namespace shibsp {
      * with heap objects. When stack objects leave scope, only the handle is freed.
      * Copying and assigning handle objects is a constant time operation equivalent
      * to a single pointer assignment, handled by compiler-generated behavior.
+     * 
+     * This code long predates modern C++, and may eventually be updated but for the
+     * moment, it does not provide the automatic memory mamagement that would be
+     * expected from such a library.
      */
     class SHIBSP_API DDF
     {
@@ -46,7 +50,6 @@ namespace shibsp {
         DDF(const char* n, long val);
         DDF(const char* n, long long val);
         DDF(const char* n, double val);
-        DDF(const char* n, void* val);
     
         DDF& destroy();         // deep destructor
         DDF copy() const;       // deep copy routine
@@ -63,14 +66,12 @@ namespace shibsp {
         bool isfloat() const;
         bool isstruct() const;
         bool islist() const;
-        bool ispointer() const;
     
         // type conversion and value extraction
         const char* string() const;     // legal for str
         long        integer() const;    // legal for all types
         long long   longinteger() const;    // legal for all types
         double      floating() const;   // legal for float
-        void*       pointer() const;    // legal for pointer
     
         // string helper methods
         size_t strlen() const;
@@ -91,7 +92,6 @@ namespace shibsp {
         DDF& floating(const char* val);
         DDF& structure();
         DDF& list();
-        DDF& pointer(void* val);
     
         // list/struct methods
         DDF& add(DDF& child);
diff --git a/shibsp/remoting/impl/AbstractHTTPRemotingService.cpp b/shibsp/remoting/impl/AbstractHTTPRemotingService.cpp
new file mode 100644
index 00000000..a8702a16
--- /dev/null
+++ b/shibsp/remoting/impl/AbstractHTTPRemotingService.cpp
@@ -0,0 +1,125 @@
+/**
+ * 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.
+ */
+
+/**
+ * remoting/impl/AbstractHTTPRemotingService.cpp
+ *
+ * Base class for HTTP-based remoting.
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "AgentConfig.h"
+#include "remoting/SecretSource.h"
+#include "remoting/impl/AbstractHTTPRemotingService.h"
+#include "util/BoostPropertySet.h"
+
+#include <stdexcept>
+#include <boost/property_tree/ptree.hpp>
+
+using namespace shibsp;
+using namespace boost::property_tree;
+using namespace std;
+
+const char AbstractHTTPRemotingService::SECRET_SOURCE_TYPE_PROP_NAME[] = "secretSourceType";
+const char AbstractHTTPRemotingService::BASE_URL_PROP_NAME[] = "baseURL";
+const char AbstractHTTPRemotingService::AGENT_ID_PROP_NAME[] = "agentID";
+const char AbstractHTTPRemotingService::AUTH_METHOD_PROP_NAME[] = "authMethod";
+const char AbstractHTTPRemotingService::CONNECT_TIMEOUT_PROP_NAME[] = "connectTimeout";
+const char AbstractHTTPRemotingService::TIMEOUT_PROP_NAME[] = "timeout";
+
+const char AbstractHTTPRemotingService::SECRET_SOURCE_TYPE_PROP_DEFAULT[] = "File";
+const char AbstractHTTPRemotingService::BASE_URL_PROP_DEFAULT[] = "http://localhost/idp/profile";
+const char AbstractHTTPRemotingService::AUTH_METHOD_PROP_DEFAULT[] = "basic";
+unsigned int AbstractHTTPRemotingService::CONNECT_TIMEOUT_PROP_DEFAULT = 3;
+unsigned int AbstractHTTPRemotingService::TIMEOUT_PROP_DEFAULT = 10;
+
+AbstractHTTPRemotingService::AbstractHTTPRemotingService(ptree& pt) : m_authMethod(agent_auth_none)
+{
+    BoostPropertySet props;
+    props.load(pt);
+
+    m_agentID = props.getString(AGENT_ID_PROP_NAME, "");
+    if (m_agentID.empty()) {
+        throw ConfigurationException("Configuration is missing required agent ID.");
+    }
+
+    m_secretSource.reset(AgentConfig::getConfig().SecretSourceManager.newPlugin(
+        props.getString(SECRET_SOURCE_TYPE_PROP_NAME, SECRET_SOURCE_TYPE_PROP_DEFAULT), pt, false)
+        );
+
+    m_baseURL = props.getString(BASE_URL_PROP_NAME, BASE_URL_PROP_DEFAULT);
+    m_authMethod = getAuthMethod(props.getString(AUTH_METHOD_PROP_NAME, AUTH_METHOD_PROP_DEFAULT));
+    m_connectTimeout = props.getUnsignedInt(CONNECT_TIMEOUT_PROP_NAME, CONNECT_TIMEOUT_PROP_DEFAULT);
+    m_timeout = props.getUnsignedInt(TIMEOUT_PROP_NAME, TIMEOUT_PROP_DEFAULT);
+}
+
+const SecretSource* AbstractHTTPRemotingService::getSecretSource(bool required) const
+{
+    if (required && !m_secretSource) {
+        throw ConfigurationException("SecretSource is not available.");
+    }
+
+    return m_secretSource.get();
+}
+
+const char* AbstractHTTPRemotingService::getBaseURL() const
+{
+    return m_baseURL.c_str();
+}
+
+const char* AbstractHTTPRemotingService::getAgentID() const
+{
+    return m_agentID.c_str();
+}
+
+AbstractHTTPRemotingService::auth_t AbstractHTTPRemotingService::getAuthMethod() const
+{
+    return m_authMethod;
+}
+
+unsigned int AbstractHTTPRemotingService::getConnectTimeout() const
+{
+    return m_connectTimeout;
+}
+
+unsigned int AbstractHTTPRemotingService::getTimeout() const
+{
+    return m_timeout;
+}
+
+AbstractHTTPRemotingService::auth_t AbstractHTTPRemotingService::getAuthMethod(const char* method)
+{
+    if (method) {
+        if (!strcmp(method, "basic")) {
+            return agent_auth_basic;
+        }
+        else if (!strcmp(method, "digest")) {
+            return agent_auth_digest;
+        }
+        else if (!strcmp(method, "gss")) {
+            return agent_auth_gss;
+        }
+        else if (!strcmp(method, "tls")) {
+            return agent_auth_tls;
+        }
+        else {
+            throw range_error("Unrecognized remoting authentication method.");
+        }
+    }
+
+    return agent_auth_none;
+}
+
+AbstractHTTPRemotingService::~AbstractHTTPRemotingService() {}
diff --git a/shibsp/remoting/impl/AbstractHTTPRemotingService.h b/shibsp/remoting/impl/AbstractHTTPRemotingService.h
new file mode 100644
index 00000000..0fe7b6dc
--- /dev/null
+++ b/shibsp/remoting/impl/AbstractHTTPRemotingService.h
@@ -0,0 +1,88 @@
+/**
+ * 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.
+ */
+
+/**
+ * remoting/impl/AbstractHTTPRemotingService.h
+ *
+ * Base class for HTTP-based remoting.
+ */
+
+#ifndef __shibsp_httpremotingservice_h__
+#define __shibsp_httpremotingservice_h__
+
+#include "remoting/impl/AbstractRemotingService.h"
+
+#include <memory>
+
+namespace shibsp {
+
+    class SHIBSP_API SecretSource;
+
+    /**
+     * Base class for HTTP remoting services.
+     */
+    class SHIBSP_API AbstractHTTPRemotingService : public virtual AbstractRemotingService
+    {
+    public:
+        virtual ~AbstractHTTPRemotingService();
+
+        /**
+         * Common types of authentication that may be supported.
+         */
+        enum auth_t {
+            agent_auth_none,
+            agent_auth_basic,
+            agent_auth_digest,
+            agent_auth_gss,
+            agent_auth_tls
+        };
+
+        const SecretSource* getSecretSource(bool required=true) const;
+        const char* getBaseURL() const;
+        const char* getAgentID() const;
+        auth_t getAuthMethod() const;
+        unsigned int getConnectTimeout() const;
+        unsigned int getTimeout() const;
+
+        // Property names and defaults.
+        SHIBSP_API static const char SECRET_SOURCE_TYPE_PROP_NAME[];
+        SHIBSP_API static const char BASE_URL_PROP_NAME[];
+        SHIBSP_API static const char AGENT_ID_PROP_NAME[];
+        SHIBSP_API static const char AUTH_METHOD_PROP_NAME[];
+        SHIBSP_API static const char CONNECT_TIMEOUT_PROP_NAME[];
+        SHIBSP_API static const char TIMEOUT_PROP_NAME[];
+
+        SHIBSP_API static const char SECRET_SOURCE_TYPE_PROP_DEFAULT[];
+        SHIBSP_API static const char BASE_URL_PROP_DEFAULT[];
+        SHIBSP_API static const char AUTH_METHOD_PROP_DEFAULT[];
+        SHIBSP_API static unsigned int CONNECT_TIMEOUT_PROP_DEFAULT;
+        SHIBSP_API static unsigned int TIMEOUT_PROP_DEFAULT;
+
+    protected:
+        AbstractHTTPRemotingService(boost::property_tree::ptree& pt);
+
+    private:
+        auth_t getAuthMethod(const char* method);
+
+        std::unique_ptr<SecretSource> m_secretSource;
+        std::string m_baseURL;
+        std::string m_agentID;
+        auth_t m_authMethod;
+        unsigned int m_connectTimeout;
+        unsigned int m_timeout;
+    };
+
+};
+
+#endif /* __shibsp_httpremotingservice_h__ */
diff --git a/shibsp/remoting/impl/RemotingService.cpp b/shibsp/remoting/impl/AbstractRemotingService.cpp
similarity index 56%
copy from shibsp/remoting/impl/RemotingService.cpp
copy to shibsp/remoting/impl/AbstractRemotingService.cpp
index 12ab0c63..32df7c0f 100644
--- a/shibsp/remoting/impl/RemotingService.cpp
+++ b/shibsp/remoting/impl/AbstractRemotingService.cpp
@@ -13,32 +13,33 @@
  */
 
 /**
- * remoting/impl/RemotingService.cpp
+ * remoting/impl/AbstractRemotingService.cpp
  *
- * Remoting service for agent/hub communication.
+ * Base class for remoting services.
  */
 
 #include "internal.h"
 
-#include "exceptions.h"
-#include "AgentConfig.h"
-#include "remoting/RemotingService.h"
+#include "remoting/impl/AbstractRemotingService.h"
 
+#include <sstream>
 #include <boost/property_tree/ptree.hpp>
 
 using namespace shibsp;
 using namespace boost::property_tree;
 using namespace std;
 
-namespace shibsp {
-    //extern RemotingService* SHIBSP_DLLLOCAL HTTPRemotingServiceFactory(ptree& pt, bool deprecationSupport);
-};
+AbstractRemotingService::AbstractRemotingService(const ptree&) {}
 
-void SHIBSP_API shibsp::registerRemotingServices()
+AbstractRemotingService::~AbstractRemotingService() {}
+
+DDF AbstractRemotingService::send(const DDF& in) const
 {
-    //AgentConfig::getConfig().RemotingServiceManager.registerFactory(HTTP_REMOTING_SERVICE, HTTPRemotingServiceFactory);
-}
+    stringstream buf;
+    buf << in;
 
-RemotingService::RemotingService() {}
+    DDF output;
+    send(buf) >> output;
 
-RemotingService::~RemotingService() {}
+    return output;
+}
\ No newline at end of file
diff --git a/shibsp/remoting/impl/AbstractRemotingService.h b/shibsp/remoting/impl/AbstractRemotingService.h
new file mode 100644
index 00000000..83d51828
--- /dev/null
+++ b/shibsp/remoting/impl/AbstractRemotingService.h
@@ -0,0 +1,55 @@
+/**
+ * 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.
+ */
+
+/**
+ * remoting/impl/AbstractRemotingService.h
+ *
+ * Base class for remoting services.
+ */
+
+#ifndef __shibsp_absremotingservice_h__
+#define __shibsp_absremotingservice_h__
+
+#include "remoting/RemotingService.h"
+
+#include <iostream>
+#include <boost/property_tree/ptree_fwd.hpp>
+
+namespace shibsp {
+
+    /**
+     * Base class for remoting services that handles data marshalling/unmarshalling.
+     */
+    class SHIBSP_API AbstractRemotingService : public virtual RemotingService
+    {
+    public:
+        virtual ~AbstractRemotingService();
+
+        /**
+         * Send a remoted message and return the response.
+         *
+         * @param in    input message to send
+         * @return      response from remote service
+         */
+        DDF send(const DDF& in) const;
+
+    protected:
+        AbstractRemotingService(const boost::property_tree::ptree& pt);
+
+        virtual std::istream& send(std::istream& input) const=0;
+    };
+
+};
+
+#endif /* __shibsp_absremotingservice_h__ */
diff --git a/shibsp/remoting/impl/RemotingService.cpp b/shibsp/remoting/impl/RemotingService.cpp
index 12ab0c63..7090ecc3 100644
--- a/shibsp/remoting/impl/RemotingService.cpp
+++ b/shibsp/remoting/impl/RemotingService.cpp
@@ -20,23 +20,27 @@
 
 #include "internal.h"
 
-#include "exceptions.h"
 #include "AgentConfig.h"
 #include "remoting/RemotingService.h"
-
-#include <boost/property_tree/ptree.hpp>
+#include "remoting/SecretSource.h"
 
 using namespace shibsp;
 using namespace boost::property_tree;
 using namespace std;
 
 namespace shibsp {
-    //extern RemotingService* SHIBSP_DLLLOCAL HTTPRemotingServiceFactory(ptree& pt, bool deprecationSupport);
+    extern RemotingService* SHIBSP_DLLLOCAL CurlHTTPRemotingServiceFactory(ptree& pt, bool deprecationSupport);
+#ifdef WIN32
+    extern RemotingService* SHIBSP_DLLLOCAL WinHTTPRemotingServiceFactory(ptree& pt, bool deprecationSupport);
+#endif
 };
 
 void SHIBSP_API shibsp::registerRemotingServices()
 {
-    //AgentConfig::getConfig().RemotingServiceManager.registerFactory(HTTP_REMOTING_SERVICE, HTTPRemotingServiceFactory);
+    //AgentConfig::getConfig().RemotingServiceManager.registerFactory(CURL_HTTP_REMOTING_SERVICE, CurlHTTPRemotingServiceFactory);
+#ifdef WIN32
+    //AgentConfig::getConfig().RemotingServiceManager.registerFactory(WIN_HTTP_REMOTING_SERVICE, WinHTTPRemotingServiceFactory);
+#endif
 }
 
 RemotingService::RemotingService() {}
diff --git a/shibsp/remoting/impl/SecretSource.cpp b/shibsp/remoting/impl/SecretSource.cpp
new file mode 100644
index 00000000..8ea9062b
--- /dev/null
+++ b/shibsp/remoting/impl/SecretSource.cpp
@@ -0,0 +1,121 @@
+/**
+ * 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.
+ */
+
+/**
+ * remoting/impl/SecretSource.cpp
+ *
+ * Implementations for obtaining secrets for RemotingService authentication.
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+
+#include "AgentConfig.h"
+#include "remoting/SecretSource.h"
+
+#include <fstream>
+#include <boost/property_tree/ptree.hpp>
+
+using namespace shibsp;
+using namespace boost::property_tree;
+using namespace std;
+
+namespace {
+
+    class FileSecretSource : public virtual SecretSource {
+    public:
+        FileSecretSource(const ptree& pt);
+        virtual ~FileSecretSource() {}
+
+        string getSecret(const char* key) const;
+
+    private:
+        string m_pathname;
+    };
+
+    class EnvSecretSource : public virtual SecretSource {
+    public:
+        EnvSecretSource(const ptree& pt);
+        virtual ~EnvSecretSource() {}
+
+        string getSecret(const char* key) const;
+
+    private:
+        string m_envname;
+    };
+
+    SecretSource* SHIBSP_DLLLOCAL FileSecretSourceFactory(ptree& pt, bool deprecationSUpport) {
+        return new FileSecretSource(pt);
+    }
+
+    SecretSource* SHIBSP_DLLLOCAL EnvSecretSourceFactory(ptree& pt, bool deprecationSUpport) {
+        return new EnvSecretSource(pt);
+    }
+};
+
+void SHIBSP_API shibsp::registerSecretSources()
+{
+    AgentConfig::getConfig().SecretSourceManager.registerFactory(FILE_SECRET_SOURCE, FileSecretSourceFactory);
+    AgentConfig::getConfig().SecretSourceManager.registerFactory(ENV_SECRET_SOURCE, EnvSecretSourceFactory);
+}
+
+SecretSource::SecretSource() {}
+
+SecretSource::~SecretSource() {}
+
+FileSecretSource::FileSecretSource(const ptree& pt)
+{
+    static const char SECRET_FILE_PROP_NAME[] = "secretFile";
+    m_pathname = pt.get(SECRET_FILE_PROP_NAME, "");
+    if (m_pathname.empty()) {
+        throw ConfigurationException("Configuration is missing required secret filename setting.");
+    }
+
+    // Test for early detection.
+    getSecret(nullptr);
+}
+
+string FileSecretSource::getSecret(const char*) const
+{
+    ifstream src(m_pathname, ios::in);
+    if (!src) {
+        throw IOException("Error accessing secret in " + m_pathname);
+    }
+
+    string val;
+    src >> val;
+    return val;
+}
+
+EnvSecretSource::EnvSecretSource(const ptree& pt)
+{
+    static const char SECRET_ENV_PROP_NAME[] = "secretEnv";
+    m_envname = pt.get(SECRET_ENV_PROP_NAME, "");
+    if (m_envname.empty()) {
+        throw ConfigurationException("Configuration is missing required secret environment variable setting.");
+    }
+
+    // Test for early detection.
+    getSecret(nullptr);
+}
+
+string EnvSecretSource::getSecret(const char*) const
+{
+    const char* val = getenv(m_envname.c_str());
+    if (!val || !*val) {
+        throw IOException("No value found in " + m_envname + " environment variable.");
+    }
+
+    return val;
+}
diff --git a/shibsp/remoting/impl/SocketListener.cpp b/shibsp/remoting/impl/SocketListener.cpp
deleted file mode 100644
index 8614637c..00000000
--- a/shibsp/remoting/impl/SocketListener.cpp
+++ /dev/null
@@ -1,686 +0,0 @@
-/**
- * Licensed to the University Corporation for Advanced Internet
- * Development, Inc. (UCAID) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for
- * additional information regarding copyright ownership.
- *
- * UCAID licenses this file to you 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.
- */
-
-/**
- * SocketListener.cpp
- *
- * Berkeley Socket-based ListenerService implementation.
- */
-
-#include "internal.h"
-#include "exceptions.h"
-#include "ServiceProvider.h"
-#include "SPConfig.h"
-#include "remoting/impl/SocketListener.h"
-
-#include <errno.h>
-#include <stack>
-#include <sstream>
-#include <boost/lexical_cast.hpp>
-#include <boost/algorithm/string.hpp>
-#include <boost/algorithm/string/classification.hpp>
-#include <boost/algorithm/string/split.hpp>
-#include <xercesc/sax/SAXException.hpp>
-#include <xercesc/util/XMLUniDefs.hpp>
-#include <xercesc/util/OutOfMemoryException.hpp>
-
-#include <xmltooling/util/XMLHelper.h>
-
-#ifndef WIN32
-# include <netinet/in.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-using namespace shibsp;
-using namespace xmltooling;
-using namespace std;
-
-using xercesc::DOMElement;
-using boost::lexical_cast;
-
-namespace shibsp {
-
-    // Manages the pool of connections
-    class SocketPool
-    {
-    public:
-        SocketPool(Category& log, const SocketListener* listener)
-            : m_log(log), m_listener(listener), m_lock(Mutex::create()) {}
-        ~SocketPool();
-        SocketListener::ShibSocket get(bool newSocket=false);
-        void put(SocketListener::ShibSocket s);
-
-    private:
-        SocketListener::ShibSocket connect();
-
-        Category& m_log;
-        const SocketListener* m_listener;
-        boost::scoped_ptr<Mutex> m_lock;
-        stack<SocketListener::ShibSocket> m_pool;
-    };
-
-    // Worker threads in server
-    class ServerThread {
-    public:
-        ServerThread(SocketListener::ShibSocket& s, SocketListener* listener, unsigned long id);
-        ~ServerThread();
-        void run();
-        int job();  // Return -1 on error, 1 for closed, 0 for success
-
-    private:
-        SocketListener::ShibSocket m_sock;
-        Thread* m_child;
-        SocketListener* m_listener;
-        string m_id;
-        char m_buf[16384];
-    };
-}
-
-SocketListener::ShibSocket SocketPool::connect()
-{
-
-    m_log.debug("trying to connect to listener");
-
-    SocketListener::ShibSocket sock;
-    if (!m_listener->create(sock)) {
-        m_log.error("cannot create socket");
-        throw ListenerException("Cannot create socket");
-    }
-
-    bool connected = false;
-    int num_tries = 3;
-
-    for (int i = num_tries-1; i >= 0; i--) {
-        if (m_listener->connect(sock)) {
-            connected = true;
-            break;
-        }
-
-        m_log.warn("cannot connect socket (%u)...%s", sock, (i > 0 ? "retrying" : ""));
-
-        if (i) {
-#ifdef WIN32
-            Sleep(2000*(num_tries-i));
-#else
-            sleep(2*(num_tries-i));
-#endif
-        }
-    }
-
-    if (!connected) {
-        m_log.crit("socket server unavailable, failing");
-        m_listener->close(sock);
-        throw ListenerException("Cannot connect to shibd process, a site administrator should be notified that this web server has malfunctioned.");
-    }
-
-    m_log.debug("socket (%u) connected successfully", sock);
-    return sock;
-}
-
-SocketPool::~SocketPool()
-{
-    while (!m_pool.empty()) {
-#ifdef WIN32
-        closesocket(m_pool.top());
-#else
-        ::close(m_pool.top());
-#endif
-        m_pool.pop();
-    }
-}
-
-SocketListener::ShibSocket SocketPool::get(bool newSocket)
-{
-    if (newSocket)
-        return connect();
-
-    m_lock->lock();
-    if (m_pool.empty()) {
-        m_lock->unlock();
-        return connect();
-    }
-    SocketListener::ShibSocket ret=m_pool.top();
-    m_pool.pop();
-    m_lock->unlock();
-    return ret;
-}
-
-void SocketPool::put(SocketListener::ShibSocket s)
-{
-    Lock lock(m_lock);
-    m_pool.push(s);
-}
-
-SocketListener::SocketListener(const DOMElement* e)
-    : m_catchAll(false), log(&Category::getInstance(SHIBSP_LOGCAT ".Listener")),
-        m_shutdown(nullptr), m_stackSize(0), m_socket((ShibSocket)0)
-{
-    // Are we a client?
-    if (SPConfig::getConfig().isEnabled(SPConfig::InProcess)) {
-        m_socketpool.reset(new SocketPool(*log,this));
-    }
-    // Are we a server?
-    if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
-        m_child_lock.reset(Mutex::create());
-        m_child_wait.reset(CondWait::create());
-
-        static const XMLCh stackSize[] = UNICODE_LITERAL_9(s,t,a,c,k,S,i,z,e);
-        m_stackSize = XMLHelper::getAttrInt(e, 0, stackSize) * 1024;
-    }
-}
-
-SocketListener::~SocketListener()
-{
-}
-
-bool SocketListener::init(bool force)
-{
-    log->info("listener service starting");
-
-    ServiceProvider* sp = SPConfig::getConfig().getServiceProvider();
-    sp->lock();
-    const PropertySet* props = sp->getPropertySet("OutOfProcess");
-    if (props) {
-        pair<bool,bool> flag = props->getBool("catchAll");
-        m_catchAll = flag.first && flag.second;
-    }
-    sp->unlock();
-
-    if (!create(m_socket)) {
-        log->crit("failed to create socket");
-        return false;
-    }
-    if (!bind(m_socket, force)) {
-        this->close(m_socket);
-        log->crit("failed to bind to socket.");
-        return false;
-    }
-
-    return true;
-}
-
-void SocketListener::set_retry_errors(const string& retry_errors)
-{
-    const char* error_list = retry_errors.c_str();
-    std::vector<string> string_list;
-    boost::split(string_list, error_list, boost::is_any_of(", \t"), boost::token_compress_on);
-    for (vector<string>::const_iterator i = string_list.begin(); i != string_list.end(); ++i) {
-        m_retry_errors.push_back(atoi(i->c_str()));
-    }
-}
-
-bool SocketListener::run(bool* shutdown)
-{
-    // Save flag to monitor for shutdown request.
-    m_shutdown = shutdown;
-    unsigned long count = 0;
-
-    while (!*m_shutdown) {
-        fd_set readfds;
-        FD_ZERO(&readfds);
-        FD_SET(m_socket, &readfds);
-        struct timeval tv = { 0, 0 };
-        tv.tv_sec = 5;
-
-        switch (select(m_socket + 1, &readfds, 0, 0, &tv)) {
-#ifdef WIN32
-            case SOCKET_ERROR:
-#else
-            case -1:
-#endif
-                if (errno == EINTR) continue;
-                log_error();
-                log->error("select() on main listener socket failed");
-                *m_shutdown = true;
-                break;
-
-            case 0:
-                continue;
-
-            default:
-            {
-                // Accept the connection.
-                SocketListener::ShibSocket newsock;
-                if (!accept(m_socket, newsock)) {
-                    log->crit("failed to accept incoming socket connection");
-                    continue;
-                }
-
-                // We throw away the result because the children manage themselves...
-                try {
-                    new ServerThread(newsock, this, ++count);
-                }
-                catch (exception& ex) {
-                    log->crit("exception starting new server thread to service incoming request: %s", ex.what());
-                }
-                catch (...) {
-                    log->crit("unknown error starting new server thread to service incoming request");
-                    if (!m_catchAll)
-                        *m_shutdown = true;
-                }
-            }
-        }
-    }
-    log->info("listener service shutting down");
-
-    // Wait for all children to exit.
-    m_child_lock->lock();
-    while (!m_children.empty())
-        m_child_wait->wait(m_child_lock.get());
-    m_child_lock->unlock();
-
-    return true;
-}
-
-void SocketListener::term()
-{
-    this->close(m_socket);
-    m_socket=(ShibSocket)0;
-}
-
-DDF SocketListener::send(const DDF& in)
-{
-    log->debug("sending message (%s)", in.name() ? in.name() : "unnamed");
-
-    // Serialize data for transmission.
-    ostringstream os;
-    os << in;
-    string ostr(os.str());
-
-    // Loop on the RPC in case we lost contact the first time through
-#ifdef WIN32
-    u_long len;
-#else
-    uint32_t len;
-#endif
-    int retry = 1;
-    SocketListener::ShibSocket sock;
-    while (retry >= 0) {
-        // On second time in, just get a new socket.
-        sock = m_socketpool->get(retry == 0);
-
-        int outlen = ostr.length();
-        len = htonl(outlen);
-        if (send(sock,(char*)&len,sizeof(len)) != sizeof(len) || send(sock,ostr.c_str(),outlen) != outlen) {
-            log_error();
-            this->close(sock);
-            if (retry) {
-                retry--;
-                log->debug("retrying failed send");
-            }
-            else
-                throw ListenerException("Failure sending remoted message ($1).", params(1,in.name()));
-        }
-        else {
-            // SUCCESS.
-            log->debug("send completed, reading response message");
-
-            // Read the message size.
-            int size_read;
-            bool retry_error = false;
-            while ((size_read = recv(sock,(char*)&len,sizeof(len))) != sizeof(len)) {
-                // Apparently this happens when a signal interrupts the blocking call.
-                if (errno == EINTR) continue;
-
-                int native_error;
-                if (size_read == -1) {
-                    log_error("reading size of output message", &native_error);
-                }
-                else {
-                    log->error("error reading size of output message (%d != %d)", size_read, sizeof(len));
-                    native_error = 0;
-                }
-                this->close(sock);
-
-                if (std::find(m_retry_errors.begin(), m_retry_errors.end(), native_error) != m_retry_errors.end()) {
-                    log->debug("recv error %d is retryable", native_error);
-                    if (retry) {
-                        retry_error = true;
-                        retry--;
-                        break;
-                    }
-                    else {
-                        log->debug("not retrying on second failure");
-                    }
-                }
-                else {
-                      log->debug("recv error %d is not retryable", native_error);
-                }
-
-                throw ListenerException("Failure receiving response to remoted message ($1).", params(1,in.name()));
-            }
-
-            // If recv had retryable error restart loop and try again
-            if (retry_error) {
-                log->debug("retrying");
-                retry_error = false;
-                continue;
-            }
-
-            len = ntohl(len);
-            retry = -1;
-        }
-    }
-
-    // Read the message.
-    char buf[16384];
-    stringstream is;
-    int size_read;
-    while (len) {
-    	size_read = recv(sock, buf, sizeof(buf));
-    	if (size_read > 0) {
-            is.write(buf, size_read);
-            len -= size_read;
-    	}
-    	else if (errno != EINTR) {
-    		break;
-    	}
-    }
-
-    if (len) {
-        log_error("reading output message");
-        this->close(sock);
-        throw ListenerException("Failure receiving response to remoted message ($1).", params(1,in.name()));
-    }
-
-    m_socketpool->put(sock);
-
-    // Unmarshall data.
-    DDF out;
-    is >> out;
-
-    // Check for exception to unmarshall and throw, otherwise return.
-    if (out.isstring() && out.name() && !strcmp(out.name(),"exception")) {
-        // Reconstitute exception object.
-        DDFJanitor jout(out);
-        XMLToolingException* except=nullptr;
-        try {
-            except=XMLToolingException::fromString(out.string());
-            log->error("remoted message returned an error: %s", except->what());
-        }
-        catch (const XMLToolingException& e) {
-            log->error("caught XMLToolingException while building the XMLToolingException: %s", e.what());
-            log->error("XML was: %s", out.string());
-            throw ListenerException("Remote call failed with an unparsable exception.");
-        }
-
-        boost::scoped_ptr<XMLToolingException> wrapper(except);
-        wrapper->raise();
-    }
-
-    return out;
-}
-
-bool SocketListener::log_error(const char* fn, int* native_error) const
-{
-    if (!fn)
-        fn = "unknown";
-#ifdef WIN32
-    int rc=WSAGetLastError();
-#else
-    int rc=errno;
-#endif
-    if (native_error != nullptr)
-        *native_error = rc;
-
-#ifdef WIN32
-    if (rc == WSAECONNRESET) {
-#else
-    if (rc == ECONNRESET) {
-#endif
-        log->debug("socket connection reset");
-        return false;
-    }
-
-    const char *msg;
-#ifdef HAVE_STRERROR_R
-    char buf[256];
-#ifdef STRERROR_R_CHAR_P
-    msg = strerror_r(rc,buf,sizeof(buf));
-#else
-    msg = strerror_r(rc,buf,sizeof(buf)) ? "<translation failed>" : buf;
-#endif
-#else
-    msg=strerror(rc);
-#endif
-    log->error("failed socket call (%s), result (%d): %s", fn, rc, isprint(*msg) ? msg : "no message");
-    return false;
-}
-
-// actual function run in listener on server threads
-void* server_thread_fn(void* arg)
-{
-    ServerThread* child = (ServerThread*)arg;
-
-#ifndef WIN32
-    // First, let's block all signals
-    Thread::mask_all_signals();
-#endif
-
-    // Run the child until it exits.
-    child->run();
-
-    // Now we can clean up and exit the thread.
-    delete child;
-    return nullptr;
-}
-
-ServerThread::ServerThread(SocketListener::ShibSocket& s, SocketListener* listener, unsigned long id)
-    : m_sock(s), m_child(nullptr), m_listener(listener)
-{
-
-    m_id = string("[") + lexical_cast<string>(id) + "]";
-
-    // Create the child thread
-    m_child = Thread::create(server_thread_fn, (void*)this, m_listener->m_stackSize);
-    m_child->detach();
-}
-
-ServerThread::~ServerThread()
-{
-    // Then lock the children map, remove this socket/thread, signal waiters, and return
-    m_listener->m_child_lock->lock();
-    m_listener->m_children.erase(m_sock);
-    m_listener->m_child_lock->unlock();
-    m_listener->m_child_wait->signal();
-
-    delete m_child;
-}
-
-void ServerThread::run()
-{
-    // Before starting up, make sure we fully "own" this socket.
-    m_listener->m_child_lock->lock();
-    while (m_listener->m_children.find(m_sock) != m_listener->m_children.end())
-        m_listener->m_child_wait->wait(m_listener->m_child_lock.get());
-    m_listener->m_children[m_sock] = m_child;
-    m_listener->m_child_lock->unlock();
-
-    int result;
-    fd_set readfds;
-    struct timeval tv = { 0, 0 };
-
-    while(!*(m_listener->m_shutdown)) {
-        FD_ZERO(&readfds);
-        FD_SET(m_sock, &readfds);
-        tv.tv_sec = 1;
-
-        switch (select(m_sock+1, &readfds, 0, 0, &tv)) {
-#ifdef WIN32
-        case SOCKET_ERROR:
-#else
-        case -1:
-#endif
-            if (errno == EINTR) continue;
-            m_listener->log_error();
-            m_listener->log->error("select() on incoming request socket (%u) returned error", m_sock);
-            return;
-
-        case 0:
-            break;
-
-        default:
-            result = job();
-            if (result) {
-                if (result < 0) {
-                    m_listener->log_error();
-                    m_listener->log->error("I/O failure processing request on socket (%u)", m_sock);
-                }
-                m_listener->close(m_sock);
-                return;
-            }
-        }
-    }
-}
-
-int ServerThread::job()
-{
-    Category& log = Category::getInstance(SHIBSP_LOGCAT ".Listener");
-
-    bool incomingError = true;  // set false once incoming message is received
-    ostringstream sink;
-#ifdef WIN32
-    u_long len;
-#else
-    uint32_t len;
-#endif
-
-    try {
-        // Read the message.
-        int readlength = m_listener->recv(m_sock,(char*)&len,sizeof(len));
-        if (readlength == 0) {
-            log.info("detected socket closure, shutting down worker thread");
-            return 1;
-        }
-        else if (readlength != sizeof(len)) {
-            log.error("error reading size of input message");
-            return -1;
-        }
-        len = ntohl(len);
-
-        int size_read;
-        stringstream is;
-        while (len && (size_read = m_listener->recv(m_sock, m_buf, sizeof(m_buf))) > 0) {
-            is.write(m_buf, size_read);
-            len -= size_read;
-        }
-
-        if (len) {
-            log.error("error reading input message from socket");
-            return -1;
-        }
-
-        // Unmarshall the message.
-        DDF in;
-        DDFJanitor jin(in);
-        is >> in;
-
-        string appid;
-        const char* aid = in["application_id"].string();
-        if (aid)
-            appid = string("[") + aid + "]";
-
-        log.debug("dispatching message (%s)", in.name() ? in.name() : "unnamed");
-
-        incomingError = false;
-
-        // Dispatch the message.
-        m_listener->receive(in, sink);
-    }
-    catch (const xercesc::DOMException& e) {
-        auto_ptr_char temp(e.getMessage());
-        if (incomingError)
-            log.error("error processing incoming message: %s", temp.get() ? temp.get() : "no message");
-        XMLParserException ex(string("DOM error: ") + (temp.get() ? temp.get() : "no message"));
-        DDF out=DDF("exception").string(ex.toString().c_str());
-        DDFJanitor jout(out);
-        sink << out;
-    }
-    catch (const xercesc::SAXException& e) {
-        auto_ptr_char temp(e.getMessage());
-        if (incomingError)
-            log.error("error processing incoming message: %s", temp.get() ? temp.get() : "no message");
-        XMLParserException ex(string("SAX error: ") + (temp.get() ? temp.get() : "no message"));
-        DDF out=DDF("exception").string(ex.toString().c_str());
-        DDFJanitor jout(out);
-        sink << out;
-    }
-    catch (const xercesc::XMLException& e) {
-        auto_ptr_char temp(e.getMessage());
-        if (incomingError)
-            log.error("error processing incoming message: %s", temp.get() ? temp.get() : "no message");
-        XMLParserException ex(string("Xerces error: ") + (temp.get() ? temp.get() : "no message"));
-        DDF out=DDF("exception").string(ex.toString().c_str());
-        DDFJanitor jout(out);
-        sink << out;
-    }
-    catch (const xercesc::OutOfMemoryException& e) {
-        auto_ptr_char temp(e.getMessage());
-        if (incomingError)
-            log.error("error processing incoming message: %s", temp.get() ? temp.get() : "no message");
-        XMLParserException ex(string("Out of memory error: ") + (temp.get() ? temp.get() : "no message"));
-        DDF out=DDF("exception").string(ex.toString().c_str());
-        DDFJanitor jout(out);
-        sink << out;
-    }
-    catch (const XMLToolingException& e) {
-        if (incomingError)
-            log.error("error processing incoming message: %s", e.what());
-        DDF out=DDF("exception").string(e.toString().c_str());
-        DDFJanitor jout(out);
-        sink << out;
-    }
-    catch (const exception& e) {
-        if (incomingError)
-            log.error("error processing incoming message: %s", e.what());
-        ListenerException ex(e.what());
-        DDF out=DDF("exception").string(ex.toString().c_str());
-        DDFJanitor jout(out);
-        sink << out;
-    }
-    catch (...) {
-        if (incomingError)
-            log.error("unexpected error processing incoming message");
-        if (!m_listener->m_catchAll)
-            throw;
-        ListenerException ex("An unexpected error occurred while processing an incoming message.");
-        DDF out=DDF("exception").string(ex.toString().c_str());
-        DDFJanitor jout(out);
-        sink << out;
-    }
-
-    // Return whatever's available.
-    string response(sink.str());
-    int outlen = response.length();
-    len = htonl(outlen);
-    if (m_listener->send(m_sock,(char*)&len,sizeof(len)) != sizeof(len)) {
-        log.error("error sending output message size");
-        return -1;
-    }
-    if (m_listener->send(m_sock,response.c_str(),outlen) != outlen) {
-        log.error("error sending output message");
-        return -1;
-    }
-
-    return 0;
-}
diff --git a/shibsp/remoting/impl/SocketListener.h b/shibsp/remoting/impl/SocketListener.h
deleted file mode 100644
index 12809859..00000000
--- a/shibsp/remoting/impl/SocketListener.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * Licensed to the University Corporation for Advanced Internet
- * Development, Inc. (UCAID) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for
- * additional information regarding copyright ownership.
- *
- * UCAID licenses this file to you 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.
- */
-
-/**
- * SocketListener.h
- *
- * Berkeley Socket-based ListenerService implementation.
- */
-
-#ifndef __shibsp_socklisten_h__
-#define __shibsp_socklisten_h__
-
-#ifndef FD_SETSIZE
-# define FD_SETSIZE 1024
-#endif
-
-#include <shibsp/remoting/ListenerService.h>
-
-#include <boost/scoped_ptr.hpp>
-#include <xercesc/dom/DOM.hpp>
-#include <xmltooling/util/Threads.h>
-
-#ifdef WIN32
-# include <winsock2.h>
-#endif
-
-namespace shibsp {
-
-    class SocketPool;
-    class ServerThread;
-
-    /**
-     * Berkeley Socket-based ListenerService implementation
-     */
-    class SocketListener : public virtual ListenerService
-    {
-    public:
-        /// @cond OFF
-        SocketListener(const xercesc::DOMElement* e);
-        ~SocketListener();
-
-        DDF send(const DDF& in);
-
-        bool init(bool force);
-        bool run(bool* shutdown);
-        void term();
-
-        // Implemented by socket-specific subclasses.
-#ifdef WIN32
-        typedef SOCKET ShibSocket;
-#else
-        typedef int ShibSocket;
-#endif
-        virtual bool create(ShibSocket& s) const=0;
-        virtual bool connect(ShibSocket& s) const=0;
-        virtual bool bind(ShibSocket& s, bool force=false) const=0;
-        virtual bool accept(ShibSocket& listener, ShibSocket& s) const=0;
-        virtual bool close(ShibSocket& s) const=0;
-        virtual int send(ShibSocket& s, const char* buf, int len) const=0;
-        virtual int recv(ShibSocket& s, char* buf, int buflen) const=0;
-
-        bool m_catchAll;
-    protected:
-        void set_retry_errors(const std::string& retry_errors);
-        bool log_error(const char* fn=nullptr, int* native_error=nullptr) const; // for OS-level errors
-        Category* log;
-        /// @endcond
-
-    private:
-
-        boost::scoped_ptr<SocketPool> m_socketpool;
-        bool* m_shutdown;
-        std::vector<int> m_retry_errors;
-
-        // Manage child threads
-        friend class ServerThread;
-        std::map<ShibSocket,xmltooling::Thread*> m_children;
-        boost::scoped_ptr<xmltooling::Mutex> m_child_lock;
-        boost::scoped_ptr<xmltooling::CondWait> m_child_wait;
-
-        unsigned int m_stackSize;
-
-        // Primary socket
-        ShibSocket m_socket;
-    };
-}
-
-#endif /* __shibsp_socklisten_h__ */
diff --git a/shibsp/remoting/impl/TCPListener.cpp b/shibsp/remoting/impl/TCPListener.cpp
deleted file mode 100644
index ee437ae9..00000000
--- a/shibsp/remoting/impl/TCPListener.cpp
+++ /dev/null
@@ -1,339 +0,0 @@
-/**
- * Licensed to the University Corporation for Advanced Internet
- * Development, Inc. (UCAID) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for
- * additional information regarding copyright ownership.
- *
- * UCAID licenses this file to you 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.
- */
-
-/**
- * TCPListener.cpp
- *
- * TCP-based SocketListener implementation.
- */
-
-#include "internal.h"
-#include "exceptions.h"
-#include "remoting/impl/SocketListener.h"
-#include "util/IPRange.h"
-
-#define BOOST_BIND_GLOBAL_PLACEHOLDERS
-#include <boost/bind.hpp>
-#include <boost/algorithm/string.hpp>
-#include <xercesc/util/XMLUniDefs.hpp>
-#include <xmltooling/unicode.h>
-#include <xmltooling/util/XMLHelper.h>
-
-#ifdef WIN32
-# include <winsock2.h>
-# include <ws2tcpip.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-# include <sys/socket.h>
-# include <sys/un.h>
-# include <netdb.h>
-# include <unistd.h>
-# include <arpa/inet.h>
-# include <netinet/in.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>		/* for chmod() */
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <errno.h>
-
-using namespace shibsp;
-using namespace xmltooling;
-using namespace xercesc;
-using namespace boost;
-using namespace std;
-
-namespace shibsp {
-    class TCPListener : virtual public SocketListener
-    {
-    public:
-        TCPListener(const DOMElement* e);
-        ~TCPListener() {}
-
-        bool create(ShibSocket& s) const;
-        bool bind(ShibSocket& s, bool force=false) const;
-        bool connect(ShibSocket& s) const;
-        bool close(ShibSocket& s) const;
-        bool accept(ShibSocket& listener, ShibSocket& s) const;
-
-        int send(ShibSocket& s, const char* buf, int len) const {
-            return ::send(s, buf, len, 0);
-        }
-
-        int recv(ShibSocket& s, char* buf, int buflen) const {
-            return ::recv(s, buf, buflen, 0);
-        }
-
-    private:
-        bool setup_tcp_sockaddr();
-
-        string m_address;
-        unsigned short m_port;
-        vector<IPRange> m_acl;
-        size_t m_sockaddrlen;
-#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
-        struct sockaddr_storage m_sockaddr;
-#else
-        struct sockaddr_in m_sockaddr;
-#endif
-    };
-
-    ListenerService* SHIBSP_DLLLOCAL TCPListenerServiceFactory(const DOMElement* const & e, bool)
-    {
-        return new TCPListener(e);
-    }
-
-    static const XMLCh address[] = UNICODE_LITERAL_7(a,d,d,r,e,s,s);
-    static const XMLCh port[] = UNICODE_LITERAL_4(p,o,r,t);
-    static const XMLCh acl[] = UNICODE_LITERAL_3(a,c,l);
-    static const XMLCh clientAddress[] = UNICODE_LITERAL_13(c,l,i,e,n,t,A,d,d,r,e,s,s);
-    static const XMLCh clientPort[] = UNICODE_LITERAL_10(c,l,i,e,n,t,P,o,r,t);
-    static const XMLCh retryErrors[] = UNICODE_LITERAL_11(r,e,t,r,y,E,r,r,o,r,s);
-};
-
-TCPListener::TCPListener(const DOMElement* e) : SocketListener(e), m_port(0)
-{
-    // In-process, check the clientAddress/clientPort settings first.
-    if (SPConfig::getConfig().isEnabled(SPConfig::InProcess)) {
-        m_address = XMLHelper::getAttrString(e, nullptr, clientAddress);
-        m_port = XMLHelper::getAttrInt(e, 0, clientPort);
-        string retry_errors = XMLHelper::getAttrString(e, nullptr, retryErrors);
-        if (!retry_errors.empty()) {
-            if (retry_errors.find_first_not_of("0123456789, \t") == std::string::npos) {
-                log->info("retrying on error codes: %s", retry_errors.c_str());
-                set_retry_errors(retry_errors);
-            }
-            else {
-                log->error("invalid characters in retryErrors, skipping");
-            }
-
-        }
-    }
-
-    // Back-off to address setting, environment, or default.
-    if (m_address.empty()) {
-        m_address = XMLHelper::getAttrString(e, getenv("SHIBSP_LISTENER_ADDRESS"), address);
-        if (m_address.empty()) {
-            m_address = "127.0.0.1";
-        }
-    }
-
-    log->info("using socket address: %s", m_address.c_str());
-
-    // Back-off to port setting, environment, or default.
-    if (m_port == 0) {
-        m_port = XMLHelper::getAttrInt(e, 0, port);
-        if (m_port == 0) {
-            const char* p = getenv("SHIBSP_LISTENER_PORT");
-            if (p && *p)
-                m_port = atoi(p);
-            if (m_port == 0) {
-                m_port = 1600;
-            }
-        }
-    }
-
-    log->info("using socket port: %u", m_port);
-
-    vector<string> rawacls;
-    string aclbuf = XMLHelper::getAttrString(e, "127.0.0.1", acl);
-    boost::trim(aclbuf);
-    boost::split(rawacls, aclbuf, boost::is_space(), algorithm::token_compress_on);
-    for (vector<string>::const_iterator i = rawacls.begin();  i < rawacls.end();  ++i) {
-        try {
-            m_acl.push_back(IPRange::parseCIDRBlock(i->c_str()));
-        }
-        catch (std::exception& ex) {
-            log->error("invalid CIDR block (%s): %s", i->c_str(), ex.what());
-        }
-    }
-
-    if (m_acl.empty()) {
-        log->warn("invalid CIDR range(s) in acl property, allowing 127.0.0.1 as a fall back");
-        m_acl.push_back(IPRange::parseCIDRBlock("127.0.0.1"));
-    }
-
-    if (!setup_tcp_sockaddr()) {
-        throw ConfigurationException("Unable to use configured socket address property.");
-    }
-}
-
-bool TCPListener::setup_tcp_sockaddr()
-{
-    struct addrinfo* ret = nullptr;
-    struct addrinfo hints;
-
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_flags = AI_NUMERICHOST;
-    hints.ai_family = AF_UNSPEC;
-
-    if (getaddrinfo(m_address.c_str(), nullptr, &hints, &ret) != 0) {
-        log->error("unable to parse server address (%s)", m_address.c_str());
-        return false;
-    }
-
-    m_sockaddrlen = ret->ai_addrlen;
-    if (ret->ai_family == AF_INET) {
-        memcpy(&m_sockaddr, ret->ai_addr, m_sockaddrlen);
-        freeaddrinfo(ret);
-        ((struct sockaddr_in*)&m_sockaddr)->sin_port=htons(m_port);
-        return true;
-    }
-#if defined(AF_INET6) && defined(HAVE_STRUCT_SOCKADDR_STORAGE)
-    else if (ret->ai_family == AF_INET6) {
-        memcpy(&m_sockaddr, ret->ai_addr, m_sockaddrlen);
-        freeaddrinfo(ret);
-        ((struct sockaddr_in6*)&m_sockaddr)->sin6_port=htons(m_port);
-        return true;
-    }
-#endif
-
-    log->error("unknown address type (%d)", ret->ai_family);
-    freeaddrinfo(ret);
-    return false;
-}
-
-bool TCPListener::create(ShibSocket& s) const
-{
-    int type = SOCK_STREAM;
-#ifdef HAVE_SOCK_CLOEXEC
-    type |= SOCK_CLOEXEC;
-#endif
-
-#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
-    s = socket(m_sockaddr.ss_family, type, 0);
-#else
-    s = socket(m_sockaddr.sin_family, type, 0);
-#endif
-#ifdef WIN32
-    if(s == INVALID_SOCKET)
-#else
-    if (s < 0)
-#endif
-        return log_error("socket");
-
-#if !defined(HAVE_SOCK_CLOEXEC) && defined(HAVE_FD_CLOEXEC)
-    int fdflags = fcntl(s, F_GETFD);
-    if (fdflags != -1) {
-        fdflags |= FD_CLOEXEC;
-        fcntl(s, F_SETFD, fdflags);
-    }
-#endif
-
-    return true;
-}
-
-bool TCPListener::bind(ShibSocket& s, bool force) const
-{
-    // XXX: Do we care about the return value from setsockopt?
-    int opt = 1;
-    ::setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(opt));
-
-#ifdef WIN32
-    if (SOCKET_ERROR==::bind(s, (const struct sockaddr*)&m_sockaddr, m_sockaddrlen) || SOCKET_ERROR==::listen(s, 3)) {
-        log_error("bind");
-        close(s);
-        return false;
-    }
-#else
-    // Newer BSDs, and Solaris, require the struct length be passed based on the socket address.
-    // All but Solaris seem to have an ss_len field in the sockaddr_storage struct.
-# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
-#  ifdef HAVE_STRUCT_SOCKADDR_STORAGE
-    if (::bind(s, (const struct sockaddr*)&m_sockaddr, m_sockaddr.ss_len) < 0) {
-#  else
-    if (::bind(s, (const struct sockaddr*)&m_sockaddr, m_sockaddr.sin_len) < 0) {
-#  endif
-# else
-    if (::bind(s, (const struct sockaddr*)&m_sockaddr, m_sockaddrlen) < 0) {
-# endif
-        log_error("bind");
-        close(s);
-        return false;
-    }
-    ::listen(s, 3);
-#endif
-    return true;
-}
-
-bool TCPListener::connect(ShibSocket& s) const
-{
-#ifdef WIN32
-    if(SOCKET_ERROR==::connect(s, (const struct sockaddr*)&m_sockaddr, m_sockaddrlen))
-        return log_error("connect");
-#else
-    // Newer BSDs require the struct length be passed based on the socket address.
-    // Others have no field for that and take the whole struct size like Windows does.
-# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
-#  ifdef HAVE_STRUCT_SOCKADDR_STORAGE
-    if (::connect(s, (const struct sockaddr*)&m_sockaddr, m_sockaddr.ss_len) < 0)
-#  else
-    if (::connect(s, (const struct sockaddr*)&m_sockaddr, m_sockaddr.sin_len) < 0)
-#  endif
-# else
-    if (::connect(s, (const struct sockaddr*)&m_sockaddr, m_sockaddrlen) < 0)
-# endif
-        return log_error("connect");
-#endif
-    return true;
-}
-
-bool TCPListener::close(ShibSocket& s) const
-{
-#ifdef WIN32
-    closesocket(s);
-#else
-    ::close(s);
-#endif
-    return true;
-}
-
-bool TCPListener::accept(ShibSocket& listener, ShibSocket& s) const
-{
-#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
-    struct sockaddr_storage addr;
-#else
-    struct sockaddr_in addr;
-#endif
-    memset(&addr, 0, sizeof(addr));
-
-#ifdef WIN32
-    int size=sizeof(addr);
-    s=::accept(listener, (struct sockaddr*)&addr, &size);
-    if(s==INVALID_SOCKET)
-#else
-    socklen_t size=sizeof(addr);
-    s=::accept(listener, (struct sockaddr*)&addr, &size);
-    if (s < 0)
-#endif
-        return log_error("accept");
-
-    static bool (IPRange::* contains)(const struct sockaddr*) const = &IPRange::contains;
-    if (find_if(m_acl.begin(), m_acl.end(), boost::bind(contains, _1, (const struct sockaddr*)&addr)) == m_acl.end()) {
-        close(s);
-        s = -1;
-        log->error("accept() rejected client with invalid address");
-        return false;
-    }
-    return true;
-}
diff --git a/shibsp/remoting/impl/UnixListener.cpp b/shibsp/remoting/impl/UnixListener.cpp
deleted file mode 100644
index 5238f0cc..00000000
--- a/shibsp/remoting/impl/UnixListener.cpp
+++ /dev/null
@@ -1,191 +0,0 @@
-/**
- * Licensed to the University Corporation for Advanced Internet
- * Development, Inc. (UCAID) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for
- * additional information regarding copyright ownership.
- *
- * UCAID licenses this file to you 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.
- */
-
-/**
- * UnixListener.cpp
- * 
- * Unix Domain-based SocketListener implementation.
- */
-
-#include "internal.h"
-
-#include "AgentConfig.h"
-#include "remoting/impl/SocketListener.h"
-#include "util/PathResolver.h"
-
-#include <xercesc/util/XMLUniDefs.hpp>
-#include <xmltooling/XMLToolingConfig.h>
-#include <xmltooling/unicode.h>
-#include <xmltooling/util/XMLHelper.h>
-
-#ifdef HAVE_UNISTD_H
-# include <sys/socket.h>
-# include <sys/un.h>
-# include <unistd.h>
-# include <arpa/inet.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>		/* for chmod() */
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <errno.h>
-
-using namespace shibsp;
-using namespace xmltooling;
-using namespace xercesc;
-using namespace std;
-
-
-namespace shibsp {
-    class UnixListener : virtual public SocketListener
-    {
-    public:
-        UnixListener(const DOMElement* e);
-        ~UnixListener() {if (m_bound) unlink(m_address.c_str());}
-
-        bool create(ShibSocket& s) const;
-        bool bind(ShibSocket& s, bool force=false) const;
-        bool connect(ShibSocket& s) const;
-        bool close(ShibSocket& s) const;
-        bool accept(ShibSocket& listener, ShibSocket& s) const;
-
-        int send(ShibSocket& s, const char* buf, int len) const {
-            return ::send(s, buf, len, 0);
-        }
-        
-        int recv(ShibSocket& s, char* buf, int buflen) const {
-            return ::recv(s, buf, buflen, 0);
-        }
-        
-    private:
-        string m_address;
-        mutable bool m_bound;
-    };
-
-    ListenerService* SHIBSP_DLLLOCAL UnixListenerServiceFactory(const DOMElement* const & e, bool)
-    {
-        return new UnixListener(e);
-    }
-
-    static const XMLCh address[] = UNICODE_LITERAL_7(a,d,d,r,e,s,s);
-    static const XMLCh clientAddress[] = UNICODE_LITERAL_13(c,l,i,e,n,t,A,d,d,r,e,s,s);
-};
-
-UnixListener::UnixListener(const DOMElement* e) : SocketListener(e), m_bound(false)
-{
-    // In-process, check the clientAddress/clientPort settings first.
-    if (SPConfig::getConfig().isEnabled(SPConfig::InProcess)) {
-        m_address = XMLHelper::getAttrString(e, nullptr, clientAddress);
-    }
-
-    // Back-off to address setting, environment, or default.
-    if (m_address.empty()) {
-        m_address = XMLHelper::getAttrString(e, getenv("SHIBSP_LISTENER_ADDRESS"), address);
-        if (m_address.empty()) {
-            m_address = "shibd.sock";
-        }
-    }
-
-    log->info("using socket address: %s", m_address.c_str());
-
-    AgentConfig::getConfig().getPathResolver().resolve(m_address, PathResolver::SHIBSP_RUN_FILE);
-}
-
-#ifndef UNIX_PATH_MAX
-#define UNIX_PATH_MAX 100
-#endif
-
-bool UnixListener::create(ShibSocket& s) const
-{
-    int type = SOCK_STREAM;
-#ifdef HAVE_SOCK_CLOEXEC
-    type |= SOCK_CLOEXEC;
-#endif
-    s = socket(PF_UNIX, type, 0);
-    if (s < 0)
-        return log_error("socket");
-
-#if !defined(HAVE_SOCK_CLOEXEC) && defined(HAVE_FD_CLOEXEC)
-    int fdflags = fcntl(s, F_GETFD);
-    if (fdflags != -1) {
-        fdflags |= FD_CLOEXEC;
-        fcntl(s, F_SETFD, fdflags);
-    }
-#endif
-
-    return true;
-}
-
-bool UnixListener::bind(ShibSocket& s, bool force) const
-{
-    struct sockaddr_un addr;
-    memset(&addr, 0, sizeof (addr));
-    addr.sun_family = AF_UNIX;
-    strncpy(addr.sun_path, m_address.c_str(), UNIX_PATH_MAX);
-
-    if (force)
-        unlink(m_address.c_str());
-
-    if (::bind(s, (struct sockaddr *)&addr, sizeof (addr)) < 0) {
-        log_error("bind");
-        close(s);
-        return false;
-    }
-
-    // Make sure that only the creator can read -- we don't want just
-    // anyone connecting, do we?
-    if (chmod(m_address.c_str(),0777) < 0) {
-        log_error("chmod");
-        close(s);
-        unlink(m_address.c_str());
-        return false;
-    }
-
-    listen(s, 3);
-    return m_bound=true;
-}
-
-bool UnixListener::connect(ShibSocket& s) const
-{
-    struct sockaddr_un addr;
-    memset(&addr, 0, sizeof (addr));
-    addr.sun_family = AF_UNIX;
-    strncpy(addr.sun_path, m_address.c_str(), UNIX_PATH_MAX);
-
-    if (::connect(s, (struct sockaddr *)&addr, sizeof (addr)) < 0)
-        return log_error("connect");
-    return true;
-}
-
-bool UnixListener::close(ShibSocket& s) const
-{
-    ::close(s);
-    return true;
-}
-
-bool UnixListener::accept(ShibSocket& listener, ShibSocket& s) const
-{
-    s=::accept(listener,nullptr,nullptr);
-    if (s < 0)
-        return log_error("accept");
-    return true;
-}
diff --git a/shibsp/remoting/impl/ddf.cpp b/shibsp/remoting/impl/ddf.cpp
index 6461b8f4..a8d44ad4 100644
--- a/shibsp/remoting/impl/ddf.cpp
+++ b/shibsp/remoting/impl/ddf.cpp
@@ -13,13 +13,12 @@
  */
 
 /**
- * ddf.cpp
+ * remoting/impl/ddf.cpp
  *
  * C++ DDF abstraction for interpretive RPC
  */
 
 #include "internal.h"
-#include "exceptions.h"
 #include "remoting/ddf.h"
 #include "util/Misc.h"
 
@@ -89,7 +88,6 @@ struct shibsp::ddf_body_t {
         DDF_FLOAT,
         DDF_STRUCT,
         DDF_LIST,
-        DDF_POINTER,
         DDF_STRING_UNSAFE,
         DDF_LONG
     } type;                         // data type of node
@@ -99,7 +97,6 @@ struct shibsp::ddf_body_t {
         long integer;
         long long longinteger;
         double floating;
-        void* pointer;
         struct {
             ddf_body_t* first;
             ddf_body_t* last;
@@ -149,13 +146,6 @@ DDF::DDF(const char* n, double val)
     floating(val);
 }
 
-DDF::DDF(const char* n, void* val)
-{
-    m_handle=new(nothrow) ddf_body_t;
-    name(n);
-    pointer(val);
-}
-
 DDF& DDF::destroy()
 {
     remove().empty().name(nullptr);
@@ -181,8 +171,6 @@ DDF DDF::copy() const
             return DDF(m_handle->name,m_handle->value.longinteger);
         case ddf_body_t::DDF_FLOAT:
             return DDF(m_handle->name,m_handle->value.floating);
-        case ddf_body_t::DDF_POINTER:
-            return DDF(m_handle->name,m_handle->value.pointer);
         case ddf_body_t::DDF_STRUCT:
         case ddf_body_t::DDF_LIST:
         {
@@ -273,11 +261,6 @@ bool DDF::islist() const
     return m_handle ? (m_handle->type==ddf_body_t::DDF_LIST) : false;
 }
 
-bool DDF::ispointer() const
-{
-    return m_handle ? (m_handle->type==ddf_body_t::DDF_POINTER) : false;
-}
-
 const char* DDF::string() const
 {
     return isstring() ? m_handle->value.string : nullptr;
@@ -352,11 +335,6 @@ double DDF::floating() const
     return 0;
 }
 
-void* DDF::pointer() const
-{
-    return ispointer() ? m_handle->value.pointer : nullptr;
-}
-
 size_t DDF::strlen() const
 {
     return ddf_strlen(string());
@@ -510,15 +488,6 @@ DDF& DDF::list()
     return *this;
 }
 
-DDF& DDF::pointer(void* val)
-{
-    if (empty().m_handle) {
-        m_handle->value.pointer=val;
-        m_handle->type=ddf_body_t::DDF_POINTER;
-    }
-    return *this;
-}
-
 DDF& DDF::add(DDF& child)
 {
     if ((!isstruct() && !islist()) || !child.m_handle)
@@ -846,17 +815,6 @@ void DDF::dump(FILE* f, int indent) const
                 putc('}',f);
                 break;
 
-            case ddf_body_t::DDF_POINTER:
-                if (m_handle->name)
-                    fprintf(f,"void* %s = ",m_handle->name);
-                else
-                    fprintf(f,"void* = ");
-                if (m_handle->value.pointer)
-                    fprintf(f,"%p",m_handle->value.pointer);
-                else
-                    fprintf(f,"nullptr");
-                break;
-
             default:
                 fprintf(f,"UNKNOWN -- WARNING: ILLEGAL VALUE");
         }
@@ -874,7 +832,6 @@ void DDF::dump(FILE* f, int indent) const
     <typenum> := 0|1|2|3|4|5|7
 
     DDF_EMPTY:
-    DDF_POINTER:
         0
     DDF_STRING:
         1 URL-encoded string
@@ -887,11 +844,10 @@ void DDF::dump(FILE* f, int indent) const
     DDF_LIST:
         5 32-bit count of children
     DDF_STRING_UNSAFE:
-        7 URL-encoded string
+        6 URL-encoded string
     DDF_LONG:
-        8 64-bit integer
+        7 64-bit integer
 
-    Pointers are collapsed into empty, so the type value of 6 is unused.
     The distinction of unsafe strings allows for proper deserialization
     in languages that need to handle non-UTF8 strings differently.
 */
@@ -946,7 +902,6 @@ void serialize(ddf_body_t* p, ostream& os)
 
         switch (p->type) {
             case ddf_body_t::DDF_EMPTY:
-            case ddf_body_t::DDF_POINTER:
                 os << ddf_body_t::DDF_EMPTY << endl;
                 break;
 
@@ -962,13 +917,13 @@ void serialize(ddf_body_t* p, ostream& os)
 
             case ddf_body_t::DDF_INT:
                 if (!is32bitSafe(p->value.integer))
-                    throw IOException("Integer Overflow");
+                    throw range_error("Integer Overflow");
                 os << ddf_body_t::DDF_INT << ' ' << p->value.integer << endl;
                 break;
 
             case ddf_body_t::DDF_LONG:
                 if (!is64bitSafe(p->value.longinteger))
-                    throw IOException("Integer Overflow");
+                    throw range_error("Integer Overflow");
                 os << ddf_body_t::DDF_LONG << ' ' << p->value.longinteger << endl;
                 break;
 
@@ -1055,7 +1010,6 @@ DDF deserialize(istream& is)
     
     switch (type) {
         case ddf_body_t::DDF_EMPTY:
-        case ddf_body_t::DDF_POINTER:
             // Nothing to do, it's already empty.
             return obj;
 

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list