aboutsummaryrefslogtreecommitdiff
path: root/Mailman
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2015-04-18 08:04:50 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2015-04-18 08:04:50 +0300
commit0018c8d2531e93883441e8bddab87548f190e176 (patch)
treef97688b299a2f0e181a8b05edcbaf57611160d9e /Mailman
parent37d3720edd2a052e7a0e8b180a0aa7a64355c95b (diff)
downloadmailman-0018c8d2531e93883441e8bddab87548f190e176.tar.gz
mailman-0018c8d2531e93883441e8bddab87548f190e176.tar.bz2
Rewrite sieve filter script
* Mailman/Handlers/Sieve.py: Rewrite using libmu_python * bin/mailsync: Change default location for configuration file. * man/mailsync.1: Update
Diffstat (limited to 'Mailman')
-rw-r--r--Mailman/Handlers/Sieve.py96
1 files changed, 55 insertions, 41 deletions
diff --git a/Mailman/Handlers/Sieve.py b/Mailman/Handlers/Sieve.py
index 9b187a4..077f5ab 100644
--- a/Mailman/Handlers/Sieve.py
+++ b/Mailman/Handlers/Sieve.py
@@ -1,6 +1,5 @@
# GNU Mailutils -- a suite of utilities for electronic mail
-# Copyright (C) 1999, 2000, 2001, 2002, 2003,
-# 2005, 2006, 2007, 2008, 2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2015 Free Software Foundation, Inc.
#
# GNU Mailutils is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -13,62 +12,77 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with GNU Mailutils; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-# MA 02110-1301 USA
+# along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
-"""Filter message through GNU Sieve.
+"""Filter message through GNU Mailutils (sieve)."""
-Since there is no Mailutils module (yet), the sieve binary is invoked
-with `-f -' flag and the message is fed to it. If sieve exits successfully,
-the message is accepted. If it exits with code 1, which means the Sieve
-script used discard, the message is discarded. Otherwise, the message is
-held for approval.
-"""
-
-import string
import os
+import sys
+
+from email.MIMEMessage import MIMEMessage
+from email.MIMEText import MIMEText
-from subprocess import Popen,PIPE
from Mailman import mm_cfg
from Mailman import Errors
+from Mailman import Utils
+from Mailman import Message
from Mailman.Logging.Syslog import syslog
from Mailman.Handlers import Hold
-sieve_program = "/usr/local/bin/sieve"
-sieve_script_dir="/srv/mailman/sieve"
+from mailutils import stream, sieve
+from mailutils.error import SieveMachineError,MU_ERR_PARSE
class SieveDiscard(Errors.DiscardMessage):
- '''The message was discarded by Sieve'''
+ """The message was discarded by Sieve"""
reason = 'Sieve discarded this message'
rejection = 'Your message has been discarded by mail filter'
class SieveHold(Errors.HoldMessage):
- '''The message was held due to Sieve error'''
- def __init__(self, retcode, err):
- Errors.HoldMessage.__init__(self)
- self.reason = 'Your message was held for moderation because of' \
- ' internal software error or misconfiguration.' \
- ' Please, report this to the list owner.'
+ """The message was held due to Sieve error"""
+ reason = 'Your message was held for moderation because of' \
+ ' internal software error or misconfiguration.' \
+ ' Please, report this to the list owner.'
-
def process(mlist, msg, msgdata):
- syslog("post", "begin")
if msgdata.get('approved'):
return
- script = sieve_script_dir + "/" + mlist.internal_name() + '.siv'
- syslog("post", "Using script file %s" % (script))
- if os.path.isfile(script):
- p = Popen([sieve_program, "--program-name", "mailman-sieve", "-f", "-", script], shell=False, stdin=PIPE,
- stdout=PIPE, stderr=PIPE)
- (out,err) = p.communicate(str(msg))
- if p.returncode != 0 and p.returncode != 1:
- syslog("post", "%s returned %d, error=%s"
- % (sieve_program, p.returncode, err))
- if p.returncode == 1:
- raise SieveDiscard
- elif p.returncode != 0:
- Hold.hold_for_approval(mlist, msg, msgdata,
- SieveHold(p.returncode, err))
+ scriptbasename = mlist.internal_name() + '.siv'
+ script = mm_cfg.SIEVE_SCRIPT_DIR + "/" + scriptbasename
+ if not os.path.isfile(script):
+ return
+ syslog("post", "Sieve is using script file %s" % script)
+
+ try:
+ mu_msg = stream.MemoryStream(str(msg)).to_message()
+ mu_sieve = sieve.Machine()
+ mu_sieve.compile(script)
+ mu_sieve.message(mu_msg)
+ except SieveMachineError, e:
+ lang = mlist.preferred_language
+ nmsg = Message.UserNotification(mlist.GetOwnerEmail(),
+ mlist.GetBouncesEmail(),
+ 'Sieve error notification',
+ lang=lang)
+ nmsg.set_type('multipart/mixed')
+ if e.status == MU_ERR_PARSE:
+ text = MIMEText(Utils.wrap('Sieve was unable to compile your script %s. The reason given was as follows:\n\n%s\n\nFor convenience, the failed script is attached herewith.' % (scriptbasename, e.strerror)),
+ charset=Utils.GetCharSet(lang))
+ else:
+ text = 'Sieve failed to execute script %s:\n\n %s.' % \
+ (script, e.strerror)
+ text = MIMEText(Utils.wrap(text),
+ charset=Utils.GetCharSet(lang))
+
+ nmsg.attach(text)
+ nmsg.attach(MIMEText(open(script, 'r').read()))
+
+ nmsg['X-Mailer'] = "Mailman Sieve Processor"
+ nmsg.send(mlist)
+
+ Hold.hold_for_approval(mlist, msg, msgdata, SieveHold)
+
+ except Exception, e:
+ Hold.hold_for_approval(mlist, msg, msgdata, SieveHold)
-
+ if mu_msg.attribute.is_deleted():
+ raise SieveDiscard

Return to:

Send suggestions and report system problems to the System administrator.