[patch] direct service connections

Colin Walters walters at verbum.org
Wed Nov 3 23:36:37 PST 2004


On Thu, 2004-11-04 at 00:19 -0500, Havoc Pennington wrote:

> I'm not saying you would, only that the current API is a per-connection
> object tree.
> 
> You might do multiple object trees e.g. for two unrelated uses of
> libdbus.

Right, I meant "why would you want separate object trees for direct
connection vs bus connection".

> My point is simply that we should be consistent; if semantically the
> object tree should be bound to the connection, then the current API is
> right; if semantically it isn't the current API is wrong. But the direct
> connect feature presumably should be consistent.

I see, that makes sense.

> > And then the bindings level would ensure that only messages to that
> > object are routed over the direct connection?
> 
> Right, the proxy for the specific object would be bound to the direct
> Connection, and the proxy for other objects would not be.

Ok, makes sense too.  I was originally thinking that all proxy objects
would transparently route over the direct connection, but it does
probably make sense to only do it for the specific proxy.

> It sort of breaks the location independence of the object though, I
> would think. Well, it means with a direct connection you always have the
> dbus_g_proxy_new_for_service_owner() semantics, while with indirect you
> have dbus_g_proxy_new_for_service(). I guess we could try to say that
> you can't use direct connections unless you use new_for_service_owner()?

That would be fine by me.  Mostly the goal is to keep the common
functionality of connecting to Imsep inside libdbus; if apps have to be
coded to use dbus_g_proxy_new_for_service_owner or
new ServiceOwner(conn, "org.example.com"), that's fine.  I just don't
want it to seem "weird" to use Imsep (along with future similar
applications).

> > > [1] note here by service you mean process/application, not what dbus
> > > actually calls a service 
> > 
> > Hm, yes, I guess you're right.  It probably isn't useful to have two or
> > more open direct connections to the same process.  But on the other
> > hand, it doesn't seem common for an application to own more than one
> > service; would this be a problem in practice?
> 
> I definitely expect multiple services per app for the session bus.
> Very easy to imagine gnome-panel or metacity for example offering a
> number of services.

Ok.

> In most cases where you want direct though, I'd expect you want a
> separate direct connect per service, e.g. for Imsep the huge messages
> would ideally not block other stuff you're doing.

Hm, yes...although the multiplexing proposal is probably the more
general solution for that particular problem, since it solves the non-
direct case too.

> > On the other other hand, an application might want to explicitly use
> > separate sockets (DBusServer) for each service - this allows one to have
> > distinct OS-level access controls on the particular sockets.  Not sure
> > if that'd be useful in practice though.
> 
> True enough.
> 
> Mention of DBusServer raises another issue - how much code do you have
> to write on the server side to make all this work?

Well, Imsep actually uses the direct connection proposal in a tricky
way, in order to be more secure.  The returned address for
GetDirectConnection is actually a totally separate process than the one
answering the GetDirectConnection request.  The current architecture
looks like this (yay M-x artist-mode!); the application name is above
the SELinux security context in the sample policy:

	  +--------------+
	  |    		 |				 
	  |    app       +\				 
	  | unconfined_t | ---\				 
	  +------+-------+     --\     	     		 
	       	 |	          ---\	     		 
		 | 		      --\    		 
		 |		         ---\		 
	  +------+---------+	     +-------+----------+
	  |                |	     |                  |
	  |  session bus   |	     |   imsep-loader   |
	  | unconfined_t   |	     |  imsep_loader_t  |
	  +------+---------+	     +--------+---------+
		 |		          /---|
		 |		       /--
		 |		    /--
	  +------+---------+    /---
	  |   	           | /--
	  |  imsep-master  +-
	  | imsep_master_t |
	  +----------------+

Basically, imsep-master starts up, spawns imsep-loader (and monitors it
for crashes, etc).  imsep-loader creates a DBusServer, and sends a
message back to imsep-master with the address of the loader DBusServer.
When the app sends a GetDirectConnection message to
org.freedesktop.Imsep, the master simply responds with the address of
the loader.  The app then makes a direct connection to the loader, but
it has no idea that it's actually a separate process.

There are a few reasons I go through this contortion, but the main one
is it allows the imsep_loader_t type to be more restricted in the
SELinux policy; primarily it has no access to the session bus (which
just runs as unconfined_t right now in the Fedora targeted policy).  It
essentially has no ability to initiate information flow (the exception
being SIGCHLD, which is problematic) - it can only receive connections
on the socket initiated by an application and answer them.  A different
approach here might be to have the loader and master be the same
process, but have D-BUS restrict what messages it can send somehow.  My
major worry was that allowing it to send any random D-BUS message to
other applications could quickly lead to total compromise or at least
major privilege escalation, much like the situation is right now with
access to the X connection.

Right now, using Imsep requires that the app use a direct connection.
But my plan is to have the master daemon transparently proxy messages to
the loader.  So that way the separate imsep-loader process is totally
hidden from the client.  If you don't use a direct connection, things
still work.  Except that you get lots of message copying :)

For other applications which just want to use direct connections for
speed purposes alone, they probably wouldn't have to have anything
nearly as complex; it can just use your dbus_server_listen_for_direct.

For reference I've put the relevant files here:
http://web.verbum.org/files/imsep-master.c
http://web.verbum.org/files/imsep-loader.c

They're also available in the Arch repository of course.

> Overall - if I had to pick something today my guess is something like:
> 
>  - add ObjectTree (think of better name for it)
>    random thought: keep it internal and refer to it by Connection,
>    so e.g. you can create one connection from an existing one and 
>    then they share objects, or you have
>    dbus_server_listen_for_direct(DBusConnection*)
>    that takes a bus connection and spawns connections sharing the
>    objects

I think I like dbus_server_listen_for_direct.

>  - don't add MessageQueue (keep it bound to Connection)
>  - have guid for each ObjectTree and include it in the address
>    from the redirect, use to verify
>  - have IORs (including guid in them)

Right, ok.  Where IOR is basically just dbus address + guid.

>  - include dbus_g_proxy_new_direct() or something like that
> 
> I'm sure there are unforeseen complexities though.

I have that feeling too, but hopefully they're solvable.

> What about the old chestnut with ORBit - which port does the Imsep
> server listen on, and can remote X apps get to it through the firewall,
> etc.

Well right now Imsep just listens on a randomly-generated socket
in /tmp.  Maybe I'm being dense, but I'm not sure why you'd want remote
X applications to be talking to an Imsep running on a machine different
from the one the X app itself is running on.  Hm.  So the plan for
remote X display is to have the session bus run on the same machine that
the X server runs on, and for it to speak over TCP or tunnel over X?  In
that case it seems like we actually want *two* session buses.  One which
is solely for inter-application IPC that runs on the same machine as the
X client, and one for hardware interaction etc which runs on the X
server side.  Ug.



More information about the dbus mailing list