Gitweb:
https://git.exim.org/exim.git/commitdiff/2bc0f45ec0637be57e5d87b576a72cac71ccaf81
Commit: 2bc0f45ec0637be57e5d87b576a72cac71ccaf81
Parent: d8d9f9301c9a31c826635bbdd334bb4be99ea05a
Author: Jeremy Harris <jgh146exb@???>
AuthorDate: Sat Jun 9 21:39:44 2018 +0100
Committer: Jeremy Harris <jgh146exb@???>
CommitDate: Sat Jun 9 22:17:54 2018 +0100
DKIM: support timestamp and expiry tags in signing. Bug 2260
---
doc/doc-docbook/spec.xfpt | 21 +++++++++++++++++----
doc/doc-txt/OptionLists.txt | 1 +
src/src/dkim.c | 11 ++++++++++-
src/src/structs.h | 1 +
src/src/transports/smtp.c | 3 +++
test/confs/4520 | 3 +++
test/log/4520 | 2 +-
test/mail/4520.b | 6 ++----
test/runtest | 17 ++++++++++++++++-
test/scripts/4500-DKIM/4520 | 4 ++--
10 files changed, 56 insertions(+), 13 deletions(-)
diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 431d456..863a6b9 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -23976,14 +23976,15 @@ the message. As a result, the overall timeout for a message depends on the size
of the message. Its value must not be zero. See also &%final_timeout%&.
+.option dkim_canon smtp string&!! unset
.option dkim_domain smtp string list&!! unset
-.option dkim_selector smtp string&!! unset
+.option dkim_hash smtp string&!! sha256
+.option dkim_identity smtp string&!! unset
.option dkim_private_key smtp string&!! unset
-.option dkim_canon smtp string&!! unset
+.option dkim_selector smtp string&!! unset
.option dkim_strict smtp string&!! unset
.option dkim_sign_headers smtp string&!! "per RFC"
-.option dkim_hash smtp string&!! sha256
-.option dkim_identity smtp string&!! unset
+.option dkim_timestamps smtp string&!! unset
DKIM signing options. For details see section &<<SECDKIMSIGN>>&.
@@ -39102,6 +39103,18 @@ If a '+' prefix if used, all headers that are present with this name
will be signed, and one signature added for a missing header with the
name will be appended.
+.new
+.option dkim_timestamps smtp integer&!! unset
+This option controls the inclusion of timestamp information in the signature.
+If not set, no such information will be included.
+Otherwise, must be an unsigned number giving an offset in seconds from the current time
+for the expiry tag
+(eg. 1209600 for two weeks);
+both creation (t=) and expiry (x=) tags will be included.
+
+RFC 6376 lists these tags as RECOMMENDED.
+.wen
+
.section "Verifying DKIM signatures in incoming mail" "SECDKIMVFY"
.cindex "DKIM" "verification"
diff --git a/doc/doc-txt/OptionLists.txt b/doc/doc-txt/OptionLists.txt
index 91ce182..0a6a320 100644
--- a/doc/doc-txt/OptionLists.txt
+++ b/doc/doc-txt/OptionLists.txt
@@ -169,6 +169,7 @@ dkim_private_key string* unset smtp
dkim_selector string* unset smtp 4.70
dkim_sign_headers string* (RFC4871) smtp 4.70
dkim_strict string* unset smtp 4.70
+dkim_timestamps integer* unset smtp 4.92
dkim_verify_signers string* $dkim_signers main 4.70
directory string* unset appendfile
directory_file string* + appendfile
diff --git a/src/src/dkim.c b/src/src/dkim.c
index 317f6e5..edbeded 100644
--- a/src/src/dkim.c
+++ b/src/src/dkim.c
@@ -645,6 +645,8 @@ if (dkim_domain)
uschar * dkim_private_key_expanded;
uschar * dkim_hash_expanded;
uschar * dkim_identity_expanded = NULL;
+ uschar * dkim_timestamps_expanded = NULL;
+ unsigned long tval = 0, xval = 0;
/* Get canonicalization to use */
@@ -695,6 +697,13 @@ if (dkim_domain)
else if (!*dkim_identity_expanded)
dkim_identity_expanded = NULL;
+ if (dkim->dkim_timestamps)
+ if (!(dkim_timestamps_expanded = expand_string(dkim->dkim_timestamps)))
+ { errwhen = US"dkim_timestamps"; goto expand_bad; }
+ else
+ xval = (tval = (unsigned long) time(NULL))
+ + strtoul(dkim_timestamps_expanded, NULL, 10);
+
if (!(sig = pdkim_init_sign(&dkim_sign_ctx, dkim_signing_domain,
dkim_signing_selector,
dkim_private_key_expanded,
@@ -708,7 +717,7 @@ if (dkim_domain)
CS dkim_sign_headers_expanded,
CS dkim_identity_expanded,
pdkim_canon,
- pdkim_canon, -1, 0, 0);
+ pdkim_canon, -1, tval, xval);
if (!pdkim_set_sig_bodyhash(&dkim_sign_ctx, sig))
goto bad;
diff --git a/src/src/structs.h b/src/src/structs.h
index 98c9501..8384920 100644
--- a/src/src/structs.h
+++ b/src/src/structs.h
@@ -878,6 +878,7 @@ struct ob_dkim {
uschar *dkim_sign_headers;
uschar *dkim_strict;
uschar *dkim_hash;
+ uschar *dkim_timestamps;
BOOL dot_stuffed;
BOOL force_bodyhash;
#ifdef EXPERIMENTAL_ARC
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index 2dfb5b7..6d70858 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -63,6 +63,8 @@ optionlist smtp_transport_options[] = {
(void *)offsetof(smtp_transport_options_block, dkim.dkim_sign_headers) },
{ "dkim_strict", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, dkim.dkim_strict) },
+ { "dkim_timestamps", opt_stringptr,
+ (void *)offsetof(smtp_transport_options_block, dkim.dkim_timestamps) },
#endif
{ "dns_qualify_single", opt_bool,
(void *)offsetof(smtp_transport_options_block, dns_qualify_single) },
@@ -295,6 +297,7 @@ smtp_transport_options_block smtp_transport_option_defaults = {
.dkim_sign_headers = NULL,
.dkim_strict = NULL,
.dkim_hash = US"sha256",
+ .dkim_timestamps = NULL,
.dot_stuffed = FALSE,
.force_bodyhash = FALSE,
# ifdef EXPERIMENTAL_ARC
diff --git a/test/confs/4520 b/test/confs/4520
index 3b8d781..8976923 100644
--- a/test/confs/4520
+++ b/test/confs/4520
@@ -67,6 +67,9 @@ send_to_server:
.ifdef STRICT
dkim_strict = STRICT
.endif
+.ifdef TIMES
+ dkim_timestamps = TIMES
+.endif
file:
driver = appendfile
diff --git a/test/log/4520 b/test/log/4520
index 2208b4f..d583933 100644
--- a/test/log/4520
+++ b/test/log/4520
@@ -34,7 +34,7 @@
1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
1999-03-02 09:44:33 rcpt acl: macro: From:Sender:Reply-To:Subject:Date:Message-ID: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 10HmbA-0005vi-00 dkim_acl: signer: test.ex bits: 1024 h=From:From
-1999-03-02 09:44:33 10HmbA-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/relaxed a=rsa-sha256 b=1024 [verification succeeded]
+1999-03-02 09:44:33 10HmbA-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/relaxed a=rsa-sha256 b=1024 t=T x=T+10 [verification succeeded]
1999-03-02 09:44:33 10HmbA-0005vi-00 data acl: dkim status pass
1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@??? H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmaZ-0005vi-00@???
1999-03-02 09:44:33 10HmbA-0005vi-00 => b <b@???> R=server_store T=file
diff --git a/test/mail/4520.b b/test/mail/4520.b
index 14ef0dd..22b8c62 100644
--- a/test/mail/4520.b
+++ b/test/mail/4520.b
@@ -5,10 +5,8 @@ Received: from the.local.host.name ([ip4.ip4.ip4.ip4] helo=myhost.test.ex)
id 10HmbA-0005vi-00
for b@???; Tue, 2 Mar 1999 09:44:33 +0000
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=test.ex;
- s=sel; h=From:From; bh=/Ab0giHZitYQbDhFszoqQRUkgqueaX9zatJttIU/plc=; b=n8PsoE
- fI7/q6r3UBtnd9bOynzqROT5SwDn/vctQeEYk79CsvhPmpFED/kb7+ojla6+ITBgvyRQMnBMxJwmk
- RjvQsvnJD7z/kyB0xJJzWPvcwS8TTJZ0oBUEUJyDmRSzDDTyOGgTWLpxD7QLoWi8WS49/tWUGkub2
- hiGw06hIjc4=;
+ s=sel; h=From:From; bh=/Ab0giHZitYQbDhFszoqQRUkgqueaX9zatJttIU/plc=;
+ t=T; x=T+10; b=bbbb;
Received: from CALLER by myhost.test.ex with local (Exim x.yz)
(envelope-from <CALLER@???>)
id 10HmaZ-0005vi-00
diff --git a/test/runtest b/test/runtest
index 63e6e11..0dc3cca 100755
--- a/test/runtest
+++ b/test/runtest
@@ -1210,6 +1210,21 @@ RESET_AFTER_EXTRA_LINE_READ:
s/(TLS error on connection [^:]*: error:)[0-9A-F]{8}(:system library):(?:fopen|func\(4095\)):(No such file or directory)$/$1xxxxxxxx$2:fopen:$3/;
s/(DANE attempt failed.*error:)[0-9A-F]{8}(:SSL routines:)(ssl3_get_server_certificate|tls_process_server_certificate|CONNECT_CR_CERT)(?=:certificate verify failed$)/$1xxxxxxxx$2ssl3_get_server_certificate/;
s/(DKIM: validation error: )error:[0-9A-F]{8}:rsa routines:(?:(?i)int_rsa_verify|CRYPTO_internal):(?:bad signature|algorithm mismatch)$/$1Public key signature verification has failed./;
+
+ # DKIM timestamps
+ s/(DKIM: d=.*) t=([0-9]*) x=([0-9]*)(?{ return $3 - $2; }) /$1 t=T x=T+$^R /;
+ }
+
+ # ======== mail ========
+
+ elsif ($is_mail)
+ {
+ # DKIM timestamps
+ if ( /^\s+t=[0-9]*; x=[0-9]*; b=[A-Za-z0-9+\/]+$/ ) {
+ s/^(\s+)t=([0-9]*); x=([0-9]*);(?{ return $3 - $2; }) b=[A-Za-z0-9+\/]+$/$1t=T; x=T+$^R; b=bbbb;/;
+ <IN>;
+ <IN>;
+ }
}
# ======== All files other than stderr ========
@@ -1569,7 +1584,7 @@ $munges =
'optional_config' =>
{ 'stdout' => '/^(
- dkim_(canon|domain|private_key|selector|sign_headers|strict|hash|identity)
+ dkim_(canon|domain|private_key|selector|sign_headers|strict|hash|identity|timestamps)
|gnutls_require_(kx|mac|protocols)
|hosts_(requ(est|ire)|try)_(dane|ocsp)
|dane_require_tls_ciphers
diff --git a/test/scripts/4500-DKIM/4520 b/test/scripts/4500-DKIM/4520
index f7fafb3..8e60f4b 100644
--- a/test/scripts/4500-DKIM/4520
+++ b/test/scripts/4500-DKIM/4520
@@ -11,8 +11,8 @@ From: second@???
content
****
#
-# single header, oversigned
-exim -DOPT=From:From -odf b@???
+# single header, oversigned, with timestamps
+exim -DOPT=From:From -DTIMES=10 -odf b@???
From: nobody@???
content