summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dns-protocol.h6
-rw-r--r--src/dnssec.c9
-rw-r--r--src/rfc1035.c25
-rw-r--r--src/util.c2
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')
diff --git a/src/util.c b/src/util.c
index 0c1a48b..9299703 100644
--- a/src/util.c
+++ b/src/util.c
@@ -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;