------------------------------------------------------------
revno: 1560
fixes bug: https://launchpad.net/bugs/1447445
committer: Mark Sapiro <m...@msapiro.net>
branch nick: 2.1
timestamp: Thu 2015-04-23 17:42:33 -0700
message:
  If SUBSCRIBE_FORM_SECRET is enabled and a user's network has a load
  balancer or similar in use the POSTing IP might not exactly match the
  GETting IP.  This is now accounted for by not requiring the last
  octet (16 bits for ipV6) to match.
modified:
  Mailman/Cgi/listinfo.py
  Mailman/Cgi/subscribe.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/listinfo.py'
--- Mailman/Cgi/listinfo.py	2014-03-22 03:47:45 +0000
+++ Mailman/Cgi/listinfo.py	2015-04-24 00:42:33 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2014 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2015 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
@@ -187,14 +187,24 @@
         'subscribe')
     if mm_cfg.SUBSCRIBE_FORM_SECRET:
         now = str(int(time.time()))
+        remote = os.environ.get('REMOTE_HOST',
+                                os.environ.get('REMOTE_ADDR',
+                                               'w.x.y.z'))
+        # Try to accept a range in case of load balancers, etc.  (LP: #1447445)
+        if remote.find('.') >= 0:
+            # ipv4 - drop last octet
+            remote = remote.rsplit('.', 1)[0]
+        else:
+            # ipv6 - drop last 16 (could end with :: in which case we just
+            #        drop one : resulting in an invalid format, but it's only
+            #        for our hash so it doesn't matter.
+            remote = remote.rsplit(':', 1)[0]
         replacements['<mm-subscribe-form-start>'] += (
                 '<input type="hidden" name="sub_form_token" value="%s:%s">\n'
                 % (now, Utils.sha_new(mm_cfg.SUBSCRIBE_FORM_SECRET +
                           now +
                           mlist.internal_name() +
-                          os.environ.get('REMOTE_HOST',
-                                         os.environ.get('REMOTE_ADDR',
-                                                        'w.x.y.z'))
+                          remote
                           ).hexdigest()
                     )
                 )

=== modified file 'Mailman/Cgi/subscribe.py'
--- Mailman/Cgi/subscribe.py	2014-03-22 03:47:45 +0000
+++ Mailman/Cgi/subscribe.py	2015-04-24 00:42:33 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 1998-2014 by the Free Software Foundation, Inc.
+# Copyright (C) 1998-2015 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
@@ -124,23 +124,36 @@
     # Are we checking the hidden data?
     if mm_cfg.SUBSCRIBE_FORM_SECRET:
         now = int(time.time())
+        # Try to accept a range in case of load balancers, etc.  (LP: #1447445)
+        if remote.find('.') >= 0:
+            # ipv4 - drop last octet
+            remote1 = remote.rsplit('.', 1)[0]
+        else:
+            # ipv6 - drop last 16 (could end with :: in which case we just
+            #        drop one : resulting in an invalid format, but it's only
+            #        for our hash so it doesn't matter.
+            remote1 = remote.rsplit(':', 1)[0]
         try:
             ftime, fhash = cgidata.getvalue('sub_form_token', '').split(':')
             then = int(ftime)
         except ValueError:
             ftime = fhash = ''
-            then = now
+            then = 0
         token = Utils.sha_new(mm_cfg.SUBSCRIBE_FORM_SECRET +
                               ftime +
                               mlist.internal_name() +
-                              remote).hexdigest()
-        if now - then > mm_cfg.FORM_LIFETIME:
+                              remote1).hexdigest()
+        if ftime and now - then > mm_cfg.FORM_LIFETIME:
             results.append(_('The form is too old.  Please GET it again.'))
-        if now - then < mm_cfg.SUBSCRIBE_FORM_MIN_TIME:
-            results.append(
-    _('Please take a few seconds to fill out the form before submitting it.')
-                          )
-        if token != fhash:
+        if ftime and now - then < mm_cfg.SUBSCRIBE_FORM_MIN_TIME:
+            results.append(
+    _('Please take a few seconds to fill out the form before submitting it.'))
+        if ftime and token != fhash:
+            results.append(
+                _("The hidden token didn't match.  Did your IP change?"))
+        if not ftime:
+            results.append(
+    _('There was no hidden token in your submission or it was corrupted.'))
             results.append(_('You must GET the form before submitting it.'))
     # Was an attempt made to subscribe the list to itself?
     if email == mlist.GetListEmail():

=== modified file 'NEWS'
--- NEWS	2015-04-15 20:31:01 +0000
+++ NEWS	2015-04-24 00:42:33 +0000
@@ -9,6 +9,11 @@
 
   Bug fixes and other patches
 
+    - If SUBSCRIBE_FORM_SECRET is enabled and a user's network has a load
+      balancer or similar in use the POSTing IP might not exactly match the
+      GETting IP.  This is now accounted for by not requiring the last
+      octet (16 bits for ipV6) to match.  (LP: #1447445)
+
     - DKIM-Signature:, DomainKey-Signature: and Authentication-Results:
       headers are now removed by default from posts to anonymous lists.
       (LP: #1444673)

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

Reply via email to