summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2018-02-18 00:33:28 +0000
committerJeremy Harris <jgh146exb@wizmail.org>2018-02-18 00:39:01 +0000
commitdfbcb5ac660065b097b0ad0cb2c26357899f0c64 (patch)
tree3eb03b962fe9792d991b77d88cb8c276881d7202 /src
parentb808677c8f0d6a1cf93ff75f4ad5b1199bd85311 (diff)
Expansions: new ${authresults {mch}} for an Authentication-Results header
Diffstat (limited to 'src')
-rw-r--r--src/src/dkim.c92
-rw-r--r--src/src/expand.c48
-rw-r--r--src/src/functions.h8
-rw-r--r--src/src/pdkim/pdkim.h1
-rw-r--r--src/src/smtp_in.c17
-rw-r--r--src/src/spf.c12
6 files changed, 167 insertions, 11 deletions
diff --git a/src/src/dkim.c b/src/src/dkim.c
index 423aad49c..571586130 100644
--- a/src/src/dkim.c
+++ b/src/src/dkim.c
@@ -151,6 +151,12 @@ uschar * s;
if (!sig) return;
+if ( dkim_verify_status
+ && ( dkim_verify_status != dkim_exim_expand_query(DKIM_VERIFY_STATUS)
+ || dkim_verify_reason != dkim_exim_expand_query(DKIM_VERIFY_REASON)
+ ) )
+ sig->verify_status |= PDKIM_VERIFY_POLICY;
+
if ( !dkim_verify_overall
&& dkim_verify_status
? Ustrcmp(dkim_verify_status, US"pass") == 0
@@ -166,9 +172,9 @@ logmsg = string_append(logmsg, 2, "d=", s);
if (!(s = sig->selector)) s = US"<UNSET>";
logmsg = string_append(logmsg, 2, " s=", s);
logmsg = string_append(logmsg, 7,
-" c=", sig->canon_headers == PDKIM_CANON_SIMPLE ? "simple" : "relaxed",
-"/", sig->canon_body == PDKIM_CANON_SIMPLE ? "simple" : "relaxed",
-" a=", dkim_sig_to_a_tag(sig),
+ " c=", sig->canon_headers == PDKIM_CANON_SIMPLE ? "simple" : "relaxed",
+ "/", sig->canon_body == PDKIM_CANON_SIMPLE ? "simple" : "relaxed",
+ " a=", dkim_sig_to_a_tag(sig),
string_sprintf(" b=" SIZE_T_FMT,
(int)sig->sighash.len > -1 ? sig->sighash.len * 8 : 0));
if ((s= sig->identity)) logmsg = string_append(logmsg, 2, " i=", s);
@@ -179,10 +185,10 @@ if (sig->expires > 0) logmsg = string_cat(logmsg,
if (sig->bodylength > -1) logmsg = string_cat(logmsg,
string_sprintf(" l=%lu", sig->bodylength));
-if ( !dkim_verify_status
- || ( dkim_verify_status == dkim_exim_expand_query(DKIM_VERIFY_STATUS)
- && dkim_verify_reason == dkim_exim_expand_query(DKIM_VERIFY_REASON)
- ) )
+if (sig->verify_status & PDKIM_VERIFY_POLICY)
+ logmsg = string_append(logmsg, 5,
+ US" [", dkim_verify_status, US" - ", dkim_verify_reason, US"]");
+else
switch (sig->verify_status)
{
case PDKIM_VERIFY_NONE:
@@ -233,7 +239,7 @@ if ( !dkim_verify_status
logmsg = string_cat(logmsg,
US"signature did not verify "
"(headers probably modified in transit)]");
- break;
+ break;
default:
logmsg = string_cat(logmsg, US"unspecified reason]");
@@ -244,9 +250,6 @@ if ( !dkim_verify_status
logmsg = string_cat(logmsg, US" [verification succeeded]");
break;
}
-else
- logmsg = string_append(logmsg, 5,
- US" [", dkim_verify_status, US" - ", dkim_verify_reason, US"]");
log_write(0, LOG_MAIN, "%s", string_from_gstring(logmsg));
return;
@@ -771,5 +774,72 @@ expand_bad:
goto bad;
}
+
+
+
+gstring *
+authres_dkim(gstring * g)
+{
+pdkim_signature * sig;
+
+for (sig = dkim_signatures; sig; sig = sig->next)
+ {
+ g = string_catn(g, US";\\n\\tdkim=", 10);
+
+ if (sig->verify_status & PDKIM_VERIFY_POLICY)
+ g = string_append(g, 5,
+ US"policy (", dkim_verify_status, US" - ", dkim_verify_reason, US")");
+ else switch(sig->verify_status)
+ {
+ case PDKIM_VERIFY_NONE: g = string_cat(g, US"none"); break;
+ case PDKIM_VERIFY_INVALID:
+ switch (sig->verify_ext_status)
+ {
+ case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE:
+ g = string_cat(g, US"tmperror (pubkey unavailable)"); break;
+ case PDKIM_VERIFY_INVALID_BUFFER_SIZE:
+ g = string_cat(g, US"permerror (overlong public key record)"); break;
+ case PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD:
+ case PDKIM_VERIFY_INVALID_PUBKEY_IMPORT:
+ g = string_cat(g, US"neutral (syntax error in public key record)");
+ break;
+ case PDKIM_VERIFY_INVALID_SIGNATURE_ERROR:
+ g = string_cat(g, US"neutral (signature tag missing or invalid)");
+ break;
+ case PDKIM_VERIFY_INVALID_DKIM_VERSION:
+ g = string_cat(g, US"neutral (unsupported DKIM version)");
+ break;
+ default:
+ g = string_cat(g, US"permerror (unspecified problem)"); break;
+ }
+ break;
+ case PDKIM_VERIFY_FAIL:
+ switch (sig->verify_ext_status)
+ {
+ case PDKIM_VERIFY_FAIL_BODY:
+ g = string_cat(g,
+ US"fail (body hash mismatch; body probably modified in transit)");
+ break;
+ case PDKIM_VERIFY_FAIL_MESSAGE:
+ g = string_cat(g,
+ US"fail (signature did not verify; headers probably modified in transit)");
+ break;
+ default:
+ g = string_cat(g, US"fail (unspecified reason)");
+ break;
+ }
+ break;
+ case PDKIM_VERIFY_PASS: g = string_cat(g, US"pass"); break;
+ default: g = string_cat(g, US"permerror"); break;
+ }
+ if (sig->domain) g = string_append(g, 2, US" header.d=", sig->domain);
+ if (sig->identity) g = string_append(g, 2, US" header.i=", sig->identity);
+ if (sig->selector) g = string_append(g, 2, US" header.s=", sig->selector);
+ g = string_append(g, 2, US" header.a=", dkim_sig_to_a_tag(sig));
+ }
+return g;
+}
+
+
# endif /*!MACRO_PREDEF*/
#endif /*!DISABLE_DKIM*/
diff --git a/src/src/expand.c b/src/src/expand.c
index c7ebf9870..44e8e1ba0 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -103,6 +103,7 @@ alphabetical order. */
static uschar *item_table[] = {
US"acl",
+ US"authresults",
US"certextract",
US"dlfunc",
US"env",
@@ -133,6 +134,7 @@ static uschar *item_table[] = {
enum {
EITEM_ACL,
+ EITEM_AUTHRESULTS,
EITEM_CERTEXTRACT,
EITEM_DLFUNC,
EITEM_ENV,
@@ -1656,6 +1658,24 @@ return yield;
+/* Append an "iprev" element to an Autherntication-Results: header
+if we have attempted to get the calling host's name.
+*/
+
+static gstring *
+authres_iprev(gstring * g)
+{
+if (sender_host_name)
+ return string_append(g, 3, US";\\n\\tiprev=pass (", sender_host_name, US")");
+if (host_lookup_deferred)
+ return string_catn(g, US";\\n\\tiprev=temperror", 21);
+if (host_lookup_failed)
+ return string_catn(g, US";\\n\\tiprev=fail", 15);
+return g;
+}
+
+
+
/*************************************************
* Return list of recipients *
*************************************************/
@@ -4100,6 +4120,34 @@ while (*s != 0)
}
}
+ case EITEM_AUTHRESULTS:
+ /* ${authresults {mysystemname}} */
+ {
+ uschar *sub_arg[1];
+
+ switch(read_subs(sub_arg, nelem(sub_arg), 1, &s, skipping, TRUE, name,
+ &resetok))
+ {
+ case 1: goto EXPAND_FAILED_CURLY;
+ case 2:
+ case 3: goto EXPAND_FAILED;
+ }
+
+ yield = string_append(yield, 3,
+ US"Authentication-Results: ", sub_arg[0], US"; none");
+ yield->ptr -= 6;
+
+ yield = authres_iprev(yield);
+ yield = authres_smtpauth(yield);
+#ifdef SUPPORT_SPF
+ yield = authres_spf(yield);
+#endif
+#ifndef DISABLE_DKIM
+ yield = authres_dkim(yield);
+#endif
+ continue;
+ }
+
/* Handle conditionals - preserve the values of the numerical expansion
variables in case they get changed by a regular expression match in the
condition. If not, they retain their external settings. At the end
diff --git a/src/src/functions.h b/src/src/functions.h
index 6dc3e4973..8a45ae48d 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -104,6 +104,14 @@ extern void auth_show_supported(FILE *);
extern uschar *auth_xtextencode(uschar *, int);
extern int auth_xtextdecode(uschar *, uschar **);
+extern gstring *authres_smtpauth(gstring *);
+#ifdef SUPPORT_SPF
+extern gstring *authres_spf(gstring *);
+#endif
+#ifndef DISABLE_DKIM
+extern gstring *authres_dkim(gstring *);
+#endif
+
extern uschar *b64encode(uschar *, int);
extern int b64decode(const uschar *, uschar **);
extern int bdat_getc(unsigned);
diff --git a/src/src/pdkim/pdkim.h b/src/src/pdkim/pdkim.h
index 1a7a0c8d0..775581be7 100644
--- a/src/src/pdkim/pdkim.h
+++ b/src/src/pdkim/pdkim.h
@@ -57,6 +57,7 @@
#define PDKIM_VERIFY_INVALID 1
#define PDKIM_VERIFY_FAIL 2
#define PDKIM_VERIFY_PASS 3
+#define PDKIM_VERIFY_POLICY BIT(31)
#define PDKIM_VERIFY_FAIL_BODY 1
#define PDKIM_VERIFY_FAIL_MESSAGE 2
diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index f54838991..1b7df5c30 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -5743,6 +5743,23 @@ while (done <= 0)
return done - 2; /* Convert yield values */
}
+
+
+gstring *
+authres_smtpauth(gstring * g)
+{
+if (!sender_host_authenticated)
+ return g;
+
+g = string_append(g, 4, US";\\n\\tauth=pass"
+ " (", sender_host_authenticated, US") smtp.auth=", authenticated_id);
+if (authenticated_sender)
+ g = string_append(g, 2, US" smtp.mailfrom=", authenticated_sender);
+return g;
+}
+
+
+
/* vi: aw ai sw=2
*/
/* End of smtp_in.c */
diff --git a/src/src/spf.c b/src/src/spf.c
index 9fdc0baec..a2f93b0ce 100644
--- a/src/src/spf.c
+++ b/src/src/spf.c
@@ -146,4 +146,16 @@ while ((spf_result_id = string_nextinlist(&list, &sep, NULL, 0)))
return FAIL;
}
+
+
+gstring *
+authres_spf(gstring * g)
+{
+if (!spf_result) return g;
+
+return string_append(g, 4, US";\\n\\tspf=", spf_result,
+ US" smtp.mailfrom=", expand_string(US"$sender_address_domain"));
+}
+
+
#endif