------------------------------------------------------------
revno: 1829
fixes bug: https://launchpad.net/bugs/1859104
committer: Mark Sapiro <m...@msapiro.net>
branch nick: 2.1
timestamp: Thu 2020-01-09 17:00:40 -0800
message:
  Implement REFUSE_SECOND_PENDING setting to prevent multiple pending 
subscribes.
modified:
  Mailman/Cgi/subscribe.py
  Mailman/Commands/cmd_subscribe.py
  Mailman/Defaults.py.in
  Mailman/Errors.py
  Mailman/MailList.py
  NEWS


--
lp:mailman/2.1
https://code.launchpad.net/~mailman-coders/mailman/2.1

Your team Mailman Checkins is subscribed to branch lp:mailman/2.1.
To unsubscribe from this branch go to 
https://code.launchpad.net/~mailman-coders/mailman/2.1/+edit-subscription
=== modified file 'Mailman/Cgi/subscribe.py'
--- Mailman/Cgi/subscribe.py	2019-06-19 23:56:49 +0000
+++ Mailman/Cgi/subscribe.py	2020-01-10 01:00:40 +0000
@@ -291,6 +291,9 @@
 Your subscription request was deferred because %(x)s.  Your request has been
 forwarded to the list moderator.  You will receive email informing you of the
 moderator's decision when they get to your request.""")
+    except Errors.MMAlreadyPending:
+        # User already has a subscription pending
+        results = _('You already have a subscription pending confirmation')
     except Errors.MMAlreadyAMember:
         # Results string depends on whether we have private rosters or not
         if not privacy_results:

=== modified file 'Mailman/Commands/cmd_subscribe.py'
--- Mailman/Commands/cmd_subscribe.py	2018-06-17 23:47:34 +0000
+++ Mailman/Commands/cmd_subscribe.py	2020-01-10 01:00:40 +0000
@@ -128,6 +128,10 @@
     except Errors.MMAlreadyAMember:
         res.results.append(_('You are already subscribed!'))
         return STOP
+    except Errors.MMAlreadyPending:
+        res.results.append(
+            _('You already have a subscription pending confirmation'))
+        return STOP
     except Errors.MMCantDigestError:
         res.results.append(
             _('No one can subscribe to the digest of this list!'))

=== modified file 'Mailman/Defaults.py.in'
--- Mailman/Defaults.py.in	2019-11-08 21:04:52 +0000
+++ Mailman/Defaults.py.in	2020-01-10 01:00:40 +0000
@@ -1122,6 +1122,14 @@
                                '^x-ack:', '^x-beenthere:',
                                '^x-list-administrivia:', '^x-spam-',
                               ]
+#
+# It is possible to mailbomb a third party by repeatrdly posting the subscribe
+# form.  You can prevent this by setting the following to Yes which will refuse
+# pending a subscription confirmation when one is already pending.  The down
+# side to this is if a subscriber loses or doesn't receive the confirmation
+# request email, she has to wait PENDING_REQUEST_LIFE (default 3 days) before
+# she can request another.
+REFUSE_SECOND_PENDING = No
 
 
 

=== modified file 'Mailman/Errors.py'
--- Mailman/Errors.py	2018-06-17 23:47:34 +0000
+++ Mailman/Errors.py	2020-01-10 01:00:40 +0000
@@ -31,6 +31,7 @@
 class MMMemberError(Exception): pass
 class MMBadUserError(MMMemberError): pass
 class MMAlreadyAMember(MMMemberError): pass
+class MMAlreadyPending(MMMemberError): pass
 
 # "New" style membership exceptions (new w/ MM2.1)
 class MemberError(Exception): pass

=== modified file 'Mailman/MailList.py'
--- Mailman/MailList.py	2019-11-08 21:51:55 +0000
+++ Mailman/MailList.py	2020-01-10 01:00:40 +0000
@@ -833,6 +833,25 @@
     #
     # Membership management front-ends and assertion checks
     #
+    def CheckPending(self, email):
+        """Check if there is already an unexpired pending subscription for
+        this email.
+        """
+        if not mm_cfg.REFUSE_SECOND_PENDING:
+            return False
+        pends = self._Pending__load()
+        # Save and reload the db to evict expired pendings.
+        self._Pending__save(pends)
+        pends = self._Pending__load()
+        for k, v in pends.items():
+            if k in ('evictions', 'version'):
+                continue
+            op, data = v
+            if (op == Pending.SUBSCRIPTION and
+                    data.address.lower() == email.lower()):
+                return True
+        return False
+
     def InviteNewMember(self, userdesc, text=''):
         """Invite a new member to the list.
 
@@ -919,6 +938,8 @@
         Utils.ValidateEmail(email)
         if self.isMember(email):
             raise Errors.MMAlreadyAMember, email
+        if self.CheckPending(email):
+            raise Errors.MMAlreadyPending, email
         if email.lower() == self.GetListEmail().lower():
             # Trying to subscribe the list to itself!
             raise Errors.MMBadEmailError

=== modified file 'NEWS'
--- NEWS	2019-11-08 21:51:55 +0000
+++ NEWS	2020-01-10 01:00:40 +0000
@@ -38,6 +38,12 @@
       controls the dropping of addresses from the Cc: header in delivered
       messages by the duplicate avoidance process.  (LP: #1845751)
 
+    - There is a new REFUSE_SECOND_PENDING mm_cfg.py setting that will cause
+      a second request to subscribe to a list when there is already a pending
+      confirmation for that user.  This can be set to Yes to prevent
+      mailbombing of a third party by repeatedly posting the subscribe form.
+      (LP: #1859104)
+
   i18n
 
     - The Japanese translation has been updated by Yasuhito FUTATSUKI.

_______________________________________________
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
https://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org

Reply via email to