summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolfgang Breyha <wbreyha@gmx.net>2014-01-14 06:12:38 -0800
committerTodd Lyons <tlyons@exim.org>2014-01-14 06:12:38 -0800
commit5a1b84430ab93b6d17b9936bd813d243885a4475 (patch)
tree754f80a3408384becec866a20c74819a81e48981
parenta11efec0735a77c5bf57b722207f1588973bbe3e (diff)
downloadexim4-5a1b84430ab93b6d17b9936bd813d243885a4475.tar.gz
Bugzilla 1433: Fix DMARC SEGV
Properly escape value passed to expand_string(). Check for NULL return from expand_string().
-rw-r--r--doc/doc-txt/ChangeLog3
-rw-r--r--src/src/dmarc.c29
2 files changed, 18 insertions, 14 deletions
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index e2b33cf91..d5c09f4c5 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -29,6 +29,9 @@ TL/02 Experimental Proxy Protocol support: allows a proxied SMTP connection
JH/02 Add ${listextract {number}{list}{success}{fail}}.
+TL/03 Bugzilla 1433: Fix DMARC SEGV with specific From header contents.
+ Properly escape header and check for NULL return.
+
Exim version 4.82
-----------------
diff --git a/src/src/dmarc.c b/src/src/dmarc.c
index 6e516525f..22a051582 100644
--- a/src/src/dmarc.c
+++ b/src/src/dmarc.c
@@ -175,19 +175,20 @@ int dmarc_process() {
* <jgh_hm> there may well be no better though
*/
header_from_sender = expand_string(
- string_sprintf("${domain:${extract{1}{:}{${addresses:%s}}}}",
- from_header->text) );
+ string_sprintf("${domain:${extract{1}{:}{${addresses:\\N%s\\N}}}}",
+ from_header->text) );
/* The opendmarc library extracts the domain from the email address, but
* only try to store it if it's not empty. Otherwise, skip out of DMARC. */
- if (strcmp( CCS header_from_sender, "") == 0)
+ if ((header_from_sender == NULL) || (strcmp( CCS header_from_sender, "") == 0))
dmarc_abort = TRUE;
libdm_status = (dmarc_abort == TRUE) ?
- DMARC_PARSE_OKAY :
- opendmarc_policy_store_from_domain(dmarc_pctx, header_from_sender);
+ DMARC_PARSE_OKAY :
+ opendmarc_policy_store_from_domain(dmarc_pctx, header_from_sender);
if (libdm_status != DMARC_PARSE_OKAY)
{
- log_write(0, LOG_MAIN|LOG_PANIC, "failure to store header From: in DMARC: %s, header was '%s'",
- opendmarc_policy_status_to_str(libdm_status), from_header->text);
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "failure to store header From: in DMARC: %s, header was '%s'",
+ opendmarc_policy_status_to_str(libdm_status), from_header->text);
dmarc_abort = TRUE;
}
}
@@ -261,24 +262,24 @@ int dmarc_process() {
( vs == PDKIM_VERIFY_INVALID ) ? DMARC_POLICY_DKIM_OUTCOME_TMPFAIL :
DMARC_POLICY_DKIM_OUTCOME_NONE;
libdm_status = opendmarc_policy_store_dkim(dmarc_pctx, (uschar *)sig->domain,
- dkim_result, US"");
+ dkim_result, US"");
DEBUG(D_receive)
debug_printf("DMARC adding DKIM sender domain = %s\n", sig->domain);
if (libdm_status != DMARC_PARSE_OKAY)
log_write(0, LOG_MAIN|LOG_PANIC, "failure to store dkim (%s) for DMARC: %s",
- sig->domain, opendmarc_policy_status_to_str(libdm_status));
+ sig->domain, opendmarc_policy_status_to_str(libdm_status));
dkim_ares_result = ( vs == PDKIM_VERIFY_PASS ) ? ARES_RESULT_PASS :
- ( vs == PDKIM_VERIFY_FAIL ) ? ARES_RESULT_FAIL :
- ( vs == PDKIM_VERIFY_NONE ) ? ARES_RESULT_NONE :
- ( vs == PDKIM_VERIFY_INVALID ) ?
+ ( vs == PDKIM_VERIFY_FAIL ) ? ARES_RESULT_FAIL :
+ ( vs == PDKIM_VERIFY_NONE ) ? ARES_RESULT_NONE :
+ ( vs == PDKIM_VERIFY_INVALID ) ?
( ves == PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE ? ARES_RESULT_PERMERROR :
ves == PDKIM_VERIFY_INVALID_BUFFER_SIZE ? ARES_RESULT_PERMERROR :
ves == PDKIM_VERIFY_INVALID_PUBKEY_PARSING ? ARES_RESULT_PERMERROR :
ARES_RESULT_UNKNOWN ) :
ARES_RESULT_UNKNOWN;
dkim_history_buffer = string_sprintf("%sdkim %s %d\n", dkim_history_buffer,
- sig->domain, dkim_ares_result);
+ sig->domain, dkim_ares_result);
sig = sig->next;
}
libdm_status = opendmarc_policy_query_dmarc(dmarc_pctx, US"");
@@ -311,7 +312,7 @@ int dmarc_process() {
* for libopendmarc using its max hostname length definition. */
uschar *dmarc_domain = (uschar *)calloc(DMARC_MAXHOSTNAMELEN, sizeof(uschar));
libdm_status = opendmarc_policy_fetch_utilized_domain(dmarc_pctx, dmarc_domain,
- DMARC_MAXHOSTNAMELEN-1);
+ DMARC_MAXHOSTNAMELEN-1);
dmarc_used_domain = string_copy(dmarc_domain);
free(dmarc_domain);
if (libdm_status != DMARC_PARSE_OKAY)