Hello user,
I am writing a custom handler to globally ban email address from sending
messages sent to Mailman. I know I can use Mark's add_banned.py script
to add an address to all lists. However, if I add an address to be
banned, as the administrator for all lists, I don't want a list admin to
remove a pest from their list(s). I banned an address for being a pest
to all lists (or a majority of them), therefore, the address stays banned.
Before I put the custom handler in place and screw up my lists, I
thought I would post it here so others more knowledgeable can review it
and let me know if it will work, correct it, and/or improve it.
Thanks,
Chris
--------------------------- Custom Handler Below
-------------------------------
#!/usr/bin/env python
#
"""This is a custom handler that will check all the sender addresses of
a message against a global ban list. If any of the sender addresses are
on the global ban list, the message will get logged and discarded.
"""
import sys
from Mailman import mm_cfg
from Mailman import Utils
from Mailman import Message
from Mailman import Errors
from Mailman.i18n import _
from Mailman.Logging.Syslog import syslog
from Mailman.MailList import MailList
def process(mlist, msg, msgdata):
# added because it was in Mailman/Handlers/Moderate.py
# I am guessing it has to due in part with an upstream
# pipeline handler marking the message approved and/or
# because the handler can be moved to different parts
# of the pipeline.
# But, I have been wrong before.
if msgdata.get('approved') or msgdata.get('fromusenet'):
return
# First, initialize the banlist
banlist = []
# Read in the global ban list of email addresses
# mm_cfg.GLOBALBANLIST_FILENAME is defined in mm_cfg and should
# be the full path to the file.
try:
with open(mm_cfg.GLOBALBANLIST_FILENAME) as f:
for addr in f:
banlist.append(addr.lower().strip())
except IOError:
# cannot open the global ban list for whatever reason
# log it and continue with the next pipeline handler
syslog('error', 'An error occurred opening the global ban list')
return
except:
# unspecified error
# log it and continue with the next pipeline handler
syslog('error', "ERROR: Unknown error: ", sys.exc_info()[0])
return
# Go through possible senders. Check if any of them are
# on the global ban list
for sender in msg.get_senders():
if sender.lower() in banlist:
break
else:
# None of the sender addresses were in the global ban
# list so return and continue with the next pipeline
# handler
return
# A sender was found on the global ban list. Log it and
# discard the message notifying the list owner
if sender:
# Log banned sender to the vette log
syslog('vette', '%s is banned by the global ban list', sender)
# Perform message discard
do_discard_globalban(mlist, msg)
else:
assert 0, 'Bad sender in GlobalBan.py'
# copied almost verbatim from Mailman/Handlers/Moderate.py
def do_discard_globalban(mlist, msg):
sender = msg.get_sender
# forward auto-discards to list owners?
if mlist.forward_auto_discards:
lang = mlist.preferred_language
# is varhelp used anywhere?
varhelp = '%s/?VARHELP=privacy/sender/discard_these_nonmembers' % \
mlist.GetScriptURL('admin', absolute=1)
nmsg = Message.UserNotification(mlist.GetOwnerEmail(),
mlist.GetBouncesEmail(),
_('Global Ban List Auto-discard
notification'),
lang=lang)
nmsg.set_type('multipart/mixed')
text = MIMEText(Utils.wrap(_("""\
The sender of the attached message is on the Global Ban list. Therefore,
the message
has been automatically discarded.""")),
_charset=Utils.GetCharSet(lang))
nmsg.attach(text)
nmsg.attach(MIMEMessage(msg))
nmsg.send(mlist)
# Discard the message
raise Errors.DiscardMessage