aboutsummaryrefslogtreecommitdiffstats
path: root/Mailman/Handlers
diff options
context:
space:
mode:
authorMark Sapiro <msapiro@value.net>2014-04-15 12:59:48 -0700
committerMark Sapiro <msapiro@value.net>2014-04-15 12:59:48 -0700
commit0d9b1cce5e97fe4095fe2cb72465129437d83b5a (patch)
tree91ac47389801b2c5c5bb67bbae8a5f45f4f05b0b /Mailman/Handlers
parent192caa4943eb87e466229736eccefd4381042fd7 (diff)
parentf00ecb3432578156b7f9df2ae33ad5f840e20de6 (diff)
downloadmailman2-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.py17
-rwxr-xr-xMailman/Handlers/CookHeaders.py10
-rw-r--r--Mailman/Handlers/Moderate.py30
-rw-r--r--Mailman/Handlers/WrapMessage.py5
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