[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