Index: NEWS
===================================================================
RCS file: /cvsroot/mailman/mailman/NEWS,v
retrieving revision 1.25.2.9
retrieving revision 1.25.2.10
diff -u -r1.25.2.9 -r1.25.2.10
--- NEWS        2001/07/25 18:52:27     1.25.2.9
+++ NEWS        2001/11/09 21:08:18     1.25.2.10
@@ -4,6 +4,34 @@

Here is a history of user visible changes to Mailman.

+2.0.7 (09-Nov-2001)
+
+    Security fixes:
+
+    - Closed a hole in cookie management whereby some carefully
+      crafted untrusted cookie data could crash Mailman if used with
+      Python 1.5.2, or cause some unintended class constructors to be
+      run on the server.
+
+    - In the DSN.py bounce handler, a message that was DSN-like, but
+      which was missing a "report-type" parameter could cause a
+      non-deletable bounce message to crash Mailman forever, requiring
+      manual intervention.
+
+    Bug fixes:
+
+    - Stray % signs in headers and footers could cause crashes.  Now
+      they'll just cause an [INVALID HEADER] or [INVALID FOOTER]
+      string to be added.
+
+    - The mail->news gateway has been made more robust in the face of
+      duplicate headers, and reserved headers that some news servers
+      reject.  If the message is still rejected, it is saved in
+      $prefix/nntp instead of discarded.
+
+    - Hand-crafted invalid chunk number in membership management
+      display could cause a traceback.
+
2.0.6 (25-Jul-2001)

    Security fix:
Index: Mailman/SecurityManager.py
===================================================================
RCS file: /cvsroot/mailman/mailman/Mailman/SecurityManager.py,v
retrieving revision 1.31.2.1
retrieving revision 1.31.2.2
diff -u -r1.31.2.1 -r1.31.2.2
--- Mailman/SecurityManager.py  2001/07/25 18:07:51     1.31.2.1
+++ Mailman/SecurityManager.py  2001/11/06 04:25:26     1.31.2.2
@@ -118,7 +118,7 @@
        cookiedata = os.environ.get('HTTP_COOKIE')
        if not cookiedata:
            return 0
-        c = Cookie.Cookie(cookiedata)
+        c = Cookie.Cookie(cookiedata, net_setfunc=lambda x: x)
        if not c.has_key(key):
            return 0
        # Undo the encoding we performed in MakeCookie() above
Index: Mailman/Version.py
===================================================================
RCS file: /cvsroot/mailman/mailman/Mailman/Version.py,v
retrieving revision 1.20.2.6
retrieving revision 1.20.2.7
diff -u -r1.20.2.6 -r1.20.2.7
--- Mailman/Version.py  2001/07/25 18:05:30     1.20.2.6
+++ Mailman/Version.py  2001/11/09 20:46:05     1.20.2.7
@@ -15,7 +15,7 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

# Mailman version
-VERSION = "2.0.6"
+VERSION = "2.0.7"

# 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 = 6
+MICRO_REV = 7
REL_LEVEL = FINAL
# at most 15 beta releases!
REL_SERIAL = 0
Index: Mailman/Bouncers/DSN.py
===================================================================
RCS file: /cvsroot/mailman/mailman/Mailman/Bouncers/DSN.py,v
retrieving revision 1.7.2.1
retrieving revision 1.7.2.2
diff -u -r1.7.2.1 -r1.7.2.2
--- Mailman/Bouncers/DSN.py     2001/07/25 18:04:42     1.7.2.1
+++ Mailman/Bouncers/DSN.py     2001/11/06 04:27:30     1.7.2.2
@@ -43,8 +43,10 @@


def process(msg):
-    if string.lower(msg.gettype()) <> 'multipart/report' or \
-       string.lower(msg.getparam('report-type')) <> 'delivery-status':
+    ctype = msg.gettype()
+    param = msg.getparam('report-type') or ''
+    if string.lower(ctype) <> 'multipart/report' or \
+       string.lower(param) <> 'delivery-status':
        # then
        return None
    boundary = msg.getparam('boundary')
