Merge pull request #5416

63186a0 Wallet: Option to export data to ASCII (tmoravec)
This commit is contained in:
luigi1111 2019-08-27 15:02:55 -05:00
commit 3254204fb9
No known key found for this signature in database
GPG Key ID: F4ACA0183641E010
4 changed files with 170 additions and 37 deletions

View File

@ -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;
} }

View File

@ -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);

View File

@ -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;

View File

@ -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)