From 291f8a457bd31118165065d5940a36135de0fb73 Mon Sep 17 00:00:00 2001 From: Dario Ernst Date: Wed, 9 Jan 2019 11:28:07 +0100 Subject: [PATCH 1/4] Deliver mails to alias-stripped-of-delimeter, even if catchall exists This fixes delivery to an alias minus recipient delimiter in cases where a wildcard alias would also match. For example, * foo@xxx.tld * %@xxx.tld Sending to foo+spam@xxx.tld would get eaten by the catchall before this fix. Now, the order of alias resolution is made clearer. closes #813 --- CHANGELOG.md | 1 + core/admin/mailu/models.py | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac4c83af..5576340c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -111,6 +111,7 @@ v1.6.0 - unreleased - Bug: Fix rainloop permissions ([#637](https://github.com/Mailu/Mailu/issues/637)) - Bug: Fix broken webmail and logo url in admin ([#792](https://github.com/Mailu/Mailu/issues/792)) - Bug: Don't recursivly chown on mailboxes ([#776](https://github.com/Mailu/Mailu/issues/776)) +- Bug: Don't deliver alias and recipient-delimiter to overwhelming wildcard-alias ([#813](https://github.com/Mailu/Mailu/issues/813)) v1.5.1 - 2017-11-21 ------------------- diff --git a/core/admin/mailu/models.py b/core/admin/mailu/models.py index eee351bf..76942c18 100644 --- a/core/admin/mailu/models.py +++ b/core/admin/mailu/models.py @@ -261,14 +261,23 @@ class Email(object): @classmethod def resolve_destination(cls, localpart, domain_name, ignore_forward_keep=False): localpart_stripped = None + stripped_alias = None + if os.environ.get('RECIPIENT_DELIMITER') in localpart: localpart_stripped = localpart.rsplit(os.environ.get('RECIPIENT_DELIMITER'), 1)[0] - alias = Alias.resolve(localpart, domain_name) - if not alias and localpart_stripped: - alias = Alias.resolve(localpart_stripped, domain_name) - if alias: - return alias.destination + pure_alias = Alias.resolve(localpart, domain_name) + has_wildcard = pure_alias and '%' in pure_alias.email and pure_alias.wildcard + stripped_alias = Alias.resolve(localpart_stripped, domain_name) + + if pure_alias and not has_wildcard: + return pure_alias.destination + elif not pure_alias and stripped_alias: + return stripped_alias.destination + elif has_wildcard and localpart_stripped and stripped_alias: + return stripped_alias.destination + elif pure_alias: + return pure_alias.destination user = User.query.get('{}@{}'.format(localpart, domain_name)) if not user and localpart_stripped: From ac64a75743017062e8aa446488f67c307c633da4 Mon Sep 17 00:00:00 2001 From: Dario Ernst Date: Thu, 10 Jan 2019 10:28:57 +0100 Subject: [PATCH 2/4] Simplify alias precedence handling; Remove bogus changelog --- CHANGELOG.md | 1 - core/admin/mailu/models.py | 20 +++++--------------- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5576340c..ac4c83af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -111,7 +111,6 @@ v1.6.0 - unreleased - Bug: Fix rainloop permissions ([#637](https://github.com/Mailu/Mailu/issues/637)) - Bug: Fix broken webmail and logo url in admin ([#792](https://github.com/Mailu/Mailu/issues/792)) - Bug: Don't recursivly chown on mailboxes ([#776](https://github.com/Mailu/Mailu/issues/776)) -- Bug: Don't deliver alias and recipient-delimiter to overwhelming wildcard-alias ([#813](https://github.com/Mailu/Mailu/issues/813)) v1.5.1 - 2017-11-21 ------------------- diff --git a/core/admin/mailu/models.py b/core/admin/mailu/models.py index 76942c18..5115b1c0 100644 --- a/core/admin/mailu/models.py +++ b/core/admin/mailu/models.py @@ -260,24 +260,14 @@ class Email(object): @classmethod def resolve_destination(cls, localpart, domain_name, ignore_forward_keep=False): - localpart_stripped = None - stripped_alias = None - + localpart_maybe_split = localpart if os.environ.get('RECIPIENT_DELIMITER') in localpart: - localpart_stripped = localpart.rsplit(os.environ.get('RECIPIENT_DELIMITER'), 1)[0] + localpart_maybe_split = localpart.rsplit(os.environ.get('RECIPIENT_DELIMITER'), 1)[0] - pure_alias = Alias.resolve(localpart, domain_name) - has_wildcard = pure_alias and '%' in pure_alias.email and pure_alias.wildcard - stripped_alias = Alias.resolve(localpart_stripped, domain_name) + alias = Alias.resolve(localpart_maybe_split, domain_name) - if pure_alias and not has_wildcard: - return pure_alias.destination - elif not pure_alias and stripped_alias: - return stripped_alias.destination - elif has_wildcard and localpart_stripped and stripped_alias: - return stripped_alias.destination - elif pure_alias: - return pure_alias.destination + if alias: + return alias.destination user = User.query.get('{}@{}'.format(localpart, domain_name)) if not user and localpart_stripped: From 10d2601963a2fad0e28d927e062e66c159fc2402 Mon Sep 17 00:00:00 2001 From: Dario Ernst Date: Thu, 10 Jan 2019 17:30:11 +0100 Subject: [PATCH 3/4] Unsimplify alias precedence handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As discussed with hoellen on matrix, since postfix indeed supports including the recipient delimiter character in a verbatim alias, we should support so too — and handle its precedence correctly. The clearer and simpler formulation of the precedence-clauses are credit to @hoellen. Thanks! --- core/admin/mailu/models.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/core/admin/mailu/models.py b/core/admin/mailu/models.py index 5115b1c0..8b7b8d63 100644 --- a/core/admin/mailu/models.py +++ b/core/admin/mailu/models.py @@ -260,14 +260,22 @@ class Email(object): @classmethod def resolve_destination(cls, localpart, domain_name, ignore_forward_keep=False): - localpart_maybe_split = localpart + localpart_stripped = None + stripped_alias = None + if os.environ.get('RECIPIENT_DELIMITER') in localpart: - localpart_maybe_split = localpart.rsplit(os.environ.get('RECIPIENT_DELIMITER'), 1)[0] + localpart_stripped = localpart.rsplit(os.environ.get('RECIPIENT_DELIMITER'), 1)[0] - alias = Alias.resolve(localpart_maybe_split, domain_name) + pure_alias = Alias.resolve(localpart, domain_name) + pure_alias_has_wildcard = pure_alias and '%' in pure_alias.email and pure_alias.wildcard + stripped_alias = Alias.resolve(localpart_stripped, domain_name) - if alias: - return alias.destination + if pure_alias and not pure_alias_has_wildcard: + return pure_alias.destination + elif stripped_alias: + return stripped_alias.destination + elif pure_alias: + return pure_alias.destination user = User.query.get('{}@{}'.format(localpart, domain_name)) if not user and localpart_stripped: From b8d1beed299f881870f992eb13d8c68735c43e85 Mon Sep 17 00:00:00 2001 From: Dario Ernst Date: Thu, 10 Jan 2019 23:06:56 +0100 Subject: [PATCH 4/4] Simplify alias-wildcard detection to not consider actual % anymore --- core/admin/mailu/models.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/admin/mailu/models.py b/core/admin/mailu/models.py index 8b7b8d63..9130ae65 100644 --- a/core/admin/mailu/models.py +++ b/core/admin/mailu/models.py @@ -267,10 +267,9 @@ class Email(object): localpart_stripped = localpart.rsplit(os.environ.get('RECIPIENT_DELIMITER'), 1)[0] pure_alias = Alias.resolve(localpart, domain_name) - pure_alias_has_wildcard = pure_alias and '%' in pure_alias.email and pure_alias.wildcard stripped_alias = Alias.resolve(localpart_stripped, domain_name) - if pure_alias and not pure_alias_has_wildcard: + if pure_alias and not pure_alias.wildcard: return pure_alias.destination elif stripped_alias: return stripped_alias.destination