diff options
-rw-r--r-- | src/dns-protocol.h | 6 | ||||
-rw-r--r-- | src/dnssec.c | 9 | ||||
-rw-r--r-- | src/rfc1035.c | 25 | ||||
-rw-r--r-- | src/util.c | 2 |
4 files changed, 30 insertions, 12 deletions
diff --git a/src/dns-protocol.h b/src/dns-protocol.h index 7f5d686..4b71746 100644 --- a/src/dns-protocol.h +++ b/src/dns-protocol.h @@ -144,5 +144,9 @@ struct dns_header { (!CHECK_LEN(header, pp, plen, len) ? 0 : (((pp) += (len)), 1)) /* Escape character in our presentation format for names. - Cannot be '.' or /000 and must be !isprint() */ + Cannot be '.' or /000 and must be !isprint(). + Note that escaped chars are stored as + <NAME_ESCAPE> <orig-char+1> + to ensure that the escaped form of /000 doesn't include /000 +*/ #define NAME_ESCAPE 1 diff --git a/src/dnssec.c b/src/dnssec.c index c116a7b..a9e1215 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -341,9 +341,11 @@ static int to_wire(char *name) if (*p >= 'A' && *p <= 'Z') *p = *p - 'A' + 'a'; else if (*p == NAME_ESCAPE) - for (q = p; *q; q++) + { + for (q = p; *q; q++) *q = *(q+1); - + (*p)--; + } term = *p; if ((len = p - l) != 0) @@ -376,7 +378,8 @@ static void from_wire(char *name) { memmove(p+1, p, 1 + last - p); len++; - *p++ = NAME_ESCAPE; + *p++ = NAME_ESCAPE; + (*p)++; } l[len] = '.'; diff --git a/src/rfc1035.c b/src/rfc1035.c index 19fecc8..32df31a 100644 --- a/src/rfc1035.c +++ b/src/rfc1035.c @@ -20,7 +20,7 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, char *name, int isExtract, int extrabytes) { unsigned char *cp = (unsigned char *)name, *p = *pp, *p1 = NULL; - unsigned int j, l, hops = 0; + unsigned int j, l, namelen = 0, hops = 0; int retvalue = 1; if (isExtract) @@ -94,9 +94,15 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, count = 256; digs = ((count-1)>>2)+1; - /* output is \[x<hex>/siz]. which is digs+9 chars */ - if (cp - (unsigned char *)name + digs + 9 >= MAXDNAME) + /* output is \[x<hex>/siz]. which is digs+6/7/8 chars */ + namelen += digs+6; + if (count > 9) + namelen++; + if (count > 99) + namelen++; + if (namelen+1 >= MAXDNAME) return 0; + if (!CHECK_LEN(header, p, plen, (count-1)>>3)) return 0; @@ -119,7 +125,8 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, } else { /* label_type = 0 -> label. */ - if (cp - (unsigned char *)name + l + 1 >= MAXDNAME) + namelen += l; + if (namelen+1 >= MAXDNAME) return 0; if (!CHECK_LEN(header, p, plen, l)) return 0; @@ -132,8 +139,12 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, if (option_bool(OPT_DNSSEC_VALID)) { if (c == 0 || c == '.' || c == NAME_ESCAPE) - *cp++ = NAME_ESCAPE; - *cp++ = c; + { + *cp++ = NAME_ESCAPE; + *cp++ = c+1; + } + else + *cp++ = c; } else #endif @@ -155,7 +166,7 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, c1 += 'a' - 'A'; #ifdef HAVE_DNSSEC if (option_bool(OPT_DNSSEC_VALID) && c1 == NAME_ESCAPE) - c1 = *cp++; + c1 = (*cp++)-1; #endif if (c2 >= 'A' && c2 <= 'Z') @@ -229,7 +229,7 @@ unsigned char *do_rfc1035_name(unsigned char *p, char *sval) { #ifdef HAVE_DNSSEC if (option_bool(OPT_DNSSEC_VALID) && *sval == NAME_ESCAPE) - *p++ = *(++sval); + *p++ = (*(++sval))-1; else #endif *p++ = *sval; |