From 2359ff1de2dcb90e50b79731d9cfddebfb8576bc Mon Sep 17 00:00:00 2001 From: Baptiste Assmann Date: Fri, 7 Aug 2015 11:24:05 +0200 Subject: [PATCH] BUG/MEDIUM: DNS resolution response parsing broken In some cases, parsing of the DNS response is broken and the response is considered as invalid, despite being valid. The current patch fixes this issue. It's a temporary solution until I rework the response parsing to store the response buffer into a real DNS packet structure. --- src/dns.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/dns.c b/src/dns.c index 53e743002..4bc54489f 100644 --- a/src/dns.c +++ b/src/dns.c @@ -462,40 +462,40 @@ int dns_validate_dns_response(unsigned char *resp, unsigned char *bufend, char * } /* ptr now points to the name */ - /* if cname is set, it means a CNAME recursion is in progress */ - if (cname) { - /* check if the name can stand in response */ - if ((reader + cnamelen) > bufend) - return DNS_RESP_INVALID; - /* compare cname and current name */ - if (memcmp(ptr, cname, cnamelen) != 0) - return DNS_RESP_CNAME_ERROR; - } - /* compare server hostname to current name */ - else if (dn_name) { - /* check if the name can stand in response */ - if ((reader + dn_name_len) > bufend) - return DNS_RESP_INVALID; - if (memcmp(ptr, dn_name, dn_name_len) != 0) - return DNS_RESP_WRONG_NAME; - } - - if ((*reader & 0xc0) == 0xc0) { - /* move forward 2 bytes for information pointer and address pointer */ - reader += 2; - } - else { + if ((*reader & 0xc0) != 0xc0) { + /* if cname is set, it means a CNAME recursion is in progress */ if (cname) { + /* check if the name can stand in response */ + if ((reader + cnamelen) > bufend) + return DNS_RESP_INVALID; + /* compare cname and current name */ + if (memcmp(ptr, cname, cnamelen) != 0) + return DNS_RESP_CNAME_ERROR; + cname = reader; cnamelen = dns_str_to_dn_label_len((const char *)cname); /* move forward cnamelen bytes + NULL byte */ reader += (cnamelen + 1); } + /* compare server hostname to current name */ + else if (dn_name) { + /* check if the name can stand in response */ + if ((reader + dn_name_len) > bufend) + return DNS_RESP_INVALID; + if (memcmp(ptr, dn_name, dn_name_len) != 0) + return DNS_RESP_WRONG_NAME; + } else { reader += (len + 1); } } + else { + /* shortname in progress */ + /* move forward 2 bytes for information pointer and address pointer */ + reader += 2; + } + if (reader >= bufend) return DNS_RESP_INVALID;