Remove tls rpc
This commit is contained in:
parent
51430f15e2
commit
f02cee1da8
19 changed files with 8 additions and 590 deletions
|
|
@ -1,6 +1,5 @@
|
|||
#include <nano/lib/jsonconfig.hpp>
|
||||
#include <nano/lib/rpcconfig.hpp>
|
||||
#include <nano/lib/tlsconfig.hpp>
|
||||
#include <nano/lib/tomlconfig.hpp>
|
||||
#include <nano/node/daemonconfig.hpp>
|
||||
#include <nano/secure/utility.hpp>
|
||||
|
|
@ -943,64 +942,6 @@ TEST (toml, daemon_read_config)
|
|||
}
|
||||
}
|
||||
|
||||
/** Deserialize an tls config with non-default values */
|
||||
TEST (toml, tls_config_deserialize_no_defaults)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
// A config file with values that differs from devnet defaults
|
||||
ss << R"toml(
|
||||
enable_https=true
|
||||
enable_wss=true
|
||||
verbose_logging=true
|
||||
server_cert_path="xyz.cert.pem"
|
||||
server_key_path="xyz.key.pem"
|
||||
server_key_passphrase="xyz"
|
||||
server_dh_path="xyz.pem"
|
||||
)toml";
|
||||
|
||||
nano::tomlconfig toml;
|
||||
toml.read (ss);
|
||||
nano::tls_config conf;
|
||||
nano::tls_config defaults;
|
||||
conf.deserialize_toml (toml);
|
||||
|
||||
ASSERT_FALSE (toml.get_error ()) << toml.get_error ().get_message ();
|
||||
|
||||
ASSERT_NE (conf.enable_https, defaults.enable_https);
|
||||
ASSERT_NE (conf.enable_wss, defaults.enable_wss);
|
||||
ASSERT_NE (conf.verbose_logging, defaults.verbose_logging);
|
||||
ASSERT_NE (conf.server_cert_path, defaults.server_cert_path);
|
||||
ASSERT_NE (conf.server_key_path, defaults.server_key_path);
|
||||
ASSERT_NE (conf.server_key_passphrase, defaults.server_key_passphrase);
|
||||
ASSERT_NE (conf.server_dh_path, defaults.server_dh_path);
|
||||
}
|
||||
|
||||
/** Empty tls config file should match a default config object, and there should be no required values. */
|
||||
TEST (toml, tls_config_defaults)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
// A config with no values
|
||||
ss << R"toml()toml";
|
||||
|
||||
nano::tomlconfig toml;
|
||||
toml.read (ss);
|
||||
nano::tls_config conf;
|
||||
nano::tls_config defaults;
|
||||
conf.deserialize_toml (toml);
|
||||
|
||||
ASSERT_FALSE (toml.get_error ()) << toml.get_error ().get_message ();
|
||||
|
||||
ASSERT_EQ (conf.enable_https, defaults.enable_wss);
|
||||
ASSERT_EQ (conf.enable_wss, defaults.enable_wss);
|
||||
ASSERT_EQ (conf.verbose_logging, defaults.verbose_logging);
|
||||
ASSERT_EQ (conf.server_cert_path, defaults.server_cert_path);
|
||||
ASSERT_EQ (conf.server_key_path, defaults.server_key_path);
|
||||
ASSERT_EQ (conf.server_key_passphrase, defaults.server_key_passphrase);
|
||||
ASSERT_EQ (conf.server_dh_path, defaults.server_dh_path);
|
||||
}
|
||||
|
||||
TEST (toml, log_config_defaults)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
|
|
|||
|
|
@ -99,8 +99,6 @@ add_library(
|
|||
threading.cpp
|
||||
timer.hpp
|
||||
timer.cpp
|
||||
tlsconfig.hpp
|
||||
tlsconfig.cpp
|
||||
tomlconfig.hpp
|
||||
tomlconfig.cpp
|
||||
uniquer.hpp
|
||||
|
|
|
|||
|
|
@ -5,30 +5,6 @@
|
|||
|
||||
#include <boost/dll/runtime_symbol_info.hpp>
|
||||
|
||||
nano::error nano::rpc_secure_config::serialize_toml (nano::tomlconfig & toml) const
|
||||
{
|
||||
toml.put ("enable", enable, "Enable or disable TLS support.\ntype:bool");
|
||||
toml.put ("verbose_logging", verbose_logging, "Enable or disable verbose logging.\ntype:bool");
|
||||
toml.put ("server_key_passphrase", server_key_passphrase, "Server key passphrase.\ntype:string");
|
||||
toml.put ("server_cert_path", server_cert_path, "Directory containing certificates.\ntype:string,path");
|
||||
toml.put ("server_key_path", server_key_path, "Path to server key PEM file.\ntype:string,path");
|
||||
toml.put ("server_dh_path", server_dh_path, "Path to Diffie-Hellman params file.\ntype:string,path");
|
||||
toml.put ("client_certs_path", client_certs_path, "Directory containing client certificates.\ntype:string");
|
||||
return toml.get_error ();
|
||||
}
|
||||
|
||||
nano::error nano::rpc_secure_config::deserialize_toml (nano::tomlconfig & toml)
|
||||
{
|
||||
toml.get<bool> ("enable", enable);
|
||||
toml.get<bool> ("verbose_logging", verbose_logging);
|
||||
toml.get<std::string> ("server_key_passphrase", server_key_passphrase);
|
||||
toml.get<std::string> ("server_cert_path", server_cert_path);
|
||||
toml.get<std::string> ("server_key_path", server_key_path);
|
||||
toml.get<std::string> ("server_dh_path", server_dh_path);
|
||||
toml.get<std::string> ("client_certs_path", client_certs_path);
|
||||
return toml.get_error ();
|
||||
}
|
||||
|
||||
nano::rpc_config::rpc_config (nano::network_constants & network_constants) :
|
||||
rpc_process{ network_constants },
|
||||
address{ boost::asio::ip::address_v6::loopback ().to_string () }
|
||||
|
|
@ -68,12 +44,6 @@ nano::error nano::rpc_config::deserialize_toml (nano::tomlconfig & toml)
|
|||
{
|
||||
if (!toml.empty ())
|
||||
{
|
||||
auto rpc_secure_l (toml.get_optional_child ("secure"));
|
||||
if (rpc_secure_l)
|
||||
{
|
||||
return nano::error ("The RPC secure configuration has moved to config-tls.toml. Please update the configuration.");
|
||||
}
|
||||
|
||||
boost::asio::ip::address_v6 address_l;
|
||||
toml.get_optional<boost::asio::ip::address_v6> ("address", address_l, boost::asio::ip::address_v6::loopback ());
|
||||
address = address_l.to_string ();
|
||||
|
|
|
|||
|
|
@ -13,34 +13,6 @@
|
|||
namespace nano
|
||||
{
|
||||
class tomlconfig;
|
||||
class tls_config;
|
||||
|
||||
/**
|
||||
* Configuration options for RPC TLS.
|
||||
* @note This is deprecated, but kept for a few versions in order to yield a config error message on startup if it's used.
|
||||
*/
|
||||
class rpc_secure_config final
|
||||
{
|
||||
public:
|
||||
nano::error serialize_toml (nano::tomlconfig &) const;
|
||||
nano::error deserialize_toml (nano::tomlconfig &);
|
||||
|
||||
private:
|
||||
/** If true, enable TLS */
|
||||
bool enable{ false };
|
||||
/** If true, log certificate verification details */
|
||||
bool verbose_logging{ false };
|
||||
/** Must be set if the private key PEM is password protected */
|
||||
std::string server_key_passphrase;
|
||||
/** Path to certificate- or chain file. Must be PEM formatted. */
|
||||
std::string server_cert_path;
|
||||
/** Path to private key file. Must be PEM formatted.*/
|
||||
std::string server_key_path;
|
||||
/** Path to dhparam file */
|
||||
std::string server_dh_path;
|
||||
/** Optional path to directory containing client certificates */
|
||||
std::string client_certs_path;
|
||||
};
|
||||
|
||||
class rpc_process_config final
|
||||
{
|
||||
|
|
@ -72,12 +44,9 @@ public:
|
|||
std::string address;
|
||||
uint16_t port{ rpc_process.network_constants.default_rpc_port };
|
||||
bool enable_control{ false };
|
||||
rpc_secure_config secure;
|
||||
uint8_t max_json_depth{ 20 };
|
||||
uint64_t max_request_size{ 32 * 1024 * 1024 };
|
||||
nano::rpc_logging_config rpc_logging;
|
||||
/** Optional TLS config */
|
||||
std::shared_ptr<nano::tls_config> tls_config;
|
||||
};
|
||||
|
||||
nano::error read_rpc_config_toml (std::filesystem::path const & data_path_a, nano::rpc_config & config_a, std::vector<std::string> const & config_overrides = std::vector<std::string> ());
|
||||
|
|
|
|||
|
|
@ -1,186 +0,0 @@
|
|||
#include <nano/lib/config.hpp>
|
||||
#include <nano/lib/logging.hpp>
|
||||
#include <nano/lib/tlsconfig.hpp>
|
||||
#include <nano/lib/tomlconfig.hpp>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace nano
|
||||
{
|
||||
nano::error nano::tls_config::serialize_toml (nano::tomlconfig & toml) const
|
||||
{
|
||||
toml.put ("enable_https", enable_https, "Enable or disable https:// support.\ntype:bool");
|
||||
toml.put ("enable_wss", enable_wss, "Enable or disable wss:// support.\ntype:bool");
|
||||
toml.put ("verbose_logging", verbose_logging, "Enable or disable verbose TLS logging.\ntype:bool");
|
||||
toml.put ("server_key_passphrase", server_key_passphrase, "Server key passphrase.\ntype:string");
|
||||
toml.put ("server_cert_path", server_cert_path, "Directory containing certificates.\ntype:string,path");
|
||||
toml.put ("server_key_path", server_key_path, "Path to server key PEM file.\ntype:string,path");
|
||||
toml.put ("server_dh_path", server_dh_path, "Path to Diffie-Hellman params file.\ntype:string,path");
|
||||
toml.put ("client_certs_path", client_certs_path, "Directory containing optional client certificates.\ntype:string,path");
|
||||
return toml.get_error ();
|
||||
}
|
||||
|
||||
nano::error nano::tls_config::deserialize_toml (nano::tomlconfig & toml)
|
||||
{
|
||||
toml.get<bool> ("enable_https", enable_https);
|
||||
toml.get<bool> ("enable_wss", enable_wss);
|
||||
toml.get<bool> ("verbose_logging", verbose_logging);
|
||||
toml.get<std::string> ("server_key_passphrase", server_key_passphrase);
|
||||
toml.get<std::string> ("server_cert_path", server_cert_path);
|
||||
toml.get<std::string> ("server_key_path", server_key_path);
|
||||
toml.get<std::string> ("server_dh_path", server_dh_path);
|
||||
toml.get<std::string> ("client_certs_path", client_certs_path);
|
||||
return toml.get_error ();
|
||||
}
|
||||
|
||||
#ifdef NANO_SECURE_RPC
|
||||
namespace
|
||||
{
|
||||
bool on_verify_certificate (bool preverified, boost::asio::ssl::verify_context & ctx, nano::tls_config & config_a, nano::logger_mt & logger_a)
|
||||
{
|
||||
X509_STORE_CTX * cts = ctx.native_handle ();
|
||||
auto error (X509_STORE_CTX_get_error (cts));
|
||||
switch (error)
|
||||
{
|
||||
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
|
||||
logger_a.always_log ("TLS: Unable to get issuer");
|
||||
break;
|
||||
case X509_V_ERR_CERT_NOT_YET_VALID:
|
||||
case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
|
||||
logger_a.always_log ("TLS: Certificate not yet valid");
|
||||
break;
|
||||
case X509_V_ERR_CERT_HAS_EXPIRED:
|
||||
case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
|
||||
logger_a.always_log ("TLS: Certificate expired");
|
||||
break;
|
||||
case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
|
||||
if (config_a.verbose_logging)
|
||||
{
|
||||
logger_a.always_log ("TLS: Self-signed certificate in chain");
|
||||
}
|
||||
|
||||
// Allow self-signed certificates
|
||||
preverified = true;
|
||||
break;
|
||||
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
|
||||
logger_a.always_log ("TLS: Self-signed certificate not in the list of trusted certs (forgot to subject-hash certificate filename?)");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (config_a.verbose_logging)
|
||||
{
|
||||
if (error != 0)
|
||||
{
|
||||
logger_a.always_log ("TLS: Error: ", X509_verify_cert_error_string (error));
|
||||
logger_a.always_log ("TLS: Error chain depth : ", X509_STORE_CTX_get_error_depth (cts));
|
||||
}
|
||||
|
||||
X509 * cert = X509_STORE_CTX_get_current_cert (cts);
|
||||
char subject_name[512];
|
||||
X509_NAME_oneline (X509_get_subject_name (cert), subject_name, sizeof (subject_name) - 1);
|
||||
logger_a.always_log ("TLS: Verifying: ", subject_name);
|
||||
logger_a.always_log ("TLS: Verification: ", preverified);
|
||||
}
|
||||
else if (!preverified)
|
||||
{
|
||||
logger_a.always_log ("TLS: Pre-verification failed. Turn on verbose logging for more information.");
|
||||
}
|
||||
|
||||
return preverified;
|
||||
}
|
||||
|
||||
void load_certs (nano::tls_config & config_a, nano::logger_mt & logger_a)
|
||||
{
|
||||
try
|
||||
{
|
||||
// This is called if the key is password protected
|
||||
config_a.ssl_context.set_password_callback (
|
||||
[&config_a] (std::size_t,
|
||||
boost::asio::ssl::context_base::password_purpose) {
|
||||
return config_a.server_key_passphrase;
|
||||
});
|
||||
|
||||
// The following two options disables the session cache and enables stateless session resumption.
|
||||
// This is necessary because of the way the RPC server abruptly terminate connections.
|
||||
SSL_CTX_set_session_cache_mode (config_a.ssl_context.native_handle (), SSL_SESS_CACHE_OFF);
|
||||
SSL_CTX_set_options (config_a.ssl_context.native_handle (), SSL_OP_NO_TICKET);
|
||||
|
||||
config_a.ssl_context.set_options (
|
||||
boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::no_sslv3 | boost::asio::ssl::context::single_dh_use);
|
||||
|
||||
config_a.ssl_context.use_certificate_chain_file (config_a.server_cert_path);
|
||||
config_a.ssl_context.use_private_key_file (config_a.server_key_path, boost::asio::ssl::context::pem);
|
||||
config_a.ssl_context.use_tmp_dh_file (config_a.server_dh_path);
|
||||
|
||||
// Verify client certificates?
|
||||
if (!config_a.client_certs_path.empty ())
|
||||
{
|
||||
config_a.ssl_context.set_verify_mode (boost::asio::ssl::verify_fail_if_no_peer_cert | boost::asio::ssl::verify_peer);
|
||||
config_a.ssl_context.add_verify_path (config_a.client_certs_path);
|
||||
config_a.ssl_context.set_verify_callback ([&config_a, &logger_a] (auto preverified, auto & ctx) {
|
||||
return on_verify_certificate (preverified, ctx, config_a, logger_a);
|
||||
});
|
||||
}
|
||||
|
||||
logger_a.always_log ("TLS: successfully configured");
|
||||
}
|
||||
catch (boost::system::system_error const & err)
|
||||
{
|
||||
auto error (boost::str (boost::format ("Could not load certificate information: %1%. Make sure the paths and the passphrase in config-tls.toml are correct.") % err.what ()));
|
||||
std::cerr << error << std::endl;
|
||||
logger_a.always_log (error);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
nano::error read_tls_config_toml (std::filesystem::path const & data_path_a, nano::tls_config & config_a, nano::logger & logger, std::vector<std::string> const & config_overrides)
|
||||
{
|
||||
nano::error error;
|
||||
auto toml_config_path = nano::get_tls_toml_config_path (data_path_a);
|
||||
|
||||
// Parse and deserialize
|
||||
nano::tomlconfig toml;
|
||||
|
||||
std::stringstream config_overrides_stream;
|
||||
for (auto const & entry : config_overrides)
|
||||
{
|
||||
config_overrides_stream << entry << std::endl;
|
||||
}
|
||||
config_overrides_stream << std::endl;
|
||||
|
||||
// Make sure we don't create an empty toml file if it doesn't exist. Running without a tls toml file is the default.
|
||||
if (!error)
|
||||
{
|
||||
if (std::filesystem::exists (toml_config_path))
|
||||
{
|
||||
error = toml.read (config_overrides_stream, toml_config_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
error = toml.read (config_overrides_stream);
|
||||
}
|
||||
}
|
||||
|
||||
if (!error)
|
||||
{
|
||||
error = config_a.deserialize_toml (toml);
|
||||
}
|
||||
|
||||
if (!error && (config_a.enable_https || config_a.enable_wss))
|
||||
{
|
||||
#ifdef NANO_SECURE_RPC
|
||||
load_certs (config_a, logger_a);
|
||||
#else
|
||||
logger.critical (nano::log::type::tls, "HTTPS or WSS is enabled in the TLS configuration, but the node is not built with NANO_SECURE_RPC");
|
||||
std::exit (1);
|
||||
#endif
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <nano/lib/config.hpp>
|
||||
#include <nano/lib/errors.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#ifdef NANO_SECURE_RPC
|
||||
#include <boost/asio/ssl/context.hpp>
|
||||
#endif
|
||||
|
||||
namespace nano
|
||||
{
|
||||
class logger;
|
||||
class jsonconfig;
|
||||
class tomlconfig;
|
||||
|
||||
/** Configuration options for secure RPC and WebSocket connections */
|
||||
class tls_config final
|
||||
{
|
||||
public:
|
||||
nano::error serialize_toml (nano::tomlconfig &) const;
|
||||
nano::error deserialize_toml (nano::tomlconfig &);
|
||||
|
||||
/** If true, enable TLS for RPC (only allow https, otherwise only allow http) */
|
||||
bool enable_https{ false };
|
||||
|
||||
/** If true, enable TLS for WebSocket (only allow wss, otherwise only allow ws) */
|
||||
bool enable_wss{ false };
|
||||
|
||||
/** If true, log certificate verification details */
|
||||
bool verbose_logging{ false };
|
||||
|
||||
/** Must be set if the private key PEM is password protected */
|
||||
std::string server_key_passphrase;
|
||||
|
||||
/** Path to certificate- or chain file. Must be PEM formatted. */
|
||||
std::string server_cert_path;
|
||||
|
||||
/** Path to private key file. Must be PEM formatted.*/
|
||||
std::string server_key_path;
|
||||
|
||||
/** Path to dhparam file */
|
||||
std::string server_dh_path;
|
||||
|
||||
/** Optional path to directory containing client certificates */
|
||||
std::string client_certs_path;
|
||||
|
||||
#ifdef NANO_SECURE_RPC
|
||||
/** The context needs to be shared between sessions to make resumption work */
|
||||
boost::asio::ssl::context ssl_context{ boost::asio::ssl::context::tlsv12_server };
|
||||
#endif
|
||||
};
|
||||
|
||||
nano::error read_tls_config_toml (std::filesystem::path const & data_path_a, nano::tls_config & config_a, nano::logger &, std::vector<std::string> const & config_overrides = std::vector<std::string> ());
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@
|
|||
#include <nano/lib/stacktrace.hpp>
|
||||
#include <nano/lib/thread_runner.hpp>
|
||||
#include <nano/lib/threading.hpp>
|
||||
#include <nano/lib/tlsconfig.hpp>
|
||||
#include <nano/lib/utility.hpp>
|
||||
#include <nano/nano_node/daemon.hpp>
|
||||
#include <nano/node/cli.hpp>
|
||||
|
|
@ -85,18 +84,6 @@ void nano::daemon::run (std::filesystem::path const & data_path, nano::node_flag
|
|||
}
|
||||
if (!error)
|
||||
{
|
||||
auto tls_config (std::make_shared<nano::tls_config> ());
|
||||
error = nano::read_tls_config_toml (data_path, *tls_config, logger);
|
||||
if (error)
|
||||
{
|
||||
std::cerr << error.get_message () << std::endl;
|
||||
std::exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
config.node.websocket_config.tls_config = tls_config;
|
||||
}
|
||||
|
||||
std::shared_ptr<boost::asio::io_context> io_ctx = std::make_shared<boost::asio::io_context> ();
|
||||
|
||||
auto opencl = nano::opencl_work::create (config.opencl_enable, config.opencl, logger, config.node.network_params.work);
|
||||
|
|
@ -176,7 +163,6 @@ void nano::daemon::run (std::filesystem::path const & data_path, nano::node_flag
|
|||
std::exit (1);
|
||||
}
|
||||
|
||||
rpc_config.tls_config = tls_config;
|
||||
rpc_handler = std::make_unique<nano::inprocess_rpc_handler> (*node, *ipc_server, config.rpc, stop_callback);
|
||||
rpc = nano::get_rpc (io_ctx, rpc_config, *rpc_handler);
|
||||
rpc->start ();
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
#include <nano/lib/signal_manager.hpp>
|
||||
#include <nano/lib/thread_runner.hpp>
|
||||
#include <nano/lib/threading.hpp>
|
||||
#include <nano/lib/tlsconfig.hpp>
|
||||
#include <nano/lib/utility.hpp>
|
||||
#include <nano/node/cli.hpp>
|
||||
#include <nano/node/ipc/ipc_server.hpp>
|
||||
|
|
@ -37,18 +36,6 @@ void run (std::filesystem::path const & data_path, std::vector<std::string> cons
|
|||
auto error = nano::read_rpc_config_toml (data_path, rpc_config, config_overrides);
|
||||
if (!error)
|
||||
{
|
||||
auto tls_config (std::make_shared<nano::tls_config> ());
|
||||
error = nano::read_tls_config_toml (data_path, *tls_config, logger);
|
||||
if (error)
|
||||
{
|
||||
logger.critical (nano::log::type::daemon_rpc, "Error reading RPC TLS config: {}", error.get_message ());
|
||||
std::exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
rpc_config.tls_config = tls_config;
|
||||
}
|
||||
|
||||
std::shared_ptr<boost::asio::io_context> io_ctx = std::make_shared<boost::asio::io_context> ();
|
||||
|
||||
runner = std::make_unique<nano::thread_runner> (io_ctx, logger, rpc_config.rpc_process.io_threads, nano::thread_role::name::io_daemon);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
#include <nano/lib/logging.hpp>
|
||||
#include <nano/lib/rpcconfig.hpp>
|
||||
#include <nano/lib/thread_runner.hpp>
|
||||
#include <nano/lib/tlsconfig.hpp>
|
||||
#include <nano/lib/tomlconfig.hpp>
|
||||
#include <nano/lib/utility.hpp>
|
||||
#include <nano/lib/walletconfig.hpp>
|
||||
|
|
@ -109,19 +108,6 @@ int run_wallet (QApplication & application, int argc, char * const * argv, std::
|
|||
{
|
||||
nano::set_use_memory_pools (config.node.use_memory_pools);
|
||||
|
||||
auto tls_config (std::make_shared<nano::tls_config> ());
|
||||
error = nano::read_tls_config_toml (data_path, *tls_config, logger);
|
||||
if (error)
|
||||
{
|
||||
splash->hide ();
|
||||
show_error (error.get_message ());
|
||||
std::exit (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
config.node.websocket_config.tls_config = tls_config;
|
||||
}
|
||||
|
||||
std::shared_ptr<boost::asio::io_context> io_ctx = std::make_shared<boost::asio::io_context> ();
|
||||
|
||||
nano::thread_runner runner (io_ctx, logger, config.node.io_threads, nano::thread_role::name::io_daemon);
|
||||
|
|
@ -190,7 +176,6 @@ int run_wallet (QApplication & application, int argc, char * const * argv, std::
|
|||
show_error (error.get_message ());
|
||||
std::exit (1);
|
||||
}
|
||||
rpc_config.tls_config = tls_config;
|
||||
rpc_handler = std::make_unique<nano::inprocess_rpc_handler> (*node, ipc, config.rpc);
|
||||
rpc = nano::get_rpc (io_ctx, rpc_config, *rpc_handler);
|
||||
rpc->start ();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#include <nano/lib/blocks.hpp>
|
||||
#include <nano/lib/cli.hpp>
|
||||
#include <nano/lib/tlsconfig.hpp>
|
||||
#include <nano/lib/tomlconfig.hpp>
|
||||
#include <nano/node/cli.hpp>
|
||||
#include <nano/node/common.hpp>
|
||||
|
|
@ -700,12 +699,6 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
|
|||
nano::log_config config = nano::log_config::sample_config ();
|
||||
config.serialize_toml (toml);
|
||||
}
|
||||
else if (type == "tls")
|
||||
{
|
||||
valid_type = true;
|
||||
nano::tls_config config;
|
||||
config.serialize_toml (toml);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Invalid configuration type " << type << ". Must be node or rpc." << std::endl;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
#include <nano/boost/asio/strand.hpp>
|
||||
#include <nano/lib/blocks.hpp>
|
||||
#include <nano/lib/logging.hpp>
|
||||
#include <nano/lib/tlsconfig.hpp>
|
||||
#include <nano/lib/work.hpp>
|
||||
#include <nano/node/election_status.hpp>
|
||||
#include <nano/node/node_observers.hpp>
|
||||
|
|
@ -578,8 +577,7 @@ void nano::websocket::listener::stop ()
|
|||
sessions.clear ();
|
||||
}
|
||||
|
||||
nano::websocket::listener::listener (std::shared_ptr<nano::tls_config> const & tls_config_a, nano::logger & logger_a, nano::wallets & wallets_a, boost::asio::io_context & io_ctx_a, boost::asio::ip::tcp::endpoint endpoint_a) :
|
||||
tls_config (tls_config_a),
|
||||
nano::websocket::listener::listener (nano::logger & logger_a, nano::wallets & wallets_a, boost::asio::io_context & io_ctx_a, boost::asio::ip::tcp::endpoint endpoint_a) :
|
||||
logger (logger_a),
|
||||
wallets (wallets_a),
|
||||
acceptor (io_ctx_a),
|
||||
|
|
@ -629,22 +627,15 @@ void nano::websocket::listener::on_accept (boost::system::error_code ec)
|
|||
{
|
||||
// Create the session and initiate websocket handshake
|
||||
std::shared_ptr<nano::websocket::session> session;
|
||||
if (tls_config && tls_config->enable_wss)
|
||||
{
|
||||
#ifdef NANO_SECURE_RPC
|
||||
session = std::make_shared<nano::websocket::session> (*this, std::move (socket), tls_config->ssl_context);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
session = std::make_shared<nano::websocket::session> (*this, std::move (socket), logger);
|
||||
}
|
||||
session = std::make_shared<nano::websocket::session> (*this, std::move (socket), logger);
|
||||
|
||||
// TODO: Why is this locking and unlocking mutex manually??
|
||||
sessions_mutex.lock ();
|
||||
sessions.push_back (session);
|
||||
// Clean up expired sessions
|
||||
sessions.erase (std::remove_if (sessions.begin (), sessions.end (), [] (auto & elem) { return elem.expired (); }), sessions.end ());
|
||||
sessions_mutex.unlock ();
|
||||
|
||||
session->handshake ();
|
||||
}
|
||||
|
||||
|
|
@ -1003,7 +994,7 @@ nano::websocket_server::websocket_server (nano::websocket::config & config_a, na
|
|||
}
|
||||
|
||||
auto endpoint = nano::tcp_endpoint{ boost::asio::ip::make_address_v6 (config.address), config.port };
|
||||
server = std::make_shared<nano::websocket::listener> (config.tls_config, logger, wallets, io_ctx, endpoint);
|
||||
server = std::make_shared<nano::websocket::listener> (logger, wallets, io_ctx, endpoint);
|
||||
|
||||
observers.blocks.add ([this] (nano::election_status const & status_a, std::vector<nano::vote_with_weight_info> const & votes_a, nano::account const & account_a, nano::amount const & amount_a, bool is_state_send_a, bool is_state_epoch_a) {
|
||||
debug_assert (status_a.type != nano::election_status_type::ongoing);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ class ledger;
|
|||
class logger;
|
||||
class node_observers;
|
||||
class telemetry_data;
|
||||
class tls_config;
|
||||
class vote;
|
||||
enum class vote_code;
|
||||
class wallets;
|
||||
|
|
@ -303,7 +302,7 @@ namespace websocket
|
|||
class listener final : public std::enable_shared_from_this<listener>
|
||||
{
|
||||
public:
|
||||
listener (std::shared_ptr<nano::tls_config> const & tls_config_a, nano::logger &, nano::wallets & wallets_a, boost::asio::io_context & io_ctx_a, boost::asio::ip::tcp::endpoint endpoint_a);
|
||||
listener (nano::logger &, nano::wallets & wallets_a, boost::asio::io_context & io_ctx_a, boost::asio::ip::tcp::endpoint endpoint_a);
|
||||
|
||||
/** Start accepting connections */
|
||||
void run ();
|
||||
|
|
@ -352,7 +351,6 @@ namespace websocket
|
|||
/** Removes from subscription count of a specific topic*/
|
||||
void decrease_subscriber_count (nano::websocket::topic const & topic_a);
|
||||
|
||||
std::shared_ptr<nano::tls_config> tls_config;
|
||||
nano::logger & logger;
|
||||
nano::wallets & wallets;
|
||||
boost::asio::ip::tcp::acceptor acceptor;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
namespace nano
|
||||
{
|
||||
class tomlconfig;
|
||||
class tls_config;
|
||||
namespace websocket
|
||||
{
|
||||
/** websocket configuration */
|
||||
|
|
@ -22,8 +21,6 @@ namespace websocket
|
|||
bool enabled{ false };
|
||||
uint16_t port;
|
||||
std::string address;
|
||||
/** Optional TLS config */
|
||||
std::shared_ptr<nano::tls_config> tls_config;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,5 @@
|
|||
if(NANO_SECURE_RPC OR RAIBLOCKS_SECURE_RPC)
|
||||
set(secure_rpc_sources rpc_secure.hpp rpc_secure.cpp
|
||||
rpc_connection_secure.hpp rpc_connection_secure.cpp)
|
||||
endif()
|
||||
|
||||
add_library(
|
||||
rpc
|
||||
${secure_rpc_sources}
|
||||
rpc.hpp
|
||||
rpc.cpp
|
||||
rpc_connection.hpp
|
||||
|
|
@ -15,4 +9,4 @@ add_library(
|
|||
rpc_request_processor.hpp
|
||||
rpc_request_processor.cpp)
|
||||
|
||||
target_link_libraries(rpc nano_lib Boost::beast ${OPENSSL_LIBRARIES})
|
||||
target_link_libraries(rpc nano_lib Boost::beast)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#include <nano/boost/asio/bind_executor.hpp>
|
||||
#include <nano/lib/rpc_handler_interface.hpp>
|
||||
#include <nano/lib/tlsconfig.hpp>
|
||||
#include <nano/rpc/rpc.hpp>
|
||||
#include <nano/rpc/rpc_connection.hpp>
|
||||
|
||||
|
|
@ -8,10 +7,6 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
#ifdef NANO_SECURE_RPC
|
||||
#include <nano/rpc/rpc_secure.hpp>
|
||||
#endif
|
||||
|
||||
nano::rpc::rpc (std::shared_ptr<boost::asio::io_context> io_ctx_a, nano::rpc_config config_a, nano::rpc_handler_interface & rpc_handler_interface_a) :
|
||||
config (std::move (config_a)),
|
||||
io_ctx_shared (io_ctx_a),
|
||||
|
|
@ -88,15 +83,5 @@ void nano::rpc::stop ()
|
|||
|
||||
std::shared_ptr<nano::rpc> nano::get_rpc (std::shared_ptr<boost::asio::io_context> io_ctx_a, nano::rpc_config const & config_a, nano::rpc_handler_interface & rpc_handler_interface_a)
|
||||
{
|
||||
if (config_a.tls_config && config_a.tls_config->enable_https)
|
||||
{
|
||||
#ifdef NANO_SECURE_RPC
|
||||
return std::make_shared<nano::rpc_secure> (io_ctx_a, config_a, rpc_handler_interface_a);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::make_shared<nano::rpc> (io_ctx_a, config_a, rpc_handler_interface_a);
|
||||
}
|
||||
return nullptr;
|
||||
return std::make_shared<nano::rpc> (io_ctx_a, config_a, rpc_handler_interface_a);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
#include <nano/boost/asio/bind_executor.hpp>
|
||||
#include <nano/rpc/rpc_connection_secure.hpp>
|
||||
#include <nano/rpc/rpc_secure.hpp>
|
||||
|
||||
#include <boost/polymorphic_pointer_cast.hpp>
|
||||
|
||||
nano::rpc_connection_secure::rpc_connection_secure (nano::rpc_config const & rpc_config, boost::asio::io_context & io_ctx, nano::logger_mt & logger, nano::rpc_handler_interface & rpc_handler_interface, boost::asio::ssl::context & ssl_context) :
|
||||
nano::rpc_connection (rpc_config, io_ctx, logger, rpc_handler_interface),
|
||||
stream (socket, ssl_context)
|
||||
{
|
||||
}
|
||||
|
||||
void nano::rpc_connection_secure::parse_connection ()
|
||||
{
|
||||
// Perform the SSL handshake
|
||||
auto this_l = std::static_pointer_cast<nano::rpc_connection_secure> (shared_from_this ());
|
||||
stream.async_handshake (boost::asio::ssl::stream_base::server,
|
||||
boost::asio::bind_executor (this_l->strand, [this_l] (auto & ec) {
|
||||
this_l->handle_handshake (ec);
|
||||
}));
|
||||
}
|
||||
|
||||
void nano::rpc_connection_secure::on_shutdown (boost::system::error_code const & error)
|
||||
{
|
||||
// No-op. We initiate the shutdown (since the RPC server kills the connection after each request)
|
||||
// and we'll thus get an expected EOF error. If the client disconnects, a short-read error will be expected.
|
||||
}
|
||||
|
||||
void nano::rpc_connection_secure::handle_handshake (boost::system::error_code const & error)
|
||||
{
|
||||
if (!error)
|
||||
{
|
||||
read (stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.always_log ("TLS: Handshake error: ", error.message ());
|
||||
}
|
||||
}
|
||||
|
||||
void nano::rpc_connection_secure::write_completion_handler (std::shared_ptr<nano::rpc_connection> const & rpc)
|
||||
{
|
||||
auto rpc_connection_secure = boost::polymorphic_pointer_downcast<nano::rpc_connection_secure> (rpc);
|
||||
rpc_connection_secure->stream.async_shutdown (boost::asio::bind_executor (rpc->strand, [rpc_connection_secure] (auto const & ec_shutdown) {
|
||||
rpc_connection_secure->on_shutdown (ec_shutdown);
|
||||
}));
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <nano/rpc/rpc_connection.hpp>
|
||||
|
||||
#include <boost/asio/ssl/stream.hpp>
|
||||
|
||||
namespace nano
|
||||
{
|
||||
/**
|
||||
* Specialization of nano::rpc_connection for establishing TLS connections.
|
||||
* Handshakes with client certificates are supported.
|
||||
*/
|
||||
class rpc_connection_secure : public rpc_connection
|
||||
{
|
||||
public:
|
||||
rpc_connection_secure (nano::rpc_config const & rpc_config, boost::asio::io_context & io_ctx, nano::logger_mt & logger, nano::rpc_handler_interface & rpc_handler_interface_a, boost::asio::ssl::context & ssl_context);
|
||||
void parse_connection () override;
|
||||
void write_completion_handler (std::shared_ptr<nano::rpc_connection> const & rpc) override;
|
||||
/** The TLS handshake callback */
|
||||
void handle_handshake (boost::system::error_code const & error);
|
||||
/** The TLS async shutdown callback */
|
||||
void on_shutdown (boost::system::error_code const & error);
|
||||
|
||||
private:
|
||||
boost::asio::ssl::stream<socket_type &> stream;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
#include <nano/boost/asio/bind_executor.hpp>
|
||||
#include <nano/lib/tlsconfig.hpp>
|
||||
#include <nano/rpc/rpc_connection_secure.hpp>
|
||||
#include <nano/rpc/rpc_secure.hpp>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/polymorphic_pointer_cast.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
nano::rpc_secure::rpc_secure (boost::asio::io_context & context_a, nano::rpc_config const & config_a, nano::rpc_handler_interface & rpc_handler_interface_a) :
|
||||
rpc (context_a, config_a, rpc_handler_interface_a)
|
||||
{
|
||||
}
|
||||
|
||||
void nano::rpc_secure::accept ()
|
||||
{
|
||||
auto connection (std::make_shared<nano::rpc_connection_secure> (config, io_ctx, logger, rpc_handler_interface, config.tls_config->ssl_context));
|
||||
acceptor.async_accept (connection->socket, boost::asio::bind_executor (connection->strand, [this, connection] (boost::system::error_code const & ec) {
|
||||
if (ec != boost::asio::error::operation_aborted && acceptor.is_open ())
|
||||
{
|
||||
accept ();
|
||||
}
|
||||
if (!ec)
|
||||
{
|
||||
connection->parse_connection ();
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.error (nano::log::type::rpc, "Error accepting RPC connection: {}", ec.message ());
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
#pragma once
|
||||
#include <nano/rpc/rpc.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace asio
|
||||
{
|
||||
class io_context;
|
||||
}
|
||||
}
|
||||
|
||||
namespace nano
|
||||
{
|
||||
/**
|
||||
* Specialization of nano::rpc with TLS support
|
||||
*/
|
||||
class rpc_secure : public rpc
|
||||
{
|
||||
public:
|
||||
rpc_secure (boost::asio::io_context & context_a, nano::rpc_config const & config_a, nano::rpc_handler_interface & rpc_handler_interface_a);
|
||||
|
||||
/** Starts accepting connections */
|
||||
void accept () override;
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue