Index: NEWS =================================================================== RCS file: /cvsroot/mailman/mailman/NEWS,v retrieving revision 1.25.2.6 retrieving revision 1.25.2.9 diff -u -r1.25.2.6 -r1.25.2.9 --- NEWS 2001/05/03 21:06:56 1.25.2.6 +++ NEWS 2001/07/25 18:52:27 1.25.2.9 @@ -4,6 +4,34 @@ Here is a history of user visible changes to Mailman. +2.0.6 (25-Jul-2001) + + Security fix: + + - Fixed a potential security hole which could allow access to list + administrative features by unauthorized users. If there is an + empty data/adm.pw file (the site password file), then any + password will be accepted as the list administrative password. + This exploit is caused by a common "bug" in the crypt() function + suffered by several Unix distributions, including at least + GNU/Linux and Solaris. Given a salt string of length zero, + crypt() always returns the empty string. + + In lieu of applying this patch, sites can run bin/mmsitepass and + ensure that data/adm.pw is of length 2 or greater. + + Bug fixes: + + - Ensure that even if DEFAULT_URL is misconfigured in mm_cfg.py + (i.e. is missing a trailing slash), it is always fixed upon list + creation. + + - Check for administrivia holds before any other tests. + + - SF bugs fixed: 407666, 227694 + + - Other miscellaneous buglets fixed. + 2.0.5 (04-May-2001) Fix a lock stagnation problem that can result when the user hits Index: Mailman/MailList.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/MailList.py,v retrieving revision 1.189 retrieving revision 1.189.2.2 diff -u -r1.189 -r1.189.2.2 --- Mailman/MailList.py 2000/11/16 04:33:27 1.189 +++ Mailman/MailList.py 2001/05/29 14:45:27 1.189.2.2 @@ -1,4 +1,4 @@ -# Copyright (C) 1998,1999,2000 by the Free Software Foundation, Inc. +# Copyright (C) 1998,1999,2000,2001 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 @@ -712,7 +712,7 @@ " fails, or if the pattern does contain an `@', then the pattern" " is matched against the entire recipient address. " "

