Merge lp:~mlm-author/mailman/2.1-author into lp:mailman/2.1

Proposed by Franck
Status: Merged
Merge reported by: Mark Sapiro
Merged at revision: not available
Proposed branch: lp:~mlm-author/mailman/2.1-author
Merge into: lp:mailman/2.1
Diff against target: 176 lines (+47/-3) (has conflicts)
10 files modified
Mailman/Defaults.py.in (+3/-0)
Mailman/Gui/General.py (+6/-0)
Mailman/Handlers/Cleanse.py (+12/-1)
Mailman/Handlers/CookHeaders.py (+1/-1)
Mailman/MailList.py (+1/-0)
Mailman/versions.py (+4/-0)
NEWS (+8/-0)
contrib/majordomo2mailman.pl (+1/-0)
doc/mailman-admin.txt (+6/-1)
doc/mailman-admin/node10.html (+5/-0)
Text conflict in Mailman/versions.py
Text conflict in NEWS
To merge this branch: bzr merge lp:~mlm-author/mailman/2.1-author
Reviewer Review Type Date Requested Status
Mark Sapiro code Needs Information
Review via email: mp+115035@code.launchpad.net

Description of the change

This change is optional through the use of the author_list variable and is set to off by default. Once set to on, it will use the list address in the From: header changing the display name to indicate who is the author of the post. The email address of the original post will be added to the reply-to field.

Overall, this change allows mailing lists that choose so, to be able to be compatible with authentication schemes such as ADSP or DMARC.

A test list using this branch is at http://lists.peachymango.org/mailman/listinfo/mlm-auth

To post a comment you must log in.
Revision history for this message
Mark Sapiro (msapiro) wrote :

Sorry for not responding to this sooner. Somehow I overlooked the original Mailman-coders notification.

The branch covers almost everything, but it is incomplete:

Mailman.versions.NewVars() needs
        add_only_if_missing('author_list', 0)

Mailman.Version.DATA_FILE_VERSION needs to be incremented.

Most importantly, the code in Cleanse.py has issues:
+ # We change the from so the list takes ownership of the email
+ if mlist.author_list:
+ mlist.include_sender_header = 0
+ if msg['reply-to'] == "" :
+ msg['reply-to'] = msg['reply-to'] + " , " + msg['from']
+ else:
+ msg['reply-to'] = msg['from']

The above test is backwards and it doesn't take into account the fact that msg['reply-to'] is not a null string, but is None if there is no Reply-To: It should be something like:
        if msg['reply-to']:
            msg['reply-to'] = msg['reply-to'] + " , " + msg['from']
        else:
           msg['reply-to'] = msg['from']

+ realname, email = parseaddr(msg['from'])
+ del msg['from']
+ msg['From'] = formataddr(('%s via %s' % (realname,mlist.real_name), mlist.GetListEmail()))
+ del msg['domainkey-signature']
+ del msg['dkim-signature']

The above two headers and any Authentication-Results: header will be removed in current Mailman if REMOVE_DKIM_HEADERS is set to Yes in mm_cfg.py. You might want to rely on that instead of removing them here, particularly because your documentation in Defaults.py.in doesn't mention these.

+ del msg['sender']

In any case, Since this can be merged without changing existing behavior, I'll consider doing it for 2.1.16

review: Needs Fixing
lp:~mlm-author/mailman/2.1-author updated
1341. By Franck

fixes for better merging in main branch

Revision history for this message
Franck (franckm) wrote :

I fixed the code as indicated, the conflicts seems cosmetic.

I removed the deletion of the DKIM and DK headers as there is a setting in cfg for that. Besides they don't create problems as the email can have another valid DKIM header using the domain of the list and the original headers can provide information on the path of the message.

Revision history for this message
Mark Sapiro (msapiro) wrote :

On 07/15/2013 02:35 AM, Franck wrote:
> You have been requested to review the proposed merge of lp:~mlm-author/mailman/2.1-author into lp:mailman/2.1.
>
> For more details, see:
> https://code.launchpad.net/~mlm-author/mailman/2.1-author/+merge/115035

This has turned into a major can of worms. I have attached the patch
that I have so far. Note that I haven't tested it yet. Also, the changes
to the mailman-admin manual aren't included here because those files are
actually derived from
<http://bazaar.launchpad.net/~mailman-administrivia/mailman-administrivia/admin/view/head:/doc/mailman-admin.tex>.

