[Mailman-Developers] RE: [Mailman-Announce] ANNOUNCE Mailman 2.0.6

Nadia Alexan nadialex@total.net
Wed, 25 Jul 2001 22:24:34 -0400


Hi Barry,
I didn't understand a word you wrote. For computer illiterates, like me,
your message might have well been written in Swahili!! Nadia

> -----Original Message-----
> From: mailman-announce-admin@python.org
> [mailto:mailman-announce-admin@python.org]On Behalf Of Barry A. Warsaw
> Sent: Wednesday, July 25, 2001 3:55 PM
> To: mailman-announce@python.org
> Cc: mailman-users@python.org; mailman-developers@python.org
> Subject: [Mailman-Announce] ANNOUNCE Mailman 2.0.6
>
>
>
> Folks,
>
> I've just released Mailman 2.0.6 which fixes a potential security
> problem in Mailman 2.0.x, and includes a few other minor bug fixes.
>
> It is possible, although unlikely, that you could have an empty site
> password, or an empty list password.  Because of peculiarities in the
> Unix crypt() function, such empty passwords could allow unauthorized
> access to the list administrative pages with an arbitrary password
> string.  This situation does not occur normally, but it is possible to
> create it by accident (e.g. by touch'ing data/adm.pw).
>
> This patch ensures that such empty passwords do not allow unauthorized
> access, by first checking to make sure that the salt is at least 2
> characters in length.  Alternatively, you can make sure that either
> data/adm.pw does not exist or that it is not empty.  For the extra
> paranoid, you'd need to be sure that none of your lists have empty
> passwords, but that's an even more difficult situation to create by
> accident.
>
> This patch guards against both situations.  Please note that Mailman
> 2.1alpha is not vulnerable to this problem because it does not use
> crypt().
>
> A few other minor bugs have been fixed; see the NEWS excerpt below for
> details.
>
> As usual, I'm releasing this as both a complete tarball and as a patch
> against Mailman 2.0.5.  You /must/ update your source to 2.0.5 before
> applying the 2.0.6 patch.  Since the patch is small, I'm including it
> in this message.  To apply, cd into your 2.0.5 source tree and apply
> it like so:
>
>     % patch -p0 < mailman-2.0.5-2.0.6.txt
>
> Then run "config.status; make install".
>
> Currently both http://mailman.sf.net and http://www.list.org are
> updated, and I expect the gnu.org site to be updated soon as well.
> The release information on SF is at
>
>     http://sourceforge.net/project/shownotes.php?release_id=45268
>
> See also
>
>     http://www.gnu.org/software/mailman
>     http://www.list.org
>     http://mailman.sf.net
>
> My thanks to Dave Helton, Ray Sanders, and Thomas Wouters for their
> help with this release.
>
> Enjoy,
> -Barry
>
> 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. "
>               " <p>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 @@
>  <h3>Downloading</h3>
>
>  <p>Version
> -(<!-VERSION--->2.0.5<!-VERSION--->,
> +(<!-VERSION--->2.0.6<!-VERSION--->,
>  released on
> -<!-DATE--->May  4 2001<!-DATE--->)
> +<!-DATE--->Jul 25 2001<!-DATE--->)
>  is the current GNU release.  It is available from the following
> mirror sites:
>
>  <ul>
> Index: admin/www/download.html
> ===================================================================
> RCS file: /cvsroot/mailman/mailman/admin/www/download.html,v
> retrieving revision 1.6.2.8
> retrieving revision 1.6.2.9
> diff -u -r1.6.2.8 -r1.6.2.9
> --- admin/www/download.html	2001/05/03 21:09:36	1.6.2.8
> +++ admin/www/download.html	2001/07/25 18:08:31	1.6.2.9
> @@ -1,6 +1,6 @@
>  <HTML>
>  <!-- THIS PAGE IS AUTOMATICALLY GENERATED.  DO NOT EDIT. -->
> -<!-- Thu May  3 17:09:03 2001 -->
> +<!-- Wed Jul 25 14:08:14 2001 -->
>  <!-- USING HT2HTML 1.1 -->
>  <!-- SEE http://www.wooz.org/barry/software/pyware.html -->
>  <!-- User-specified headers:
> @@ -237,9 +237,9 @@
>  <h3>Downloading</h3>
>
>  <p>Version
> -(<!-VERSION--->2.0.5<!-VERSION--->,
> +(<!-VERSION--->2.0.6<!-VERSION--->,
>  released on
> -<!-DATE--->May  4 2001<!-DATE--->)
> +<!-DATE--->Jul 25 2001<!-DATE--->)
>  is the current GNU release.  It is available from the following
> mirror sites:
>
>  <ul>
> Index: bin/find_member
> ===================================================================
> RCS file: /cvsroot/mailman/mailman/bin/find_member,v
> retrieving revision 1.5
> retrieving revision 1.5.2.1
> diff -u -r1.5 -r1.5.2.1
> --- bin/find_member	2000/09/11 03:58:57	1.5
> +++ bin/find_member	2001/07/25 17:38:43	1.5.2.1
> @@ -90,7 +90,7 @@
>          try:
>              mlist = MailList.MailList(listname, lock=0)
>          except Errors.MMListError:
> -            print 'No such list "%s"' % name
> +            print 'No such list "%s"' % listname
>              continue
>          if options.owners:
>              owners = mlist.owner
> Index: src/cgi-wrapper.c
> ===================================================================
> RCS file: /cvsroot/mailman/mailman/src/cgi-wrapper.c,v
> retrieving revision 1.13
> retrieving revision 1.13.2.1
> diff -u -r1.13 -r1.13.2.1
> --- src/cgi-wrapper.c	2000/03/21 06:26:41	1.13
> +++ src/cgi-wrapper.c	2001/05/29 13:20:27	1.13.2.1
> @@ -23,7 +23,7 @@
>
>  /* passed in by configure */
>  #define SCRIPTNAME  SCRIPT
> -#define LOG_IDENT   "Mailman cgi-wrapper (" ## SCRIPT ## ")"
> +#define LOG_IDENT   "Mailman cgi-wrapper (" SCRIPT ")"
>
>  /* GID that CGI scripts run as.  See your Web server's documentation. */
>  #define LEGAL_PARENT_GID CGI_GID
> Index: src/common.c
> ===================================================================
> RCS file: /cvsroot/mailman/mailman/src/common.c,v
> retrieving revision 1.26
> retrieving revision 1.26.2.1
> diff -u -r1.26 -r1.26.2.1
> --- src/common.c	2000/11/09 06:18:02	1.26
> +++ src/common.c	2001/05/29 13:20:27	1.26.2.1
> @@ -20,7 +20,7 @@
>  #include "common.h"
>
>  /* passed in by configure */
> -#define SCRIPTDIR PREFIX ## "/scripts/"	     /* trailing slash */
> +#define SCRIPTDIR PREFIX "/scripts/"	     /* trailing slash */
>  #define MODULEDIR PREFIX		     /* no trailing slash */
>
>  const char* scriptdir = SCRIPTDIR;
>
> _______________________________________________
> Mailman-announce mailing list
> Mailman-announce@python.org
> http://mail.python.org/mailman/listinfo/mailman-announce
>