*************************************************/
/* Copyright (c) University of Cambridge 1995 - 2018 */
+/* Copyright (c) The Exim Maintainers 2020 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for interfacing with the DNS. */
int infd, outfd, rc;
uschar *argv[5];
- DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) using fakens\n", name, dns_text_type(type));
+ DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) using fakens\n",
+ name, dns_text_type(type));
argv[0] = utilname;
argv[1] = config_main_directory;
argv[3] = dns_text_type(type);
argv[4] = NULL;
- pid = child_open(argv, NULL, 0000, &infd, &outfd, FALSE);
+ pid = child_open(argv, NULL, 0000, &infd, &outfd, FALSE, US"fakens-search");
if (pid < 0)
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to run fakens: %s",
strerror(errno));
Arguments:
string the IP address as a string
- buffer a suitable buffer, long enough to hold the result
-Returns: nothing
+Returns: an allocated string
*/
-void
-dns_build_reverse(const uschar *string, uschar *buffer)
+uschar *
+dns_build_reverse(const uschar * string)
{
-const uschar *p = string + Ustrlen(string);
-uschar *pp = buffer;
+const uschar * p = string + Ustrlen(string);
+gstring * g = NULL;
/* Handle IPv4 address */
{
for (int i = 0; i < 4; i++)
{
- const uschar *ppp = p;
+ const uschar * ppp = p;
while (ppp > string && ppp[-1] != '.') ppp--;
- Ustrncpy(pp, ppp, p - ppp);
- pp += p - ppp;
- *pp++ = '.';
+ g = string_catn(g, ppp, p - ppp);
+ g = string_catn(g, US".", 1);
p = ppp - 1;
}
- Ustrcpy(pp, US"in-addr.arpa");
+ g = string_catn(g, US"in-addr.arpa", 12);
}
/* Handle IPv6 address; convert to binary so as to fill out any
else
{
int v6[4];
+
+ g = string_get_tainted(32, is_tainted(string));
(void)host_aton(string, v6);
/* The original specification for IPv6 reverse lookup was to invert each
for (int i = 3; i >= 0; i--)
for (int j = 0; j < 32; j += 4)
- pp += sprintf(CS pp, "%x.", (v6[i] >> j) & 15);
- Ustrcpy(pp, US"ip6.arpa.");
+ g = string_fmt_append(g, "%x.", (v6[i] >> j) & 15);
+ g = string_catn(g, US"ip6.arpa.", 9);
/* Another way of doing IPv6 reverse lookups was proposed in conjunction
with A6 records. However, it fell out of favour when they did. The
}
#endif
+return string_from_gstring(g);
}
const uschar * trusted;
if (dnsa->answerlen < 0) return FALSE;
+/* Beware that newer versions of glibc on Linux will filter out the ad bit
+unless their shiny new RES_TRUSTAD bit is set for the resolver. */
if (h->ad) return TRUE;
/* If the resolver we ask is authoritative for the domain in question, it may
the packet length if the packet header looks plausible. */
static void
-fake_dnsa_len_for_fail(dns_answer * dnsa)
+fake_dnsa_len_for_fail(dns_answer * dnsa, int type)
{
const HEADER * h = (const HEADER *)dnsa->answer;
&& ntohs(h->ancount) == 0 /* no answer records */
&& ntohs(h->nscount) >= 1) /* authority records */
{
- DEBUG(D_dns) debug_printf("faking res_search() response length as %d\n",
- (int)sizeof(dnsa->answer));
+ DEBUG(D_dns) debug_printf("faking res_search(%s) response length as %d\n",
+ dns_text_type(type), (int)sizeof(dnsa->answer));
dnsa->answerlen = sizeof(dnsa->answer);
}
}
*/
time_t
-dns_expire_from_soa(dns_answer * dnsa)
+dns_expire_from_soa(dns_answer * dnsa, int type)
{
dns_scan dnss;
-fake_dnsa_len_for_fail(dnsa);
+fake_dnsa_len_for_fail(dnsa, type);
for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_AUTHORITY);
rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)
case HOST_NOT_FOUND:
DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave HOST_NOT_FOUND\n"
"returning DNS_NOMATCH\n", name, dns_text_type(type));
- return dns_fail_return(name, type, dns_expire_from_soa(dnsa), DNS_NOMATCH);
+ return dns_fail_return(name, type, dns_expire_from_soa(dnsa, type), DNS_NOMATCH);
case TRY_AGAIN:
DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave TRY_AGAIN\n",
}
DEBUG(D_dns) debug_printf("%s is in dns_again_means_nonexist: returning "
"DNS_NOMATCH\n", name);
- return dns_fail_return(name, type, dns_expire_from_soa(dnsa), DNS_NOMATCH);
+ return dns_fail_return(name, type, dns_expire_from_soa(dnsa, type), DNS_NOMATCH);
#else /* For stand-alone tests */
return dns_fail_return(name, type, 0, DNS_AGAIN);
case NO_DATA:
DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave NO_DATA\n"
"returning DNS_NODATA\n", name, dns_text_type(type));
- return dns_fail_return(name, type, dns_expire_from_soa(dnsa), DNS_NODATA);
+ return dns_fail_return(name, type, dns_expire_from_soa(dnsa, type), DNS_NODATA);
default:
DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave unknown DNS error %d\n"
if (rc == DNS_NOMATCH)
{
- fake_dnsa_len_for_fail(dnsa);
+ fake_dnsa_len_for_fail(dnsa, T_CSA);
for (rr = dns_next_rr(dnsa, &dnss, RESET_AUTHORITY);
rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)