diff options
-rw-r--r-- | src/src/dkim.c | 6 | ||||
-rw-r--r-- | src/src/dmarc.c | 56 | ||||
-rw-r--r-- | src/src/globals.c | 1 | ||||
-rw-r--r-- | src/src/globals.h | 1 | ||||
-rw-r--r-- | src/src/smtp_in.c | 8 |
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 */ |