diff --git a/src/dnssec.c b/src/dnssec.c index 8c77098..a503fcd 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -383,7 +383,7 @@ static int explore_rrset(struct dns_header *header, size_t plen, int class, int an attacker using signatures made with the key of an unrelated zone he controls. Note that the root key is always allowed. Ignore sigs which aren't valid */ - if (*daemon->workspacename == 0 || hostname_issubdomain(name, daemon->workspacename) != 0) + if (*daemon->workspacename == 0 || hostname_issubdomain(daemon->workspacename, name) != 0) { if (gotkey) { @@ -2095,8 +2095,8 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch CNAME must be . CNAME target must be . s must match for name and target. */ - if (hostname_issubdomain(daemon->cname, name) == 1 && - hostname_issubdomain(daemon->workspacename, keyname) == 1 && + if (hostname_issubdomain(name, daemon->cname) == 1 && + hostname_issubdomain(keyname, daemon->workspacename) == 1 && name_prefix_len == strlen(daemon->workspacename) - strlen(keyname)) { char save = daemon->cname[name_prefix_len]; diff --git a/src/util.c b/src/util.c index b41b7c1..1d98951 100644 --- a/src/util.c +++ b/src/util.c @@ -439,10 +439,14 @@ int hostname_issubdomain(char *a, char *b) for (ap = a; *ap; ap++); for (bp = b; *bp; bp++); - /* a shorter than b */ - if ((ap - a) < (bp - b)) + /* anything is a subdomain of the root domain. */ + if (ap == a) + return (bp == b) ? 2 : 1; + + /* b shorter than a */ + if ((bp - b) < (ap - a)) return 0; - + do { c1 = (unsigned char) *(--ap); @@ -455,18 +459,17 @@ int hostname_issubdomain(char *a, char *b) if (c1 != c2) return 0; - } while (bp != b); + } while (ap != a); - if (ap == a) + if (bp == b) return 2; - if (*(--ap) == '.') + if (*(--bp) == '.') return 1; return 0; } - time_t dnsmasq_time(void) { #ifdef HAVE_BROKEN_RTC