From ec5135e5b71e0bc5d5f596e56e9818dec38e9867 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 28 Oct 2017 16:09:13 +0100 Subject: move input_line from command_line to simplewallet It was only used there, and this removes one part of the common dependency on libreadline --- src/simplewallet/simplewallet.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/simplewallet/simplewallet.cpp') diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 3d8d395db..2698b709e 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -125,6 +125,19 @@ namespace const command_line::arg_descriptor< std::vector > arg_command = {"command", ""}; + std::string input_line(const std::string& prompt) + { +#ifdef HAVE_READLINE + rdln::suspend_readline pause_readline; +#endif + std::cout << prompt; + + std::string buf; + std::getline(std::cin, buf); + + return epee::string_tools::trim(buf); + } + inline std::string interpret_rpc_response(bool ok, const std::string& status) { std::string err; -- cgit v1.2.3 From e89994e98f85be95d68c7bf471fcadf9aabbc93a Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 28 Oct 2017 19:13:42 +0100 Subject: wallet: rejig to avoid prompting in wallet2 wallet2 is a library, and should not prompt for stdin. Instead, pass a function so simplewallet can prompt on stdin, and a GUI might display a window, etc. --- src/common/password.cpp | 7 +--- src/common/password.h | 2 +- src/daemon/main.cpp | 7 +++- src/rpc/rpc_args.cpp | 4 +- src/simplewallet/simplewallet.cpp | 78 ++++++++++++++++++++++++--------------- src/wallet/wallet2.cpp | 46 +++++++++-------------- src/wallet/wallet2.h | 11 ++---- src/wallet/wallet_rpc_server.cpp | 20 +++++++--- 8 files changed, 97 insertions(+), 78 deletions(-) (limited to 'src/simplewallet/simplewallet.cpp') diff --git a/src/common/password.cpp b/src/common/password.cpp index b84d6fb2e..5d56464a5 100644 --- a/src/common/password.cpp +++ b/src/common/password.cpp @@ -238,9 +238,6 @@ namespace tools boost::optional password_container::prompt(const bool verify, const char *message) { -#ifdef HAVE_READLINE - rdln::suspend_readline pause_readline; -#endif password_container pass1{}; password_container pass2{}; if (is_cin_tty() ? read_from_tty(verify, message, pass1.m_password, pass2.m_password) : read_from_file(pass1.m_password)) @@ -249,7 +246,7 @@ namespace tools return boost::none; } - boost::optional login::parse(std::string&& userpass, bool verify, const char* message) + boost::optional login::parse(std::string&& userpass, bool verify, const std::function(bool)> &prompt) { login out{}; password_container wipe{std::move(userpass)}; @@ -257,7 +254,7 @@ namespace tools const auto loc = wipe.password().find(':'); if (loc == std::string::npos) { - auto result = tools::password_container::prompt(verify, message); + auto result = prompt(verify); if (!result) return boost::none; diff --git a/src/common/password.h b/src/common/password.h index 12f715df4..ba1c30a28 100644 --- a/src/common/password.h +++ b/src/common/password.h @@ -82,7 +82,7 @@ namespace tools \return The username and password, or boost::none if `password_container::prompt` fails. */ - static boost::optional parse(std::string&& userpass, bool verify, const char* message = "Password"); + static boost::optional parse(std::string&& userpass, bool verify, const std::function(bool)> &prompt); login(const login&) = delete; login(login&&) = default; diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp index e7aaa22c1..ae83943b6 100644 --- a/src/daemon/main.cpp +++ b/src/daemon/main.cpp @@ -247,7 +247,12 @@ int main(int argc, char const * argv[]) if (command_line::has_arg(vm, arg.rpc_login)) { login = tools::login::parse( - command_line::get_arg(vm, arg.rpc_login), false, "Daemon client password" + command_line::get_arg(vm, arg.rpc_login), false, [](bool verify) { +#ifdef HAVE_READLINE + rdln::suspend_readline pause_readline; +#endif + return tools::password_container::prompt(verify, "Daemon client password"); + } ); if (!login) { diff --git a/src/rpc/rpc_args.cpp b/src/rpc/rpc_args.cpp index 93309bf3c..e03c5472d 100644 --- a/src/rpc/rpc_args.cpp +++ b/src/rpc/rpc_args.cpp @@ -83,7 +83,9 @@ namespace cryptonote if (command_line::has_arg(vm, arg.rpc_login)) { - config.login = tools::login::parse(command_line::get_arg(vm, arg.rpc_login), true, "RPC server password"); + config.login = tools::login::parse(command_line::get_arg(vm, arg.rpc_login), true, [](bool verify) { + return tools::password_container::prompt(verify, "RPC server password"); + }); if (!config.login) return boost::none; diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 2698b709e..298e60e73 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -138,6 +138,24 @@ namespace return epee::string_tools::trim(buf); } + boost::optional password_prompter(const char *prompt, bool verify) + { +#ifdef HAVE_READLINE + rdln::suspend_readline pause_readline; +#endif + auto pwd_container = tools::password_container::prompt(verify, prompt); + if (!pwd_container) + { + tools::fail_msg_writer() << tr("failed to read wallet password"); + } + return pwd_container; + } + + boost::optional default_password_prompter(bool verify) + { + return password_prompter(verify ? tr("Enter new wallet password") : tr("Wallet password"), verify); + } + inline std::string interpret_rpc_response(bool ok, const std::string& status) { std::string err; @@ -283,7 +301,7 @@ namespace << tr("Is this OK? (Y/n) ") ; // prompt the user for confirmation given the dns query and dnssec status - std::string confirm_dns_ok = command_line::input_line(prompt.str()); + std::string confirm_dns_ok = input_line(prompt.str()); if (std::cin.eof()) { return {}; @@ -461,7 +479,7 @@ bool simple_wallet::change_password(const std::vector &args) } // prompts for a new password, pass true to verify the password - const auto pwd_container = tools::wallet2::password_prompt(true); + const auto pwd_container = default_password_prompter(true); try { @@ -1033,7 +1051,7 @@ bool simple_wallet::ask_wallet_create_if_needed() do{ LOG_PRINT_L3("User asked to specify wallet file name."); - wallet_path = command_line::input_line( + wallet_path = input_line( tr(m_restoring ? "Specify a new wallet file name for your restored wallet (e.g., MyWallet).\n" "Wallet file name (or Ctrl-C to quit): " : "Specify wallet file name (e.g., MyWallet). If the wallet doesn't exist, it will be created.\n" @@ -1084,7 +1102,7 @@ bool simple_wallet::ask_wallet_create_if_needed() if (!m_restoring) { message_writer() << tr("No wallet found with that name. Confirm creation of new wallet named: ") << wallet_path; - confirm_creation = command_line::input_line(tr("(Y/Yes/N/No): ")); + confirm_creation = input_line(tr("(Y/Yes/N/No): ")); if(std::cin.eof()) { LOG_ERROR("Unexpected std::cin.eof() - Exited simple_wallet::ask_wallet_create_if_needed()"); @@ -1168,7 +1186,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) do { const char *prompt = m_electrum_seed.empty() ? "Specify Electrum seed: " : "Electrum seed continued: "; - std::string electrum_seed = command_line::input_line(prompt); + std::string electrum_seed = input_line(prompt); if (std::cin.eof()) return false; if (electrum_seed.empty()) @@ -1197,7 +1215,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) { m_wallet_file = m_generate_from_view_key; // parse address - std::string address_string = command_line::input_line("Standard address: "); + std::string address_string = input_line("Standard address: "); if (std::cin.eof()) return false; if (address_string.empty()) { @@ -1217,7 +1235,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) } // parse view secret key - std::string viewkey_string = command_line::input_line("View key: "); + std::string viewkey_string = input_line("View key: "); if (std::cin.eof()) return false; if (viewkey_string.empty()) { @@ -1271,7 +1289,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) { m_wallet_file = m_generate_from_keys; // parse address - std::string address_string = command_line::input_line("Standard address: "); + std::string address_string = input_line("Standard address: "); if (std::cin.eof()) return false; if (address_string.empty()) { @@ -1291,7 +1309,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) } // parse spend secret key - std::string spendkey_string = command_line::input_line("Secret spend key: "); + std::string spendkey_string = input_line("Secret spend key: "); if (std::cin.eof()) return false; if (spendkey_string.empty()) { @@ -1307,7 +1325,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) crypto::secret_key spendkey = *reinterpret_cast(spendkey_data.data()); // parse view secret key - std::string viewkey_string = command_line::input_line("Secret view key: "); + std::string viewkey_string = input_line("Secret view key: "); if (std::cin.eof()) return false; if (viewkey_string.empty()) { @@ -1354,7 +1372,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) unsigned int multisig_n; // parse multisig type - std::string multisig_type_string = command_line::input_line("Multisig type (input as M/N with M <= N and M > 1): "); + std::string multisig_type_string = input_line("Multisig type (input as M/N with M <= N and M > 1): "); if (std::cin.eof()) return false; if (multisig_type_string.empty()) @@ -1380,7 +1398,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) message_writer() << boost::format(tr("Generating master wallet from %u of %u multisig wallet keys")) % multisig_m % multisig_n; // parse multisig address - std::string address_string = command_line::input_line("Multisig wallet address: "); + std::string address_string = input_line("Multisig wallet address: "); if (std::cin.eof()) return false; if (address_string.empty()) { @@ -1395,7 +1413,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) } // parse secret view key - std::string viewkey_string = command_line::input_line("Secret view key: "); + std::string viewkey_string = input_line("Secret view key: "); if (std::cin.eof()) return false; if (viewkey_string.empty()) @@ -1435,7 +1453,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) // get N secret spend keys from user for(unsigned int i=0; i(heightstr.substr(8,2)); m_restore_height = m_wallet->get_blockchain_height_by_date(year, month, day); success_msg_writer() << tr("Restore height is: ") << m_restore_height; - std::string confirm = command_line::input_line(tr("Is this okay? (Y/Yes/N/No): ")); + std::string confirm = input_line(tr("Is this okay? (Y/Yes/N/No): ")); if (std::cin.eof()) return false; if(command_line::is_yes(confirm)) @@ -1674,7 +1692,7 @@ std::string simple_wallet::get_mnemonic_language() } while (language_number < 0) { - language_choice = command_line::input_line(tr("Enter the number corresponding to the language of your choice: ")); + language_choice = input_line(tr("Enter the number corresponding to the language of your choice: ")); if (std::cin.eof()) return std::string(); try @@ -1696,7 +1714,7 @@ std::string simple_wallet::get_mnemonic_language() //---------------------------------------------------------------------------------------------------- boost::optional simple_wallet::get_and_verify_password() const { - auto pwd_container = tools::wallet2::password_prompt(m_wallet_file.empty()); + auto pwd_container = default_password_prompter(m_wallet_file.empty()); if (!pwd_container) return boost::none; @@ -1711,7 +1729,7 @@ boost::optional simple_wallet::get_and_verify_passwor bool simple_wallet::new_wallet(const boost::program_options::variables_map& vm, const crypto::secret_key& recovery_key, bool recover, bool two_random, const std::string &old_language) { - auto rc = tools::wallet2::make_new(vm); + auto rc = tools::wallet2::make_new(vm, password_prompter); m_wallet = std::move(rc.first); if (!m_wallet) { @@ -1792,7 +1810,7 @@ bool simple_wallet::new_wallet(const boost::program_options::variables_map& vm, const cryptonote::account_public_address& address, const boost::optional& spendkey, const crypto::secret_key& viewkey) { - auto rc = tools::wallet2::make_new(vm); + auto rc = tools::wallet2::make_new(vm, password_prompter); m_wallet = std::move(rc.first); if (!m_wallet) { @@ -1834,7 +1852,7 @@ bool simple_wallet::open_wallet(const boost::program_options::variables_map& vm) std::string password; try { - auto rc = tools::wallet2::make_from_file(vm, m_wallet_file); + auto rc = tools::wallet2::make_from_file(vm, m_wallet_file, password_prompter); m_wallet = std::move(rc.first); password = std::move(rc.second).password(); if (!m_wallet) @@ -2724,7 +2742,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vectorconfirm_missing_payment_id()) { - std::string accepted = command_line::input_line(tr("No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): ")); + std::string accepted = input_line(tr("No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): ")); if (std::cin.eof()) return true; if (!command_line::is_yes(accepted)) @@ -2808,7 +2826,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector &args_) print_money(total_unmixable) % print_money(total_fee)).str(); } - std::string accepted = command_line::input_line(prompt_str); + std::string accepted = input_line(prompt_str); if (std::cin.eof()) return true; if (!command_line::is_yes(accepted)) @@ -3303,7 +3321,7 @@ bool simple_wallet::sweep_main(uint64_t below, const std::vector &a // prompt is there is no payment id and confirmation is required if (!payment_id_seen && m_wallet->confirm_missing_payment_id()) { - std::string accepted = command_line::input_line(tr("No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): ")); + std::string accepted = input_line(tr("No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): ")); if (std::cin.eof()) return true; if (!command_line::is_yes(accepted)) @@ -3361,7 +3379,7 @@ bool simple_wallet::sweep_main(uint64_t below, const std::vector &a print_money(total_sent) % print_money(total_fee); } - std::string accepted = command_line::input_line(prompt.str()); + std::string accepted = input_line(prompt.str()); if (std::cin.eof()) return true; if (!command_line::is_yes(accepted)) @@ -3657,7 +3675,7 @@ bool simple_wallet::accept_loaded_tx(const std::function get_num_txes, uint64_t fee = amount - amount_to_dests; std::string prompt_str = (boost::format(tr("Loaded %lu transactions, for %s, fee %s, %s, %s, with min ring size %lu, %s. %sIs this okay? (Y/Yes/N/No): ")) % (unsigned long)get_num_txes() % print_money(amount) % print_money(fee) % dest_string % change_string % (unsigned long)min_ring_size % payment_id_string % extra_message).str(); - return command_line::is_yes(command_line::input_line(prompt_str)); + return command_line::is_yes(input_line(prompt_str)); } //---------------------------------------------------------------------------------------------------- bool simple_wallet::accept_loaded_tx(const tools::wallet2::unsigned_tx_set &txs) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index a7161ffcb..4719447e9 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -135,7 +135,7 @@ uint64_t calculate_fee(uint64_t fee_per_kb, const cryptonote::blobdata &blob, ui return calculate_fee(fee_per_kb, blob.size(), fee_multiplier); } -std::unique_ptr make_basic(const boost::program_options::variables_map& vm, const options& opts) +std::unique_ptr make_basic(const boost::program_options::variables_map& vm, const options& opts, const std::function(const char *, bool)> &password_prompter) { const bool testnet = command_line::get_arg(vm, opts.testnet); const bool restricted = command_line::get_arg(vm, opts.restricted); @@ -154,7 +154,9 @@ std::unique_ptr make_basic(const boost::program_options::variabl if (command_line::has_arg(vm, opts.daemon_login)) { auto parsed = tools::login::parse( - command_line::get_arg(vm, opts.daemon_login), false, "Daemon client password" + command_line::get_arg(vm, opts.daemon_login), false, [password_prompter](bool verify) { + return password_prompter("Daemon client password", verify); + } ); if (!parsed) return nullptr; @@ -178,7 +180,7 @@ std::unique_ptr make_basic(const boost::program_options::variabl return wallet; } -boost::optional get_password(const boost::program_options::variables_map& vm, const options& opts, const bool verify) +boost::optional get_password(const boost::program_options::variables_map& vm, const options& opts, const std::function(const char*, bool)> &password_prompter, const bool verify) { if (command_line::has_arg(vm, opts.password) && command_line::has_arg(vm, opts.password_file)) { @@ -207,10 +209,10 @@ boost::optional get_password(const boost::program_opt return {tools::password_container{std::move(password)}}; } - return tools::wallet2::password_prompt(verify); + return password_prompter(verify ? tr("Enter new wallet password") : tr("Wallet password"), verify); } -std::unique_ptr generate_from_json(const std::string& json_file, const boost::program_options::variables_map& vm, const options& opts) +std::unique_ptr generate_from_json(const std::string& json_file, const boost::program_options::variables_map& vm, const options& opts, const std::function(const char *, bool)> &password_prompter) { const bool testnet = command_line::get_arg(vm, opts.testnet); @@ -359,7 +361,7 @@ std::unique_ptr generate_from_json(const std::string& json_file, return false; } - wallet.reset(make_basic(vm, opts).release()); + wallet.reset(make_basic(vm, opts, password_prompter).release()); wallet->set_refresh_from_block_height(field_scan_from_height); try @@ -496,34 +498,22 @@ void wallet2::init_options(boost::program_options::options_description& desc_par command_line::add_arg(desc_params, opts.restricted); } -boost::optional wallet2::password_prompt(const bool new_password) -{ - auto pwd_container = tools::password_container::prompt( - new_password, (new_password ? tr("Enter new wallet password") : tr("Wallet password")) - ); - if (!pwd_container) - { - tools::fail_msg_writer() << tr("failed to read wallet password"); - } - return pwd_container; -} - -std::unique_ptr wallet2::make_from_json(const boost::program_options::variables_map& vm, const std::string& json_file) +std::unique_ptr wallet2::make_from_json(const boost::program_options::variables_map& vm, const std::string& json_file, const std::function(const char *, bool)> &password_prompter) { const options opts{}; - return generate_from_json(json_file, vm, opts); + return generate_from_json(json_file, vm, opts, password_prompter); } std::pair, password_container> wallet2::make_from_file( - const boost::program_options::variables_map& vm, const std::string& wallet_file) + const boost::program_options::variables_map& vm, const std::string& wallet_file, const std::function(const char *, bool)> &password_prompter) { const options opts{}; - auto pwd = get_password(vm, opts, false); + auto pwd = get_password(vm, opts, password_prompter, false); if (!pwd) { return {nullptr, password_container{}}; } - auto wallet = make_basic(vm, opts); + auto wallet = make_basic(vm, opts, password_prompter); if (wallet) { wallet->load(wallet_file, pwd->password()); @@ -531,21 +521,21 @@ std::pair, password_container> wallet2::make_from_file( return {std::move(wallet), std::move(*pwd)}; } -std::pair, password_container> wallet2::make_new(const boost::program_options::variables_map& vm) +std::pair, password_container> wallet2::make_new(const boost::program_options::variables_map& vm, const std::function(const char *, bool)> &password_prompter) { const options opts{}; - auto pwd = get_password(vm, opts, true); + auto pwd = get_password(vm, opts, password_prompter, true); if (!pwd) { return {nullptr, password_container{}}; } - return {make_basic(vm, opts), std::move(*pwd)}; + return {make_basic(vm, opts, password_prompter), std::move(*pwd)}; } -std::unique_ptr wallet2::make_dummy(const boost::program_options::variables_map& vm) +std::unique_ptr wallet2::make_dummy(const boost::program_options::variables_map& vm, const std::function(const char *, bool)> &password_prompter) { const options opts{}; - return make_basic(vm, opts); + return make_basic(vm, opts, password_prompter); } //---------------------------------------------------------------------------------------------------- diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 8576227e8..b07295253 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -155,21 +155,18 @@ namespace tools static bool has_testnet_option(const boost::program_options::variables_map& vm); static void init_options(boost::program_options::options_description& desc_params); - //! \return Password retrieved from prompt. Logs error on failure. - static boost::optional password_prompt(const bool new_password); - //! Uses stdin and stdout. Returns a wallet2 if no errors. - static std::unique_ptr make_from_json(const boost::program_options::variables_map& vm, const std::string& json_file); + static std::unique_ptr make_from_json(const boost::program_options::variables_map& vm, 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> - make_from_file(const boost::program_options::variables_map& vm, const std::string& wallet_file); + make_from_file(const boost::program_options::variables_map& vm, const std::string& wallet_file, const std::function(const char *, bool)> &password_prompter); //! Uses stdin and stdout. Returns a wallet2 and password for wallet with no file if no errors. - static std::pair, password_container> make_new(const boost::program_options::variables_map& vm); + static std::pair, password_container> make_new(const boost::program_options::variables_map& vm, const std::function(const char *, bool)> &password_prompter); //! Just parses variables. - static std::unique_ptr make_dummy(const boost::program_options::variables_map& vm); + static std::unique_ptr make_dummy(const boost::program_options::variables_map& vm, const std::function(const char *, bool)> &password_prompter); static bool verify_password(const std::string& keys_file_name, const std::string& password, bool watch_only); diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index fda8f244a..9dc2baea6 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -60,6 +60,16 @@ namespace const command_line::arg_descriptor arg_wallet_dir = {"wallet-dir", "Directory for newly created wallets"}; constexpr const char default_rpc_username[] = "monero"; + + boost::optional password_prompter(const char *prompt, bool verify) + { + auto pwd_container = tools::password_container::prompt(verify, prompt); + if (!pwd_container) + { + MERROR("failed to read wallet password"); + } + return pwd_container; + } } namespace tools @@ -131,7 +141,7 @@ namespace tools walvars = m_wallet; else { - tmpwal = tools::wallet2::make_dummy(*m_vm); + tmpwal = tools::wallet2::make_dummy(*m_vm, password_prompter); walvars = tmpwal.get(); } boost::optional http_login{}; @@ -1798,7 +1808,7 @@ namespace tools command_line::add_arg(desc, arg_password); po::store(po::parse_command_line(argc, argv, desc), vm2); } - std::unique_ptr wal = tools::wallet2::make_new(vm2).first; + std::unique_ptr wal = tools::wallet2::make_new(vm2, password_prompter).first; if (!wal) { er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR; @@ -1872,7 +1882,7 @@ namespace tools } std::unique_ptr wal = nullptr; try { - wal = tools::wallet2::make_from_file(vm2, wallet_file).first; + wal = tools::wallet2::make_from_file(vm2, wallet_file, password_prompter).first; } catch (const std::exception& e) { @@ -2007,11 +2017,11 @@ int main(int argc, char** argv) { LOG_PRINT_L0(tools::wallet_rpc_server::tr("Loading wallet...")); if(!wallet_file.empty()) { - wal = tools::wallet2::make_from_file(*vm, wallet_file).first; + wal = tools::wallet2::make_from_file(*vm, wallet_file, password_prompter).first; } else { - wal = tools::wallet2::make_from_json(*vm, from_json); + wal = tools::wallet2::make_from_json(*vm, from_json, password_prompter); } if (!wal) { -- cgit v1.2.3 From 437421ce42f1deaa7ec3f28c0c17aff519f1230d Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 28 Oct 2017 23:04:24 +0100 Subject: wallet: move some scoped_message_writer calls from the libs --- src/simplewallet/simplewallet.cpp | 11 +++- src/wallet/wallet2.cpp | 109 ++++++++++++-------------------------- src/wallet/wallet_args.cpp | 33 ++++++++---- src/wallet/wallet_args.h | 1 + src/wallet/wallet_errors.h | 6 +++ src/wallet/wallet_rpc_server.cpp | 12 ++++- 6 files changed, 86 insertions(+), 86 deletions(-) (limited to 'src/simplewallet/simplewallet.cpp') diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 298e60e73..890aec060 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -1501,7 +1501,15 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) else if (!m_generate_from_json.empty()) { m_wallet_file = m_generate_from_json; - m_wallet = tools::wallet2::make_from_json(vm, m_wallet_file, password_prompter); + try + { + m_wallet = tools::wallet2::make_from_json(vm, m_wallet_file, password_prompter); + } + catch (const std::exception &e) + { + fail_msg_writer() << e.what(); + return false; + } if (!m_wallet) return false; } @@ -5702,6 +5710,7 @@ int main(int argc, char* argv[]) "monero-wallet-cli [--wallet-file=|--generate-new-wallet=] []", desc_params, positional_options, + [](const std::string &s, bool emphasis){ tools::scoped_message_writer(emphasis ? epee::console_color_white : epee::console_color_default, true) << s; }, "monero-wallet-cli.log" ); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 4719447e9..7a38be48f 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -144,11 +144,8 @@ std::unique_ptr make_basic(const boost::program_options::variabl auto daemon_host = command_line::get_arg(vm, opts.daemon_host); auto daemon_port = command_line::get_arg(vm, opts.daemon_port); - if (!daemon_address.empty() && !daemon_host.empty() && 0 != daemon_port) - { - tools::fail_msg_writer() << tools::wallet2::tr("can't specify daemon host or port more than once"); - return nullptr; - } + 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")); boost::optional login{}; if (command_line::has_arg(vm, opts.daemon_login)) @@ -184,8 +181,7 @@ boost::optional get_password(const boost::program_opt { if (command_line::has_arg(vm, opts.password) && command_line::has_arg(vm, opts.password_file)) { - tools::fail_msg_writer() << tools::wallet2::tr("can't specify more than one of --password and --password-file"); - return boost::none; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("can't specify more than one of --password and --password-file")); } if (command_line::has_arg(vm, opts.password)) @@ -198,11 +194,7 @@ boost::optional get_password(const boost::program_opt std::string password; bool r = epee::file_io_utils::load_file_to_string(command_line::get_arg(vm, opts.password_file), password); - if (!r) - { - tools::fail_msg_writer() << tools::wallet2::tr("the password file specified could not be read"); - return boost::none; - } + THROW_WALLET_EXCEPTION_IF(!r, tools::error::wallet_internal_error, tools::wallet2::tr("the password file specified could not be read")); // Remove line breaks the user might have inserted boost::trim_right_if(password, boost::is_any_of("\r\n")); @@ -223,22 +215,20 @@ std::unique_ptr generate_from_json(const std::string& json_file, const auto do_generate = [&]() -> bool { std::string buf; if (!epee::file_io_utils::load_file_to_string(json_file, buf)) { - tools::fail_msg_writer() << tools::wallet2::tr("Failed to load file ") << json_file; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, std::string(tools::wallet2::tr("Failed to load file ")) + json_file); return false; } rapidjson::Document json; if (json.Parse(buf.c_str()).HasParseError()) { - tools::fail_msg_writer() << tools::wallet2::tr("Failed to parse JSON"); + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("Failed to parse JSON")); return false; } GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, version, unsigned, Uint, true, 0); const int current_version = 1; - if (field_version > current_version) { - tools::fail_msg_writer() << boost::format(tools::wallet2::tr("Version %u too new, we can only grok up to %u")) % field_version % current_version; - return false; - } + THROW_WALLET_EXCEPTION_IF(field_version > current_version, tools::error::wallet_internal_error, + ((boost::format(tools::wallet2::tr("Version %u too new, we can only grok up to %u")) % field_version % current_version)).str()); GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, filename, std::string, String, true, std::string()); @@ -254,14 +244,12 @@ std::unique_ptr generate_from_json(const std::string& json_file, cryptonote::blobdata viewkey_data; if(!epee::string_tools::parse_hexstr_to_binbuff(field_viewkey, viewkey_data) || viewkey_data.size() != sizeof(crypto::secret_key)) { - tools::fail_msg_writer() << tools::wallet2::tr("failed to parse view key secret key"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to parse view key secret key")); } viewkey = *reinterpret_cast(viewkey_data.data()); crypto::public_key pkey; if (!crypto::secret_key_to_public_key(viewkey, pkey)) { - tools::fail_msg_writer() << tools::wallet2::tr("failed to verify view key secret key"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify view key secret key")); } } @@ -272,14 +260,12 @@ std::unique_ptr generate_from_json(const std::string& json_file, cryptonote::blobdata spendkey_data; if(!epee::string_tools::parse_hexstr_to_binbuff(field_spendkey, spendkey_data) || spendkey_data.size() != sizeof(crypto::secret_key)) { - tools::fail_msg_writer() << tools::wallet2::tr("failed to parse spend key secret key"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to parse spend key secret key")); } spendkey = *reinterpret_cast(spendkey_data.data()); crypto::public_key pkey; if (!crypto::secret_key_to_public_key(spendkey, pkey)) { - tools::fail_msg_writer() << tools::wallet2::tr("failed to verify spend key secret key"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify spend key secret key")); } } @@ -291,8 +277,7 @@ std::unique_ptr generate_from_json(const std::string& json_file, { if (!crypto::ElectrumWords::words_to_bytes(field_seed, recovery_key, old_language)) { - tools::fail_msg_writer() << tools::wallet2::tr("Electrum-style word list failed verification"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("Electrum-style word list failed verification")); } restore_deterministic_wallet = true; @@ -309,13 +294,11 @@ std::unique_ptr generate_from_json(const std::string& json_file, // compatibility checks if (!field_seed_found && !field_viewkey_found && !field_spendkey_found) { - tools::fail_msg_writer() << tools::wallet2::tr("At least one of Electrum-style word list and private view key and private spend key must be specified"); - return false; + THROW_WALLET_EXCEPTION(tools::wallet2::tr("At least one of Electrum-style word list and private view key and private spend key must be specified")); } if (field_seed_found && (field_viewkey_found || field_spendkey_found)) { - tools::fail_msg_writer() << tools::wallet2::tr("Both Electrum-style word list and private key(s) specified"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("Both Electrum-style word list and private key(s) specified")); } // if an address was given, we check keys against it, and deduce the spend @@ -325,41 +308,34 @@ std::unique_ptr generate_from_json(const std::string& json_file, cryptonote::address_parse_info info; if(!get_account_address_from_str(info, testnet, field_address)) { - tools::fail_msg_writer() << tools::wallet2::tr("invalid address"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("invalid address")); } if (field_viewkey_found) { crypto::public_key pkey; if (!crypto::secret_key_to_public_key(viewkey, pkey)) { - tools::fail_msg_writer() << tools::wallet2::tr("failed to verify view key secret key"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify view key secret key")); } if (info.address.m_view_public_key != pkey) { - tools::fail_msg_writer() << tools::wallet2::tr("view key does not match standard address"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("view key does not match standard address")); } } if (field_spendkey_found) { crypto::public_key pkey; if (!crypto::secret_key_to_public_key(spendkey, pkey)) { - tools::fail_msg_writer() << tools::wallet2::tr("failed to verify spend key secret key"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify spend key secret key")); } if (info.address.m_spend_public_key != pkey) { - tools::fail_msg_writer() << tools::wallet2::tr("spend key does not match standard address"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("spend key does not match standard address")); } } } const bool deprecated_wallet = restore_deterministic_wallet && ((old_language == crypto::ElectrumWords::old_language_name) || crypto::ElectrumWords::get_is_old_style_seed(field_seed)); - if (deprecated_wallet) { - tools::fail_msg_writer() << tools::wallet2::tr("Cannot create deprecated wallets from JSON"); - return false; - } + THROW_WALLET_EXCEPTION_IF(deprecated_wallet, tools::error::wallet_internal_error, + tools::wallet2::tr("Cannot create deprecated wallets from JSON")); wallet.reset(make_basic(vm, opts, password_prompter).release()); wallet->set_refresh_from_block_height(field_scan_from_height); @@ -378,8 +354,7 @@ std::unique_ptr generate_from_json(const std::string& json_file, { cryptonote::account_public_address address; if (!crypto::secret_key_to_public_key(viewkey, address.m_view_public_key)) { - tools::fail_msg_writer() << tools::wallet2::tr("failed to verify view key secret key"); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify view key secret key")); } if (field_spendkey.empty()) @@ -391,8 +366,7 @@ std::unique_ptr generate_from_json(const std::string& json_file, cryptonote::address_parse_info info; if(!get_account_address_from_str(info, testnet, field_address)) { - tools::fail_msg_writer() << tools::wallet2::tr("failed to parse address: ") << field_address; - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, std::string(tools::wallet2::tr("failed to parse address: ")) + field_address); } address.m_spend_public_key = info.address.m_spend_public_key; } @@ -406,8 +380,7 @@ std::unique_ptr generate_from_json(const std::string& json_file, else { if (!crypto::secret_key_to_public_key(spendkey, address.m_spend_public_key)) { - tools::fail_msg_writer() << tools::wallet2::tr("failed to verify spend key secret key"); - return false; + 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); } @@ -415,8 +388,7 @@ std::unique_ptr generate_from_json(const std::string& json_file, } catch (const std::exception& e) { - tools::fail_msg_writer() << tools::wallet2::tr("failed to generate new wallet: ") << e.what(); - return false; + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, std::string(tools::wallet2::tr("failed to generate new wallet: ")) + e.what()); } return true; }; @@ -6513,16 +6485,12 @@ uint64_t wallet2::import_key_images(const std::string &filename, uint64_t &spent std::string data; bool r = epee::file_io_utils::load_file_to_string(filename, data); - if (!r) - { - fail_msg_writer() << tr("failed to read file ") << filename; - return 0; - } + THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, std::string(tr("failed to read file ")) + filename); + const size_t magiclen = strlen(KEY_IMAGE_EXPORT_FILE_MAGIC); if (data.size() < magiclen || memcmp(data.data(), KEY_IMAGE_EXPORT_FILE_MAGIC, magiclen)) { - fail_msg_writer() << "Bad key image export file magic in " << filename; - return 0; + THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Bad key image export file magic in ") + filename); } try @@ -6531,31 +6499,22 @@ uint64_t wallet2::import_key_images(const std::string &filename, uint64_t &spent } catch (const std::exception &e) { - fail_msg_writer() << "Failed to decrypt " << filename << ": " << e.what(); - return 0; + THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Failed to decrypt ") + filename + ": " + e.what()); } const size_t headerlen = 2 * sizeof(crypto::public_key); - if (data.size() < headerlen) - { - fail_msg_writer() << "Bad data size from file " << filename; - return 0; - } + THROW_WALLET_EXCEPTION_IF(data.size() < headerlen, error::wallet_internal_error, std::string("Bad data size from file ") + filename); const crypto::public_key &public_spend_key = *(const crypto::public_key*)&data[0]; const crypto::public_key &public_view_key = *(const crypto::public_key*)&data[sizeof(crypto::public_key)]; const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address; if (public_spend_key != keys.m_spend_public_key || public_view_key != keys.m_view_public_key) { - fail_msg_writer() << "Key images from " << filename << " are for a different account"; - return 0; + THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string( "Key images from ") + filename + " are for a different account"); } const size_t record_size = sizeof(crypto::key_image) + sizeof(crypto::signature); - if ((data.size() - headerlen) % record_size) - { - fail_msg_writer() << "Bad data size from file " << filename; - return 0; - } + THROW_WALLET_EXCEPTION_IF((data.size() - headerlen) % record_size, + error::wallet_internal_error, std::string("Bad data size from file ") + filename); size_t nki = (data.size() - headerlen) / record_size; std::vector> ski; diff --git a/src/wallet/wallet_args.cpp b/src/wallet/wallet_args.cpp index df01ec238..cc6bb1de2 100644 --- a/src/wallet/wallet_args.cpp +++ b/src/wallet/wallet_args.cpp @@ -30,7 +30,6 @@ #include #include #include "common/i18n.h" -#include "common/scoped_message_writer.h" #include "common/util.h" #include "misc_log_ex.h" #include "string_tools.h" @@ -50,6 +49,20 @@ #define DEFAULT_MAX_CONCURRENCY 0 #endif +namespace +{ + class Print + { + public: + Print(const std::function &p, bool em = false): print(p), emphasis(em) {} + ~Print() { print(ss.str(), emphasis); } + template std::ostream &operator<<(const T &t) { ss << t; return ss; } + private: + const std::function &print; + std::stringstream ss; + bool emphasis; + }; +} namespace wallet_args { @@ -73,6 +86,7 @@ namespace wallet_args const char* const usage, boost::program_options::options_description desc_params, const boost::program_options::positional_options_description& positional_options, + const std::function &print, const char *default_log_name, bool log_to_console) @@ -118,16 +132,16 @@ namespace wallet_args if (command_line::get_arg(vm, command_line::arg_help)) { - tools::msg_writer() << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL; - tools::msg_writer() << wallet_args::tr("This is the command line monero wallet. It needs to connect to a monero\n" + Print(print) << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL; + Print(print) << wallet_args::tr("This is the command line monero wallet. It needs to connect to a monero\n" "daemon to work correctly.") << ENDL; - tools::msg_writer() << wallet_args::tr("Usage:") << ENDL << " " << usage; - tools::msg_writer() << desc_all; + Print(print) << wallet_args::tr("Usage:") << ENDL << " " << usage; + Print(print) << desc_all; return false; } else if (command_line::get_arg(vm, command_line::arg_version)) { - tools::msg_writer() << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")"; + Print(print) << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")"; return false; } @@ -142,7 +156,7 @@ namespace wallet_args } else { - tools::fail_msg_writer() << wallet_args::tr("Can't find config file ") << config; + MERROR(wallet_args::tr("Can't find config file ") << config); return false; } } @@ -167,14 +181,15 @@ namespace wallet_args if(command_line::has_arg(vm, arg_max_concurrency)) tools::set_max_concurrency(command_line::get_arg(vm, arg_max_concurrency)); - tools::scoped_message_writer(epee::console_color_white, true) << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")"; + Print(print) << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")"; if (!command_line::is_arg_defaulted(vm, arg_log_level)) MINFO("Setting log level = " << command_line::get_arg(vm, arg_log_level)); else MINFO("Setting log levels = " << getenv("MONERO_LOGS")); MINFO(wallet_args::tr("Logging to: ") << log_path); - tools::scoped_message_writer(epee::console_color_white, true) << boost::format(wallet_args::tr("Logging to %s")) % log_path; + + Print(print) << boost::format(wallet_args::tr("Logging to %s")) % log_path; return {std::move(vm)}; } diff --git a/src/wallet/wallet_args.h b/src/wallet/wallet_args.h index cf23ffded..8974098ad 100644 --- a/src/wallet/wallet_args.h +++ b/src/wallet/wallet_args.h @@ -50,5 +50,6 @@ namespace wallet_args const char* const usage, boost::program_options::options_description desc_params, const boost::program_options::positional_options_description& positional_options, + const std::function &print, const char *default_log_name, bool log_to_console = false); } diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h index 9d66f125e..41eb77451 100644 --- a/src/wallet/wallet_errors.h +++ b/src/wallet/wallet_errors.h @@ -765,6 +765,12 @@ namespace tools #define STRINGIZE_DETAIL(x) #x #define STRINGIZE(x) STRINGIZE_DETAIL(x) +#define THROW_WALLET_EXCEPTION(err_type, ...) \ + do { \ + LOG_ERROR("THROW EXCEPTION: " << #err_type); \ + tools::error::throw_wallet_ex(std::string(__FILE__ ":" STRINGIZE(__LINE__)), ## __VA_ARGS__); \ + } while(0) + #define THROW_WALLET_EXCEPTION_IF(cond, err_type, ...) \ if (cond) \ { \ diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 9dc2baea6..173cc7bbe 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -38,6 +38,7 @@ using namespace epee; #include "wallet/wallet_args.h" #include "common/command_line.h" #include "common/i18n.h" +#include "common/scoped_message_writer.h" #include "cryptonote_basic/cryptonote_format_utils.h" #include "cryptonote_basic/account.h" #include "wallet_rpc_server_commands_defs.h" @@ -1981,6 +1982,7 @@ int main(int argc, char** argv) { "monero-wallet-rpc [--wallet-file=|--generate-from-json=|--wallet-dir=] [--rpc-bind-port=]", desc_params, po::positional_options_description(), + [](const std::string &s, bool emphasis){ tools::scoped_message_writer(emphasis ? epee::console_color_white : epee::console_color_default, true) << s; }, "monero-wallet-rpc.log", true ); @@ -2021,7 +2023,15 @@ int main(int argc, char** argv) { } else { - wal = tools::wallet2::make_from_json(*vm, from_json, password_prompter); + try + { + wal = tools::wallet2::make_from_json(*vm, from_json, password_prompter); + } + catch (const std::exception &e) + { + MERROR("Error creating wallet: " << e.what()); + return 1; + } } if (!wal) { -- cgit v1.2.3