[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