summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeiko Schlittermann (HS12) <hs@schlittermann.de>2015-06-22 09:57:02 +0200
committerHeiko Schlittermann (HS12) <hs@schlittermann.de>2015-06-22 11:35:48 +0200
commitf6584c83fdb3b168c430b5757209cc71cae10727 (patch)
treea04207efdd610d4fdf9ab5ecb495f9ffe5ecab7c
parent790fbb71d92b47c6637892f3feedc0f99000f01e (diff)
downloadexim4-f6584c83fdb3b168c430b5757209cc71cae10727.tar.gz
Testsuite: fakens may return AUTHORITY records
If an entry in db.<zone> is prefixed with "AA ", fakens will put a valid NS record into the AUTHORITY section of the returned packet. This will be used by dns_trust_aa checks.
-rw-r--r--test/dnszones-src/db.test.ex3
-rw-r--r--test/src/fakens.c135
2 files changed, 74 insertions, 64 deletions
diff --git a/test/dnszones-src/db.test.ex b/test/dnszones-src/db.test.ex
index 6056506c5..4cbf0f251 100644
--- a/test/dnszones-src/db.test.ex
+++ b/test/dnszones-src/db.test.ex
@@ -15,6 +15,9 @@
; NOTE (3): the top-level networks for testing addresses are parameterized by
; the use of V4NET and V6NET. These networks should be such that no real
; host ever uses them.
+;
+; Several prefixes may be used, see the source in src/fakens.c for a complete list
+; and description.
test.ex. NS exim.test.ex.
test.ex. SOA exim.test.ex. hostmaster.exim.test.ex 1430683638 1200 120 604800 3600
diff --git a/test/src/fakens.c b/test/src/fakens.c
index aff5f40f6..a03f94a07 100644
--- a/test/src/fakens.c
+++ b/test/src/fakens.c
@@ -55,7 +55,7 @@ a number of milliseconds (followed by one space).
Any DNS record line in a zone file can be prefixed with "DNSSEC ";
if all the records found by a lookup are marked
-as such then the response will have the "AD" bit set.
+as such then the response will have the "AD" bit set.
Any DNS record line in a zone file can be prefixed with "AA "
if all the records found by a lookup are marked
@@ -298,8 +298,8 @@ Arguments:
qtypelen the length of qtype
pkptr points to the output buffer pointer; this is updated
countptr points to the record count; this is updated
- dnssec points to the AD flag indicator; this updated
- aa points to the AA flag indicator; this updated
+ dnssec points to the AD flag indicator; this is updated
+ aa points to the AA flag indicator; this is updated
Returns: 0 on success, else HOST_NOT_FOUND or NO_DATA or NO_RECOVERY or
PASS_ON - the latter if a "PASS ON NOT FOUND" line is seen
@@ -318,8 +318,8 @@ uschar buffer[256];
uschar rrdomain[256];
uschar RRdomain[256];
-/* Decode the required type */
+/* Decode the required type */
for (typeptr = type_list; typeptr->name != NULL; typeptr++)
{ if (Ustrcmp(typeptr->name, qtype) == 0) break; }
if (typeptr->name == NULL)
@@ -331,8 +331,8 @@ if (typeptr->name == NULL)
rrdomain[0] = 0; /* No previous domain */
(void)fseek(f, 0, SEEK_SET); /* Start again at the beginning */
-*dnssec = TRUE; /* cancelled by first nonsecure rec found */
-*aa = TRUE; /* cancelled by first non-authoritive record */
+if (dnssec) *dnssec = TRUE; /* cancelled by first nonsecure rec found */
+if (aa) *aa = TRUE; /* cancelled by first non-aa rec found */
/* Scan for RRs */
@@ -365,17 +365,17 @@ while (fgets(CS buffer, sizeof(buffer), f) != NULL)
p = buffer;
for (;;)
{
- if (Ustrncmp(p, US"DNSSEC ", 7) == 0) /* tagged as secure */
+ if (Ustrncmp(p, US"DNSSEC ", 7) == 0) /* tagged as secure */
{
rr_sec = TRUE;
p += 7;
}
- else if (Ustrncmp(p, US"AA ", 3) == 0) /* tagged as authoritive */
+ else if (Ustrncmp(p, US"AA ", 3) == 0) /* tagged as authoritive */
{
rr_aa = TRUE;
p += 3;
}
- else if (Ustrncmp(p, US"DELAY=", 6) == 0) /* delay before response */
+ else if (Ustrncmp(p, US"DELAY=", 6) == 0) /* delay before response */
{
for (p += 6; *p >= '0' && *p <= '9'; p++) delay = delay*10 + *p - '0';
if (isspace(*p)) p++;
@@ -435,15 +435,14 @@ while (fgets(CS buffer, sizeof(buffer), f) != NULL)
else if (Ustrncmp(p, qtype, qtypelen) != 0 || !isspace(p[qtypelen])) continue;
/* Found a relevant record */
-
if (delay)
millisleep(delay);
- if (!rr_sec)
- *dnssec = FALSE; /* cancel AD return */
+ if (dnssec && !rr_sec)
+ *dnssec = FALSE; /* cancel AD return */
- if (!rr_aa)
- *aa = FALSE; /* cancel AA return */
+ if (aa && !rr_aa)
+ *aa = FALSE; /* cancel AA return */
yield = 0;
*countptr = *countptr + 1;
@@ -473,48 +472,48 @@ while (fgets(CS buffer, sizeof(buffer), f) != NULL)
p = strtok(p, " ");
ep = p + strlen(p);
if (ep[-1] != '.') sprintf(CS ep, "%s.", zone);
- pk = packname(p, pk); /* primary ns */
+ pk = packname(p, pk); /* primary ns */
p = strtok(NULL, " ");
- pk = packname(p , pk); /* responsible mailbox */
+ pk = packname(p , pk); /* responsible mailbox */
*(p += strlen(p)) = ' ';
while (isspace(*p)) p++;
- pk = longfield(&p, pk); /* serial */
- pk = longfield(&p, pk); /* refresh */
- pk = longfield(&p, pk); /* retry */
- pk = longfield(&p, pk); /* expire */
- pk = longfield(&p, pk); /* minimum */
+ pk = longfield(&p, pk); /* serial */
+ pk = longfield(&p, pk); /* refresh */
+ pk = longfield(&p, pk); /* retry */
+ pk = longfield(&p, pk); /* expire */
+ pk = longfield(&p, pk); /* minimum */
break;
case ns_t_a:
for (i = 0; i < 4; i++)
- {
- value = 0;
- while (isdigit(*p)) value = value*10 + *p++ - '0';
- *pk++ = value;
- p++;
- }
+ {
+ value = 0;
+ while (isdigit(*p)) value = value*10 + *p++ - '0';
+ *pk++ = value;
+ p++;
+ }
break;
/* The only occurrence of a double colon is for ::1 */
case ns_t_aaaa:
if (Ustrcmp(p, "::1") == 0)
- {
- memset(pk, 0, 15);
- pk += 15;
- *pk++ = 1;
- }
+ {
+ memset(pk, 0, 15);
+ pk += 15;
+ *pk++ = 1;
+ }
else for (i = 0; i < 8; i++)
- {
- value = 0;
- while (isxdigit(*p))
- {
- value = value * 16 + toupper(*p) - (isdigit(*p)? '0' : '7');
- p++;
- }
- *pk++ = (value >> 8) & 255;
- *pk++ = value & 255;
- p++;
- }
+ {
+ value = 0;
+ while (isxdigit(*p))
+ {
+ value = value * 16 + toupper(*p) - (isdigit(*p)? '0' : '7');
+ p++;
+ }
+ *pk++ = (value >> 8) & 255;
+ *pk++ = value & 255;
+ p++;
+ }
break;
case ns_t_mx:
@@ -531,17 +530,17 @@ while (fgets(CS buffer, sizeof(buffer), f) != NULL)
break;
case ns_t_tlsa:
- pk = bytefield(&p, pk); /* usage */
- pk = bytefield(&p, pk); /* selector */
- pk = bytefield(&p, pk); /* match type */
+ pk = bytefield(&p, pk); /* usage */
+ pk = bytefield(&p, pk); /* selector */
+ pk = bytefield(&p, pk); /* match type */
while (isxdigit(*p))
{
value = toupper(*p) - (isdigit(*p) ? '0' : '7') << 4;
if (isxdigit(*++p))
- {
- value |= toupper(*p) - (isdigit(*p) ? '0' : '7');
- p++;
- }
+ {
+ value |= toupper(*p) - (isdigit(*p) ? '0' : '7');
+ p++;
+ }
*pk++ = value & 255;
}
@@ -549,13 +548,13 @@ while (fgets(CS buffer, sizeof(buffer), f) != NULL)
case ns_t_srv:
for (i = 0; i < 3; i++)
- {
- value = 0;
- while (isdigit(*p)) value = value*10 + *p++ - '0';
- while (isspace(*p)) p++;
- *pk++ = (value >> 8) & 255;
- *pk++ = value & 255;
- }
+ {
+ value = 0;
+ while (isdigit(*p)) value = value*10 + *p++ - '0';
+ while (isspace(*p)) p++;
+ *pk++ = (value >> 8) & 255;
+ *pk++ = value & 255;
+ }
/* Fall through */
@@ -654,6 +653,7 @@ uschar domain[256];
uschar buffer[256];
uschar qtype[12];
uschar packet[2048 * 32 + 32];
+HEADER *header = (HEADER *)packet;
uschar *pk = packet;
BOOL dnssec;
BOOL aa;
@@ -771,21 +771,28 @@ if (f == NULL)
count = 0;
yield = find_records(f, zone, domain, qtype, qtypelen, &pk, &count, &dnssec, &aa);
if (yield == NO_RECOVERY) goto END_OFF;
+header->ancount = htons(count);
-packet[6] = (count >> 8) & 255;
-packet[7] = count & 255;
+/* If the AA bit should be set (as indicated by the AA prefix in the zone file),
+we are expected to return some records in the authortive section. Bind9: If
+there is data in the answer section, the authoritive section contains the NS
+records, otherwise it contains the SOA record. Currently we mimic this
+behaviour for the first case (there is some answer record).
+*/
+
+if (aa)
+ find_records(f, zone, zone[0] == '.' ? zone+1 : zone, US"NS", 2, &pk, &count, NULL, NULL);
+header->nscount = htons(count - ntohs(header->ancount));
/* There is no need to return any additional records because Exim no longer
(from release 4.61) makes any use of them. */
-
-packet[10] = 0;
-packet[11] = 0;
+header->arcount = 0;
if (dnssec)
- ((HEADER *)packet)->ad = 1;
+ header->ad = 1;
if (aa)
- ((HEADER *)packet)->aa = 1;
+ header->aa = 1;
/* Close the zone file, write the result, and return. */