[Pkg-mailman-hackers] Pkg-mailman commit - rev 382 - in
trunk/debian: . patches
Hector Garcia
hector at costa.debian.org
Tue Sep 19 21:16:07 UTC 2006
Author: hector
Date: 2006-09-19 21:16:07 +0000 (Tue, 19 Sep 2006)
New Revision: 382
Added:
trunk/debian/patches/23_CVE-2006-3636.dpatch
trunk/debian/patches/24_CVE-2006-2941.dpatch
trunk/debian/patches/25_CVE-2006-4624.dpatch
Modified:
trunk/debian/changelog
trunk/debian/patches/series
Log:
Added security patches from Lionel's port to sarge
Modified: trunk/debian/changelog
===================================================================
--- trunk/debian/changelog 2006-09-19 20:50:43 UTC (rev 381)
+++ trunk/debian/changelog 2006-09-19 21:16:07 UTC (rev 382)
@@ -37,8 +37,13 @@
* Updated sv.po. Translated by Daniel Nylander. (Closes: #388090)
* Updated hu.po. Translated by Laszlo Boszormenyi.
- -- Thijs Kinkhorst <thijs at debian.org> Tue, 19 Sep 2006 13:52:06 +0200
+ [ Hector Garcia ]
+ * Added 24_CVE-2006-2941 taken from Lionel's port to sarge
+ * Added 23_CVE-2006-3636 taken from Lionel's port to sarge
+ * Added 25_CVE-2006-4624 taken from Lionel's port to sarge
+ -- Hector Garcia <hector at debian.org> Tue, 19 Sep 2006 23:11:32 +0200
+
mailman (1:2.1.8-2) unstable; urgency=low
[ Thijs Kinkhorst ]
Added: trunk/debian/patches/23_CVE-2006-3636.dpatch
===================================================================
--- trunk/debian/patches/23_CVE-2006-3636.dpatch (rev 0)
+++ trunk/debian/patches/23_CVE-2006-3636.dpatch 2006-09-19 21:16:07 UTC (rev 382)
@@ -0,0 +1,249 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 72_CVE-2006-3636.dpatch by <lionel at mamane.lu>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: CVE-2006-3636. Fixes for various cross-site scripting issues.
+## DP: Discovery by Moritz Naumann and most of the repair work done by
+## DP: Mark Sapiro (with some additional work by Barry).
+
+
+ at DPATCH@
+Index: Mailman/Cgi/admin.py
+===================================================================
+--- Mailman/Cgi/admin.py.orig 2005-12-30 19:50:07.000000000 +0100
++++ Mailman/Cgi/admin.py 2006-09-19 22:57:38.000000000 +0200
+@@ -1318,6 +1318,7 @@
+ # we display. Try uploading a file with 10k names -- it takes a while
+ # to render the status page.
+ for entry in entries:
++ safeentry = Utils.websafe(entry)
+ fullname, address = parseaddr(entry)
+ # Canonicalize the full name
+ fullname = Utils.canonstr(fullname, mlist.preferred_language)
+@@ -1335,20 +1336,20 @@
+ send_admin_notif, invitation,
+ whence='admin mass sub')
+ except Errors.MMAlreadyAMember:
+- subscribe_errors.append((entry, _('Already a member')))
++ subscribe_errors.append((safeentry, _('Already a member')))
+ except Errors.MMBadEmailError:
+ if userdesc.address == '':
+ subscribe_errors.append((_('<blank line>'),
+ _('Bad/Invalid email address')))
+ else:
+- subscribe_errors.append((entry,
++ subscribe_errors.append((safeentry,
+ _('Bad/Invalid email address')))
+ except Errors.MMHostileAddress:
+ subscribe_errors.append(
+- (entry, _('Hostile address (illegal characters)')))
++ (safeentry, _('Hostile address (illegal characters)')))
+ except Errors.MembershipIsBanned, pattern:
+ subscribe_errors.append(
+- (entry, _('Banned address (matched %(pattern)s)')))
++ (safeentry, _('Banned address (matched %(pattern)s)')))
+ else:
+ member = Utils.uncanonstr(formataddr((fullname, address)))
+ subscribe_success.append(Utils.websafe(member))
+@@ -1388,9 +1389,9 @@
+ addr, whence='admin mass unsub',
+ admin_notif=send_unsub_notifications,
+ userack=userack)
+- unsubscribe_success.append(addr)
++ unsubscribe_success.append(Utils.websafe(addr))
+ except Errors.NotAMemberError:
+- unsubscribe_errors.append(addr)
++ unsubscribe_errors.append(Utils.websafe(addr))
+ if unsubscribe_success:
+ doc.AddItem(Header(5, _('Successfully Unsubscribed:')))
+ doc.AddItem(UnorderedList(*unsubscribe_success))
+Index: Mailman/Cgi/admindb.py
+===================================================================
+--- Mailman/Cgi/admindb.py.orig 2005-12-30 19:50:07.000000000 +0100
++++ Mailman/Cgi/admindb.py 2006-09-19 22:48:50.000000000 +0200
+@@ -313,7 +313,7 @@
+ ' ' + _('Permanently ban from this list')
+ # While the address may be a unicode, it must be ascii
+ paddr = addr.encode('us-ascii', 'replace')
+- table.AddRow(['%s<br><em>%s</em>' % (paddr, fullname),
++ table.AddRow(['%s<br><em>%s</em>' % (paddr, Utils.websafe(fullname)),
+ radio,
+ TextBox('comment-%d' % id, size=40)
+ ])
+@@ -357,7 +357,7 @@
+ mlist.HandleRequest(id, mm_cfg.DISCARD)
+ continue
+ num += 1
+- table.AddRow(['%s<br><em>%s</em>' % (addr, fullname),
++ table.AddRow(['%s<br><em>%s</em>' % (addr, Utils.websafe(fullname)),
+ RadioButtonArray(id, (_('Defer'),
+ _('Approve'),
+ _('Reject'),
+Index: Mailman/Cgi/create.py
+===================================================================
+--- Mailman/Cgi/create.py.orig 2005-12-30 19:50:07.000000000 +0100
++++ Mailman/Cgi/create.py 2006-09-19 22:48:50.000000000 +0200
+@@ -190,15 +190,24 @@
+ mlist.Create(listname, owner, pw, langs, emailhost)
+ finally:
+ os.umask(oldmask)
+- except Errors.EmailAddressError, s:
++ except Errors.EmailAddressError, e:
++ if e.args:
++ s = Utils.websafe(e.args[0])
++ else:
++ s = Utils.websafe(owner)
+ request_creation(doc, cgidata,
+ _('Bad owner email address: %(s)s'))
+ return
+ except Errors.MMListAlreadyExistsError:
++ # MAS: List already exists so we don't need to websafe it.
+ request_creation(doc, cgidata,
+ _('List already exists: %(listname)s'))
+ return
+- except Errors.BadListNameError, s:
++ except Errors.BadListNameError, e:
++ if e.args:
++ s = Utils.websafe(e.args[0])
++ else:
++ s = Utils.websafe(listname)
+ request_creation(doc, cgidata,
+ _('Illegal list name: %(s)s'))
+ return
+@@ -321,15 +330,17 @@
+ ftable.AddRow([Center(Italic(_('List Identity')))])
+ ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 0, colspan=2)
+
+- safelistname = Utils.websafe(cgidata.getvalue('listname', ''))
++ listname = cgidata.getvalue('listname', '')
++ # MAS: Don't websafe twice. TextBox does it.
+ ftable.AddRow([Label(_('Name of list:')),
+- TextBox('listname', safelistname)])
++ TextBox('listname', listname)])
+ ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 0, bgcolor=GREY)
+ ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 1, bgcolor=GREY)
+
+- safeowner = Utils.websafe(cgidata.getvalue('owner', ''))
++ owner = cgidata.getvalue('owner', '')
++ # MAS: Don't websafe twice. TextBox does it.
+ ftable.AddRow([Label(_('Initial list owner address:')),
+- TextBox('owner', safeowner)])
++ TextBox('owner', owner)])
+ ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 0, bgcolor=GREY)
+ ftable.AddCellInfo(ftable.GetCurrentRowIndex(), 1, bgcolor=GREY)
+
+Index: Mailman/Cgi/edithtml.py
+===================================================================
+--- Mailman/Cgi/edithtml.py.orig 2006-01-09 08:06:52.000000000 +0100
++++ Mailman/Cgi/edithtml.py 2006-09-19 22:48:50.000000000 +0200
+@@ -143,7 +143,8 @@
+ doc.AddItem('<p>')
+ doc.AddItem('<hr>')
+ form = Form(mlist.GetScriptURL('edithtml') + '/' + template_name)
+- text = Utils.websafe(Utils.maketext(template_name, raw=1, mlist=mlist))
++ text = Utils.maketext(template_name, raw=1, mlist=mlist)
++ # MAS: Don't websafe twice. TextArea does it.
+ form.AddItem(TextArea('html_code', text, rows=40, cols=75))
+ form.AddItem('<p>' + _('When you are done making changes...'))
+ form.AddItem(SubmitButton('submit', _('Submit Changes')))
+Index: Mailman/Cgi/options.py
+===================================================================
+--- Mailman/Cgi/options.py.orig 2005-12-03 02:07:13.000000000 +0100
++++ Mailman/Cgi/options.py 2006-09-19 22:48:50.000000000 +0200
+@@ -702,7 +702,7 @@
+
+ fullname = Utils.uncanonstr(mlist.getMemberName(user), userlang)
+ if fullname:
+- presentable_user += ', %s' % fullname
++ presentable_user += ', %s' % Utils.websafe(fullname)
+
+ # Do replacements
+ replacements = mlist.GetStandardReplacements(userlang)
+Index: Mailman/Gui/General.py
+===================================================================
+--- Mailman/Gui/General.py.orig 2006-03-23 11:51:25.000000000 +0100
++++ Mailman/Gui/General.py 2006-09-19 22:48:50.000000000 +0200
+@@ -439,13 +439,13 @@
+ GUIBase._setValue(self, mlist, property, val, doc)
+
+ def _escape(self, property, value):
+- # The 'info' property allows HTML, but lets sanitize it to avoid XSS
++ # The 'info' property allows HTML, but let's sanitize it to avoid XSS
+ # exploits. Everything else should be fully escaped.
+ if property <> 'info':
+ return GUIBase._escape(self, property, value)
+ # Sanitize <script> and </script> tags but nothing else. Not the best
+ # solution, but expedient.
+- return re.sub(r'<([/]?script.*?)>', r'<\1>', value)
++ return re.sub(r'(?i)<([/]?script.*?)>', r'<\1>', value)
+
+ def _postValidate(self, mlist, doc):
+ if not mlist.reply_to_address.strip() and \
+Index: Mailman/HTMLFormatter.py
+===================================================================
+--- Mailman/HTMLFormatter.py.orig 2005-08-27 03:40:15.000000000 +0200
++++ Mailman/HTMLFormatter.py 2006-09-19 22:48:50.000000000 +0200
+@@ -1,4 +1,4 @@
+-# Copyright (C) 1998-2003 by the Free Software Foundation, Inc.
++# Copyright (C) 1998-2006 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
+@@ -332,8 +332,12 @@
+ return '</FORM>'
+
+ def FormatBox(self, name, size=20, value=''):
++ if isinstance(value, str):
++ safevalue = Utils.websafe(value)
++ else:
++ safevalue = value
+ return '<INPUT type="Text" name="%s" size="%d" value="%s">' % (
+- name, size, value)
++ name, size, safevalue)
+
+ def FormatSecureBox(self, name):
+ return '<INPUT type="Password" name="%s" size="15">' % name
+Index: Mailman/Utils.py
+===================================================================
+--- Mailman/Utils.py.orig 2006-03-18 18:23:04.000000000 +0100
++++ Mailman/Utils.py 2006-09-19 22:48:50.000000000 +0200
+@@ -204,7 +204,7 @@
+ _badchars = re.compile(r'[][()<>|;^,\000-\037\177-\377]')
+
+ def ValidateEmail(s):
+- """Verify that the an email address isn't grossly evil."""
++ """Verify that an email address isn't grossly evil."""
+ # Pretty minimal, cheesy check. We could do better...
+ if not s or s.count(' ') > 0:
+ raise Errors.MMBadEmailError
+Index: Mailman/htmlformat.py
+===================================================================
+--- Mailman/htmlformat.py.orig 2005-08-27 03:40:15.000000000 +0200
++++ Mailman/htmlformat.py 2006-09-19 22:48:50.000000000 +0200
+@@ -448,7 +448,11 @@
+
+ class TextBox(InputObj):
+ def __init__(self, name, value='', size=mm_cfg.TEXTFIELDWIDTH):
+- InputObj.__init__(self, name, "TEXT", value, checked=0, size=size)
++ if isinstance(value, str):
++ safevalue = Utils.websafe(value)
++ else:
++ safevalue = value
++ InputObj.__init__(self, name, "TEXT", safevalue, checked=0, size=size)
+
+ class Hidden(InputObj):
+ def __init__(self, name, value=''):
+@@ -457,8 +461,12 @@
+ class TextArea:
+ def __init__(self, name, text='', rows=None, cols=None, wrap='soft',
+ readonly=0):
++ if isinstance(text, str):
++ safetext = Utils.websafe(text)
++ else:
++ safetext = text
+ self.name = name
+- self.text = text
++ self.text = safetext
+ self.rows = rows
+ self.cols = cols
+ self.wrap = wrap
Added: trunk/debian/patches/24_CVE-2006-2941.dpatch
===================================================================
--- trunk/debian/patches/24_CVE-2006-2941.dpatch (rev 0)
+++ trunk/debian/patches/24_CVE-2006-2941.dpatch 2006-09-19 21:16:07 UTC (rev 382)
@@ -0,0 +1,441 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 73_CVE-2006-2941.dpatch by <lionel at mamane.lu>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: CVE-2006-2941: DoS caused by standards-breaking RFC 2231 formatted headers.
+
+ at DPATCH@
+Index: misc/CVE-2006-2941.patch
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ misc/CVE-2006-2941.patch 2006-09-19 23:02:23.000000000 +0200
+@@ -0,0 +1,414 @@
++diff --recursive -u email-2.5.7/email/__init__.py email-2.5.8/email/__init__.py
++--- email-2.5.7/email/__init__.py 2006-03-06 01:23:54.000000000 +0100
+++++ email-2.5.8/email/__init__.py 2006-07-25 15:10:39.000000000 +0200
++@@ -3,7 +3,7 @@
++
++ """A package for parsing, handling, and generating email messages."""
++
++-__version__ = '2.5.5'
+++__version__ = '2.5.5.debian1'
++
++ __all__ = [
++ 'base64MIME',
++diff --recursive -u email-2.5.7/email/_parseaddr.py email-2.5.8/email/_parseaddr.py
++--- email-2.5.7/email/_parseaddr.py 2006-03-06 01:23:54.000000000 +0100
+++++ email-2.5.8/email/_parseaddr.py 2006-06-13 05:43:49.000000000 +0200
++@@ -365,6 +365,7 @@
++ break
++ elif allowcomments and self.field[self.pos] == '(':
++ slist.append(self.getcomment())
+++ continue # have already advanced pos from getcomment
++ elif self.field[self.pos] == '\\':
++ quote = True
++ else:
++diff --recursive -u email-2.5.7/email/test/test_email.py email-2.5.8/email/test/test_email.py
++--- email-2.5.7/email/test/test_email.py 2006-03-06 01:23:53.000000000 +0100
+++++ email-2.5.8/email/test/test_email.py 2006-07-26 05:58:13.000000000 +0200
++@@ -9,7 +9,7 @@
++ import unittest
++ import warnings
++ from cStringIO import StringIO
++-from types import StringType, ListType
+++from types import StringType, ListType, TupleType
++
++ import email
++
++@@ -2064,6 +2064,12 @@
++ ['foo: ;', '"Jason R. Mastaler" <jason at dom.ain>']),
++ [('', ''), ('Jason R. Mastaler', 'jason at dom.ain')])
++
+++ def test_getaddresses_embedded_comment(self):
+++ """Test proper handling of a nested comment"""
+++ eq = self.assertEqual
+++ addrs = Utils.getaddresses(['User ((nested comment)) <foo at bar.com>'])
+++ eq(addrs[0][1], 'foo at bar.com')
+++
++ def test_utils_quote_unquote(self):
++ eq = self.assertEqual
++ msg = Message()
++@@ -2750,14 +2756,17 @@
++
++ '''
++ msg = email.message_from_string(m)
++- self.assertEqual(msg.get_param('NAME'),
++- (None, None, 'file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEMP_nsmail.htm'))
+++ param = msg.get_param('NAME')
+++ self.failIf(isinstance(param, TupleType))
+++ self.assertEqual(
+++ param,
+++ 'file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEMP_nsmail.htm')
++
++ def test_rfc2231_no_language_or_charset_in_filename(self):
++ m = '''\
++ Content-Disposition: inline;
++-\tfilename*0="This%20is%20even%20more%20";
++-\tfilename*1="%2A%2A%2Afun%2A%2A%2A%20";
+++\tfilename*0*="This%20is%20even%20more%20";
+++\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
++ \tfilename*2="is it not.pdf"
++
++ '''
++@@ -2768,8 +2777,8 @@
++ def test_rfc2231_no_language_or_charset_in_boundary(self):
++ m = '''\
++ Content-Type: multipart/alternative;
++-\tboundary*0="This%20is%20even%20more%20";
++-\tboundary*1="%2A%2A%2Afun%2A%2A%2A%20";
+++\tboundary*0*="This%20is%20even%20more%20";
+++\tboundary*1*="%2A%2A%2Afun%2A%2A%2A%20";
++ \tboundary*2="is it not.pdf"
++
++ '''
++@@ -2777,12 +2786,38 @@
++ self.assertEqual(msg.get_boundary(),
++ 'This is even more ***fun*** is it not.pdf')
++
+++ def test_rfc2231_partly_encoded(self):
+++ m = '''\
+++Content-Disposition: inline;
+++\tfilename*0="''This%20is%20even%20more%20";
+++\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
+++\tfilename*2="is it not.pdf"
+++
+++'''
+++ msg = email.message_from_string(m)
+++ self.assertEqual(
+++ msg.get_filename(),
+++ 'This%20is%20even%20more%20***fun*** is it not.pdf')
+++
+++ def test_rfc2231_partly_nonencoded(self):
+++ m = '''\
+++Content-Disposition: inline;
+++\tfilename*0="This%20is%20even%20more%20";
+++\tfilename*1="%2A%2A%2Afun%2A%2A%2A%20";
+++\tfilename*2="is it not.pdf"
+++
+++'''
+++ msg = email.message_from_string(m)
+++ self.assertEqual(
+++ msg.get_filename(),
+++ 'This%20is%20even%20more%20%2A%2A%2Afun%2A%2A%2A%20is it not.pdf')
+++
++ def test_rfc2231_no_language_or_charset_in_charset(self):
++ # This is a nonsensical charset value, but tests the code anyway
++ m = '''\
++ Content-Type: text/plain;
++-\tcharset*0="This%20is%20even%20more%20";
++-\tcharset*1="%2A%2A%2Afun%2A%2A%2A%20";
+++\tcharset*0*="This%20is%20even%20more%20";
+++\tcharset*1*="%2A%2A%2Afun%2A%2A%2A%20";
++ \tcharset*2="is it not.pdf"
++
++ '''
++@@ -2793,8 +2828,8 @@
++ def test_rfc2231_bad_encoding_in_filename(self):
++ m = '''\
++ Content-Disposition: inline;
++-\tfilename*0="bogus'xx'This%20is%20even%20more%20";
++-\tfilename*1="%2A%2A%2Afun%2A%2A%2A%20";
+++\tfilename*0*="bogus'xx'This%20is%20even%20more%20";
+++\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
++ \tfilename*2="is it not.pdf"
++
++ '''
++@@ -2825,9 +2860,9 @@
++ def test_rfc2231_bad_character_in_filename(self):
++ m = '''\
++ Content-Disposition: inline;
++-\tfilename*0="ascii'xx'This%20is%20even%20more%20";
++-\tfilename*1="%2A%2A%2Afun%2A%2A%2A%20";
++-\tfilename*2="is it not.pdf%E2"
+++\tfilename*0*="ascii'xx'This%20is%20even%20more%20";
+++\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20";
+++\tfilename*2*="is it not.pdf%E2"
++
++ '''
++ msg = email.message_from_string(m)
++@@ -2835,6 +2870,102 @@
++ 'This is even more ***fun*** is it not.pdf\xe2')
++
++
+++ def test_rfc2231_unknown_encoding(self):
+++ m = """\
+++Content-Transfer-Encoding: 8bit
+++Content-Disposition: inline; filename*=X-UNKNOWN''myfile.txt
+++
+++"""
+++ msg = email.message_from_string(m)
+++ self.assertEqual(msg.get_filename(), 'myfile.txt')
+++
+++ def test_rfc2231_single_tick_in_filename_extended(self):
+++ eq = self.assertEqual
+++ m = """\
+++Content-Type: application/x-foo;
+++\tname*0*=\"Frank's\"; name*1*=\" Document\"
+++
+++"""
+++ msg = email.message_from_string(m)
+++ charset, language, s = msg.get_param('name')
+++ eq(charset, None)
+++ eq(language, None)
+++ eq(s, "Frank's Document")
+++
+++ def test_rfc2231_single_tick_in_filename(self):
+++ m = """\
+++Content-Type: application/x-foo; name*0=\"Frank's\"; name*1=\" Document\"
+++
+++"""
+++ msg = email.message_from_string(m)
+++ param = msg.get_param('name')
+++ self.failIf(isinstance(param, TupleType))
+++ self.assertEqual(param, "Frank's Document")
+++
+++ def test_rfc2231_tick_attack_extended(self):
+++ eq = self.assertEqual
+++ m = """\
+++Content-Type: application/x-foo;
+++\tname*0*=\"us-ascii'en-us'Frank's\"; name*1*=\" Document\"
+++
+++"""
+++ msg = email.message_from_string(m)
+++ charset, language, s = msg.get_param('name')
+++ eq(charset, 'us-ascii')
+++ eq(language, 'en-us')
+++ eq(s, "Frank's Document")
+++
+++ def test_rfc2231_tick_attack(self):
+++ m = """\
+++Content-Type: application/x-foo;
+++\tname*0=\"us-ascii'en-us'Frank's\"; name*1=\" Document\"
+++
+++"""
+++ msg = email.message_from_string(m)
+++ param = msg.get_param('name')
+++ self.failIf(isinstance(param, TupleType))
+++ self.assertEqual(param, "us-ascii'en-us'Frank's Document")
+++
+++ def test_rfc2231_no_extended_values(self):
+++ eq = self.assertEqual
+++ m = """\
+++Content-Type: application/x-foo; name=\"Frank's Document\"
+++
+++"""
+++ msg = email.message_from_string(m)
+++ eq(msg.get_param('name'), "Frank's Document")
+++
+++ def test_rfc2231_encoded_then_unencoded_segments(self):
+++ eq = self.assertEqual
+++ m = """\
+++Content-Type: application/x-foo;
+++\tname*0*=\"us-ascii'en-us'My\";
+++\tname*1=\" Document\";
+++\tname*2*=\" For You\"
+++
+++"""
+++ msg = email.message_from_string(m)
+++ charset, language, s = msg.get_param('name')
+++ eq(charset, 'us-ascii')
+++ eq(language, 'en-us')
+++ eq(s, 'My Document For You')
+++
+++ def test_rfc2231_unencoded_then_encoded_segments(self):
+++ eq = self.assertEqual
+++ m = """\
+++Content-Type: application/x-foo;
+++\tname*0=\"us-ascii'en-us'My\";
+++\tname*1*=\" Document\";
+++\tname*2*=\" For You\"
+++
+++"""
+++ msg = email.message_from_string(m)
+++ charset, language, s = msg.get_param('name')
+++ eq(charset, 'us-ascii')
+++ eq(language, 'en-us')
+++ eq(s, 'My Document For You')
+++
+++
++
++ def _testclasses():
++ mod = sys.modules[__name__]
++diff --recursive -u email-2.5.7/email/Utils.py email-2.5.8/email/Utils.py
++--- email-2.5.7/email/Utils.py 2006-03-06 01:23:54.000000000 +0100
+++++ email-2.5.8/email/Utils.py 2006-07-25 15:10:39.000000000 +0200
++@@ -1,14 +1,15 @@
++-# Copyright (C) 2001,2002 Python Software Foundation
++-# Author: barry at zope.com (Barry Warsaw)
+++# Copyright (C) 2001-2006 Python Software Foundation
+++# Author: Barry Warsaw
+++# Contact: email-sig at python.org
++
++-"""Miscellaneous utilities.
++-"""
+++"""Miscellaneous utilities."""
++
++ import time
++ import socket
++ import re
++ import random
++ import os
+++import urllib
++ import warnings
++ from cStringIO import StringIO
++ from types import ListType
++@@ -53,6 +54,7 @@
++ EMPTYSTRING = ''
++ UEMPTYSTRING = u''
++ CRLF = '\r\n'
+++TICK = "'"
++
++ specialsre = re.compile(r'[][\\()<>@,:;".]')
++ escapesre = re.compile(r'[][\\()"]')
++@@ -277,12 +279,14 @@
++ # RFC2231-related functions - parameter encoding and decoding
++ def decode_rfc2231(s):
++ """Decode string according to RFC 2231"""
++- import urllib
++- parts = s.split("'", 2)
++- if len(parts) == 1:
+++ parts = s.split(TICK, 2)
+++ if len(parts) <= 2:
++ return None, None, urllib.unquote(s)
++- charset, language, s = parts
++- return charset, language, urllib.unquote(s)
+++ if len(parts) > 3:
+++ charset, language = pars[:2]
+++ s = TICK.join(parts[2:])
+++ return charset, language, s
+++ return parts
++
++
++ def encode_rfc2231(s, charset=None, language=None):
++@@ -306,35 +310,52 @@
++ def decode_params(params):
++ """Decode parameters list according to RFC 2231.
++
++- params is a sequence of 2-tuples containing (content type, string value).
+++ params is a sequence of 2-tuples containing (param name, string value).
++ """
+++ # Copy params so we don't mess with the original
+++ params = params[:]
++ new_params = []
++- # maps parameter's name to a list of continuations
+++ # Map parameter's name to a list of continuations. The values are a
+++ # 3-tuple of the continuation number, the string value, and a flag
+++ # specifying whether a particular segment is %-encoded.
++ rfc2231_params = {}
++- # params is a sequence of 2-tuples containing (content_type, string value)
++- name, value = params[0]
+++ name, value = params.pop(0)
++ new_params.append((name, value))
++- # Cycle through each of the rest of the parameters.
++- for name, value in params[1:]:
+++ while params:
+++ name, value = params.pop(0)
+++ if name.endswith('*'):
+++ encoded = True
+++ else:
+++ encoded = False
++ value = unquote(value)
++ mo = rfc2231_continuation.match(name)
++ if mo:
++ name, num = mo.group('name', 'num')
++ if num is not None:
++ num = int(num)
++- rfc2231_param1 = rfc2231_params.setdefault(name, [])
++- rfc2231_param1.append((num, value))
+++ rfc2231_params.setdefault(name, []).append((num, value, encoded))
++ else:
++ new_params.append((name, '"%s"' % quote(value)))
++ if rfc2231_params:
++ for name, continuations in rfc2231_params.items():
++ value = []
+++ extended = False
++ # Sort by number
++ continuations.sort()
++- # And now append all values in num order
++- for num, continuation in continuations:
++- value.append(continuation)
++- charset, language, value = decode_rfc2231(EMPTYSTRING.join(value))
++- new_params.append(
++- (name, (charset, language, '"%s"' % quote(value))))
+++ # And now append all values in numerical order, converting
+++ # %-encodings for the encoded segments. If any of the
+++ # continuation names ends in a *, then the entire string, after
+++ # decoding segments and concatenating, must have the charset and
+++ # language specifiers at the beginning of the string.
+++ for num, s, encoded in continuations:
+++ if encoded:
+++ s = urllib.unquote(s)
+++ extended = True
+++ value.append(s)
+++ value = quote(EMPTYSTRING.join(value))
+++ if extended:
+++ charset, language, value = decode_rfc2231(value)
+++ new_params.append((name, (charset, language, '"%s"' % value)))
+++ else:
+++ new_params.append((name, '"%s"' % value))
++ return new_params
++diff --recursive -u email-2.5.7/PKG-INFO email-2.5.8/PKG-INFO
++--- email-2.5.7/PKG-INFO 2006-03-06 02:39:57.000000000 +0100
+++++ email-2.5.8/PKG-INFO 2006-07-26 06:15:58.000000000 +0200
++@@ -1,10 +1,10 @@
++ Metadata-Version: 1.0
++ Name: email
++-Version: 2.5.5
+++Version: 2.5.5.debian1
++ Summary: Standalone email package
++ Home-page: http://www.python.org/sigs/email-sig
++ Author: Barry Warsaw
++-Author-email: barry at python.org
+++Author-email: email-sig at python.org
++ License: UNKNOWN
++ Description: UNKNOWN
++ Platform: UNKNOWN
++diff --recursive -u email-2.5.7/setup.py email-2.5.8/setup.py
++--- email-2.5.7/setup.py 2006-03-06 01:21:59.000000000 +0100
+++++ email-2.5.8/setup.py 2006-07-25 16:08:43.000000000 +0200
++@@ -1,5 +1,3 @@
++-#! /usr/bin/env python
++-#
++ # Copyright (C) 2001-2006 Python Software Foundation
++
++ # Standard distutils setup.py install script for the `mimelib' library, a next
++@@ -20,7 +18,7 @@
++ version=email.__version__,
++ description='Standalone email package',
++ author='Barry Warsaw',
++- author_email='barry at python.org',
+++ author_email='email-sig at python.org',
++ url='http://www.python.org/sigs/email-sig',
++ packages=['email'],
++ )
++diff --recursive -u email-2.5.7/testall.py email-2.5.8/testall.py
++--- email-2.5.7/testall.py 2006-03-06 01:21:59.000000000 +0100
+++++ email-2.5.8/testall.py 2006-07-25 16:09:00.000000000 +0200
++@@ -13,8 +13,8 @@
++ """
++
++ import sys
++-import unittest
++ import getopt
+++import unittest
++
++ from email.test import test_email
++
+Index: misc/Makefile.in
+===================================================================
+--- misc/Makefile.in.orig 2006-09-19 23:01:05.000000000 +0200
++++ misc/Makefile.in 2006-09-19 23:01:08.000000000 +0200
+@@ -94,7 +94,9 @@
+ for p in $(PACKAGES); \
+ do \
+ gunzip -c $(srcdir)/$$p.tar.gz | (cd $(PKGDIR) ; tar xf -); \
+- (cd $(PKGDIR)/$$p ; umask 02 ; PYTHONPATH=$(PYTHONLIBDIR) $(PYTHON) $(SETUPCMD)); \
++ (cd $(PKGDIR)/$$p ; umask 02 ; \
++ if [ "$$p" = "email-2.5.5" ]; then patch -p1 "$(PWD)/CVE-2006-2941.patch"; fi; \
++ PYTHONPATH=$(PYTHONLIBDIR) $(PYTHON) $(SETUPCMD)); \
+ done
+
+ finish:
Added: trunk/debian/patches/25_CVE-2006-4624.dpatch
===================================================================
--- trunk/debian/patches/25_CVE-2006-4624.dpatch (rev 0)
+++ trunk/debian/patches/25_CVE-2006-4624.dpatch 2006-09-19 21:16:07 UTC (rev 382)
@@ -0,0 +1,44 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 74_CVE-2006-4624.dpatch by <lionel at mamane.lu>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Security: log injection vulnerability
+
+ at DPATCH@
+Index: Mailman/Utils.py
+===================================================================
+--- Mailman/Utils.py.orig 2006-09-19 22:58:19.000000000 +0200
++++ Mailman/Utils.py 2006-09-19 23:03:24.000000000 +0200
+@@ -53,6 +53,7 @@
+ from Mailman import Errors
+ from Mailman import Site
+ from Mailman.SafeDict import SafeDict
++from Mailman.Logging.Syslog import syslog
+
+ try:
+ True, False
+@@ -219,9 +220,16 @@
+
+
+
++# Patterns which may be used to form malicious path to inject a new
++# line in the mailman error log. (TK: advisory by Moritz Naumann)
++CRNLpat = re.compile(r'[^\x21-\x7e]')
++
+ def GetPathPieces(envar='PATH_INFO'):
+ path = os.environ.get(envar)
+ if path:
++ if CRNLpat.search(path):
++ path = CRNLpat.split(path)[0]
++ syslog('error', 'Warning: Possible malformed path attack.')
+ return [p for p in path.split('/') if p]
+ return None
+
+@@ -541,7 +549,6 @@
+ text = sdict.interpolate(utemplate)
+ except (TypeError, ValueError), e:
+ # The template is really screwed up
+- from Mailman.Logging.Syslog import syslog
+ syslog('error', 'broken template: %s\n%s', filename, e)
+ pass
+ if raw:
Modified: trunk/debian/patches/series
===================================================================
--- trunk/debian/patches/series 2006-09-19 20:50:43 UTC (rev 381)
+++ trunk/debian/patches/series 2006-09-19 21:16:07 UTC (rev 382)
@@ -9,6 +9,9 @@
16_update_debian.patch -p0
20_qmail_to_mailman.debian.patch -p0
21_newlist_help.patch -p0
+23_CVE-2006-3636.dpatch -p0
+24_CVE-2006-2941.dpatch -p0
+25_CVE-2006-4624.dpatch -p0
30_pipermail_threads.patch -p0
32_MIME_fixup.patch -p0
51_nocompile.pyc.patch -p0
More information about the Pkg-mailman-hackers
mailing list