commit 5fdffb49b9198907d9f91b76cf7128286e175a0a from: Martijn van Duren date: Thu Jan 27 21:56:05 2022 UTC Implement -D file as an easy way to manage multiple domains. Requested by Mischa Peters and Renaud Allard commit - 500ea6d4e3c9b60a442cf1bdd4f493026dcf3a5e commit + 5fdffb49b9198907d9f91b76cf7128286e175a0a blob - 5474b82b07a262e571a2f8e296770e58c895c214 blob + 024829c9ff003efd27ebd99bc42ae8588f09ddc9 --- filter-dkimsign.8 +++ filter-dkimsign.8 @@ -28,6 +28,7 @@ .Op Fl h Ar headers .Op Fl x Ar seconds .Fl d Ar domain +.Fl D Ar file .Fl k Ar file .Fl s Ar selector .Sh DESCRIPTION @@ -51,6 +52,13 @@ Defaults to The canonicalization algorithm used to sign the message. Defaults to .Em simple/simple . +.It Fl D Ar file +.Ar file +should point to a file containing a list of domains. +Only one domain per line should be specified. +See +.Fl d +for more information. .It Fl d Ar domain The .Ar domain blob - 6e3bee7c5f62afa22685453206abc72833040b0a blob + 2961793635330ed82f566e8870166a7f012e7e7a --- main.c +++ main.c @@ -99,6 +99,7 @@ static int sephash = 0; #define DKIM_SIGNATURE_LINELEN 78 void usage(void); +void dkim_adddomain(char *); void dkim_err(struct dkim_message *, char *); void dkim_errx(struct dkim_message *, char *); void dkim_headers_set(char *); @@ -121,10 +122,13 @@ int main(int argc, char *argv[]) { int ch; - FILE *keyfile; + FILE *file; + char *line; + size_t linesz; + ssize_t linelen; const char *errstr; - while ((ch = getopt(argc, argv, "a:c:d:h:k:s:tx:z")) != -1) { + while ((ch = getopt(argc, argv, "a:c:D:d:h:k:s:tx:z")) != -1) { switch (ch) { case 'a': if (strncmp(optarg, "rsa-", 4) == 0) { @@ -163,24 +167,40 @@ main(int argc, char *argv[]) canonbody = CANON_SIMPLE; else osmtpd_err(1, "Invalid canonicalization"); + break; + case 'D': + if ((file = fopen(optarg, "r")) == NULL) + osmtpd_err(1, "Can't open domain file (%s)", + optarg); + do { + line = NULL; + linesz = 0; + linelen = getline(&line, &linesz, file); + if (linelen > 0) { + if (line[linelen - 1] == '\n') + line[linelen - 1] = '\0'; + dkim_adddomain(line); + } + } while (linelen != -1); + if (ferror(file)) + osmtpd_err(1, "Error reading domain file (%s)", + optarg); + fclose(file); break; case 'd': - if ((domain = reallocarray(domain, ndomains + 1, - sizeof(*domain))) == NULL) - osmtpd_err(1, "malloc"); - domain[ndomains++] = optarg; + dkim_adddomain(optarg); break; case 'h': dkim_headers_set(optarg); break; case 'k': - if ((keyfile = fopen(optarg, "r")) == NULL) + if ((file = fopen(optarg, "r")) == NULL) osmtpd_err(1, "Can't open key file (%s)", optarg); - pkey = PEM_read_PrivateKey(keyfile, NULL, NULL, NULL); + pkey = PEM_read_PrivateKey(file, NULL, NULL, NULL); if (pkey == NULL) osmtpd_errx(1, "Can't read key file"); - fclose(keyfile); + fclose(file); break; case 's': selector = optarg; @@ -221,6 +241,16 @@ main(int argc, char *argv[]) osmtpd_run(); return 0; +} + +void +dkim_adddomain(char *d) +{ + domain = reallocarray(domain, ndomains + 1, sizeof(*domain)); + if (domain == NULL) + osmtpd_err(1, "malloc"); + domain[ndomains++] = d; + } void @@ -932,6 +962,6 @@ usage(void) { fprintf(stderr, "usage: filter-dkimsign [-tz] [-a signalg] " "[-c canonicalization] \n [-h headerfields]" - "[-x seconds] -d domain -k keyfile -s selector\n"); + "[-x seconds] -D file -d domain -k keyfile -s selector\n"); exit(1); }