diff options
Diffstat (limited to '')
-rw-r--r-- | Mailman/Cgi/admin.py | 5 | ||||
-rw-r--r-- | Mailman/Cgi/admindb.py | 9 | ||||
-rw-r--r-- | Mailman/Cgi/confirm.py | 13 | ||||
-rw-r--r-- | Mailman/Cgi/options.py | 5 | ||||
-rw-r--r-- | Mailman/MailList.py | 82 |
5 files changed, 88 insertions, 26 deletions
diff --git a/Mailman/Cgi/admin.py b/Mailman/Cgi/admin.py index eb63e008..b75ff2df 100644 --- a/Mailman/Cgi/admin.py +++ b/Mailman/Cgi/admin.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2004 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2005 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 @@ -1345,6 +1345,9 @@ def change_options(mlist, category, subcat, cgidata, doc): except Errors.MMHostileAddress: subscribe_errors.append( (entry, _('Hostile address (illegal characters)'))) + except Errors.MembershipIsBanned, pattern: + subscribe_errors.append( + (entry, _('Banned address (matched %(pattern)s)'))) else: member = Utils.uncanonstr(formataddr((fullname, address))) subscribe_success.append(Utils.websafe(member)) diff --git a/Mailman/Cgi/admindb.py b/Mailman/Cgi/admindb.py index 1dd0e28a..3f421cfe 100644 --- a/Mailman/Cgi/admindb.py +++ b/Mailman/Cgi/admindb.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2004 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2005 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 @@ -745,6 +745,7 @@ def process_form(mlist, doc, cgidata): if sender not in mlist.ban_list: mlist.ban_list.append(sender) # Now, do message specific actions + banaddrs = [] erroraddrs = [] for k in cgidata.keys(): formv = cgidata[k] @@ -794,8 +795,14 @@ def process_form(mlist, doc, cgidata): continue except Errors.MMAlreadyAMember, v: erroraddrs.append(v) + except Errors.MembershipIsBanned, pattern: + sender = mlist.GetRecord(request_id)[1] + banaddrs.append((sender, pattern)) # save the list and print the results doc.AddItem(Header(2, _('Database Updated...'))) if erroraddrs: for addr in erroraddrs: doc.AddItem(`addr` + _(' is already a member') + '<br>') + if banaddrs: + for addr, patt in banaddrs: + doc.AddItem(_('%(addr)s is banned (matched: %(patt)s)') + '<br>') diff --git a/Mailman/Cgi/confirm.py b/Mailman/Cgi/confirm.py index d2cf0cce..6238e72a 100644 --- a/Mailman/Cgi/confirm.py +++ b/Mailman/Cgi/confirm.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2004 by the Free Software Foundation, Inc. +# Copyright (C) 2001-2005 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 @@ -370,6 +370,11 @@ def subscription_confirm(mlist, doc, cookie, cgidata): address that has already been unsubscribed.''')) except Errors.MMAlreadyAMember: doc.addError(_("You are already a member of this mailing list!")) + except Errors.MembershipIsBanned: + owneraddr = mlist.GetOwnerEmail() + doc.addError(_("""You are currently banned from subscribing to + this list. If you think this restriction is erroneous, please + contact the list owners at %(owneraddr)s.""")) except Errors.HostileSubscriptionError: doc.addError(_("""\ You were not invited to this mailing list. The invitation has @@ -517,6 +522,12 @@ def addrchange_confirm(mlist, doc, cookie): bad_confirmation(doc, _('''Invalid confirmation string. It is possible that you are attempting to confirm a request for an address that has already been unsubscribed.''')) + except Errors.MembershipIsBanned: + owneraddr = mlist.GetOwnerEmail() + realname = mlist.real_name + doc.addError(_("""%(newaddr)s is banned from subscribing to the + %(realname)s list. If you think this restriction is erroneous, + please contact the list owners at %(owneraddr)s.""")) else: # The response listname = mlist.real_name diff --git a/Mailman/Cgi/options.py b/Mailman/Cgi/options.py index ed40e828..eb7adb67 100644 --- a/Mailman/Cgi/options.py +++ b/Mailman/Cgi/options.py @@ -399,6 +399,11 @@ address. Upon confirmation, any other mailing list containing the address msg = _('Illegal email address provided') except Errors.MMAlreadyAMember: msg = _('%(newaddr)s is already a member of the list.') + except Errors.MembershipIsBanned: + owneraddr = mlist.GetOwnerEmail() + msg = _("""%(newaddr)s is banned from this list. If you + think this restriction is erroneous, please contact + the list owners at %(owneraddr)s.""") if set_membername: mlist.Lock() diff --git a/Mailman/MailList.py b/Mailman/MailList.py index 0a52567d..cf07c842 100644 --- a/Mailman/MailList.py +++ b/Mailman/MailList.py @@ -764,6 +764,10 @@ class MailList(HTMLFormatter, Deliverer, ListAdmin, """ invitee = userdesc.address Utils.ValidateEmail(invitee) + # check for banned address + pattern = self.GetBannedPattern(invitee) + if pattern: + raise Errors.MembershipIsBanned, pattern # Hack alert! Squirrel away a flag that only invitations have, so # that we can do something slightly different when an invitation # subscription is confirmed. In those cases, we don't need further @@ -837,29 +841,13 @@ class MailList(HTMLFormatter, Deliverer, ListAdmin, if email.lower() == self.GetListEmail().lower(): # Trying to subscribe the list to itself! raise Errors.MMBadEmailError - + realname = self.real_name # Is the subscribing address banned from this list? - ban = 0 - for pattern in self.ban_list: - if pattern.startswith('^'): - # This is a regular expression match - try: - if re.search(pattern, email, re.IGNORECASE): - ban = 1 - break - except re.error: - # BAW: we should probably remove this pattern - pass - else: - # Do the comparison case insensitively - if pattern.lower() == email.lower(): - ban = 1 - break - if ban: - syslog('vette', 'banned subscription: %s (matched: %s)', - email, pattern) + pattern = self.GetBannedPattern(email) + if pattern: + syslog('vette', '%s banned subscription: %s (matched: %s)', + realname, email, pattern) raise Errors.MembershipIsBanned, pattern - # Sanity check the digest flag if digest and not self.digestable: raise Errors.MMCantDigestError @@ -889,7 +877,6 @@ class MailList(HTMLFormatter, Deliverer, ListAdmin, remote = _(' from %(remote)s') recipient = self.GetMemberAdminEmail(email) - realname = self.real_name confirmurl = '%s/%s' % (self.GetScriptURL('confirm', absolute=1), cookie) text = Utils.maketext( @@ -961,6 +948,11 @@ class MailList(HTMLFormatter, Deliverer, ListAdmin, Utils.ValidateEmail(email) if self.isMember(email): raise Errors.MMAlreadyAMember, email + # Check for banned address here too for admin mass subscribes + # and confirmations. + pattern = self.GetBannedPattern(email) + if pattern: + raise Errors.MembershipIsBanned, pattern # Do the actual addition self.addNewMember(email, realname=name, digest=digest, password=password, language=lang) @@ -1073,12 +1065,21 @@ class MailList(HTMLFormatter, Deliverer, ListAdmin, raise Errors.MMAlreadyAMember if newaddr == self.GetListEmail().lower(): raise Errors.MMBadEmailError + realname = self.real_name + # Don't allow changing to a banned address. MAS: maybe we should + # unsubscribe the oldaddr too just for trying, but that's probably + # too harsh. + pattern = self.GetBannedPattern(newaddr) + if pattern: + syslog('vette', + '%s banned address change: %s -> %s (matched: %s)', + realname, oldaddr, newaddr, pattern) + raise Errors.MembershipIsBanned, pattern # Pend the subscription change cookie = self.pend_new(Pending.CHANGE_OF_ADDRESS, oldaddr, newaddr, globally) confirmurl = '%s/%s' % (self.GetScriptURL('confirm', absolute=1), cookie) - realname = self.real_name lang = self.getMemberLanguage(oldaddr) text = Utils.maketext( 'verify.txt', @@ -1107,6 +1108,13 @@ class MailList(HTMLFormatter, Deliverer, ListAdmin, msg.send(self) def ApprovedChangeMemberAddress(self, oldaddr, newaddr, globally): + # Check here for banned address in case address was banned after + # confirmation was mailed. MAS: If it's global change should we just + # skip this list and proceed to the others? For now we'll throw the + # exception. + pattern = self.GetBannedPattern(newaddr) + if pattern: + raise Errors.MembershipIsBanned, pattern # It's possible they were a member of this list, but choose to change # their membership globally. In that case, we simply remove the old # address. @@ -1127,6 +1135,9 @@ class MailList(HTMLFormatter, Deliverer, ListAdmin, continue if not mlist.isMember(oldaddr): continue + # If new address is banned from this list, just skip it. + if mlist.GetBannedPattern(newaddr): + continue mlist.Lock() try: # Same logic as above, re newaddr is already a member @@ -1454,6 +1465,31 @@ bad regexp in bounce_matching_header line: %s self.hold_and_cmd_autoresponses[sender] = (today, count+1) return 1 + def GetBannedPattern(self, email): + """Returns matched entry in ban_list if email matches. + Otherwise returns None. + """ + ban = 0 + for pattern in self.ban_list: + if pattern.startswith('^'): + # This is a regular expression match + try: + if re.search(pattern, email, re.IGNORECASE): + ban = 1 + break + except re.error: + # BAW: we should probably remove this pattern + pass + else: + # Do the comparison case insensitively + if pattern.lower() == email.lower(): + ban = 1 + break + if ban: + return pattern + else: + return None + # |