[patch][python] Various validation improvements

Simon McVittie simon.mcvittie at collabora.co.uk
Fri Mar 2 10:55:10 PST 2007


For review:

* Don't let the user call methods on the reserved local path - we'll get
  kicked off the bus if they do.
* Don't try to introspect the reserved local path - same problem.
* Do earlier validation of bus names etc. in client proxies.

* SignalMatch: check that interface, member and sender are either valid, or None

* ProxyObject: allow named_service to be None, in preparation for peer-to-peer
  connections. If so, never attempt to follow name owner changes (doesn't make
  sense when you're talking directly to the peer).
* _ProxyMethod: allow interface to be None, for when a method call is made
  on a ProxyObject without going via a dbus.Interface.

* dbus.service.Object: don't let the user try to export objects on the local
  path reserved by libdbus/dbus-daemon, or on an invalid path.
* BusName: don't even try to claim an invalid bus name either.

>From cf48b799ebdcaf7dca0b6f729516b413be21e989 Mon Sep 17 00:00:00 2001
From: Simon McVittie <simon.mcvittie at collabora.co.uk>
Date: Fri, 2 Mar 2007 18:12:47 +0000
Subject: [PATCH] * Don't let the user call methods on the reserved local path - we'll get
  kicked off the bus if they do.
* Don't try to introspect the reserved local path - same problem.
* Do earlier validation of bus names etc. in client proxies.
---
 dbus/proxies.py |   19 ++++++++++++++++++-
 1 files changed, 18 insertions(+), 1 deletions(-)

diff --git a/dbus/proxies.py b/dbus/proxies.py
index 46382a5..8a11a2a 100644
--- a/dbus/proxies.py
+++ b/dbus/proxies.py
@@ -41,6 +41,10 @@ BUS_DAEMON_NAME = 'org.freedesktop.DBus'
 BUS_DAEMON_PATH = '/org/freedesktop/DBus'
 BUS_DAEMON_IFACE = BUS_DAEMON_NAME
 
+# This is special in libdbus - the bus daemon will kick us off if we try to
+# send any message to it :-/
+LOCAL_PATH = '/org/freedesktop/DBus/Local'
+
 
 class _ReplyHandler(object):
     __slots__ = ('_on_error', '_on_reply', '_get_args_options')
@@ -93,12 +97,21 @@ class _ProxyMethod:
     to a specific named Service.
     """
     def __init__(self, proxy, connection, named_service, object_path, method_name, iface):
+        if object_path == LOCAL_PATH:
+            raise DBusException('Methods may not be called on the reserved '
+                                'path %s' % LOCAL_PATH)
+
+        # trust that the proxy, and the properties it had, are OK
         self._proxy          = proxy
         self._connection     = connection
         self._named_service  = named_service
         self._object_path    = object_path
+        # fail early if the method name is bad
+        _dbus_bindings.validate_member_name(method_name)
         # the test suite relies on the existence of this property
         self._method_name    = method_name
+        # fail early if the interface name is bad
+        _dbus_bindings.validate_interface_name(iface)
         self._dbus_interface = iface
 
     def __call__(self, *args, **keywords):
@@ -212,7 +225,11 @@ class ProxyObject:
             bus._require_main_loop()   # we don't get the signals otherwise
 
         self._bus           = bus
+
+        _dbus_bindings.validate_bus_name(named_service)
         self._named_service = named_service
+
+        _dbus_bindings.validate_object_path(object_path)
         self.__dbus_object_path__ = object_path
 
         if (named_service[:1] != ':' and named_service != BUS_DAEMON_NAME
@@ -242,7 +259,7 @@ class ProxyObject:
         # and calls the callback which re-takes the lock
         self._introspect_lock = RLock()
 
-        if not introspect:
+        if not introspect or self.__dbus_object_path__ == LOCAL_PATH:
             self._introspect_state = self.INTROSPECT_STATE_DONT_INTROSPECT
         else:
             self._introspect_state = self.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS
-- 
1.5.0.1

>From f2fda30b23b0176dd314329050127f61b5e92255 Mon Sep 17 00:00:00 2001
From: Simon McVittie <simon.mcvittie at collabora.co.uk>
Date: Fri, 2 Mar 2007 18:38:00 +0000
Subject: [PATCH] SignalMatch: check that interface, member and sender are either valid, or None

---
 dbus/_dbus.py |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/dbus/_dbus.py b/dbus/_dbus.py
index 86ba2d8..353b2fd 100644
--- a/dbus/_dbus.py
+++ b/dbus/_dbus.py
@@ -73,6 +73,15 @@ class SignalMatch(object):
                  interface_keyword=None, member_keyword=None,
                  message_keyword=None, destination_keyword=None,
                  **kwargs):
+        if member is not None:
+            _dbus_bindings.validate_member_name(member)
+        if dbus_interface is not None:
+            _dbus_bindings.validate_interface_name(dbus_interface)
+        if sender is not None:
+            _dbus_bindings.validate_bus_name(sender)
+        if object_path is not None:
+            _dbus_bindings.validate_object_path(object_path)
+
         self._conn_weakref = weakref.ref(conn)
         self._sender = sender
         self._interface = dbus_interface
-- 
1.5.0.1

>From 5ee2e05d5056584d589991f5d5fd0d22df598676 Mon Sep 17 00:00:00 2001
From: Simon McVittie <simon.mcvittie at collabora.co.uk>
Date: Fri, 2 Mar 2007 18:41:01 +0000
Subject: [PATCH] * ProxyObject: allow named_service to be None, in preparation for peer-to-peer
  connections. If so, never attempt to follow name owner changes (doesn't make
  sense when you're talking directly to the peer).
* _ProxyMethod: allow interface to be None, for when a method call is made
  on a ProxyObject without going via a dbus.Interface.
---
 dbus/proxies.py |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/dbus/proxies.py b/dbus/proxies.py
index 8a11a2a..3ade930 100644
--- a/dbus/proxies.py
+++ b/dbus/proxies.py
@@ -111,7 +111,8 @@ class _ProxyMethod:
         # the test suite relies on the existence of this property
         self._method_name    = method_name
         # fail early if the interface name is bad
-        _dbus_bindings.validate_interface_name(iface)
+        if iface is not None:
+            _dbus_bindings.validate_interface_name(iface)
         self._dbus_interface = iface
 
     def __call__(self, *args, **keywords):
@@ -226,13 +227,15 @@ class ProxyObject:
 
         self._bus           = bus
 
-        _dbus_bindings.validate_bus_name(named_service)
+        if named_service is not None:
+            _dbus_bindings.validate_bus_name(named_service)
         self._named_service = named_service
 
         _dbus_bindings.validate_object_path(object_path)
         self.__dbus_object_path__ = object_path
 
-        if (named_service[:1] != ':' and named_service != BUS_DAEMON_NAME
+        if (named_service is not None and named_service[:1] != ':'
+            and named_service != BUS_DAEMON_NAME
             and not follow_name_owner_changes):
             bus_object = bus.get_object(BUS_DAEMON_NAME, BUS_DAEMON_PATH)
             try:
-- 
1.5.0.1

>From cfb1ea5f32a5ab77078ce184cb13602f2e28fec1 Mon Sep 17 00:00:00 2001
From: Simon McVittie <simon.mcvittie at collabora.co.uk>
Date: Fri, 2 Mar 2007 18:43:09 +0000
Subject: [PATCH] * dbus.service.Object: don't let the user try to export objects on the local
  path reserved by libdbus/dbus-daemon, or on an invalid path.
* BusName: don't even try to claim an invalid bus name either.
---
 dbus/service.py |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/dbus/service.py b/dbus/service.py
index 306818e..64f0330 100644
--- a/dbus/service.py
+++ b/dbus/service.py
@@ -33,6 +33,7 @@ from dbus.exceptions import NameExistsException
 from dbus.exceptions import UnknownMethodException
 from dbus.decorators import method
 from dbus.decorators import signal
+from dbus.proxies import LOCAL_PATH
 
 
 _logger = logging.getLogger('dbus.service')
@@ -89,6 +90,9 @@ class BusName(object):
                 services waiting for the requested name if another service
                 already holds it.
         """
+        _dbus_bindings.validate_bus_name(name, allow_well_known=True,
+                                         allow_unique=False)
+
         # get default bus
         if bus == None:
             bus = _dbus.Bus()
@@ -394,6 +398,10 @@ class Object(Interface):
         """
         if object_path is None:
             raise TypeError('The object_path argument is required')
+        _dbus_bindings.validate_object_path(object_path)
+        if object_path == LOCAL_PATH:
+            raise DBusException('Objects may not be exported on the reserved '
+                                'path %s' % LOCAL_PATH)
 
         if isinstance(conn, BusName):
             # someone's using the old API; don't gratuitously break them
-- 
1.5.0.1



More information about the dbus mailing list