summaryrefslogtreecommitdiff
path: root/src/resolve/resolved-dns-transaction.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-12-14 21:26:42 +0100
committerLennart Poettering <lennart@poettering.net>2015-12-14 21:28:39 +0100
commit72667f0890372a952a7c5b8cc498ec3cf9440973 (patch)
tree250c0fd5bc5ec29d5789f09dbb5b01680c4ef6fc /src/resolve/resolved-dns-transaction.c
parentd0ae14ff09fca330d0ae3b41ab15e0d42210967b (diff)
resolved: add basic proof of non-existance support for NSEC+NSEC3
Note that this is not complete yet, as we don't handle wildcard domains correctly, nor handle domains correctly that use empty non-terminals.
Diffstat (limited to 'src/resolve/resolved-dns-transaction.c')
-rw-r--r--src/resolve/resolved-dns-transaction.c53
1 files changed, 51 insertions, 2 deletions
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index 045627340b..f09788b0c6 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -1472,8 +1472,57 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) {
/* Everything that's now in t->answer is known to be good, hence cacheable. */
t->n_answer_cacheable = (unsigned) -1; /* everything! */
- t->answer_authenticated = true;
- t->dnssec_result = DNSSEC_VALIDATED;
+ /* At this point the answer only contains validated
+ * RRsets. Now, let's see if it actually answers the question
+ * we asked. If so, great! If it doesn't, then see if
+ * NSEC/NSEC3 can prove this. */
+ r = dns_answer_match_key(t->answer, t->key);
+ if (r < 0)
+ return r;
+ if (r > 0) {
+ /* Yes, it answer the question, everything is authenticated. */
+ t->dnssec_result = DNSSEC_VALIDATED;
+ t->answer_rcode = DNS_RCODE_SUCCESS;
+ t->answer_authenticated = true;
+ } else if (r == 0) {
+ DnssecNsecResult nr;
+
+ /* Bummer! Let's check NSEC/NSEC3 */
+ r = dnssec_test_nsec(t->answer, t->key, &nr);
+ if (r < 0)
+ return r;
+
+ switch (nr) {
+
+ case DNSSEC_NSEC_NXDOMAIN:
+ /* NSEC proves the domain doesn't exist. Very good. */
+ t->dnssec_result = DNSSEC_VALIDATED;
+ t->answer_rcode = DNS_RCODE_NXDOMAIN;
+ t->answer_authenticated = true;
+ break;
+
+ case DNSSEC_NSEC_NODATA:
+ /* NSEC proves that there's no data here, very good. */
+ t->dnssec_result = DNSSEC_VALIDATED;
+ t->answer_rcode = DNS_RCODE_SUCCESS;
+ t->answer_authenticated = true;
+ break;
+
+ case DNSSEC_NSEC_NO_RR:
+ /* No NSEC data? Bummer! */
+ t->dnssec_result = DNSSEC_UNSIGNED;
+ break;
+
+ case DNSSEC_NSEC_FOUND:
+ /* NSEC says it needs to be there, but we couldn't find it? Bummer! */
+ t->dnssec_result = DNSSEC_NSEC_MISMATCH;
+ break;
+
+ default:
+ assert_not_reached("Unexpected NSEC result.");
+ }
+ }
+
return 1;
}