Re: D-Bus service, forking and shared service name

David Sommerseth <[email protected]>
Newsgroups gmane.comp.freedesktop.dbus
Message-ID <[email protected]>
On 26/05/17 16:43, Simon McVittie wrote:
> On Fri, 26 May 2017 at 16:14:36 +0200, David Sommerseth wrote:
>> We would prefer to have a unified bus name (net.openvpn) which is used
>> across all our processes.  Each configuration and running tunnel should
>> then have a unique object path, with their own set of methods.
> 
> Sorry, you can't do that. If you think of well-known bus names as being
> like hostnames, and object paths being like HTTP paths, that's close to how
> it works.

Thanks a lot, Simon!  This makes very much sense, and is how I
understood it.

> You can have several web servers trying to implement the same hostname,
> but if you do, you don't get to decide which one handles a request
> from a client - so in practice it doesn't make sense unless they all
> serve the same content. Semi-similarly, you can have several D-Bus
> processes[1] trying to own the same well-known bus name, but they'll
> be in a queue, and only the process at the front of the queue (the
> current owner) actually gets to handle requests from clients.
>
> The closest you can get to this is one of these two approaches:
> 
> * Have objects in the net.openvpn main process that represent the
>   actual tunnels. Clients communicate with those objects. When clients
>   call methods on those objects, the main process implements those
>   methods by calling methods on the individual tunnel processes
>   (effectively it's behaving like a proxy). It could pass
>   requests straight through without understanding them if you
>   want it to, but it would be more common to have it interpret
>   the method calls and have their implementation be implemented
>   in terms of further method calls.
> 
>   Prior art: NetworkManager exposes D-Bus objects for connections, and
>   some of those objects are implemented in terms of calling D-Bus
>   methods on dnsmasq and/or wpasupplicant instances.

Hmmm ... But there's not so much difference between this approach and
the approach below, is it - in regards to the bus name?
dnsmasq/wpasupplicant already have their own unique bus names already.
But this approach makes NetworkManager act as an advanced proxy (kind of
like Varnish), where it will adopt the NM D-Bus "API" to what the
backend expects, or did I miss understand this?

> -or-
> 
> * Wherever you would expect a method in the net.openvpn main process to
>   return an object path, if it might be in a different process, either
>   return a (bus name, object path) pair instead or have a documented
>   rule for deriving a bus name from the object path. Clients are
>   expected to communicate with the actual tunnel process using the
>   given bus name.
> 
>   Prior art: The Telepathy AccountManager creates connections which
>   are in "connection manager" processes distinct from the AccountManager.

So here the "front-ends" are expected to get in touch with the
"AccountManager", where they're told to "connect to this bus/path" for
further operations ... is this correctly understood?


> To get D-Bus access control to work well, you will probably find that
> you want all your service processes (except for perhaps the main one)
> to get in the queue for a special well-known bus name like
> net.openvpn.anytunnel that is not actually intended to be used in
> any method calls. The reason you should probably do that is that it
> can be used in access-control decisions: the dbus-daemon policy language
> understands <allow send_destination="com.example.foo"> to mean
> "allow sending messages to any process that *is in the queue to own*
> the com.example.foo name", not just the process that currently owns
> the name (i.e. is at the front of the queue) like you might expect.

So I'm just thinking aloud, wondering and pondering ...

 - Front-end application (cli/gui user front-ends) connects to a
   "manager" process which owns net.openvpn.  And asks for a particular
   tunnel to be started.

 - The "manager" generates a unique session ID, which it provides to the
   back-end process setting up the tunnel.  In addition it creates a
   session object the front-end needs to use.

 - The back-end sends a response to the "manager" process to a
   SetupComplete method, together with a unique bus name (for example,
   net.openvpn.backend.$PID).  It would reports its unique session ID to
   the "manager", together with bus name/PID,  object path used, etc.

 - The "manager" when getting the "response" back from the back-end,
   sets up a signal watcher on the back-end object path on the
   back-end's unique bus name.  At this point, the front-end is given
   the "managers" object path to this particular session object.

 - The "manager" will now proxy requests from front-ends to the
   back-ends.  When the front-ends does an operation, the "manager"
   ensures the proper back-end gets the request.

 - When the back-end needs the front-end's attention, it sends a signal
   to the "manager" which proxies that signal to the front-end.


Would this work?

One downside I see with this approach is if the "manager" dies - it may
loose overview of all back-end processes.  The back-end processes may
live longer though, but won't be able to reach the front-ends.  This
might be solved by having a "state file" where all running back-end
processes are logged with managers unique session ID, back-ends PID, bus
name and object paths.  When a new "manager" starts up, it can double
check if these logged processes are still active or not and hook back
into them again.  The front-ends would also need to be "reactivated"
somehow; perhaps they would be required to register with the "manager"
process too before being able to start new tunnels?

But I'm wondering if it makes sense if the various front-ends should
just be able connect directly to the back-ends directly - by being given
the busname and object path provided by the back-end.

What are the pros/cons for these alternatives - proxy requests or direct
backend access?

And I know I need to think more carefully about the ACL side of this.
Did I understand you correctly that I with this approach above can have
an ACL saying:

    <allow send_destination="net.openvpn.backends">

which is tied to the "manager" process, that I can restrict the calls
this way?  So the "manager" process may through this access methods and
objects on net.openvpn.backends.$PID?

And would it be possible or clever to have the manager/back-end
communication on the session bus instead of the system bus?  Given that
the back-ends are started by the "manager" process.


-- 
kind regards,

David Sommerseth

-- 
kind regards,

David Sommerseth
_______________________________________________
dbus mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dbus
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.