From cc55f4208e997ee8cdd87bf2a141be0c615488f9 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Tue, 7 Nov 2017 21:40:19 +0000 Subject: DKIM: make verification results visible in data ACL --- src/src/dkim.c | 7 ++- src/src/receive.c | 164 ++++++++++++++++++++++++++++-------------------------- 2 files changed, 90 insertions(+), 81 deletions(-) (limited to 'src') diff --git a/src/src/dkim.c b/src/src/dkim.c index 9a13e2a80..528ce82c4 100644 --- a/src/src/dkim.c +++ b/src/src/dkim.c @@ -138,9 +138,12 @@ store_pool = dkim_verify_oldpool; static void dkim_exim_verify_log_sig(pdkim_signature * sig) { -gstring * logmsg = string_catn(NULL, "DKIM: ", 6); +gstring * logmsg; uschar * s; +if (!sig) return; + +logmsg = string_catn(NULL, "DKIM: ", 6); if (!(s = sig->domain)) s = US""; logmsg = string_append(logmsg, 2, "d=", s); if (!(s = sig->selector)) s = US""; @@ -306,6 +309,8 @@ dkim_exim_acl_setup(uschar * id) pdkim_signature * sig; uschar * cmp_val; +dkim_verify_status = US"none"; +dkim_verify_reason = US""; dkim_cur_sig = NULL; dkim_cur_signer = id; diff --git a/src/src/receive.c b/src/src/receive.c index f181f1a51..8aa890bd0 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -3388,99 +3388,103 @@ else #ifndef DISABLE_DKIM if (!dkim_disable_verify) { - /* Finish verification, this will log individual signature results to - the mainlog */ + /* Finish verification */ dkim_exim_verify_finish(); /* Check if we must run the DKIM ACL */ if (acl_smtp_dkim && dkim_verify_signers && *dkim_verify_signers) { - uschar *dkim_verify_signers_expanded = + uschar * dkim_verify_signers_expanded = expand_string(dkim_verify_signers); - if (!dkim_verify_signers_expanded) + gstring * results = NULL; + int signer_sep = 0; + const uschar * ptr; + uschar * item; + gstring * seen_items = NULL; + int old_pool = store_pool; + + store_pool = POOL_PERM; /* Allow created variables to live to data ACL */ + + if (!(ptr = dkim_verify_signers_expanded)) log_write(0, LOG_MAIN|LOG_PANIC, "expansion of dkim_verify_signers option failed: %s", expand_string_message); - else - { - int sep = 0; - const uschar * ptr = dkim_verify_signers_expanded; - uschar * item = NULL; - gstring * seen_items = NULL; - - /* Default to OK when no items are present */ - rc = OK; - while ((item = string_nextinlist(&ptr, &sep, NULL, 0))) - { - /* Prevent running ACL for an empty item */ - if (!item || !*item) continue; - - /* Only run ACL once for each domain or identity, - no matter how often it appears in the expanded list. */ - if (seen_items) - { - uschar *seen_item; - const uschar *seen_items_list = string_from_gstring(seen_items); - BOOL seen_this_item = FALSE; - - while ((seen_item = string_nextinlist(&seen_items_list, &sep, - NULL, 0))) - if (Ustrcmp(seen_item,item) == 0) - { - seen_this_item = TRUE; - break; - } - - if (seen_this_item) - { - DEBUG(D_receive) - debug_printf("acl_smtp_dkim: skipping signer %s, " - "already seen\n", item); - continue; - } - - seen_items = string_cat(seen_items, ":"); - } - - seen_items = string_cat(seen_items, item); - - DEBUG(D_receive) - debug_printf("calling acl_smtp_dkim for dkim_cur_signer=%s\n", - item); - - dkim_exim_acl_setup(item); - rc = acl_check(ACL_WHERE_DKIM, NULL, acl_smtp_dkim, - &user_msg, &log_msg); - dkim_exim_verify_log_item(); - - if (rc != OK) + /* Default to OK when no items are present */ + rc = OK; + while ((item = string_nextinlist(&ptr, &signer_sep, NULL, 0))) + { + /* Prevent running ACL for an empty item */ + if (!item || !*item) continue; + + /* Only run ACL once for each domain or identity, + no matter how often it appears in the expanded list. */ + if (seen_items) + { + uschar * seen_item; + const uschar * seen_items_list = string_from_gstring(seen_items); + int seen_sep = ':'; + BOOL seen_this_item = FALSE; + + while ((seen_item = string_nextinlist(&seen_items_list, &seen_sep, + NULL, 0))) + if (Ustrcmp(seen_item,item) == 0) + { + seen_this_item = TRUE; + break; + } + + if (seen_this_item) { DEBUG(D_receive) - debug_printf("acl_smtp_dkim: acl_check returned %d on %s, " - "skipping remaining items\n", rc, item); - cancel_cutthrough_connection(TRUE, US"dkim acl not ok"); - break; + debug_printf("acl_smtp_dkim: skipping signer %s, " + "already seen\n", item); + continue; } - } - add_acl_headers(ACL_WHERE_DKIM, US"DKIM"); - if (rc == DISCARD) - { - recipients_count = 0; - blackholed_by = US"DKIM ACL"; - if (log_msg) - blackhole_log_msg = string_sprintf(": %s", log_msg); - } - else if (rc != OK) - { - Uunlink(spool_name); - if (smtp_handle_acl_fail(ACL_WHERE_DKIM, rc, user_msg, log_msg) != 0) - smtp_yield = FALSE; /* No more messages after dropped connection */ - smtp_reply = US""; /* Indicate reply already sent */ - message_id[0] = 0; /* Indicate no message accepted */ - goto TIDYUP; /* Skip to end of function */ - } - } + + seen_items = string_catn(seen_items, ":", 1); + } + + seen_items = string_cat(seen_items, item); + + dkim_exim_acl_setup(item); + DEBUG(D_receive) + debug_printf("calling acl_smtp_dkim for dkim_cur_signer='%s'\n", + item); + + rc = acl_check(ACL_WHERE_DKIM, NULL, acl_smtp_dkim, + &user_msg, &log_msg); + dkim_exim_verify_log_item(); + results = string_append_listele(results, ':', dkim_verify_status); + + if (rc != OK) + { + DEBUG(D_receive) + debug_printf("acl_smtp_dkim: acl_check returned %d on %s, " + "skipping remaining items\n", rc, item); + cancel_cutthrough_connection(TRUE, US"dkim acl not ok"); + break; + } + } + dkim_verify_status = string_from_gstring(results); + store_pool = old_pool; + add_acl_headers(ACL_WHERE_DKIM, US"DKIM"); + if (rc == DISCARD) + { + recipients_count = 0; + blackholed_by = US"DKIM ACL"; + if (log_msg) + blackhole_log_msg = string_sprintf(": %s", log_msg); + } + else if (rc != OK) + { + Uunlink(spool_name); + if (smtp_handle_acl_fail(ACL_WHERE_DKIM, rc, user_msg, log_msg) != 0) + smtp_yield = FALSE; /* No more messages after dropped connection */ + smtp_reply = US""; /* Indicate reply already sent */ + message_id[0] = 0; /* Indicate no message accepted */ + goto TIDYUP; /* Skip to end of function */ + } } else dkim_exim_verify_log_all(); -- cgit v1.2.3