commit - e974922c653d65bd532e1dc385cf9e479aa4f38f
commit + c826412d86123fb2346635710aabec82f8e33946
blob - 28d8ba5bf82eb2649a65a0eac8506ad50819861c
blob + 114ca8bc90f950566cfe35bb43c14ae1b58834c9
--- filter-dkim.1
+++ filter-dkim.1
.Op Fl h Ar headers
.Op Fl t
.Op Fl x Ar seconds
+.Op Fl z
+.Op Fl Z
.Fl d Ar domain
.Fl k Ar file
.Fl s Ar selector
Add the amount of
.Ar seconds
the signature is valid to the dkim header.
+.It Fl z
+Add the mail headers used in the dkim signature to the dkim header.
+Useful for debugging purposes.
+.It Fl Z
+Add all the mail headers to the dkim header.
+Useful for debugging purposes.
.El
.Sh SEE ALSO
.Xr smtpd 8
blob - 3cea23ed9ce4523d9d36321b860f6531d5554eec
blob + be71a9bd0e73e19d1841154579e31e506362fa4e
--- main.c
+++ main.c
#include <ctype.h>
#include <err.h>
+#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
static int addtime = 0;
static long long addexpire = 0;
+static int addheaders = 0;
static char *domain = NULL;
static char *selector = NULL;
void dkim_parse_header(struct dkim_session *, char *, int);
void dkim_parse_body(struct dkim_session *, char *);
void dkim_sign(struct dkim_session *);
+int dkim_signature_printheader(struct dkim_session *, char *);
int dkim_signature_printf(struct dkim_session *, char *, ...)
__attribute__((__format__ (printf, 2, 3)));
int dkim_signature_normalize(struct dkim_session *);
FILE *keyfile;
const char *errstr;
- while ((ch = getopt(argc, argv, "a:c:Dd:h:k:s:tx:")) != -1) {
+ while ((ch = getopt(argc, argv, "a:c:Dd:h:k:s:tx:zZ")) != -1) {
switch (ch) {
case 'a':
if (strncmp(optarg, "rsa-", 4) != 0)
if (addexpire == 0)
errx(1, "Expire offset is %s", errstr);
break;
+ case 'z':
+ addheaders = 1;
+ break;
+ case 'Z':
+ addheaders = 2;
+ break;
case 'D':
debug = 1;
break;
line++;
dkim_parse_header(session, line, 0);
} else if (linelen == 0 && session->parsing_headers) {
+ if (addheaders > 0 && !dkim_signature_printf(session, "; "))
+ return;
session->parsing_headers = 0;
} else {
if (line[0] == '.')
canonbody == CANON_SIMPLE ? "simple" : "relaxed",
domain, selector))
return NULL;
+ if (addheaders > 0 && !dkim_signature_printf(session, "z="))
+ return NULL;
if ((session->b = EVP_MD_CTX_new()) == NULL ||
(session->bh = EVP_MD_CTX_new()) == NULL) {
char *htmp;
char *tmp;
+ if (addheaders == 2 && !force &&
+ !dkim_signature_printheader(session, line))
+ return;
+
if ((line[0] == ' ' || line[0] == '\t') && !session->lastheader)
return;
if ((line[0] != ' ' && line[0] != '\t')) {
return;
}
+ if (addheaders == 1 && !force &&
+ !dkim_signature_printheader(session, line))
+ return;
+
if (canonheader == CANON_RELAXED) {
if (!session->lastheader)
fieldname = 1;
switch (tag) {
case 'B':
case 'b':
+ case 'z':
checkpoint = i;
break;
case 'h':
if (sig[i] == ':')
checkpoint = i;
+ break;
}
if (tag == '\0' && sig[i] != ' ' && sig[i] != '\t') {
if ((tag = sig[i]) == 'b' && sig[i + 1] == 'h' &&
}
int
+dkim_signature_printheader(struct dkim_session *session, char *header)
+{
+ size_t i, j, len;
+ static char *fmtheader = NULL;
+ char *tmp;
+ static size_t size = 0;
+ int first;
+
+ len = strlen(header);
+ if ((len + 3) * 3 < len) {
+ errno = EOVERFLOW;
+ dkim_err(session, "Can't add z-component to header");
+ return 0;
+ }
+ if ((len + 3) * 3 > size) {
+ if ((tmp = reallocarray(fmtheader, 3, len + 3)) == NULL) {
+ dkim_err(session, "Can't add z-component to header");
+ return 0;
+ }
+ fmtheader = tmp;
+ size = (len + 1) * 3;
+ }
+
+ first = session->signature.signature[session->signature.len - 1] == '=';
+ for (j = i = 0; header[i] != '\0'; i++, j++) {
+ if (i == 0 && header[i] != ' ' && header[i] != '\t' && !first)
+ fmtheader[j++] = '|';
+ if ((header[i] >= 0x21 && header[i] <= 0x3A) ||
+ header[i] == 0x3C ||
+ (header[i] >= 0x3E && header[i] <= 0x7B) ||
+ (header[i] >= 0x7D && header[i] <= 0x7E))
+ fmtheader[j] = header[i];
+ else {
+ fmtheader[j++] = '=';
+ (void) sprintf(fmtheader + j, "%02hhX", header[i]);
+ j++;
+ }
+ }
+ (void) sprintf(fmtheader + j, "=%02hhX=%02hhX", (unsigned char) '\r',
+ (unsigned char) '\n');
+
+ return dkim_signature_printf(session, "%s", fmtheader);
+}
+
+int
dkim_signature_printf(struct dkim_session *session, char *fmt, ...)
{
struct dkim_signature *sig = &(session->signature);