I still have some issues. I have actually changed the semantics of
REMOVE_DKIM_HEADERS so that current behavior is preserved, but there is
no a third option to remove the headers only for author_is_list lists
(and I changed that name to make it more meaningful, at least to me).

My one remaining serious question is the behavior for Sender: I notice
you both remove the original Sender: and set mlist.include_sender_header
= 0. This will actually change the list setting for
include_sender_header. because IncomingRunner will save the updated list
object when it finishes processing the pipeline. I'm not sure this is
appropriate. I think it should be up to the list admin to set this
behavior for the list and not have his choice changed behind his back.
What do you think about that?

Also, I think the code in Cleanse.py really belongs in CookHeaders.py,
but it's tricky because of 'what has precedence' questions, so I didn't
make that change. Another way to do this would be to add another handler
just to do the author_is_list stuff.

--
Mark Sapiro <email address hidden> The highway is for gamblers,
San Francisco Bay Area, California better use your sense - B. Dylan

Revision history for this message
Mark Sapiro (msapiro) wrote :
Download full text (9.7 KiB)

My comment is above (via email) The attached diff got stripped so I'm pasting it here in hopes it will survive:

=== modified file 'Mailman/Defaults.py.in'
--- Mailman/Defaults.py.in 2013-05-20 15:19:19 +0000
+++ Mailman/Defaults.py.in 2013-07-19 00:16:57 +0000
@@ -1,6 +1,6 @@
 # -*- python -*-

-# 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
@@ -548,7 +548,10 @@
 # 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
@@ -1065,6 +1068,10 @@
 # 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

