diff options
author | Mark Sapiro <msapiro@value.net> | 2014-04-15 12:59:48 -0700 |
---|---|---|
committer | Mark Sapiro <msapiro@value.net> | 2014-04-15 12:59:48 -0700 |
commit | 0d9b1cce5e97fe4095fe2cb72465129437d83b5a (patch) | |
tree | 91ac47389801b2c5c5bb67bbae8a5f45f4f05b0b /Mailman/Handlers | |
parent | 192caa4943eb87e466229736eccefd4381042fd7 (diff) | |
parent | f00ecb3432578156b7f9df2ae33ad5f840e20de6 (diff) | |
download | mailman2-0d9b1cce5e97fe4095fe2cb72465129437d83b5a.tar.gz mailman2-0d9b1cce5e97fe4095fe2cb72465129437d83b5a.tar.xz mailman2-0d9b1cce5e97fe4095fe2cb72465129437d83b5a.zip |
Added and modified various options regarding DMARC. See the NEWS file.
Diffstat (limited to 'Mailman/Handlers')
-rw-r--r-- | Mailman/Handlers/CleanseDKIM.py | 17 | ||||
-rwxr-xr-x | Mailman/Handlers/CookHeaders.py | 10 | ||||
-rw-r--r-- | Mailman/Handlers/Moderate.py | 30 | ||||
-rw-r--r-- | Mailman/Handlers/WrapMessage.py | 5 |
4 files changed, 45 insertions, 17 deletions
diff --git a/Mailman/Handlers/CleanseDKIM.py b/Mailman/Handlers/CleanseDKIM.py index 0df2d97f..5a83a2e0 100644 --- a/Mailman/Handlers/CleanseDKIM.py +++ b/Mailman/Handlers/CleanseDKIM.py @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2006-2014 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -31,11 +31,12 @@ from Mailman import mm_cfg def process(mlist, msg, msgdata): if not mm_cfg.REMOVE_DKIM_HEADERS: return - if (mm_cfg.ALLOW_FROM_IS_LIST and - mm_cfg.REMOVE_DKIM_HEADERS == 1 and - mlist.from_is_list != 1): - return - del msg['domainkey-signature'] - del msg['dkim-signature'] - del msg['authentication-results'] + if (mm_cfg.REMOVE_DKIM_HEADERS == 1 and + (msgdata.get('from_is_list') == 1 or + (mlist.from_is_list == 1 and msgdata.get('from_is_list') != 2) + ) + ): + del msg['domainkey-signature'] + del msg['dkim-signature'] + del msg['authentication-results'] diff --git a/Mailman/Handlers/CookHeaders.py b/Mailman/Handlers/CookHeaders.py index 110302ea..83f278b4 100755 --- a/Mailman/Handlers/CookHeaders.py +++ b/Mailman/Handlers/CookHeaders.py @@ -65,8 +65,8 @@ def uheader(mlist, s, header_name=None, continuation_ws='\t', maxlinelen=None): return Header(s, charset, maxlinelen, header_name, continuation_ws) def change_header(name, value, mlist, msg, msgdata, delete=True, repl=True): - if (mm_cfg.ALLOW_FROM_IS_LIST and - mlist.from_is_list == 2 and + if ((msgdata.get('from_is_list') == 2 or + (msgdata.get('from_is_list') == 0 and mlist.from_is_list == 2)) and not msgdata.get('_fasttrack') ): msgdata.setdefault('add_header', {})[name] = value @@ -119,7 +119,7 @@ def process(mlist, msg, msgdata): change_header('Precedence', 'list', mlist, msg, msgdata, repl=False) # Do we change the from so the list takes ownership of the email - if mm_cfg.ALLOW_FROM_IS_LIST and mlist.from_is_list and not fasttrack: + if (msgdata.get('from_is_list') or mlist.from_is_list) and not fasttrack: realname, email = parseaddr(msg['from']) if not realname: if mlist.isMember(email): @@ -200,8 +200,8 @@ def process(mlist, msg, msgdata): # is already in From and Reply-To in this case and similarly for # a 'from is list' list. if mlist.personalize == 2 and mlist.reply_goes_to_list <> 1 \ - and not mlist.anonymous_list and not (mlist.from_is_list and - mm_cfg.ALLOW_FROM_IS_LIST): + and not mlist.anonymous_list and not (mlist.from_is_list or + msgdata.get('from_is_list')): # Watch out for existing Cc headers, merge, and remove dups. Note # that RFC 2822 says only zero or one Cc header is allowed. new = [] diff --git a/Mailman/Handlers/Moderate.py b/Mailman/Handlers/Moderate.py index 42dffb88..d901eb59 100644 --- a/Mailman/Handlers/Moderate.py +++ b/Mailman/Handlers/Moderate.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2001-2014 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -21,6 +21,7 @@ import re from email.MIMEMessage import MIMEMessage from email.MIMEText import MIMEText +from email.Utils import parseaddr from Mailman import mm_cfg from Mailman import Utils @@ -49,7 +50,32 @@ class ModeratedMemberPost(Hold.ModeratedPost): def process(mlist, msg, msgdata): if msgdata.get('approved'): return - # First of all, is the poster a member or not? + # Before anything else, check DMARC. + msgdata['from_is_list'] = 0 + dn, addr = parseaddr(msg.get('from')) + if addr: + if Utils.IsDMARCProhibited(addr): + # Note that for dmarc_moderation_action, 0 = Accept, + # 1 = Wrap, 2 = Munge, 3 = Reject, 4 = Discard + if mlist.dmarc_moderation_action == 1: + msgdata['from_is_list'] = 2 + elif mlist.dmarc_moderation_action == 2: + msgdata['from_is_list'] = 1 + elif mlist.dmarc_moderation_action == 3: + # Reject + text = mlist.dmarc_moderation_notice + if text: + text = Utils.wrap(text) + else: + text = Utils.wrap(_( +"""You are not allowed to post to this mailing list From: a domain which +publishes a DMARC policy of reject or quarantine, and your message has been +automatically rejected. If you think that your messages are being rejected in +error, contact the mailing list owner at %(listowner)s.""")) + raise Errors.RejectMessage, text + elif mlist.dmarc_moderation_action == 4: + raise Errors.DiscardMessage + # Then, is the poster a member or not? for sender in msg.get_senders(): if mlist.isMember(sender): break diff --git a/Mailman/Handlers/WrapMessage.py b/Mailman/Handlers/WrapMessage.py index 68c89ff2..de981dd6 100644 --- a/Mailman/Handlers/WrapMessage.py +++ b/Mailman/Handlers/WrapMessage.py @@ -1,4 +1,4 @@ -# Copyright (C) 2013 by the Free Software Foundation, Inc. +# Copyright (C) 2013-2014 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -35,7 +35,8 @@ KEEPERS = ('to', def process(mlist, msg, msgdata): - if not mm_cfg.ALLOW_FROM_IS_LIST or mlist.from_is_list != 2: + if not (msgdata.get('from_is_list') == 2 or + (mlist.from_is_list == 2 and msgdata.get('from_is_list') == 0)): return # There are various headers in msg that we don't want, so we basically |