Merge pull request #4324
44259e56
wallet: ask-password can now ask without encrypting the secret spend key (moneromooo-monero)
This commit is contained in:
commit
d743994086
|
@ -29,14 +29,14 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, name, type, jtype, mandatory, def) \
|
#define GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, name, type, jtype, mandatory, def) \
|
||||||
type field_##name = def; \
|
type field_##name = static_cast<type>(def); \
|
||||||
bool field_##name##_found = false; \
|
bool field_##name##_found = false; \
|
||||||
(void)field_##name##_found; \
|
(void)field_##name##_found; \
|
||||||
do if (json.HasMember(#name)) \
|
do if (json.HasMember(#name)) \
|
||||||
{ \
|
{ \
|
||||||
if (json[#name].Is##jtype()) \
|
if (json[#name].Is##jtype()) \
|
||||||
{ \
|
{ \
|
||||||
field_##name = json[#name].Get##jtype(); \
|
field_##name = static_cast<type>(json[#name].Get##jtype()); \
|
||||||
field_##name##_found = true; \
|
field_##name##_found = true; \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
|
|
|
@ -1992,18 +1992,29 @@ bool simple_wallet::set_ask_password(const std::vector<std::string> &args/* = st
|
||||||
const auto pwd_container = get_and_verify_password();
|
const auto pwd_container = get_and_verify_password();
|
||||||
if (pwd_container)
|
if (pwd_container)
|
||||||
{
|
{
|
||||||
parse_bool_and_use(args[1], [&](bool r) {
|
tools::wallet2::AskPasswordType ask = tools::wallet2::AskPasswordToDecrypt;
|
||||||
const bool cur_r = m_wallet->ask_password();
|
if (args[1] == "never" || args[1] == "0")
|
||||||
|
ask = tools::wallet2::AskPasswordNever;
|
||||||
|
else if (args[1] == "action" || args[1] == "1")
|
||||||
|
ask = tools::wallet2::AskPasswordOnAction;
|
||||||
|
else if (args[1] == "encrypt" || args[1] == "decrypt" || args[1] == "2")
|
||||||
|
ask = tools::wallet2::AskPasswordToDecrypt;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fail_msg_writer() << tr("invalid argument: must be either 0/never, 1/action, or 2/encrypt/decrypt");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tools::wallet2::AskPasswordType cur_ask = m_wallet->ask_password();
|
||||||
if (!m_wallet->watch_only())
|
if (!m_wallet->watch_only())
|
||||||
{
|
{
|
||||||
if (cur_r && !r)
|
if (cur_ask == tools::wallet2::AskPasswordToDecrypt && ask != tools::wallet2::AskPasswordToDecrypt)
|
||||||
m_wallet->decrypt_keys(pwd_container->password());
|
m_wallet->decrypt_keys(pwd_container->password());
|
||||||
else if (!cur_r && r)
|
else if (cur_ask != tools::wallet2::AskPasswordToDecrypt && ask == tools::wallet2::AskPasswordToDecrypt)
|
||||||
m_wallet->encrypt_keys(pwd_container->password());
|
m_wallet->encrypt_keys(pwd_container->password());
|
||||||
}
|
}
|
||||||
m_wallet->ask_password(r);
|
m_wallet->ask_password(ask);
|
||||||
m_wallet->rewrite(m_wallet_file, pwd_container->password());
|
m_wallet->rewrite(m_wallet_file, pwd_container->password());
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2394,7 +2405,7 @@ simple_wallet::simple_wallet()
|
||||||
"priority [0|1|2|3|4]\n "
|
"priority [0|1|2|3|4]\n "
|
||||||
" Set the fee to default/unimportant/normal/elevated/priority.\n "
|
" Set the fee to default/unimportant/normal/elevated/priority.\n "
|
||||||
"confirm-missing-payment-id <1|0>\n "
|
"confirm-missing-payment-id <1|0>\n "
|
||||||
"ask-password <1|0>\n "
|
"ask-password <0|1|2 (or never|action|decrypt)>\n "
|
||||||
"unit <monero|millinero|micronero|nanonero|piconero>\n "
|
"unit <monero|millinero|micronero|nanonero|piconero>\n "
|
||||||
" Set the default monero (sub-)unit.\n "
|
" Set the default monero (sub-)unit.\n "
|
||||||
"min-outputs-count [n]\n "
|
"min-outputs-count [n]\n "
|
||||||
|
@ -2607,6 +2618,13 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
|
||||||
uint32_t priority = m_wallet->get_default_priority();
|
uint32_t priority = m_wallet->get_default_priority();
|
||||||
if (priority < allowed_priority_strings.size())
|
if (priority < allowed_priority_strings.size())
|
||||||
priority_string = allowed_priority_strings[priority];
|
priority_string = allowed_priority_strings[priority];
|
||||||
|
std::string ask_password_string = "invalid";
|
||||||
|
switch (m_wallet->ask_password())
|
||||||
|
{
|
||||||
|
case tools::wallet2::AskPasswordNever: ask_password_string = "never"; break;
|
||||||
|
case tools::wallet2::AskPasswordOnAction: ask_password_string = "action"; break;
|
||||||
|
case tools::wallet2::AskPasswordToDecrypt: ask_password_string = "decrypt"; break;
|
||||||
|
}
|
||||||
success_msg_writer() << "seed = " << seed_language;
|
success_msg_writer() << "seed = " << seed_language;
|
||||||
success_msg_writer() << "always-confirm-transfers = " << m_wallet->always_confirm_transfers();
|
success_msg_writer() << "always-confirm-transfers = " << m_wallet->always_confirm_transfers();
|
||||||
success_msg_writer() << "print-ring-members = " << m_wallet->print_ring_members();
|
success_msg_writer() << "print-ring-members = " << m_wallet->print_ring_members();
|
||||||
|
@ -2616,7 +2634,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
|
||||||
success_msg_writer() << "refresh-type = " << get_refresh_type_name(m_wallet->get_refresh_type());
|
success_msg_writer() << "refresh-type = " << get_refresh_type_name(m_wallet->get_refresh_type());
|
||||||
success_msg_writer() << "priority = " << priority<< " (" << priority_string << ")";
|
success_msg_writer() << "priority = " << priority<< " (" << priority_string << ")";
|
||||||
success_msg_writer() << "confirm-missing-payment-id = " << m_wallet->confirm_missing_payment_id();
|
success_msg_writer() << "confirm-missing-payment-id = " << m_wallet->confirm_missing_payment_id();
|
||||||
success_msg_writer() << "ask-password = " << m_wallet->ask_password();
|
success_msg_writer() << "ask-password = " << m_wallet->ask_password() << " (" << ask_password_string << ")";
|
||||||
success_msg_writer() << "unit = " << cryptonote::get_unit(cryptonote::get_default_decimal_point());
|
success_msg_writer() << "unit = " << cryptonote::get_unit(cryptonote::get_default_decimal_point());
|
||||||
success_msg_writer() << "min-outputs-count = " << m_wallet->get_min_output_count();
|
success_msg_writer() << "min-outputs-count = " << m_wallet->get_min_output_count();
|
||||||
success_msg_writer() << "min-outputs-value = " << cryptonote::print_money(m_wallet->get_min_output_value());
|
success_msg_writer() << "min-outputs-value = " << cryptonote::print_money(m_wallet->get_min_output_value());
|
||||||
|
@ -2672,7 +2690,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
|
||||||
CHECK_SIMPLE_VARIABLE("refresh-type", set_refresh_type, tr("full (slowest, no assumptions); optimize-coinbase (fast, assumes the whole coinbase is paid to a single address); no-coinbase (fastest, assumes we receive no coinbase transaction), default (same as optimize-coinbase)"));
|
CHECK_SIMPLE_VARIABLE("refresh-type", set_refresh_type, tr("full (slowest, no assumptions); optimize-coinbase (fast, assumes the whole coinbase is paid to a single address); no-coinbase (fastest, assumes we receive no coinbase transaction), default (same as optimize-coinbase)"));
|
||||||
CHECK_SIMPLE_VARIABLE("priority", set_default_priority, tr("0, 1, 2, 3, or 4, or one of ") << join_priority_strings(", "));
|
CHECK_SIMPLE_VARIABLE("priority", set_default_priority, tr("0, 1, 2, 3, or 4, or one of ") << join_priority_strings(", "));
|
||||||
CHECK_SIMPLE_VARIABLE("confirm-missing-payment-id", set_confirm_missing_payment_id, tr("0 or 1"));
|
CHECK_SIMPLE_VARIABLE("confirm-missing-payment-id", set_confirm_missing_payment_id, tr("0 or 1"));
|
||||||
CHECK_SIMPLE_VARIABLE("ask-password", set_ask_password, tr("0 or 1"));
|
CHECK_SIMPLE_VARIABLE("ask-password", set_ask_password, tr("0|1|2 (or never|action|decrypt)"));
|
||||||
CHECK_SIMPLE_VARIABLE("unit", set_unit, tr("monero, millinero, micronero, nanonero, piconero"));
|
CHECK_SIMPLE_VARIABLE("unit", set_unit, tr("monero, millinero, micronero, nanonero, piconero"));
|
||||||
CHECK_SIMPLE_VARIABLE("min-outputs-count", set_min_output_count, tr("unsigned integer"));
|
CHECK_SIMPLE_VARIABLE("min-outputs-count", set_min_output_count, tr("unsigned integer"));
|
||||||
CHECK_SIMPLE_VARIABLE("min-outputs-value", set_min_output_value, tr("amount"));
|
CHECK_SIMPLE_VARIABLE("min-outputs-value", set_min_output_value, tr("amount"));
|
||||||
|
|
|
@ -200,7 +200,7 @@ std::string get_weight_string(const cryptonote::transaction &tx, size_t blob_siz
|
||||||
return get_weight_string(get_transaction_weight(tx, blob_size));
|
return get_weight_string(get_transaction_weight(tx, blob_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variables_map& vm, bool rpc, const options& opts, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
|
std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variables_map& vm, bool unattended, const options& opts, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
|
||||||
{
|
{
|
||||||
const bool testnet = command_line::get_arg(vm, opts.testnet);
|
const bool testnet = command_line::get_arg(vm, opts.testnet);
|
||||||
const bool stagenet = command_line::get_arg(vm, opts.stagenet);
|
const bool stagenet = command_line::get_arg(vm, opts.stagenet);
|
||||||
|
@ -262,7 +262,7 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<tools::wallet2> wallet(new tools::wallet2(nettype, kdf_rounds));
|
std::unique_ptr<tools::wallet2> wallet(new tools::wallet2(nettype, kdf_rounds));
|
||||||
wallet->init(rpc, std::move(daemon_address), std::move(login), 0, false, *trusted_daemon);
|
wallet->init(unattended, std::move(daemon_address), std::move(login), 0, false, *trusted_daemon);
|
||||||
boost::filesystem::path ringdb_path = command_line::get_arg(vm, opts.shared_ringdb_dir);
|
boost::filesystem::path ringdb_path = command_line::get_arg(vm, opts.shared_ringdb_dir);
|
||||||
wallet->set_ring_database(ringdb_path.string());
|
wallet->set_ring_database(ringdb_path.string());
|
||||||
return wallet;
|
return wallet;
|
||||||
|
@ -297,7 +297,7 @@ boost::optional<tools::password_container> get_password(const boost::program_opt
|
||||||
return password_prompter(verify ? tr("Enter a new password for the wallet") : tr("Wallet password"), verify);
|
return password_prompter(verify ? tr("Enter a new password for the wallet") : tr("Wallet password"), verify);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, const boost::program_options::variables_map& vm, bool rpc, const options& opts, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
|
std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, const boost::program_options::variables_map& vm, bool unattended, const options& opts, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
|
||||||
{
|
{
|
||||||
const bool testnet = command_line::get_arg(vm, opts.testnet);
|
const bool testnet = command_line::get_arg(vm, opts.testnet);
|
||||||
const bool stagenet = command_line::get_arg(vm, opts.stagenet);
|
const bool stagenet = command_line::get_arg(vm, opts.stagenet);
|
||||||
|
@ -435,7 +435,7 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file,
|
||||||
THROW_WALLET_EXCEPTION_IF(deprecated_wallet, tools::error::wallet_internal_error,
|
THROW_WALLET_EXCEPTION_IF(deprecated_wallet, tools::error::wallet_internal_error,
|
||||||
tools::wallet2::tr("Cannot generate deprecated wallets from JSON"));
|
tools::wallet2::tr("Cannot generate deprecated wallets from JSON"));
|
||||||
|
|
||||||
wallet.reset(make_basic(vm, rpc, opts, password_prompter).release());
|
wallet.reset(make_basic(vm, unattended, opts, password_prompter).release());
|
||||||
wallet->set_refresh_from_block_height(field_scan_from_height);
|
wallet->set_refresh_from_block_height(field_scan_from_height);
|
||||||
wallet->explicit_refresh_from_block_height(field_scan_from_height_found);
|
wallet->explicit_refresh_from_block_height(field_scan_from_height_found);
|
||||||
|
|
||||||
|
@ -721,8 +721,11 @@ wallet_keys_unlocker::wallet_keys_unlocker(wallet2 &w, const boost::optional<too
|
||||||
w(w),
|
w(w),
|
||||||
locked(password != boost::none)
|
locked(password != boost::none)
|
||||||
{
|
{
|
||||||
if (!locked || w.is_rpc())
|
if (!locked || w.is_unattended() || w.ask_password() != tools::wallet2::AskPasswordToDecrypt)
|
||||||
|
{
|
||||||
|
locked = false;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
const epee::wipeable_string pass = password->password();
|
const epee::wipeable_string pass = password->password();
|
||||||
w.generate_chacha_key_from_password(pass, key);
|
w.generate_chacha_key_from_password(pass, key);
|
||||||
w.decrypt_keys(key);
|
w.decrypt_keys(key);
|
||||||
|
@ -764,7 +767,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds):
|
||||||
m_explicit_refresh_from_block_height(true),
|
m_explicit_refresh_from_block_height(true),
|
||||||
m_confirm_missing_payment_id(true),
|
m_confirm_missing_payment_id(true),
|
||||||
m_confirm_non_default_ring_size(true),
|
m_confirm_non_default_ring_size(true),
|
||||||
m_ask_password(true),
|
m_ask_password(AskPasswordToDecrypt),
|
||||||
m_min_output_count(0),
|
m_min_output_count(0),
|
||||||
m_min_output_value(0),
|
m_min_output_value(0),
|
||||||
m_merge_destinations(false),
|
m_merge_destinations(false),
|
||||||
|
@ -793,7 +796,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds):
|
||||||
m_ringdb(),
|
m_ringdb(),
|
||||||
m_last_block_reward(0),
|
m_last_block_reward(0),
|
||||||
m_encrypt_keys_after_refresh(boost::none),
|
m_encrypt_keys_after_refresh(boost::none),
|
||||||
m_rpc(false)
|
m_unattended(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -828,14 +831,14 @@ void wallet2::init_options(boost::program_options::options_description& desc_par
|
||||||
command_line::add_arg(desc_params, opts.kdf_rounds);
|
command_line::add_arg(desc_params, opts.kdf_rounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<wallet2> wallet2::make_from_json(const boost::program_options::variables_map& vm, bool rpc, const std::string& json_file, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
|
std::unique_ptr<wallet2> wallet2::make_from_json(const boost::program_options::variables_map& vm, bool unattended, const std::string& json_file, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
|
||||||
{
|
{
|
||||||
const options opts{};
|
const options opts{};
|
||||||
return generate_from_json(json_file, vm, rpc, opts, password_prompter);
|
return generate_from_json(json_file, vm, unattended, opts, password_prompter);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::unique_ptr<wallet2>, password_container> wallet2::make_from_file(
|
std::pair<std::unique_ptr<wallet2>, password_container> wallet2::make_from_file(
|
||||||
const boost::program_options::variables_map& vm, bool rpc, const std::string& wallet_file, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
|
const boost::program_options::variables_map& vm, bool unattended, const std::string& wallet_file, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
|
||||||
{
|
{
|
||||||
const options opts{};
|
const options opts{};
|
||||||
auto pwd = get_password(vm, opts, password_prompter, false);
|
auto pwd = get_password(vm, opts, password_prompter, false);
|
||||||
|
@ -843,7 +846,7 @@ std::pair<std::unique_ptr<wallet2>, password_container> wallet2::make_from_file(
|
||||||
{
|
{
|
||||||
return {nullptr, password_container{}};
|
return {nullptr, password_container{}};
|
||||||
}
|
}
|
||||||
auto wallet = make_basic(vm, rpc, opts, password_prompter);
|
auto wallet = make_basic(vm, unattended, opts, password_prompter);
|
||||||
if (wallet)
|
if (wallet)
|
||||||
{
|
{
|
||||||
wallet->load(wallet_file, pwd->password());
|
wallet->load(wallet_file, pwd->password());
|
||||||
|
@ -851,7 +854,7 @@ std::pair<std::unique_ptr<wallet2>, password_container> wallet2::make_from_file(
|
||||||
return {std::move(wallet), std::move(*pwd)};
|
return {std::move(wallet), std::move(*pwd)};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::unique_ptr<wallet2>, password_container> wallet2::make_new(const boost::program_options::variables_map& vm, bool rpc, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter)
|
std::pair<std::unique_ptr<wallet2>, password_container> wallet2::make_new(const boost::program_options::variables_map& vm, bool unattended, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter)
|
||||||
{
|
{
|
||||||
const options opts{};
|
const options opts{};
|
||||||
auto pwd = get_password(vm, opts, password_prompter, true);
|
auto pwd = get_password(vm, opts, password_prompter, true);
|
||||||
|
@ -859,19 +862,19 @@ std::pair<std::unique_ptr<wallet2>, password_container> wallet2::make_new(const
|
||||||
{
|
{
|
||||||
return {nullptr, password_container{}};
|
return {nullptr, password_container{}};
|
||||||
}
|
}
|
||||||
return {make_basic(vm, rpc, opts, password_prompter), std::move(*pwd)};
|
return {make_basic(vm, unattended, opts, password_prompter), std::move(*pwd)};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<wallet2> wallet2::make_dummy(const boost::program_options::variables_map& vm, bool rpc, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
|
std::unique_ptr<wallet2> wallet2::make_dummy(const boost::program_options::variables_map& vm, bool unattended, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter)
|
||||||
{
|
{
|
||||||
const options opts{};
|
const options opts{};
|
||||||
return make_basic(vm, rpc, opts, password_prompter);
|
return make_basic(vm, unattended, opts, password_prompter);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
bool wallet2::init(bool rpc, std::string daemon_address, boost::optional<epee::net_utils::http::login> daemon_login, uint64_t upper_transaction_weight_limit, bool ssl, bool trusted_daemon)
|
bool wallet2::init(bool unattended, std::string daemon_address, boost::optional<epee::net_utils::http::login> daemon_login, uint64_t upper_transaction_weight_limit, bool ssl, bool trusted_daemon)
|
||||||
{
|
{
|
||||||
m_rpc = rpc;
|
m_unattended = unattended;
|
||||||
m_checkpoints.init_default_checkpoints(m_nettype);
|
m_checkpoints.init_default_checkpoints(m_nettype);
|
||||||
if(m_http_client.is_connected())
|
if(m_http_client.is_connected())
|
||||||
m_http_client.disconnect();
|
m_http_client.disconnect();
|
||||||
|
@ -1210,7 +1213,7 @@ void wallet2::scan_output(const cryptonote::transaction &tx, const crypto::publi
|
||||||
THROW_WALLET_EXCEPTION_IF(i >= tx.vout.size(), error::wallet_internal_error, "Invalid vout index");
|
THROW_WALLET_EXCEPTION_IF(i >= tx.vout.size(), error::wallet_internal_error, "Invalid vout index");
|
||||||
|
|
||||||
// if keys are encrypted, ask for password
|
// if keys are encrypted, ask for password
|
||||||
if (m_ask_password && !m_rpc && !m_watch_only && !m_multisig_rescan_k)
|
if (m_ask_password == AskPasswordToDecrypt && !m_unattended && !m_watch_only && !m_multisig_rescan_k)
|
||||||
{
|
{
|
||||||
static critical_section password_lock;
|
static critical_section password_lock;
|
||||||
CRITICAL_REGION_LOCAL(password_lock);
|
CRITICAL_REGION_LOCAL(password_lock);
|
||||||
|
@ -2847,7 +2850,7 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable
|
||||||
crypto::chacha_key key;
|
crypto::chacha_key key;
|
||||||
crypto::generate_chacha_key(password.data(), password.size(), key, m_kdf_rounds);
|
crypto::generate_chacha_key(password.data(), password.size(), key, m_kdf_rounds);
|
||||||
|
|
||||||
if (m_ask_password && !m_rpc && !m_watch_only)
|
if (m_ask_password == AskPasswordToDecrypt && !m_unattended && !m_watch_only)
|
||||||
{
|
{
|
||||||
account.encrypt_viewkey(key);
|
account.encrypt_viewkey(key);
|
||||||
account.decrypt_keys(key);
|
account.decrypt_keys(key);
|
||||||
|
@ -2926,7 +2929,7 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable
|
||||||
value2.SetInt(m_confirm_non_default_ring_size ? 1 :0);
|
value2.SetInt(m_confirm_non_default_ring_size ? 1 :0);
|
||||||
json.AddMember("confirm_non_default_ring_size", value2, json.GetAllocator());
|
json.AddMember("confirm_non_default_ring_size", value2, json.GetAllocator());
|
||||||
|
|
||||||
value2.SetInt(m_ask_password ? 1 :0);
|
value2.SetInt(m_ask_password);
|
||||||
json.AddMember("ask_password", value2, json.GetAllocator());
|
json.AddMember("ask_password", value2, json.GetAllocator());
|
||||||
|
|
||||||
value2.SetUint(m_min_output_count);
|
value2.SetUint(m_min_output_count);
|
||||||
|
@ -3007,7 +3010,7 @@ void wallet2::setup_keys(const epee::wipeable_string &password)
|
||||||
crypto::generate_chacha_key(password.data(), password.size(), key, m_kdf_rounds);
|
crypto::generate_chacha_key(password.data(), password.size(), key, m_kdf_rounds);
|
||||||
|
|
||||||
// re-encrypt, but keep viewkey unencrypted
|
// re-encrypt, but keep viewkey unencrypted
|
||||||
if (m_ask_password && !m_rpc && !m_watch_only)
|
if (m_ask_password == AskPasswordToDecrypt && !m_unattended && !m_watch_only)
|
||||||
{
|
{
|
||||||
m_account.encrypt_keys(key);
|
m_account.encrypt_keys(key);
|
||||||
m_account.decrypt_viewkey(key);
|
m_account.decrypt_viewkey(key);
|
||||||
|
@ -3023,7 +3026,7 @@ void wallet2::setup_keys(const epee::wipeable_string &password)
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
void wallet2::change_password(const std::string &filename, const epee::wipeable_string &original_password, const epee::wipeable_string &new_password)
|
void wallet2::change_password(const std::string &filename, const epee::wipeable_string &original_password, const epee::wipeable_string &new_password)
|
||||||
{
|
{
|
||||||
if (m_ask_password && !m_rpc && !m_watch_only)
|
if (m_ask_password == AskPasswordToDecrypt && !m_unattended && !m_watch_only)
|
||||||
decrypt_keys(original_password);
|
decrypt_keys(original_password);
|
||||||
setup_keys(new_password);
|
setup_keys(new_password);
|
||||||
rewrite(filename, new_password);
|
rewrite(filename, new_password);
|
||||||
|
@ -3071,7 +3074,7 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
|
||||||
m_refresh_type = RefreshType::RefreshDefault;
|
m_refresh_type = RefreshType::RefreshDefault;
|
||||||
m_confirm_missing_payment_id = true;
|
m_confirm_missing_payment_id = true;
|
||||||
m_confirm_non_default_ring_size = true;
|
m_confirm_non_default_ring_size = true;
|
||||||
m_ask_password = true;
|
m_ask_password = AskPasswordToDecrypt;
|
||||||
m_min_output_count = 0;
|
m_min_output_count = 0;
|
||||||
m_min_output_value = 0;
|
m_min_output_value = 0;
|
||||||
m_merge_destinations = false;
|
m_merge_destinations = false;
|
||||||
|
@ -3180,7 +3183,7 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
|
||||||
m_confirm_missing_payment_id = field_confirm_missing_payment_id;
|
m_confirm_missing_payment_id = field_confirm_missing_payment_id;
|
||||||
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, confirm_non_default_ring_size, int, Int, false, true);
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, confirm_non_default_ring_size, int, Int, false, true);
|
||||||
m_confirm_non_default_ring_size = field_confirm_non_default_ring_size;
|
m_confirm_non_default_ring_size = field_confirm_non_default_ring_size;
|
||||||
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, ask_password, int, Int, false, true);
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, ask_password, AskPasswordType, Int, false, AskPasswordToDecrypt);
|
||||||
m_ask_password = field_ask_password;
|
m_ask_password = field_ask_password;
|
||||||
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, default_decimal_point, int, Int, false, CRYPTONOTE_DISPLAY_DECIMAL_POINT);
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, default_decimal_point, int, Int, false, CRYPTONOTE_DISPLAY_DECIMAL_POINT);
|
||||||
cryptonote::set_default_decimal_point(field_default_decimal_point);
|
cryptonote::set_default_decimal_point(field_default_decimal_point);
|
||||||
|
@ -3244,7 +3247,7 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// rewrite with encrypted keys, ignore errors
|
// rewrite with encrypted keys, ignore errors
|
||||||
if (m_ask_password && !m_rpc && !m_watch_only)
|
if (m_ask_password == AskPasswordToDecrypt && !m_unattended && !m_watch_only)
|
||||||
encrypt_keys(key);
|
encrypt_keys(key);
|
||||||
bool saved_ret = store_keys(keys_file_name, password, m_watch_only);
|
bool saved_ret = store_keys(keys_file_name, password, m_watch_only);
|
||||||
if (!saved_ret)
|
if (!saved_ret)
|
||||||
|
@ -3252,7 +3255,7 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
|
||||||
// just moan a bit, but not fatal
|
// just moan a bit, but not fatal
|
||||||
MERROR("Error saving keys file with encrypted keys, not fatal");
|
MERROR("Error saving keys file with encrypted keys, not fatal");
|
||||||
}
|
}
|
||||||
if (m_ask_password && !m_rpc && !m_watch_only)
|
if (m_ask_password == AskPasswordToDecrypt && !m_unattended && !m_watch_only)
|
||||||
decrypt_keys(key);
|
decrypt_keys(key);
|
||||||
m_keys_file_locker.reset();
|
m_keys_file_locker.reset();
|
||||||
}
|
}
|
||||||
|
@ -3708,7 +3711,7 @@ std::string wallet2::make_multisig(const epee::wipeable_string &password,
|
||||||
|
|
||||||
// decrypt keys
|
// decrypt keys
|
||||||
epee::misc_utils::auto_scope_leave_caller keys_reencryptor;
|
epee::misc_utils::auto_scope_leave_caller keys_reencryptor;
|
||||||
if (m_ask_password && !m_rpc && !m_watch_only)
|
if (m_ask_password == AskPasswordToDecrypt && !m_unattended && !m_watch_only)
|
||||||
{
|
{
|
||||||
crypto::chacha_key chacha_key;
|
crypto::chacha_key chacha_key;
|
||||||
crypto::generate_chacha_key(password.data(), password.size(), chacha_key, m_kdf_rounds);
|
crypto::generate_chacha_key(password.data(), password.size(), chacha_key, m_kdf_rounds);
|
||||||
|
@ -3851,7 +3854,7 @@ bool wallet2::finalize_multisig(const epee::wipeable_string &password, std::unor
|
||||||
|
|
||||||
// keys are decrypted
|
// keys are decrypted
|
||||||
epee::misc_utils::auto_scope_leave_caller keys_reencryptor;
|
epee::misc_utils::auto_scope_leave_caller keys_reencryptor;
|
||||||
if (m_ask_password && !m_rpc && !m_watch_only)
|
if (m_ask_password == AskPasswordToDecrypt && !m_unattended && !m_watch_only)
|
||||||
{
|
{
|
||||||
crypto::chacha_key chacha_key;
|
crypto::chacha_key chacha_key;
|
||||||
crypto::generate_chacha_key(password.data(), password.size(), chacha_key, m_kdf_rounds);
|
crypto::generate_chacha_key(password.data(), password.size(), chacha_key, m_kdf_rounds);
|
||||||
|
@ -4211,7 +4214,7 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass
|
||||||
LOG_PRINT_L0("Loaded wallet keys file, with public address: " << m_account.get_public_address_str(m_nettype));
|
LOG_PRINT_L0("Loaded wallet keys file, with public address: " << m_account.get_public_address_str(m_nettype));
|
||||||
lock_keys_file();
|
lock_keys_file();
|
||||||
|
|
||||||
wallet_keys_unlocker unlocker(*this, m_ask_password && !m_rpc && !m_watch_only, password);
|
wallet_keys_unlocker unlocker(*this, m_ask_password == AskPasswordToDecrypt && !m_unattended && !m_watch_only, password);
|
||||||
|
|
||||||
//keys loaded ok!
|
//keys loaded ok!
|
||||||
//try to load wallet file. but even if we failed, it is not big problem
|
//try to load wallet file. but even if we failed, it is not big problem
|
||||||
|
|
|
@ -162,6 +162,12 @@ namespace tools
|
||||||
RefreshDefault = RefreshOptimizeCoinbase,
|
RefreshDefault = RefreshOptimizeCoinbase,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum AskPasswordType {
|
||||||
|
AskPasswordNever = 0,
|
||||||
|
AskPasswordOnAction = 1,
|
||||||
|
AskPasswordToDecrypt = 2,
|
||||||
|
};
|
||||||
|
|
||||||
static const char* tr(const char* str);
|
static const char* tr(const char* str);
|
||||||
|
|
||||||
static bool has_testnet_option(const boost::program_options::variables_map& vm);
|
static bool has_testnet_option(const boost::program_options::variables_map& vm);
|
||||||
|
@ -169,17 +175,17 @@ namespace tools
|
||||||
static void init_options(boost::program_options::options_description& desc_params);
|
static void init_options(boost::program_options::options_description& desc_params);
|
||||||
|
|
||||||
//! Uses stdin and stdout. Returns a wallet2 if no errors.
|
//! Uses stdin and stdout. Returns a wallet2 if no errors.
|
||||||
static std::unique_ptr<wallet2> make_from_json(const boost::program_options::variables_map& vm, bool rpc, const std::string& json_file, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter);
|
static std::unique_ptr<wallet2> make_from_json(const boost::program_options::variables_map& vm, bool unattended, const std::string& json_file, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter);
|
||||||
|
|
||||||
//! Uses stdin and stdout. Returns a wallet2 and password for `wallet_file` if no errors.
|
//! Uses stdin and stdout. Returns a wallet2 and password for `wallet_file` if no errors.
|
||||||
static std::pair<std::unique_ptr<wallet2>, password_container>
|
static std::pair<std::unique_ptr<wallet2>, password_container>
|
||||||
make_from_file(const boost::program_options::variables_map& vm, bool rpc, const std::string& wallet_file, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter);
|
make_from_file(const boost::program_options::variables_map& vm, bool unattended, const std::string& wallet_file, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter);
|
||||||
|
|
||||||
//! Uses stdin and stdout. Returns a wallet2 and password for wallet with no file if no errors.
|
//! Uses stdin and stdout. Returns a wallet2 and password for wallet with no file if no errors.
|
||||||
static std::pair<std::unique_ptr<wallet2>, password_container> make_new(const boost::program_options::variables_map& vm, bool rpc, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter);
|
static std::pair<std::unique_ptr<wallet2>, password_container> make_new(const boost::program_options::variables_map& vm, bool unattended, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter);
|
||||||
|
|
||||||
//! Just parses variables.
|
//! Just parses variables.
|
||||||
static std::unique_ptr<wallet2> make_dummy(const boost::program_options::variables_map& vm, bool rpc, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter);
|
static std::unique_ptr<wallet2> make_dummy(const boost::program_options::variables_map& vm, bool unattended, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter);
|
||||||
|
|
||||||
static bool verify_password(const std::string& keys_file_name, const epee::wipeable_string& password, bool no_spend_key, hw::device &hwdev, uint64_t kdf_rounds);
|
static bool verify_password(const std::string& keys_file_name, const epee::wipeable_string& password, bool no_spend_key, hw::device &hwdev, uint64_t kdf_rounds);
|
||||||
|
|
||||||
|
@ -632,7 +638,7 @@ namespace tools
|
||||||
bool explicit_refresh_from_block_height() const {return m_explicit_refresh_from_block_height;}
|
bool explicit_refresh_from_block_height() const {return m_explicit_refresh_from_block_height;}
|
||||||
|
|
||||||
bool deinit();
|
bool deinit();
|
||||||
bool init(bool rpc, std::string daemon_address = "http://localhost:8080",
|
bool init(bool unatteded, std::string daemon_address = "http://localhost:8080",
|
||||||
boost::optional<epee::net_utils::http::login> daemon_login = boost::none, uint64_t upper_transaction_weight_limit = 0, bool ssl = false, bool trusted_daemon = false);
|
boost::optional<epee::net_utils::http::login> daemon_login = boost::none, uint64_t upper_transaction_weight_limit = 0, bool ssl = false, bool trusted_daemon = false);
|
||||||
|
|
||||||
void stop() { m_run.store(false, std::memory_order_relaxed); }
|
void stop() { m_run.store(false, std::memory_order_relaxed); }
|
||||||
|
@ -906,8 +912,8 @@ namespace tools
|
||||||
void auto_refresh(bool r) { m_auto_refresh = r; }
|
void auto_refresh(bool r) { m_auto_refresh = r; }
|
||||||
bool confirm_missing_payment_id() const { return m_confirm_missing_payment_id; }
|
bool confirm_missing_payment_id() const { return m_confirm_missing_payment_id; }
|
||||||
void confirm_missing_payment_id(bool always) { m_confirm_missing_payment_id = always; }
|
void confirm_missing_payment_id(bool always) { m_confirm_missing_payment_id = always; }
|
||||||
bool ask_password() const { return m_ask_password; }
|
AskPasswordType ask_password() const { return m_ask_password; }
|
||||||
void ask_password(bool always) { m_ask_password = always; }
|
void ask_password(AskPasswordType ask) { m_ask_password = ask; }
|
||||||
void set_min_output_count(uint32_t count) { m_min_output_count = count; }
|
void set_min_output_count(uint32_t count) { m_min_output_count = count; }
|
||||||
uint32_t get_min_output_count() const { return m_min_output_count; }
|
uint32_t get_min_output_count() const { return m_min_output_count; }
|
||||||
void set_min_output_value(uint64_t value) { m_min_output_value = value; }
|
void set_min_output_value(uint64_t value) { m_min_output_value = value; }
|
||||||
|
@ -1083,7 +1089,7 @@ namespace tools
|
||||||
uint64_t adjust_mixin(uint64_t mixin) const;
|
uint64_t adjust_mixin(uint64_t mixin) const;
|
||||||
uint32_t adjust_priority(uint32_t priority);
|
uint32_t adjust_priority(uint32_t priority);
|
||||||
|
|
||||||
bool is_rpc() const { return m_rpc; }
|
bool is_unattended() const { return m_unattended; }
|
||||||
|
|
||||||
// Light wallet specific functions
|
// Light wallet specific functions
|
||||||
// fetch unspent outs from lw node and store in m_transfers
|
// fetch unspent outs from lw node and store in m_transfers
|
||||||
|
@ -1297,7 +1303,7 @@ namespace tools
|
||||||
bool m_explicit_refresh_from_block_height;
|
bool m_explicit_refresh_from_block_height;
|
||||||
bool m_confirm_missing_payment_id;
|
bool m_confirm_missing_payment_id;
|
||||||
bool m_confirm_non_default_ring_size;
|
bool m_confirm_non_default_ring_size;
|
||||||
bool m_ask_password;
|
AskPasswordType m_ask_password;
|
||||||
uint32_t m_min_output_count;
|
uint32_t m_min_output_count;
|
||||||
uint64_t m_min_output_value;
|
uint64_t m_min_output_value;
|
||||||
bool m_merge_destinations;
|
bool m_merge_destinations;
|
||||||
|
@ -1339,7 +1345,7 @@ namespace tools
|
||||||
crypto::chacha_key m_cache_key;
|
crypto::chacha_key m_cache_key;
|
||||||
boost::optional<epee::wipeable_string> m_encrypt_keys_after_refresh;
|
boost::optional<epee::wipeable_string> m_encrypt_keys_after_refresh;
|
||||||
|
|
||||||
bool m_rpc;
|
bool m_unattended;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
BOOST_CLASS_VERSION(tools::wallet2, 25)
|
BOOST_CLASS_VERSION(tools::wallet2, 25)
|
||||||
|
|
Loading…
Reference in New Issue