Both the version of python-dns in Lenny and Sid suffer from #493519: Regression: 490217 fix (and upstream fix too) break TCP DNS queries http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=493519 As a result, upstream cranked out another release (2.3.3) that fixes this and has some minor cleanups. I'd like to get the upstream version of the fix into Lenny, but haven't uploaded to Sid yet so it would be available if debian-release preferred I extract a minimal change for Lenny. I have packaged 2.3.3-1 and have it running on one of my servers without issue currently. I explicitly tested the DNS over TCP and DNS timeout fixes. A 'minimal' fix would only differ from this upstream by less than 10 lines of real code and would, in my opinion, be riskier since I wouldn't have the advantage of their testing. So my recommendation is that 2.3.3-1 be approved and that it be allowed to migrate to Lenny after the full 10 day transition period if no new issue arise. Complete 2.3.2-1 -> 2.3.3-1 debdiff is attached. Scott K
diff -Nru python-dns-2.3.2/debian/changelog python-dns-2.3.3/debian/changelog --- python-dns-2.3.2/debian/changelog 2008-08-02 18:37:35.000000000 -0400 +++ python-dns-2.3.3/debian/changelog 2008-08-02 18:37:36.000000000 -0400 @@ -1,3 +1,10 @@ +python-dns (2.3.3-1) unstable; urgency=low + + * New upstream release (Closes: #493519) + - Correct regressions from CVE-2008-1447 fix (TCP queries and timeouts) + + -- Scott Kitterman <scott@kitterman.com> Sat, 02 Aug 2008 17:09:19 -0400 + python-dns (2.3.2-1) unstable; urgency=low * New upstream release diff -Nru python-dns-2.3.2/DNS/Base.py python-dns-2.3.3/DNS/Base.py --- python-dns-2.3.2/DNS/Base.py 2008-07-27 21:27:00.000000000 -0400 +++ python-dns-2.3.3/DNS/Base.py 2008-07-31 23:58:03.000000000 -0400 @@ -1,5 +1,5 @@ """ -$Id: Base.py,v 1.12.2.7 2008/07/28 01:27:00 customdesigned Exp $ +$Id: Base.py,v 1.12.2.10 2008/08/01 03:58:03 customdesigned Exp $ This file is part of the pydns project. Homepage: http://pydns.sourceforge.net @@ -98,8 +98,8 @@ self.s = socket.socket(a,b) def processUDPReply(self): - if self.args['timeout'] > 0: - r,w,e = select.select([self.s],[],[],self.args['timeout']) + if self.timeout > 0: + r,w,e = select.select([self.s],[],[],self.timeout) if not len(r): raise DNSError, 'Timeout' (self.reply, self.from_address) = self.s.recvfrom(65535) @@ -108,13 +108,19 @@ return self.processReply() def processTCPReply(self): - self.f = self.s.makefile('r') - header = self.f.read(2) + if self.timeout > 0: + r,w,e = select.select([self.s],[],[],self.timeout) + if not len(r): + raise DNSError, 'Timeout' + f = self.s.makefile('r') + header = f.read(2) if len(header) < 2: raise DNSError,'EOF' count = Lib.unpack16bit(header) - self.reply = self.f.read(count) + self.reply = f.read(count) if len(self.reply) != count: + # FIXME: Since we are non-blocking, it could just be a large reply + # that we need to loop and wait for. raise DNSError,'incomplete reply' self.time_finish=time.time() self.args['server']=self.ns @@ -169,6 +175,7 @@ protocol = self.args['protocol'] self.port = self.args['port'] self.tid = random.randint(0,65535) + self.timeout = self.args['timeout']; opcode = self.args['opcode'] rd = self.args['rd'] server=self.args['server'] @@ -204,18 +211,26 @@ if self.async: return None else: + if not self.response: + raise DNSError,'no working nameservers found' return self.response def sendUDPRequest(self, server): "refactor me" self.response=None - self.socketInit(socket.AF_INET, socket.SOCK_DGRAM) for self.ns in server: + #print "trying udp",self.ns try: + if self.ns.count(':'): + if hasattr(socket,'has_ipv6') and socket.has_ipv6: + self.socketInit(socket.AF_INET6, socket.SOCK_DGRAM) + else: continue + else: + self.socketInit(socket.AF_INET, socket.SOCK_DGRAM) try: # TODO. Handle timeouts &c correctly (RFC) - self.conn() self.time_start=time.time() + self.conn() if not self.async: self.s.send(self.request) r=self.processUDPReply() @@ -228,40 +243,44 @@ r=self.processUDPReply() self.response = r # FIXME: check waiting async queries - #except socket.error: - except None: - continue - break - finally: - if not self.async: - self.s.close() - if not self.response and not self.async: - raise DNSError,'no working nameservers found' + finally: + if not self.async: + self.s.close() + except socket.error: + continue + break def sendTCPRequest(self, server): " do the work of sending a TCP request " self.response=None for self.ns in server: + #print "trying tcp",self.ns try: + if self.ns.count(':'): + if hasattr(socket,'has_ipv6') and socket.has_ipv6: + self.socketInit(socket.AF_INET6, socket.SOCK_STREAM) + else: continue + else: + self.socketInit(socket.AF_INET, socket.SOCK_STREAM) try: # TODO. Handle timeouts &c correctly (RFC) - self.socketInit(socket.AF_INET, socket.SOCK_STREAM) self.time_start=time.time() self.conn() - self.s.setblocking(0) buf = Lib.pack16bit(len(self.request))+self.request + # Keep server from making sendall hang + self.s.setblocking(0) + # FIXME: throws WOULDBLOCK if request too large to fit in + # system buffer self.s.sendall(buf) self.s.shutdown(socket.SHUT_WR) r=self.processTCPReply() if r.header['id'] == self.tid: self.response = r break - except socket.error: - continue - finally: - self.s.close() - if not self.response: - raise DNSError, 'no working nameservers found' + finally: + self.s.close() + except socket.error: + continue #class DnsAsyncRequest(DnsRequest): class DnsAsyncRequest(DnsRequest,asyncore.dispatcher_with_send): @@ -299,6 +318,15 @@ # # $Log: Base.py,v $ +# Revision 1.12.2.10 2008/08/01 03:58:03 customdesigned +# Don't try to close socket when never opened. +# +# Revision 1.12.2.9 2008/08/01 03:48:31 customdesigned +# Fix more breakage from port randomization patch. Support Ipv6 queries. +# +# Revision 1.12.2.8 2008/07/31 18:22:59 customdesigned +# Wait until tcp response at least starts coming in. +# # Revision 1.12.2.7 2008/07/28 01:27:00 customdesigned # Check configured port. # diff -Nru python-dns-2.3.2/DNS/__init__.py python-dns-2.3.3/DNS/__init__.py --- python-dns-2.3.2/DNS/__init__.py 2008-07-27 22:11:07.000000000 -0400 +++ python-dns-2.3.3/DNS/__init__.py 2008-08-01 00:01:25.000000000 -0400 @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -# $Id: __init__.py,v 1.8.2.5 2008/07/28 02:11:07 customdesigned Exp $ +# $Id: __init__.py,v 1.8.2.6 2008/08/01 04:01:25 customdesigned Exp $ # # This file is part of the pydns project. # Homepage: http://pydns.sourceforge.net @@ -9,7 +9,7 @@ # __init__.py for DNS class. -__version__ = '2.3.2' +__version__ = '2.3.3' import Type,Opcode,Status,Class from Base import DnsRequest, DNSError @@ -24,6 +24,9 @@ # # $Log: __init__.py,v $ +# Revision 1.8.2.6 2008/08/01 04:01:25 customdesigned +# Release 2.3.3 +# # Revision 1.8.2.5 2008/07/28 02:11:07 customdesigned # Bump version. # diff -Nru python-dns-2.3.2/PKG-INFO python-dns-2.3.3/PKG-INFO --- python-dns-2.3.2/PKG-INFO 2008-07-27 22:11:26.000000000 -0400 +++ python-dns-2.3.3/PKG-INFO 2008-08-01 00:14:03.000000000 -0400 @@ -1,11 +1,21 @@ Metadata-Version: 1.0 Name: pydns -Version: 2.3.2 +Version: 2.3.3 Summary: Python DNS library Home-page: http://pydns.sourceforge.net/ -Author: Anthony Baxter and others -Author-email: pydns-developer@lists.sourceforge.net -License: Python license +Author: Stuart D. Gathman +Author-email: stuart@bmsi.com +License: Python License Description: Python DNS library: +Keywords: DNS Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: No Input/Output (Daemon) +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Python License (CNRI Python License) +Classifier: Natural Language :: English +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: Name Service (DNS) +Classifier: Topic :: Software Development :: Libraries :: Python Modules diff -Nru python-dns-2.3.2/pydns.spec python-dns-2.3.3/pydns.spec --- python-dns-2.3.2/pydns.spec 2008-07-24 16:10:08.000000000 -0400 +++ python-dns-2.3.3/pydns.spec 2008-08-01 00:13:16.000000000 -0400 @@ -1,5 +1,5 @@ %define name pydns -%define version 2.3.2 +%define version 2.3.3 %define release 2.4 Summary: Python DNS library @@ -35,8 +35,10 @@ %defattr(-,root,root) %changelog +* Thu Jul 24 2008 Stuart Gathman <stuart@bmsi.com> 2.3.2-2 +- Fix tcp timeout * Thu Jul 24 2008 Stuart Gathman <stuart@bmsi.com> 2.3.2-1 -- Randomize TID +- Randomize TID and source port * Tue May 22 2007 Stuart Gathman <stuart@bmsi.com> 2.3.1-1 - Bug fix release - BTS Patches: diff -Nru python-dns-2.3.2/python-pydns.spec python-dns-2.3.3/python-pydns.spec --- python-dns-2.3.2/python-pydns.spec 2008-07-24 16:10:14.000000000 -0400 +++ python-dns-2.3.3/python-pydns.spec 2008-08-01 00:13:05.000000000 -0400 @@ -1,8 +1,8 @@ %{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} Name: python-pydns -Version: 2.3.2 -Release: 1%{?dist} +Version: 2.3.3 +Release: 2%{?dist} Summary: Python module for DNS (Domain Name Service). Group: Development/Languages @@ -27,7 +27,6 @@ %prep %setup -q -n %{namewithoutpythonprefix}-%{version} - %build %{__python} setup.py build @@ -47,8 +46,10 @@ %{python_sitelib}/DNS/*.py* %changelog +* Thu Jul 24 2008 Stuart Gathman <stuart@bmsi.com> 2.3.2-2 +- Fix tcp timeout * Thu Jul 24 2008 Stuart Gathman <stuart@bmsi.com> 2.3.2-1 -- Randomize TID +- Randomize TID and source port * Tue May 22 2007 Stuart Gathman <stuart@bmsi.com> 2.3.1-1 - Bug fix release - BTS Patches: diff -Nru python-dns-2.3.2/setup.py python-dns-2.3.3/setup.py --- python-dns-2.3.2/setup.py 2007-05-22 16:29:23.000000000 -0400 +++ python-dns-2.3.3/setup.py 2008-08-01 00:01:25.000000000 -0400 @@ -1,6 +1,6 @@ #! /usr/bin/env python # -# $Id: setup.py,v 1.4 2002/05/06 06:32:07 anthonybaxter Exp $ +# $Id: setup.py,v 1.4.2.3 2008/08/01 04:01:25 customdesigned Exp $ # import sys,os @@ -14,19 +14,41 @@ setup( #-- Package description name = 'pydns', - license = 'Python license', + license = 'Python License', version = DNS.__version__, description = 'Python DNS library', long_description = """Python DNS library: """, author = 'Anthony Baxter and others', author_email = 'pydns-developer@lists.sourceforge.net', - url = 'http://pydns.sourceforge.net/', - packages = ['DNS'], + maintainer="Stuart D. Gathman", + maintainer_email="stuart@bmsi.com", + url = 'http://pydns.sourceforge.net/', + packages = ['DNS'], keywords = ['DNS'], + classifiers = [ + 'Development Status :: 5 - Production/Stable', + 'Environment :: No Input/Output (Daemon)', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: Python License (CNRI Python License)', + 'Natural Language :: English', + 'Operating System :: OS Independent', + 'Programming Language :: Python', + 'Topic :: Internet :: Name Service (DNS)', + 'Topic :: Software Development :: Libraries :: Python Modules' + ] ) # # $Log: setup.py,v $ +# Revision 1.4.2.3 2008/08/01 04:01:25 customdesigned +# Release 2.3.3 +# +# Revision 1.4.2.2 2008/08/01 03:58:03 customdesigned +# Don't try to close socket when never opened. +# +# Revision 1.4.2.1 2008/07/28 19:54:13 customdesigned +# Add pypi metadata to setup.py +# # Revision 1.4 2002/05/06 06:32:07 anthonybaxter # filled in a blank #
Attachment:
signature.asc
Description: This is a digitally signed message part.