=== modified file 'Mailman/Gui/General.py'
--- Mailman/Gui/General.py 2011-10-04 21:53:13 +0000
+++ Mailman/Gui/General.py 2013-07-19 00:14:55 +0000
@@ -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 @@
                             (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)""")),

=== modified file 'Mailman/Handlers/Cleanse.py'
--- Mailman/Handlers/Cleanse.py 2010-04-09 20:17:07 +0000
+++ Mailman/Handlers/Cleanse.py 2013-07-19 00:18:16 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2010 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2013 by the Free Software Foundation, Inc....

Read more...

review: Needs Information (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Mailman/Defaults.py.in'
--- Mailman/Defaults.py.in 2013-05-20 15:19:19 +0000
+++ Mailman/Defaults.py.in 2013-07-15 08:18:27 +0000
@@ -1065,6 +1065,9 @@
1065# Send goodbye messages to unsubscribed members?1065# Send goodbye messages to unsubscribed members?
1066DEFAULT_SEND_GOODBYE_MSG = Yes1066DEFAULT_SEND_GOODBYE_MSG = Yes
10671067
1068# Change emails so that the list is the author of emails
1069DEFAULT_AUTHOR_LIST = No
1070
1068# Wipe sender information, and make it look like the list-admin1071# Wipe sender information, and make it look like the list-admin
1069# address sends all messages1072# address sends all messages
1070DEFAULT_ANONYMOUS_LIST = No1073DEFAULT_ANONYMOUS_LIST = No
10711074
=== modified file 'Mailman/Gui/General.py'
--- Mailman/Gui/General.py 2011-10-04 21:53:13 +0000
+++ Mailman/Gui/General.py 2013-07-15 08:18:27 +0000
@@ -154,6 +154,12 @@
154 (listname %%05d) -> (listname 00123)154 (listname %%05d) -> (listname 00123)
155 """)),155 """)),
156156
157 ('author_list', mm_cfg.Radio, (_('No'), _('Yes')), 0,
158 _("""Replace the sender with the list address to conform with policies
159 like ADSP and DMARC. It replaces the From to put the list address
160 and modify the Reply-To to keep the reply to post behavior.
161 It is advised to set the MTA to DKIM sign all emails.""")),
162
157 ('anonymous_list', mm_cfg.Radio, (_('No'), _('Yes')), 0,163 ('anonymous_list', mm_cfg.Radio, (_('No'), _('Yes')), 0,
158 _("""Hide the sender of a message, replacing it with the list164 _("""Hide the sender of a message, replacing it with the list
159 address (Removes From, Sender and Reply-To fields)""")),165 address (Removes From, Sender and Reply-To fields)""")),
160166
=== modified file 'Mailman/Handlers/Cleanse.py'
--- Mailman/Handlers/Cleanse.py 2010-04-09 20:17:07 +0000
+++ Mailman/Handlers/Cleanse.py 2013-07-15 08:18:27 +0000
@@ -19,7 +19,7 @@
1919
20import re20import re
2121
22from email.Utils import formataddr22from email.Utils import formataddr, parseaddr
2323
24from Mailman.Utils import unique_message_id24from Mailman.Utils import unique_message_id
25from Mailman.Logging.Syslog import syslog25from Mailman.Logging.Syslog import syslog
@@ -38,6 +38,17 @@
38 del msg['x-approve']38 del msg['x-approve']
39 # Also remove this header since it can contain a password39 # Also remove this header since it can contain a password
40 del msg['urgent']40 del msg['urgent']
41 # We change the from so the list takes ownership of the email
42 if mlist.author_list:
43 mlist.include_sender_header = 0
44 if msg['reply-to'] :
45 msg['reply-to'] = msg['reply-to'] + " , " + msg['from']
46 else:
47 msg['reply-to'] = msg['from']
48 realname, email = parseaddr(msg['from'])
49 del msg['from']
50 msg['From'] = formataddr(('%s via %s' % (realname,mlist.real_name), mlist.GetListEmail()))
51 del msg['sender']
41 # We remove other headers from anonymous lists52 # We remove other headers from anonymous lists
42 if mlist.anonymous_list:53 if mlist.anonymous_list:
43 syslog('post', 'post to %s from %s anonymized',54 syslog('post', 'post to %s from %s anonymized',
4455
=== modified file 'Mailman/Handlers/CookHeaders.py'
--- Mailman/Handlers/CookHeaders.py 2012-06-20 23:32:30 +0000
+++ Mailman/Handlers/CookHeaders.py 2013-07-15 08:18:27 +0000
@@ -159,7 +159,7 @@
159 # Also skip Cc if this is an anonymous list as list posting address159 # Also skip Cc if this is an anonymous list as list posting address
160 # is already in From and Reply-To in this case.160 # is already in From and Reply-To in this case.
161 if mlist.personalize == 2 and mlist.reply_goes_to_list <> 1 \161 if mlist.personalize == 2 and mlist.reply_goes_to_list <> 1 \
162 and not mlist.anonymous_list:162 and not mlist.anonymous_list and not mlist.author_list:
163 # Watch out for existing Cc headers, merge, and remove dups. Note163 # Watch out for existing Cc headers, merge, and remove dups. Note
164 # that RFC 2822 says only zero or one Cc header is allowed.164 # that RFC 2822 says only zero or one Cc header is allowed.
165 new = []165 new = []
166166
=== modified file 'Mailman/MailList.py'
--- Mailman/MailList.py 2012-06-20 23:32:30 +0000
+++ Mailman/MailList.py 2013-07-15 08:18:27 +0000
@@ -347,6 +347,7 @@
347 self.bounce_matching_headers = \347 self.bounce_matching_headers = \
348 mm_cfg.DEFAULT_BOUNCE_MATCHING_HEADERS348 mm_cfg.DEFAULT_BOUNCE_MATCHING_HEADERS
349 self.header_filter_rules = []349 self.header_filter_rules = []
350 self.author_list = mm_cfg.DEFAULT_AUTHOR_LIST
350 self.anonymous_list = mm_cfg.DEFAULT_ANONYMOUS_LIST351 self.anonymous_list = mm_cfg.DEFAULT_ANONYMOUS_LIST
351 internalname = self.internal_name()352 internalname = self.internal_name()
352 self.real_name = internalname[0].upper() + internalname[1:]353 self.real_name = internalname[0].upper() + internalname[1:]
353354
=== modified file 'Mailman/Version.py'
=== modified file 'Mailman/versions.py'
--- Mailman/versions.py 2012-06-20 23:32:30 +0000
+++ Mailman/versions.py 2013-07-15 08:18:27 +0000
@@ -416,8 +416,12 @@
416 mm_cfg.DEFAULT_REGULAR_EXCLUDE_LISTS)416 mm_cfg.DEFAULT_REGULAR_EXCLUDE_LISTS)
417 add_only_if_missing('regular_include_lists',417 add_only_if_missing('regular_include_lists',
418 mm_cfg.DEFAULT_REGULAR_INCLUDE_LISTS)418 mm_cfg.DEFAULT_REGULAR_INCLUDE_LISTS)
419<<<<<<< TREE
419 add_only_if_missing('regular_exclude_ignore',420 add_only_if_missing('regular_exclude_ignore',
420 mm_cfg.DEFAULT_REGULAR_EXCLUDE_IGNORE)421 mm_cfg.DEFAULT_REGULAR_EXCLUDE_IGNORE)
422=======
423 add_only_if_missing('author_list', 0)
424>>>>>>> MERGE-SOURCE
421425
422426
423427
424428
425429
=== modified file 'NEWS'
--- NEWS 2013-07-14 09:10:07 +0000
+++ NEWS 2013-07-15 08:18:27 +0000
@@ -5,6 +5,7 @@
55
6Here is a history of user visible changes to Mailman.6Here is a history of user visible changes to Mailman.
77
8<<<<<<< TREE
82.1.16rc1 (14-Aug-2013)92.1.16rc1 (14-Aug-2013)
910
10 New Features11 New Features
@@ -124,6 +125,13 @@
124 HTML entities. (LP: #1018208)125 HTML entities. (LP: #1018208)
125126
1262.1.15 (13-Jun-2012)1272.1.15 (13-Jun-2012)
128=======
129This Branch
130 -Adding author_list to enable the application of ADSP and DMARC like
131 email policies
132
1332.1.15 (xx-xxx-xxxx)
134>>>>>>> MERGE-SOURCE
127135
128 Security136 Security
129137
130138
=== modified file 'contrib/majordomo2mailman.pl'
--- contrib/majordomo2mailman.pl 2003-01-02 05:25:50 +0000
+++ contrib/majordomo2mailman.pl 2013-07-15 08:18:27 +0000
@@ -480,6 +480,7 @@
480 'max_num_recipients', "10",480 'max_num_recipients', "10",
481 'forbidden_posters', "[]",481 'forbidden_posters', "[]",
482 'bounce_matching_headers', "\"\"\"\n\"\"\"\n",482 'bounce_matching_headers', "\"\"\"\n\"\"\"\n",
483 'author_list', "0",
483 'anonymous_list', "0",484 'anonymous_list', "0",
484 'nondigestable', "1",485 'nondigestable', "1",
485 'digestable', "1",486 'digestable', "1",
486487
=== modified file 'doc/mailman-admin.txt'
--- doc/mailman-admin.txt 2013-07-14 09:10:07 +0000
+++ doc/mailman-admin.txt 2013-07-15 08:18:27 +0000
@@ -329,7 +329,12 @@
329 language. In this case, because of vagarities of the email329 language. In this case, because of vagarities of the email
330 standards, you may or may not want to add a trailing space.330 standards, you may or may not want to add a trailing space.
331331
332 anonymous_list332 author_list
333 This variable allows you to replace the From header with the
334 list address, so that policies like ADSP or DMARC can be
335 applied.
336
337 anonymous_list
333 This variable allows you to turn on some simple anonymizing338 This variable allows you to turn on some simple anonymizing
334 features of Mailman. When you set this option to Yes, Mailman339 features of Mailman. When you set this option to Yes, Mailman
335 will remove or replace the From:, Sender:, and Reply-To: fields340 will remove or replace the From:, Sender:, and Reply-To: fields
336341
=== modified file 'doc/mailman-admin/node10.html'
--- doc/mailman-admin/node10.html 2013-07-14 09:10:07 +0000
+++ doc/mailman-admin/node10.html 2013-07-15 08:18:27 +0000
@@ -140,6 +140,11 @@
140140
141<p>141<p>
142</dd>142</dd>
143<dt><strong>author_list</strong></dt>
144<dd>This variable allows you to replace the From header with the
145 list address, so that policies like ADSP or DMARC can be
146 applied.
147</dd>
143<dt><strong>anonymous_list</strong></dt>148<dt><strong>anonymous_list</strong></dt>
144<dd>This variable allows you to turn on some simple anonymizing149<dd>This variable allows you to turn on some simple anonymizing
145 features of Mailman. When you set this option to <em>Yes</em>,150 features of Mailman. When you set this option to <em>Yes</em>,