diff options
-rw-r--r-- | Mailman/Handlers/Approve.py | 30 | ||||
-rw-r--r-- | NEWS | 5 |
2 files changed, 34 insertions, 1 deletions
diff --git a/Mailman/Handlers/Approve.py b/Mailman/Handlers/Approve.py index 483ac21c..53fac181 100644 --- a/Mailman/Handlers/Approve.py +++ b/Mailman/Handlers/Approve.py @@ -22,6 +22,8 @@ denied. Situations that could hold a message for approval or confirmation are not tested by this module. """ +import re + from email.Iterators import typed_subpart_iterator from Mailman import mm_cfg @@ -49,6 +51,7 @@ def process(mlist, msg, msgdata): if passwd is missing: # Find the first text/plain part in the message part = None + stripped = False for part in typed_subpart_iterator(msg, 'text', 'plain'): break # XXX I'm not entirely sure why, but it is possible for the payload of @@ -68,7 +71,32 @@ def process(mlist, msg, msgdata): # Now strip the first line from the payload so the # password doesn't leak. del lines[lineno] - part.set_payload(NL.join(lines[0:])) + part.set_payload(NL.join(lines)) + stripped = True + if stripped: + # MAS: Bug 1181161 - Now try all the text parts in case + # it's multipart/alternative with the approved line in + # HTML or other text part. We make a pattern from the + # approved line and delete it from all text/* parts in + # which we find it. It would be better to just iterate + # forward, but email compatability for pre Python 2.2 + # returns a list, not a true iterator. + # This will process all the multipart/alternative parts + # in the message as well as all other text parts. We + # shouldn't find the pattern outside the mp/a parts, but + # if we do, it is probably best to delete it anyway as it + # does contain the password. + # Make a pattern to delete. We can't just delete a line + # because line of HTML or other fancy text may include + # additional message text. This pattern works with HTML. + # It may not work with rtf or whatever else is possible. + pattern = name + ':(\s| )*' + re.escape(passwd) + for part in typed_subpart_iterator(msg, 'text'): + if part is not None and part.get_payload() is not None: + # Should we decode the payload? + lines = part.get_payload() + if re.search(pattern, lines): + part.set_payload(re.sub(pattern, '', lines)) if passwd is not missing and mlist.Authenticate((mm_cfg.AuthListModerator, mm_cfg.AuthListAdmin), passwd): @@ -78,6 +78,11 @@ Here is a history of user visible changes to Mailman. - Stop removing line following Approve(d): line in body of post (1318883). + - Remove Approve(d): <password> from all text/* parts in addition the + initial text/plain part. It still must be the first non-blank line in + the first text/plain part or it won't be found or removed at all + (1181161). + - Log post in post log with true sender, not listname-bounces (1287921). - Correctly initialize and remember the list's default_member_moderation |