From 25e5890d37a1b243d4b8aadb45743d715bd4d0f9 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 1 Oct 2018 11:18:50 +0000 Subject: [PATCH] wallet: fix --generate-from-json using wrong password --- src/common/password.cpp | 4 ++++ src/common/password.h | 1 + src/simplewallet/simplewallet.cpp | 4 +++- src/wallet/wallet2.cpp | 13 +++++++++---- src/wallet/wallet2.h | 2 +- src/wallet/wallet_rpc_server.cpp | 3 ++- 6 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/common/password.cpp b/src/common/password.cpp index 5671c4a4e..b32bedae2 100644 --- a/src/common/password.cpp +++ b/src/common/password.cpp @@ -221,6 +221,10 @@ namespace tools : m_password(std::move(password)) { } + password_container::password_container(const epee::wipeable_string& password) noexcept + : m_password(password) + { + } password_container::~password_container() noexcept { diff --git a/src/common/password.h b/src/common/password.h index 529881e40..beb98283b 100644 --- a/src/common/password.h +++ b/src/common/password.h @@ -47,6 +47,7 @@ namespace tools //! `password` is used as password password_container(std::string&& password) noexcept; + password_container(const epee::wipeable_string& password) noexcept; //! \return A password from stdin TTY prompt or `std::cin` pipe. static boost::optional prompt(bool verify, const char *mesage = "Password", bool hide_input = true); diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 7c68de3f3..90f8535d7 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -3275,7 +3275,9 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) { try { - m_wallet = tools::wallet2::make_from_json(vm, false, m_generate_from_json, password_prompter); + auto rc = tools::wallet2::make_from_json(vm, false, m_generate_from_json, password_prompter); + m_wallet = std::move(rc.first); + password = rc.second.password(); m_wallet_file = m_wallet->path(); } catch (const std::exception &e) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 299b4afeb..b657fcd9f 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -313,7 +313,7 @@ boost::optional get_password(const boost::program_opt return password_prompter(verify ? tr("Enter a new password for the wallet") : tr("Wallet password"), verify); } -std::unique_ptr generate_from_json(const std::string& json_file, const boost::program_options::variables_map& vm, bool unattended, const options& opts, const std::function(const char *, bool)> &password_prompter) +std::pair, tools::password_container> generate_from_json(const std::string& json_file, const boost::program_options::variables_map& vm, bool unattended, const options& opts, const std::function(const char *, bool)> &password_prompter) { const bool testnet = command_line::get_arg(vm, opts.testnet); const bool stagenet = command_line::get_arg(vm, opts.stagenet); @@ -323,6 +323,7 @@ std::unique_ptr generate_from_json(const std::string& json_file, false. Gcc will coerce this into unique_ptr(nullptr), but clang correctly fails. This large wrapper is for the use of that macro */ std::unique_ptr wallet; + epee::wipeable_string password; const auto do_generate = [&]() -> bool { std::string buf; if (!epee::file_io_utils::load_file_to_string(json_file, buf)) { @@ -460,10 +461,12 @@ std::unique_ptr generate_from_json(const std::string& json_file, if (!field_seed.empty()) { wallet->generate(field_filename, field_password, recovery_key, recover, false, create_address_file); + password = field_password; } else if (field_viewkey.empty() && !field_spendkey.empty()) { wallet->generate(field_filename, field_password, spendkey, recover, false, create_address_file); + password = field_password; } else { @@ -490,6 +493,7 @@ std::unique_ptr generate_from_json(const std::string& json_file, THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("Address must be specified in order to create watch-only wallet")); } wallet->generate(field_filename, field_password, address, viewkey, create_address_file); + password = field_password; } else { @@ -497,6 +501,7 @@ std::unique_ptr generate_from_json(const std::string& json_file, THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify spend key secret key")); } wallet->generate(field_filename, field_password, address, spendkey, viewkey, create_address_file); + password = field_password; } } } @@ -509,9 +514,9 @@ std::unique_ptr generate_from_json(const std::string& json_file, if (do_generate()) { - return wallet; + return {std::move(wallet), tools::password_container(password)}; } - return nullptr; + return {nullptr, tools::password_container{}}; } static void throw_on_rpc_response_error(const boost::optional &status, const char *method) @@ -854,7 +859,7 @@ void wallet2::init_options(boost::program_options::options_description& desc_par command_line::add_arg(desc_params, opts.tx_notify); } -std::unique_ptr wallet2::make_from_json(const boost::program_options::variables_map& vm, bool unattended, const std::string& json_file, const std::function(const char *, bool)> &password_prompter) +std::pair, tools::password_container> wallet2::make_from_json(const boost::program_options::variables_map& vm, bool unattended, const std::string& json_file, const std::function(const char *, bool)> &password_prompter) { const options opts{}; return generate_from_json(json_file, vm, unattended, opts, password_prompter); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 497dd486f..7857f36f1 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -177,7 +177,7 @@ namespace tools static void init_options(boost::program_options::options_description& desc_params); //! Uses stdin and stdout. Returns a wallet2 if no errors. - static std::unique_ptr make_from_json(const boost::program_options::variables_map& vm, bool unattended, const std::string& json_file, const std::function(const char *, bool)> &password_prompter); + static std::pair, password_container> make_from_json(const boost::program_options::variables_map& vm, bool unattended, const std::string& json_file, const std::function(const char *, bool)> &password_prompter); //! Uses stdin and stdout. Returns a wallet2 and password for `wallet_file` if no errors. static std::pair, password_container> diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 5991e0cc2..8b15359cc 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -3352,7 +3352,8 @@ public: { try { - wal = tools::wallet2::make_from_json(vm, true, from_json, password_prompt); + auto rc = tools::wallet2::make_from_json(vm, true, from_json, password_prompt); + wal = std::move(rc.first); } catch (const std::exception &e) {