change to allow (at least a bit) for multiple TXT records
This commit is contained in:
parent
f437cb58bf
commit
c14c7e1683
|
@ -89,7 +89,7 @@ std::vector<std::string> DNSResolver::get_ipv4(const std::string& url)
|
||||||
{
|
{
|
||||||
if (result.ptr->havedata)
|
if (result.ptr->havedata)
|
||||||
{
|
{
|
||||||
for (int i=0; result.ptr->data[i] != NULL; i++)
|
for (size_t i=0; result.ptr->data[i] != NULL; i++)
|
||||||
{
|
{
|
||||||
char as_str[INET_ADDRSTRLEN];
|
char as_str[INET_ADDRSTRLEN];
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ std::vector<std::string> DNSResolver::get_ipv6(const std::string& url)
|
||||||
{
|
{
|
||||||
if (result.ptr->havedata)
|
if (result.ptr->havedata)
|
||||||
{
|
{
|
||||||
for (int i=0; result.ptr->data[i] != NULL; i++)
|
for (size_t i=0; result.ptr->data[i] != NULL; i++)
|
||||||
{
|
{
|
||||||
char as_str[INET6_ADDRSTRLEN];
|
char as_str[INET6_ADDRSTRLEN];
|
||||||
|
|
||||||
|
@ -131,19 +131,24 @@ std::vector<std::string> DNSResolver::get_ipv6(const std::string& url)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DNSResolver::get_txt_record(const std::string& url)
|
std::vector<std::string> DNSResolver::get_txt_record(const std::string& url)
|
||||||
{
|
{
|
||||||
ub_result_ptr result;
|
ub_result_ptr result;
|
||||||
|
std::vector<std::string> records;
|
||||||
|
|
||||||
// call DNS resolver, blocking. if return value not zero, something went wrong
|
// call DNS resolver, blocking. if return value not zero, something went wrong
|
||||||
if (!ub_resolve(m_data->m_ub_context, url.c_str(), LDNS_RR_TYPE_TXT, LDNS_RR_CLASS_IN, &(result.ptr)))
|
if (!ub_resolve(m_data->m_ub_context, url.c_str(), LDNS_RR_TYPE_TXT, LDNS_RR_CLASS_IN, &(result.ptr)))
|
||||||
{
|
{
|
||||||
if (result.ptr->havedata)
|
if (result.ptr->havedata)
|
||||||
{
|
{
|
||||||
return std::string(result.ptr->data[0]);
|
for (size_t i=0; result.ptr->data[i] != NULL; i++)
|
||||||
|
{
|
||||||
|
records.push_back(result.ptr->data[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return std::string();
|
|
||||||
|
return records;
|
||||||
}
|
}
|
||||||
|
|
||||||
DNSResolver& DNSResolver::instance()
|
DNSResolver& DNSResolver::instance()
|
||||||
|
|
|
@ -82,15 +82,15 @@ public:
|
||||||
std::vector<std::string> get_ipv6(const std::string& url);
|
std::vector<std::string> get_ipv6(const std::string& url);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief gets a TXT record from a DNS query for the supplied URL;
|
* @brief gets all TXT records from a DNS query for the supplied URL;
|
||||||
* if no TXT record present returns an empty string.
|
* if no TXT record present returns an empty vector.
|
||||||
*
|
*
|
||||||
* @param url A string containing a URL to query for
|
* @param url A string containing a URL to query for
|
||||||
*
|
*
|
||||||
* @return A string containing a TXT record; or an empty string
|
* @return A vector of strings containing a TXT record; or an empty vector
|
||||||
*/
|
*/
|
||||||
// TODO: modify this to accomodate DNSSEC
|
// TODO: modify this to accomodate DNSSEC
|
||||||
std::string get_txt_record(const std::string& url);
|
std::vector<std::string> get_txt_record(const std::string& url);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the singleton instance of DNSResolver
|
* @brief Gets the singleton instance of DNSResolver
|
||||||
|
|
|
@ -913,16 +913,15 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
||||||
{
|
{
|
||||||
// if treating as an address fails, try as url
|
// if treating as an address fails, try as url
|
||||||
bool dnssec_ok = false;
|
bool dnssec_ok = false;
|
||||||
std::string addr_from_dns;
|
|
||||||
std::string url = local_args[i];
|
std::string url = local_args[i];
|
||||||
|
|
||||||
// attempt to get address from dns query
|
// attempt to get address from dns query
|
||||||
addr_from_dns = tools::wallet2::address_from_url(url, dnssec_ok);
|
auto addresses_from_dns = tools::wallet2::addresses_from_url(url, dnssec_ok);
|
||||||
|
|
||||||
// if string not empty, see if it's an address
|
// for now, move on only if one address found
|
||||||
if (addr_from_dns.size())
|
if (addresses_from_dns.size() == 1)
|
||||||
{
|
{
|
||||||
if (get_account_address_from_str(de.addr, addr_from_dns))
|
if (get_account_address_from_str(de.addr, addresses_from_dns[0]))
|
||||||
{
|
{
|
||||||
// if it was an address, prompt user for confirmation.
|
// if it was an address, prompt user for confirmation.
|
||||||
// inform user of DNSSEC validation status as well.
|
// inform user of DNSSEC validation status as well.
|
||||||
|
@ -938,8 +937,8 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
||||||
}
|
}
|
||||||
std::stringstream prompt;
|
std::stringstream prompt;
|
||||||
prompt << "For URL: " << url
|
prompt << "For URL: " << url
|
||||||
<< "," << dnssec_str
|
<< "," << dnssec_str << std::endl
|
||||||
<< " Monero Address = " << addr_from_dns
|
<< " Monero Address = " << addresses_from_dns[0]
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< "Is this OK? (Y/n) "
|
<< "Is this OK? (Y/n) "
|
||||||
;
|
;
|
||||||
|
@ -958,6 +957,10 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (addresses_from_dns.size() > 1)
|
||||||
|
{
|
||||||
|
tools::fail_msg_writer() << "Multiple Monero addresses found for given URL: " << url << ", this is not yet supported.";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fail_msg_writer() << "wrong address: " << local_args[i];
|
fail_msg_writer() << "wrong address: " << local_args[i];
|
||||||
|
|
|
@ -831,21 +831,30 @@ std::vector<std::vector<cryptonote::tx_destination_entry>> split_amounts(
|
||||||
*
|
*
|
||||||
* @return a monero address (as a string) or an empty string
|
* @return a monero address (as a string) or an empty string
|
||||||
*/
|
*/
|
||||||
std::string wallet2::address_from_url(const std::string& url, bool& dnssec_valid)
|
std::vector<std::string> wallet2::addresses_from_url(const std::string& url, bool& dnssec_valid)
|
||||||
{
|
{
|
||||||
// TODO: update this correctly once DNSResolver::get_txt_record() supports it.
|
// TODO: update this correctly once DNSResolver::get_txt_record() supports it.
|
||||||
dnssec_valid = false;
|
dnssec_valid = false;
|
||||||
// get txt record
|
|
||||||
std::string txt = tools::DNSResolver::instance().get_txt_record(url);
|
|
||||||
|
|
||||||
if (txt.size())
|
std::vector<std::string> addresses;
|
||||||
|
// get txt records
|
||||||
|
auto records = tools::DNSResolver::instance().get_txt_record(url);
|
||||||
|
|
||||||
|
// for each txt record, try to find a monero address in it.
|
||||||
|
for (auto& rec : records)
|
||||||
{
|
{
|
||||||
return address_from_txt_record(txt);
|
std::string addr = address_from_txt_record(rec);
|
||||||
|
if (addr.size())
|
||||||
|
{
|
||||||
|
addresses.push_back(addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return std::string();
|
|
||||||
|
return addresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
|
// TODO: parse the string in a less stupid way, probably with regex
|
||||||
std::string wallet2::address_from_txt_record(const std::string& s)
|
std::string wallet2::address_from_txt_record(const std::string& s)
|
||||||
{
|
{
|
||||||
// make sure the txt record has "oa1:xmr" and find it
|
// make sure the txt record has "oa1:xmr" and find it
|
||||||
|
|
|
@ -196,7 +196,7 @@ namespace tools
|
||||||
|
|
||||||
static bool parse_payment_id(const std::string& payment_id_str, crypto::hash& payment_id);
|
static bool parse_payment_id(const std::string& payment_id_str, crypto::hash& payment_id);
|
||||||
|
|
||||||
static std::string address_from_url(const std::string& url, bool& dnssec_valid);
|
static std::vector<std::string> addresses_from_url(const std::string& url, bool& dnssec_valid);
|
||||||
|
|
||||||
static std::string address_from_txt_record(const std::string& s);
|
static std::string address_from_txt_record(const std::string& s);
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -85,18 +85,23 @@ TEST(AddressFromURL, Success)
|
||||||
std::string addr = "46BeWrHpwXmHDpDEUmZBWZfoQpdc6HaERCNmx1pEYL2rAcuwufPN9rXHHtyUA4QVy66qeFQkn6sfK8aHYjA3jk3o1Bv16em";
|
std::string addr = "46BeWrHpwXmHDpDEUmZBWZfoQpdc6HaERCNmx1pEYL2rAcuwufPN9rXHHtyUA4QVy66qeFQkn6sfK8aHYjA3jk3o1Bv16em";
|
||||||
|
|
||||||
bool dnssec_result = false;
|
bool dnssec_result = false;
|
||||||
std::string res = tools::wallet2::address_from_url("donate.monero.cc", dnssec_result);
|
|
||||||
|
|
||||||
EXPECT_STREQ(addr.c_str(), res.c_str());
|
std::vector<std::string> addresses = tools::wallet2::addresses_from_url("donate.monero.cc", dnssec_result);
|
||||||
|
|
||||||
|
EXPECT_EQ(1, addresses.size());
|
||||||
|
if (addresses.size() == 1)
|
||||||
|
{
|
||||||
|
EXPECT_STREQ(addr.c_str(), addresses[0].c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(AddressFromURL, Failure)
|
TEST(AddressFromURL, Failure)
|
||||||
{
|
{
|
||||||
bool dnssec_result = false;
|
bool dnssec_result = false;
|
||||||
|
|
||||||
std::string res = tools::wallet2::address_from_url("example.invalid", dnssec_result);
|
std::vector<std::string> addresses = tools::wallet2::addresses_from_url("example.invalid", dnssec_result);
|
||||||
|
|
||||||
ASSERT_FALSE(dnssec_result);
|
ASSERT_FALSE(dnssec_result);
|
||||||
|
|
||||||
ASSERT_STREQ("", res.c_str());
|
ASSERT_EQ(0, addresses.size());
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
@ -97,8 +98,12 @@ TEST(DNSResolver, IPv6Failure)
|
||||||
TEST(DNSResolver, GetTXTRecord)
|
TEST(DNSResolver, GetTXTRecord)
|
||||||
{
|
{
|
||||||
|
|
||||||
std::string txt = tools::DNSResolver::instance().get_txt_record("donate.monero.cc");
|
std::vector<std::string> records = tools::DNSResolver::instance().get_txt_record("donate.monero.cc");
|
||||||
std::cout << "TXT record for donate.monero.cc: " << txt << std::endl;
|
|
||||||
|
|
||||||
EXPECT_STRNE("", txt.c_str());
|
EXPECT_NE(0, records.size());
|
||||||
|
|
||||||
|
for (auto& rec : records)
|
||||||
|
{
|
||||||
|
std::cout << "TXT record for donate.monero.cc: " << rec << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue