aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xmodules/private/mail/filter-rewrite-from.py68
-rw-r--r--modules/private/mail/opensmtpd.nix15
2 files changed, 80 insertions, 3 deletions
diff --git a/modules/private/mail/filter-rewrite-from.py b/modules/private/mail/filter-rewrite-from.py
new file mode 100755
index 0000000..aad9c69
--- /dev/null
+++ b/modules/private/mail/filter-rewrite-from.py
@@ -0,0 +1,68 @@
1#! /usr/bin/env python3
2import sys
3
4sys.stdin.reconfigure(encoding='utf-8')
5sys.stdout.reconfigure(encoding='utf-8')
6stdin = sys.stdin
7stdout = sys.stdout
8
9mailaddr = sys.argv[1]
10inheader = {}
11
12# Change to actual file for logging
13logfile = open("/dev/null", "a")
14
15def log(l, i):
16 logfile.write("{} {}\n".format(i, l))
17 logfile.flush()
18
19def send(l):
20 log(l, ">")
21 stdout.write("{}\n".format(l))
22 stdout.flush()
23
24def token_and_sid(version, sid, token):
25 if version < "0.5":
26 return "{}|{}".format(token, sid)
27 else:
28 return "{}|{}".format(sid, token)
29
30log("started", "l")
31while True:
32 line = stdin.readline().strip()
33 log(line, "<")
34 if not line:
35 log("finished", "l")
36 break
37 splitted = line.split("|")
38 if line == "config|ready":
39 log("in config ready", "l")
40 send("register|filter|smtp-in|mail-from")
41 send("register|filter|smtp-in|data-line")
42 send("register|ready")
43 if splitted[0] != "filter":
44 continue
45 if len(splitted) < 7:
46 send("invalid filter command: expected >6 fields!")
47 sys.exit(1)
48 version = splitted[1]
49 action = splitted[4]
50 sid = splitted[5]
51 token = splitted[6]
52 token_sid = token_and_sid(version, sid, token)
53 rest = "|".join(splitted[7:])
54 if action == "mail-from":
55 inheader[sid] = True
56 send("filter-result|{}|rewrite|<{}>".format(token_sid, mailaddr))
57 continue
58 if action == "data-line":
59 if rest == "" and inheader.get(sid, False):
60 inheader[sid] = False
61 if rest == "." and not inheader.get(sid):
62 del(inheader[sid])
63 if inheader.get(sid, False) and rest.upper().startswith("FROM:"):
64 send("filter-dataline|{}|From: {}".format(token_sid, mailaddr))
65 else:
66 send("filter-dataline|{}|{}".format(token_sid, rest))
67 continue
68 send("filter-result|{}|proceed".format(token_sid))
diff --git a/modules/private/mail/opensmtpd.nix b/modules/private/mail/opensmtpd.nix
index e4a6140..a7be066 100644
--- a/modules/private/mail/opensmtpd.nix
+++ b/modules/private/mail/opensmtpd.nix
@@ -15,12 +15,21 @@
15 users.users.smtpd.extraGroups = [ "keys" ]; 15 users.users.smtpd.extraGroups = [ "keys" ];
16 services.opensmtpd = { 16 services.opensmtpd = {
17 enable = true; 17 enable = true;
18 serverConfiguration = '' 18 serverConfiguration = let
19 filter-rewrite-from = pkgs.runCommand "filter-rewrite-from.py" {
20 buildInputs = [ pkgs.python3 ];
21 } ''
22 cp ${./filter-rewrite-from.py} $out
23 patchShebangs $out
24 '';
25 in ''
19 table creds \ 26 table creds \
20 "${config.secrets.fullPaths."opensmtpd/creds"}" 27 "${config.secrets.fullPaths."opensmtpd/creds"}"
21 # FIXME: filtering requires 6.6 28 # FIXME: filtering requires 6.6, uncomment following lines when
29 # upgrading
22 # filter "fixfrom" \ 30 # filter "fixfrom" \
23 # proc-exec "${pkgs.procmail}/bin/formail -i 'From: ${name}@immae.eu'" 31 # proc-exec "${filter-rewrite-from} ${name}@immae.eu"
32 # listen on socket filter "fixfrom"
24 action "relay-rewrite-from" relay \ 33 action "relay-rewrite-from" relay \
25 helo ${config.hostEnv.fqdn} \ 34 helo ${config.hostEnv.fqdn} \
26 host smtp+tls://eldiron@eldiron.immae.eu:587 \ 35 host smtp+tls://eldiron@eldiron.immae.eu:587 \