Package: mailman
Severity: wishlist
Tags: patch

Please apply the attached patch which prevents extra subscription spam.
By this I mean that on lists where admin approval is required for
subscription, an annoying user could attempt to subscribe the same email
address over and over again, spamming the list admin or the person they
attempt to subscribe (depending on the list config). 

I've posted this patch to the upstream tracker too:

http://sf.net/tracker/?func=detail&aid=1527537&group_id=103&atid=300103

-- 
bye,
pabs

http://wiki.debian.org/PaulWise
Paul Wise <[EMAIL PROTECTED]> http://pabs.zip.to
Prevent (and log) subscription spam
diff -urNad mailman-2.1.8~/Mailman/ListAdmin.py mailman-2.1.8/Mailman/ListAdmin.py
--- mailman-2.1.8~/Mailman/ListAdmin.py	2006-07-24 03:24:02.000000000 +0800
+++ mailman-2.1.8/Mailman/ListAdmin.py	2006-07-24 03:24:03.000000000 +0800
@@ -376,6 +376,10 @@
     def HoldSubscription(self, addr, fullname, password, digest, lang):
         # Assure that the database is open for writing
         self.__opendb()
+        # Check for attempts at spamming the admin
+        for k, (type, data) in self.__db.items():
+            if type == SUBSCRIPTION and data[1] == addr:
+                return 1
         # Get the next unique id
         id = self.__nextid()
         # Save the information to the request database. for held subscription
@@ -412,6 +416,7 @@
             msg = Message.UserNotification(owneraddr, owneraddr, subject, text,
                                            self.preferred_language)
             msg.send(self, **{'tomoderators': 1})
+        return 0
 
     def __handlesubscription(self, record, value, comment):
         stime, addr, fullname, password, digest, lang = record
@@ -440,6 +445,10 @@
     def HoldUnsubscription(self, addr):
         # Assure the database is open for writing
         self.__opendb()
+        # Check for attempts at spamming the admin
+        for k, (type, data) in self.__db.items():
+            if type == UNSUBSCRIPTION and data[1] == addr:
+                return 1
         # Get the next unique id
         id = self.__nextid()
         # All we need to do is save the unsubscribing address
@@ -464,6 +473,7 @@
             msg = Message.UserNotification(owneraddr, owneraddr, subject, text,
                                            self.preferred_language)
             msg.send(self, **{'tomoderators': 1})
+        return 0
 
     def __handleunsubscription(self, record, value, comment):
         addr = record
diff -urNad mailman-2.1.8~/Mailman/MailList.py mailman-2.1.8/Mailman/MailList.py
--- mailman-2.1.8~/Mailman/MailList.py	2006-07-24 03:24:02.000000000 +0800
+++ mailman-2.1.8/Mailman/MailList.py	2006-07-24 03:24:03.000000000 +0800
@@ -966,6 +966,10 @@
             # User confirmation required.  BAW: this should probably just
             # accept a userdesc instance.
             cookie = self.pend_new(Pending.SUBSCRIPTION, userdesc)
+            if cookie == '':
+                # Someone tried to spam some random email address
+                syslog('mischief', 'Duplicate subscription attempt on list %s for %s by %s', self.internal_name(), email, remote)
+                raise Errors.MMSubscribeNeedsConfirmation
             # Send the user the confirmation mailback
             if remote is None:
                 by = remote = ''
@@ -1003,7 +1007,9 @@
             # Subscription approval is required.  Add this entry to the admin
             # requests database.  BAW: this should probably take a userdesc
             # just like above.
-            self.HoldSubscription(email, name, password, digest, lang)
+            if self.HoldSubscription(email, name, password, digest, lang):
+                # Someone tried to spam the poor list admin
+                syslog('mischief', 'Duplicate subscription attempt on list %s for %s by %s', self.internal_name(), email, remote)
             raise Errors.MMNeedApproval, _(
                 'subscriptions to %(realname)s require moderator approval')
 
@@ -1091,7 +1097,9 @@
         if self.unsubscribe_policy == 0:
             self.ApprovedDeleteMember(name, whence, admin_notif, userack)
         else:
-            self.HoldUnsubscription(email)
+            if self.HoldUnsubscription(email):
+                # Someone tried to spam the poor list admin
+                syslog('mischief', 'Duplicate subscription attempt on list %s for %s by %s', self.internal_name(), email, whence)
             raise Errors.MMNeedApproval, _(
                 'unsubscriptions require moderator approval')
 
diff -urNad mailman-2.1.8~/Mailman/Pending.py mailman-2.1.8/Mailman/Pending.py
--- mailman-2.1.8~/Mailman/Pending.py	2005-08-27 09:40:15.000000000 +0800
+++ mailman-2.1.8/Mailman/Pending.py	2006-07-24 03:24:26.000000000 +0800
@@ -63,6 +63,16 @@
         assert self.Locked()
         # Load the database
         db = self.__load()
+        evictions = db['evictions']
+        now = time.time()
+        for cookie, data in db.items():
+            if cookie in ('evictions', 'version'):
+                continue
+            timestamp = evictions[cookie]
+            if now > timestamp:
+                continue
+            if data[0] in (SUBSCRIPTION, UNSUBSCRIPTION) and data[1].address == content[0].address:
+                return ''
         # Calculate a unique cookie.  Algorithm vetted by the Timbot.  time()
         # has high resolution on Linux, clock() on Windows.  random gives us
         # about 45 bits in Python 2.2, 53 bits on Python 2.3.  The time and

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to