Matching against the local part is deprecated; in a future" - " release, the patterm will always be matched against the " + " release, the pattern will always be matched against the " " entire recipient address."), ('max_num_recipients', mm_cfg.Number, 5, 0, @@ -787,6 +787,7 @@ self.InitVars(name, admin, crypted_password) self._ready = 1 self.InitTemplates() + self.CheckValues() self.Save() # Touch these files so they have the right dir perms no matter what. # A "just-in-case" thing. This shouldn't have to be here. Index: Mailman/SecurityManager.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/SecurityManager.py,v retrieving revision 1.31 retrieving revision 1.31.2.1 diff -u -r1.31 -r1.31.2.1 --- Mailman/SecurityManager.py 2000/10/02 20:40:41 1.31 +++ Mailman/SecurityManager.py 2001/07/25 18:07:51 1.31.2.1 @@ -1,4 +1,4 @@ -# Copyright (C) 1998,1999,2000 by the Free Software Foundation, Inc. +# Copyright (C) 1998,1999,2000,2001 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 @@ -44,8 +44,12 @@ def ValidAdminPassword(self, pw): if Utils.CheckSiteAdminPassword(pw): return 1 - return type(pw) == StringType and \ - Crypt.crypt(pw, self.password) == self.password + salt = self.password[:2] + # crypt() has a bug in that if the salt is the empty string, it will + # always return the empty string, regardless of the key. :( + if len(salt) < 2: + return 0 + return Crypt.crypt(pw, salt) == self.password def ConfirmAdminPassword(self, pw): if not self.ValidAdminPassword(pw): Index: Mailman/Utils.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Utils.py,v retrieving revision 1.104.2.2 retrieving revision 1.104.2.4 diff -u -r1.104.2.2 -r1.104.2.4 --- Mailman/Utils.py 2001/04/18 04:23:07 1.104.2.2 +++ Mailman/Utils.py 2001/07/25 18:06:46 1.104.2.4 @@ -262,7 +262,7 @@ finally: os.umask(ou) if verbose: - print 'made directory: ', madepart + print 'made directory: ', made_part @@ -405,7 +405,12 @@ f = open(mm_cfg.SITE_PW_FILE) pw2 = f.read() f.close() - return Crypt.crypt(pw1, pw2[:2]) == pw2 + salt = pw2[:2] + # crypt() has a bug in that if the salt is the empty string, it will + # always return the empty string, regardless of the key. :( + if len(salt) < 2: + return 0 + return Crypt.crypt(pw1, salt) == pw2 # There probably is no site admin password if there was an exception except IOError: return 0 Index: Mailman/Version.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Version.py,v retrieving revision 1.20.2.5 retrieving revision 1.20.2.6 diff -u -r1.20.2.5 -r1.20.2.6 --- Mailman/Version.py 2001/05/03 20:58:19 1.20.2.5 +++ Mailman/Version.py 2001/07/25 18:05:30 1.20.2.6 @@ -15,7 +15,7 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Mailman version -VERSION = "2.0.5" +VERSION = "2.0.6" # And as a hex number in the manner of PY_VERSION_HEX ALPHA = 0xa @@ -27,7 +27,7 @@ MAJOR_REV = 2 MINOR_REV = 0 -MICRO_REV = 5 +MICRO_REV = 6 REL_LEVEL = FINAL # at most 15 beta releases! REL_SERIAL = 0 Index: Mailman/versions.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/versions.py,v retrieving revision 1.27 retrieving revision 1.27.2.1 diff -u -r1.27 -r1.27.2.1 --- Mailman/versions.py 2000/06/14 05:09:58 1.27 +++ Mailman/versions.py 2001/07/10 14:58:56 1.27.2.1 @@ -142,7 +142,7 @@ # set admin_notify_mchanges # if not hasattr(l, "admin_notify_mchanges"): - setatrr(l, "admin_notify_mchanges", + setattr(l, "admin_notify_mchanges", mm_cfg.DEFAULT_ADMIN_NOTIFY_MCHANGES) # # Convert the members and digest_members addresses so that the keys of Index: Mailman/Archiver/pipermail.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Archiver/pipermail.py,v retrieving revision 1.15 retrieving revision 1.15.2.2 diff -u -r1.15 -r1.15.2.2 --- Mailman/Archiver/pipermail.py 2000/10/20 06:18:11 1.15 +++ Mailman/Archiver/pipermail.py 2001/06/01 22:30:16 1.15.2.2 @@ -62,7 +62,7 @@ # Abstract class for databases -class DatabaseInterface: +class DatabaseInterface: def __init__(self): pass def close(self): pass def getArticle(self, archive, msgid): pass @@ -162,13 +162,15 @@ id = strip_separators(message.getheader('Message-Id')) if id == "": self.msgid = str(self.sequence) - else: self.msgid = id + else: + self.msgid = id if message.has_key('Subject'): self.subject = str(message['Subject']) else: + self.subject = 'No subject' + if self.subject == "": self.subject = 'No subject' - if self.subject == "": self.subject = 'No subject' self._set_date(message) @@ -180,7 +182,8 @@ self.email = strip_separators(self.email) self.author = strip_separators(self.author) - if self.author == "": self.author = self.email + if self.author == "": + self.author = self.email # Save the In-Reply-To:, References:, and Message-ID: lines # @@ -197,8 +200,10 @@ self.in_reply_to = '' else: match = msgid_pat.search(i_r_t) - if match is None: self.in_reply_to = '' - else: self.in_reply_to = strip_separators(match.group(1)) + if match is None: + self.in_reply_to = '' + else: + self.in_reply_to = strip_separators(match.group(1)) references = message.getheader('References') if references is None: @@ -352,7 +357,7 @@ refs[0]) for ref in refs[1:]: a = self.database.getArticle(self.archive, ref) - if a.date > maxdate.data: + if a.date > maxdate.date: maxdate = a parentID = maxdate.msgid else: Index: Mailman/Bouncers/BouncerAPI.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Bouncers/BouncerAPI.py,v retrieving revision 1.11 retrieving revision 1.11.2.1 diff -u -r1.11 -r1.11.2.1 --- Mailman/Bouncers/BouncerAPI.py 2000/09/21 04:50:10 1.11 +++ Mailman/Bouncers/BouncerAPI.py 2001/07/10 15:00:09 1.11.2.1 @@ -82,6 +82,7 @@ # for testing if __name__ == '__main__': + import sys import mimetools from Mailman import MailList Index: Mailman/Bouncers/DSN.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Bouncers/DSN.py,v retrieving revision 1.7 retrieving revision 1.7.2.1 diff -u -r1.7 -r1.7.2.1 --- Mailman/Bouncers/DSN.py 2000/07/21 05:25:53 1.7 +++ Mailman/Bouncers/DSN.py 2001/07/25 18:04:42 1.7.2.1 @@ -1,4 +1,4 @@ -# Copyright (C) 1998,1999,2000 by the Free Software Foundation, Inc. +# Copyright (C) 1998,1999,2000,2001 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 @@ -43,8 +43,8 @@ def process(msg): - if msg.gettype() <> 'multipart/report' or \ - msg.getparam('report-type') <> 'delivery-status': + if string.lower(msg.gettype()) <> 'multipart/report' or \ + string.lower(msg.getparam('report-type')) <> 'delivery-status': # then return None boundary = msg.getparam('boundary') Index: Mailman/Cgi/handle_opts.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/Attic/handle_opts.py,v retrieving revision 1.30.2.2 retrieving revision 1.30.2.3 diff -u -r1.30.2.2 -r1.30.2.3 --- Mailman/Cgi/handle_opts.py 2001/05/03 21:05:06 1.30.2.2 +++ Mailman/Cgi/handle_opts.py 2001/07/10 14:52:32 1.30.2.3 @@ -266,14 +266,14 @@ except Errors.MMNotAMemberError: PrintResults(mlist, operation, doc, "%s isn't subscribed to this list." - % mail.GetSender(), user) + % user, user) except Errors.MMListNotReadyError: PrintResults(mlist, operation, doc, "List is not functional.", user) except Errors.MMNoSuchUserError: PrintResults(mlist, operation, doc, "%s is not subscribed to this list." - % mail.GetSender(), user) + % user, user) except Errors.MMBadPasswordError: PrintResults(mlist, operation, doc, "You gave the wrong password.", user) Index: Mailman/Handlers/Hold.py =================================================================== RCS file: /cvsroot/mailman/mailman/Mailman/Handlers/Hold.py,v retrieving revision 1.16 retrieving revision 1.16.2.2 diff -u -r1.16 -r1.16.2.2 --- Mailman/Handlers/Hold.py 2000/08/01 23:02:28 1.16 +++ Mailman/Handlers/Hold.py 2001/05/31 21:05:44 1.16.2.2 @@ -1,4 +1,4 @@ -# Copyright (C) 1998,1999,2000 by the Free Software Foundation, Inc. +# Copyright (C) 1998,1999,2000,2001 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 @@ -118,6 +118,11 @@ if not sender or sender[:len(listname)+6] == adminaddr: sender = msg.GetSender(use_envelope=0) # + # possible administrivia? + if mlist.administrivia and Utils.IsAdministrivia(msg): + hold_for_approval(mlist, msg, msgdata, Administrivia) + # no return + # # is the poster in the list of explicitly forbidden posters? if len(mlist.forbidden_posters): forbiddens = Utils.List2Dict(mlist.forbidden_posters) @@ -175,11 +180,6 @@ not msgdata.get('fromusenet'): # then hold_for_approval(mlist, msg, msgdata, ImplicitDestination) - # no return - # - # possible administrivia? - if mlist.administrivia and Utils.IsAdministrivia(msg): - hold_for_approval(mlist, msg, msgdata, Administrivia) # no return # # suspicious headers? Index: admin/www/download.ht =================================================================== RCS file: /cvsroot/mailman/mailman/admin/www/download.ht,v retrieving revision 1.5.2.6 retrieving revision 1.5.2.7 diff -u -r1.5.2.6 -r1.5.2.7 --- admin/www/download.ht 2001/05/03 21:09:36 1.5.2.6 +++ admin/www/download.ht 2001/07/25 18:08:31 1.5.2.7 @@ -65,9 +65,9 @@

Downloading

Version -(2.0.5, +(2.0.6, released on -May 4 2001) +Jul 25 2001) is the current GNU release. It is available from the following mirror sites: