Update of /cvsroot/mailman/mailman/Mailman
In directory sc8-pr-cvs1:/tmp/cvs-serv10999

Modified Files:
      Tag: Release_2_1-maint
        SecurityManager.py 
Log Message:
Authenticate(): When authenticating AuthUser, wrap the
self.authenticateMember() call in a try/except catching and ignoring
NotAMemberErrors.  The effect of this is that other authcontexts being
check will then proceed as normal.  This fixes admin login to the
private archives, and non-public rosters.

Under the old code, if you tried to get into the private archives w/o
entering an email address, but using the admin password, you'd be
denied access.

WebAuthenticate(): Removed the wrapping of .Authenticate() in
try/except catching of NotAMemberError, since this should never
percolate out now.

Also, use True/False everywhere it's appropriate (but not in the
cookie code).

Original bug and patch by Stephan Berndts.  Closes SF bug # 864676 and
SF patch # 864674.


Index: SecurityManager.py
===================================================================
RCS file: /cvsroot/mailman/mailman/Mailman/SecurityManager.py,v
retrieving revision 2.20.2.1
retrieving revision 2.20.2.2
diff -u -d -r2.20.2.1 -r2.20.2.2
--- SecurityManager.py  8 Feb 2003 07:13:48 -0000       2.20.2.1
+++ SecurityManager.py  26 Dec 2003 16:36:53 -0000      2.20.2.2
@@ -67,6 +67,12 @@
 from Mailman import Errors
 from Mailman.Logging.Syslog import syslog
 
+try:
+    True, False
+except NameError:
+    True = 1
+    False = 0
+
 
 
 class SecurityManager:
@@ -143,15 +149,15 @@
                     try:
                         salt = secret[:2]
                         if crypt and crypt.crypt(response, salt) == secret:
-                            return 1
-                        return 0
+                            return True
+                        return False
                     except TypeError:
                         # BAW: Hard to say why we can get a TypeError here.
                         # SF bug report #585776 says crypt.crypt() can raise
                         # this if salt contains null bytes, although I don't
                         # know how that can happen (perhaps if a MM2.0 list
                         # with USE_CRYPT = 0 has been updated?  Doubtful.
-                        return 0
+                        return False
                 # The password for the list admin and list moderator are not
                 # kept as plain text, but instead as an sha hexdigest.  The
                 # response being passed in is plain text, so we need to
@@ -163,20 +169,18 @@
                 if secret is None:
                     continue
                 sharesponse = sha.new(response).hexdigest()
-                upgrade = ok = 0
+                upgrade = ok = False
                 if sharesponse == secret:
-                    ok = 1
+                    ok = True
                 elif md5.new(response).digest() == secret:
-                    ok = 1
-                    upgrade = 1
+                    ok = upgrade = True
                 elif cryptmatchp(response, secret):
-                    ok = 1
-                    upgrade = 1
+                    ok = upgrade = True
                 if upgrade:
-                    save_and_unlock = 0
+                    save_and_unlock = False
                     if not self.Locked():
                         self.Lock()
-                        save_and_unlock = 1
+                        save_and_unlock = True
                     try:
                         self.password = sharesponse
                         if save_and_unlock:
@@ -192,8 +196,12 @@
                 if secret and sha.new(response).hexdigest() == secret:
                     return ac
             elif ac == mm_cfg.AuthUser:
-                if self.authenticateMember(user, response):
-                    return ac
+                if user is not None:
+                    try:
+                        if self.authenticateMember(user, response):
+                            return ac
+                    except Errors.NotAMemberError:
+                        pass
             else:
                 # What is this context???
                 syslog('error', 'Bad authcontext: %s', ac)
@@ -205,22 +213,19 @@
         # contains a matching authorization, falling back to checking whether
         # the response matches one of the passwords.  authcontexts must be a
         # sequence, and if it contains the context AuthUser, then the user
-        # argument must not be None.
+        # argument should not be None.
         #
         # Returns a flag indicating whether authentication succeeded or not.
-        try:
-            for ac in authcontexts:
-                ok = self.CheckCookie(ac, user)
-                if ok:
-                    return 1
-            # Check passwords
-            ac = self.Authenticate(authcontexts, response, user)
-            if ac:
-                print self.MakeCookie(ac, user)
-                return 1
-        except Errors.NotAMemberError:
-            pass
-        return 0
+        for ac in authcontexts:
+            ok = self.CheckCookie(ac, user)
+            if ok:
+                return True
+        # Check passwords
+        ac = self.Authenticate(authcontexts, response, user)
+        if ac:
+            print self.MakeCookie(ac, user)
+            return True
+        return False
 
     def MakeCookie(self, authcontext, user=None):
         key, secret = self.AuthContextInfo(authcontext, user)
@@ -269,7 +274,7 @@
         # authentication.
         cookiedata = os.environ.get('HTTP_COOKIE')
         if not cookiedata:
-            return 0
+            return False
         # We can't use the Cookie module here because it isn't liberal in what
         # it accepts.  Feed it a MM2.0 cookie along with a MM2.1 cookie and
         # you get a CookieError. :(.  All we care about is accessing the
@@ -294,8 +299,8 @@
             for user in [Utils.UnobscureEmail(u) for u in usernames]:
                 ok = self.__checkone(c, authcontext, user)
                 if ok:
-                    return 1
-            return 0
+                    return True
+            return False
         else:
             return self.__checkone(c, authcontext, user)
 
@@ -304,7 +309,7 @@
         # combination.
         key, secret = self.AuthContextInfo(authcontext, user)
         if not c.has_key(key) or not isinstance(secret, StringType):
-            return 0
+            return False
         # Undo the encoding we performed in MakeCookie() above.  BAW: I
         # believe this is safe from exploit because marshal can't be forced to
         # load recursive data structures, and it can't be forced to execute
@@ -318,18 +323,18 @@
             data = marshal.loads(binascii.unhexlify(c[key]))
             issued, received_mac = data
         except (EOFError, ValueError, TypeError, KeyError):
-            return 0
+            return False
         # Make sure the issued timestamp makes sense
         now = time.time()
         if now < issued:
-            return 0
+            return False
         # Calculate what the mac ought to be based on the cookie's timestamp
         # and the shared secret.
         mac = sha.new(secret + `issued`).hexdigest()
         if mac <> received_mac:
-            return 0
+            return False
         # Authenticated!
-        return 1
+        return True
 
 
 



_______________________________________________
Mailman-checkins mailing list
[EMAIL PROTECTED]
Unsubscribe: http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org

Reply via email to