From 21eb1b0725717ad013d3e2b00fbfc3b84ad04699 Mon Sep 17 00:00:00 2001 From: Lee Clagett Date: Fri, 15 Mar 2019 00:03:32 -0400 Subject: Pass SSL arguments via one class and use shared_ptr instead of reference --- src/rpc/core_rpc_server.cpp | 31 +++++++++++++++++++------------ src/wallet/wallet2.cpp | 38 ++++++++++++++++++++++++-------------- src/wallet/wallet2.h | 10 ++-------- src/wallet/wallet_rpc_server.cpp | 38 +++++++++++++++++++++++++++++--------- 4 files changed, 74 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 0a45fca27..161ad2951 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -149,21 +149,29 @@ namespace cryptonote if (rpc_config->login) http_login.emplace(std::move(rpc_config->login->username), std::move(rpc_config->login->password).password()); - const std::string ssl_private_key = command_line::get_arg(vm, arg_rpc_ssl_private_key); - const std::string ssl_certificate = command_line::get_arg(vm, arg_rpc_ssl_certificate); - std::string ssl_ca_path = command_line::get_arg(vm, arg_rpc_ssl_ca_certificates); + epee::net_utils::ssl_options_t ssl_options = epee::net_utils::ssl_support_t::e_ssl_support_autodetect; + if (command_line::get_arg(vm, arg_rpc_ssl_allow_any_cert)) + ssl_options.verification = epee::net_utils::ssl_verification_t::none; + else + { + std::string ssl_ca_path = command_line::get_arg(vm, arg_rpc_ssl_ca_certificates); + const std::vector ssl_allowed_fingerprint_strings = command_line::get_arg(vm, arg_rpc_ssl_allowed_fingerprints); + std::vector> ssl_allowed_fingerprints{ ssl_allowed_fingerprint_strings.size() }; + std::transform(ssl_allowed_fingerprint_strings.begin(), ssl_allowed_fingerprint_strings.end(), ssl_allowed_fingerprints.begin(), epee::from_hex::vector); - const std::vector ssl_allowed_fingerprint_strings = command_line::get_arg(vm, arg_rpc_ssl_allowed_fingerprints); - std::vector> ssl_allowed_fingerprints{ ssl_allowed_fingerprint_strings.size() }; - std::transform(ssl_allowed_fingerprint_strings.begin(), ssl_allowed_fingerprint_strings.end(), ssl_allowed_fingerprints.begin(), epee::from_hex::vector); - const bool ssl_allow_any_cert = command_line::get_arg(vm, arg_rpc_ssl_allow_any_cert); + if (!ssl_ca_path.empty() || !ssl_allowed_fingerprints.empty()) + ssl_options = epee::net_utils::ssl_options_t{std::move(ssl_allowed_fingerprints), std::move(ssl_ca_path)}; + } + + ssl_options.auth = epee::net_utils::ssl_authentication_t{ + command_line::get_arg(vm, arg_rpc_ssl_private_key), command_line::get_arg(vm, arg_rpc_ssl_certificate) + }; // user specified CA file or fingeprints implies enabled SSL by default - epee::net_utils::ssl_support_t ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_enabled; - if ((ssl_allowed_fingerprints.empty() && ssl_ca_path.empty()) || !command_line::is_arg_defaulted(vm, arg_rpc_ssl)) + if (ssl_options.verification != epee::net_utils::ssl_verification_t::user_certificates || !command_line::is_arg_defaulted(vm, arg_rpc_ssl)) { const std::string ssl = command_line::get_arg(vm, arg_rpc_ssl); - if (!epee::net_utils::ssl_support_from_string(ssl_support, ssl)) + if (!epee::net_utils::ssl_support_from_string(ssl_options.support, ssl)) { MFATAL("Invalid RPC SSL support: " << ssl); return false; @@ -172,8 +180,7 @@ namespace cryptonote auto rng = [](size_t len, uint8_t *ptr){ return crypto::rand(len, ptr); }; return epee::http_server_impl_base::init( - rng, std::move(port), std::move(rpc_config->bind_ip), std::move(rpc_config->access_control_origins), std::move(http_login), - ssl_support, std::make_pair(ssl_private_key, ssl_certificate), std::move(ssl_ca_path), std::move(ssl_allowed_fingerprints), ssl_allow_any_cert + rng, std::move(port), std::move(rpc_config->bind_ip), std::move(rpc_config->access_control_origins), std::move(http_login), std::move(ssl_options) ); } //------------------------------------------------------------------------------------------------------------------------------ diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 9e2a826d9..9f2cd2a41 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -327,13 +327,29 @@ std::unique_ptr make_basic(const boost::program_options::variabl auto daemon_ssl = command_line::get_arg(vm, opts.daemon_ssl); // user specified CA file or fingeprints implies enabled SSL by default - epee::net_utils::ssl_support_t ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_enabled; - if ((daemon_ssl_ca_file.empty() && daemon_ssl_allowed_fingerprints.empty()) || !command_line::is_arg_defaulted(vm, opts.daemon_ssl)) + epee::net_utils::ssl_options_t ssl_options = epee::net_utils::ssl_support_t::e_ssl_support_enabled; + if (command_line::get_arg(vm, opts.daemon_ssl_allow_any_cert)) + ssl_options.verification = epee::net_utils::ssl_verification_t::none; + else if (!daemon_ssl_ca_file.empty() || !daemon_ssl_allowed_fingerprints.empty()) { - THROW_WALLET_EXCEPTION_IF(!epee::net_utils::ssl_support_from_string(ssl_support, daemon_ssl), tools::error::wallet_internal_error, + std::vector> ssl_allowed_fingerprints{ daemon_ssl_allowed_fingerprints.size() }; + std::transform(daemon_ssl_allowed_fingerprints.begin(), daemon_ssl_allowed_fingerprints.end(), ssl_allowed_fingerprints.begin(), epee::from_hex::vector); + + ssl_options = epee::net_utils::ssl_options_t{ + std::move(ssl_allowed_fingerprints), std::move(daemon_ssl_ca_file) + }; + } + + if (ssl_options.verification != epee::net_utils::ssl_verification_t::user_certificates || !command_line::is_arg_defaulted(vm, opts.daemon_ssl)) + { + THROW_WALLET_EXCEPTION_IF(!epee::net_utils::ssl_support_from_string(ssl_options.support, daemon_ssl), tools::error::wallet_internal_error, tools::wallet2::tr("Invalid argument for ") + std::string(opts.daemon_ssl.name)); } + ssl_options.auth = epee::net_utils::ssl_authentication_t{ + std::move(daemon_ssl_private_key), std::move(daemon_ssl_certificate) + }; + THROW_WALLET_EXCEPTION_IF(!daemon_address.empty() && !daemon_host.empty() && 0 != daemon_port, tools::error::wallet_internal_error, tools::wallet2::tr("can't specify daemon host or port more than once")); @@ -421,11 +437,8 @@ std::unique_ptr make_basic(const boost::program_options::variabl catch (const std::exception &e) { } } - std::vector> ssl_allowed_fingerprints{ daemon_ssl_allowed_fingerprints.size() }; - std::transform(daemon_ssl_allowed_fingerprints.begin(), daemon_ssl_allowed_fingerprints.end(), ssl_allowed_fingerprints.begin(), epee::from_hex::vector); - std::unique_ptr wallet(new tools::wallet2(nettype, kdf_rounds, unattended)); - wallet->init(std::move(daemon_address), std::move(login), std::move(proxy), 0, *trusted_daemon, ssl_support, std::make_pair(daemon_ssl_private_key, daemon_ssl_certificate), std::move(daemon_ssl_ca_file), ssl_allowed_fingerprints, daemon_ssl_allow_any_cert); + wallet->init(std::move(daemon_address), std::move(login), std::move(proxy), 0, *trusted_daemon, std::move(ssl_options)); boost::filesystem::path ringdb_path = command_line::get_arg(vm, opts.shared_ringdb_dir); wallet->set_ring_database(ringdb_path.string()); wallet->get_message_store().set_options(vm); @@ -1148,10 +1161,7 @@ std::unique_ptr wallet2::make_dummy(const boost::program_options::varia } //---------------------------------------------------------------------------------------------------- -bool wallet2::set_daemon(std::string daemon_address, boost::optional daemon_login, bool trusted_daemon, - epee::net_utils::ssl_support_t ssl_support, const std::pair &private_key_and_certificate_path, - std::string ca_file, const std::vector> &allowed_fingerprints, - bool allow_any_cert) +bool wallet2::set_daemon(std::string daemon_address, boost::optional daemon_login, bool trusted_daemon, epee::net_utils::ssl_options_t ssl_options) { if(m_http_client.is_connected()) m_http_client.disconnect(); @@ -1160,17 +1170,17 @@ bool wallet2::set_daemon(std::string daemon_address, boost::optional daemon_login, boost::asio::ip::tcp::endpoint proxy, uint64_t upper_transaction_weight_limit, bool trusted_daemon, epee::net_utils::ssl_support_t ssl_support, const std::pair &private_key_and_certificate_path, std::string ca_file, const std::vector> &allowed_fingerprints, bool allow_any_cert) +bool wallet2::init(std::string daemon_address, boost::optional daemon_login, boost::asio::ip::tcp::endpoint proxy, uint64_t upper_transaction_weight_limit, bool trusted_daemon, epee::net_utils::ssl_options_t ssl_options) { m_checkpoints.init_default_checkpoints(m_nettype); m_is_initialized = true; m_upper_transaction_weight_limit = upper_transaction_weight_limit; if (proxy != boost::asio::ip::tcp::endpoint{}) m_http_client.set_connector(net::socks::connector{std::move(proxy)}); - return set_daemon(daemon_address, daemon_login, trusted_daemon, ssl_support, private_key_and_certificate_path, std::move(ca_file), allowed_fingerprints, allow_any_cert); + return set_daemon(daemon_address, daemon_login, trusted_daemon, std::move(ssl_options)); } //---------------------------------------------------------------------------------------------------- bool wallet2::is_deterministic() const diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 58dc5f082..38cd68784 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -689,16 +689,10 @@ namespace tools boost::asio::ip::tcp::endpoint proxy = {}, uint64_t upper_transaction_weight_limit = 0, bool trusted_daemon = true, - epee::net_utils::ssl_support_t ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_autodetect, - const std::pair &private_key_and_certificate_path = {}, - std::string ca_file = {}, const std::vector> &allowed_fingerprints = {}, - bool allow_any_cert = false); + epee::net_utils::ssl_options_t ssl_options = epee::net_utils::ssl_support_t::e_ssl_support_autodetect); bool set_daemon(std::string daemon_address = "http://localhost:8080", boost::optional daemon_login = boost::none, bool trusted_daemon = true, - epee::net_utils::ssl_support_t ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_autodetect, - const std::pair &private_key_and_certificate_path = {}, - std::string ca_file = {}, const std::vector> &allowed_fingerprints = {}, - bool allow_any_cert = false); + epee::net_utils::ssl_options_t ssl_options = epee::net_utils::ssl_support_t::e_ssl_support_autodetect); void stop() { m_run.store(false, std::memory_order_relaxed); m_message_store.stop(); } diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index a07e8e767..474e0d101 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -250,20 +250,31 @@ namespace tools auto rpc_ssl_ca_file = command_line::get_arg(vm, arg_rpc_ssl_ca_certificates); auto rpc_ssl_allowed_fingerprints = command_line::get_arg(vm, arg_rpc_ssl_allowed_fingerprints); auto rpc_ssl = command_line::get_arg(vm, arg_rpc_ssl); - epee::net_utils::ssl_support_t rpc_ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_enabled; + epee::net_utils::ssl_options_t rpc_ssl_options = epee::net_utils::ssl_support_t::e_ssl_support_enabled; + + if (!rpc_ssl_ca_file.empty() || !rpc_ssl_allowed_fingerprints.empty()) + { + std::vector> allowed_fingerprints{ rpc_ssl_allowed_fingerprints.size() }; + std::transform(rpc_ssl_allowed_fingerprints.begin(), rpc_ssl_allowed_fingerprints.end(), allowed_fingerprints.begin(), epee::from_hex::vector); + + rpc_ssl_options = epee::net_utils::ssl_options_t{ + std::move(allowed_fingerprints), std::move(rpc_ssl_ca_file) + }; + } // user specified CA file or fingeprints implies enabled SSL by default - if ((rpc_ssl_ca_file.empty() && rpc_ssl_allowed_fingerprints.empty()) || !command_line::is_arg_defaulted(vm, arg_rpc_ssl)) + if (rpc_ssl_options.verification != epee::net_utils::ssl_verification_t::user_certificates || !command_line::is_arg_defaulted(vm, arg_rpc_ssl)) { - if (!epee::net_utils::ssl_support_from_string(rpc_ssl_support, rpc_ssl)) + if (!epee::net_utils::ssl_support_from_string(rpc_ssl_options.support, rpc_ssl)) { MERROR("Invalid argument for " << std::string(arg_rpc_ssl.name)); return false; } } - std::vector> allowed_fingerprints{ rpc_ssl_allowed_fingerprints.size() }; - std::transform(rpc_ssl_allowed_fingerprints.begin(), rpc_ssl_allowed_fingerprints.end(), allowed_fingerprints.begin(), epee::from_hex::vector); + rpc_ssl_options.auth = epee::net_utils::ssl_authentication_t{ + std::move(rpc_ssl_private_key), std::move(rpc_ssl_certificate) + }; m_auto_refresh_period = DEFAULT_AUTO_REFRESH_PERIOD; m_last_auto_refresh_time = boost::posix_time::min_date_time; @@ -272,7 +283,7 @@ namespace tools auto rng = [](size_t len, uint8_t *ptr) { return crypto::rand(len, ptr); }; return epee::http_server_impl_base::init( rng, std::move(bind_port), std::move(rpc_config->bind_ip), std::move(rpc_config->access_control_origins), std::move(http_login), - rpc_ssl_support, std::make_pair(rpc_ssl_private_key, rpc_ssl_certificate), std::move(rpc_ssl_ca_file), std::move(allowed_fingerprints) + std::move(rpc_ssl_options) ); } //------------------------------------------------------------------------------------------------------------------------------ @@ -4049,8 +4060,8 @@ namespace tools er.message = "Command unavailable in restricted mode."; return false; } - epee::net_utils::ssl_support_t ssl_support; - if (!epee::net_utils::ssl_support_from_string(ssl_support, req.ssl_support)) + epee::net_utils::ssl_options_t ssl_options = epee::net_utils::ssl_support_t::e_ssl_support_enabled; + if (!epee::net_utils::ssl_support_from_string(ssl_options.support, req.ssl_support)) { er.code = WALLET_RPC_ERROR_CODE_NO_DAEMON_CONNECTION; er.message = std::string("Invalid ssl support mode"); @@ -4065,7 +4076,16 @@ namespace tools for (auto c: fp) v.push_back(c); } - if (!m_wallet->set_daemon(req.address, boost::none, req.trusted, ssl_support, std::make_pair(req.ssl_private_key_path, req.ssl_certificate_path), std::move(req.ssl_ca_file), ssl_allowed_fingerprints, req.ssl_allow_any_cert)) + if (req.ssl_allow_any_cert) + ssl_options.verification = epee::net_utils::ssl_verification_t::none; + else if (!ssl_allowed_fingerprints.empty() || !req.ssl_ca_file.empty()) + ssl_options = epee::net_utils::ssl_options_t{std::move(ssl_allowed_fingerprints), std::move(req.ssl_ca_file)}; + + ssl_options.auth = epee::net_utils::ssl_authentication_t{ + std::move(req.ssl_private_key_path), std::move(req.ssl_certificate_path) + }; + + if (!m_wallet->set_daemon(req.address, boost::none, req.trusted, std::move(ssl_options))) { er.code = WALLET_RPC_ERROR_CODE_NO_DAEMON_CONNECTION; er.message = std::string("Unable to set daemon"); -- cgit v1.2.3