Wallet: Option to export data to ASCII
New CLI wallet variable: export-format with options "binary" (the default), or "ascii". "Binary" behaves as before, "ascii" forces the wallet to convert data to ASCII using base64. Reading files from the disk tries to auto detect what format has been used (using a magic string added when exporting the data). Implements https://github.com/monero-project/monero/issues/2859
This commit is contained in:
parent
cdfa2e58df
commit
63186a01ce
|
@ -1254,7 +1254,7 @@ bool simple_wallet::export_multisig_main(const std::vector<std::string> &args, b
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool r = epee::file_io_utils::save_string_to_file(filename, ciphertext);
|
bool r = m_wallet->save_to_file(filename, ciphertext);
|
||||||
if (!r)
|
if (!r)
|
||||||
{
|
{
|
||||||
fail_msg_writer() << tr("failed to save file ") << filename;
|
fail_msg_writer() << tr("failed to save file ") << filename;
|
||||||
|
@ -1315,7 +1315,7 @@ bool simple_wallet::import_multisig_main(const std::vector<std::string> &args, b
|
||||||
{
|
{
|
||||||
const std::string &filename = args[n];
|
const std::string &filename = args[n];
|
||||||
std::string data;
|
std::string data;
|
||||||
bool r = epee::file_io_utils::load_file_to_string(filename, data);
|
bool r = m_wallet->load_from_file(filename, data);
|
||||||
if (!r)
|
if (!r)
|
||||||
{
|
{
|
||||||
fail_msg_writer() << tr("failed to read file ") << filename;
|
fail_msg_writer() << tr("failed to read file ") << filename;
|
||||||
|
@ -1626,7 +1626,7 @@ bool simple_wallet::export_raw_multisig(const std::vector<std::string> &args)
|
||||||
if (!filenames.empty())
|
if (!filenames.empty())
|
||||||
filenames += ", ";
|
filenames += ", ";
|
||||||
filenames += filename;
|
filenames += filename;
|
||||||
if (!epee::file_io_utils::save_string_to_file(filename, cryptonote::tx_to_blob(ptx.tx)))
|
if (!m_wallet->save_to_file(filename, cryptonote::tx_to_blob(ptx.tx)))
|
||||||
{
|
{
|
||||||
fail_msg_writer() << tr("Failed to export multisig transaction to file ") << filename;
|
fail_msg_writer() << tr("Failed to export multisig transaction to file ") << filename;
|
||||||
return true;
|
return true;
|
||||||
|
@ -2712,6 +2712,35 @@ bool simple_wallet::set_device_name(const std::vector<std::string> &args/* = std
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool simple_wallet::set_export_format(const std::vector<std::string> &args/* = std::vector<std::string()*/)
|
||||||
|
{
|
||||||
|
if (args.size() < 2)
|
||||||
|
{
|
||||||
|
fail_msg_writer() << tr("Export format not specified");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (boost::algorithm::iequals(args[1], "ascii"))
|
||||||
|
{
|
||||||
|
m_wallet->set_export_format(tools::wallet2::ExportFormat::Ascii);
|
||||||
|
}
|
||||||
|
else if (boost::algorithm::iequals(args[1], "binary"))
|
||||||
|
{
|
||||||
|
m_wallet->set_export_format(tools::wallet2::ExportFormat::Binary);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fail_msg_writer() << tr("Export format not recognized.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const auto pwd_container = get_and_verify_password();
|
||||||
|
if (pwd_container)
|
||||||
|
{
|
||||||
|
m_wallet->rewrite(m_wallet_file, pwd_container->password());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool simple_wallet::help(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
|
bool simple_wallet::help(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
|
||||||
{
|
{
|
||||||
if(args.empty())
|
if(args.empty())
|
||||||
|
@ -2912,7 +2941,9 @@ simple_wallet::simple_wallet()
|
||||||
"setup-background-mining <1|0>\n "
|
"setup-background-mining <1|0>\n "
|
||||||
" Whether to enable background mining. Set this to support the network and to get a chance to receive new monero.\n "
|
" Whether to enable background mining. Set this to support the network and to get a chance to receive new monero.\n "
|
||||||
"device-name <device_name[:device_spec]>\n "
|
"device-name <device_name[:device_spec]>\n "
|
||||||
" Device name for hardware wallet."));
|
" Device name for hardware wallet.\n "
|
||||||
|
"export-format <\"binary\"|\"ascii\">\n "
|
||||||
|
" Save all exported files as binary (cannot be copied and pasted) or ascii (can be).\n "));
|
||||||
m_cmd_binder.set_handler("encrypted_seed",
|
m_cmd_binder.set_handler("encrypted_seed",
|
||||||
boost::bind(&simple_wallet::encrypted_seed, this, _1),
|
boost::bind(&simple_wallet::encrypted_seed, this, _1),
|
||||||
tr("Display the encrypted Electrum-style mnemonic seed."));
|
tr("Display the encrypted Electrum-style mnemonic seed."));
|
||||||
|
@ -3278,6 +3309,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
|
||||||
success_msg_writer() << "track-uses = " << m_wallet->track_uses();
|
success_msg_writer() << "track-uses = " << m_wallet->track_uses();
|
||||||
success_msg_writer() << "setup-background-mining = " << setup_background_mining_string;
|
success_msg_writer() << "setup-background-mining = " << setup_background_mining_string;
|
||||||
success_msg_writer() << "device-name = " << m_wallet->device_name();
|
success_msg_writer() << "device-name = " << m_wallet->device_name();
|
||||||
|
success_msg_writer() << "export-format = " << (m_wallet->export_format() == tools::wallet2::ExportFormat::Ascii ? "ascii" : "binary");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3336,6 +3368,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
|
||||||
CHECK_SIMPLE_VARIABLE("track-uses", set_track_uses, tr("0 or 1"));
|
CHECK_SIMPLE_VARIABLE("track-uses", set_track_uses, tr("0 or 1"));
|
||||||
CHECK_SIMPLE_VARIABLE("setup-background-mining", set_setup_background_mining, tr("1/yes or 0/no"));
|
CHECK_SIMPLE_VARIABLE("setup-background-mining", set_setup_background_mining, tr("1/yes or 0/no"));
|
||||||
CHECK_SIMPLE_VARIABLE("device-name", set_device_name, tr("<device_name[:device_spec]>"));
|
CHECK_SIMPLE_VARIABLE("device-name", set_device_name, tr("<device_name[:device_spec]>"));
|
||||||
|
CHECK_SIMPLE_VARIABLE("export-format", set_export_format, tr("\"binary\" or \"ascii\""));
|
||||||
}
|
}
|
||||||
fail_msg_writer() << tr("set: unrecognized argument(s)");
|
fail_msg_writer() << tr("set: unrecognized argument(s)");
|
||||||
return true;
|
return true;
|
||||||
|
@ -7312,7 +7345,7 @@ bool simple_wallet::get_tx_proof(const std::vector<std::string> &args)
|
||||||
{
|
{
|
||||||
std::string sig_str = m_wallet->get_tx_proof(txid, info.address, info.is_subaddress, args.size() == 3 ? args[2] : "");
|
std::string sig_str = m_wallet->get_tx_proof(txid, info.address, info.is_subaddress, args.size() == 3 ? args[2] : "");
|
||||||
const std::string filename = "monero_tx_proof";
|
const std::string filename = "monero_tx_proof";
|
||||||
if (epee::file_io_utils::save_string_to_file(filename, sig_str))
|
if (m_wallet->save_to_file(filename, sig_str, true))
|
||||||
success_msg_writer() << tr("signature file saved to: ") << filename;
|
success_msg_writer() << tr("signature file saved to: ") << filename;
|
||||||
else
|
else
|
||||||
fail_msg_writer() << tr("failed to save signature file");
|
fail_msg_writer() << tr("failed to save signature file");
|
||||||
|
@ -7440,7 +7473,7 @@ bool simple_wallet::check_tx_proof(const std::vector<std::string> &args)
|
||||||
|
|
||||||
// read signature file
|
// read signature file
|
||||||
std::string sig_str;
|
std::string sig_str;
|
||||||
if (!epee::file_io_utils::load_file_to_string(args[2], sig_str))
|
if (!m_wallet->load_from_file(args[2], sig_str))
|
||||||
{
|
{
|
||||||
fail_msg_writer() << tr("failed to load signature file");
|
fail_msg_writer() << tr("failed to load signature file");
|
||||||
return true;
|
return true;
|
||||||
|
@ -7524,7 +7557,7 @@ bool simple_wallet::get_spend_proof(const std::vector<std::string> &args)
|
||||||
{
|
{
|
||||||
const std::string sig_str = m_wallet->get_spend_proof(txid, args.size() == 2 ? args[1] : "");
|
const std::string sig_str = m_wallet->get_spend_proof(txid, args.size() == 2 ? args[1] : "");
|
||||||
const std::string filename = "monero_spend_proof";
|
const std::string filename = "monero_spend_proof";
|
||||||
if (epee::file_io_utils::save_string_to_file(filename, sig_str))
|
if (m_wallet->save_to_file(filename, sig_str, true))
|
||||||
success_msg_writer() << tr("signature file saved to: ") << filename;
|
success_msg_writer() << tr("signature file saved to: ") << filename;
|
||||||
else
|
else
|
||||||
fail_msg_writer() << tr("failed to save signature file");
|
fail_msg_writer() << tr("failed to save signature file");
|
||||||
|
@ -7554,7 +7587,7 @@ bool simple_wallet::check_spend_proof(const std::vector<std::string> &args)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
std::string sig_str;
|
std::string sig_str;
|
||||||
if (!epee::file_io_utils::load_file_to_string(args[1], sig_str))
|
if (!m_wallet->load_from_file(args[1], sig_str))
|
||||||
{
|
{
|
||||||
fail_msg_writer() << tr("failed to load signature file");
|
fail_msg_writer() << tr("failed to load signature file");
|
||||||
return true;
|
return true;
|
||||||
|
@ -7613,7 +7646,7 @@ bool simple_wallet::get_reserve_proof(const std::vector<std::string> &args)
|
||||||
{
|
{
|
||||||
const std::string sig_str = m_wallet->get_reserve_proof(account_minreserve, args.size() == 2 ? args[1] : "");
|
const std::string sig_str = m_wallet->get_reserve_proof(account_minreserve, args.size() == 2 ? args[1] : "");
|
||||||
const std::string filename = "monero_reserve_proof";
|
const std::string filename = "monero_reserve_proof";
|
||||||
if (epee::file_io_utils::save_string_to_file(filename, sig_str))
|
if (m_wallet->save_to_file(filename, sig_str, true))
|
||||||
success_msg_writer() << tr("signature file saved to: ") << filename;
|
success_msg_writer() << tr("signature file saved to: ") << filename;
|
||||||
else
|
else
|
||||||
fail_msg_writer() << tr("failed to save signature file");
|
fail_msg_writer() << tr("failed to save signature file");
|
||||||
|
@ -7648,7 +7681,7 @@ bool simple_wallet::check_reserve_proof(const std::vector<std::string> &args)
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string sig_str;
|
std::string sig_str;
|
||||||
if (!epee::file_io_utils::load_file_to_string(args[1], sig_str))
|
if (!m_wallet->load_from_file(args[1], sig_str))
|
||||||
{
|
{
|
||||||
fail_msg_writer() << tr("failed to load signature file");
|
fail_msg_writer() << tr("failed to load signature file");
|
||||||
return true;
|
return true;
|
||||||
|
@ -9011,7 +9044,7 @@ bool simple_wallet::sign(const std::vector<std::string> &args)
|
||||||
|
|
||||||
std::string filename = args[0];
|
std::string filename = args[0];
|
||||||
std::string data;
|
std::string data;
|
||||||
bool r = epee::file_io_utils::load_file_to_string(filename, data);
|
bool r = m_wallet->load_from_file(filename, data);
|
||||||
if (!r)
|
if (!r)
|
||||||
{
|
{
|
||||||
fail_msg_writer() << tr("failed to read file ") << filename;
|
fail_msg_writer() << tr("failed to read file ") << filename;
|
||||||
|
@ -9037,7 +9070,7 @@ bool simple_wallet::verify(const std::vector<std::string> &args)
|
||||||
std::string signature= args[2];
|
std::string signature= args[2];
|
||||||
|
|
||||||
std::string data;
|
std::string data;
|
||||||
bool r = epee::file_io_utils::load_file_to_string(filename, data);
|
bool r = m_wallet->load_from_file(filename, data);
|
||||||
if (!r)
|
if (!r)
|
||||||
{
|
{
|
||||||
fail_msg_writer() << tr("failed to read file ") << filename;
|
fail_msg_writer() << tr("failed to read file ") << filename;
|
||||||
|
@ -9255,7 +9288,7 @@ bool simple_wallet::export_outputs(const std::vector<std::string> &args_)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::string data = m_wallet->export_outputs_to_str(all);
|
std::string data = m_wallet->export_outputs_to_str(all);
|
||||||
bool r = epee::file_io_utils::save_string_to_file(filename, data);
|
bool r = m_wallet->save_to_file(filename, data);
|
||||||
if (!r)
|
if (!r)
|
||||||
{
|
{
|
||||||
fail_msg_writer() << tr("failed to save file ") << filename;
|
fail_msg_writer() << tr("failed to save file ") << filename;
|
||||||
|
@ -9288,7 +9321,7 @@ bool simple_wallet::import_outputs(const std::vector<std::string> &args)
|
||||||
std::string filename = args[0];
|
std::string filename = args[0];
|
||||||
|
|
||||||
std::string data;
|
std::string data;
|
||||||
bool r = epee::file_io_utils::load_file_to_string(filename, data);
|
bool r = m_wallet->load_from_file(filename, data);
|
||||||
if (!r)
|
if (!r)
|
||||||
{
|
{
|
||||||
fail_msg_writer() << tr("failed to read file ") << filename;
|
fail_msg_writer() << tr("failed to read file ") << filename;
|
||||||
|
@ -9489,7 +9522,7 @@ void simple_wallet::commit_or_save(std::vector<tools::wallet2::pending_tx>& ptx_
|
||||||
tx_to_blob(ptx.tx, blob);
|
tx_to_blob(ptx.tx, blob);
|
||||||
const std::string blob_hex = epee::string_tools::buff_to_hex_nodelimer(blob);
|
const std::string blob_hex = epee::string_tools::buff_to_hex_nodelimer(blob);
|
||||||
const std::string filename = "raw_monero_tx" + (ptx_vector.size() == 1 ? "" : ("_" + std::to_string(i++)));
|
const std::string filename = "raw_monero_tx" + (ptx_vector.size() == 1 ? "" : ("_" + std::to_string(i++)));
|
||||||
if (epee::file_io_utils::save_string_to_file(filename, blob_hex))
|
if (m_wallet->save_to_file(filename, blob_hex, true))
|
||||||
success_msg_writer(true) << tr("Transaction successfully saved to ") << filename << tr(", txid ") << txid;
|
success_msg_writer(true) << tr("Transaction successfully saved to ") << filename << tr(", txid ") << txid;
|
||||||
else
|
else
|
||||||
fail_msg_writer() << tr("Failed to save transaction to ") << filename << tr(", txid ") << txid;
|
fail_msg_writer() << tr("Failed to save transaction to ") << filename << tr(", txid ") << txid;
|
||||||
|
@ -10274,7 +10307,7 @@ void simple_wallet::mms_export(const std::vector<std::string> &args)
|
||||||
if (valid_id)
|
if (valid_id)
|
||||||
{
|
{
|
||||||
const std::string filename = "mms_message_content";
|
const std::string filename = "mms_message_content";
|
||||||
if (epee::file_io_utils::save_string_to_file(filename, m.content))
|
if (m_wallet->save_to_file(filename, m.content))
|
||||||
{
|
{
|
||||||
success_msg_writer() << tr("Message content saved to: ") << filename;
|
success_msg_writer() << tr("Message content saved to: ") << filename;
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,6 +146,7 @@ namespace cryptonote
|
||||||
bool set_track_uses(const std::vector<std::string> &args = std::vector<std::string>());
|
bool set_track_uses(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
bool set_setup_background_mining(const std::vector<std::string> &args = std::vector<std::string>());
|
bool set_setup_background_mining(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
bool set_device_name(const std::vector<std::string> &args = std::vector<std::string>());
|
bool set_device_name(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
|
bool set_export_format(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
bool help(const std::vector<std::string> &args = std::vector<std::string>());
|
bool help(const std::vector<std::string> &args = std::vector<std::string>());
|
||||||
bool start_mining(const std::vector<std::string> &args);
|
bool start_mining(const std::vector<std::string> &args);
|
||||||
bool stop_mining(const std::vector<std::string> &args);
|
bool stop_mining(const std::vector<std::string> &args);
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include <boost/asio/ip/address.hpp>
|
#include <boost/asio/ip/address.hpp>
|
||||||
#include <boost/range/adaptor/transformed.hpp>
|
#include <boost/range/adaptor/transformed.hpp>
|
||||||
#include <boost/preprocessor/stringize.hpp>
|
#include <boost/preprocessor/stringize.hpp>
|
||||||
|
#include <openssl/evp.h>
|
||||||
#include "include_base_utils.h"
|
#include "include_base_utils.h"
|
||||||
using namespace epee;
|
using namespace epee;
|
||||||
|
|
||||||
|
@ -138,6 +139,8 @@ using namespace cryptonote;
|
||||||
static const std::string MULTISIG_SIGNATURE_MAGIC = "SigMultisigPkV1";
|
static const std::string MULTISIG_SIGNATURE_MAGIC = "SigMultisigPkV1";
|
||||||
static const std::string MULTISIG_EXTRA_INFO_MAGIC = "MultisigxV1";
|
static const std::string MULTISIG_EXTRA_INFO_MAGIC = "MultisigxV1";
|
||||||
|
|
||||||
|
static const std::string ASCII_OUTPUT_MAGIC = "MoneroAsciiDataV1";
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
std::string get_default_ringdb_path()
|
std::string get_default_ringdb_path()
|
||||||
|
@ -1143,7 +1146,8 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended):
|
||||||
m_device_last_key_image_sync(0),
|
m_device_last_key_image_sync(0),
|
||||||
m_use_dns(true),
|
m_use_dns(true),
|
||||||
m_offline(false),
|
m_offline(false),
|
||||||
m_rpc_version(0)
|
m_rpc_version(0),
|
||||||
|
m_export_format(ExportFormat::Binary)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3647,6 +3651,9 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable
|
||||||
value2.SetInt(m_original_keys_available ? 1 : 0);
|
value2.SetInt(m_original_keys_available ? 1 : 0);
|
||||||
json.AddMember("original_keys_available", value2, json.GetAllocator());
|
json.AddMember("original_keys_available", value2, json.GetAllocator());
|
||||||
|
|
||||||
|
value2.SetInt(m_export_format);
|
||||||
|
json.AddMember("export_format", value2, json.GetAllocator());
|
||||||
|
|
||||||
value2.SetUint(1);
|
value2.SetUint(1);
|
||||||
json.AddMember("encrypted_secret_keys", value2, json.GetAllocator());
|
json.AddMember("encrypted_secret_keys", value2, json.GetAllocator());
|
||||||
|
|
||||||
|
@ -3684,7 +3691,7 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable
|
||||||
std::string tmp_file_name = keys_file_name + ".new";
|
std::string tmp_file_name = keys_file_name + ".new";
|
||||||
std::string buf;
|
std::string buf;
|
||||||
r = ::serialization::dump_binary(keys_file_data, buf);
|
r = ::serialization::dump_binary(keys_file_data, buf);
|
||||||
r = r && epee::file_io_utils::save_string_to_file(tmp_file_name, buf);
|
r = r && save_to_file(tmp_file_name, buf);
|
||||||
CHECK_AND_ASSERT_MES(r, false, "failed to generate wallet keys file " << tmp_file_name);
|
CHECK_AND_ASSERT_MES(r, false, "failed to generate wallet keys file " << tmp_file_name);
|
||||||
|
|
||||||
unlock_keys_file();
|
unlock_keys_file();
|
||||||
|
@ -3741,7 +3748,7 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
|
||||||
wallet2::keys_file_data keys_file_data;
|
wallet2::keys_file_data keys_file_data;
|
||||||
std::string buf;
|
std::string buf;
|
||||||
bool encrypted_secret_keys = false;
|
bool encrypted_secret_keys = false;
|
||||||
bool r = epee::file_io_utils::load_file_to_string(keys_file_name, buf);
|
bool r = load_from_file(keys_file_name, buf);
|
||||||
THROW_WALLET_EXCEPTION_IF(!r, error::file_read_error, keys_file_name);
|
THROW_WALLET_EXCEPTION_IF(!r, error::file_read_error, keys_file_name);
|
||||||
|
|
||||||
// Decrypt the contents
|
// Decrypt the contents
|
||||||
|
@ -3754,7 +3761,6 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
|
||||||
crypto::chacha20(keys_file_data.account_data.data(), keys_file_data.account_data.size(), key, keys_file_data.iv, &account_data[0]);
|
crypto::chacha20(keys_file_data.account_data.data(), keys_file_data.account_data.size(), key, keys_file_data.iv, &account_data[0]);
|
||||||
if (json.Parse(account_data.c_str()).HasParseError() || !json.IsObject())
|
if (json.Parse(account_data.c_str()).HasParseError() || !json.IsObject())
|
||||||
crypto::chacha8(keys_file_data.account_data.data(), keys_file_data.account_data.size(), key, keys_file_data.iv, &account_data[0]);
|
crypto::chacha8(keys_file_data.account_data.data(), keys_file_data.account_data.size(), key, keys_file_data.iv, &account_data[0]);
|
||||||
|
|
||||||
// The contents should be JSON if the wallet follows the new format.
|
// The contents should be JSON if the wallet follows the new format.
|
||||||
if (json.Parse(account_data.c_str()).HasParseError())
|
if (json.Parse(account_data.c_str()).HasParseError())
|
||||||
{
|
{
|
||||||
|
@ -3793,6 +3799,7 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
|
||||||
m_subaddress_lookahead_major = SUBADDRESS_LOOKAHEAD_MAJOR;
|
m_subaddress_lookahead_major = SUBADDRESS_LOOKAHEAD_MAJOR;
|
||||||
m_subaddress_lookahead_minor = SUBADDRESS_LOOKAHEAD_MINOR;
|
m_subaddress_lookahead_minor = SUBADDRESS_LOOKAHEAD_MINOR;
|
||||||
m_original_keys_available = false;
|
m_original_keys_available = false;
|
||||||
|
m_export_format = ExportFormat::Binary;
|
||||||
m_device_name = "";
|
m_device_name = "";
|
||||||
m_device_derivation_path = "";
|
m_device_derivation_path = "";
|
||||||
m_key_device_type = hw::device::device_type::SOFTWARE;
|
m_key_device_type = hw::device::device_type::SOFTWARE;
|
||||||
|
@ -3954,6 +3961,9 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
|
||||||
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, encrypted_secret_keys, uint32_t, Uint, false, false);
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, encrypted_secret_keys, uint32_t, Uint, false, false);
|
||||||
encrypted_secret_keys = field_encrypted_secret_keys;
|
encrypted_secret_keys = field_encrypted_secret_keys;
|
||||||
|
|
||||||
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, export_format, ExportFormat, Int, false, Binary);
|
||||||
|
m_export_format = field_export_format;
|
||||||
|
|
||||||
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, device_name, std::string, String, false, std::string());
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, device_name, std::string, String, false, std::string());
|
||||||
if (m_device_name.empty())
|
if (m_device_name.empty())
|
||||||
{
|
{
|
||||||
|
@ -4101,7 +4111,7 @@ bool wallet2::verify_password(const std::string& keys_file_name, const epee::wip
|
||||||
wallet2::keys_file_data keys_file_data;
|
wallet2::keys_file_data keys_file_data;
|
||||||
std::string buf;
|
std::string buf;
|
||||||
bool encrypted_secret_keys = false;
|
bool encrypted_secret_keys = false;
|
||||||
bool r = epee::file_io_utils::load_file_to_string(keys_file_name, buf);
|
bool r = load_from_file(keys_file_name, buf);
|
||||||
THROW_WALLET_EXCEPTION_IF(!r, error::file_read_error, keys_file_name);
|
THROW_WALLET_EXCEPTION_IF(!r, error::file_read_error, keys_file_name);
|
||||||
|
|
||||||
// Decrypt the contents
|
// Decrypt the contents
|
||||||
|
@ -4186,7 +4196,7 @@ void wallet2::create_keys_file(const std::string &wallet_, bool watch_only, cons
|
||||||
|
|
||||||
if (create_address_file)
|
if (create_address_file)
|
||||||
{
|
{
|
||||||
r = file_io_utils::save_string_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_nettype));
|
r = save_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_nettype), true);
|
||||||
if(!r) MERROR("String with address text not saved");
|
if(!r) MERROR("String with address text not saved");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4208,7 +4218,7 @@ bool wallet2::query_device(hw::device::device_type& device_type, const std::stri
|
||||||
rapidjson::Document json;
|
rapidjson::Document json;
|
||||||
wallet2::keys_file_data keys_file_data;
|
wallet2::keys_file_data keys_file_data;
|
||||||
std::string buf;
|
std::string buf;
|
||||||
bool r = epee::file_io_utils::load_file_to_string(keys_file_name, buf);
|
bool r = load_from_file(keys_file_name, buf);
|
||||||
THROW_WALLET_EXCEPTION_IF(!r, error::file_read_error, keys_file_name);
|
THROW_WALLET_EXCEPTION_IF(!r, error::file_read_error, keys_file_name);
|
||||||
|
|
||||||
// Decrypt the contents
|
// Decrypt the contents
|
||||||
|
@ -4757,7 +4767,7 @@ std::string wallet2::exchange_multisig_keys(const epee::wipeable_string &passwor
|
||||||
|
|
||||||
if (boost::filesystem::exists(m_wallet_file + ".address.txt"))
|
if (boost::filesystem::exists(m_wallet_file + ".address.txt"))
|
||||||
{
|
{
|
||||||
r = file_io_utils::save_string_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_nettype));
|
r = save_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_nettype), true);
|
||||||
if(!r) MERROR("String with address text not saved");
|
if(!r) MERROR("String with address text not saved");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5266,7 +5276,7 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass
|
||||||
{
|
{
|
||||||
wallet2::cache_file_data cache_file_data;
|
wallet2::cache_file_data cache_file_data;
|
||||||
std::string buf;
|
std::string buf;
|
||||||
bool r = epee::file_io_utils::load_file_to_string(m_wallet_file, buf, std::numeric_limits<size_t>::max());
|
bool r = load_from_file(m_wallet_file, buf, std::numeric_limits<size_t>::max());
|
||||||
THROW_WALLET_EXCEPTION_IF(!r, error::file_read_error, m_wallet_file);
|
THROW_WALLET_EXCEPTION_IF(!r, error::file_read_error, m_wallet_file);
|
||||||
|
|
||||||
// try to read it as an encrypted cache
|
// try to read it as an encrypted cache
|
||||||
|
@ -5501,7 +5511,7 @@ void wallet2::store_to(const std::string &path, const epee::wipeable_string &pas
|
||||||
{
|
{
|
||||||
// save address to the new file
|
// save address to the new file
|
||||||
const std::string address_file = m_wallet_file + ".address.txt";
|
const std::string address_file = m_wallet_file + ".address.txt";
|
||||||
r = file_io_utils::save_string_to_file(address_file, m_account.get_public_address_str(m_nettype));
|
r = save_to_file(address_file, m_account.get_public_address_str(m_nettype), true);
|
||||||
THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_wallet_file);
|
THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_wallet_file);
|
||||||
}
|
}
|
||||||
// remove old wallet file
|
// remove old wallet file
|
||||||
|
@ -5536,7 +5546,7 @@ void wallet2::store_to(const std::string &path, const epee::wipeable_string &pas
|
||||||
binary_archive<true> oar(oss);
|
binary_archive<true> oar(oss);
|
||||||
bool success = ::serialization::serialize(oar, cache_file_data);
|
bool success = ::serialization::serialize(oar, cache_file_data);
|
||||||
if (success) {
|
if (success) {
|
||||||
success = epee::file_io_utils::save_string_to_file(new_file, oss.str());
|
success = save_to_file(new_file, oss.str());
|
||||||
}
|
}
|
||||||
THROW_WALLET_EXCEPTION_IF(!success, error::file_save_error, new_file);
|
THROW_WALLET_EXCEPTION_IF(!success, error::file_save_error, new_file);
|
||||||
#else
|
#else
|
||||||
|
@ -6164,7 +6174,7 @@ bool wallet2::save_tx(const std::vector<pending_tx>& ptx_vector, const std::stri
|
||||||
std::string ciphertext = dump_tx_to_str(ptx_vector);
|
std::string ciphertext = dump_tx_to_str(ptx_vector);
|
||||||
if (ciphertext.empty())
|
if (ciphertext.empty())
|
||||||
return false;
|
return false;
|
||||||
return epee::file_io_utils::save_string_to_file(filename, ciphertext);
|
return save_to_file(filename, ciphertext);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
std::string wallet2::dump_tx_to_str(const std::vector<pending_tx> &ptx_vector) const
|
std::string wallet2::dump_tx_to_str(const std::vector<pending_tx> &ptx_vector) const
|
||||||
|
@ -6206,7 +6216,7 @@ bool wallet2::load_unsigned_tx(const std::string &unsigned_filename, unsigned_tx
|
||||||
LOG_PRINT_L0("File " << unsigned_filename << " does not exist: " << errcode);
|
LOG_PRINT_L0("File " << unsigned_filename << " does not exist: " << errcode);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!epee::file_io_utils::load_file_to_string(unsigned_filename.c_str(), s))
|
if (!load_from_file(unsigned_filename.c_str(), s))
|
||||||
{
|
{
|
||||||
LOG_PRINT_L0("Failed to load from " << unsigned_filename);
|
LOG_PRINT_L0("Failed to load from " << unsigned_filename);
|
||||||
return false;
|
return false;
|
||||||
|
@ -6427,7 +6437,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, const std::string &signed_f
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!epee::file_io_utils::save_string_to_file(signed_filename, ciphertext))
|
if (!save_to_file(signed_filename, ciphertext))
|
||||||
{
|
{
|
||||||
LOG_PRINT_L0("Failed to save file to " << signed_filename);
|
LOG_PRINT_L0("Failed to save file to " << signed_filename);
|
||||||
return false;
|
return false;
|
||||||
|
@ -6439,7 +6449,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, const std::string &signed_f
|
||||||
{
|
{
|
||||||
std::string tx_as_hex = epee::string_tools::buff_to_hex_nodelimer(tx_to_blob(signed_txes.ptx[i].tx));
|
std::string tx_as_hex = epee::string_tools::buff_to_hex_nodelimer(tx_to_blob(signed_txes.ptx[i].tx));
|
||||||
std::string raw_filename = signed_filename + "_raw" + (signed_txes.ptx.size() == 1 ? "" : ("_" + std::to_string(i)));
|
std::string raw_filename = signed_filename + "_raw" + (signed_txes.ptx.size() == 1 ? "" : ("_" + std::to_string(i)));
|
||||||
if (!epee::file_io_utils::save_string_to_file(raw_filename, tx_as_hex))
|
if (!save_to_file(raw_filename, tx_as_hex))
|
||||||
{
|
{
|
||||||
LOG_PRINT_L0("Failed to save file to " << raw_filename);
|
LOG_PRINT_L0("Failed to save file to " << raw_filename);
|
||||||
return false;
|
return false;
|
||||||
|
@ -6487,7 +6497,7 @@ bool wallet2::load_tx(const std::string &signed_filename, std::vector<tools::wal
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!epee::file_io_utils::load_file_to_string(signed_filename.c_str(), s))
|
if (!load_from_file(signed_filename.c_str(), s))
|
||||||
{
|
{
|
||||||
LOG_PRINT_L0("Failed to load from " << signed_filename);
|
LOG_PRINT_L0("Failed to load from " << signed_filename);
|
||||||
return false;
|
return false;
|
||||||
|
@ -6618,7 +6628,7 @@ bool wallet2::save_multisig_tx(const multisig_tx_set &txs, const std::string &fi
|
||||||
std::string ciphertext = save_multisig_tx(txs);
|
std::string ciphertext = save_multisig_tx(txs);
|
||||||
if (ciphertext.empty())
|
if (ciphertext.empty())
|
||||||
return false;
|
return false;
|
||||||
return epee::file_io_utils::save_string_to_file(filename, ciphertext);
|
return save_to_file(filename, ciphertext);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
wallet2::multisig_tx_set wallet2::make_multisig_tx_set(const std::vector<pending_tx>& ptx_vector) const
|
wallet2::multisig_tx_set wallet2::make_multisig_tx_set(const std::vector<pending_tx>& ptx_vector) const
|
||||||
|
@ -6646,7 +6656,7 @@ bool wallet2::save_multisig_tx(const std::vector<pending_tx>& ptx_vector, const
|
||||||
std::string ciphertext = save_multisig_tx(ptx_vector);
|
std::string ciphertext = save_multisig_tx(ptx_vector);
|
||||||
if (ciphertext.empty())
|
if (ciphertext.empty())
|
||||||
return false;
|
return false;
|
||||||
return epee::file_io_utils::save_string_to_file(filename, ciphertext);
|
return save_to_file(filename, ciphertext);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
bool wallet2::parse_multisig_tx_from_str(std::string multisig_tx_st, multisig_tx_set &exported_txs) const
|
bool wallet2::parse_multisig_tx_from_str(std::string multisig_tx_st, multisig_tx_set &exported_txs) const
|
||||||
|
@ -6737,7 +6747,7 @@ bool wallet2::load_multisig_tx_from_file(const std::string &filename, multisig_t
|
||||||
LOG_PRINT_L0("File " << filename << " does not exist: " << errcode);
|
LOG_PRINT_L0("File " << filename << " does not exist: " << errcode);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!epee::file_io_utils::load_file_to_string(filename.c_str(), s))
|
if (!load_from_file(filename.c_str(), s))
|
||||||
{
|
{
|
||||||
LOG_PRINT_L0("Failed to load from " << filename);
|
LOG_PRINT_L0("Failed to load from " << filename);
|
||||||
return false;
|
return false;
|
||||||
|
@ -11633,7 +11643,7 @@ bool wallet2::export_key_images(const std::string &filename, bool all) const
|
||||||
// encrypt data, keep magic plaintext
|
// encrypt data, keep magic plaintext
|
||||||
PERF_TIMER(export_key_images_encrypt);
|
PERF_TIMER(export_key_images_encrypt);
|
||||||
std::string ciphertext = encrypt_with_view_secret_key(data);
|
std::string ciphertext = encrypt_with_view_secret_key(data);
|
||||||
return epee::file_io_utils::save_string_to_file(filename, magic + ciphertext);
|
return save_to_file(filename, magic + ciphertext);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
@ -11698,7 +11708,7 @@ uint64_t wallet2::import_key_images(const std::string &filename, uint64_t &spent
|
||||||
{
|
{
|
||||||
PERF_TIMER(import_key_images_fsu);
|
PERF_TIMER(import_key_images_fsu);
|
||||||
std::string data;
|
std::string data;
|
||||||
bool r = epee::file_io_utils::load_file_to_string(filename, data);
|
bool r = load_from_file(filename, data);
|
||||||
|
|
||||||
THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, std::string(tr("failed to read file ")) + filename);
|
THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, std::string(tr("failed to read file ")) + filename);
|
||||||
|
|
||||||
|
@ -13102,6 +13112,83 @@ void wallet2::throw_on_rpc_response_error(const boost::optional<std::string> &st
|
||||||
THROW_WALLET_EXCEPTION_IF(*status != CORE_RPC_STATUS_OK, tools::error::wallet_generic_rpc_error, method, m_trusted_daemon ? *status : "daemon error");
|
THROW_WALLET_EXCEPTION_IF(*status != CORE_RPC_STATUS_OK, tools::error::wallet_generic_rpc_error, method, m_trusted_daemon ? *status : "daemon error");
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool wallet2::save_to_file(const std::string& path_to_file, const std::string& raw, bool is_printable) const
|
||||||
|
{
|
||||||
|
if (is_printable || m_export_format == ExportFormat::Binary)
|
||||||
|
{
|
||||||
|
return epee::file_io_utils::save_string_to_file(path_to_file, raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *fp = fopen(path_to_file.c_str(), "w+");
|
||||||
|
// Save the result b/c we need to close the fp before returning success/failure.
|
||||||
|
int write_result = PEM_write(fp, ASCII_OUTPUT_MAGIC.c_str(), "", (const unsigned char *) raw.c_str(), raw.length());
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
if (write_result == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool wallet2::load_from_file(const std::string& path_to_file, std::string& target_str,
|
||||||
|
size_t max_size)
|
||||||
|
{
|
||||||
|
std::string data;
|
||||||
|
bool r = epee::file_io_utils::load_file_to_string(path_to_file, data, max_size);
|
||||||
|
if (!r)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!boost::algorithm::contains(boost::make_iterator_range(data.begin(), data.end()), ASCII_OUTPUT_MAGIC))
|
||||||
|
{
|
||||||
|
// It's NOT our ascii dump.
|
||||||
|
target_str = std::move(data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creating a BIO and calling PEM_read_bio instead of simpler PEM_read
|
||||||
|
// to avoid reading the file from disk twice.
|
||||||
|
BIO* b = BIO_new_mem_buf((const void*) data.data(), data.length());
|
||||||
|
|
||||||
|
char *name = NULL;
|
||||||
|
char *header = NULL;
|
||||||
|
unsigned char *openssl_data = NULL;
|
||||||
|
long len = 0;
|
||||||
|
|
||||||
|
// Save the result b/c we need to free the data before returning success/failure.
|
||||||
|
int success = PEM_read_bio(b, &name, &header, &openssl_data, &len);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
target_str = std::string((const char*) openssl_data, len);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
success = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
OPENSSL_free((void *) name);
|
||||||
|
OPENSSL_free((void *) header);
|
||||||
|
OPENSSL_free((void *) openssl_data);
|
||||||
|
BIO_free(b);
|
||||||
|
|
||||||
|
if (success == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
void wallet2::hash_m_transfer(const transfer_details & transfer, crypto::hash &hash) const
|
void wallet2::hash_m_transfer(const transfer_details & transfer, crypto::hash &hash) const
|
||||||
{
|
{
|
||||||
KECCAK_CTX state;
|
KECCAK_CTX state;
|
||||||
|
|
|
@ -227,6 +227,11 @@ private:
|
||||||
BackgroundMiningNo = 2,
|
BackgroundMiningNo = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ExportFormat {
|
||||||
|
Binary = 0,
|
||||||
|
Ascii,
|
||||||
|
};
|
||||||
|
|
||||||
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);
|
||||||
|
@ -1050,6 +1055,8 @@ private:
|
||||||
void device_name(const std::string & device_name) { m_device_name = device_name; }
|
void device_name(const std::string & device_name) { m_device_name = device_name; }
|
||||||
const std::string & device_derivation_path() const { return m_device_derivation_path; }
|
const std::string & device_derivation_path() const { return m_device_derivation_path; }
|
||||||
void device_derivation_path(const std::string &device_derivation_path) { m_device_derivation_path = device_derivation_path; }
|
void device_derivation_path(const std::string &device_derivation_path) { m_device_derivation_path = device_derivation_path; }
|
||||||
|
const ExportFormat & export_format() const { return m_export_format; }
|
||||||
|
inline void set_export_format(const ExportFormat& export_format) { m_export_format = export_format; }
|
||||||
|
|
||||||
bool get_tx_key_cached(const crypto::hash &txid, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys) const;
|
bool get_tx_key_cached(const crypto::hash &txid, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys) const;
|
||||||
void set_tx_key(const crypto::hash &txid, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys);
|
void set_tx_key(const crypto::hash &txid, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys);
|
||||||
|
@ -1300,6 +1307,9 @@ private:
|
||||||
bool frozen(const crypto::key_image &ki) const;
|
bool frozen(const crypto::key_image &ki) const;
|
||||||
bool frozen(const transfer_details &td) const;
|
bool frozen(const transfer_details &td) const;
|
||||||
|
|
||||||
|
bool save_to_file(const std::string& path_to_file, const std::string& binary, bool is_printable = false) const;
|
||||||
|
static bool load_from_file(const std::string& path_to_file, std::string& target_str, size_t max_size = 1000000000);
|
||||||
|
|
||||||
uint64_t get_bytes_sent() const;
|
uint64_t get_bytes_sent() const;
|
||||||
uint64_t get_bytes_received() const;
|
uint64_t get_bytes_received() const;
|
||||||
|
|
||||||
|
@ -1546,6 +1556,8 @@ private:
|
||||||
|
|
||||||
std::shared_ptr<tools::Notify> m_tx_notify;
|
std::shared_ptr<tools::Notify> m_tx_notify;
|
||||||
std::unique_ptr<wallet_device_callback> m_device_callback;
|
std::unique_ptr<wallet_device_callback> m_device_callback;
|
||||||
|
|
||||||
|
ExportFormat m_export_format;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
BOOST_CLASS_VERSION(tools::wallet2, 28)
|
BOOST_CLASS_VERSION(tools::wallet2, 28)
|
||||||
|
|
Loading…
Reference in New Issue