summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/src/dkim.c6
-rw-r--r--src/src/dmarc.c56
-rw-r--r--src/src/globals.c1
-rw-r--r--src/src/globals.h1
-rw-r--r--src/src/smtp_in.c8
5 files changed, 40 insertions, 32 deletions
diff --git a/src/src/dkim.c b/src/src/dkim.c
index 59445a85a..d223f9e62 100644
--- a/src/src/dkim.c
+++ b/src/src/dkim.c
@@ -30,7 +30,6 @@ pdkim_ctx dkim_sign_ctx;
int dkim_verify_oldpool;
pdkim_ctx *dkim_verify_ctx = NULL;
-pdkim_signature *dkim_signatures = NULL;
pdkim_signature *dkim_cur_sig = NULL;
static const uschar * dkim_collect_error = NULL;
@@ -313,7 +312,8 @@ dkim_collect_input = FALSE;
/* Finish DKIM operation and fetch link to signatures chain */
-rc = pdkim_feed_finish(dkim_verify_ctx, &dkim_signatures, &errstr);
+rc = pdkim_feed_finish(dkim_verify_ctx, (pdkim_signature **)&dkim_signatures,
+ &errstr);
if (rc != PDKIM_OK && errstr)
log_write(0, LOG_MAIN, "DKIM: validation error: %s", errstr);
@@ -395,7 +395,7 @@ for (sig = dkim_signatures; sig; sig = sig->next)
them here. This is easy since a domain and selector is guaranteed
to be in a signature. The other dkim_* expansion items are
dynamically fetched from dkim_cur_sig at expansion time (see
- function below). */
+ dkim_exim_expand_query() below). */
dkim_cur_sig = sig;
dkim_signing_domain = US sig->domain;
diff --git a/src/src/dmarc.c b/src/src/dmarc.c
index 2ac0ac550..956c16b4e 100644
--- a/src/src/dmarc.c
+++ b/src/src/dmarc.c
@@ -28,7 +28,6 @@ OPENDMARC_STATUS_T libdm_status, action, dmarc_policy;
OPENDMARC_STATUS_T da, sa, action;
BOOL dmarc_abort = FALSE;
uschar *dmarc_pass_fail = US"skipped";
-extern pdkim_signature *dkim_signatures;
header_line *from_header = NULL;
extern SPF_response_t *spf_response;
int dmarc_spf_ares_result = 0;
@@ -222,7 +221,7 @@ dmarc_process()
int sr, origin; /* used in SPF section */
int dmarc_spf_result = 0; /* stores spf into dmarc conn ctx */
int tmp_ans, c;
-pdkim_signature *sig = NULL;
+pdkim_signature * sig = dkim_signatures;
BOOL has_dmarc_record = TRUE;
u_char **ruf; /* forensic report addressees, if called for */
@@ -243,27 +242,27 @@ if (!from_header)
}
else if (!dmarc_abort)
{
- uschar * errormsg;
- int dummy, domain;
- uschar * p;
- uschar saveend;
-
- parse_allow_group = TRUE;
- p = parse_find_address_end(from_header->text, FALSE);
- saveend = *p; *p = '\0';
- if ((header_from_sender = parse_extract_address(from_header->text, &errormsg,
- &dummy, &dummy, &domain, FALSE)))
- header_from_sender += domain;
- *p = saveend;
-
- /* 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 (!header_from_sender || (strcmp( CCS header_from_sender, "") == 0))
- dmarc_abort = TRUE;
- libdm_status = dmarc_abort ?
- DMARC_PARSE_OKAY :
- opendmarc_policy_store_from_domain(dmarc_pctx, header_from_sender);
- if (libdm_status != DMARC_PARSE_OKAY)
+ uschar * errormsg;
+ int dummy, domain;
+ uschar * p;
+ uschar saveend;
+
+ parse_allow_group = TRUE;
+ p = parse_find_address_end(from_header->text, FALSE);
+ saveend = *p; *p = '\0';
+ if ((header_from_sender = parse_extract_address(from_header->text, &errormsg,
+ &dummy, &dummy, &domain, FALSE)))
+ header_from_sender += domain;
+ *p = saveend;
+
+ /* 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 (!header_from_sender || (strcmp( CCS header_from_sender, "") == 0))
+ dmarc_abort = TRUE;
+ libdm_status = dmarc_abort
+ ? 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'",
@@ -276,6 +275,8 @@ else if (!dmarc_abort)
* instead do this in the ACLs. */
if (!dmarc_abort && !sender_host_authenticated)
{
+ uschar * dmarc_domain;
+
/* Use the envelope sender domain for this part of DMARC */
spf_sender_domain = expand_string(US"$sender_address_domain");
if (!spf_response)
@@ -330,11 +331,11 @@ if (!dmarc_abort && !sender_host_authenticated)
/* Now we cycle through the dkim signature results and put into
* the opendmarc context, further building the DMARC reply. */
- sig = dkim_signatures;
dkim_history_buffer = US"";
while (sig)
{
int dkim_result, dkim_ares_result, vs, ves;
+
vs = sig->verify_status & ~PDKIM_VERIFY_POLICY;
ves = sig->verify_ext_status;
dkim_result = vs == PDKIM_VERIFY_PASS ? DMARC_POLICY_DKIM_OUTCOME_PASS :
@@ -403,9 +404,9 @@ if (!dmarc_abort && !sender_host_authenticated)
}
/* Can't use exim's string manipulation functions so allocate memory
- * for libopendmarc using its max hostname length definition. */
+ for libopendmarc using its max hostname length definition. */
- uschar *dmarc_domain = US calloc(DMARC_MAXHOSTNAMELEN, sizeof(uschar));
+ dmarc_domain = US calloc(DMARC_MAXHOSTNAMELEN, sizeof(uschar));
libdm_status = opendmarc_policy_fetch_utilized_domain(dmarc_pctx,
dmarc_domain, DMARC_MAXHOSTNAMELEN-1);
dmarc_used_domain = string_copy(dmarc_domain);
@@ -416,8 +417,7 @@ if (!dmarc_abort && !sender_host_authenticated)
"failure to read domainname used for DMARC lookup: %s",
opendmarc_policy_status_to_str(libdm_status));
- libdm_status = opendmarc_get_policy_to_enforce(dmarc_pctx);
- dmarc_policy = libdm_status;
+ dmarc_policy = libdm_status = opendmarc_get_policy_to_enforce(dmarc_pctx);
switch(libdm_status)
{
case DMARC_POLICY_ABSENT: /* No DMARC record found */
diff --git a/src/src/globals.c b/src/src/globals.c
index 0ae1e2f4e..d17f9a9dc 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -673,6 +673,7 @@ BOOL dkim_collect_input = FALSE;
uschar *dkim_cur_signer = NULL;
BOOL dkim_disable_verify = FALSE;
int dkim_key_length = 0;
+void *dkim_signatures = NULL;
uschar *dkim_signers = NULL;
uschar *dkim_signing_domain = NULL;
uschar *dkim_signing_selector = NULL;
diff --git a/src/src/globals.h b/src/src/globals.h
index cdd493cbb..95a75cd90 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -396,6 +396,7 @@ extern BOOL dkim_collect_input; /* Runtime flag that tracks wether SMTP i
extern uschar *dkim_cur_signer; /* Expansion variable, holds the current "signer" domain or identity during a acl_smtp_dkim run */
extern BOOL dkim_disable_verify; /* Set via ACL control statement. When set, DKIM verification is disabled for the current message */
extern int dkim_key_length; /* Expansion variable, length of signing key in bits */
+extern void *dkim_signatures; /* Actually a (pdkim_signature *) but most files do not need to know */
extern uschar *dkim_signers; /* Expansion variable, holds colon-separated list of domains and identities that have signed a message */
extern uschar *dkim_signing_domain; /* Expansion variable, domain used for signing a message. */
extern uschar *dkim_signing_selector; /* Expansion variable, selector used for signing a message. */
diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index 433c677e4..cf1d9fd90 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -2039,13 +2039,19 @@ bmi_verdicts = NULL;
dnslist_domain = dnslist_matched = NULL;
#ifndef DISABLE_DKIM
dkim_cur_signer = dkim_signers =
-dkim_signing_domain = dkim_signing_selector = NULL;
+dkim_signing_domain = dkim_signing_selector = dkim_signatures = NULL;
dkim_cur_signer = dkim_signers = dkim_signing_domain = dkim_signing_selector = NULL;
dkim_disable_verify = dkim_collect_input = FALSE;
dkim_verify_overall = dkim_verify_status = dkim_verify_reason = NULL;
dkim_key_length = 0;
dkim_verify_signers = US"$dkim_signers";
#endif
+#ifdef EXPERIMENTAL_DMARC
+dmarc_has_been_checked = dmarc_disable_verify = dmarc_enable_forensic = FALSE;
+dmarc_ar_header = dmarc_domain_policy = dmarc_forensic_sender =
+dmarc_history_file = dmarc_status = dmarc_status_text = dmarc_tld_file =
+dmarc_used_domain = NULL;
+#endif
dsn_ret = 0;
dsn_envid = NULL;
deliver_host = deliver_host_address = NULL; /* Can be set by ACL */