--- /dev/null
+#! /usr/bin/env python3
+import sys
+
+sys.stdin.reconfigure(encoding='utf-8')
+sys.stdout.reconfigure(encoding='utf-8')
+stdin = sys.stdin
+stdout = sys.stdout
+
+mailaddr = sys.argv[1]
+inheader = {}
+
+# Change to actual file for logging
+logfile = open("/dev/null", "a")
+
+def log(l, i):
+ logfile.write("{} {}\n".format(i, l))
+ logfile.flush()
+
+def send(l):
+ log(l, ">")
+ stdout.write("{}\n".format(l))
+ stdout.flush()
+
+def token_and_sid(version, sid, token):
+ if version < "0.5":
+ return "{}|{}".format(token, sid)
+ else:
+ return "{}|{}".format(sid, token)
+
+log("started", "l")
+while True:
+ line = stdin.readline().strip()
+ log(line, "<")
+ if not line:
+ log("finished", "l")
+ break
+ splitted = line.split("|")
+ if line == "config|ready":
+ log("in config ready", "l")
+ send("register|filter|smtp-in|mail-from")
+ send("register|filter|smtp-in|data-line")
+ send("register|ready")
+ if splitted[0] != "filter":
+ continue
+ if len(splitted) < 7:
+ send("invalid filter command: expected >6 fields!")
+ sys.exit(1)
+ version = splitted[1]
+ action = splitted[4]
+ sid = splitted[5]
+ token = splitted[6]
+ token_sid = token_and_sid(version, sid, token)
+ rest = "|".join(splitted[7:])
+ if action == "mail-from":
+ inheader[sid] = True
+ send("filter-result|{}|rewrite|<{}>".format(token_sid, mailaddr))
+ continue
+ if action == "data-line":
+ if rest == "" and inheader.get(sid, False):
+ inheader[sid] = False
+ if rest == "." and not inheader.get(sid):
+ del(inheader[sid])
+ if inheader.get(sid, False) and rest.upper().startswith("FROM:"):
+ send("filter-dataline|{}|From: {}".format(token_sid, mailaddr))
+ else:
+ send("filter-dataline|{}|{}".format(token_sid, rest))
+ continue
+ send("filter-result|{}|proceed".format(token_sid))
users.users.smtpd.extraGroups = [ "keys" ];
services.opensmtpd = {
enable = true;
- serverConfiguration = ''
+ serverConfiguration = let
+ filter-rewrite-from = pkgs.runCommand "filter-rewrite-from.py" {
+ buildInputs = [ pkgs.python3 ];
+ } ''
+ cp ${./filter-rewrite-from.py} $out
+ patchShebangs $out
+ '';
+ in ''
table creds \
"${config.secrets.fullPaths."opensmtpd/creds"}"
- # FIXME: filtering requires 6.6
+ # FIXME: filtering requires 6.6, uncomment following lines when
+ # upgrading
# filter "fixfrom" \
- # proc-exec "${pkgs.procmail}/bin/formail -i 'From: ${name}@immae.eu'"
+ # proc-exec "${filter-rewrite-from} ${name}@immae.eu"
+ # listen on socket filter "fixfrom"
action "relay-rewrite-from" relay \
helo ${config.hostEnv.fqdn} \
host smtp+tls://eldiron@eldiron.immae.eu:587 \