From bd69b7a4915cb1841adf700003018b07f7a260ad Mon Sep 17 00:00:00 2001 From: kaiyou Date: Tue, 14 Jan 2020 01:18:30 +0100 Subject: [PATCH 1/2] Add support for SRS, related to #328 --- core/admin/mailu/internal/views/postfix.py | 33 ++++++++++++++++++++++ core/admin/requirements-prod.txt | 1 + core/admin/requirements.txt | 1 + core/postfix/conf/main.cf | 7 ++++- core/postfix/start.py | 2 ++ 5 files changed, 43 insertions(+), 1 deletion(-) diff --git a/core/admin/mailu/internal/views/postfix.py b/core/admin/mailu/internal/views/postfix.py index 21a4aa91..76d33fca 100644 --- a/core/admin/mailu/internal/views/postfix.py +++ b/core/admin/mailu/internal/views/postfix.py @@ -3,6 +3,7 @@ from mailu.internal import internal import flask import re +import srslib @internal.route("/postfix/domain/") @@ -39,6 +40,38 @@ def postfix_transport(email): return flask.jsonify("smtp:[{}]".format(relay.smtp)) +@internal.route("/postfix/recipient/map/") +def postfix_recipient_map(recipient): + """ Rewrite the envelope recipient if it is a valid SRS address. + + This is meant for bounces to go back to the original sender. + """ + srs = srslib.SRS(flask.current_app.config["SECRET_KEY"]) + if srslib.SRS.is_srs_address(recipient): + try: + return flask.jsonify(srs.reverse(recipient)) + except srslib.Error as error: + return flask.abort(404) + return flask.abort(404) + + +@internal.route("/postfix/sender/map/") +def postfix_sender_map(sender): + """ Rewrite the envelope sender in case the mail was not emitted by us. + + This is for bounces to come back the reverse path properly. + """ + srs = srslib.SRS(flask.current_app.config["SECRET_KEY"]) + domain = flask.current_app.config["DOMAIN"] + try: + localpart, domain_name = models.Email.resolve_domain(sender) + except Exception as error: + return flask.abort(404) + if models.Domain.query.get(domain_name): + return flask.abort(404) + return flask.jsonify(srs.forward(sender, domain)) + + @internal.route("/postfix/sender/login/") def postfix_sender_login(sender): localpart, domain_name = models.Email.resolve_domain(sender) diff --git a/core/admin/requirements-prod.txt b/core/admin/requirements-prod.txt index e61eebfd..1fcffbcd 100644 --- a/core/admin/requirements-prod.txt +++ b/core/admin/requirements-prod.txt @@ -41,6 +41,7 @@ redis==3.2.1 six==1.12.0 socrate==0.1.1 SQLAlchemy==1.3.3 +srslib==0.1.4 tabulate==0.8.3 tenacity==5.0.4 validators==0.12.5 diff --git a/core/admin/requirements.txt b/core/admin/requirements.txt index c68130db..d0515b52 100644 --- a/core/admin/requirements.txt +++ b/core/admin/requirements.txt @@ -22,3 +22,4 @@ tenacity mysqlclient psycopg2 idna +srslib diff --git a/core/postfix/conf/main.cf b/core/postfix/conf/main.cf index 0790946d..8b4b11ac 100644 --- a/core/postfix/conf/main.cf +++ b/core/postfix/conf/main.cf @@ -75,6 +75,12 @@ relay_domains = ${podop}transport transport_maps = ${podop}transport virtual_transport = lmtp:inet:{{ LMTP_ADDRESS }} +# Sender and recipient canonical maps, mostly for SRS +sender_canonical_maps = ${podop}sendermap +sender_canonical_classes = envelope_sender +recipient_canonical_maps = ${podop}recipientmap +recipient_canonical_classes= envelope_recipient,header_recipient + # In order to prevent Postfix from running DNS query, enforce the use of the # native DNS stack, that will check /etc/hosts properly. lmtp_host_lookup = native @@ -120,4 +126,3 @@ milter_default_action = tempfail ############### # Extra Settings ############### - diff --git a/core/postfix/start.py b/core/postfix/start.py index 7523bb4d..12aaa770 100755 --- a/core/postfix/start.py +++ b/core/postfix/start.py @@ -21,6 +21,8 @@ def start_podop(): ("alias", "url", url + "alias/§"), ("domain", "url", url + "domain/§"), ("mailbox", "url", url + "mailbox/§"), + ("recipientmap", "url", url + "recipient/map/§"), + ("sendermap", "url", url + "sender/map/§"), ("senderaccess", "url", url + "sender/access/§"), ("senderlogin", "url", url + "sender/login/§") ]) From 6ad9b7c2b2498866551399fcc227dd7ebadb6900 Mon Sep 17 00:00:00 2001 From: kaiyou Date: Fri, 7 Feb 2020 15:17:29 +0100 Subject: [PATCH 2/2] Add a newsfragment --- towncrier/newsfragments/328.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 towncrier/newsfragments/328.feature diff --git a/towncrier/newsfragments/328.feature b/towncrier/newsfragments/328.feature new file mode 100644 index 00000000..b73b478e --- /dev/null +++ b/towncrier/newsfragments/328.feature @@ -0,0 +1 @@ +Add support for backward-forwarding using SRS \ No newline at end of file