Following on from what @oSoMoN said, the design of the native messaging protocol makes it particularly amenable to cofinement. It was designed for the needs of Chrome, where sandboxed subprocesses running the browser extension needed a well defined method to communicate with its native code component.
Running in-process was out because there would be no way to know if the code would run under the restrictions the browser uses. So instead the native messaging server is run as its own sub-process with length prefixed JSON messages passed on its stdin and stdout.
The native messaging host is described by a JSON metadata blob that looks something like:
{
"name": "org.gnome.chrome_gnome_shell",
"description": "Native connector for extensions.gnome.org",
"path": "/usr/bin/chrome-gnome-shell",
"type": "stdio",
"allowed_extensions": [
"chrome-gnome-shell@gnome.org"
]
}
In particular, you have:
- the
name
that the web extension requests to talk to - the
path
to the program that will be executed - the list of
allowed_extensions
(for Firefox) orallowed_origins
(for Chrome) that the server is willing to talk to
So one possibility would be to represent this as a D-Bus API looking roughly like the following:
<method name="StartNativeMessaging">
<arg type="s" name="name" direction="in"/>
<arg type="s" name="extensionOrOrigin" direction="in"/>
<arg type="h" name="stdin" direction="out"/>
<arg type="h" name="stdout" direction="out"/>
</method>
When called, the service would look for a matching JSON metadata file and verify that it allows communication with the named extension. If so, it spawns an instance of the app and returns stdin and stdout file descriptors that are pipes to the equivalent descriptors of the app. It may also be necessary to have some kind of process control method too to let the browser terminate the app too.
This could be done as part of snap userd
, although we’d want to make sure userd isn’t left needing to reap child processes (something we tried to avoid for the desktop-launch
feature). Alternatively it could be done in xdg-desktop-portal, which has a well developed permission prompting system and could also be used by Flatpak packaged browsers (something that could make upstream browser code changes more palatable).