You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
4.0 KiB
147 lines
4.0 KiB
diff --git a/lib/dns/message.c b/lib/dns/message.c |
|
index 869d258..c1f9498 100644 |
|
--- a/lib/dns/message.c |
|
+++ b/lib/dns/message.c |
|
@@ -1150,6 +1150,63 @@ update(dns_section_t section, dns_rdataclass_t rdclass) { |
|
return (ISC_FALSE); |
|
} |
|
|
|
+/* |
|
+ * Check to confirm that all DNSSEC records (DS, NSEC, NSEC3) have |
|
+ * covering RRSIGs. |
|
+ */ |
|
+static isc_boolean_t |
|
+auth_signed(dns_namelist_t *section) { |
|
+ dns_name_t *name; |
|
+ |
|
+ for (name = ISC_LIST_HEAD(*section); |
|
+ name != NULL; |
|
+ name = ISC_LIST_NEXT(name, link)) |
|
+ { |
|
+ int auth_dnssec = 0, auth_rrsig = 0; |
|
+ dns_rdataset_t *rds; |
|
+ |
|
+ for (rds = ISC_LIST_HEAD(name->list); |
|
+ rds != NULL; |
|
+ rds = ISC_LIST_NEXT(rds, link)) |
|
+ { |
|
+ switch (rds->type) { |
|
+ case dns_rdatatype_ds: |
|
+ auth_dnssec |= 0x1; |
|
+ break; |
|
+ case dns_rdatatype_nsec: |
|
+ auth_dnssec |= 0x2; |
|
+ break; |
|
+ case dns_rdatatype_nsec3: |
|
+ auth_dnssec |= 0x4; |
|
+ break; |
|
+ case dns_rdatatype_rrsig: |
|
+ break; |
|
+ default: |
|
+ continue; |
|
+ } |
|
+ |
|
+ switch (rds->covers) { |
|
+ case dns_rdatatype_ds: |
|
+ auth_rrsig |= 0x1; |
|
+ break; |
|
+ case dns_rdatatype_nsec: |
|
+ auth_rrsig |= 0x2; |
|
+ break; |
|
+ case dns_rdatatype_nsec3: |
|
+ auth_rrsig |= 0x4; |
|
+ break; |
|
+ default: |
|
+ break; |
|
+ } |
|
+ } |
|
+ |
|
+ if (auth_dnssec != auth_rrsig) |
|
+ return (ISC_FALSE); |
|
+ } |
|
+ |
|
+ return (ISC_TRUE); |
|
+} |
|
+ |
|
static isc_result_t |
|
getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, |
|
dns_section_t sectionid, unsigned int options) |
|
@@ -1175,12 +1232,12 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, |
|
best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT); |
|
seen_problem = ISC_FALSE; |
|
|
|
+ section = &msg->sections[sectionid]; |
|
+ |
|
for (count = 0; count < msg->counts[sectionid]; count++) { |
|
int recstart = source->current; |
|
isc_boolean_t skip_name_search, skip_type_search; |
|
|
|
- section = &msg->sections[sectionid]; |
|
- |
|
skip_name_search = ISC_FALSE; |
|
skip_type_search = ISC_FALSE; |
|
free_rdataset = ISC_FALSE; |
|
@@ -1354,7 +1411,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, |
|
goto cleanup; |
|
rdata->rdclass = rdclass; |
|
issigzero = ISC_FALSE; |
|
- if (rdtype == dns_rdatatype_rrsig && |
|
+ if (rdtype == dns_rdatatype_rrsig && |
|
rdata->flags == 0) { |
|
covers = dns_rdata_covers(rdata); |
|
if (covers == 0) |
|
@@ -1565,6 +1622,19 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, |
|
INSIST(free_rdataset == ISC_FALSE); |
|
} |
|
|
|
+ /* |
|
+ * If any of DS, NSEC or NSEC3 appeared in the |
|
+ * authority section of a query response without |
|
+ * a covering RRSIG, FORMERR |
|
+ */ |
|
+ if (sectionid == DNS_SECTION_AUTHORITY && |
|
+ msg->opcode == dns_opcode_query && |
|
+ ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) && |
|
+ ((msg->flags & DNS_MESSAGEFLAG_TC) == 0) && |
|
+ !preserve_order && |
|
+ !auth_signed(section)) |
|
+ DO_FORMERR; |
|
+ |
|
if (seen_problem) |
|
return (DNS_R_RECOVERABLE); |
|
return (ISC_R_SUCCESS); |
|
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c |
|
index 2bc4461..e5600a3 100644 |
|
--- a/lib/dns/resolver.c |
|
+++ b/lib/dns/resolver.c |
|
@@ -5194,13 +5194,9 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, |
|
rdataset->type, |
|
&noqname); |
|
if (tresult == ISC_R_SUCCESS && |
|
- noqname != NULL) { |
|
- tresult = |
|
- dns_rdataset_addnoqname( |
|
+ noqname != NULL) |
|
+ (void) dns_rdataset_addnoqname( |
|
rdataset, noqname); |
|
- RUNTIME_CHECK(tresult == |
|
- ISC_R_SUCCESS); |
|
- } |
|
} |
|
addedrdataset = ardataset; |
|
result = dns_db_addrdataset(fctx->cache, node, |
|
@@ -5330,11 +5326,9 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, |
|
tresult = findnoqname(fctx, name, |
|
rdataset->type, &noqname); |
|
if (tresult == ISC_R_SUCCESS && |
|
- noqname != NULL) { |
|
- tresult = dns_rdataset_addnoqname( |
|
- rdataset, noqname); |
|
- RUNTIME_CHECK(tresult == ISC_R_SUCCESS); |
|
- } |
|
+ noqname != NULL) |
|
+ (void) dns_rdataset_addnoqname( |
|
+ rdataset, noqname); |
|
} |
|
|
|
/*
|
|
|