mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-10-27 18:55:09 +03:00
resolved: when we find a DNAME RR, don't insist in a signed CNAME RR
If we have a signed DNAME RR response, there's no need to insist on a signature for a CNAME RR response, after all it is unlikely to be signed, given the implicit synthethis of CNAME through DNAME RRs.
This commit is contained in:
parent
cde3d68750
commit
43e6779ac2
@ -821,3 +821,40 @@ void dns_answer_dump(DnsAnswer *answer, FILE *f) {
|
||||
fputc('\n', f);
|
||||
}
|
||||
}
|
||||
|
||||
bool dns_answer_has_dname_for_cname(DnsAnswer *a, DnsResourceRecord *cname) {
|
||||
DnsResourceRecord *rr;
|
||||
int r;
|
||||
|
||||
assert(cname);
|
||||
|
||||
/* Checks whether the answer contains a DNAME record that indicates that the specified CNAME record is
|
||||
* synthesized from it */
|
||||
|
||||
if (cname->key->type != DNS_TYPE_CNAME)
|
||||
return 0;
|
||||
|
||||
DNS_ANSWER_FOREACH(rr, a) {
|
||||
_cleanup_free_ char *n = NULL;
|
||||
|
||||
if (rr->key->type != DNS_TYPE_DNAME)
|
||||
continue;
|
||||
if (rr->key->class != cname->key->class)
|
||||
continue;
|
||||
|
||||
r = dns_name_change_suffix(cname->cname.name, rr->dname.name, DNS_RESOURCE_KEY_NAME(rr->key), &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
continue;
|
||||
|
||||
r = dns_name_equal(n, DNS_RESOURCE_KEY_NAME(cname->key));
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0)
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -83,6 +83,8 @@ int dns_answer_remove_by_rr(DnsAnswer **a, DnsResourceRecord *rr);
|
||||
int dns_answer_copy_by_key(DnsAnswer **a, DnsAnswer *source, const DnsResourceKey *key, DnsAnswerFlags or_flags);
|
||||
int dns_answer_move_by_key(DnsAnswer **to, DnsAnswer **from, const DnsResourceKey *key, DnsAnswerFlags or_flags);
|
||||
|
||||
bool dns_answer_has_dname_for_cname(DnsAnswer *a, DnsResourceRecord *cname);
|
||||
|
||||
static inline unsigned dns_answer_size(DnsAnswer *a) {
|
||||
return a ? a->n_rrs : 0;
|
||||
}
|
||||
|
@ -1827,6 +1827,12 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) {
|
||||
if (r > 0)
|
||||
continue;
|
||||
|
||||
r = dns_answer_has_dname_for_cname(t->answer, rr);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0)
|
||||
continue;
|
||||
|
||||
name = DNS_RESOURCE_KEY_NAME(rr->key);
|
||||
r = dns_name_parent(&name);
|
||||
if (r < 0)
|
||||
@ -2719,17 +2725,30 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0) {
|
||||
/* This is a primary response
|
||||
* to our question, and it
|
||||
* failed validation. That's
|
||||
* fatal. */
|
||||
t->answer_dnssec_result = result;
|
||||
return 0;
|
||||
|
||||
/* Look for a matching DNAME for this CNAME */
|
||||
r = dns_answer_has_dname_for_cname(t->answer, rr);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
/* Also look among the stuff we already validated */
|
||||
r = dns_answer_has_dname_for_cname(validated, rr);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (r == 0) {
|
||||
/* This is a primary response to our question, and it failed validation. That's
|
||||
* fatal. */
|
||||
t->answer_dnssec_result = result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This is a primary response, but we do have a DNAME RR in the RR that can replay this
|
||||
* CNAME, hence rely on that, and we can remove the CNAME in favour of it. */
|
||||
}
|
||||
|
||||
/* This is just some auxiliary
|
||||
* data. Just remove the RRset and
|
||||
* continue. */
|
||||
/* This is just some auxiliary data. Just remove the RRset and continue. */
|
||||
r = dns_answer_remove_by_key(&t->answer, rr->key);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
Loading…
Reference in New Issue
Block a user