X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/79e5ebf9e9bb833ce004be65c04b2f8eea91c337..654056e44fc93a0ee7c09d1228933e8af6862206:/src/src/spf.c diff --git a/src/src/spf.c b/src/src/spf.c index fd9831c43..1981d81b6 100644 --- a/src/src/spf.c +++ b/src/src/spf.c @@ -3,9 +3,9 @@ *************************************************/ /* SPF support. + Copyright (c) The Exim Maintainers 2015 - 2022 Copyright (c) Tom Kistner 2004 - 2014 License: GPL - Copyright (c) The Exim Maintainers 2015 - 2020 */ /* Code for calling spf checks via libspf-alt. Called from acl.c. */ @@ -34,15 +34,17 @@ SPF_response_t *spf_response_2mx = NULL; SPF_dns_rr_t * spf_nxdomain = NULL; -void -spf_lib_version_report(FILE * fp) +gstring * +spf_lib_version_report(gstring * g) { int maj, min, patch; + SPF_get_lib_version(&maj, &min, &patch); -fprintf(fp, "Library version: spf2: Compile: %d.%d.%d\n", +g = string_fmt_append(g, "Library version: spf2: Compile: %d.%d.%d\n", SPF_LIB_VERSION_MAJOR, SPF_LIB_VERSION_MINOR, SPF_LIB_VERSION_PATCH); -fprintf(fp, " Runtime: %d.%d.%d\n", +g = string_fmt_append(g, " Runtime: %d.%d.%d\n", maj, min, patch); +return g; } @@ -72,15 +74,15 @@ int dns_rc; DEBUG(D_receive) debug_printf("SPF_dns_exim_lookup '%s'\n", domain); -/* Shortcircuit SPF RR lookups by returning HOST_NOT_FOUND (shortest code path -in libspf2). They were obsoleted by RFC 6686/7208 years ago. see bug #1294 -*/ +/* Shortcircuit SPF RR lookups by returning NO_DATA. They were obsoleted by +RFC 6686/7208 years ago. see bug #1294 */ if (rr_type == T_SPF) { - HDEBUG(D_host_lookup) debug_printf("faking HOST_NOT_FOUND for SPF RR(99) lookup\n"); - srr.herrno = HOST_NOT_FOUND; + HDEBUG(D_host_lookup) debug_printf("faking NO_DATA for SPF RR(99) lookup\n"); + srr.herrno = NO_DATA; SPF_dns_rr_dup(&spfrr, &srr); + store_free_dns_answer(dnsa); return spfrr; } @@ -92,7 +94,7 @@ switch (dns_rc = dns_lookup(dnsa, US domain, rr_type, NULL)) case DNS_NODATA: srr.herrno = NO_DATA; break; case DNS_FAIL: default: srr.herrno = NO_RECOVERY; break; - } + } for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)) @@ -101,6 +103,7 @@ for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr; if (found == 0) { SPF_dns_rr_dup(&spfrr, &srr); + store_free_dns_answer(dnsa); return spfrr; } @@ -117,6 +120,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: { @@ -132,6 +136,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", @@ -139,9 +144,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) @@ -172,6 +180,7 @@ if (!(srr.num_rr = found)) /* spfrr->rr must have been malloc()d for this */ SPF_dns_rr_dup(&spfrr, &srr); +store_free_dns_answer(dnsa); return spfrr; } @@ -219,6 +228,7 @@ spf_init(void) { SPF_dns_server_t * dc; int debug = 0; +const uschar *s; DEBUG(D_receive) debug = 1; @@ -241,11 +251,16 @@ if (!(spf_server = SPF_server_new_dns(dc, debug))) DEBUG(D_receive) debug_printf("spf: SPF_server_new() failed.\n"); return FALSE; } - /* Quick hack to override the outdated explanation URL. - See https://www.mail-archive.com/mailop@mailop.org/msg08019.html */ - SPF_server_set_explanation(spf_server, "Please%_see%_http://www.open-spf.org/Why?id=%{S}&ip=%{C}&receiver=%{R}", &spf_response); - if (SPF_response_errcode(spf_response) != SPF_E_SUCCESS) - log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s", SPF_strerror(SPF_response_errcode(spf_response))); + /* Override the outdated explanation URL. + See https://www.mail-archive.com/mailop@mailop.org/msg08019.html + Used to work as "Please%_see%_http://www.open-spf.org/Why?id=%{S}&ip=%{C}&receiver=%{R}", + but is broken now (May 18th, 2020) */ +if (!(s = expand_string(spf_smtp_comment_template))) + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "expansion of spf_smtp_comment_template failed"); + +SPF_server_set_explanation(spf_server, CCS s, &spf_response); +if (SPF_response_errcode(spf_response) != SPF_E_SUCCESS) + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s", SPF_strerror(SPF_response_errcode(spf_response))); return TRUE; } @@ -397,8 +412,12 @@ if (spf_result_guessed) g = string_cat(g, US" (best guess record for domain)"); s = expand_string(US"$sender_address_domain"); +if (s && *s) + return string_append(g, 2, US" smtp.mailfrom=", s); + +s = sender_helo_name; return s && *s - ? string_append(g, 2, US" smtp.mailfrom=", s) + ? string_append(g, 2, US" smtp.helo=", s) : string_cat(g, US" smtp.mailfrom=<>"); }