From dbf46a721af5d54792bca80fc1c439c1badc9069 Mon Sep 17 00:00:00 2001 From: Thomas Winget Date: Tue, 24 Mar 2015 06:34:15 -0400 Subject: [PATCH] DNSSEC added (hardcoded key) DNSSEC is now implemented with the hardcoded key from unbound. This will need to be not hardcoded in the future, but is okay for now. Unit tests updated for DNSSEC (as well as for the fact that, contrary to previous assumption, example.com does not have a static IP address). --- src/common/dns_utils.cpp | 66 +++++++++++++++++++++++++++++++ tests/unit_tests/dns_resolver.cpp | 36 ++++++++++++++++- 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/src/common/dns_utils.cpp b/src/common/dns_utils.cpp index 3e50b6af8..4ab93cce8 100644 --- a/src/common/dns_utils.cpp +++ b/src/common/dns_utils.cpp @@ -34,7 +34,65 @@ #include #include "include_base_utils.h" +#include using namespace epee; +namespace bf = boost::filesystem; + +namespace +{ + +/* + * The following two functions were taken from unbound-anchor.c, from + * the unbound library packaged with this source. The license and source + * can be found in $PROJECT_ROOT/external/unbound + */ + +/* Cert builtin commented out until it's used, as the compiler complains + +// return the built in root update certificate +static const char* +get_builtin_cert(void) +{ + return +// The ICANN CA fetched at 24 Sep 2010. Valid to 2028 +"-----BEGIN CERTIFICATE-----\n" +"MIIDdzCCAl+gAwIBAgIBATANBgkqhkiG9w0BAQsFADBdMQ4wDAYDVQQKEwVJQ0FO\n" +"TjEmMCQGA1UECxMdSUNBTk4gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNV\n" +"BAMTDUlDQU5OIFJvb3QgQ0ExCzAJBgNVBAYTAlVTMB4XDTA5MTIyMzA0MTkxMloX\n" +"DTI5MTIxODA0MTkxMlowXTEOMAwGA1UEChMFSUNBTk4xJjAkBgNVBAsTHUlDQU5O\n" +"IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1JQ0FOTiBSb290IENB\n" +"MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKDb\n" +"cLhPNNqc1NB+u+oVvOnJESofYS9qub0/PXagmgr37pNublVThIzyLPGCJ8gPms9S\n" +"G1TaKNIsMI7d+5IgMy3WyPEOECGIcfqEIktdR1YWfJufXcMReZwU4v/AdKzdOdfg\n" +"ONiwc6r70duEr1IiqPbVm5T05l1e6D+HkAvHGnf1LtOPGs4CHQdpIUcy2kauAEy2\n" +"paKcOcHASvbTHK7TbbvHGPB+7faAztABLoneErruEcumetcNfPMIjXKdv1V1E3C7\n" +"MSJKy+jAqqQJqjZoQGB0necZgUMiUv7JK1IPQRM2CXJllcyJrm9WFxY0c1KjBO29\n" +"iIKK69fcglKcBuFShUECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\n" +"Af8EBAMCAf4wHQYDVR0OBBYEFLpS6UmDJIZSL8eZzfyNa2kITcBQMA0GCSqGSIb3\n" +"DQEBCwUAA4IBAQAP8emCogqHny2UYFqywEuhLys7R9UKmYY4suzGO4nkbgfPFMfH\n" +"6M+Zj6owwxlwueZt1j/IaCayoKU3QsrYYoDRolpILh+FPwx7wseUEV8ZKpWsoDoD\n" +"2JFbLg2cfB8u/OlE4RYmcxxFSmXBg0yQ8/IoQt/bxOcEEhhiQ168H2yE5rxJMt9h\n" +"15nu5JBSewrCkYqYYmaxyOC3WrVGfHZxVI7MpIFcGdvSb2a1uyuua8l0BKgk3ujF\n" +"0/wsHNeP22qNyVO+XVBzrM8fk8BSUFuiT/6tZTYXRtEt5aKQZgXbKU5dUF3jT9qg\n" +"j/Br5BZw3X/zd325TvnswzMC1+ljLzHnQGGk\n" +"-----END CERTIFICATE-----\n" + ; +} +*/ + +/** return the built in root DS trust anchor */ +static const char* +get_builtin_ds(void) +{ + return +". IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5\n"; +} + +/************************************************************ + ************************************************************ + ***********************************************************/ + +} // anonymous namespace namespace tools { @@ -109,6 +167,8 @@ DNSResolver::DNSResolver() : m_data(new DNSResolverData()) // look for "/etc/resolv.conf" and "/etc/hosts" or platform equivalent ub_ctx_resolvconf(m_data->m_ub_context, &empty_string); ub_ctx_hosts(m_data->m_ub_context, &empty_string); + + ub_ctx_add_ta(m_data->m_ub_context, ::get_builtin_ds()); } DNSResolver::~DNSResolver() @@ -143,6 +203,8 @@ std::vector DNSResolver::get_ipv4(const std::string& url, bool& dns // call DNS resolver, blocking. if return value not zero, something went wrong if (!ub_resolve(m_data->m_ub_context, urlC, DNS_TYPE_A, DNS_CLASS_IN, &(result.ptr))) { + dnssec_available = (result.ptr->secure || (!result.ptr->secure && result.ptr->bogus)); + dnssec_valid = !result.ptr->bogus; if (result.ptr->havedata) { for (size_t i=0; result.ptr->data[i] != NULL; i++) @@ -175,6 +237,8 @@ std::vector DNSResolver::get_ipv6(const std::string& url, bool& dns // call DNS resolver, blocking. if return value not zero, something went wrong if (!ub_resolve(m_data->m_ub_context, urlC, DNS_TYPE_AAAA, DNS_CLASS_IN, &(result.ptr))) { + dnssec_available = (result.ptr->secure || (!result.ptr->secure && result.ptr->bogus)); + dnssec_valid = !result.ptr->bogus; if (result.ptr->havedata) { for (size_t i=0; result.ptr->data[i] != NULL; i++) @@ -207,6 +271,8 @@ std::vector DNSResolver::get_txt_record(const std::string& url, boo // call DNS resolver, blocking. if return value not zero, something went wrong if (!ub_resolve(m_data->m_ub_context, urlC, DNS_TYPE_TXT, DNS_CLASS_IN, &(result.ptr))) { + dnssec_available = (result.ptr->secure || (!result.ptr->secure && result.ptr->bogus)); + dnssec_valid = !result.ptr->bogus; if (result.ptr->havedata) { for (size_t i=0; result.ptr->data[i] != NULL; i++) diff --git a/tests/unit_tests/dns_resolver.cpp b/tests/unit_tests/dns_resolver.cpp index 680633778..6717e990a 100644 --- a/tests/unit_tests/dns_resolver.cpp +++ b/tests/unit_tests/dns_resolver.cpp @@ -43,13 +43,13 @@ TEST(DNSResolver, IPv4Success) ASSERT_EQ(1, ips.size()); - ASSERT_STREQ("93.184.216.119", ips[0].c_str()); + //ASSERT_STREQ("93.184.216.119", ips[0].c_str()); ips = tools::DNSResolver::instance().get_ipv4("example.com", avail, valid); ASSERT_EQ(1, ips.size()); - ASSERT_STREQ("93.184.216.119", ips[0].c_str()); + //ASSERT_STREQ("93.184.216.119", ips[0].c_str()); } TEST(DNSResolver, IPv4Failure) @@ -68,6 +68,38 @@ TEST(DNSResolver, IPv4Failure) ASSERT_EQ(0, ips.size()); } +TEST(DNSResolver, DNSSECSuccess) +{ + tools::DNSResolver resolver; + + bool avail, valid; + + auto ips = resolver.get_ipv4("example.com", avail, valid); + + ASSERT_EQ(1, ips.size()); + + //ASSERT_STREQ("93.184.216.119", ips[0].c_str()); + + ASSERT_TRUE(avail); + ASSERT_TRUE(valid); +} + +TEST(DNSResolver, DNSSECFailure) +{ + tools::DNSResolver resolver; + + bool avail, valid; + + auto ips = resolver.get_ipv4("dnssec-failed.org", avail, valid); + + ASSERT_EQ(1, ips.size()); + + //ASSERT_STREQ("93.184.216.119", ips[0].c_str()); + + ASSERT_TRUE(avail); + ASSERT_FALSE(valid); +} + // It would be great to include an IPv6 test and assume it'll pass, but not every ISP / resolver plays nicely with IPv6;) /*TEST(DNSResolver, IPv6Success) {