Index: Mailman/Cgi/admin.py
===================================================================
RCS file: /cvsroot/mailman/mailman/Mailman/Cgi/admin.py,v
retrieving revision 1.82.2.3
retrieving revision 1.82.2.4
diff -u -r1.82.2.3 -r1.82.2.4
--- Mailman/Cgi/admin.py        2001/05/03 21:03:48     1.82.2.3
+++ Mailman/Cgi/admin.py        2001/11/06 04:42:33     1.82.2.4
@@ -585,6 +585,8 @@
            chunk = 0
        else:
            chunk = string.atoi(cgi_data["chunk"].value)
+        # Sanitize the chunk
+        chunk = min(len(chunks)-1, max(chunk, 0))
        all = chunks[chunk]
        footer = ("<p><em>To View other sections, "
                  "click on the appropriate range listed below</em>")
Index: Mailman/Handlers/Decorate.py
===================================================================
RCS file: /cvsroot/mailman/mailman/Mailman/Handlers/Decorate.py,v
retrieving revision 1.7.2.1
retrieving revision 1.7.2.2
diff -u -r1.7.2.1 -r1.7.2.2
--- Mailman/Handlers/Decorate.py        2001/03/03 06:49:11     1.7.2.1
+++ Mailman/Handlers/Decorate.py        2001/08/29 18:38:17     1.7.2.2
@@ -37,12 +37,12 @@
    # interpolate into the header
    try:
        header = string.replace(mlist.msg_header % d, '\r\n', '\n')
-    except ValueError, e:
+    except (ValueError, TypeError), e:
        syslog('error', 'Exception while calculating message header:\n%s' % e)
        header = '[INVALID HEADER]'
    try:
        footer = string.replace(mlist.msg_footer % d, '\r\n', '\n')
-    except ValueError, e:
+    except (ValueError, TypeError), e:
        syslog('error', 'Exception while calculating message footer:\n%s' % e)
        footer = '[INVALID FOOTER]'
    msg.body = header + msg.body + footer
Index: Mailman/Handlers/ToUsenet.py
===================================================================
RCS file: /cvsroot/mailman/mailman/Mailman/Handlers/ToUsenet.py,v
retrieving revision 1.17
retrieving revision 1.17.2.1
diff -u -r1.17 -r1.17.2.1
--- Mailman/Handlers/ToUsenet.py        2000/09/22 04:28:20     1.17
+++ Mailman/Handlers/ToUsenet.py        2001/11/06 04:31:47     1.17.2.1
@@ -23,6 +23,7 @@
import re
import socket
import traceback
+import errno

from Mailman import mm_cfg
from Mailman.Logging.Syslog import syslog
@@ -146,9 +147,34 @@
        ctevalue = ctetuple[1]
        del msg['content-transfer-encoding']
        msg['content-transfer-encoding'] = ctevalue
+    # Here some headers that our NNTP server will simply outright reject.
+    # These are hardcoded to what we know about INN, and other NNTP servers
+    # may have different lists.  This will be configurable in MM2.1.
+    #
+    # We got this list of headers from two sources: from a post in
+    # news.software.nntp describing the headers rejected by default in
+    # nnrpd/post.c for INN, and in the logs/error file collected since early
+    # 2000 on mail.python.org.
+    for header in ('nntp-posting-host', 'x-trace', 'x-complaints-to',
+                   'nntp-posting-date', 'xref', 'date-received',
+                   'posted', 'posting-version', 'relay-version'):
+        del msg[header]
+    # INN will apparently complain if there are duplicates of any of these
+    # headers.  That seems completely stupid on INN's part.  What choice do we
+    # have?  In the interest of simplicity, we'll move all those to
+    # X-Original-*: headers.
+    for header in ('Cc', 'To'):
+        headervals = msg.getaddrlist(header)
+        del msg[header]
+        newheader = 'X-Original-' + header + ': %s\n'
+        for h, v in headervals:
+            msg.headers.append(newheader % v)
    # NNTP is strict about spaces after the colon in headers.
    for n in range(len(msg.headers)):
        line = msg.headers[n]
