X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Fdns.c;h=6333d3cff7018e0512ea9cf27d81b6d5ee1677ed;hb=b3317cfaabe29c73478125e14f58236b2229da4b;hp=28bc5958d62ea162a7871941007a9b1074553fb3;hpb=b574c5baeb94e3a176c63982f507a5b48bf3917b;p=exim.git diff --git a/src/src/dns.c b/src/src/dns.c index 28bc5958d..6333d3cff 100644 --- a/src/src/dns.c +++ b/src/src/dns.c @@ -221,16 +221,15 @@ a name that can be used to look up PTR records. 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 */ @@ -240,14 +239,13 @@ if (Ustrchr(string, ':') == NULL) { 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 @@ -257,6 +255,8 @@ abbreviation in the textual form. */ 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 @@ -265,8 +265,8 @@ else 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 @@ -290,6 +290,7 @@ else } #endif +return string_from_gstring(g); } @@ -693,7 +694,7 @@ success and packet length return values.) For added safety we only reset 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; @@ -706,8 +707,8 @@ if ( h->qr == 1 /* a response */ && 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); } } @@ -719,11 +720,11 @@ bother doing a separate lookup; if not found return a forever TTL. */ 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) @@ -893,7 +894,7 @@ if (dnsa->answerlen < 0) switch (h_errno) 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", @@ -913,7 +914,7 @@ if (dnsa->answerlen < 0) switch (h_errno) } 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); @@ -927,7 +928,7 @@ if (dnsa->answerlen < 0) switch (h_errno) 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" @@ -1200,7 +1201,7 @@ switch (type) 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)