summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2017-09-25 16:36:47 +0100
committerJeremy Harris <jgh146exb@wizmail.org>2017-09-25 16:36:47 +0100
commit7c6ec81b9594697a5b916db1aabbb1c8b6c4e342 (patch)
tree097d5cf24991d19d24fc0895b239401eae500bec
parent4a5cbaff2f9addfc9b4375a97ec6669bf18ee4db (diff)
DKIM: support specifying alternate-identity tag for signing. Bug 2170
-rw-r--r--doc/doc-docbook/spec.xfpt20
-rw-r--r--doc/doc-txt/NewStuff2
-rw-r--r--src/src/dkim.c60
-rw-r--r--src/src/structs.h1
-rw-r--r--src/src/transports/smtp.c5
-rw-r--r--test/confs/45202
-rw-r--r--test/log/45203
-rw-r--r--test/log/45233
8 files changed, 50 insertions, 46 deletions
diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 44a274b98..4a8e1d06e 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -23800,6 +23800,7 @@ of the message. Its value must not be zero. See also &%final_timeout%&.
.option dkim_strict smtp string&!! unset
.option dkim_sign_headers smtp string&!! unset
.option dkim_hash smtp string&!! sha256
+.option dkim_identity smtp string&!! unset
DKIM signing options. For details see section &<<SECDKIMSIGN>>&.
@@ -38553,6 +38554,19 @@ is set.
.endlist
If the option is empty after expansion, DKIM signing is not done.
+.new
+.option dkim_hash smtp string&!! sha256
+Can be set alternatively to &"sha1"& to use an alternate hash
+method. Note that sha1 is now condidered insecure, and deprecated.
+
+.option dkim_identity smtp string&!! unset
+If set after expansion, the value is used to set an "i=" tag in
+the signing header. The DKIM standards restrict the permissible
+syntax of this optional tag to a mail address, with possibly-empty
+local part, an @, and a domain identical to or subdomain of the "d="
+tag value. Note that Exim does not check the value.
+.wen
+
.option dkim_canon smtp string&!! unset
This option sets the canonicalization method used when signing a message.
The DKIM RFC currently supports two methods: "simple" and "relaxed".
@@ -38572,12 +38586,6 @@ list of header names. Headers with these names will be included in the message
signature.
When unspecified, the header names recommended in RFC4871 will be used.
-.new
-.option dkim_hash smtp string&!! sha256
-Can be set alternatively to &"sha1"& to use an alternate hash
-method. Note that sha1 is now condidered insecure, and deprecated.
-.wen
-
.section "Verifying DKIM signatures in incoming mail" "SECID514"
.cindex "DKIM" "verification"
diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index 88def2629..39fce1eab 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -52,7 +52,7 @@ Version 4.90
is opened with a TFO cookie.
13. DKIM support for multiple signing, by domain and/or key-selector.
- DKIM support for multiple hashes.
+ DKIM support for multiple hashes, and for alternate-identity tags.
14. Exipick understands -C|--config for an alternative Exim
configuration file.
diff --git a/src/src/dkim.c b/src/src/dkim.c
index ea2007225..cd8a16ae6 100644
--- a/src/src/dkim.c
+++ b/src/src/dkim.c
@@ -471,18 +471,15 @@ int sread;
uschar buf[4096];
int save_errno = 0;
int old_pool = store_pool;
+uschar * errwhen;
store_pool = POOL_MAIN;
pdkim_init_context(&ctx, dkim->dot_stuffed, &dkim_exim_query_dns_txt);
if (!(dkim_domain = expand_cstring(dkim->dkim_domain)))
- {
/* expansion error, do not send message. */
- log_write(0, LOG_MAIN | LOG_PANIC, "failed to expand "
- "dkim_domain: %s", expand_string_message);
- goto bad;
- }
+ { errwhen = US"dkim_domain"; goto expand_bad; }
/* Set $dkim_domain expansion variable to each unique domain in list. */
@@ -509,11 +506,7 @@ while ((dkim_signing_domain = string_nextinlist(&dkim_domain, &sep, NULL, 0)))
if (!(dkim_sel = expand_string(dkim->dkim_selector)))
if (!(dkim_signing_selector = expand_string(dkim->dkim_selector)))
- {
- log_write(0, LOG_MAIN | LOG_PANIC, "failed to expand "
- "dkim_selector: %s", expand_string_message);
- goto bad;
- }
+ { errwhen = US"dkim_selector"; goto expand_bad; }
while ((dkim_signing_selector = string_nextinlist(&dkim_sel, &sel_sep,
NULL, 0)))
@@ -523,18 +516,14 @@ while ((dkim_signing_domain = string_nextinlist(&dkim_domain, &sep, NULL, 0)))
uschar * dkim_sign_headers_expanded = NULL;
uschar * dkim_private_key_expanded;
uschar * dkim_hash_expanded;
+ uschar * dkim_identity_expanded = NULL;
/* Get canonicalization to use */
dkim_canon_expanded = dkim->dkim_canon
? expand_string(dkim->dkim_canon) : US"relaxed";
- if (!dkim_canon_expanded)
- {
- /* expansion error, do not send message. */
- log_write(0, LOG_MAIN | LOG_PANIC, "failed to expand "
- "dkim_canon: %s", expand_string_message);
- goto bad;
- }
+ if (!dkim_canon_expanded) /* expansion error, do not send message. */
+ { errwhen = US"dkim_canon"; goto expand_bad; }
if (Ustrcmp(dkim_canon_expanded, "relaxed") == 0)
pdkim_canon = PDKIM_CANON_RELAXED;
@@ -548,23 +537,15 @@ while ((dkim_signing_domain = string_nextinlist(&dkim_domain, &sep, NULL, 0)))
pdkim_canon = PDKIM_CANON_RELAXED;
}
- if (dkim->dkim_sign_headers)
- if (!(dkim_sign_headers_expanded = expand_string(dkim->dkim_sign_headers)))
- {
- log_write(0, LOG_MAIN | LOG_PANIC, "failed to expand "
- "dkim_sign_headers: %s", expand_string_message);
- goto bad;
- }
- /* else pass NULL, which means default header list */
+ if ( dkim->dkim_sign_headers
+ && !(dkim_sign_headers_expanded = expand_string(dkim->dkim_sign_headers)))
+ { errwhen = US"dkim_sign_header"; goto expand_bad; }
+ /* else pass NULL, which means default header list */
/* Get private key to use. */
if (!(dkim_private_key_expanded = expand_string(dkim->dkim_private_key)))
- {
- log_write(0, LOG_MAIN | LOG_PANIC, "failed to expand "
- "dkim_private_key: %s", expand_string_message);
- goto bad;
- }
+ { errwhen = US"dkim_private_key"; goto expand_bad; }
if ( Ustrlen(dkim_private_key_expanded) == 0
|| Ustrcmp(dkim_private_key_expanded, "0") == 0
@@ -607,11 +588,13 @@ while ((dkim_signing_domain = string_nextinlist(&dkim_domain, &sep, NULL, 0)))
}
if (!(dkim_hash_expanded = expand_string(dkim->dkim_hash)))
- {
- log_write(0, LOG_MAIN | LOG_PANIC, "failed to expand "
- "dkim_hash: %s", expand_string_message);
- goto bad;
- }
+ { errwhen = US"dkim_hash"; goto expand_bad; }
+
+ if (dkim->dkim_identity)
+ if (!(dkim_identity_expanded = expand_string(dkim->dkim_identity)))
+ { errwhen = US"dkim_identity"; goto expand_bad; }
+ else if (!*dkim_identity_expanded)
+ dkim_identity_expanded = NULL;
/*XXX so we currently nail signing to RSA + this hash.
Need to extract algo from privkey and check for disallowed combos. */
@@ -627,7 +610,7 @@ while ((dkim_signing_domain = string_nextinlist(&dkim_domain, &sep, NULL, 0)))
pdkim_set_optional(sig,
CS dkim_sign_headers_expanded,
- NULL,
+ dkim_identity_expanded,
pdkim_canon,
pdkim_canon, -1, 0, 0);
@@ -694,6 +677,11 @@ pk_bad:
bad:
sigbuf = NULL;
goto CLEANUP;
+
+expand_bad:
+ log_write(0, LOG_MAIN | LOG_PANIC, "failed to expand %s: %s",
+ errwhen, expand_string_message);
+ goto bad;
}
#endif
diff --git a/src/src/structs.h b/src/src/structs.h
index 06fcd4188..d8ac19ab8 100644
--- a/src/src/structs.h
+++ b/src/src/structs.h
@@ -867,6 +867,7 @@ typedef BOOL (*oicf) (uschar *message_id, void *data);
/* DKIM information for transport */
struct ob_dkim {
uschar *dkim_domain;
+ uschar *dkim_identity;
uschar *dkim_private_key;
uschar *dkim_selector;
uschar *dkim_canon;
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index 557d650ae..461b26c4a 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -45,6 +45,8 @@ optionlist smtp_transport_options[] = {
(void *)offsetof(smtp_transport_options_block, dkim.dkim_domain) },
{ "dkim_hash", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, dkim.dkim_hash) },
+ { "dkim_identity", opt_stringptr,
+ (void *)offsetof(smtp_transport_options_block, dkim.dkim_identity) },
{ "dkim_private_key", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, dkim.dkim_private_key) },
{ "dkim_selector", opt_stringptr,
@@ -278,10 +280,11 @@ smtp_transport_options_block smtp_transport_option_defaults = {
#ifndef DISABLE_DKIM
.dkim =
{.dkim_domain = NULL,
+ .dkim_identity = NULL,
.dkim_private_key = NULL,
.dkim_selector = NULL,
.dkim_canon = NULL,
- .dkim_sign_headers = NULL,
+ .dkim_sign_headers = NULL,
.dkim_strict = NULL,
.dkim_hash = US"sha256",
.dot_stuffed = FALSE},
diff --git a/test/confs/4520 b/test/confs/4520
index 5f4649846..897c1a675 100644
--- a/test/confs/4520
+++ b/test/confs/4520
@@ -50,6 +50,8 @@ send_to_server:
.ifndef HEADERS_MAXSIZE
dkim_sign_headers = OPT
+.else
+ dkim_identity = allheaders@$dkim_domain
.endif
.ifdef VALUE
dkim_hash = VALUE
diff --git a/test/log/4520 b/test/log/4520
index 73854cfc1..8daa636c0 100644
--- a/test/log/4520
+++ b/test/log/4520
@@ -23,8 +23,9 @@
1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmaZ-0005vi-00@myhost.test.ex
1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: <b@test.ex> R=server_dump
1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbC-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/relaxed a=rsa-sha256 b=1024 [verification succeeded]
+1999-03-02 09:44:33 10HmbC-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/relaxed a=rsa-sha256 b=1024 i=allheaders@test.ex [verification succeeded]
1999-03-02 09:44:33 10HmbC-0005vi-00 signer: test.ex bits: 1024 h=Date:Sender:Message-Id:From:Reply-To:Subject:To:Cc:MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive
+1999-03-02 09:44:33 10HmbC-0005vi-00 signer: allheaders@test.ex bits: 1024 h=Date:Sender:Message-Id:From:Reply-To:Subject:To:Cc:MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive
1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmbB-0005vi-00@myhost.test.ex
1999-03-02 09:44:33 10HmbC-0005vi-00 => :blackhole: <c@test.ex> R=server_dump
1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
diff --git a/test/log/4523 b/test/log/4523
index 45eb89c9c..d1e5ebba3 100644
--- a/test/log/4523
+++ b/test/log/4523
@@ -4,8 +4,9 @@
******** SERVER ********
1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
-1999-03-02 09:44:33 10HmaY-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/relaxed a=rsa-sha512 b=1024 [verification succeeded]
+1999-03-02 09:44:33 10HmaY-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/relaxed a=rsa-sha512 b=1024 i=allheaders@test.ex [verification succeeded]
1999-03-02 09:44:33 10HmaY-0005vi-00 signer: test.ex bits: 1024 h=Date:Sender:Message-Id:From:Reply-To:Subject:To:Cc:MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive
+1999-03-02 09:44:33 10HmaY-0005vi-00 signer: allheaders@test.ex bits: 1024 h=Date:Sender:Message-Id:From:Reply-To:Subject:To:Cc:MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive
1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex
1999-03-02 09:44:33 10HmaY-0005vi-00 => :blackhole: <a@test.ex> R=server_dump
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed