*************************************************/
/* SPF support.
+ Copyright (c) The Exim Maintainers 2015 - 2022
Copyright (c) Tom Kistner <tom@duncanthrax.net> 2004 - 2014
License: GPL
- Copyright (c) The Exim Maintainers 2015 - 2020
*/
/* Code for calling spf checks via libspf-alt. Called from acl.c. */
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;
}
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;
}
if (found == 0)
{
SPF_dns_rr_dup(&spfrr, &srr);
+ store_free_dns_answer(dnsa);
return spfrr;
}
switch(rr_type)
{
case T_MX:
+ if (rr->size < 2) continue;
s += 2; /* skip the MX precedence field */
case T_PTR:
{
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",
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)
/* spfrr->rr must have been malloc()d for this */
SPF_dns_rr_dup(&spfrr, &srr);
+store_free_dns_answer(dnsa);
return spfrr;
}