summaryrefslogtreecommitdiff
path: root/src/resolve
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-01-06 18:36:32 +0100
committerLennart Poettering <lennart@poettering.net>2016-01-06 18:36:32 +0100
commit8a516214c4412e8a40544bd725a6d499a30cbbbf (patch)
treed8e7504d9da15641f03f7b4ca82dd3fc612544ed /src/resolve
parentbec690501ed544199e72a292fbd6d28bc1e1727e (diff)
resolved: introduce support for per-interface negative trust anchors
Diffstat (limited to 'src/resolve')
-rw-r--r--src/resolve/resolved-dns-transaction.c29
-rw-r--r--src/resolve/resolved-link.c43
-rw-r--r--src/resolve/resolved-link.h1
3 files changed, 68 insertions, 5 deletions
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;