summaryrefslogtreecommitdiff
path: root/src/resolve/resolved-dns-transaction.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-01-04 22:35:54 +0100
committerLennart Poettering <lennart@poettering.net>2016-01-04 22:42:10 +0100
commitb2b796b8ab5565fbe60b544d2579e2bfca31bf6a (patch)
treeb06a7484dcc2fb4cfa0de22880fe048a9104c5ba /src/resolve/resolved-dns-transaction.c
parenta761c1ca851a9397b5a207ef600e077d0f7f4534 (diff)
resolved: explicitly handle case when the trust anchor is empty
Since we honour RFC5011 revoked keys it might happen we end up with an empty trust anchor, or one where there's no entry for the root left. With this patch the logic is changed what to do in this case. Before this patch we'd end up requesting the root DS, which returns with NODATA but a signed NSEC we cannot verify, since the trust anchor is empty after all. Thus we'd return a DNSSEC result of "missing-key", as we lack a verified version of the key. With this patch in place, look-ups for the root DS are explicitly recognized, and not passed on to the DNS servers. Instead, if downgrade-ok mode is on an unsigned NODATA response is synthesized, so that the validator code continues under the assumption the root zone was unsigned. If downgrade-ok mode is off a new transaction failure is generated, that makes this case recognizable.
Diffstat (limited to 'src/resolve/resolved-dns-transaction.c')
-rw-r--r--src/resolve/resolved-dns-transaction.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index ce320e9a97..677d643463 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -926,6 +926,41 @@ static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
return 0;
}
+
+ if (dns_name_is_root(DNS_RESOURCE_KEY_NAME(t->key)) &&
+ t->key->type == DNS_TYPE_DS) {
+
+ /* Hmm, this is a request for the root DS? A
+ * DS RR doesn't exist in the root zone, and
+ * if our trust anchor didn't know it either,
+ * this means we cannot do any DNSSEC logic
+ * anymore. */
+
+ if (t->scope->dnssec_mode == DNSSEC_DOWNGRADE_OK) {
+ /* We are in downgrade mode. In this
+ * case, synthesize an unsigned empty
+ * response, so that the any lookup
+ * depending on this one can continue
+ * assuming there was no DS, and hence
+ * the root zone was unsigned. */
+
+ t->answer_rcode = DNS_RCODE_SUCCESS;
+ t->answer_source = DNS_TRANSACTION_TRUST_ANCHOR;
+ t->answer_authenticated = false;
+ dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);
+ } else
+ /* If we are not in downgrade mode,
+ * then fail the lookup, because we
+ * cannot reasonably answer it. There
+ * might be DS RRs, but we don't know
+ * them, and the DNS server won't tell
+ * them to us (and even if it would,
+ * we couldn't validate it and trust
+ * it). */
+ dns_transaction_complete(t, DNS_TRANSACTION_NO_TRUST_ANCHOR);
+
+ return 0;
+ }
}
/* Check the zone, but only if this transaction is not used
@@ -2438,6 +2473,7 @@ static const char* const dns_transaction_state_table[_DNS_TRANSACTION_STATE_MAX]
[DNS_TRANSACTION_CONNECTION_FAILURE] = "connection-failure",
[DNS_TRANSACTION_ABORTED] = "aborted",
[DNS_TRANSACTION_DNSSEC_FAILED] = "dnssec-failed",
+ [DNS_TRANSACTION_NO_TRUST_ANCHOR] = "no-trust-anchor",
};
DEFINE_STRING_TABLE_LOOKUP(dns_transaction_state, DnsTransactionState);