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>