aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xMailman/Defaults.py.in9
-rw-r--r--Mailman/Gui/General.py10
-rw-r--r--Mailman/Handlers/Cleanse.py24
-rw-r--r--Mailman/Handlers/CleanseDKIM.py13
-rwxr-xr-xMailman/Handlers/CookHeaders.py7
-rwxr-xr-xMailman/MailList.py3
-rw-r--r--Mailman/Version.py4
-rwxr-xr-xMailman/versions.py4
-rwxr-xr-xNEWS7
-rw-r--r--contrib/import_majordomo_into_mailman.pl1
-rw-r--r--contrib/majordomo2mailman.pl1
11 files changed, 67 insertions, 16 deletions
diff --git a/Mailman/Defaults.py.in b/Mailman/Defaults.py.in
index f1a5d907..f87f6665 100755
--- a/Mailman/Defaults.py.in
+++ b/Mailman/Defaults.py.in
@@ -552,7 +552,10 @@ NNTP_REWRITE_DUPLICATE_HEADERS = [
# footer or scrubbing attachments or even reply-to munging can break these
# signatures. It is generally felt that these signatures have value, even if
# broken and even if the outgoing message is resigned. However, some sites
-# may wish to remove these headers by setting this to Yes.
+# may wish to remove these headers. Possible values and meanings are:
+# No, 0, False -> do not remove headers.
+# 1 -> remove headers only if the list's author_is_list setting is Yes.
+# Yes, 2, True -> always remove headers.
REMOVE_DKIM_HEADERS = No
# All `normal' messages which are delivered to the entire list membership go
@@ -1069,6 +1072,10 @@ DEFAULT_SEND_WELCOME_MSG = Yes
# Send goodbye messages to unsubscribed members?
DEFAULT_SEND_GOODBYE_MSG = Yes
+# Rewrite the From: header of posts replacing the posters address with
+# that of the list. Also see REMOVE_DKIM_HEADERS above.
+DEFAULT_AUTHOR_IS_LIST = No
+
# Wipe sender information, and make it look like the list-admin
# address sends all messages
DEFAULT_ANONYMOUS_LIST = No
diff --git a/Mailman/Gui/General.py b/Mailman/Gui/General.py
index e9f8f9b5..53f2e908 100644
--- a/Mailman/Gui/General.py
+++ b/Mailman/Gui/General.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2001-2011 by the Free Software Foundation, Inc.
+# Copyright (C) 2001-2013 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
@@ -154,6 +154,14 @@ class General(GUIBase):
(listname %%05d) -> (listname 00123)
""")),
+ ('author_is_list', mm_cfg.Radio, (_('No'), _('Yes')), 0,
+ _("""Replace the sender with the list address to conform with
+ policies like ADSP and DMARC. It replaces the poster's address
+ in the From: header with the list address and adds the poster to
+ the Reply-To: header, but the anonymous_list and Reply-To: header
+ munging settings below take priority. If setting this to Yes,
+ it is advised to set the MTA to DKIM sign all emails.""")),
+
('anonymous_list', mm_cfg.Radio, (_('No'), _('Yes')), 0,
_("""Hide the sender of a message, replacing it with the list
address (Removes From, Sender and Reply-To fields)""")),
diff --git a/Mailman/Handlers/Cleanse.py b/Mailman/Handlers/Cleanse.py
index 725cb41b..678f6b56 100644
--- a/Mailman/Handlers/Cleanse.py
+++ b/Mailman/Handlers/Cleanse.py
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2010 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2013 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
@@ -19,7 +19,7 @@
import re
-from email.Utils import formataddr
+from email.Utils import formataddr, getaddresses, parseaddr
from Mailman.Utils import unique_message_id
from Mailman.Logging.Syslog import syslog
@@ -38,6 +38,26 @@ def process(mlist, msg, msgdata):
del msg['x-approve']
# Also remove this header since it can contain a password
del msg['urgent']
+ # Do we change the from so the list takes ownership of the email
+ # This really belongs in CookHeaders.
+ if mlist.author_is_list:
+ realname, email = parseaddr(msg['from'])
+ replies = getaddresses(msg.get('reply-to', ''))
+ reply_addrs = [x[1].lower() for x in replies]
+ if reply_addrs:
+ if email.lower() not in reply_addrs:
+ rt = msg['reply-to'] + ', ' + msg['from']
+ else:
+ rt = msg['reply-to']
+ else:
+ rt = msg['from']
+ del msg['reply-to']
+ msg['Reply-To'] = rt
+ del msg['from']
+ msg['From'] = formataddr(('%s via %s' % (realname, mlist.real_name),
+ mlist.GetListEmail()))
+ del msg['sender']
+ #MAS mlist.include_sender_header = 0
# We remove other headers from anonymous lists
if mlist.anonymous_list:
syslog('post', 'post to %s from %s anonymized',
diff --git a/Mailman/Handlers/CleanseDKIM.py b/Mailman/Handlers/CleanseDKIM.py
index c4b06613..3a157890 100644
--- a/Mailman/Handlers/CleanseDKIM.py
+++ b/Mailman/Handlers/CleanseDKIM.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2006-2007 by the Free Software Foundation, Inc.
+# Copyright (C) 2006-2013 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
@@ -29,8 +29,11 @@ from Mailman import mm_cfg
def process(mlist, msg, msgdata):
- if mm_cfg.REMOVE_DKIM_HEADERS:
- del msg['domainkey-signature']
- del msg['dkim-signature']
- del msg['authentication-results']
+ if not mm_cfg.REMOVE_DKIM_HEADERS:
+ return
+ if mm_cfg.REMOVE_DKIM_HEADERS == 1 and not mlist.author_is_list:
+ return
+ 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 a2096172..7455dcc6 100755
--- a/Mailman/Handlers/CookHeaders.py
+++ b/Mailman/Handlers/CookHeaders.py
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2011 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2013 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
@@ -157,9 +157,10 @@ def process(mlist, msg, msgdata):
# Cc header. BAW: should we force it into a Reply-To header in the
# above code?
# Also skip Cc if this is an anonymous list as list posting address
- # is already in From and Reply-To in this case.
+ # is already in From and Reply-To in this case and similarly for
+ # an 'author is list' list.
if mlist.personalize == 2 and mlist.reply_goes_to_list <> 1 \
- and not mlist.anonymous_list:
+ and not mlist.anonymous_list and not mlist.author_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/MailList.py b/Mailman/MailList.py
index 2d653acb..afb1ce15 100755
--- a/Mailman/MailList.py
+++ b/Mailman/MailList.py
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2012 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2013 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
@@ -347,6 +347,7 @@ class MailList(HTMLFormatter, Deliverer, ListAdmin,
self.bounce_matching_headers = \
mm_cfg.DEFAULT_BOUNCE_MATCHING_HEADERS
self.header_filter_rules = []
+ self.author_is_list = mm_cfg.DEFAULT_AUTHOR_IS_LIST
self.anonymous_list = mm_cfg.DEFAULT_ANONYMOUS_LIST
internalname = self.internal_name()
self.real_name = internalname[0].upper() + internalname[1:]
diff --git a/Mailman/Version.py b/Mailman/Version.py
index 801a614a..bda02592 100644
--- a/Mailman/Version.py
+++ b/Mailman/Version.py
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2011 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2013 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
@@ -37,7 +37,7 @@ HEX_VERSION = ((MAJOR_REV << 24) | (MINOR_REV << 16) | (MICRO_REV << 8) |
(REL_LEVEL << 4) | (REL_SERIAL << 0))
# config.pck schema version number
-DATA_FILE_VERSION = 100
+DATA_FILE_VERSION = 101
# qfile/*.db schema version number
QFILE_SCHEMA_VERSION = 3
diff --git a/Mailman/versions.py b/Mailman/versions.py
index 84943efc..e731d33c 100755
--- a/Mailman/versions.py
+++ b/Mailman/versions.py
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2011 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2013 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
@@ -418,6 +418,8 @@ def NewVars(l):
mm_cfg.DEFAULT_REGULAR_INCLUDE_LISTS)
add_only_if_missing('regular_exclude_ignore',
mm_cfg.DEFAULT_REGULAR_EXCLUDE_IGNORE)
+ add_only_if_missing('author_is_list',
+ mm_cfg.DEFAULT_AUTHOR_IS_LIST)
diff --git a/NEWS b/NEWS
index 07a06091..c82cdec2 100755
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,13 @@ Here is a history of user visible changes to Mailman.
New Features
+ - There is a new list attribute author_is_list to rewrite the From: header
+ of posts replacing the posters address with that of the list for
+ compatability with DMARC and or ADSP. There is a new mm_cfg.py setting
+ DEFAULT_AUTHOR_IS_LIST to control the default for new lists, and the
+ existing REMOVE_DKIM_HEADERS setting has been extended to allow removing
+ those headers only for author_is_list = Yes lists.
+
- There is a new DISPLAY_HELD_SUMMARY_SORT_BUTTONS setting which if set
to Yes in mm_cfg.py will display a set of radio buttons in the admindb
held message summary to select how the held messages are sorted and
diff --git a/contrib/import_majordomo_into_mailman.pl b/contrib/import_majordomo_into_mailman.pl
index 604546bb..e157ce24 100644
--- a/contrib/import_majordomo_into_mailman.pl
+++ b/contrib/import_majordomo_into_mailman.pl
@@ -909,6 +909,7 @@ sub getMailmanConfig {
'administrivia' => 'True',
'advertised' => 1,
'anonymous_list' => 'False',
+ 'author_is_list' => 'False',
# NOTE: some may wish to map some Majordomo setting, such as index_access
# to Mailman's archive. As is, all archiving is turned off for imported
# lists.
diff --git a/contrib/majordomo2mailman.pl b/contrib/majordomo2mailman.pl
index c874862e..3e54a3ac 100644
--- a/contrib/majordomo2mailman.pl
+++ b/contrib/majordomo2mailman.pl
@@ -480,6 +480,7 @@ sub init_defaultmmconf {
'max_num_recipients', "10",
'forbidden_posters', "[]",
'bounce_matching_headers', "\"\"\"\n\"\"\"\n",
+ 'author_is_list', "0",
'anonymous_list', "0",
'nondigestable', "1",
'digestable', "1",