diff --git a/src/common/config/config.cpp b/src/common/config/config.cpp index 12b61542..d2892c4e 100644 --- a/src/common/config/config.cpp +++ b/src/common/config/config.cpp @@ -1,6 +1,8 @@ +#include #include +#include -#include +#include #include #include @@ -9,96 +11,25 @@ #include "common/config/config.h" #include "common/error/error.h" -namespace ssf { -namespace config { - -Tls::Tls() - : ca_cert_path_("./certs/trusted/ca.crt"), - cert_path_("./certs/certificate.crt"), - key_path_("./certs/private.key"), - key_password_(""), - dh_path_("./certs/dh4096.pem"), - cipher_alg_("DHE-RSA-AES256-GCM-SHA384") {} - -void Tls::Log() const { -#ifdef TLS_OVER_TCP_LINK - SSF_LOG(kLogInfo) << "config[tls]: CA cert path: <" << ca_cert_path_ << ">"; - SSF_LOG(kLogInfo) << "config[tls]: cert path: <" << cert_path_ << ">"; - SSF_LOG(kLogInfo) << "config[tls]: key path: <" << key_path_ << ">"; - SSF_LOG(kLogInfo) << "config[tls]: key password: <" << key_password_ << ">"; - SSF_LOG(kLogInfo) << "config[tls]: dh path: <" << dh_path_ << ">"; - SSF_LOG(kLogInfo) << "config[tls]: cipher suite: <" << cipher_alg_ << ">"; +#if defined(BOOST_ASIO_WINDOWS) +#define SSF_PROCESS_SERVICE_BINARY_PATH \ + "\"C:\\\\windows\\\\system32\\\\cmd.exe\"" +#else +#define SSF_PROCESS_SERVICE_BINARY_PATH "\"/bin/bash\"" #endif -} - -Proxy::Proxy() - : host_(""), - port_(""), - username_(""), - domain_(""), - password_(""), - reuse_ntlm_(true), - reuse_kerb_(true) {} - -void Proxy::Log() const { - if (IsSet()) { - SSF_LOG(kLogInfo) << "config[HTTP proxy]: <" << host_ << ":" << port_ - << ">"; - if (!username_.empty()) { - SSF_LOG(kLogInfo) << "config[HTTP proxy]: username: <" << username_ - << ">"; - } - SSF_LOG(kLogInfo) << "config[HTTP proxy]: reuse NTLM credentials <" - << (reuse_ntlm_ ? "true" : "false") << ">"; - SSF_LOG(kLogInfo) << "config[HTTP proxy]: reuse Kerberos credentials <" - << (reuse_kerb_ ? "true" : "false") << ">"; - } else { - SSF_LOG(kLogInfo) << "config[HTTP proxy]: "; - } -} - -ProcessService::ProcessService() - : path_(SSF_PROCESS_SERVICE_BINARY_PATH), args_("") {} - -ProcessService::ProcessService(const ProcessService& process_service) - : path_(process_service.path_), args_(process_service.args_) {} - -Services::Services() : process_() {} -Services::Services(const Services& services) : process_(services.process_) {} - -void Services::UpdateProcessService(const boost::property_tree::ptree& pt) { - auto shell_optional = pt.get_child_optional("shell"); - if (!shell_optional) { - SSF_LOG(kLogDebug) - << "config[update]: shell service configuration not found"; - return; - } +namespace ssf { +namespace config { - auto& shell_prop = shell_optional.get(); - auto path = shell_prop.get_child_optional("path"); - if (path) { - process_.set_path(path.get().data()); - } - auto args = shell_prop.get_child_optional("args"); - if (args) { - process_.set_args(args.get().data()); - } -} +Config::Config() : tls_(), http_proxy_(), services_() {} -void Services::Log() const { - SSF_LOG(kLogInfo) << "config[services][shell]: path: <" - << process_service().path() << ">"; - std::string args(process_service().args()); - if (!args.empty()) { - SSF_LOG(kLogInfo) << "config[services][shell]: args: <" << args << ">"; - } +void Config::Init() { + boost::system::error_code ec; + UpdateFromString(default_config_, ec); } -Config::Config() : tls_(), http_proxy_(), services_() {} - -void Config::Update(const std::string& filepath, - boost::system::error_code& ec) { +void Config::UpdateFromFile(const std::string& filepath, + boost::system::error_code& ec) { std::string conf_file("config.json"); ec.assign(::error::success, ::error::get_ssf_category()); if (filepath.empty()) { @@ -116,9 +47,7 @@ void Config::Update(const std::string& filepath, boost::property_tree::ptree pt; boost::property_tree::read_json(conf_file, pt); - UpdateTls(pt); - UpdateHttpProxy(pt); - UpdateServices(pt); + UpdateFromPTree(pt); } catch (const std::exception& e) { SSF_LOG(kLogError) << "config[ssf]: error reading SSF config file: " << e.what(); @@ -126,111 +55,107 @@ void Config::Update(const std::string& filepath, } } +void Config::UpdateFromString(const std::string& config_string, + boost::system::error_code& ec) { + std::stringstream ss_config; + ss_config << config_string; + + SSF_LOG(kLogDebug) << "config[ssf]: update config from string:" + << default_config_; + + try { + boost::property_tree::ptree pt; + boost::property_tree::read_json(ss_config, pt); + + UpdateFromPTree(pt); + } catch (const std::exception& e) { + SSF_LOG(kLogError) << "config[ssf]: error reading config string: " + << e.what(); + } +} + void Config::Log() const { tls_.Log(); http_proxy_.Log(); services_.Log(); } -void Config::UpdateTls(const boost::property_tree::ptree& pt) { +void Config::LogStatus() const { services_.LogServiceStatus(); } + +void Config::UpdateFromPTree(const PTree& pt) { + UpdateTls(pt); + UpdateHttpProxy(pt); + UpdateServices(pt); +} + +void Config::UpdateTls(const PTree& pt) { auto tls_optional = pt.get_child_optional("ssf.tls"); if (!tls_optional) { SSF_LOG(kLogDebug) << "config[update]: TLS configuration not found"; return; } - auto& tls_prop = tls_optional.get(); - - auto ca_cert_path_optional = tls_prop.get_child_optional("ca_cert_path"); - if (ca_cert_path_optional) { - tls_.set_ca_cert_path(ca_cert_path_optional.get().data()); - } - - auto cert_path_optional = tls_prop.get_child_optional("cert_path"); - if (cert_path_optional) { - tls_.set_cert_path(cert_path_optional.get().data()); - } - - auto key_path_optional = tls_prop.get_child_optional("key_path"); - if (key_path_optional) { - tls_.set_key_path(key_path_optional.get().data()); - } - - auto key_password_optional = tls_prop.get_child_optional("key_password"); - if (key_password_optional) { - tls_.set_key_password(key_password_optional.get().data()); - } - - auto dh_path_optional = tls_prop.get_child_optional("dh_path"); - if (dh_path_optional) { - tls_.set_dh_path(dh_path_optional.get().data()); - } - - auto cipher_alg_optional = tls_prop.get_child_optional("cipher_alg"); - if (cipher_alg_optional) { - tls_.set_cipher_alg(cipher_alg_optional.get().data()); - } + tls_.Update(tls_optional.get()); } -void Config::UpdateHttpProxy(const boost::property_tree::ptree& pt) { +void Config::UpdateHttpProxy(const PTree& pt) { auto proxy_optional = pt.get_child_optional("ssf.http_proxy"); if (!proxy_optional) { SSF_LOG(kLogDebug) << "config[update]: proxy configuration not found"; return; } - auto& proxy_prop = proxy_optional.get(); - - auto host_optional = proxy_prop.get_child_optional("host"); - if (host_optional) { - http_proxy_.set_host(host_optional.get().data()); - } - - auto port_optional = proxy_prop.get_child_optional("port"); - if (port_optional) { - http_proxy_.set_port(port_optional.get().data()); - } - - auto cred_username_optional = - proxy_prop.get_child_optional("credentials.username"); - if (cred_username_optional) { - http_proxy_.set_username(cred_username_optional.get().data()); - } - - auto cred_domain_optional = - proxy_prop.get_child_optional("credentials.domain"); - if (cred_domain_optional) { - http_proxy_.set_domain(cred_domain_optional.get().data()); - } - - auto cred_password_optional = - proxy_prop.get_child_optional("credentials.password"); - if (cred_password_optional) { - http_proxy_.set_password(cred_password_optional.get().data()); - } - - auto cred_reuse_ntlm_optional = - proxy_prop.get_child_optional("credentials.reuse_ntlm"); - if (cred_reuse_ntlm_optional) { - http_proxy_.set_reuse_ntlm(cred_reuse_ntlm_optional.get().data() == "true"); - } - - auto cred_reuse_kerb_optional = - proxy_prop.get_child_optional("credentials.reuse_kerb"); - if (cred_reuse_kerb_optional) { - http_proxy_.set_reuse_kerb(cred_reuse_kerb_optional.get().data() == "true"); - } + http_proxy_.Update(proxy_optional.get()); } -void Config::UpdateServices(const boost::property_tree::ptree& pt) { +void Config::UpdateServices(const PTree& pt) { auto services_optional = pt.get_child_optional("ssf.services"); if (!services_optional) { SSF_LOG(kLogDebug) << "config[update]: services configuration not found"; return; } - services_.UpdateProcessService(services_optional.get()); + services_.Update(services_optional.get()); +} + +const char* Config::default_config_ = R"RAWSTRING( +{ + "ssf": { + "tls" : { + "ca_cert_path": "./certs/trusted/ca.crt", + "cert_path": "./certs/certificate.crt", + "key_path": "./certs/private.key", + "key_password": "", + "dh_path": "./certs/dh4096.pem", + "cipher_alg": "DHE-RSA-AES256-GCM-SHA384" + }, + "http_proxy" : { + "host": "", + "port": "", + "credentials": { + "username": "", + "password": "", + "domain": "", + "reuse_ntlm": "true", + "reuse_nego": "true" + } + }, + "services": { + "datagram_forwarder": { "enable": true }, + "datagram_listener": { "enable": true }, + "stream_forwarder": { "enable": true }, + "stream_listener": { "enable": true }, + "file_copy": { "enable": false }, + "shell": { + "enable": false, + "path": )RAWSTRING" SSF_PROCESS_SERVICE_BINARY_PATH R"RAWSTRING(, + "args": "" + }, + "socks": { "enable": true } + } + } } +)RAWSTRING"; } // config } // ssf diff --git a/src/common/config/config.h b/src/common/config/config.h index 956da9d3..584388c6 100644 --- a/src/common/config/config.h +++ b/src/common/config/config.h @@ -8,183 +8,23 @@ #include #include -#if defined(BOOST_ASIO_WINDOWS) -#define SSF_PROCESS_SERVICE_BINARY_PATH "C:\\windows\\system32\\cmd.exe" -#else -#define SSF_PROCESS_SERVICE_BINARY_PATH "/bin/bash" -#endif +#include "common/config/tls.h" +#include "common/config/proxy.h" +#include "common/config/services.h" namespace ssf { namespace config { -class Tls { - public: - Tls(); - - public: - void Log() const; - - inline std::string ca_cert_path() const { return ca_cert_path_; } - - inline void set_ca_cert_path(const std::string& ca_cert_path) { - ca_cert_path_ = ca_cert_path; - } - - inline std::string cert_path() const { return cert_path_; } - - inline void set_cert_path(const std::string& cert_path) { - cert_path_ = cert_path; - } - - inline std::string key_path() const { return key_path_; } - - inline void set_key_path(const std::string& key_path) { - key_path_ = key_path; - } - - inline std::string key_password() const { return key_password_; } - - inline void set_key_password(const std::string& key_password) { - key_password_ = key_password; - } - - inline std::string dh_path() const { return dh_path_; } - - inline void set_dh_path(const std::string& dh_path) { dh_path_ = dh_path; } - - inline std::string cipher_alg() const { return cipher_alg_; } - - inline void set_cipher_alg(const std::string& cipher_alg) { - cipher_alg_ = cipher_alg; - } - - private: - // CA certificate filepath - std::string ca_cert_path_; - // Client certificate filepath - std::string cert_path_; - // Client key filepath - std::string key_path_; - // Client key password - std::string key_password_; - // Diffie-Hellman ephemeral parameters filepath - std::string dh_path_; - // Allowed cipher suite algorithms - std::string cipher_alg_; -}; - -struct Proxy { - public: - Proxy(); - - public: - void Log() const; - - inline bool IsSet() const { - return !host_.empty() && !port_.empty(); - } - - inline std::string host() const { return host_; } - - inline void set_host(const std::string& host) { - host_ = host; - } - - inline std::string port() const { return port_; } - - inline void set_port(const std::string& port) { - port_ = port; - } - - inline std::string username() const { return username_; } - - inline void set_username(const std::string& username) { - username_ = username; - } - - inline std::string domain() const { return domain_; } - - inline void set_domain(const std::string& domain) { - domain_ = domain; - } - - inline std::string password() const { return password_; } - - inline void set_password(const std::string& password) { - password_ = password; - } - - inline bool reuse_ntlm() const { return reuse_ntlm_; } - - inline void set_reuse_ntlm(bool reuse_ntlm) { - reuse_ntlm_ = reuse_ntlm; - } - - inline bool reuse_kerb() const { return reuse_kerb_; } - - inline void set_reuse_kerb(bool reuse_kerb) { - reuse_kerb_ = reuse_kerb; - } - - private: - // Proxy host - std::string host_; - // Proxy port - std::string port_; - // Credentials username - std::string username_; - // Credentials user's domain - std::string domain_; - // Credentials password - std::string password_; - // Reuse default NTLM credentials - bool reuse_ntlm_; - // Reuse default Kerberos/Negotiate credentials - bool reuse_kerb_; -}; - -class ProcessService { - public: - ProcessService(); - ProcessService(const ProcessService& process_service); - - inline std::string path() const { return path_; } - inline void set_path(const std::string& path) { path_ = path; } - - inline std::string args() const { return args_; } - inline void set_args(const std::string& args) { args_ = args; } - - private: - std::string path_; - std::string args_; -}; - -class Services { +class Config { public: - Services(); - Services(const Services& services); - - inline const ProcessService& process_service() const { return process_; } - inline ProcessService& process() { return process_; } - - void UpdateProcessService(const boost::property_tree::ptree& pt); - void Log() const; + using PTree = boost::property_tree::ptree; - private: - ProcessService process_; -}; - -class Config { public: Config(); public: /** - * Update configuration with JSON file - * If no file provided, try to load config from "config.json" file - * @param filepath config filepath (relative or absolute) - * @param ec error code set if update failed - * + * Initialize config with default values * Format example (default values): * { * "ssf": { @@ -196,7 +36,7 @@ class Config { * "dh_path": "./certs/dh4096.pem", * "cipher_alg": "DHE-RSA-AES256-GCM-SHA384" * }, - * "proxy" : { + * "http_proxy" : { * "host": "", * "port": "", * "credentials": { @@ -208,21 +48,50 @@ class Config { * } * }, * "services": { - * "process": { - * "path": "/bin/bash", + * "datagram_forwarder": { "enable": true }, + * "datagram_listener": { "enable": true }, + * "stream_forwarder": { "enable": true }, + * "stream_listener": { "enable": true }, + * "file_copy": { "enable": false }, + * "shell": { + * "enable": false, + * "path": "/bin/bash|C:\\windows\\system32\\cmd.exe", * "args": "" - * } + * }, + * "socks": { "enable": true } * } * } * } */ - void Update(const std::string& filepath, boost::system::error_code& ec); + void Init(); + + /** + * Update configuration with JSON file + * If no file provided, try to load config from "config.json" file + * @param filepath config filepath (relative or absolute) + * @param ec error code set if update failed + */ + void UpdateFromFile(const std::string& filepath, + boost::system::error_code& ec); + + /** + * Update configuration from ptree + * @param pt + * @param ec error code set if update failed + */ + void UpdateFromString(const std::string& config_string, + boost::system::error_code& ec); /** * Log configuration */ void Log() const; + /** + * Log status + */ + void LogStatus() const; + inline const Tls& tls() const { return tls_; } inline Tls& tls() { return tls_; } @@ -233,11 +102,13 @@ class Config { inline Services& services() { return services_; } private: - void UpdateTls(const boost::property_tree::ptree& pt); - void UpdateHttpProxy(const boost::property_tree::ptree& pt); - void UpdateServices(const boost::property_tree::ptree& pt); + void UpdateFromPTree(const PTree& pt); + void UpdateTls(const PTree& pt); + void UpdateHttpProxy(const PTree& pt); + void UpdateServices(const PTree& pt); private: + static const char* default_config_; Tls tls_; Proxy http_proxy_; Services services_; diff --git a/src/common/config/proxy.cpp b/src/common/config/proxy.cpp new file mode 100644 index 00000000..73af0569 --- /dev/null +++ b/src/common/config/proxy.cpp @@ -0,0 +1,78 @@ +#include + +#include + +#include "common/config/proxy.h" +namespace ssf { +namespace config { + +Proxy::Proxy() + : host_(""), + port_(""), + username_(""), + domain_(""), + password_(""), + reuse_ntlm_(true), + reuse_kerb_(true) {} + +void Proxy::Update(const PTree& proxy_prop) { + auto host_optional = proxy_prop.get_child_optional("host"); + if (host_optional) { + host_ = host_optional.get().data(); + } + + auto port_optional = proxy_prop.get_child_optional("port"); + if (port_optional) { + port_ = port_optional.get().data(); + } + + auto cred_username_optional = + proxy_prop.get_child_optional("credentials.username"); + if (cred_username_optional) { + username_ = cred_username_optional.get().data(); + } + + auto cred_domain_optional = + proxy_prop.get_child_optional("credentials.domain"); + if (cred_domain_optional) { + domain_ = cred_domain_optional.get().data(); + } + + auto cred_password_optional = + proxy_prop.get_child_optional("credentials.password"); + if (cred_password_optional) { + password_ = cred_password_optional.get().data(); + } + + auto cred_reuse_ntlm_optional = + proxy_prop.get_child_optional("credentials.reuse_ntlm"); + if (cred_reuse_ntlm_optional) { + reuse_ntlm_ = cred_reuse_ntlm_optional.get().data() == "true"; + } + + auto cred_reuse_kerb_optional = + proxy_prop.get_child_optional("credentials.reuse_kerb"); + if (cred_reuse_kerb_optional) { + reuse_kerb_ = cred_reuse_kerb_optional.get().data() == "true"; + } +} + +void Proxy::Log() const { + if (IsSet()) { + SSF_LOG(kLogInfo) << "config[HTTP proxy]: <" << host_ << ":" << port_ + << ">"; + if (!username_.empty()) { + SSF_LOG(kLogInfo) << "config[HTTP proxy]: username: <" << username_ + << ">"; + } + SSF_LOG(kLogInfo) << "config[HTTP proxy]: reuse NTLM credentials <" + << (reuse_ntlm_ ? "true" : "false") << ">"; + SSF_LOG(kLogInfo) << "config[HTTP proxy]: reuse Kerberos credentials <" + << (reuse_kerb_ ? "true" : "false") << ">"; + } else { + SSF_LOG(kLogInfo) << "config[HTTP proxy]: "; + } +} + +} // config +} // ssf \ No newline at end of file diff --git a/src/common/config/proxy.h b/src/common/config/proxy.h new file mode 100644 index 00000000..96c604d7 --- /dev/null +++ b/src/common/config/proxy.h @@ -0,0 +1,59 @@ +#ifndef SSF_COMMON_CONFIG_PROXY_H_ +#define SSF_COMMON_CONFIG_PROXY_H_ + +#include + +#include + +namespace ssf { +namespace config { + +struct Proxy { + public: + using PTree = boost::property_tree::ptree; + + public: + Proxy(); + + public: + void Update(const PTree& pt); + + void Log() const; + + inline bool IsSet() const { return !host_.empty() && !port_.empty(); } + + inline std::string host() const { return host_; } + + inline std::string port() const { return port_; } + + inline std::string username() const { return username_; } + + inline std::string domain() const { return domain_; } + + inline std::string password() const { return password_; } + + inline bool reuse_ntlm() const { return reuse_ntlm_; } + + inline bool reuse_kerb() const { return reuse_kerb_; } + + private: + // Proxy host + std::string host_; + // Proxy port + std::string port_; + // Credentials username + std::string username_; + // Credentials user's domain + std::string domain_; + // Credentials password + std::string password_; + // Reuse default NTLM credentials + bool reuse_ntlm_; + // Reuse default Kerberos/Negotiate credentials + bool reuse_kerb_; +}; + +} // config +} // ssf + +#endif // SSF_COMMON_CONFIG_PROXY_H_ \ No newline at end of file diff --git a/src/common/config/services.cpp b/src/common/config/services.cpp new file mode 100644 index 00000000..74c713df --- /dev/null +++ b/src/common/config/services.cpp @@ -0,0 +1,168 @@ +#include + +#include "common/config/services.h" + +namespace ssf { +namespace config { + +Services::Services() + : datagram_forwarder_(), + datagram_listener_(), + file_copy_(), + socks_(), + shell_(), + stream_forwarder_(), + stream_listener_() {} + +Services::Services(const Services& services) + : datagram_forwarder_(services.datagram_forwarder_), + datagram_listener_(services.datagram_listener_), + file_copy_(services.file_copy_), + socks_(services.socks_), + shell_(services.shell_), + stream_forwarder_(services.stream_forwarder_), + stream_listener_(services.stream_listener_) {} + +void Services::Update(const PTree& pt) { + UpdateDatagramForwarder(pt); + UpdateDatagramListener(pt); + UpdateStreamForwarder(pt); + UpdateStreamListener(pt); + + UpdateShell(pt); + UpdateSocks(pt); + UpdateFileCopy(pt); +} + +void Services::Log() const { + if (shell_.enabled()) { + SSF_LOG(kLogInfo) << "config[microservices][shell]: path: <" + << process().path() << ">"; + std::string args(process().args()); + if (!args.empty()) { + SSF_LOG(kLogInfo) << "config[microservices][shell]: args: <" << args + << ">"; + } + } +} + +void Services::LogServiceStatus() const { + SSF_LOG(kLogInfo) << "status[microservices] datagram_forwarder: " + << (datagram_forwarder_.enabled() ? "On" : "Off"); + SSF_LOG(kLogInfo) << "status[microservices] datagram_listener: " + << (datagram_listener_.enabled() ? "On" : "Off"); + SSF_LOG(kLogInfo) << "status[microservices] stream_forwarder: " + << (stream_forwarder_.enabled() ? "On" : "Off"); + SSF_LOG(kLogInfo) << "status[microservices] stream_listener: " + << (stream_listener_.enabled() ? "On" : "Off"); + SSF_LOG(kLogInfo) << "status[microservices] file_copy: " + << (file_copy_.enabled() ? "On" : "Off"); + SSF_LOG(kLogInfo) << "status[microservices] shell: " + << (shell_.enabled() ? "On" : "Off"); + SSF_LOG(kLogInfo) << "status[microservices] socks: " + << (socks_.enabled() ? "On" : "Off"); +} + +void Services::UpdateDatagramForwarder(const PTree& pt) { + auto optional = pt.get_child_optional("datagram_forwarder"); + if (!optional) { + SSF_LOG(kLogDebug) + << "config[update]: datagram_forwarder service configuration not found"; + return; + } + + datagram_forwarder_.set_enabled( + ServiceEnabled(optional.get(), datagram_forwarder_.enabled())); +} + +void Services::UpdateDatagramListener(const PTree& pt) { + auto optional = pt.get_child_optional("datagram_listener"); + if (!optional) { + SSF_LOG(kLogDebug) + << "config[update]: datagram_listener service configuration not found"; + return; + } + + datagram_listener_.set_enabled( + ServiceEnabled(optional.get(), datagram_listener_.enabled())); +} + +void Services::UpdateFileCopy(const PTree& pt) { + auto file_copy_optional = pt.get_child_optional("file_copy"); + if (!file_copy_optional) { + SSF_LOG(kLogDebug) + << "config[update]: file_copy service configuration not found"; + return; + } + + file_copy_.set_enabled( + ServiceEnabled(file_copy_optional.get(), file_copy_.enabled())); +} + +void Services::UpdateShell(const PTree& pt) { + auto shell_optional = pt.get_child_optional("shell"); + if (!shell_optional) { + SSF_LOG(kLogDebug) + << "config[update]: shell service configuration not found"; + return; + } + + auto& shell_prop = shell_optional.get(); + shell_.set_enabled(ServiceEnabled(shell_prop, shell_.enabled())); + + auto path = shell_prop.get_child_optional("path"); + if (path) { + shell_.set_path(path.get().data()); + } + auto args = shell_prop.get_child_optional("args"); + if (args) { + shell_.set_args(args.get().data()); + } +} + +void Services::UpdateSocks(const PTree& pt) { + auto socks_optional = pt.get_child_optional("socks"); + if (!socks_optional) { + SSF_LOG(kLogDebug) + << "config[update]: socks service configuration not found"; + return; + } + + socks_.set_enabled(ServiceEnabled(socks_optional.get(), socks_.enabled())); +} + +void Services::UpdateStreamForwarder(const PTree& pt) { + auto optional = pt.get_child_optional("stream_forwarder"); + if (!optional) { + SSF_LOG(kLogDebug) + << "config[update]: stream_forwarder service configuration not found"; + return; + } + + stream_forwarder_.set_enabled( + ServiceEnabled(optional.get(), stream_forwarder_.enabled())); +} + +void Services::UpdateStreamListener(const PTree& pt) { + auto optional = pt.get_child_optional("stream_listener"); + if (!optional) { + SSF_LOG(kLogDebug) + << "config[update]: stream_listener service configuration not found"; + return; + } + + stream_listener_.set_enabled( + ServiceEnabled(optional.get(), stream_listener_.enabled())); +} + +bool Services::ServiceEnabled(const PTree& service_ptree, bool default_value) { + auto enable_prop = service_ptree.get_child_optional("enable"); + if (enable_prop) { + return enable_prop.get().get_value(); + } else { + return default_value; + } +} + +} // config +} // ssf \ No newline at end of file diff --git a/src/common/config/services.h b/src/common/config/services.h new file mode 100644 index 00000000..a1d3858b --- /dev/null +++ b/src/common/config/services.h @@ -0,0 +1,87 @@ +#ifndef SSF_COMMON_CONFIG_SERVICES_H_ +#define SSF_COMMON_CONFIG_SERVICES_H_ + +#include +#include + +#include "services/copy_file/config.h" +#include "services/datagrams_to_fibers/config.h" +#include "services/fibers_to_sockets/config.h" +#include "services/fibers_to_datagrams/config.h" +#include "services/process/config.h" +#include "services/sockets_to_fibers/config.h" +#include "services/socks/config.h" + +namespace ssf { +namespace config { + +class Services { + public: + using PTree = boost::property_tree::ptree; + + using UDPToFibersConfig = ssf::services::datagrams_to_fibers::Config; + using DatagramForwarderConfig = ssf::services::fibers_to_datagrams::Config; + using DatagramListenerConfig = ssf::services::datagrams_to_fibers::Config; + using FileCopyConfig = ssf::services::copy_file::Config; + using ShellConfig = ssf::services::process::Config; + using SocksConfig = ssf::services::socks::Config; + using StreamForwarderConfig = ssf::services::fibers_to_sockets::Config; + using StreamListenerConfig = ssf::services::sockets_to_fibers::Config; + + public: + Services(); + Services(const Services& services); + + inline const DatagramForwarderConfig datagram_forwarder() const { + return datagram_forwarder_; + } + + inline const DatagramListenerConfig datagram_listener() const { + return datagram_listener_; + } + + inline const ShellConfig& process() const { return shell_; } + + inline const SocksConfig& socks() const { return socks_; } + + inline const FileCopyConfig& file_copy() const { return file_copy_; } + + inline const StreamForwarderConfig& stream_forwarder() const { + return stream_forwarder_; + } + + inline const StreamListenerConfig& stream_listener() const { + return stream_listener_; + } + + void Update(const PTree& pt); + + void Log() const; + + void LogServiceStatus() const; + + private: + void UpdateDatagramForwarder(const PTree& pt); + void UpdateDatagramListener(const PTree& pt); + void UpdateFileCopy(const PTree& pt); + void UpdateShell(const PTree& pt); + void UpdateSocks(const PTree& pt); + void UpdateStreamForwarder(const PTree& pt); + void UpdateStreamListener(const PTree& pt); + + static bool ServiceEnabled(const PTree& service, bool default_value); + + private: + DatagramForwarderConfig datagram_forwarder_; + DatagramListenerConfig datagram_listener_; + FileCopyConfig file_copy_; + ShellConfig shell_; + SocksConfig socks_; + StreamForwarderConfig stream_forwarder_; + StreamListenerConfig stream_listener_; +}; + +} // config +} // ssf + +#endif // SSF_COMMON_CONFIG_SERVICES_H_ \ No newline at end of file diff --git a/src/common/config/tls.cpp b/src/common/config/tls.cpp new file mode 100644 index 00000000..02f91f8b --- /dev/null +++ b/src/common/config/tls.cpp @@ -0,0 +1,60 @@ +#include + +#include "common/config/tls.h" + +namespace ssf { +namespace config { + +Tls::Tls() + : ca_cert_path_("./certs/trusted/ca.crt"), + cert_path_("./certs/certificate.crt"), + key_path_("./certs/private.key"), + key_password_(""), + dh_path_("./certs/dh4096.pem"), + cipher_alg_("DHE-RSA-AES256-GCM-SHA384") {} + +void Tls::Update(const PTree& tls_prop) { + auto ca_cert_path_optional = tls_prop.get_child_optional("ca_cert_path"); + if (ca_cert_path_optional) { + ca_cert_path_ = ca_cert_path_optional.get().data(); + } + + auto cert_path_optional = tls_prop.get_child_optional("cert_path"); + if (cert_path_optional) { + cert_path_ = cert_path_optional.get().data(); + } + + auto key_path_optional = tls_prop.get_child_optional("key_path"); + if (key_path_optional) { + key_path_ = key_path_optional.get().data(); + } + + auto key_password_optional = tls_prop.get_child_optional("key_password"); + if (key_password_optional) { + key_password_ = key_password_optional.get().data(); + } + + auto dh_path_optional = tls_prop.get_child_optional("dh_path"); + if (dh_path_optional) { + dh_path_ = dh_path_optional.get().data(); + } + + auto cipher_alg_optional = tls_prop.get_child_optional("cipher_alg"); + if (cipher_alg_optional) { + cipher_alg_ = cipher_alg_optional.get().data(); + } +} + +void Tls::Log() const { +#ifdef TLS_OVER_TCP_LINK + SSF_LOG(kLogInfo) << "config[tls]: CA cert path: <" << ca_cert_path_ << ">"; + SSF_LOG(kLogInfo) << "config[tls]: cert path: <" << cert_path_ << ">"; + SSF_LOG(kLogInfo) << "config[tls]: key path: <" << key_path_ << ">"; + SSF_LOG(kLogInfo) << "config[tls]: key password: <" << key_password_ << ">"; + SSF_LOG(kLogInfo) << "config[tls]: dh path: <" << dh_path_ << ">"; + SSF_LOG(kLogInfo) << "config[tls]: cipher suite: <" << cipher_alg_ << ">"; +#endif +} + +} // config +} // ssf diff --git a/src/common/config/tls.h b/src/common/config/tls.h new file mode 100644 index 00000000..c444038f --- /dev/null +++ b/src/common/config/tls.h @@ -0,0 +1,53 @@ +#ifndef SSF_COMMON_CONFIG_TLS_H_ +#define SSF_COMMON_CONFIG_TLS_H_ + +#include + +#include + +namespace ssf { +namespace config { + +class Tls { + public: + using PTree = boost::property_tree::ptree; + + public: + Tls(); + + public: + void Update(const PTree& pt); + + void Log() const; + + inline std::string ca_cert_path() const { return ca_cert_path_; } + + inline std::string cert_path() const { return cert_path_; } + + inline std::string key_path() const { return key_path_; } + + inline std::string key_password() const { return key_password_; } + + inline std::string dh_path() const { return dh_path_; } + + inline std::string cipher_alg() const { return cipher_alg_; } + + private: + // CA certificate filepath + std::string ca_cert_path_; + // Client certificate filepath + std::string cert_path_; + // Client key filepath + std::string key_path_; + // Client key password + std::string key_password_; + // Diffie-Hellman ephemeral parameters filepath + std::string dh_path_; + // Allowed cipher suite algorithms + std::string cipher_alg_; +}; + +} // config +} // ssf + +#endif // SSF_COMMON_CONFIG_TLS_H_ \ No newline at end of file diff --git a/src/core/client/client.ipp b/src/core/client/client.ipp index e208d320..8b3bead4 100644 --- a/src/core/client/client.ipp +++ b/src/core/client/client.ipp @@ -139,21 +139,26 @@ void SSFClient::DoFiberize(NetworkSocketPtr p_socket, // Register supported micro services services::socks::SocksServer::RegisterToServiceFactory( - p_service_factory); + p_service_factory, services_config_.socks()); services::fibers_to_sockets::FibersToSockets::RegisterToServiceFactory( - p_service_factory); + p_service_factory, services_config_.stream_forwarder()); services::sockets_to_fibers::SocketsToFibers::RegisterToServiceFactory( - p_service_factory); + p_service_factory, services_config_.stream_listener()); services::fibers_to_datagrams::FibersToDatagrams< - Demux>::RegisterToServiceFactory(p_service_factory); + Demux>::RegisterToServiceFactory(p_service_factory, + services_config_.datagram_forwarder()); services::datagrams_to_fibers::DatagramsToFibers< - Demux>::RegisterToServiceFactory(p_service_factory); + Demux>::RegisterToServiceFactory(p_service_factory, + services_config_.datagram_listener()); services::copy_file::file_to_fiber::FileToFiber< - Demux>::RegisterToServiceFactory(p_service_factory); + Demux>::RegisterToServiceFactory(p_service_factory, + services_config_.file_copy()); services::copy_file::fiber_to_file::FiberToFile< - Demux>::RegisterToServiceFactory(p_service_factory); + Demux>::RegisterToServiceFactory(p_service_factory, + services_config_.file_copy()); services::copy_file::file_enquirer::FileEnquirer< - Demux>::RegisterToServiceFactory(p_service_factory); + Demux>::RegisterToServiceFactory(p_service_factory, + services_config_.file_copy()); services::process::Server::RegisterToServiceFactory( p_service_factory, services_config_.process()); diff --git a/src/core/client/main.cpp b/src/core/client/main.cpp index 43d570f0..f97bd4f7 100644 --- a/src/core/client/main.cpp +++ b/src/core/client/main.cpp @@ -98,8 +98,9 @@ int main(int argc, char** argv) { // Load SSF config if any ssf::config::Config ssf_config; + ssf_config.Init(); - ssf_config.Update(cmd.config_file(), ec); + ssf_config.UpdateFromFile(cmd.config_file(), ec); if (ec) { SSF_LOG(kLogError) << "client: invalid config file format -- Exiting"; @@ -108,6 +109,10 @@ int main(int argc, char** argv) { ssf_config.Log(); + if (cmd.show_status()) { + ssf_config.LogStatus(); + } + CircuitConfig circuit_config; circuit_config.Update(cmd.circuit_file(), ec); diff --git a/src/core/client/main_cp.cpp b/src/core/client/main_cp.cpp index f1bca8c5..ff1a05a5 100644 --- a/src/core/client/main_cp.cpp +++ b/src/core/client/main_cp.cpp @@ -50,7 +50,7 @@ int main(int argc, char** argv) { SSF_LOG(kLogError) << "client: wrong command line arguments"; return 1; } - + ssf::log::Configure(cmd.log_level()); // Create and initialize copy user service @@ -79,7 +79,9 @@ int main(int argc, char** argv) { boost::system::error_code ec_config; ssf::config::Config ssf_config; - ssf_config.Update(cmd.config_file(), ec_config); + ssf_config.Init(); + + ssf_config.UpdateFromFile(cmd.config_file(), ec_config); if (ec_config) { SSF_LOG(kLogError) << "client: invalid config file format"; diff --git a/src/core/command_line/standard/command_line.cpp b/src/core/command_line/standard/command_line.cpp index e07fb75a..4918eec8 100644 --- a/src/core/command_line/standard/command_line.cpp +++ b/src/core/command_line/standard/command_line.cpp @@ -22,6 +22,10 @@ void CommandLine::PopulateLocalOptions(OptionDescription& local_opts) { ("host,H", p_host_option, "Set host"); + local_opts.add_options() + ("status,S", + boost::program_options::bool_switch()->default_value(false), + "Display micro services statuses (on/off)"); // clang-format on } @@ -40,12 +44,12 @@ void CommandLine::ParseOptions(const VariableMap& vm, host_ = vm["host"].as(); host_set_ = true; } + if (vm.count("status")) { + show_status_ = vm["status"].as(); + } } -std::string CommandLine::GetUsageDesc() { - return "ssf[c|s] [options] [host]"; -} - +std::string CommandLine::GetUsageDesc() { return "ssf[c|s] [options] [host]"; } } // standard } // command_line diff --git a/src/core/command_line/standard/command_line.h b/src/core/command_line/standard/command_line.h index 5cd49fe2..ed7d4ea6 100644 --- a/src/core/command_line/standard/command_line.h +++ b/src/core/command_line/standard/command_line.h @@ -27,6 +27,8 @@ class CommandLine : public BaseCommandLine { public: CommandLine(bool is_server = false); + inline bool show_status() const { return show_status_; } + virtual ~CommandLine() {} protected: @@ -41,6 +43,7 @@ class CommandLine : public BaseCommandLine { private: bool is_server_; + bool show_status_; }; } // standard diff --git a/src/core/network_protocol.cpp b/src/core/network_protocol.cpp index 7c273197..76d6eefc 100644 --- a/src/core/network_protocol.cpp +++ b/src/core/network_protocol.cpp @@ -1,3 +1,5 @@ +#include "common/config/config.h" + #include "core/network_protocol.h" namespace ssf { diff --git a/src/core/network_protocol.h b/src/core/network_protocol.h index 2231aa12..c16670e9 100644 --- a/src/core/network_protocol.h +++ b/src/core/network_protocol.h @@ -12,10 +12,14 @@ #include #include -#include "common/config/config.h" #include "core/circuit/config.h" namespace ssf { + +namespace config { +class Config; +} // config + namespace network { class NetworkProtocol { diff --git a/src/core/server/main.cpp b/src/core/server/main.cpp index 4fd489b8..ecb9be22 100644 --- a/src/core/server/main.cpp +++ b/src/core/server/main.cpp @@ -27,7 +27,7 @@ int main(int argc, char** argv) { // Parse the command line boost::system::error_code ec; cmd.Parse(argc, argv, ec); - + if (ec.value() == ::error::operation_canceled) { return 0; } @@ -36,12 +36,14 @@ int main(int argc, char** argv) { SSF_LOG(kLogError) << "server: wrong arguments -- Exiting"; return 1; } - + ssf::log::Configure(cmd.log_level()); // Load SSF config if any ssf::config::Config ssf_config; - ssf_config.Update(cmd.config_file(), ec); + ssf_config.Init(); + + ssf_config.UpdateFromFile(cmd.config_file(), ec); if (ec) { SSF_LOG(kLogError) << "server: invalid config file format -- Exiting"; @@ -50,6 +52,10 @@ int main(int argc, char** argv) { ssf_config.Log(); + if (cmd.show_status()) { + ssf_config.LogStatus(); + } + // Initiate and start the server Server server(ssf_config.services()); diff --git a/src/core/server/server.ipp b/src/core/server/server.ipp index 4a1ed9fd..9f3e79f5 100644 --- a/src/core/server/server.ipp +++ b/src/core/server/server.ipp @@ -164,19 +164,23 @@ void SSFServer::DoFiberize(NetworkSocketPtr p_socket, // Register supported micro services services::socks::SocksServer::RegisterToServiceFactory( - p_service_factory); + p_service_factory, services_config_.socks()); services::fibers_to_sockets::FibersToSockets::RegisterToServiceFactory( - p_service_factory); + p_service_factory, services_config_.stream_forwarder()); services::sockets_to_fibers::SocketsToFibers::RegisterToServiceFactory( - p_service_factory); + p_service_factory, services_config_.stream_listener()); services::fibers_to_datagrams::FibersToDatagrams< - demux>::RegisterToServiceFactory(p_service_factory); + demux>::RegisterToServiceFactory(p_service_factory, + services_config_.datagram_forwarder()); services::datagrams_to_fibers::DatagramsToFibers< - demux>::RegisterToServiceFactory(p_service_factory); + demux>::RegisterToServiceFactory(p_service_factory, + services_config_.datagram_listener()); services::copy_file::file_to_fiber::FileToFiber< - demux>::RegisterToServiceFactory(p_service_factory); + demux>::RegisterToServiceFactory(p_service_factory, + services_config_.file_copy()); services::copy_file::fiber_to_file::FiberToFile< - demux>::RegisterToServiceFactory(p_service_factory); + demux>::RegisterToServiceFactory(p_service_factory, + services_config_.file_copy()); services::process::Server::RegisterToServiceFactory( p_service_factory, services_config_.process()); diff --git a/src/services/base_service.h b/src/services/base_service.h index 323e6b04..0baa56c2 100644 --- a/src/services/base_service.h +++ b/src/services/base_service.h @@ -14,6 +14,7 @@ #include "common/boost/fiber/datagram_fiber.hpp" namespace ssf { + //---------------------------------------------------------------------------- /// Base class for services template diff --git a/src/services/base_service_config.cpp b/src/services/base_service_config.cpp new file mode 100644 index 00000000..c03c9944 --- /dev/null +++ b/src/services/base_service_config.cpp @@ -0,0 +1,9 @@ +#include "services/base_service_config.h" + +namespace ssf { + +BaseServiceConfig::BaseServiceConfig(bool enabled) : enabled_(enabled) {} + +BaseServiceConfig::~BaseServiceConfig() {} + +} // ssf diff --git a/src/services/base_service_config.h b/src/services/base_service_config.h new file mode 100644 index 00000000..676d8f04 --- /dev/null +++ b/src/services/base_service_config.h @@ -0,0 +1,23 @@ +#ifndef SSF_SERVICES_BASE_SERVICE_CONFIG_H_ +#define SSF_SERVICES_BASE_SERVICE_CONFIG_H_ + +namespace ssf { + +class BaseServiceConfig { + public: + virtual ~BaseServiceConfig(); + + inline bool enabled() const { return enabled_; } + + inline void set_enabled(bool enabled) { enabled_ = enabled; } + + protected: + BaseServiceConfig(bool enabled); + + private: + bool enabled_; +}; + +} // ssf + +#endif // SSF_SERVICES_BASE_SERVICE_CONFIG_H_ \ No newline at end of file diff --git a/src/services/copy_file/config.cpp b/src/services/copy_file/config.cpp new file mode 100644 index 00000000..0935885e --- /dev/null +++ b/src/services/copy_file/config.cpp @@ -0,0 +1,14 @@ +#include "services/copy_file/config.h" + +namespace ssf { +namespace services { +namespace copy_file { + +Config::Config() : BaseServiceConfig(false) {} + +Config::Config(const Config& process_service) + : BaseServiceConfig(process_service.enabled()) {} + +} // copy_file +} // services +} // ssf \ No newline at end of file diff --git a/src/services/copy_file/config.h b/src/services/copy_file/config.h new file mode 100644 index 00000000..6addc3d9 --- /dev/null +++ b/src/services/copy_file/config.h @@ -0,0 +1,22 @@ +#ifndef SSF_SERVICES_COPY_FILE_CONFIG_H_ +#define SSF_SERVICES_COPY_FILE_CONFIG_H_ + +#include + +#include "services/base_service_config.h" + +namespace ssf { +namespace services { +namespace copy_file { + +class Config : public BaseServiceConfig { + public: + Config(); + Config(const Config& process_service); +}; + +} // copy_file +} // services +} // ssf + +#endif // SSF_SERVICES_COPY_FILE_CONFIG_H_ \ No newline at end of file diff --git a/src/services/copy_file/fiber_to_file/fiber_to_file.h b/src/services/copy_file/fiber_to_file/fiber_to_file.h index cfe9be3d..63c24d33 100644 --- a/src/services/copy_file/fiber_to_file/fiber_to_file.h +++ b/src/services/copy_file/fiber_to_file/fiber_to_file.h @@ -11,6 +11,7 @@ #include "core/factories/service_factory.h" #include "services/admin/requests/create_service_request.h" +#include "services/copy_file/config.h" #include "services/copy_file/fiber_to_file/fiber_to_ofstream_session.h" namespace ssf { @@ -66,7 +67,12 @@ class FiberToFile : public BaseService { virtual uint32_t service_type_id() { return factory_id; } static void RegisterToServiceFactory( - std::shared_ptr> p_factory) { + std::shared_ptr> p_factory, const Config& config) { + if (!config.enabled()) { + // service factory is not enabled + return; + } + p_factory->RegisterServiceCreator(factory_id, &FiberToFile::Create); } diff --git a/src/services/copy_file/file_enquirer/file_enquirer.h b/src/services/copy_file/file_enquirer/file_enquirer.h index f8685bab..f3736259 100644 --- a/src/services/copy_file/file_enquirer/file_enquirer.h +++ b/src/services/copy_file/file_enquirer/file_enquirer.h @@ -7,6 +7,7 @@ #include "core/factories/service_factory.h" #include "services/admin/requests/create_service_request.h" +#include "services/copy_file/config.h" #include "services/copy_file/file_to_fiber/file_to_fiber.h" namespace ssf { @@ -51,7 +52,12 @@ class FileEnquirer : public BaseService { virtual uint32_t service_type_id() { return factory_id; } static void RegisterToServiceFactory( - std::shared_ptr> p_factory) { + std::shared_ptr> p_factory, const Config& config) { + if (!config.enabled()) { + // service factory is not enabled + return; + } + p_factory->RegisterServiceCreator(factory_id, &FileEnquirer::Create); } diff --git a/src/services/copy_file/file_to_fiber/file_to_fiber.h b/src/services/copy_file/file_to_fiber/file_to_fiber.h index a7814709..4f3f6779 100644 --- a/src/services/copy_file/file_to_fiber/file_to_fiber.h +++ b/src/services/copy_file/file_to_fiber/file_to_fiber.h @@ -25,6 +25,7 @@ #include "services/admin/requests/create_service_request.h" #include "services/copy_file/file_to_fiber/istream_to_fiber_session.h" +#include "services/copy_file/config.h" #include "services/copy_file/filename_buffer.h" #include "services/copy_file/filesystem/filesystem.h" #include "services/copy_file/fiber_to_file/fiber_to_file.h" @@ -119,7 +120,12 @@ class FileToFiber : public BaseService { virtual uint32_t service_type_id() { return factory_id; } static void RegisterToServiceFactory( - std::shared_ptr> p_factory) { + std::shared_ptr> p_factory, const Config& config) { + if (!config.enabled()) { + // service factory is not enabled + return; + } + p_factory->RegisterServiceCreator(factory_id, &FileToFiber::Create); } diff --git a/src/services/datagrams_to_fibers/config.cpp b/src/services/datagrams_to_fibers/config.cpp new file mode 100644 index 00000000..94a9698f --- /dev/null +++ b/src/services/datagrams_to_fibers/config.cpp @@ -0,0 +1,14 @@ +#include "services/datagrams_to_fibers/config.h" + +namespace ssf { +namespace services { +namespace datagrams_to_fibers { + +Config::Config() : BaseServiceConfig(true) {} + +Config::Config(const Config& datagram_listener) + : BaseServiceConfig(datagram_listener.enabled()) {} + +} // datagrams_to_fibers +} // services +} // ssf \ No newline at end of file diff --git a/src/services/datagrams_to_fibers/config.h b/src/services/datagrams_to_fibers/config.h new file mode 100644 index 00000000..e85fd031 --- /dev/null +++ b/src/services/datagrams_to_fibers/config.h @@ -0,0 +1,22 @@ +#ifndef SSF_SERVICES_DATAGRAMS_TO_FIBERS_CONFIG_H_ +#define SSF_SERVICES_DATAGRAMS_TO_FIBERS_CONFIG_H_ + +#include + +#include "services/base_service_config.h" + +namespace ssf { +namespace services { +namespace datagrams_to_fibers { + +class Config : public BaseServiceConfig { + public: + Config(); + Config(const Config& datagram_listener); +}; + +} // datagrams_to_fibers +} // services +} // ssf + +#endif // SSF_SERVICES_DATAGRAMS_TO_FIBERS_CONFIG_H_ \ No newline at end of file diff --git a/src/services/datagrams_to_fibers/datagrams_to_fibers.h b/src/services/datagrams_to_fibers/datagrams_to_fibers.h index d61d5246..dde35cd6 100644 --- a/src/services/datagrams_to_fibers/datagrams_to_fibers.h +++ b/src/services/datagrams_to_fibers/datagrams_to_fibers.h @@ -18,6 +18,7 @@ #include "core/factories/service_factory.h" #include "services/admin/requests/create_service_request.h" +#include "services/datagrams_to_fibers/config.h" namespace ssf { namespace services { @@ -61,7 +62,12 @@ class DatagramsToFibers : public BaseService { enum { factory_id = 6 }; static void RegisterToServiceFactory( - std::shared_ptr> p_factory) { + std::shared_ptr> p_factory, const Config& config) { + if (!config.enabled()) { + // service factory is not enabled + return; + } + p_factory->RegisterServiceCreator(factory_id, &DatagramsToFibers::Create); } diff --git a/src/services/fibers_to_datagrams/config.cpp b/src/services/fibers_to_datagrams/config.cpp new file mode 100644 index 00000000..38ffba23 --- /dev/null +++ b/src/services/fibers_to_datagrams/config.cpp @@ -0,0 +1,14 @@ +#include "services/fibers_to_datagrams/config.h" + +namespace ssf { +namespace services { +namespace fibers_to_datagrams { + +Config::Config() : BaseServiceConfig(true) {} + +Config::Config(const Config& datagram_forwarder) + : BaseServiceConfig(datagram_forwarder.enabled()) {} + +} // fibers_to_datagrams +} // services +} // ssf \ No newline at end of file diff --git a/src/services/fibers_to_datagrams/config.h b/src/services/fibers_to_datagrams/config.h new file mode 100644 index 00000000..32531e37 --- /dev/null +++ b/src/services/fibers_to_datagrams/config.h @@ -0,0 +1,22 @@ +#ifndef SSF_SERVICES_FIBERS_TO_DATAGRAMS_CONFIG_H_ +#define SSF_SERVICES_FIBERS_TO_DATAGRAMS_CONFIG_H_ + +#include + +#include "services/base_service_config.h" + +namespace ssf { +namespace services { +namespace fibers_to_datagrams { + +class Config : public BaseServiceConfig { + public: + Config(); + Config(const Config& datagram_forwarder); +}; + +} // fibers_to_datagrams +} // services +} // ssf + +#endif // SSF_SERVICES_FIBERS_TO_DATAGRAMS_CONFIG_H_ \ No newline at end of file diff --git a/src/services/fibers_to_datagrams/fibers_to_datagrams.h b/src/services/fibers_to_datagrams/fibers_to_datagrams.h index ee5db75c..ef3b9bb1 100644 --- a/src/services/fibers_to_datagrams/fibers_to_datagrams.h +++ b/src/services/fibers_to_datagrams/fibers_to_datagrams.h @@ -18,6 +18,7 @@ #include "core/factories/service_factory.h" #include "services/admin/requests/create_service_request.h" +#include "services/fibers_to_datagrams/config.h" namespace ssf { namespace services { @@ -62,7 +63,12 @@ class FibersToDatagrams : public BaseService { enum { factory_id = 5 }; static void RegisterToServiceFactory( - std::shared_ptr> p_factory) { + std::shared_ptr> p_factory, const Config& config) { + if (!config.enabled()) { + // service factory is not enabled + return; + } + p_factory->RegisterServiceCreator(factory_id, &FibersToDatagrams::create); } diff --git a/src/services/fibers_to_sockets/config.cpp b/src/services/fibers_to_sockets/config.cpp new file mode 100644 index 00000000..d0d28cba --- /dev/null +++ b/src/services/fibers_to_sockets/config.cpp @@ -0,0 +1,14 @@ +#include "services/fibers_to_sockets/config.h" + +namespace ssf { +namespace services { +namespace fibers_to_sockets { + +Config::Config() : BaseServiceConfig(true) {} + +Config::Config(const Config& stream_forwarder) + : BaseServiceConfig(stream_forwarder.enabled()) {} + +} // fibers_to_sockets +} // services +} // ssf \ No newline at end of file diff --git a/src/services/fibers_to_sockets/config.h b/src/services/fibers_to_sockets/config.h new file mode 100644 index 00000000..1f2d90af --- /dev/null +++ b/src/services/fibers_to_sockets/config.h @@ -0,0 +1,22 @@ +#ifndef SSF_SERVICES_FIBERS_TO_SOCKETS_CONFIG_H_ +#define SSF_SERVICES_FIBERS_TO_SOCKETS_CONFIG_H_ + +#include + +#include "services/base_service_config.h" + +namespace ssf { +namespace services { +namespace fibers_to_sockets { + +class Config : public BaseServiceConfig { + public: + Config(); + Config(const Config& stream_forwarder); +}; + +} // fibers_to_sockets +} // services +} // ssf + +#endif // SSF_SERVICES_FIBERS_TO_SOCKETS_CONFIG_H_ \ No newline at end of file diff --git a/src/services/fibers_to_sockets/fibers_to_sockets.h b/src/services/fibers_to_sockets/fibers_to_sockets.h index 9fb631d8..2cce22ac 100644 --- a/src/services/fibers_to_sockets/fibers_to_sockets.h +++ b/src/services/fibers_to_sockets/fibers_to_sockets.h @@ -17,6 +17,7 @@ #include "core/factories/service_factory.h" #include "services/admin/requests/create_service_request.h" +#include "services/fibers_to_sockets/config.h" namespace ssf { namespace services { @@ -54,7 +55,12 @@ class FibersToSockets : public BaseService { enum { factory_id = 3 }; static void RegisterToServiceFactory( - std::shared_ptr> p_factory) { + std::shared_ptr> p_factory, const Config& config) { + if (!config.enabled()) { + // service factory is not enabled + return; + } + p_factory->RegisterServiceCreator(factory_id, &FibersToSockets::create); } diff --git a/src/services/process/config.cpp b/src/services/process/config.cpp new file mode 100644 index 00000000..bafeeb21 --- /dev/null +++ b/src/services/process/config.cpp @@ -0,0 +1,19 @@ +#include "services/process/config.h" + +namespace ssf { +namespace services { +namespace process { + +Config::Config() + : BaseServiceConfig(false), + path_(""), + args_("") {} + +Config::Config(const Config& process_service) + : BaseServiceConfig(process_service.enabled()), + path_(process_service.path_), + args_(process_service.args_) {} + +} // process +} // services +} // ssf \ No newline at end of file diff --git a/src/services/process/config.h b/src/services/process/config.h new file mode 100644 index 00000000..c1945cc8 --- /dev/null +++ b/src/services/process/config.h @@ -0,0 +1,32 @@ +#ifndef SSF_SERVICES_PROCESS_CONFIG_H_ +#define SSF_SERVICES_PROCESS_CONFIG_H_ + +#include + +#include "services/base_service_config.h" + +namespace ssf { +namespace services { +namespace process { + +class Config : public BaseServiceConfig { + public: + Config(); + Config(const Config& process_service); + + inline std::string path() const { return path_; } + inline void set_path(const std::string& path) { path_ = path; } + + inline std::string args() const { return args_; } + inline void set_args(const std::string& args) { args_ = args; } + + private: + std::string path_; + std::string args_; +}; + +} // process +} // services +} // ssf + +#endif // SSF_SERVICES_PROCESS_CONFIG_H_ \ No newline at end of file diff --git a/src/services/process/server.h b/src/services/process/server.h index a2870375..68f26cbe 100644 --- a/src/services/process/server.h +++ b/src/services/process/server.h @@ -11,13 +11,13 @@ #include "services/base_service.h" -#include "common/config/config.h" #include "common/boost/fiber/stream_fiber.hpp" #include "common/boost/fiber/basic_fiber_demux.hpp" #include "core/factories/service_factory.h" #include "services/admin/requests/create_service_request.h" +#include "services/process/config.h" #if defined(BOOST_ASIO_WINDOWS) #include "services/process/windows/session.h" @@ -73,8 +73,12 @@ class Server : public BaseService { // Function used to register the micro service to the given factory static void RegisterToServiceFactory( - std::shared_ptr> p_factory, - const ssf::config::ProcessService& config) { + std::shared_ptr> p_factory, const Config& config) { + if (!config.enabled()) { + // service factory is not enabled + return; + } + p_factory->RegisterServiceCreator( factory_id, boost::bind(&Server::Create, _1, _2, _3, config.path(), config.args())); diff --git a/src/services/sockets_to_fibers/config.cpp b/src/services/sockets_to_fibers/config.cpp new file mode 100644 index 00000000..5f64e808 --- /dev/null +++ b/src/services/sockets_to_fibers/config.cpp @@ -0,0 +1,14 @@ +#include "services/sockets_to_fibers/config.h" + +namespace ssf { +namespace services { +namespace sockets_to_fibers { + +Config::Config() : BaseServiceConfig(true) {} + +Config::Config(const Config& stream_listener) + : BaseServiceConfig(stream_listener.enabled()) {} + +} // sockets_to_fibers +} // services +} // ssf \ No newline at end of file diff --git a/src/services/sockets_to_fibers/config.h b/src/services/sockets_to_fibers/config.h new file mode 100644 index 00000000..cd196f24 --- /dev/null +++ b/src/services/sockets_to_fibers/config.h @@ -0,0 +1,22 @@ +#ifndef SSF_SERVICES_SOCKETS_TO_FIBERS_CONFIG_H_ +#define SSF_SERVICES_SOCKETS_TO_FIBERS_CONFIG_H_ + +#include + +#include "services/base_service_config.h" + +namespace ssf { +namespace services { +namespace sockets_to_fibers { + +class Config : public BaseServiceConfig { + public: + Config(); + Config(const Config& stream_listener); +}; + +} // sockets_to_fibers +} // services +} // ssf + +#endif // SSF_SERVICES_SOCKETS_TO_FIBERS_CONFIG_H_ \ No newline at end of file diff --git a/src/services/sockets_to_fibers/sockets_to_fibers.h b/src/services/sockets_to_fibers/sockets_to_fibers.h index f567c0d7..b1fe8ab7 100644 --- a/src/services/sockets_to_fibers/sockets_to_fibers.h +++ b/src/services/sockets_to_fibers/sockets_to_fibers.h @@ -15,6 +15,7 @@ #include "core/factories/service_factory.h" #include "services/admin/requests/create_service_request.h" +#include "services/sockets_to_fibers/config.h" namespace ssf { namespace services { @@ -51,7 +52,12 @@ class SocketsToFibers : public BaseService { enum { factory_id = 4 }; static void RegisterToServiceFactory( - std::shared_ptr> p_factory) { + std::shared_ptr> p_factory, const Config& config) { + if (!config.enabled()) { + // service factory is not enabled + return; + } + p_factory->RegisterServiceCreator(factory_id, &SocketsToFibers::Create); } diff --git a/src/services/socks/config.cpp b/src/services/socks/config.cpp new file mode 100644 index 00000000..d7878458 --- /dev/null +++ b/src/services/socks/config.cpp @@ -0,0 +1,14 @@ +#include "services/socks/config.h" + +namespace ssf { +namespace services { +namespace socks { + +Config::Config() : BaseServiceConfig(true) {} + +Config::Config(const Config& process_service) + : BaseServiceConfig(process_service.enabled()) {} + +} // socks +} // services +} // ssf \ No newline at end of file diff --git a/src/services/socks/config.h b/src/services/socks/config.h new file mode 100644 index 00000000..971dff6a --- /dev/null +++ b/src/services/socks/config.h @@ -0,0 +1,22 @@ +#ifndef SSF_SERVICES_SOCKS_CONFIG_H_ +#define SSF_SERVICES_SOCKS_CONFIG_H_ + +#include + +#include "services/base_service_config.h" + +namespace ssf { +namespace services { +namespace socks { + +class Config : public BaseServiceConfig { + public: + Config(); + Config(const Config& process_service); +}; + +} // socks +} // services +} // ssf + +#endif // SSF_SERVICES_SOCKS_CONFIG_H_ \ No newline at end of file diff --git a/src/services/socks/socks_server.h b/src/services/socks/socks_server.h index 387d02cb..447dfaa1 100644 --- a/src/services/socks/socks_server.h +++ b/src/services/socks/socks_server.h @@ -19,6 +19,8 @@ #include "services/admin/requests/create_service_request.h" +#include "services/socks/config.h" + namespace ssf { namespace services { namespace socks { @@ -56,7 +58,12 @@ class SocksServer : public BaseService { /// Function used to register the micro service to the given factory static void RegisterToServiceFactory( - std::shared_ptr> p_factory) { + std::shared_ptr> p_factory, const Config& config) { + if (!config.enabled()) { + // service factory is not enabled + return; + } + p_factory->RegisterServiceCreator(factory_id, &SocksServer::create); } diff --git a/src/tests/config/CMakeLists.txt b/src/tests/config/CMakeLists.txt index ad293c2b..a5ea9bc5 100644 --- a/src/tests/config/CMakeLists.txt +++ b/src/tests/config/CMakeLists.txt @@ -1,15 +1,15 @@ cmake_minimum_required(VERSION 2.8) -set(config_tests_group_name "Unit Tests/Config") +set(config_tests_group_name "Unit Tests/Config") set(project_BINARY_CONFIG_TESTS_DIR "${project_BINARY_DIR}/src/tests/config") - + # --- copy test config files set(project_BINARY_CONFIG_TESTS_CONF_DIR ${project_BINARY_CONFIG_TESTS_DIR}/config_files) file(GLOB_RECURSE CONFIG_TEST_FILES "${CMAKE_CURRENT_SOURCE_DIR}/config_files/*.json") - + file(MAKE_DIRECTORY ${project_BINARY_CONFIG_TESTS_CONF_DIR}) file(COPY ${CONFIG_TEST_FILES} DESTINATION ${project_BINARY_CONFIG_TESTS_CONF_DIR}) @@ -21,6 +21,7 @@ set(load_config_test_source_files "load_config_tests.cpp" ${COMMON_CONFIG_FILES} ${COMMON_ERROR_FILES} + ${SERVICES_FILES} ) add_target("load_config_tests" @@ -36,4 +37,4 @@ add_target("load_config_tests" FILES ${load_config_test_source_files} ) -project_group(${config_tests_group_name} load_config_tests) \ No newline at end of file +project_group(${config_tests_group_name} load_config_tests) diff --git a/src/tests/config/config_files/services.json b/src/tests/config/config_files/services.json index 560c8fd3..95cc1ac2 100644 --- a/src/tests/config/config_files/services.json +++ b/src/tests/config/config_files/services.json @@ -1,10 +1,17 @@ { "ssf": { "services" : { + "datagram_forwarder": { "enable": false }, + "datagram_listener": { "enable": false }, + "stream_forwarder": { "enable": false }, + "stream_listener": { "enable": false }, + "file_copy": { "enable": true }, "shell": { + "enable": true, "path": "/bin/custom_path", "args": "-custom args" - } + }, + "socks": { "enable": false } } } } diff --git a/src/tests/config/load_config_tests.cpp b/src/tests/config/load_config_tests.cpp index daa05d3c..6af0ba8f 100644 --- a/src/tests/config/load_config_tests.cpp +++ b/src/tests/config/load_config_tests.cpp @@ -9,6 +9,9 @@ #include "common/config/config.h" class LoadConfigTest : public ::testing::Test { + public: + virtual void SetUp() { config_.Init(); } + protected: ssf::config::Config config_; }; @@ -16,14 +19,15 @@ class LoadConfigTest : public ::testing::Test { TEST_F(LoadConfigTest, LoadNoFileTest) { boost::system::error_code ec; - config_.Update("", ec); + config_.UpdateFromFile("", ec); ASSERT_EQ(ec.value(), 0) << "Success if no file given"; } TEST_F(LoadConfigTest, LoadNonExistantFileTest) { boost::system::error_code ec; - config_.Update("./config_files/unknown.json", ec); + + config_.UpdateFromFile("./config_files/unknown.json", ec); ASSERT_NE(ec.value(), 0) << "No success if file not existant"; } @@ -31,7 +35,7 @@ TEST_F(LoadConfigTest, LoadNonExistantFileTest) { TEST_F(LoadConfigTest, LoadEmptyFileTest) { boost::system::error_code ec; - config_.Update("./config_files/empty.json", ec); + config_.UpdateFromFile("./config_files/empty.json", ec); ASSERT_NE(ec.value(), 0) << "No success if file empty"; } @@ -39,15 +43,43 @@ TEST_F(LoadConfigTest, LoadEmptyFileTest) { TEST_F(LoadConfigTest, LoadWrongFormatFileTest) { boost::system::error_code ec; - config_.Update("./config_files/wrong_format.json", ec); + config_.UpdateFromFile("./config_files/wrong_format.json", ec); ASSERT_NE(ec.value(), 0) << "No success if wrong file format"; } +TEST_F(LoadConfigTest, DefaultValueTest) { + ASSERT_EQ(config_.tls().ca_cert_path(), "./certs/trusted/ca.crt"); + ASSERT_EQ(config_.tls().cert_path(), "./certs/certificate.crt"); + ASSERT_EQ(config_.tls().key_path(), "./certs/private.key"); + ASSERT_EQ(config_.tls().key_password(), ""); + ASSERT_EQ(config_.tls().dh_path(), "./certs/dh4096.pem"); + ASSERT_EQ(config_.tls().cipher_alg(), "DHE-RSA-AES256-GCM-SHA384"); + ASSERT_EQ(config_.http_proxy().host(), ""); + ASSERT_EQ(config_.http_proxy().port(), ""); + ASSERT_EQ(config_.http_proxy().username(), ""); + ASSERT_EQ(config_.http_proxy().domain(), ""); + ASSERT_EQ(config_.http_proxy().password(), ""); + ASSERT_EQ(config_.http_proxy().reuse_kerb(), true); + ASSERT_EQ(config_.http_proxy().reuse_ntlm(), true); + + ASSERT_TRUE(config_.services().datagram_forwarder().enabled()); + ASSERT_TRUE(config_.services().datagram_listener().enabled()); + ASSERT_FALSE(config_.services().file_copy().enabled()); + ASSERT_TRUE(config_.services().socks().enabled()); + ASSERT_TRUE(config_.services().stream_forwarder().enabled()); + ASSERT_TRUE(config_.services().stream_listener().enabled()); + ASSERT_FALSE(config_.services().process().enabled()); + + ASSERT_GT(config_.services().process().path().length(), + static_cast(0)); + ASSERT_EQ(config_.services().process().args(), ""); +} + TEST_F(LoadConfigTest, LoadTlsPartialFileTest) { boost::system::error_code ec; - config_.Update("./config_files/tls_partial.json", ec); + config_.UpdateFromFile("./config_files/tls_partial.json", ec); ASSERT_EQ(ec.value(), 0) << "Success if partial file format"; ASSERT_EQ(config_.tls().ca_cert_path(), "test_ca_path"); @@ -61,7 +93,7 @@ TEST_F(LoadConfigTest, LoadTlsPartialFileTest) { TEST_F(LoadConfigTest, LoadTlsCompleteFileTest) { boost::system::error_code ec; - config_.Update("./config_files/tls_complete.json", ec); + config_.UpdateFromFile("./config_files/tls_complete.json", ec); ASSERT_EQ(ec.value(), 0) << "Success if complete file format"; ASSERT_EQ(config_.tls().ca_cert_path(), "test_ca_path"); @@ -77,15 +109,24 @@ TEST_F(LoadConfigTest, LoadTlsCompleteFileTest) { ASSERT_EQ(config_.http_proxy().password(), ""); ASSERT_EQ(config_.http_proxy().reuse_kerb(), true); ASSERT_EQ(config_.http_proxy().reuse_ntlm(), true); - ASSERT_EQ(config_.services().process().path(), - SSF_PROCESS_SERVICE_BINARY_PATH); + + ASSERT_TRUE(config_.services().datagram_forwarder().enabled()); + ASSERT_TRUE(config_.services().datagram_listener().enabled()); + ASSERT_FALSE(config_.services().file_copy().enabled()); + ASSERT_TRUE(config_.services().socks().enabled()); + ASSERT_TRUE(config_.services().stream_forwarder().enabled()); + ASSERT_TRUE(config_.services().stream_listener().enabled()); + ASSERT_FALSE(config_.services().process().enabled()); + + ASSERT_GT(config_.services().process().path().length(), + static_cast(0)); ASSERT_EQ(config_.services().process().args(), ""); } TEST_F(LoadConfigTest, LoadProxyFileTest) { boost::system::error_code ec; - config_.Update("./config_files/proxy.json", ec); + config_.UpdateFromFile("./config_files/proxy.json", ec); ASSERT_EQ(ec.value(), 0) << "Success if complete file format"; ASSERT_EQ(config_.http_proxy().host(), "127.0.0.1"); ASSERT_EQ(config_.http_proxy().port(), "8080"); @@ -99,9 +140,17 @@ TEST_F(LoadConfigTest, LoadProxyFileTest) { TEST_F(LoadConfigTest, LoadServicesFileTest) { boost::system::error_code ec; - config_.Update("./config_files/services.json", ec); + config_.UpdateFromFile("./config_files/services.json", ec); ASSERT_EQ(ec.value(), 0) << "Success if complete file format"; + ASSERT_FALSE(config_.services().datagram_forwarder().enabled()); + ASSERT_FALSE(config_.services().datagram_listener().enabled()); + ASSERT_TRUE(config_.services().file_copy().enabled()); + ASSERT_FALSE(config_.services().socks().enabled()); + ASSERT_FALSE(config_.services().stream_forwarder().enabled()); + ASSERT_FALSE(config_.services().stream_listener().enabled()); + ASSERT_TRUE(config_.services().process().enabled()); + ASSERT_EQ(config_.services().process().path(), "/bin/custom_path"); ASSERT_EQ(config_.services().process().args(), "-custom args"); } @@ -109,7 +158,7 @@ TEST_F(LoadConfigTest, LoadServicesFileTest) { TEST_F(LoadConfigTest, LoadCompleteFileTest) { boost::system::error_code ec; - config_.Update("./config_files/complete.json", ec); + config_.UpdateFromFile("./config_files/complete.json", ec); ASSERT_EQ(ec.value(), 0) << "Success if complete file format"; ASSERT_EQ(config_.tls().ca_cert_path(), "test_ca_path"); diff --git a/src/tests/network/ssf_client_server_cipher_suites_tests.cpp b/src/tests/network/ssf_client_server_cipher_suites_tests.cpp index 64e5af65..f849a510 100644 --- a/src/tests/network/ssf_client_server_cipher_suites_tests.cpp +++ b/src/tests/network/ssf_client_server_cipher_suites_tests.cpp @@ -61,7 +61,8 @@ class SSFClientServerCipherSuitesTest : public ::testing::Test { auto endpoint_query = NetworkProtocol::GenerateClientTLSQuery( "127.0.0.1", "8000", config, {}); - p_ssf_client_.reset(new Client(client_options, config.services(), callback)); + p_ssf_client_.reset( + new Client(client_options, config.services(), callback)); boost::system::error_code run_ec; p_ssf_client_->Run(endpoint_query, run_ec); @@ -92,7 +93,21 @@ TEST_F(SSFClientServerCipherSuitesTest, connectDisconnectDifferentSuite) { }; ssf::config::Config client_config; ssf::config::Config server_config; - server_config.tls().set_cipher_alg("DHE-RSA-AES256-GCM-SHA256"); + boost::system::error_code ec; + + const char* new_config = R"RAWSTRING( +{ + "ssf": { + "tls" : { + "cipher_alg": "DHE-RSA-AES256-GCM-SHA256" + } + } +} +)RAWSTRING"; + + server_config.UpdateFromString(new_config, ec); + ASSERT_EQ(ec.value(), 0) << "Could not update server config from string " + << new_config; StartServer(server_config); StartClient(client_config, callback); @@ -126,11 +141,33 @@ TEST_F(SSFClientServerCipherSuitesTest, connectDisconnectTwoSuites) { }; ssf::config::Config client_config; ssf::config::Config server_config; - - client_config.tls().set_cipher_alg( - "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-SHA256^"); - server_config.tls().set_cipher_alg( - "ECDH-ECDSA-AES128-SHA256:DHE-RSA-AES128-SHA256"); + boost::system::error_code ec; + const char* new_client_config = R"RAWSTRING( +{ + "ssf": { + "tls" : { + "cipher_alg": "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-SHA256" + } + } +} +)RAWSTRING"; + + const char* new_server_config = R"RAWSTRING( +{ + "ssf": { + "tls" : { + "cipher_alg": "ECDH-ECDSA-AES128-SHA256:DHE-RSA-AES128-SHA256" + } + } +} +)RAWSTRING"; + + client_config.UpdateFromString(new_client_config, ec); + ASSERT_EQ(ec.value(), 0) << "Could not update client config from string " + << new_client_config; + server_config.UpdateFromString(new_server_config, ec); + ASSERT_EQ(ec.value(), 0) << "Could not update server config from string " + << new_server_config; StartServer(server_config); StartClient(client_config, callback); diff --git a/src/tests/services/file_copy_fixture_test.cpp b/src/tests/services/file_copy_fixture_test.cpp index 61997684..1e3acc29 100644 --- a/src/tests/services/file_copy_fixture_test.cpp +++ b/src/tests/services/file_copy_fixture_test.cpp @@ -31,6 +31,21 @@ void FileCopyTestFixture::TearDown() { void FileCopyTestFixture::StartServer() { ssf::config::Config ssf_config; + boost::system::error_code ec; + + const char* new_config = R"RAWSTRING( +{ + "ssf": { + "services" : { + "file_copy": { "enable": true } + } + } +} +)RAWSTRING"; + + ssf_config.UpdateFromString(new_config, ec); + ASSERT_EQ(ec.value(), 0) << "Could not update server config from string " + << new_config; auto endpoint_query = NetworkProtocol::GenerateServerQuery("", "8000", ssf_config); @@ -53,6 +68,20 @@ void FileCopyTestFixture::StartClient() { ssf::config::Config ssf_config; + const char* new_config = R"RAWSTRING( +{ + "ssf": { + "services" : { + "file_copy": { "enable": true } + } + } +} +)RAWSTRING"; + + ssf_config.UpdateFromString(new_config, ec); + ASSERT_EQ(ec.value(), 0) << "Could not update server config from string " + << new_config; + auto endpoint_query = NetworkProtocol::GenerateClientQuery("127.0.0.1", "8000", ssf_config, {}); diff --git a/src/tests/services/file_copy_from_client_tests.cpp b/src/tests/services/file_copy_from_client_tests.cpp index 9af59ff9..0ae49352 100644 --- a/src/tests/services/file_copy_from_client_tests.cpp +++ b/src/tests/services/file_copy_from_client_tests.cpp @@ -55,7 +55,6 @@ void FileExistsAndIdentical(const std::string& source_filepath, << " are different"; } -//----------------------------------------------------------------------------- TEST_F(CopyNoFileFromClientToRemoteTest, CopyTest) { ASSERT_TRUE(Wait()); @@ -67,7 +66,6 @@ TEST_F(CopyNoFileFromClientToRemoteTest, CopyTest) { << "The file test_filex.txt should not exist in files_copied"; } -//----------------------------------------------------------------------------- TEST_F(CopyUniqueFileFromClientToRemoteTest, CopyTest) { ASSERT_TRUE(Wait()); @@ -77,7 +75,6 @@ TEST_F(CopyUniqueFileFromClientToRemoteTest, CopyTest) { "files_copied/test_file1.txt"); } -//----------------------------------------------------------------------------- TEST_F(CopyGlobFileFromClientToRemoteTest, CopyTest) { ASSERT_TRUE(Wait()); @@ -89,7 +86,6 @@ TEST_F(CopyGlobFileFromClientToRemoteTest, CopyTest) { "files_copied/test_file2.txt"); } -//----------------------------------------------------------------------------- TEST_F(CopyUniqueFileFromRemoteToClientTest, CopyTest) { ASSERT_TRUE(Wait()); @@ -99,7 +95,6 @@ TEST_F(CopyUniqueFileFromRemoteToClientTest, CopyTest) { "files_copied/test_file1.txt"); } -//----------------------------------------------------------------------------- TEST_F(CopyGlobFileFromRemoteToClientTest, CopyTest) { ASSERT_TRUE(Wait()); @@ -111,7 +106,6 @@ TEST_F(CopyGlobFileFromRemoteToClientTest, CopyTest) { "files_copied/test_file2.txt"); } -//----------------------------------------------------------------------------- TEST_F(CopyStdinFromClientToRemoteTest, CopyTest) { // stdin as test_file1.txt filebuf std::ifstream in("files_to_copy/test_file1.txt", std::ifstream::binary); diff --git a/src/tests/services/process_fixture_test.h b/src/tests/services/process_fixture_test.h index ef691e79..05c0a3f3 100644 --- a/src/tests/services/process_fixture_test.h +++ b/src/tests/services/process_fixture_test.h @@ -16,7 +16,8 @@ template