From c50ade514fab0f48908e4b940fbf2ca08216a67a Mon Sep 17 00:00:00 2001 From: 0xFFFC0000 <0xFFFC0000@proton.me> Date: Sun, 18 Feb 2024 18:36:52 +0000 Subject: [PATCH] Daemon-specific proxy for the wallet-rpc. 1. Daemon-specific proxy is exclusive with global proxy (--proxy). 2. If you set global proxy (--proxy) you cannot set daemon-specific proxy. 3. If you don't set global proxy, you can set proxy (or not set) proxy for each daemon connection with the proxy field in jsonrpc to the wallet-rpc. --- src/wallet/wallet2.cpp | 13 +++++++++++-- src/wallet/wallet2.h | 10 +++++++++- src/wallet/wallet_rpc_server.cpp | 9 ++++++++- src/wallet/wallet_rpc_server_commands_defs.h | 2 ++ src/wallet/wallet_rpc_server_error_codes.h | 1 + 5 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 336f4e159..ab6c86b04 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1267,6 +1267,11 @@ bool wallet2::has_stagenet_option(const boost::program_options::variables_map& v return command_line::get_arg(vm, options().stagenet); } +bool wallet2::has_proxy_option() const +{ + return !m_proxy.empty(); +} + std::string wallet2::device_name_option(const boost::program_options::variables_map& vm) { return command_line::get_arg(vm, options().hw_device); @@ -1351,12 +1356,15 @@ 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_options_t ssl_options) +bool wallet2::set_daemon(std::string daemon_address, boost::optional daemon_login, bool trusted_daemon, epee::net_utils::ssl_options_t ssl_options, const std::string& proxy) { boost::lock_guard lock(m_daemon_rpc_mutex); if(m_http_client->is_connected()) m_http_client->disconnect(); + CHECK_AND_ASSERT_MES2(m_proxy.empty() || proxy.empty() , "It is not possible to set global proxy (--proxy) and daemon specific proxy together."); + if(m_proxy.empty()) + CHECK_AND_ASSERT_MES(set_proxy(proxy), false, "failed to set proxy address"); const bool changed = m_daemon_address != daemon_address; m_daemon_address = std::move(daemon_address); m_daemon_login = std::move(daemon_login); @@ -1386,7 +1394,8 @@ bool wallet2::set_proxy(const std::string &address) //---------------------------------------------------------------------------------------------------- bool wallet2::init(std::string daemon_address, boost::optional daemon_login, const std::string &proxy_address, uint64_t upper_transaction_weight_limit, bool trusted_daemon, epee::net_utils::ssl_options_t ssl_options) { - CHECK_AND_ASSERT_MES(set_proxy(proxy_address), false, "failed to set proxy address"); + m_proxy = proxy_address; + CHECK_AND_ASSERT_MES(set_proxy(m_proxy), false, "failed to set proxy address"); m_checkpoints.init_default_checkpoints(m_nettype); m_is_initialized = true; m_upper_transaction_weight_limit = upper_transaction_weight_limit; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 21ca48464..310aadb94 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -962,6 +962,12 @@ private: std::string path() const; + /*! + * \brief has_proxy_option Check the global proxy (--proxy) has been defined or not. + * \return returns bool representing the global proxy (--proxy). + */ + bool has_proxy_option() const; + /*! * \brief verifies given password is correct for default wallet keys file */ @@ -992,7 +998,8 @@ private: 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_options_t ssl_options = epee::net_utils::ssl_support_t::e_ssl_support_autodetect); + epee::net_utils::ssl_options_t ssl_options = epee::net_utils::ssl_support_t::e_ssl_support_autodetect, + const std::string &proxy = ""); bool set_proxy(const std::string &address); void stop() { m_run.store(false, std::memory_order_relaxed); m_message_store.stop(); } @@ -1771,6 +1778,7 @@ private: cryptonote::account_base m_account; boost::optional m_daemon_login; std::string m_daemon_address; + std::string m_proxy; std::string m_wallet_file; std::string m_keys_file; std::string m_mms_file; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 0cc42ae3f..1d835a86b 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -4406,6 +4406,13 @@ namespace tools er.message = "Command unavailable in restricted mode."; return false; } + + if (m_wallet->has_proxy_option() && !req.proxy.empty()) + { + er.code = WALLET_RPC_ERROR_CODE_PROXY_ALREADY_DEFINED; + er.message = "It is not possible to set daemon specific proxy when --proxy is defined."; + return false; + } std::vector> ssl_allowed_fingerprints; ssl_allowed_fingerprints.reserve(req.ssl_allowed_fingerprints.size()); @@ -4449,7 +4456,7 @@ namespace tools if (!req.username.empty() || !req.password.empty()) daemon_login.emplace(req.username, req.password); - if (!m_wallet->set_daemon(req.address, daemon_login, req.trusted, std::move(ssl_options))) + if (!m_wallet->set_daemon(req.address, daemon_login, req.trusted, std::move(ssl_options), req.proxy)) { er.code = WALLET_RPC_ERROR_CODE_NO_DAEMON_CONNECTION; er.message = std::string("Unable to set daemon"); diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index 33afefb80..2a1e5ac41 100644 --- a/src/wallet/wallet_rpc_server_commands_defs.h +++ b/src/wallet/wallet_rpc_server_commands_defs.h @@ -2581,6 +2581,7 @@ namespace wallet_rpc std::string ssl_ca_file; std::vector ssl_allowed_fingerprints; bool ssl_allow_any_cert; + std::string proxy; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(address) @@ -2593,6 +2594,7 @@ namespace wallet_rpc KV_SERIALIZE(ssl_ca_file) KV_SERIALIZE(ssl_allowed_fingerprints) KV_SERIALIZE_OPT(ssl_allow_any_cert, false) + KV_SERIALIZE_OPT(proxy, (std::string)"") END_KV_SERIALIZE_MAP() }; typedef epee::misc_utils::struct_init request; diff --git a/src/wallet/wallet_rpc_server_error_codes.h b/src/wallet/wallet_rpc_server_error_codes.h index 8e3bdf650..2988f52ad 100644 --- a/src/wallet/wallet_rpc_server_error_codes.h +++ b/src/wallet/wallet_rpc_server_error_codes.h @@ -79,3 +79,4 @@ #define WALLET_RPC_ERROR_CODE_ZERO_AMOUNT -46 #define WALLET_RPC_ERROR_CODE_INVALID_SIGNATURE_TYPE -47 #define WALLET_RPC_ERROR_CODE_DISABLED -48 +#define WALLET_RPC_ERROR_CODE_PROXY_ALREADY_DEFINED -49