From fb85e6fd737102e23647d45d208939d30c352496 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Dec 2015 18:55:17 +0100 Subject: resolved: change mapping of BUS_ERROR_NO_NAME_SERVERS to ESRCH EIO is really too generic, and indicates transmission problems. --- src/libsystemd/sd-bus/bus-common-errors.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsystemd/sd-bus/bus-common-errors.c b/src/libsystemd/sd-bus/bus-common-errors.c index 8d486fcbbd..7dd726f4da 100644 --- a/src/libsystemd/sd-bus/bus-common-errors.c +++ b/src/libsystemd/sd-bus/bus-common-errors.c @@ -67,7 +67,7 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = { SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_PROCESS, ESRCH), - SD_BUS_ERROR_MAP(BUS_ERROR_NO_NAME_SERVERS, EIO), + SD_BUS_ERROR_MAP(BUS_ERROR_NO_NAME_SERVERS, ESRCH), SD_BUS_ERROR_MAP(BUS_ERROR_INVALID_REPLY, EINVAL), SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_RR, ENOENT), SD_BUS_ERROR_MAP(BUS_ERROR_NO_RESOURCES, ENOMEM), -- cgit v1.2.3-54-g00ecf From eebffed767ca51977a9f53067d2a04f248c0ed1d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Dec 2015 18:55:58 +0100 Subject: resolved: add errno mapping for BUS_ERROR_CONNECTION_FAILURE This was missing when the error type was added in ac720200b7e5b80cc4985087e38f3452e5b3b080. --- src/libsystemd/sd-bus/bus-common-errors.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libsystemd/sd-bus/bus-common-errors.c b/src/libsystemd/sd-bus/bus-common-errors.c index 7dd726f4da..e825cf6c4f 100644 --- a/src/libsystemd/sd-bus/bus-common-errors.c +++ b/src/libsystemd/sd-bus/bus-common-errors.c @@ -73,6 +73,7 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = { SD_BUS_ERROR_MAP(BUS_ERROR_NO_RESOURCES, ENOMEM), SD_BUS_ERROR_MAP(BUS_ERROR_CNAME_LOOP, EDEADLK), SD_BUS_ERROR_MAP(BUS_ERROR_ABORTED, ECANCELED), + SD_BUS_ERROR_MAP(BUS_ERROR_CONNECTION_FAILURE, ECONNREFUSED), SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_TRANSFER, ENXIO), SD_BUS_ERROR_MAP(BUS_ERROR_TRANSFER_IN_PROGRESS, EBUSY), -- cgit v1.2.3-54-g00ecf From 9a1f0c283bac56eb26a2fa02d62e0e9ece82f25a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Dec 2015 18:58:05 +0100 Subject: resolved: properly handle SRV RRs with the DNS root as hostname --- src/libsystemd/sd-bus/bus-common-errors.c | 1 + src/libsystemd/sd-bus/bus-common-errors.h | 1 + src/resolve/resolved-bus.c | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+) diff --git a/src/libsystemd/sd-bus/bus-common-errors.c b/src/libsystemd/sd-bus/bus-common-errors.c index e825cf6c4f..6e2594d001 100644 --- a/src/libsystemd/sd-bus/bus-common-errors.c +++ b/src/libsystemd/sd-bus/bus-common-errors.c @@ -74,6 +74,7 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = { SD_BUS_ERROR_MAP(BUS_ERROR_CNAME_LOOP, EDEADLK), SD_BUS_ERROR_MAP(BUS_ERROR_ABORTED, ECANCELED), SD_BUS_ERROR_MAP(BUS_ERROR_CONNECTION_FAILURE, ECONNREFUSED), + SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_SERVICE, EUNATCH), SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_TRANSFER, ENXIO), SD_BUS_ERROR_MAP(BUS_ERROR_TRANSFER_IN_PROGRESS, EBUSY), diff --git a/src/libsystemd/sd-bus/bus-common-errors.h b/src/libsystemd/sd-bus/bus-common-errors.h index d7d210b0c4..9076993f01 100644 --- a/src/libsystemd/sd-bus/bus-common-errors.h +++ b/src/libsystemd/sd-bus/bus-common-errors.h @@ -73,6 +73,7 @@ #define BUS_ERROR_CNAME_LOOP "org.freedesktop.resolve1.CNameLoop" #define BUS_ERROR_ABORTED "org.freedesktop.resolve1.Aborted" #define BUS_ERROR_CONNECTION_FAILURE "org.freedesktop.resolve1.ConnectionFailure" +#define BUS_ERROR_NO_SUCH_SERVICE "org.freedesktop.resolve1.NoSuchService" #define _BUS_ERROR_DNS "org.freedesktop.resolve1.DnsError." #define BUS_ERROR_NO_SUCH_TRANSFER "org.freedesktop.import1.NoSuchTransfer" diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index 5c7893d01c..4d4c1ca014 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -976,6 +976,7 @@ static void bus_method_resolve_service_complete(DnsQuery *q) { return; if (q->answer) { + bool has_root_domain = false; DnsResourceRecord *rr; int ifindex; @@ -989,6 +990,11 @@ static void bus_method_resolve_service_complete(DnsQuery *q) { if (rr->key->type != DNS_TYPE_SRV) continue; + if (dns_name_is_root(rr->srv.name)) { + has_root_domain = true; + continue; + } + if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) { q->block_all_complete ++; r = resolve_service_hostname(q, rr, ifindex); @@ -1000,6 +1006,18 @@ static void bus_method_resolve_service_complete(DnsQuery *q) { found++; } + + if (has_root_domain && found == 0) { + /* If there's exactly one SRV RR and it uses + * the root domain as host name, then the + * service is explicitly not offered on the + * domain. Report this as a recognizable + * error. See RFC 2782, Section "Usage + * Rules". */ + r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_SERVICE, "'%s' does not provide the requested service", dns_question_first_name(q->question)); + goto finish; + } + } if (found <= 0) { -- cgit v1.2.3-54-g00ecf From 0d0b52d79c2e9a79aeff9a9cca877de8b4fcbd16 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Dec 2015 19:00:53 +0100 Subject: resolved: reset RR TTL to 0, if MSB is set RFC 2181, Section 8 suggests to treat an RR TTL with the MSB set as 0. Implement this. --- src/resolve/resolved-dns-packet.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index 5f79701296..b0c70d0017 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -1580,6 +1580,11 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl if (r < 0) goto fail; + /* RFC 2181, Section 8, suggests to + * treat a TTL with the MSB set as a zero TTL. */ + if (rr->ttl & UINT32_C(0x80000000)) + rr->ttl = 0; + r = dns_packet_read_uint16(p, &rdlength, NULL); if (r < 0) goto fail; -- cgit v1.2.3-54-g00ecf From f3abbe25403444688e1a1a23b9dbcc9aeefc0507 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Dec 2015 19:04:35 +0100 Subject: resolved: parse EDNS0 rcode extension bits --- src/resolve/resolved-dns-packet.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h index a09ace5b75..6821be73e4 100644 --- a/src/resolve/resolved-dns-packet.h +++ b/src/resolve/resolved-dns-packet.h @@ -119,7 +119,17 @@ static inline uint8_t* DNS_PACKET_DATA(DnsPacket *p) { #define DNS_PACKET_RA(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 7) & 1) #define DNS_PACKET_AD(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 5) & 1) #define DNS_PACKET_CD(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 4) & 1) -#define DNS_PACKET_RCODE(p) (be16toh(DNS_PACKET_HEADER(p)->flags) & 15) + +static inline uint16_t DNS_PACKET_RCODE(DnsPacket *p) { + uint16_t rcode; + + if (p->opt) + rcode = (uint16_t) (p->opt->ttl >> 24); + else + rcode = 0; + + return rcode | (be16toh(DNS_PACKET_HEADER(p)->flags) & 15); +} /* LLMNR defines some bits differently */ #define DNS_PACKET_LLMNR_C(p) DNS_PACKET_AA(p) @@ -203,6 +213,7 @@ static inline bool DNS_PACKET_SHALL_CACHE(DnsPacket *p) { return in_addr_is_localhost(p->family, &p->sender) == 0; } +/* https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6 */ enum { DNS_RCODE_SUCCESS = 0, DNS_RCODE_FORMERR = 1, -- cgit v1.2.3-54-g00ecf From 7feea00bb06bca94545d5682930c11a6dee9c642 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Dec 2015 19:06:12 +0100 Subject: resolved: don't allow RRs with TTL=0 and TTL!=0 in the same RRset --- src/resolve/resolved-dns-answer.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c index 399b518644..445999f545 100644 --- a/src/resolve/resolved-dns-answer.c +++ b/src/resolve/resolved-dns-answer.c @@ -125,10 +125,13 @@ int dns_answer_add(DnsAnswer *a, DnsResourceRecord *rr, int ifindex, DnsAnswerFl if (r < 0) return r; if (r > 0) { - /* Entry already exists, keep the entry with - * the higher RR, or the one with TTL 0 */ + /* Don't mix contradicting TTLs (see below) */ + if ((rr->ttl == 0) != (a->items[i].rr->ttl == 0)) + return -EINVAL; - if (rr->ttl == 0 || (rr->ttl > a->items[i].rr->ttl && a->items[i].rr->ttl != 0)) { + /* Entry already exists, keep the entry with + * the higher RR. */ + if (rr->ttl > a->items[i].rr->ttl) { dns_resource_record_ref(rr); dns_resource_record_unref(a->items[i].rr); a->items[i].rr = rr; @@ -137,6 +140,21 @@ int dns_answer_add(DnsAnswer *a, DnsResourceRecord *rr, int ifindex, DnsAnswerFl a->items[i].flags |= flags; return 0; } + + r = dns_resource_key_equal(a->items[i].rr->key, rr->key); + if (r < 0) + return r; + if (r > 0) { + /* There's already an RR of the same RRset in + * place! Let's see if the TTLs more or less + * match. We don't really care if they match + * precisely, but we do care whether one is 0 + * and the other is not. See RFC 2181, Section + * 5.2.*/ + + if ((rr->ttl == 0) != (a->items[i].rr->ttl == 0)) + return -EINVAL; + } } return dns_answer_add_raw(a, rr, ifindex, flags); -- cgit v1.2.3-54-g00ecf From efd46a696d31097c38f653b36921e00c4df62319 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Dec 2015 19:08:22 +0100 Subject: resolved: use CLAMP() intsead of MIN(MAX()) --- src/resolve/resolved-dns-server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c index a57385d47d..fbd1c27c14 100644 --- a/src/resolve/resolved-dns-server.c +++ b/src/resolve/resolved-dns-server.c @@ -253,7 +253,7 @@ void dns_server_packet_received(DnsServer *s, DnsServerFeatureLevel level, usec_ if (s->max_rtt < rtt) { s->max_rtt = rtt; - s->resend_timeout = MIN(MAX(DNS_TIMEOUT_MIN_USEC, s->max_rtt * 2), DNS_TIMEOUT_MAX_USEC); + s->resend_timeout = CLAMP(s->max_rtt * 2, DNS_TIMEOUT_MIN_USEC, DNS_TIMEOUT_MAX_USEC); } } -- cgit v1.2.3-54-g00ecf From 6f717d0817573a76c3e586eae02793d8b23a0581 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Dec 2015 19:09:14 +0100 Subject: resolved: include GOST in list of DNSSEC algorithms We don't implement it, and we have no intention to, but at least mention that it exists. (This also adds a couple of other algorithms to the algorithm string list, where these strings were missing previously.) --- src/resolve/resolved-dns-rr.c | 11 +++++++++-- src/resolve/resolved-dns-rr.h | 10 ++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index d479de7125..89645b064c 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -1109,6 +1109,7 @@ bool dns_txt_item_equal(DnsTxtItem *a, DnsTxtItem *b) { } static const char* const dnssec_algorithm_table[_DNSSEC_ALGORITHM_MAX_DEFINED] = { + /* Mnemonics as listed on https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml */ [DNSSEC_ALGORITHM_RSAMD5] = "RSAMD5", [DNSSEC_ALGORITHM_DH] = "DH", [DNSSEC_ALGORITHM_DSA] = "DSA", @@ -1118,6 +1119,9 @@ static const char* const dnssec_algorithm_table[_DNSSEC_ALGORITHM_MAX_DEFINED] = [DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1] = "RSASHA1-NSEC3-SHA1", [DNSSEC_ALGORITHM_RSASHA256] = "RSASHA256", [DNSSEC_ALGORITHM_RSASHA512] = "RSASHA512", + [DNSSEC_ALGORITHM_ECC_GOST] = "ECC-GOST", + [DNSSEC_ALGORITHM_ECDSAP256SHA256] = "ECDSAP256SHA256", + [DNSSEC_ALGORITHM_ECDSAP384SHA384] = "ECDSAP384SHA384", [DNSSEC_ALGORITHM_INDIRECT] = "INDIRECT", [DNSSEC_ALGORITHM_PRIVATEDNS] = "PRIVATEDNS", [DNSSEC_ALGORITHM_PRIVATEOID] = "PRIVATEOID", @@ -1125,7 +1129,10 @@ static const char* const dnssec_algorithm_table[_DNSSEC_ALGORITHM_MAX_DEFINED] = DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm, int); static const char* const dnssec_digest_table[_DNSSEC_DIGEST_MAX_DEFINED] = { - [DNSSEC_DIGEST_SHA1] = "SHA1", - [DNSSEC_DIGEST_SHA256] = "SHA256", + /* Names as listed on https://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml */ + [DNSSEC_DIGEST_SHA1] = "SHA-1", + [DNSSEC_DIGEST_SHA256] = "SHA-256", + [DNSSEC_DIGEST_GOST_R_34_11_94] = "GOST_R_34.11-94", + [DNSSEC_DIGEST_SHA384] = "SHA-384", }; DEFINE_STRING_TABLE_LOOKUP(dnssec_digest, int); diff --git a/src/resolve/resolved-dns-rr.h b/src/resolve/resolved-dns-rr.h index fccc4dba6a..317be0efbe 100644 --- a/src/resolve/resolved-dns-rr.h +++ b/src/resolve/resolved-dns-rr.h @@ -51,8 +51,9 @@ enum { DNSSEC_ALGORITHM_RSASHA1, DNSSEC_ALGORITHM_DSA_NSEC3_SHA1, DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1, - DNSSEC_ALGORITHM_RSASHA256 = 8, /* RFC 5702 */ - DNSSEC_ALGORITHM_RSASHA512 = 10, /* RFC 5702 */ + DNSSEC_ALGORITHM_RSASHA256 = 8, /* RFC 5702 */ + DNSSEC_ALGORITHM_RSASHA512 = 10, /* RFC 5702 */ + DNSSEC_ALGORITHM_ECC_GOST = 12, /* RFC 5933 */ DNSSEC_ALGORITHM_ECDSAP256SHA256 = 13, /* RFC 6605 */ DNSSEC_ALGORITHM_ECDSAP384SHA384 = 14, /* RFC 6605 */ DNSSEC_ALGORITHM_INDIRECT = 252, @@ -65,8 +66,9 @@ enum { * https://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml */ enum { DNSSEC_DIGEST_SHA1 = 1, - DNSSEC_DIGEST_SHA256 = 2, - DNSSEC_DIGEST_SHA384 = 4, + DNSSEC_DIGEST_SHA256 = 2, /* RFC 4509 */ + DNSSEC_DIGEST_GOST_R_34_11_94 = 3, /* RFC 5933 */ + DNSSEC_DIGEST_SHA384 = 4, /* RFC 6605 */ _DNSSEC_DIGEST_MAX_DEFINED }; -- cgit v1.2.3-54-g00ecf From 6af47493de0ef2b66d4c3fbcdd4a2e12fec4bfba Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Dec 2015 19:27:09 +0100 Subject: resolved: add comments referencing various RFCs to various places --- src/resolve/resolved-dns-cache.c | 3 ++- src/resolve/resolved-dns-dnssec.c | 10 +++++++++- src/resolve/resolved-dns-rr.c | 4 ++++ src/resolve/resolved-dns-rr.h | 18 ++++++++++-------- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c index 3193985542..1c7dd56b3b 100644 --- a/src/resolve/resolved-dns-cache.c +++ b/src/resolve/resolved-dns-cache.c @@ -26,7 +26,8 @@ #include "resolved-dns-packet.h" #include "string-util.h" -/* Never cache more than 4K entries */ +/* Never cache more than 4K entries. RFC 1536, Section 5 suggests to + * leave DNS caches unbounded, but that's crazy. */ #define CACHE_MAX 4096 /* We never keep any item longer than 2h in our cache */ diff --git a/src/resolve/resolved-dns-dnssec.c b/src/resolve/resolved-dns-dnssec.c index a3aa90e98d..3f5226de0d 100644 --- a/src/resolve/resolved-dns-dnssec.c +++ b/src/resolve/resolved-dns-dnssec.c @@ -458,7 +458,15 @@ static int dnssec_rrsig_expired(DnsResourceRecord *rrsig, usec_t realtime) { static int algorithm_to_gcrypt_md(uint8_t algorithm) { - /* Translates a DNSSEC signature algorithm into a gcrypt digest identifier */ + /* Translates a DNSSEC signature algorithm into a gcrypt + * digest identifier. + * + * Note that we implement all algorithms listed as "Must + * implement" and "Recommended to Implement" in RFC6944. We + * don't implement any algorithms that are listed as + * "Optional" or "Must Not Implement". Specifically, we do not + * implement RSAMD5, DSASHA1, DH, DSA-NSEC3-SHA1, and + * GOST-ECC. */ switch (algorithm) { diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c index 89645b064c..274e857586 100644 --- a/src/resolve/resolved-dns-rr.c +++ b/src/resolve/resolved-dns-rr.c @@ -311,6 +311,9 @@ int dns_resource_key_to_string(const DnsResourceKey *key, char **ret) { const char *c, *t; char *s; + /* If we cannot convert the CLASS/TYPE into a known string, + use the format recommended by RFC 3597, Section 5. */ + c = dns_class_to_string(key->class); if (!c) { sprintf(cbuf, "CLASS%u", key->class); @@ -1021,6 +1024,7 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) { if (!t) return NULL; + /* Format as documented in RFC 3597, Section 5 */ r = asprintf(&s, "%s \\# %zu %s", k, rr->generic.size, t); if (r < 0) return NULL; diff --git a/src/resolve/resolved-dns-rr.h b/src/resolve/resolved-dns-rr.h index 317be0efbe..cee3978969 100644 --- a/src/resolve/resolved-dns-rr.h +++ b/src/resolve/resolved-dns-rr.h @@ -157,6 +157,7 @@ struct DnsResourceRecord { char *exchange; } mx; + /* https://tools.ietf.org/html/rfc1876 */ struct { uint8_t version; uint8_t size; @@ -167,14 +168,6 @@ struct DnsResourceRecord { uint32_t altitude; } loc; - struct { - uint16_t key_tag; - uint8_t algorithm; - uint8_t digest_type; - void *digest; - size_t digest_size; - } ds; - /* https://tools.ietf.org/html/rfc4255#section-3.1 */ struct { uint8_t algorithm; @@ -212,6 +205,15 @@ struct DnsResourceRecord { Bitmap *types; } nsec; + /* https://tools.ietf.org/html/rfc4034#section-5.1 */ + struct { + uint16_t key_tag; + uint8_t algorithm; + uint8_t digest_type; + void *digest; + size_t digest_size; + } ds; + struct { uint8_t algorithm; uint8_t flags; -- cgit v1.2.3-54-g00ecf From 0a9a2ac3d3369b5add3b54823d088ba89baa27ab Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Dec 2015 19:27:55 +0100 Subject: update DNSSEC TODO --- src/resolve/resolved-dns-dnssec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/resolve/resolved-dns-dnssec.c b/src/resolve/resolved-dns-dnssec.c index 3f5226de0d..aca67b85f8 100644 --- a/src/resolve/resolved-dns-dnssec.c +++ b/src/resolve/resolved-dns-dnssec.c @@ -42,7 +42,8 @@ * - per-interface DNSSEC setting * - nxdomain on qname * - retry on failed validation? - * - DSA support? + * - DNSSEC key revocation support? https://tools.ietf.org/html/rfc5011 + * - when doing negative caching, use NSEC/NSEC3 RR instead of SOA for TTL * * */ -- cgit v1.2.3-54-g00ecf From d15ad74251454d55b715958d8e6f50f45195904a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Dec 2015 20:50:03 +0100 Subject: resolved: NSEC3 hash algorithms are distinct from DS digest algorithms Previously, we'd use the same set of identifiers for both, but that's actually incorrect. It didn't matter much since the only NSEC3 hash algorithm defined (SHA-1) is mapped to code 1 which is also what it is encoded as in DS digests, but we really should make sure to use two distinct enumerations. --- src/resolve/resolved-dns-dnssec.c | 20 +++++++++++++++++++- src/resolve/resolved-dns-rr.h | 7 +++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/resolve/resolved-dns-dnssec.c b/src/resolve/resolved-dns-dnssec.c index aca67b85f8..e4b32c7e4b 100644 --- a/src/resolve/resolved-dns-dnssec.c +++ b/src/resolve/resolved-dns-dnssec.c @@ -1057,6 +1057,20 @@ int dnssec_verify_dnskey_search(DnsResourceRecord *dnskey, DnsAnswer *validated_ return 0; } +static int nsec3_hash_to_gcrypt_md(uint8_t algorithm) { + + /* Translates a DNSSEC NSEC3 hash algorithm into a gcrypt digest identifier */ + + switch (algorithm) { + + case NSEC3_ALGORITHM_SHA1: + return GCRY_MD_SHA1; + + default: + return -EOPNOTSUPP; + } +} + int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret) { uint8_t wire_format[DNS_WIRE_FOMAT_HOSTNAME_MAX]; gcry_md_hd_t md = NULL; @@ -1073,7 +1087,7 @@ int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret) { if (nsec3->key->type != DNS_TYPE_NSEC3) return -EINVAL; - algorithm = digest_to_gcrypt_md(nsec3->nsec3.algorithm); + algorithm = nsec3_hash_to_gcrypt_md(nsec3->nsec3.algorithm); if (algorithm < 0) return algorithm; @@ -1138,6 +1152,10 @@ static int nsec3_is_good(DnsResourceRecord *rr, DnsAnswerFlags flags, DnsResourc if (!IN_SET(rr->nsec3.flags, 0, 1)) return 0; + /* Ignore NSEC3 RRs whose algorithm we don't know */ + if (nsec3_hash_to_gcrypt_md(rr->nsec3.algorithm) < 0) + return 0; + if (!nsec3) return 1; diff --git a/src/resolve/resolved-dns-rr.h b/src/resolve/resolved-dns-rr.h index cee3978969..27c5f5384e 100644 --- a/src/resolve/resolved-dns-rr.h +++ b/src/resolve/resolved-dns-rr.h @@ -72,6 +72,13 @@ enum { _DNSSEC_DIGEST_MAX_DEFINED }; +/* DNSSEC NSEC3 hash algorithms, see + * https://www.iana.org/assignments/dnssec-nsec3-parameters/dnssec-nsec3-parameters.xhtml */ +enum { + NSEC3_ALGORITHM_SHA1 = 1, + _NSEC3_ALGORITHM_MAX_DEFINED +}; + struct DnsResourceKey { unsigned n_ref; uint16_t class, type; -- cgit v1.2.3-54-g00ecf From 665408ac05d2609a19f8a0073865ab8cf6ab9a6a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Dec 2015 20:52:27 +0100 Subject: resolved: append RFC6975 algorithm data to EDNS OPT RR --- src/resolve/resolved-dns-packet.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index b0c70d0017..5cc96308da 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -723,7 +723,40 @@ int dns_packet_append_opt(DnsPacket *p, uint16_t max_udp_size, bool edns0_do, si goto fail; /* RDLENGTH */ - r = dns_packet_append_uint16(p, 0, NULL); + + if (edns0_do) { + /* If DO is on, also append RFC6975 Algorithm data */ + + static const uint8_t rfc6975[] = { + + 0, 5, /* OPTION_CODE: DAU */ + 0, 6, /* LIST_LENGTH */ + DNSSEC_ALGORITHM_RSASHA1, + DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1, + DNSSEC_ALGORITHM_RSASHA256, + DNSSEC_ALGORITHM_RSASHA512, + DNSSEC_ALGORITHM_ECDSAP256SHA256, + DNSSEC_ALGORITHM_ECDSAP384SHA384, + + 0, 6, /* OPTION_CODE: DHU */ + 0, 3, /* LIST_LENGTH */ + DNSSEC_DIGEST_SHA1, + DNSSEC_DIGEST_SHA256, + DNSSEC_DIGEST_SHA384, + + 0, 7, /* OPTION_CODE: N3U */ + 0, 1, /* LIST_LENGTH */ + NSEC3_ALGORITHM_SHA1, + }; + + r = dns_packet_append_uint16(p, sizeof(rfc6975), NULL); + if (r < 0) + goto fail; + + r = dns_packet_append_blob(p, rfc6975, sizeof(rfc6975), NULL); + } else + r = dns_packet_append_uint16(p, 0, NULL); + if (r < 0) goto fail; -- cgit v1.2.3-54-g00ecf From e9bb4ec69dafb2f39551265e6b900bb18a3169bd Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Dec 2015 21:27:11 +0100 Subject: resolved: add a list of DNS-related RFCs and their implementation status in resolved --- src/resolve/RFCs | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/resolve/RFCs diff --git a/src/resolve/RFCs b/src/resolve/RFCs new file mode 100644 index 0000000000..8cad108d2c --- /dev/null +++ b/src/resolve/RFCs @@ -0,0 +1,53 @@ +Y = Comprehensively Implemented, to the point appropriate for resolved +D = Comprehensively Implemented, by a dependency of resolved +! = Missing and something we might want to implement +~ = Needs no explicit support or doesn't apply +? = Is this relevant today? + = We are working on this + +Y https://tools.ietf.org/html/rfc1034 → DOMAIN NAMES - CONCEPTS AND FACILITIES +Y https://tools.ietf.org/html/rfc1035 → DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION +? https://tools.ietf.org/html/rfc1101 → DNS Encoding of Network Names and Other Types +Y https://tools.ietf.org/html/rfc1123 → Requirements for Internet Hosts -- Application and Support +Y https://tools.ietf.org/html/rfc1536 → Common DNS Implementation Errors and Suggested Fixes +Y https://tools.ietf.org/html/rfc1876 → A Means for Expressing Location Information in the Domain Name System +Y https://tools.ietf.org/html/rfc2181 → Clarifications to the DNS Specification + https://tools.ietf.org/html/rfc2308 → Negative Caching of DNS Queries (DNS NCACHE) +Y https://tools.ietf.org/html/rfc2782 → A DNS RR for specifying the location of services (DNS SRV) +D https://tools.ietf.org/html/rfc3492 → Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA) +Y https://tools.ietf.org/html/rfc3596 → DNS Extensions to Support IP Version 6 +Y https://tools.ietf.org/html/rfc3597 → Handling of Unknown DNS Resource Record (RR) Types + https://tools.ietf.org/html/rfc4033 → DNS Security Introduction and Requirements + https://tools.ietf.org/html/rfc4034 → Resource Records for the DNS Security Extensions + https://tools.ietf.org/html/rfc4035 → Protocol Modifications for the DNS Security Extensions +! https://tools.ietf.org/html/rfc4183 → A Suggested Scheme for DNS Resolution of Networks and Gateways +Y https://tools.ietf.org/html/rfc4255 → Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints +Y https://tools.ietf.org/html/rfc4343 → Domain Name System (DNS) Case Insensitivity Clarification +~ https://tools.ietf.org/html/rfc4470 → Minimally Covering NSEC Records and DNSSEC On-line Signing +Y https://tools.ietf.org/html/rfc4509 → Use of SHA-256 in DNSSEC Delegation Signer (DS) Resource Records (RRs) +~ https://tools.ietf.org/html/rfc4592 → The Role of Wildcards in the Domain Name System +Y https://tools.ietf.org/html/rfc4795 → Link-Local Multicast Name Resolution (LLMNR) +! https://tools.ietf.org/html/rfc5011 → Automated Updates of DNS Security (DNSSEC) Trust Anchors + https://tools.ietf.org/html/rfc5155 → DNS Security (DNSSEC) Hashed Authenticated Denial of Existence +Y https://tools.ietf.org/html/rfc5702 → Use of SHA-2 Algorithms with RSA in DNSKEY and RRSIG Resource Records for DNSSEC +Y https://tools.ietf.org/html/rfc5890 → Internationalized Domain Names for Applications (IDNA): Definitions and Document Framework +Y https://tools.ietf.org/html/rfc5891 → Internationalized Domain Names in Applications (IDNA): Protocol +Y https://tools.ietf.org/html/rfc5966 → DNS Transport over TCP - Implementation Requirements +Y https://tools.ietf.org/html/rfc6303 → Locally Served DNS Zones +Y https://tools.ietf.org/html/rfc6605 → Elliptic Curve Digital Signature Algorithm (DSA) for DNSSEC + https://tools.ietf.org/html/rfc6672 → DNAME Redirection in the DNS +Y https://tools.ietf.org/html/rfc6761 → Special-Use Domain Names + https://tools.ietf.org/html/rfc6762 → Multicast DNS + https://tools.ietf.org/html/rfc6763 → DNS-Based Service Discovery + https://tools.ietf.org/html/rfc6781 → DNSSEC Operational Practices, Version 2 + https://tools.ietf.org/html/rfc6840 → Clarifications and Implementation Notes for DNS Security (DNSSEC) +Y https://tools.ietf.org/html/rfc6891 → Extension Mechanisms for DNS (EDNS(0)) +Y https://tools.ietf.org/html/rfc6944 → Applicability Statement: DNS Security (DNSSEC) DNSKEY Algorithm Implementation Status +Y https://tools.ietf.org/html/rfc6975 → Signaling Cryptographic Algorithm Understanding in DNS Security Extensions (DNSSEC) + https://tools.ietf.org/html/rfc7129 → Authenticated Denial of Existence in the DNS +! https://tools.ietf.org/html/rfc7646 → Definition and Use of DNSSEC Negative Trust Anchors +~ https://tools.ietf.org/html/rfc7719 → DNS Terminology + +Also relevant: + + https://www.iab.org/documents/correspondence-reports-documents/2013-2/iab-statement-dotless-domains-considered-harmful/ -- cgit v1.2.3-54-g00ecf