X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/1ddb1855402d48ad735e46abaf0d662e45600ecd..fa1c8faf169384bebaa8d172f491574c45ae2aa4:/src/src/spf.c diff --git a/src/src/spf.c b/src/src/spf.c index e3df789fb..2e3f861eb 100644 --- a/src/src/spf.c +++ b/src/src/spf.c @@ -3,9 +3,10 @@ *************************************************/ /* SPF support. + Copyright (c) The Exim Maintainers 2015 - 2023 Copyright (c) Tom Kistner 2004 - 2014 License: GPL - Copyright (c) The Exim Maintainers 2015 - 2021 + SPDX-License-Identifier: GPL-2.0-or-later */ /* Code for calling spf checks via libspf-alt. Called from acl.c. */ @@ -70,7 +71,6 @@ SPF_dns_rr_t srr = { .hook = NULL, /* misc information */ .source = spf_dns_server }; -int dns_rc; DEBUG(D_receive) debug_printf("SPF_dns_exim_lookup '%s'\n", domain); @@ -86,20 +86,22 @@ if (rr_type == T_SPF) return spfrr; } -switch (dns_rc = dns_lookup(dnsa, US domain, rr_type, NULL)) +switch (dns_lookup(dnsa, US domain, rr_type, NULL)) { - case DNS_SUCCEED: srr.herrno = NETDB_SUCCESS; break; case DNS_AGAIN: srr.herrno = TRY_AGAIN; break; case DNS_NOMATCH: srr.herrno = HOST_NOT_FOUND; break; case DNS_NODATA: srr.herrno = NO_DATA; break; case DNS_FAIL: default: srr.herrno = NO_RECOVERY; break; + case DNS_SUCCEED: + srr.herrno = NETDB_SUCCESS; + for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr; + rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)) + /* Need to alloc space for all records, so no early-out */ + if (rr->type == rr_type) found++; + break; } -for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr; - rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)) - if (rr->type == rr_type) found++; - if (found == 0) { SPF_dns_rr_dup(&spfrr, &srr); @@ -120,6 +122,7 @@ for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr; switch(rr_type) { case T_MX: + if (rr->size < 2) continue; s += 2; /* skip the MX precedence field */ case T_PTR: { @@ -135,6 +138,7 @@ for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr; gstring * g = NULL; uschar chunk_len; + if (rr->size < 1+6) continue; /* min for version str */ if (strncmpic(rr->data+1, US SPF_VER_STR, 6) != 0) { HDEBUG(D_host_lookup) debug_printf("not an spf record: %.*s\n", @@ -142,9 +146,12 @@ for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr; continue; } - for (int off = 0; off < rr->size; off += chunk_len) + /* require 1 byte for the chunk_len */ + for (int off = 0; off < rr->size - 1; off += chunk_len) { - if (!(chunk_len = s[off++])) break; + if ( !(chunk_len = s[off++]) + || rr->size < off + chunk_len /* ignore bogus size chunks */ + ) break; g = string_catn(g, s+off, chunk_len); } if (!g) @@ -204,7 +211,7 @@ spf_nxdomain = SPF_dns_rr_new_init(spf_dns_server, "", ns_t_any, 24 * 60 * 60, HOST_NOT_FOUND); if (!spf_nxdomain) { - free(spf_dns_server); + store_free(spf_dns_server); return NULL; } @@ -334,7 +341,8 @@ else for (int i = 0; i < SPF_response_messages(spf_response); i++) Return: OK/FAIL */ int -spf_process(const uschar **listptr, uschar *spf_envelope_sender, int action) +spf_process(const uschar ** listptr, const uschar * spf_envelope_sender, + int action) { int sep = 0; const uschar *list = *listptr; @@ -400,20 +408,31 @@ gstring * authres_spf(gstring * g) { uschar * s; -if (!spf_result) return g; - -g = string_append(g, 2, US";\n\tspf=", spf_result); -if (spf_result_guessed) - g = string_cat(g, US" (best guess record for domain)"); +if (spf_result) + { + int start = 0; /* Compiler quietening */ + DEBUG(D_acl) start = gstring_length(g); -s = expand_string(US"$sender_address_domain"); -if (s && *s) - return string_append(g, 2, US" smtp.mailfrom=", s); + g = string_append(g, 2, US";\n\tspf=", spf_result); + if (spf_result_guessed) + g = string_cat(g, US" (best guess record for domain)"); -s = sender_helo_name; -return s && *s - ? string_append(g, 2, US" smtp.helo=", s) - : string_cat(g, US" smtp.mailfrom=<>"); + s = expand_string(US"$sender_address_domain"); + if (s && *s) + g = string_append(g, 2, US" smtp.mailfrom=", s); + else + { + s = sender_helo_name; + g = s && *s + ? string_append(g, 2, US" smtp.helo=", s) + : string_cat(g, US" smtp.mailfrom=<>"); + } + DEBUG(D_acl) debug_printf("SPF:\tauthres '%.*s'\n", + gstring_length(g) - start - 3, g->s + start + 3); + } +else + DEBUG(D_acl) debug_printf("SPF:\tno authres\n"); +return g; }