wallet: make the JSON reading type safe
This commit is contained in:
parent
f8d05f3cd9
commit
3e557254c7
1 changed files with 31 additions and 41 deletions
|
@ -58,6 +58,7 @@
|
||||||
#include "crypto/crypto.h" // for crypto::secret_key definition
|
#include "crypto/crypto.h" // for crypto::secret_key definition
|
||||||
#include "mnemonics/electrum-words.h"
|
#include "mnemonics/electrum-words.h"
|
||||||
#include "rapidjson/document.h"
|
#include "rapidjson/document.h"
|
||||||
|
#include "common/json_util.h"
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
|
@ -833,40 +834,27 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!json.HasMember("version")) {
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, version, unsigned, Uint, true);
|
||||||
fail_msg_writer() << tr("Version not found in JSON");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
unsigned int version = json["version"].GetUint();
|
|
||||||
const int current_version = 1;
|
const int current_version = 1;
|
||||||
if (version > current_version) {
|
if (field_version > current_version) {
|
||||||
fail_msg_writer() << boost::format(tr("Version %u too new, we can only grok up to %u")) % version % current_version;
|
fail_msg_writer() << boost::format(tr("Version %u too new, we can only grok up to %u")) % field_version % current_version;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!json.HasMember("filename")) {
|
|
||||||
fail_msg_writer() << tr("Filename not found in JSON");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
std::string filename = json["filename"].GetString();
|
|
||||||
|
|
||||||
bool recover = false;
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, filename, std::string, String, true);
|
||||||
uint64_t scan_from_height = 0;
|
|
||||||
if (json.HasMember("scan_from_height")) {
|
|
||||||
scan_from_height = json["scan_from_height"].GetUint64();
|
|
||||||
recover = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
password = "";
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, scan_from_height, uint64_t, Uint64, false);
|
||||||
if (json.HasMember("password")) {
|
bool recover = field_scan_from_height_found;
|
||||||
password = json["password"].GetString();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string viewkey_string("");
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, password, std::string, String, false);
|
||||||
|
password = field_password;
|
||||||
|
|
||||||
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, viewkey, std::string, String, false);
|
||||||
crypto::secret_key viewkey;
|
crypto::secret_key viewkey;
|
||||||
if (json.HasMember("viewkey")) {
|
if (field_viewkey_found)
|
||||||
viewkey_string = json["viewkey"].GetString();
|
{
|
||||||
cryptonote::blobdata viewkey_data;
|
cryptonote::blobdata viewkey_data;
|
||||||
if(!epee::string_tools::parse_hexstr_to_binbuff(viewkey_string, viewkey_data))
|
if(!epee::string_tools::parse_hexstr_to_binbuff(field_viewkey, viewkey_data))
|
||||||
{
|
{
|
||||||
fail_msg_writer() << tr("failed to parse view key secret key");
|
fail_msg_writer() << tr("failed to parse view key secret key");
|
||||||
return false;
|
return false;
|
||||||
|
@ -874,12 +862,12 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m
|
||||||
viewkey = *reinterpret_cast<const crypto::secret_key*>(viewkey_data.data());
|
viewkey = *reinterpret_cast<const crypto::secret_key*>(viewkey_data.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string spendkey_string("");
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, spendkey, std::string, String, false);
|
||||||
crypto::secret_key spendkey;
|
crypto::secret_key spendkey;
|
||||||
if (json.HasMember("spendkey")) {
|
if (field_spendkey_found)
|
||||||
spendkey_string = json["spendkey"].GetString();
|
{
|
||||||
cryptonote::blobdata spendkey_data;
|
cryptonote::blobdata spendkey_data;
|
||||||
if(!epee::string_tools::parse_hexstr_to_binbuff(spendkey_string, spendkey_data))
|
if(!epee::string_tools::parse_hexstr_to_binbuff(field_spendkey, spendkey_data))
|
||||||
{
|
{
|
||||||
fail_msg_writer() << tr("failed to parse spend key secret key");
|
fail_msg_writer() << tr("failed to parse spend key secret key");
|
||||||
return false;
|
return false;
|
||||||
|
@ -887,30 +875,32 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m
|
||||||
spendkey = *reinterpret_cast<const crypto::secret_key*>(spendkey_data.data());
|
spendkey = *reinterpret_cast<const crypto::secret_key*>(spendkey_data.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string seed("");
|
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, seed, std::string, String, false);
|
||||||
std::string old_language;
|
std::string old_language;
|
||||||
if (json.HasMember("seed")) {
|
if (field_seed_found)
|
||||||
seed = json["seed"].GetString();
|
{
|
||||||
if (!crypto::ElectrumWords::words_to_bytes(seed, m_recovery_key, old_language))
|
if (!crypto::ElectrumWords::words_to_bytes(field_seed, m_recovery_key, old_language))
|
||||||
{
|
{
|
||||||
fail_msg_writer() << tr("Electrum-style word list failed verification");
|
fail_msg_writer() << tr("Electrum-style word list failed verification");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_electrum_seed = seed;
|
m_electrum_seed = field_seed;
|
||||||
m_restore_deterministic_wallet = true;
|
m_restore_deterministic_wallet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// compatibility checks
|
// compatibility checks
|
||||||
if (seed.empty() && viewkey_string.empty()) {
|
if (!field_seed_found && !field_viewkey_found)
|
||||||
|
{
|
||||||
fail_msg_writer() << tr("At least one of Electrum-style word list and private view key must be specified");
|
fail_msg_writer() << tr("At least one of Electrum-style word list and private view key must be specified");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!seed.empty() && (!viewkey_string.empty() || !spendkey_string.empty())) {
|
if (field_seed_found && (field_viewkey_found || field_spendkey_found))
|
||||||
|
{
|
||||||
fail_msg_writer() << tr("Both Electrum-style word list and private key(s) specified");
|
fail_msg_writer() << tr("Both Electrum-style word list and private key(s) specified");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_wallet_file = filename;
|
m_wallet_file = field_filename;
|
||||||
|
|
||||||
bool was_deprecated_wallet = m_restore_deterministic_wallet && ((old_language == crypto::ElectrumWords::old_language_name) ||
|
bool was_deprecated_wallet = m_restore_deterministic_wallet && ((old_language == crypto::ElectrumWords::old_language_name) ||
|
||||||
crypto::ElectrumWords::get_is_old_style_seed(m_electrum_seed));
|
crypto::ElectrumWords::get_is_old_style_seed(m_electrum_seed));
|
||||||
|
@ -925,7 +915,7 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!seed.empty())
|
if (!field_seed.empty())
|
||||||
{
|
{
|
||||||
m_wallet->generate(m_wallet_file, password, m_recovery_key, recover, false);
|
m_wallet->generate(m_wallet_file, password, m_recovery_key, recover, false);
|
||||||
}
|
}
|
||||||
|
@ -941,7 +931,7 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spendkey_string.empty())
|
if (field_spendkey.empty())
|
||||||
{
|
{
|
||||||
m_wallet->generate(m_wallet_file, password, address, viewkey);
|
m_wallet->generate(m_wallet_file, password, address, viewkey);
|
||||||
}
|
}
|
||||||
|
@ -957,7 +947,7 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_wallet->set_refresh_from_block_height(scan_from_height);
|
m_wallet->set_refresh_from_block_height(field_scan_from_height);
|
||||||
|
|
||||||
wallet_file = m_wallet_file;
|
wallet_file = m_wallet_file;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue