SVN: ZODB/tags/3.9.0b5/s Bugs Fixed:

Jim Fulton <[email protected]>
Newsgroups gmane.comp.python.zope.zodb.cvs
Message-ID <20090813215627.CDFEE9417E__47213.0847083919$1250200599$gmane$org@cvs.zope.org>
Log message for revision 102750:
  Bugs Fixed:
  
  - Fixed vulnerabilities in the ZEO network protocol that allow:
  
  CVE-2009-0668 Arbitrary Python code execution in ZODB ZEO storage servers
    CVE-2009-0669 Authentication bypass in ZODB ZEO storage servers
  
  - Limit the number of object ids that can be allocated at once to
    avoid running out of memory.
  

Changed:
  U   ZODB/tags/3.9.0b5/setup.py
  U   ZODB/tags/3.9.0b5/src/CHANGES.txt
  U   ZODB/tags/3.9.0b5/src/ZEO/StorageServer.py
  U   ZODB/tags/3.9.0b5/src/ZEO/auth/auth_digest.py
  U   ZODB/tags/3.9.0b5/src/ZEO/tests/auth_plaintext.py
  U   ZODB/tags/3.9.0b5/src/ZEO/zrpc/connection.py
  U   ZODB/tags/3.9.0b5/src/ZEO/zrpc/marshal.py

-=-
Modified: ZODB/tags/3.9.0b5/setup.py
===================================================================
--- ZODB/tags/3.9.0b5/setup.py	2009-08-13 21:53:34 UTC (rev 102749)
+++ ZODB/tags/3.9.0b5/setup.py	2009-08-13 21:56:27 UTC (rev 102750)
@@ -20,7 +20,7 @@
 interface, rich transaction support, and undo.
 """
 
-VERSION = "3.9.0b4"
+VERSION = "3.9.0b5"
 
 from setuptools import setup, find_packages
 import glob

Modified: ZODB/tags/3.9.0b5/src/CHANGES.txt
===================================================================
--- ZODB/tags/3.9.0b5/src/CHANGES.txt	2009-08-13 21:53:34 UTC (rev 102749)
+++ ZODB/tags/3.9.0b5/src/CHANGES.txt	2009-08-13 21:56:27 UTC (rev 102750)
@@ -2,6 +2,29 @@
  Change History
 ================
 
+3.9.0b5 (2009-08-06)
+====================
+
+Bugs Fixed
+----------
+
+- Fixed vulnerabilities in the ZEO network protocol that allow:
+
+  - CVE-2009-0668 Arbitrary Python code execution in ZODB ZEO storage servers
+  - CVE-2009-0669 Authentication bypass in ZODB ZEO storage servers
+
+  The vulnerabilities only apply if you are using ZEO to share a
+  database among multiple applications or application instances and if
+  untrusted clients are able to connect to your ZEO servers.
+
+3.9.0b4 (2009-07-30)
+====================
+
+Bugs Fixed
+----------
+
+- Sources were ommitted due to setup script problems.
+
 3.9.0b3 (2009-07-30)
 ====================
 

Modified: ZODB/tags/3.9.0b5/src/ZEO/StorageServer.py
===================================================================
--- ZODB/tags/3.9.0b5/src/ZEO/StorageServer.py	2009-08-13 21:53:34 UTC (rev 102749)
+++ ZODB/tags/3.9.0b5/src/ZEO/StorageServer.py	2009-08-13 21:56:27 UTC (rev 102750)
@@ -114,7 +114,7 @@
         # transaction iterator.
         self._txn_iterators_last = {}
 
-    def finish_auth(self, authenticated):
+    def _finish_auth(self, authenticated):
         if not self.auth_realm:
             return 1
         self.authenticated = authenticated
@@ -381,6 +381,7 @@
 
     def new_oids(self, n=100):
         """Return a sequence of n new oids, where n defaults to 100"""
+        n = min(n, 100)
         if self.read_only:
             raise ReadOnlyError()
         if n <= 0:

Modified: ZODB/tags/3.9.0b5/src/ZEO/auth/auth_digest.py
===================================================================
--- ZODB/tags/3.9.0b5/src/ZEO/auth/auth_digest.py	2009-08-13 21:53:34 UTC (rev 102749)
+++ ZODB/tags/3.9.0b5/src/ZEO/auth/auth_digest.py	2009-08-13 21:56:27 UTC (rev 102750)
@@ -121,7 +121,7 @@
         check = hexdigest("%s:%s" % (h_up, challenge))
         if check == response:
             self.connection.setSessionKey(session_key(h_up, self._key_nonce))
-        return self.finish_auth(check == response)
+        return self._finish_auth(check == response)
 
     extensions = [auth_get_challenge, auth_response]
 

Modified: ZODB/tags/3.9.0b5/src/ZEO/tests/auth_plaintext.py
===================================================================
--- ZODB/tags/3.9.0b5/src/ZEO/tests/auth_plaintext.py	2009-08-13 21:53:34 UTC (rev 102749)
+++ ZODB/tags/3.9.0b5/src/ZEO/tests/auth_plaintext.py	2009-08-13 21:56:27 UTC (rev 102750)
@@ -41,7 +41,7 @@
             self.connection.setSessionKey(session_key(username,
                                                       self.database.realm,
                                                       password))
-        return self.finish_auth(dbpw == password_dig)
+        return self._finish_auth(dbpw == password_dig)
 
 class PlaintextClient(Client):
     extensions = ["auth"]

Modified: ZODB/tags/3.9.0b5/src/ZEO/zrpc/connection.py
===================================================================
--- ZODB/tags/3.9.0b5/src/ZEO/zrpc/connection.py	2009-08-13 21:53:34 UTC (rev 102749)
+++ ZODB/tags/3.9.0b5/src/ZEO/zrpc/connection.py	2009-08-13 21:56:27 UTC (rev 102750)
@@ -23,7 +23,7 @@
 
 from ZEO.zrpc import smac
 from ZEO.zrpc.error import ZRPCError, DisconnectedError
-from ZEO.zrpc.marshal import Marshaller
+from ZEO.zrpc.marshal import Marshaller, ServerMarshaller
 from ZEO.zrpc.trigger import trigger
 from ZEO.zrpc.log import short_repr, log
 from ZODB.loglevels import BLATHER, TRACE
@@ -794,6 +794,7 @@
     def __init__(self, sock, addr, obj, mgr):
         self.mgr = mgr
         Connection.__init__(self, sock, addr, obj, 'S')
+        self.marshal = ServerMarshaller()
 
     def handshake(self):
         # Send the server's preferred protocol to the client.

Modified: ZODB/tags/3.9.0b5/src/ZEO/zrpc/marshal.py
===================================================================
--- ZODB/tags/3.9.0b5/src/ZEO/zrpc/marshal.py	2009-08-13 21:53:34 UTC (rev 102749)
+++ ZODB/tags/3.9.0b5/src/ZEO/zrpc/marshal.py	2009-08-13 21:56:27 UTC (rev 102750)
@@ -52,6 +52,20 @@
                 level=logging.ERROR)
             raise
 
+class ServerMarshaller(Marshaller):
+
+    def decode(self, msg):
+        """Decodes msg and returns its parts"""
+        unpickler = cPickle.Unpickler(StringIO(msg))
+        unpickler.find_global = server_find_global
+
+        try:
+            return unpickler.load() # msgid, flags, name, args
+        except:
+            log("can't decode message: %s" % short_repr(msg),
+                level=logging.ERROR)
+            raise
+
 _globals = globals()
 _silly = ('__doc__',)
 
@@ -78,3 +92,19 @@
         return r
 
     raise ZRPCError("Unsafe global: %s.%s" % (module, name))
+
+def server_find_global(module, name):
+    """Helper for message unpickler"""
+    try:
+        if module != 'ZopeUndo.Prefix':
+            raise ImportError
+        m = __import__(module, _globals, _globals, _silly)
+    except ImportError, msg:
+        raise ZRPCError("import error %s: %s" % (module, msg))
+
+    try:
+        r = getattr(m, name)
+    except AttributeError:
+        raise ZRPCError("module %s has no global %s" % (module, name))
+
+    return r
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.