aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Sapiro <msapiro@value.net>2011-02-07 11:59:23 -0800
committerMark Sapiro <msapiro@value.net>2011-02-07 11:59:23 -0800
commitea9bee8858f3a9940412164e0908bc7d12614063 (patch)
tree07dca439b93a936c541426583e2de6c1edb12290
parent0def772b0be9114e58226665941009a9a5566256 (diff)
downloadmailman2-ea9bee8858f3a9940412164e0908bc7d12614063.tar.gz
mailman2-ea9bee8858f3a9940412164e0908bc7d12614063.tar.xz
mailman2-ea9bee8858f3a9940412164e0908bc7d12614063.zip
- A new mm_cfg.py setting RESPONSE_INCLUDE_LEVEL has been added to control
how much of the original message is included in automatic responses to email commands. The default is 2 to preserve the prior behavior of including the full message. Setting this to 1 in mm_cfg.py will include only the original headers, and 0 will include none of the original. It is recommended to set this to 0 in mm_cfg.py to minimize the effects of backscatter. Bug #265835. - A new mm_cfg.py setting DEFAULT_RESPOND_TO_POST_REQUESTS has been added to control the default for respond_to_post_requests for new lists. It is set to Yes for backwards compatibility, but it is recommended that serious consideration be given to setting it to No. Bug #266051. - A new mm_cfg.py setting DISCARD_MESSAGE_WITH_NO_COMMAND has been added to control whether a message to the -request address without any commands or a message to -confirm whose To: address doesn't match VERP_CONFIRM_REGEXP is responded to or just logged. It defaults to Yes which is different from prior behavior. Bug #410236.
-rw-r--r--Mailman/Defaults.py.in34
-rw-r--r--Mailman/MailList.py4
-rw-r--r--Mailman/Queue/CommandRunner.py58
-rw-r--r--NEWS21
4 files changed, 98 insertions, 19 deletions
diff --git a/Mailman/Defaults.py.in b/Mailman/Defaults.py.in
index e1ede271..1bf8362d 100644
--- a/Mailman/Defaults.py.in
+++ b/Mailman/Defaults.py.in
@@ -1,6 +1,6 @@
# -*- python -*-
-# Copyright (C) 1998-2010 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2011 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
@@ -690,7 +690,7 @@ VERP_CONFIRM_FORMAT = '%(addr)s+%(cookie)s'
# To: "local_part@host" <local_part@host>
# and may even fold the header when replying, so we skip everything up to '<'
# if any and include ($s) so dot will match the newline in a folded header.
-VERP_CONFIRM_REGEXP = r'(?s)^(.*<)?(?P<addr>.+)\+(?P<cookie>[^@+]+)@.*$'
+VERP_CONFIRM_REGEXP = r'(?s)^(.*<)?(?P<addr>.+)\+(?P<cookie>[0-9a-f]{40})@.*$'
# Set this to Yes to enable VERP-like (more user friendly) confirmations
VERP_CONFIRMATIONS = No
@@ -707,6 +707,36 @@ MAX_AUTORESPONSES_PER_DAY = 10
#####
+# Backscatter mitigation
+#####
+
+# This controls whether a message to the -request address without any
+# commands or a message to -confirm whose To: address doesn't match
+# VERP_CONFIRM_REGEXP above is responded to or just logged.
+DISCARD_MESSAGE_WITH_NO_COMMAND = Yes
+
+# This controls how much of the original message is included in automatic
+# responses to email commands. The values are:
+# 0 - Do not include any unprocessed or ignored commands. Do not include
+# the original message.
+# 1 - Do not include any unprocessed or ignored commands. Include only the
+# headers from the original message.
+# 2 - Include unprocessed and ignored commands. Include the complete original
+# message.
+#
+# In order to minimize the effect of backscatter due to spam sent to
+# administrative addresses, it is recommended to set this to 0, however the
+# default is 2 for backwards compatibility.
+RESPONSE_INCLUDE_LEVEL = 2
+
+# This sets the default for respond_to_post_requests for new lists. It is
+# set to Yes for backwards compatibility, but it is recommended that serious
+# consideration be given to setting it to No.
+DEFAULT_RESPOND_TO_POST_REQUESTS = Yes
+
+
+
+#####
# Qrunner defaults
#####
diff --git a/Mailman/MailList.py b/Mailman/MailList.py
index a7efd986..504effa7 100644
--- a/Mailman/MailList.py
+++ b/Mailman/MailList.py
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2010 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2011 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
@@ -314,7 +314,7 @@ class MailList(HTMLFormatter, Deliverer, ListAdmin,
self.new_member_options = mm_cfg.DEFAULT_NEW_MEMBER_OPTIONS
# This stuff is configurable
- self.respond_to_post_requests = 1
+ self.respond_to_post_requests = mm_cfg.DEFAULT_RESPOND_TO_POST_REQUESTS
self.advertised = mm_cfg.DEFAULT_LIST_ADVERTISED
self.max_num_recipients = mm_cfg.DEFAULT_MAX_NUM_RECIPIENTS
self.max_message_size = mm_cfg.DEFAULT_MAX_MESSAGE_SIZE
diff --git a/Mailman/Queue/CommandRunner.py b/Mailman/Queue/CommandRunner.py
index 3155f22f..b63b050c 100644
--- a/Mailman/Queue/CommandRunner.py
+++ b/Mailman/Queue/CommandRunner.py
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2010 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2011 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
@@ -46,6 +46,10 @@ from email.MIMEText import MIMEText
from email.MIMEMessage import MIMEMessage
NL = '\n'
+CONTINUE = 0
+STOP = 1
+BADCMD = 2
+BADSUBJ = 3
try:
True, False
@@ -105,15 +109,19 @@ class Results:
def process(self):
# Now, process each line until we find an error. The first
# non-command line found stops processing.
- stop = False
+ found = BADCMD
+ ret = CONTINUE
for line in self.commands:
if line and line.strip():
args = line.split()
cmd = args.pop(0).lower()
- stop = self.do_command(cmd, args)
+ ret = self.do_command(cmd, args)
+ if ret == STOP or ret == CONTINUE:
+ found = ret
self.lineno += 1
- if stop:
+ if ret == STOP or ret == BADCMD:
break
+ return found
def do_command(self, cmd, args=None):
if args is None:
@@ -136,8 +144,14 @@ class Results:
self.subjcmdretried += 1
cmd = args.pop(0)
return self.do_command(cmd, args)
- return self.lineno <> 0
- return handler.process(self, args)
+ if self.lineno <> 0:
+ return BADCMD
+ else:
+ return BADSUBJ
+ if handler.process(self, args):
+ return STOP
+ else:
+ return CONTINUE
def send_response(self):
# Helper
@@ -156,7 +170,7 @@ Attached is your original message.
# Ignore empty lines
unprocessed = [line for line in self.commands[self.lineno:]
if line and line.strip()]
- if unprocessed:
+ if unprocessed and mm_cfg.RESPONSE_INCLUDE_LEVEL >= 2:
resp.append(_('\n- Unprocessed:'))
resp.extend(indent(unprocessed))
if not unprocessed and not self.results:
@@ -165,7 +179,7 @@ Attached is your original message.
No commands were found in this message.
To obtain instructions, send a message containing just the word "help".
""")))
- if self.ignored:
+ if self.ignored and mm_cfg.RESPONSE_INCLUDE_LEVEL >= 2:
resp.append(_('\n- Ignored:'))
resp.extend(indent(self.ignored))
resp.append(_('\n- Done.\n\n'))
@@ -196,7 +210,15 @@ To obtain instructions, send a message containing just the word "help".
lang=self.msgdata['lang'])
msg.set_type('multipart/mixed')
msg.attach(results)
- orig = MIMEMessage(self.msg)
+ if mm_cfg.RESPONSE_INCLUDE_LEVEL == 1:
+ self.msg.set_payload(
+ _('Message body suppressed by Mailman site configuration\n'))
+ if mm_cfg.RESPONSE_INCLUDE_LEVEL == 0:
+ orig = MIMEText(_(
+ 'Original message suppressed by Mailman site configuration\n'
+ ), _charset=charset)
+ else:
+ orig = MIMEMessage(self.msg)
msg.attach(orig)
msg.send(self.mlist)
@@ -236,17 +258,23 @@ class CommandRunner(Runner):
# mylist-join, or mylist-leave, and the message metadata will contain
# a key to which one was used.
try:
+ ret = BADCMD
if msgdata.get('torequest'):
- res.process()
+ ret = res.process()
elif msgdata.get('tojoin'):
- res.do_command('join')
+ ret = res.do_command('join')
elif msgdata.get('toleave'):
- res.do_command('leave')
+ ret = res.do_command('leave')
elif msgdata.get('toconfirm'):
mo = re.match(mm_cfg.VERP_CONFIRM_REGEXP, msg.get('to', ''))
if mo:
- res.do_command('confirm', (mo.group('cookie'),))
- res.send_response()
- mlist.Save()
+ ret = res.do_command('confirm', (mo.group('cookie'),))
+ if ret == BADCMD and mm_cfg.DISCARD_MESSAGE_WITH_NO_COMMAND:
+ syslog('vette',
+ 'No command, message discarded, msgid: %s',
+ msg.get('message-id', 'n/a'))
+ else:
+ res.send_response()
+ mlist.Save()
finally:
mlist.Unlock()
diff --git a/NEWS b/NEWS
index 890e8185..c433caef 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,27 @@ Here is a history of user visible changes to Mailman.
2.1.15 (xx-xxx-xxxx)
+ New Features
+
+ - A new mm_cfg.py setting RESPONSE_INCLUDE_LEVEL has been added to control
+ how much of the original message is included in automatic responses to
+ email commands. The default is 2 to preserve the prior behavior of
+ including the full message. Setting this to 1 in mm_cfg.py will include
+ only the original headers, and 0 will include none of the original. It
+ is recommended to set this to 0 in mm_cfg.py to minimize the effects of
+ backscatter. Bug #265835.
+
+ - A new mm_cfg.py setting DEFAULT_RESPOND_TO_POST_REQUESTS has been added
+ to control the default for respond_to_post_requests for new lists. It is
+ set to Yes for backwards compatibility, but it is recommended that
+ serious consideration be given to setting it to No. Bug #266051.
+
+ - A new mm_cfg.py setting DISCARD_MESSAGE_WITH_NO_COMMAND has been added to
+ control whether a message to the -request address without any commands or
+ a message to -confirm whose To: address doesn't match VERP_CONFIRM_REGEXP
+ is responded to or just logged. It defaults to Yes which is different
+ from prior behavior. Bug #410236.
+
i18n
- Fixed a missing format character in the Spanish translation.