From e05c9acce708e8467817e0f3b7367c299c41dc40 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Isma=C3=ABl=20Bouya?= Date: Sun, 23 Feb 2020 14:12:12 +0100 Subject: [PATCH] Prepare script for opensmtpd next upgrade --- modules/private/mail/filter-rewrite-from.py | 68 +++++++++++++++++++++ modules/private/mail/opensmtpd.nix | 15 ++++- 2 files changed, 80 insertions(+), 3 deletions(-) create mode 100755 modules/private/mail/filter-rewrite-from.py 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 @@ +#! /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)) 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 @@ 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 \ -- 2.41.0