+        if line[0] in ' \t':
+            # skip continuation lines
+            continue
        i = string.find(line,":")
        if i <> -1 and line[i+1] <> ' ':
            msg.headers[n] = line[:i+1] + ' ' + line[i+1:]
@@ -163,11 +189,37 @@
                                password=mm_cfg.NNTP_PASSWORD)
            conn.post(fp)
        except nntplib.error_temp, e:
-            syslog('error', '(ToUsenet) NNTP error for list "%s": %s' %
-                   (mlist.internal_name(), e))
+            errmsg = '(ToUsenet) NNTP error for list "%s": %s' % (
+                mlist.internal_name(), e)
+            preserve_message(msg, errmsg)
        except socket.error, e:
-            syslog('error', '(ToUsenet) socket error for list "%s": %s'
-                   % (mlist.internal_name(), e))
+            errmsg = '(ToUsenet) socket error for list "%s": %s' % (
+                mlist.internal_name(), e)
+            preserve_message(msg, errmsg)
    finally:
        if conn:
            conn.quit()
+
+
+def preserve_message(msg, errmsg):
+    # Preserve this message for possible reposting
+    msgid = msg['message-id']
+    # Set a useful header and log this failure
+    msg['X-ToUsenet-Failure'] = errmsg
+    syslog('error', errmsg)
+    syslog('error', '(ToUsenet) Message-ID: %s' % msgid)
+    path = os.path.join(mm_cfg.VAR_PREFIX, 'nntp')
+    try:
+        os.mkdir(path)
+    except OSError, e:
+        if e.errno <> errno.EEXIST: raise
+    counter = 0
+    filename = os.path.join(path, msgid + '.txt')
+    while os.path.exists(filename):
+        counter = counter + 1
+        filename = os.path.join(path, msgid + '-%02d.txt' % counter)
+    fp = open(filename, 'w')
+    try:
+        fp.write(str(msg))
+    finally:
+        fp.close()
Index: admin/www/download.ht
===================================================================
RCS file: /cvsroot/mailman/mailman/admin/www/download.ht,v
retrieving revision 1.5.2.7
retrieving revision 1.5.2.8
diff -u -r1.5.2.7 -r1.5.2.8
--- admin/www/download.ht       2001/07/25 18:08:31     1.5.2.7
+++ admin/www/download.ht       2001/11/09 20:46:27     1.5.2.8
@@ -65,9 +65,9 @@
<h3>Downloading</h3>

<p>Version
-(<!-VERSION--->2.0.6<!-VERSION--->,
+(<!-VERSION--->2.0.7<!-VERSION--->,
released on
-<!-DATE--->Jul 25 2001<!-DATE--->)
+<!-DATE--->Nov  9 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.9
retrieving revision 1.6.2.10
diff -u -r1.6.2.9 -r1.6.2.10
--- admin/www/download.html     2001/07/25 18:08:31     1.6.2.9
+++ admin/www/download.html     2001/11/09 20:46:27     1.6.2.10
@@ -1,8 +1,8 @@
<HTML>
<!-- THIS PAGE IS AUTOMATICALLY GENERATED.  DO NOT EDIT. -->
-<!-- Wed Jul 25 14:08:14 2001 -->
-<!-- USING HT2HTML 1.1 -->
-<!-- SEE http://www.wooz.org/barry/software/pyware.html -->
+<!-- Fri Nov  9 15:46:15 2001 -->
+<!-- USING HT2HTML 1.2 -->
+<!-- SEE http://barry.wooz.org/software/ht2html -->
<!-- User-specified headers:
Title: Downloading Mailman

@@ -237,9 +237,9 @@
<h3>Downloading</h3>

<p>Version
-(<!-VERSION--->2.0.6<!-VERSION--->,
+(<!-VERSION--->2.0.7<!-VERSION--->,
released on
-<!-DATE--->Jul 25 2001<!-DATE--->)
+<!-DATE--->Nov  9 2001<!-DATE--->)
is the current GNU release.  It is available from the following mirror sites:

<ul>