diff options
author | Hanno Böck <hanno@gentoo.org> | 2008-02-05 11:24:01 +0000 |
---|---|---|
committer | Hanno Böck <hanno@gentoo.org> | 2008-02-05 11:24:01 +0000 |
commit | a0e5e09a344dec3b38ecff9cabf405b4e9545fc4 (patch) | |
tree | 4f35a7918f93cd79146ee05afef44f8195c881c3 /net-mail/mailman | |
parent | Stable on ppc64 (diff) | |
download | gentoo-2-a0e5e09a344dec3b38ecff9cabf405b4e9545fc4.tar.gz gentoo-2-a0e5e09a344dec3b38ecff9cabf405b4e9545fc4.tar.bz2 gentoo-2-a0e5e09a344dec3b38ecff9cabf405b4e9545fc4.zip |
mailman security bump
(Portage version: 2.1.4.1)
Diffstat (limited to 'net-mail/mailman')
-rw-r--r-- | net-mail/mailman/ChangeLog | 8 | ||||
-rw-r--r-- | net-mail/mailman/files/mailman-2.1.9-fix-XSS.patch | 275 | ||||
-rw-r--r-- | net-mail/mailman/mailman-2.1.9-r3.ebuild | 147 |
3 files changed, 429 insertions, 1 deletions
diff --git a/net-mail/mailman/ChangeLog b/net-mail/mailman/ChangeLog index 8d66c1a1a953..dda00d042dcd 100644 --- a/net-mail/mailman/ChangeLog +++ b/net-mail/mailman/ChangeLog @@ -1,6 +1,12 @@ # ChangeLog for net-mail/mailman # Copyright 2002-2008 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/net-mail/mailman/ChangeLog,v 1.105 2008/01/31 20:29:02 hollow Exp $ +# $Header: /var/cvsroot/gentoo-x86/net-mail/mailman/ChangeLog,v 1.106 2008/02/05 11:24:00 hanno Exp $ + +*mailman-2.1.9-r3 (05 Feb 2008) + + 05 Feb 2008; Hanno Boeck <hanno@gentoo.org> + +files/mailman-2.1.9-fix-XSS.patch, +mailman-2.1.9-r3.ebuild: + Patch XSS issues, CVE-2008-0564. 31 Jan 2008; Benedikt Böhm <hollow@gentoo.org> mailman-2.1.9.ebuild, mailman-2.1.9-r1.ebuild, mailman-2.1.9-r2.ebuild: diff --git a/net-mail/mailman/files/mailman-2.1.9-fix-XSS.patch b/net-mail/mailman/files/mailman-2.1.9-fix-XSS.patch new file mode 100644 index 000000000000..b80c50dca6fd --- /dev/null +++ b/net-mail/mailman/files/mailman-2.1.9-fix-XSS.patch @@ -0,0 +1,275 @@ +=== modified file 'Mailman/Cgi/edithtml.py' +--- Mailman/Cgi/edithtml.py 2006-08-30 14:54:22 +0000 ++++ Mailman/Cgi/edithtml.py 2007-12-04 19:52:18 +0000 +@@ -1,4 +1,4 @@ +-# Copyright (C) 1998-2006 by the Free Software Foundation, Inc. ++# Copyright (C) 1998-2007 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 +@@ -159,7 +159,20 @@ + doc.AddItem('<hr>') + return + code = cgi_info['html_code'].value +- code = re.sub(r'<([/]?script.*?)>', r'<\1>', code) ++ if Utils.suspiciousHTML(code): ++ doc.AddItem(Header(3, ++ _("""The page you saved contains suspicious HTML that could ++potentially expose your users to cross-site scripting attacks. This change ++has therefore been rejected. If you still want to make these changes, you ++must have shell access to your Mailman server. ++ """))) ++ doc.AddItem(_('See ')) ++ doc.AddItem(Link( ++'http://www.python.org/cgi-bin/faqw-mm.py?req=show&file=faq04.048.htp', ++ _('FAQ 4.48.'))) ++ doc.AddItem(Header(3,_("Page Unchanged."))) ++ doc.AddItem('<hr>') ++ return + langdir = os.path.join(mlist.fullpath(), mlist.preferred_language) + # Make sure the directory exists + omask = os.umask(0) + +=== modified file 'Mailman/Gui/General.py' +--- Mailman/Gui/General.py 2006-08-30 14:54:22 +0000 ++++ Mailman/Gui/General.py 2007-12-04 19:52:18 +0000 +@@ -1,4 +1,4 @@ +-# Copyright (C) 2001-2006 by the Free Software Foundation, Inc. ++# Copyright (C) 2001-2007 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 +@@ -436,17 +442,21 @@ + # Convert any html entities to Unicode + mlist.subject_prefix = Utils.canonstr( + val, mlist.preferred_language) ++ elif property == 'info': ++ if val <> mlist.info: ++ if Utils.suspiciousHTML(val): ++ doc.addError(_("""The <b>info</b> attribute you saved ++contains suspicious HTML that could potentially expose your users to cross-site ++scripting attacks. This change has therefore been rejected. If you still want ++to make these changes, you must have shell access to your Mailman server. ++This change can be made with bin/withlist or with bin/config_list by setting ++mlist.info. ++ """)) ++ else: ++ mlist.info = val + else: + GUIBase._setValue(self, mlist, property, val, doc) + +- def _escape(self, property, value): +- # 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'(?i)<([/]?script.*?)>', r'<\1>', value) + + def _postValidate(self, mlist, doc): + if not mlist.reply_to_address.strip() and \ + +=== modified file 'Mailman/Gui/GUIBase.py' +--- Mailman/Gui/GUIBase.py 2005-08-27 01:40:17 +0000 ++++ Mailman/Gui/GUIBase.py 2007-11-18 20:01:26 +0000 +@@ -1,4 +1,4 @@ +-# Copyright (C) 2002-2004 by the Free Software Foundation, Inc. ++# Copyright (C) 2002-2007 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 +@@ -12,7 +12,8 @@ + # + # You should have received a copy of the GNU General Public License + # along with this program; if not, write to the Free Software +-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++# USA. + + """Base class for all web GUI components.""" + +@@ -122,10 +127,6 @@ + # Validate all the attributes for this category + pass + +- def _escape(self, property, value): +- value = value.replace('<', '<') +- return value +- + def handleForm(self, mlist, category, subcat, cgidata, doc): + for item in self.GetConfigInfo(mlist, category, subcat): + # Skip descriptions and legacy non-attributes +@@ -144,10 +145,9 @@ + elif not cgidata.has_key(property): + continue + elif isinstance(cgidata[property], ListType): +- val = [self._escape(property, x.value) +- for x in cgidata[property]] ++ val = [x.value for x in cgidata[property]] + else: +- val = self._escape(property, cgidata[property].value) ++ val = cgidata[property].value + # Coerce the value to the expected type, raising exceptions if the + # value is invalid. + try: + +=== modified file 'Mailman/Utils.py' +--- Mailman/Utils.py 2007-11-25 08:04:30 +0000 ++++ Mailman/Utils.py 2007-12-04 19:52:18 +0000 +@@ -876,3 +876,154 @@ + except (LookupError, UnicodeError, ValueError, HeaderParseError): + # possibly charset problem. return with undecoded string in one line. + return EMPTYSTRING.join(s.splitlines()) ++ ++ ++# Patterns and functions to flag possible XSS attacks in HTML. ++# This list is compiled from information at http://ha.ckers.org/xss.html, ++# http://www.quirksmode.org/js/events_compinfo.html, ++# http://www.htmlref.com/reference/appa/events1.htm, ++# http://lxr.mozilla.org/mozilla/source/content/events/src/nsDOMEvent.cpp#59, ++# http://www.w3.org/TR/DOM-Level-2-Events/events.html and ++# http://www.xulplanet.com/references/elemref/ref_EventHandlers.html ++# Many thanks are due to Moritz Naumann for his assistance with this. ++_badwords = [ ++ '<i?frame', ++ '<link', ++ '<meta', ++ '<script', ++ r'(?:^|\W)j(?:ava)?script(?:\W|$)', ++ r'(?:^|\W)vbs(?:cript)?(?:\W|$)', ++ r'(?:^|\W)domactivate(?:\W|$)', ++ r'(?:^|\W)domattrmodified(?:\W|$)', ++ r'(?:^|\W)domcharacterdatamodified(?:\W|$)', ++ r'(?:^|\W)domfocus(?:in|out)(?:\W|$)', ++ r'(?:^|\W)dommenuitem(?:in)?active(?:\W|$)', ++ r'(?:^|\W)dommousescroll(?:\W|$)', ++ r'(?:^|\W)domnodeinserted(?:intodocument)?(?:\W|$)', ++ r'(?:^|\W)domnoderemoved(?:fromdocument)?(?:\W|$)', ++ r'(?:^|\W)domsubtreemodified(?:\W|$)', ++ r'(?:^|\W)fscommand(?:\W|$)', ++ r'(?:^|\W)onabort(?:\W|$)', ++ r'(?:^|\W)on(?:de)?activate(?:\W|$)', ++ r'(?:^|\W)on(?:after|before)print(?:\W|$)', ++ r'(?:^|\W)on(?:after|before)update(?:\W|$)', ++ r'(?:^|\W)onbefore(?:(?:de)?activate|copy|cut|editfocus|paste)(?:\W|$)', ++ r'(?:^|\W)onbeforeunload(?:\W|$)', ++ r'(?:^|\W)onbegin(?:\W|$)', ++ r'(?:^|\W)onblur(?:\W|$)', ++ r'(?:^|\W)onbounce(?:\W|$)', ++ r'(?:^|\W)onbroadcast(?:\W|$)', ++ r'(?:^|\W)on(?:cell)?change(?:\W|$)', ++ r'(?:^|\W)oncheckboxstatechange(?:\W|$)', ++ r'(?:^|\W)on(?:dbl)?click(?:\W|$)', ++ r'(?:^|\W)onclose(?:\W|$)', ++ r'(?:^|\W)oncommand(?:update)?(?:\W|$)', ++ r'(?:^|\W)oncomposition(?:end|start)(?:\W|$)', ++ r'(?:^|\W)oncontextmenu(?:\W|$)', ++ r'(?:^|\W)oncontrolselect(?:\W|$)', ++ r'(?:^|\W)oncopy(?:\W|$)', ++ r'(?:^|\W)oncut(?:\W|$)', ++ r'(?:^|\W)ondataavailable(?:\W|$)', ++ r'(?:^|\W)ondataset(?:changed|complete)(?:\W|$)', ++ r'(?:^|\W)ondrag(?:drop|end|enter|exit|gesture|leave|over)?(?:\W|$)', ++ r'(?:^|\W)ondragstart(?:\W|$)', ++ r'(?:^|\W)ondrop(?:\W|$)', ++ r'(?:^|\W)onend(?:\W|$)', ++ r'(?:^|\W)onerror(?:update)?(?:\W|$)', ++ r'(?:^|\W)onfilterchange(?:\W|$)', ++ r'(?:^|\W)onfinish(?:\W|$)', ++ r'(?:^|\W)onfocus(?:in|out)?(?:\W|$)', ++ r'(?:^|\W)onhelp(?:\W|$)', ++ r'(?:^|\W)oninput(?:\W|$)', ++ r'(?:^|\W)onkey(?:up|down|press)(?:\W|$)', ++ r'(?:^|\W)onlayoutcomplete(?:\W|$)', ++ r'(?:^|\W)on(?:un)?load(?:\W|$)', ++ r'(?:^|\W)onlosecapture(?:\W|$)', ++ r'(?:^|\W)onmedia(?:complete|error)(?:\W|$)', ++ r'(?:^|\W)onmouse(?:down|enter|leave|move|out|over|up|wheel)(?:\W|$)', ++ r'(?:^|\W)onmove(?:end|start)?(?:\W|$)', ++ r'(?:^|\W)on(?:off|on)line(?:\W|$)', ++ r'(?:^|\W)onoutofsync(?:\W|$)', ++ r'(?:^|\W)onoverflow(?:changed)?(?:\W|$)', ++ r'(?:^|\W)onpage(?:hide|show)(?:\W|$)', ++ r'(?:^|\W)onpaint(?:\W|$)', ++ r'(?:^|\W)onpaste(?:\W|$)', ++ r'(?:^|\W)onpause(?:\W|$)', ++ r'(?:^|\W)onpopup(?:hidden|hiding|showing|shown)(?:\W|$)', ++ r'(?:^|\W)onprogress(?:\W|$)', ++ r'(?:^|\W)onpropertychange(?:\W|$)', ++ r'(?:^|\W)onradiostatechange(?:\W|$)', ++ r'(?:^|\W)onreadystatechange(?:\W|$)', ++ r'(?:^|\W)onrepeat(?:\W|$)', ++ r'(?:^|\W)onreset(?:\W|$)', ++ r'(?:^|\W)onresize(?:end|start)?(?:\W|$)', ++ r'(?:^|\W)onresume(?:\W|$)', ++ r'(?:^|\W)onreverse(?:\W|$)', ++ r'(?:^|\W)onrow(?:delete|enter|exit|inserted)(?:\W|$)', ++ r'(?:^|\W)onrows(?:delete|enter|inserted)(?:\W|$)', ++ r'(?:^|\W)onscroll(?:\W|$)', ++ r'(?:^|\W)onseek(?:\W|$)', ++ r'(?:^|\W)onselect(?:start)?(?:\W|$)', ++ r'(?:^|\W)onselectionchange(?:\W|$)', ++ r'(?:^|\W)onstart(?:\W|$)', ++ r'(?:^|\W)onstop(?:\W|$)', ++ r'(?:^|\W)onsubmit(?:\W|$)', ++ r'(?:^|\W)onsync(?:from|to)preference(?:\W|$)', ++ r'(?:^|\W)onsyncrestored(?:\W|$)', ++ r'(?:^|\W)ontext(?:\W|$)', ++ r'(?:^|\W)ontimeerror(?:\W|$)', ++ r'(?:^|\W)ontrackchange(?:\W|$)', ++ r'(?:^|\W)onunderflow(?:\W|$)', ++ r'(?:^|\W)onurlflip(?:\W|$)', ++ r'(?:^|\W)seeksegmenttime(?:\W|$)', ++ r'(?:^|\W)svgabort(?:\W|$)', ++ r'(?:^|\W)svgerror(?:\W|$)', ++ r'(?:^|\W)svgload(?:\W|$)', ++ r'(?:^|\W)svgresize(?:\W|$)', ++ r'(?:^|\W)svgscroll(?:\W|$)', ++ r'(?:^|\W)svgunload(?:\W|$)', ++ r'(?:^|\W)svgzoom(?:\W|$)', ++ ] ++ ++ ++# This is the actual re to look for the above patterns ++_badhtml = re.compile('|'.join(_badwords), re.IGNORECASE) ++# This is used to filter non-printable us-ascii characters, some of which ++# can be used to break words to avoid recognition. ++_filterchars = re.compile('[\000-\011\013\014\016-\037\177-\237]') ++# This is used to recognize '&#' and '%xx' strings for _translate which ++# translates them to characters ++_encodedchars = re.compile('(&#[0-9]+;?)|(&#x[0-9a-f]+;?)|(%[0-9a-f]{2})', ++ re.IGNORECASE) ++ ++ ++def _translate(mo): ++ """Translate &#... and %xx encodings into the encoded character.""" ++ match = mo.group().lower().strip('&#;') ++ try: ++ if match.startswith('x') or match.startswith('%'): ++ val = int(match[1:], 16) ++ else: ++ val = int(match, 10) ++ except ValueError: ++ return '' ++ if val < 256: ++ return chr(val) ++ else: ++ return '' ++ ++ ++def suspiciousHTML(html): ++ """Check HTML string for various tags, script language names and ++ 'onxxx' actions that can be used in XSS attacks. ++ Currently, this a very simple minded test. It just looks for ++ patterns without analyzing context. Thus, it potentially flags lots ++ of benign stuff. ++ Returns True if anything suspicious found, False otherwise. ++ """ ++ ++ if _badhtml.search(_filterchars.sub( ++ '', _encodedchars.sub(_translate, html))): ++ return True ++ else: ++ return False + diff --git a/net-mail/mailman/mailman-2.1.9-r3.ebuild b/net-mail/mailman/mailman-2.1.9-r3.ebuild new file mode 100644 index 000000000000..78941571db85 --- /dev/null +++ b/net-mail/mailman/mailman-2.1.9-r3.ebuild @@ -0,0 +1,147 @@ +# Copyright 1999-2008 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/net-mail/mailman/mailman-2.1.9-r3.ebuild,v 1.1 2008/02/05 11:24:00 hanno Exp $ + +inherit eutils python multilib + +DESCRIPTION="A python-based mailing list server with an extensive web interface" +SRC_URI="mirror://sourceforge/${PN}/${P}.tgz" +HOMEPAGE="http://www.list.org/" + +SLOT="0" +LICENSE="GPL-2" +KEYWORDS="~amd64 ~ppc ~sparc ~x86" +IUSE="" + +DEPEND=">=dev-lang/python-2.3 + virtual/mta + virtual/cron + virtual/httpd-cgi" + +pkg_setup() { + INSTALLDIR=${MAILMAN_PREFIX:-"/usr/$(get_libdir)/mailman"} + VAR_PREFIX=${MAILMAN_VAR_PREFIX:-"/var/lib/mailman"} + CGIGID=${MAILMAN_CGIGID:-81} + MAILUSR=${MAILMAN_MAILUSR:-mailman} + MAILUID=${MAILMAN_MAILUID:-280} + MAILGRP=${MAILMAN_MAILGRP:-mailman} + MAILGID=${MAILMAN_MAILGID:-280} + + # Bug #58526: switch to enew{group,user}. + # need to add mailman here for compile process. + # Duplicated at pkg_postinst() for binary install. + enewgroup ${MAILGRP} ${MAILGID} + enewuser ${MAILUSR} ${MAILUID} /bin/bash ${INSTALLDIR} mailman -G cron -c "mailman" +} + +src_unpack() { + unpack ${A} + cd "${S}" + epatch "${FILESDIR}/${PN}-2.1.8_rc1-directory-check.patch" || die "patch failed." + epatch "${FILESDIR}/mailman-2.1.9-fix-XSS.patch" || die "patch failed." +} + +src_compile() { + econf --without-permcheck \ + --prefix="${INSTALLDIR}" \ + --with-mail-gid=${MAILGID} \ + --with-cgi-gid=${CGIGID} \ + --with-cgi-ext="${MAILMAN_CGIEXT}" \ + --with-var-prefix="${VAR_PREFIX}" \ + --with-username=${MAILUSR} \ + --with-groupname=${MAILGRP} \ + || die "configure failed" + + emake || die "make failed" +} + +src_install () { + emake "DESTDIR=${D}" doinstall || die + + insinto /etc/apache2/modules.d + doins "${FILESDIR}/50_mailman.conf" + dosed "s:/usr/local/mailman/cgi-bin:${INSTALLDIR}/cgi-bin:g" /etc/apache2/modules.d/50_mailman.conf + dosed "s:/usr/local/mailman/archives:${VAR_PREFIX}/archives:g" /etc/apache2/modules.d/50_mailman.conf + + newdoc "${FILESDIR}/README.gentoo-r2" README.gentoo || die "newdoc failed" + + dodoc ACK* BUGS FAQ NEWS README* TODO UPGRADING INSTALL contrib/mailman.mc \ + contrib/README.check_perms_grsecurity contrib/virtusertable || die "dodoc failed" + + exeinto ${INSTALLDIR}/bin + doexe build/contrib/*.py contrib/majordomo2mailman.pl contrib/auto \ + contrib/mm-handler* || die + + dodir /etc/mailman + mv "${D}/${INSTALLDIR}/Mailman/mm_cfg.py" "${D}/etc/mailman" + dosym /etc/mailman/mm_cfg.py ${INSTALLDIR}/Mailman/mm_cfg.py + + # Save the old config for updates from pre-2.1.9-r2 + # To be removed some distant day + for i in /var/mailman /home/mailman /usr/local/mailman ${INSTALLDIR} + do + if [ -f ${i}/Mailman/mm_cfg.py ] && ! [ -L ${i}/Mailman/mm_cfg.py ]; then + cp ${i}/Mailman/mm_cfg.py "${D}/etc/mailman/mm_cfg.py" + fi + done + + newinitd "${FILESDIR}/mailman.rc" mailman + + keepdir ${VAR_PREFIX}/logs + keepdir ${VAR_PREFIX}/locks + keepdir ${VAR_PREFIX}/spam + keepdir ${VAR_PREFIX}/archives/public + keepdir ${VAR_PREFIX}/archives/private + keepdir ${VAR_PREFIX}/lists + keepdir ${VAR_PREFIX}/qfiles + + chown -R ${MAILUSR}:${MAILGRP} "${D}/${VAR_PREFIX}" "${D}/${INSTALLDIR}" "${D}"/etc/mailman/* + chmod 2775 "${D}/${INSTALLDIR}" "${D}/${INSTALLDIR}"/templates/* \ + "${D}/${INSTALLDIR}"/messages/* "${D}/${VAR_PREFIX}" "${D}/${VAR_PREFIX}"/{logs,lists,spam,locks,archives/public} + chmod 2750 "${D}/${VAR_PREFIX}/archives/private" + chmod 2770 "${D}/${VAR_PREFIX}/qfiles" + chmod 2755 "${D}/${INSTALLDIR}"/cgi-bin/* "${D}/${INSTALLDIR}/mail/mailman" + +} + +pkg_postinst() { + python_mod_optimize ${INSTALLDIR}/bin/ ${INSTALLDIR}/Mailman + + enewgroup ${MAILGRP} ${MAILGID} + enewuser ${MAILUSR} ${MAILUID} -1 ${INSTALLDIR} mailman -G cron -c "mailman" + elog + elog "Please read /usr/share/doc/${PF}/README.gentoo.bz2 for additional" + elog "Setup information, mailman will NOT run unless you follow" + elog "those instructions!" + elog + + elog "An example Mailman configuration file for Apache has been installed into:" + elog " ${APACHE_MODULES_CONFDIR}/50_mailman.conf" + elog + elog "To enable, you will need to add \"-D MAILMAN\" to" + elog "/etc/conf.d/apache2." + elog + + ewarn "Default-Configuration has changed deeply in 2.1.9-r2. You can configure" + ewarn "mailman with the following variables:" + ewarn "MAILMAN_PREFIX (default: /usr/$(get_libdir)/mailman)" + ewarn "MAILMAN_VAR_PREFIX (default: /var/lib/mailman)" + ewarn "MAILMAN_CGIGID (default: 81)" + ewarn "MAILMAN_CGIEXT (default: empty)" + ewarn "MAILMAN_MAILUSR (default: mailman)" + ewarn "MAILMAN_MAILUID (default: 280)" + ewarn "MAILMAN_MAILGRP (default: mailman)" + ewarn "MAILMAN_MAILGID (default: 280)" + ewarn + ewarn "Config file is now symlinked in /etc/mailman, so etc-update works." + ewarn + ewarn "If you're upgrading from below 2.1.9-r2 or changed MAILMAN_PREFIX, you" + ewarn "MUST change the homedir of the mailman-user manually:" + ewarn "usermod -d ${INSTALLDIR} mailman" + ebeep +} + +pkg_postrm() { + INSTALLDIR=${MAILMAN_PREFIX:-"/usr/$(get_libdir)/mailman"} + python_mod_cleanup ${INSTALLDIR}/bin ${INSTALLDIR}/Mailman +} |