bunpen: dbus_proxy: implement restrict_dbus, totally untested function to shell out to xdg-dbus-proxy

This commit is contained in:
2025-01-03 03:38:05 +00:00
parent f25eba7f37
commit 27365ff602
4 changed files with 60 additions and 26 deletions

View File

@@ -4,6 +4,7 @@ all: bunpen
IP ?= $(shell which ip)
IPTABLES ?= $(shell which iptables)
PASTA ?= $(shell which pasta)
XDG_DBUS_PROXY ?= $(shell which xdg-dbus-proxy)
config/runtime_deps.ha: config/runtime_deps.ha.in
test -x "$(IP)"
@@ -12,6 +13,7 @@ config/runtime_deps.ha: config/runtime_deps.ha.in
sed -e "s:@IP@:$(IP):" \
-e "s:@IPTABLES@:$(IPTABLES):" \
-e "s:@PASTA@:$(PASTA):" \
-e "s:@XDG_DBUS_PROXY@:$(XDG_DBUS_PROXY):" \
$^ > $@
cat $@

View File

@@ -4,3 +4,4 @@
export const IP: str = "@IP@";
export const IPTABLES: str = "@IPTABLES@";
export const PASTA: str = "@PASTA@";
export const XDG_DBUS_PROXY: str = "@XDG_DBUS_PROXY@";

View File

@@ -8,6 +8,7 @@
stdenv,
util-linux,
which,
xdg-dbus-proxy,
}: stdenv.mkDerivation {
pname = "bunpen";
version = "0.1.0";
@@ -23,6 +24,7 @@
"IP=${lib.getExe' iproute2 "ip"}"
"IPTABLES=${lib.getExe' iptables "iptables"}"
"PASTA=${lib.getExe' passt "pasta"}"
"XDG_DBUS_PROXY=${lib.getExe xdg-dbus-proxy}"
];
nativeCheckInputs = [

View File

@@ -14,6 +14,9 @@
// other dbus names.
// - own the dbus name `org.baz.Bap`.
//
// `man xdg-dbus-proxy` provides this example invocation:
// `xdg-dbus-proxy --fd=26 unix:path=/run/usr/1000/bus /run/usr/1000/.dbus-proxy/session-bus-proxy --filter --own=org.gnome.ghex.* --talk=ca.desrt.dconf --call=org.freedesktop.portal.*=* --broadcast=org.freedesktop.portal.*=@/org/freedesktop/portal/*`
//
// proof-of-concept minimal:
// ```sh
// $ xdg-dbus-proxy unix:path=/run/user/colin/dbus/bus /run/user/colin/dbus/proxy-1 --filter &
@@ -55,35 +58,61 @@
// - wildcards are supported above as expected (e.g. `'--call=org.gnome.Calls=org.gtk.Application.*@*'`
// - best is to use exclusively `--call=...` rules (and `--own`), no --see or --talk
// use config;
use config;
use errors;
// use errors::ext;
use errors::ext;
use strings;
use os;
// use os::exec;
//
// // instantiate a `xdg-dbus-proxy` process,
// // which talks to the bus on the sandboxed process's behalf,
// // selectively forwarding traffic based on the passed policy.
// // this can be called from within an existing sandbox.
// // the dbus bus should be reachable from the present namespace.
// // xdg-dbus-proxy will run in this namespace,
// //
// // `man xdg-dbus-proxy` provides this example invocation:
// // `xdg-dbus-proxy --fd=26 unix:path=/run/usr/1000/bus /run/usr/1000/.dbus-proxy/session-bus-proxy --filter --own=org.gnome.ghex.* --talk=ca.desrt.dconf --call=org.freedesktop.portal.*=* --broadcast=org.freedesktop.portal.*=@/org/freedesktop/portal/*`
// fn setup_dbus_proxy(dbus: restrict::dbus_subset) void = {
// let dbus_socket = errors::ext::check("setup_dbus_proxy: get_dbus_socket", get_dbus_socket());
// match (os::exec::fork()) {
// case let child_pid: os::exec::process =>
// // parent process: continue execution
// void;
// case void =>
// // child process: TODO: spawn xdg-dbus-proxy
// void;
// case let e: os::exec::error =>
// errors::ext::check("setup_dbus_proxy: fork", e);
// };
// };
use os::exec;
use ps;
use rt::ext;
export type dbus_resources = struct {
talk: []str,
own: []str,
};
// given an existing, unfiltered bus at the fs path `upstream`,
// proxy the bus into the fs path indicated by `downstream`.
// clients attaching to the `downstream` path are provided access only to the
// resources indicated by `dbus`.
fn dbus_restrict(dbus: dbus_resources, upstream: str, downstream: str) void = {
match (ps::fork_and_die_with_parent()) {
case let child_pid: os::exec::process =>
let proxy_args: []str = [
"xdg-dbus-proxy",
"--filter",
];
for (let spec .. dbus.talk) {
append(proxy_args, "--talk");
append(proxy_args, spec);
};
for (let spec .. dbus.own) {
append(proxy_args, "--own");
append(proxy_args, spec);
};
errors::ext::check(
"dbus_restrict: invoke xdg-dbus-proxy",
rt::ext::execvpe_or_default(
config::XDG_DBUS_PROXY,
"xdg-dbus-proxy",
proxy_args,
os::getenvs(),
),
);
case void =>
// xdg-dbus-proxy provides no explicit synchronization mechanism;
// we have to assume that once we fork, it starts listening "reasonably quickly".
// TODO: i could probably hack some synchronization in here:
// - `write` a HELLO message and block until it's read.
// - invoke with `--log` and parse the output.
// - or maybe pre-create the unix socket _before_ forking here, and
// somehow pass that into xdg-dbus-proxy instead of letting it create
// its own socket.
void;
};
};
fn parse_dbus_address(address: (str | void)) (str | errors::invalid) = {
// dbus address is specified like: