Commit Diff


commit - e7076cef86ccd15d68dbaa2fc3c76976f34cd3bf
commit + e974922c653d65bd532e1dc385cf9e479aa4f38f
blob - f20a0b16810cd2d9d16b9aae503ebcde39f284f4
blob + 28d8ba5bf82eb2649a65a0eac8506ad50819861c
--- filter-dkim.1
+++ filter-dkim.1
@@ -26,6 +26,7 @@
 .Op Fl c Ar canonicalization
 .Op Fl h Ar headers
 .Op Fl t
+.Op Fl x Ar seconds
 .Fl d Ar domain
 .Fl k Ar file
 .Fl s Ar selector
@@ -52,7 +53,7 @@ The email headers which are included in the mail signa
 Per RFC this option requires at least the from header to be included.
 The headers are specified by separating them with a colon.
 The default is
-Ar from:reply-to:subject:date:to:cc:resent-date:resent-from:resent-to:resent-cc:in-reply-to:references:list-id:list-help:list-unsubscribe:list-subscribe:list-post:list-owner:list-archive .
+from:reply-to:subject:date:to:cc:resent-date:resent-from:resent-to:resent-cc:in-reply-to:references:list-id:list-help:list-unsubscribe:list-subscribe:list-post:list-owner:list-archive .
 .It Fl k
 .Ar file
 should point to a file containing the RSA private key to sign the messages.
@@ -62,6 +63,10 @@ The selector within the _domainkey subdomain of
 where the public key can be found.
 .It Fl t
 Add the time of signing to the dkim header.
+.It Fl x
+Add the amount of
+.Ar seconds
+the signature is valid to the dkim header.
 .El
 .Sh SEE ALSO
 .Xr smtpd 8
blob - f937ced559e717719dad86ab9c0ffd92400ed283
blob + 3cea23ed9ce4523d9d36321b860f6531d5554eec
--- main.c
+++ main.c
@@ -91,6 +91,7 @@ static int canonheader = CANON_SIMPLE;
 static int canonbody = CANON_SIMPLE;
 
 static int addtime = 0;
+static long long addexpire = 0;
 
 static char *domain = NULL;
 static char *selector = NULL;
@@ -128,8 +129,9 @@ main(int argc, char *argv[])
 	int i;
 	int debug = 0;
 	FILE *keyfile;
+	const char *errstr;
 
-	while ((ch = getopt(argc, argv, "a:c:Dd:h:k:s:t")) != -1) {
+	while ((ch = getopt(argc, argv, "a:c:Dd:h:k:s:tx:")) != -1) {
 		switch (ch) {
 		case 'a':
 			if (strncmp(optarg, "rsa-", 4) != 0)
@@ -179,6 +181,11 @@ main(int argc, char *argv[])
 		case 't':
 			addtime = 1;
 			break;
+		case 'x':
+			addexpire = strtonum(optarg, 1, INT64_MAX, &errstr);
+			if (addexpire == 0)
+				errx(1, "Expire offset is %s", errstr);
+			break;
 		case 'D':
 			debug = 1;
 			break;
@@ -556,14 +563,20 @@ dkim_sign(struct dkim_session *session)
 	char bbh[EVP_MAX_MD_SIZE];
 	char bh[(((sizeof(bbh) + 2) / 3) * 4) + 1];
 	char *b;
+	time_t now;
 	ssize_t i, j;
 	size_t linelen;
 	char *tmp, *tmp2;
 	char tmpchar;
 
-	if (addtime && !dkim_signature_printf(session, "t=%lld; ",
-	    (long long) time(NULL)))
+	if (addtime || addexpire)
+		now = time(NULL);
+	if (addtime && !dkim_signature_printf(session, "t=%lld; ", now))
 		return;
+	if (addexpire != 0 && !dkim_signature_printf(session, "x=%lld; ",
+	    now + addexpire < now ? INT64_MAX : now + addexpire))
+		return;
+
 	if (canonbody == CANON_SIMPLE && !session->has_body) {
 		if (EVP_DigestUpdate(session->bh, "\r\n", 2) <= 0) {
 			dkim_err(session, "Can't update hash context");