aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/dns_utils.cpp46
-rw-r--r--src/common/dns_utils.h2
-rw-r--r--src/cryptonote_basic/cryptonote_basic_impl.cpp8
-rw-r--r--src/cryptonote_basic/cryptonote_basic_impl.h13
-rw-r--r--src/daemon/command_parser_executor.cpp3
-rw-r--r--src/simplewallet/simplewallet.cpp50
-rw-r--r--src/wallet/wallet_rpc_server.cpp55
7 files changed, 113 insertions, 64 deletions
diff --git a/src/common/dns_utils.cpp b/src/common/dns_utils.cpp
index ab38cbbae..b3b464e92 100644
--- a/src/common/dns_utils.cpp
+++ b/src/common/dns_utils.cpp
@@ -26,12 +26,9 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "common/command_line.h"
-#include "common/i18n.h"
#include "common/dns_utils.h"
+#include "common/i18n.h"
#include "cryptonote_basic/cryptonote_basic_impl.h"
-#include <cstring>
-#include <sstream>
// check local first (in the event of static or in-source compilation of libunbound)
#include "unbound.h"
@@ -405,7 +402,7 @@ std::vector<std::string> addresses_from_url(const std::string& url, bool& dnssec
return addresses;
}
-std::string get_account_address_as_str_from_url(const std::string& url, bool& dnssec_valid, bool cli_confirm)
+std::string get_account_address_as_str_from_url(const std::string& url, bool& dnssec_valid, std::function<std::string(const std::string&, const std::vector<std::string>&, bool)> dns_confirm)
{
// attempt to get address from dns query
auto addresses = addresses_from_url(url, dnssec_valid);
@@ -414,44 +411,7 @@ std::string get_account_address_as_str_from_url(const std::string& url, bool& dn
LOG_ERROR("wrong address: " << url);
return {};
}
- // for now, move on only if one address found
- if (addresses.size() > 1)
- {
- LOG_ERROR("not yet supported: Multiple Monero addresses found for given URL: " << url);
- return {};
- }
- if (!cli_confirm)
- return addresses[0];
- // prompt user for confirmation.
- // inform user of DNSSEC validation status as well.
- std::string dnssec_str;
- if (dnssec_valid)
- {
- dnssec_str = tr("DNSSEC validation passed");
- }
- else
- {
- dnssec_str = tr("WARNING: DNSSEC validation was unsuccessful, this address may not be correct!");
- }
- std::stringstream prompt;
- prompt << tr("For URL: ") << url
- << ", " << dnssec_str << std::endl
- << tr(" Monero Address = ") << addresses[0]
- << std::endl
- << tr("Is this OK? (Y/n) ")
- ;
- // prompt the user for confirmation given the dns query and dnssec status
- std::string confirm_dns_ok = command_line::input_line(prompt.str());
- if (std::cin.eof())
- {
- return {};
- }
- if (!command_line::is_yes(confirm_dns_ok))
- {
- std::cout << tr("you have cancelled the transfer request") << std::endl;
- return {};
- }
- return addresses[0];
+ return dns_confirm(url, addresses, dnssec_valid);
}
namespace
diff --git a/src/common/dns_utils.h b/src/common/dns_utils.h
index 53c0c1c7b..1f5cb4e7f 100644
--- a/src/common/dns_utils.h
+++ b/src/common/dns_utils.h
@@ -163,7 +163,7 @@ namespace dns_utils
std::string address_from_txt_record(const std::string& s);
std::vector<std::string> addresses_from_url(const std::string& url, bool& dnssec_valid);
-std::string get_account_address_as_str_from_url(const std::string& url, bool& dnssec_valid, bool cli_confirm = true);
+std::string get_account_address_as_str_from_url(const std::string& url, bool& dnssec_valid, std::function<std::string(const std::string&, const std::vector<std::string>&, bool)> confirm_dns);
bool load_txt_records_from_dns(std::vector<std::string> &records, const std::vector<std::string> &dns_urls);
diff --git a/src/cryptonote_basic/cryptonote_basic_impl.cpp b/src/cryptonote_basic/cryptonote_basic_impl.cpp
index edd67793f..a59f96956 100644
--- a/src/cryptonote_basic/cryptonote_basic_impl.cpp
+++ b/src/cryptonote_basic/cryptonote_basic_impl.cpp
@@ -308,13 +308,13 @@ namespace cryptonote {
, crypto::hash8& payment_id
, bool testnet
, const std::string& str_or_url
- , bool cli_confirm
+ , std::function<std::string(const std::string&, const std::vector<std::string>&, bool)> dns_confirm
)
{
if (get_account_integrated_address_from_str(address, has_payment_id, payment_id, testnet, str_or_url))
return true;
bool dnssec_valid;
- std::string address_str = tools::dns_utils::get_account_address_as_str_from_url(str_or_url, dnssec_valid, cli_confirm);
+ std::string address_str = tools::dns_utils::get_account_address_as_str_from_url(str_or_url, dnssec_valid, dns_confirm);
return !address_str.empty() &&
get_account_integrated_address_from_str(address, has_payment_id, payment_id, testnet, address_str);
}
@@ -323,12 +323,12 @@ namespace cryptonote {
cryptonote::account_public_address& address
, bool testnet
, const std::string& str_or_url
- , bool cli_confirm
+ , std::function<std::string(const std::string&, const std::vector<std::string>&, bool)> dns_confirm
)
{
bool has_payment_id;
crypto::hash8 payment_id;
- return get_account_address_from_str_or_url(address, has_payment_id, payment_id, testnet, str_or_url, cli_confirm);
+ return get_account_address_from_str_or_url(address, has_payment_id, payment_id, testnet, str_or_url, dns_confirm);
}
//--------------------------------------------------------------------------------
bool operator ==(const cryptonote::transaction& a, const cryptonote::transaction& b) {
diff --git a/src/cryptonote_basic/cryptonote_basic_impl.h b/src/cryptonote_basic/cryptonote_basic_impl.h
index 14c03ac4c..9838fcb47 100644
--- a/src/cryptonote_basic/cryptonote_basic_impl.h
+++ b/src/cryptonote_basic/cryptonote_basic_impl.h
@@ -67,6 +67,15 @@ namespace cryptonote {
};
#pragma pack (pop)
+ namespace
+ {
+ std::string return_first_address(const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid)
+ {
+ if (addresses.empty())
+ return {};
+ return addresses[0];
+ }
+ }
/************************************************************************/
/* Cryptonote helper functions */
@@ -109,14 +118,14 @@ namespace cryptonote {
, crypto::hash8& payment_id
, bool testnet
, const std::string& str_or_url
- , bool cli_confirm = true
+ , std::function<std::string(const std::string&, const std::vector<std::string>&, bool)> dns_confirm = return_first_address
);
bool get_account_address_from_str_or_url(
cryptonote::account_public_address& address
, bool testnet
, const std::string& str_or_url
- , bool cli_confirm = true
+ , std::function<std::string(const std::string&, const std::vector<std::string>&, bool)> dns_confirm = return_first_address
);
bool is_coinbase(const transaction& tx);
diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp
index a7caeeffc..d654954ef 100644
--- a/src/daemon/command_parser_executor.cpp
+++ b/src/daemon/command_parser_executor.cpp
@@ -256,7 +256,8 @@ bool t_command_parser_executor::start_mining(const std::vector<std::string>& arg
if(!cryptonote::get_account_integrated_address_from_str(adr, has_payment_id, payment_id, true, args.front()))
{
bool dnssec_valid;
- std::string address_str = tools::dns_utils::get_account_address_as_str_from_url(args.front(), dnssec_valid);
+ std::string address_str = tools::dns_utils::get_account_address_as_str_from_url(args.front(), dnssec_valid,
+ [](const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid){return addresses[0];});
if(!cryptonote::get_account_integrated_address_from_str(adr, has_payment_id, payment_id, false, address_str))
{
if(!cryptonote::get_account_integrated_address_from_str(adr, has_payment_id, payment_id, true, address_str))
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index adf2fde80..c132db196 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -281,6 +281,42 @@ namespace
{
return boost::lexical_cast<std::string>(version >> 16) + "." + boost::lexical_cast<std::string>(version & 0xffff);
}
+
+ std::string oa_prompter(const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid)
+ {
+ if (addresses.empty())
+ return {};
+ // prompt user for confirmation.
+ // inform user of DNSSEC validation status as well.
+ std::string dnssec_str;
+ if (dnssec_valid)
+ {
+ dnssec_str = tr("DNSSEC validation passed");
+ }
+ else
+ {
+ dnssec_str = tr("WARNING: DNSSEC validation was unsuccessful, this address may not be correct!");
+ }
+ std::stringstream prompt;
+ prompt << tr("For URL: ") << url
+ << ", " << dnssec_str << std::endl
+ << tr(" Monero Address = ") << addresses[0]
+ << std::endl
+ << tr("Is this OK? (Y/n) ")
+ ;
+ // prompt the user for confirmation given the dns query and dnssec status
+ std::string confirm_dns_ok = command_line::input_line(prompt.str());
+ if (std::cin.eof())
+ {
+ return {};
+ }
+ if (!command_line::is_yes(confirm_dns_ok))
+ {
+ std::cout << tr("you have cancelled the transfer request") << std::endl;
+ return {};
+ }
+ return addresses[0];
+ }
}
@@ -2215,7 +2251,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
cryptonote::tx_destination_entry de;
bool has_payment_id;
crypto::hash8 new_payment_id;
- if (!cryptonote::get_account_address_from_str_or_url(de.addr, has_payment_id, new_payment_id, m_wallet->testnet(), local_args[i]))
+ if (!cryptonote::get_account_address_from_str_or_url(de.addr, has_payment_id, new_payment_id, m_wallet->testnet(), local_args[i], oa_prompter))
{
fail_msg_writer() << tr("failed to parse address");
return true;
@@ -2713,7 +2749,7 @@ bool simple_wallet::sweep_main(uint64_t below, const std::vector<std::string> &a
bool has_payment_id;
crypto::hash8 new_payment_id;
cryptonote::account_public_address address;
- if (!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, new_payment_id, m_wallet->testnet(), local_args[0]))
+ if (!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, new_payment_id, m_wallet->testnet(), local_args[0], oa_prompter))
{
fail_msg_writer() << tr("failed to parse address");
return true;
@@ -3273,7 +3309,7 @@ bool simple_wallet::get_tx_proof(const std::vector<std::string> &args)
cryptonote::account_public_address address;
bool has_payment_id;
crypto::hash8 payment_id;
- if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), args[1]))
+ if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), args[1], oa_prompter))
{
fail_msg_writer() << tr("failed to parse address");
return true;
@@ -3375,7 +3411,7 @@ bool simple_wallet::check_tx_key(const std::vector<std::string> &args_)
cryptonote::account_public_address address;
bool has_payment_id;
crypto::hash8 payment_id;
- if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), local_args[2]))
+ if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), local_args[2], oa_prompter))
{
fail_msg_writer() << tr("failed to parse address");
return true;
@@ -3527,7 +3563,7 @@ bool simple_wallet::check_tx_proof(const std::vector<std::string> &args)
cryptonote::account_public_address address;
bool has_payment_id;
crypto::hash8 payment_id;
- if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), args[1]))
+ if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), args[1], oa_prompter))
{
fail_msg_writer() << tr("failed to parse address");
return true;
@@ -4045,7 +4081,7 @@ bool simple_wallet::address_book(const std::vector<std::string> &args/* = std::v
cryptonote::account_public_address address;
bool has_payment_id;
crypto::hash8 payment_id8;
- if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id8, m_wallet->testnet(), args[1]))
+ if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id8, m_wallet->testnet(), args[1], oa_prompter))
{
fail_msg_writer() << tr("failed to parse address");
return true;
@@ -4236,7 +4272,7 @@ bool simple_wallet::verify(const std::vector<std::string> &args)
cryptonote::account_public_address address;
bool has_payment_id;
crypto::hash8 payment_id;
- if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), address_string))
+ if(!cryptonote::get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), address_string, oa_prompter))
{
fail_msg_writer() << tr("failed to parse address");
return true;
diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp
index e7b9b5a71..164b3d251 100644
--- a/src/wallet/wallet_rpc_server.cpp
+++ b/src/wallet/wallet_rpc_server.cpp
@@ -352,10 +352,25 @@ namespace tools
cryptonote::tx_destination_entry de;
bool has_payment_id;
crypto::hash8 new_payment_id;
- if(!get_account_address_from_str_or_url(de.addr, has_payment_id, new_payment_id, m_wallet->testnet(), it->address, false))
+ er.message = "";
+ if(!get_account_address_from_str_or_url(de.addr, has_payment_id, new_payment_id, m_wallet->testnet(), it->address,
+ [&er](const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid)->std::string {
+ if (!dnssec_valid)
+ {
+ er.message = std::string("Invalid DNSSEC for ") + url;
+ return {};
+ }
+ if (addresses.empty())
+ {
+ er.message = std::string("No Monero address found at ") + url;
+ return {};
+ }
+ return addresses[0];
+ }))
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS;
- er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + it->address;
+ if (er.message.empty())
+ er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + it->address;
return false;
}
de.amount = it->amount;
@@ -1018,10 +1033,23 @@ namespace tools
cryptonote::account_public_address address;
bool has_payment_id;
crypto::hash8 payment_id;
- if(!get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), req.address, false))
+ er.message = "";
+ if(!get_account_address_from_str_or_url(address, has_payment_id, payment_id, m_wallet->testnet(), req.address,
+ [&er](const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid)->std::string {
+ if (!dnssec_valid)
+ {
+ er.message = std::string("Invalid DNSSEC for ") + url;
+ return {};
+ }
+ if (addresses.empty())
+ {
+ er.message = std::string("No Monero address found at ") + url;
+ return {};
+ }
+ return addresses[0];
+ }))
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS;
- er.message = "";
return false;
}
@@ -1412,10 +1440,25 @@ namespace tools
bool has_payment_id;
crypto::hash8 payment_id8;
crypto::hash payment_id = cryptonote::null_hash;
- if(!get_account_address_from_str_or_url(address, has_payment_id, payment_id8, m_wallet->testnet(), req.address, false))
+ er.message = "";
+ if(!get_account_address_from_str_or_url(address, has_payment_id, payment_id8, m_wallet->testnet(), req.address,
+ [&er](const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid)->std::string {
+ if (!dnssec_valid)
+ {
+ er.message = std::string("Invalid DNSSEC for ") + url;
+ return {};
+ }
+ if (addresses.empty())
+ {
+ er.message = std::string("No Monero address found at ") + url;
+ return {};
+ }
+ return addresses[0];
+ }))
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS;
- er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + req.address;
+ if (er.message.empty())
+ er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + req.address;
return false;
}
if (has_payment_id)