From 8a516214c4412e8a40544bd725a6d499a30cbbbf Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 6 Jan 2016 18:36:32 +0100 Subject: resolved: introduce support for per-interface negative trust anchors --- src/resolve/resolved-dns-transaction.c | 29 +++++++++++++++++++---- src/resolve/resolved-link.c | 43 ++++++++++++++++++++++++++++++++++ src/resolve/resolved-link.h | 1 + 3 files changed, 68 insertions(+), 5 deletions(-) (limited to 'src/resolve') diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c index 8631afadb2..f5171a940f 100644 --- a/src/resolve/resolved-dns-transaction.c +++ b/src/resolve/resolved-dns-transaction.c @@ -1406,6 +1406,25 @@ static int dns_transaction_has_positive_answer(DnsTransaction *t, DnsAnswerFlags return false; } +static int dns_transaction_negative_trust_anchor_lookup(DnsTransaction *t, const char *name) { + int r; + + assert(t); + + /* Check whether the specified name is in the the NTA + * database, either in the global one, or the link-local + * one. */ + + r = dns_trust_anchor_lookup_negative(&t->scope->manager->trust_anchor, name); + if (r != 0) + return r; + + if (!t->scope->link) + return 0; + + return set_contains(t->scope->link->dnssec_negative_trust_anchors, name); +} + static int dns_transaction_has_unsigned_negative_answer(DnsTransaction *t) { int r; @@ -1422,7 +1441,7 @@ static int dns_transaction_has_unsigned_negative_answer(DnsTransaction *t) { /* Is this key explicitly listed as a negative trust anchor? * If so, it's nothing we need to care about */ - r = dns_trust_anchor_lookup_negative(&t->scope->manager->trust_anchor, DNS_RESOURCE_KEY_NAME(t->key)); + r = dns_transaction_negative_trust_anchor_lookup(t, DNS_RESOURCE_KEY_NAME(t->key)); if (r < 0) return r; if (r > 0) @@ -1513,7 +1532,7 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) { continue; /* If this RR is in the negative trust anchor, we don't need to validate it. */ - r = dns_trust_anchor_lookup_negative(&t->scope->manager->trust_anchor, DNS_RESOURCE_KEY_NAME(rr->key)); + r = dns_transaction_negative_trust_anchor_lookup(t, DNS_RESOURCE_KEY_NAME(rr->key)); if (r < 0) return r; if (r > 0) @@ -1863,7 +1882,7 @@ static int dns_transaction_requires_rrsig(DnsTransaction *t, DnsResourceRecord * if (dns_type_is_pseudo(rr->key->type)) return -EINVAL; - r = dns_trust_anchor_lookup_negative(&t->scope->manager->trust_anchor, DNS_RESOURCE_KEY_NAME(rr->key)); + r = dns_transaction_negative_trust_anchor_lookup(t, DNS_RESOURCE_KEY_NAME(rr->key)); if (r < 0) return r; if (r > 0) @@ -2066,7 +2085,7 @@ static int dns_transaction_requires_nsec(DnsTransaction *t) { if (dns_type_is_pseudo(t->key->type)) return -EINVAL; - r = dns_trust_anchor_lookup_negative(&t->scope->manager->trust_anchor, DNS_RESOURCE_KEY_NAME(t->key)); + r = dns_transaction_negative_trust_anchor_lookup(t, DNS_RESOURCE_KEY_NAME(t->key)); if (r < 0) return r; if (r > 0) @@ -2135,7 +2154,7 @@ static int dns_transaction_dnskey_authenticated(DnsTransaction *t, DnsResourceRe * the specified RRset is authenticated (i.e. has a matching * DS RR). */ - r = dns_trust_anchor_lookup_negative(&t->scope->manager->trust_anchor, DNS_RESOURCE_KEY_NAME(rr->key)); + r = dns_transaction_negative_trust_anchor_lookup(t, DNS_RESOURCE_KEY_NAME(rr->key)); if (r < 0) return r; if (r > 0) diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c index 50d3f9096b..30838ef8cc 100644 --- a/src/resolve/resolved-link.c +++ b/src/resolve/resolved-link.c @@ -82,6 +82,8 @@ Link *link_free(Link *l) { dns_scope_free(l->mdns_ipv4_scope); dns_scope_free(l->mdns_ipv6_scope); + set_free_free(l->dnssec_negative_trust_anchors); + free(l); return NULL; } @@ -302,6 +304,43 @@ clear: return r; } +static int link_update_dnssec_negative_trust_anchors(Link *l) { + _cleanup_strv_free_ char **ntas = NULL; + _cleanup_set_free_free_ Set *ns = NULL; + char **i; + int r; + + assert(l); + + r = sd_network_link_get_dnssec_negative_trust_anchors(l->ifindex, &ntas); + if (r == -ENODATA) { + r = 0; + goto clear; + } + if (r < 0) + goto clear; + + ns = set_new(&dns_name_hash_ops); + if (!ns) + return -ENOMEM; + + STRV_FOREACH(i, ntas) { + r = set_put_strdup(ns, *i); + if (r < 0) + return r; + } + + set_free_free(l->dnssec_negative_trust_anchors); + l->dnssec_negative_trust_anchors = ns; + ns = NULL; + + return 0; + +clear: + l->dnssec_negative_trust_anchors = set_free_free(l->dnssec_negative_trust_anchors); + return r; +} + static int link_update_search_domains(Link *l) { _cleanup_strv_free_ char **domains = NULL; char **i; @@ -365,6 +404,10 @@ int link_update_monitor(Link *l) { if (r < 0) log_warning_errno(r, "Failed to read DNSSEC mode for interface %s, ignoring: %m", l->name); + r = link_update_dnssec_negative_trust_anchors(l); + if (r < 0) + log_warning_errno(r, "Failed to read DNSSEC negative trust anchors for interface %s, ignoring: %m", l->name); + r = link_update_search_domains(l); if (r < 0) log_warning_errno(r, "Failed to read search domains for interface %s, ignoring: %m", l->name); diff --git a/src/resolve/resolved-link.h b/src/resolve/resolved-link.h index d17b57253b..db0e51da04 100644 --- a/src/resolve/resolved-link.h +++ b/src/resolve/resolved-link.h @@ -70,6 +70,7 @@ struct Link { ResolveSupport llmnr_support; ResolveSupport mdns_support; DnssecMode dnssec_mode; + Set *dnssec_negative_trust_anchors; DnsScope *unicast_scope; DnsScope *llmnr_ipv4_scope; -- cgit v1.2.3-54-g00ecf