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

View File

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

View File

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

View File

@@ -14,6 +14,9 @@
// other dbus names. // other dbus names.
// - own the dbus name `org.baz.Bap`. // - 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: // proof-of-concept minimal:
// ```sh // ```sh
// $ xdg-dbus-proxy unix:path=/run/user/colin/dbus/bus /run/user/colin/dbus/proxy-1 --filter & // $ 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.*@*'` // - 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 // - best is to use exclusively `--call=...` rules (and `--own`), no --see or --talk
// use config; use config;
use errors; use errors;
// use errors::ext; use errors::ext;
use strings; use strings;
use os; use os;
// use os::exec; use os::exec;
// use ps;
// // instantiate a `xdg-dbus-proxy` process, use rt::ext;
// // which talks to the bus on the sandboxed process's behalf,
// // selectively forwarding traffic based on the passed policy. export type dbus_resources = struct {
// // this can be called from within an existing sandbox. talk: []str,
// // the dbus bus should be reachable from the present namespace. own: []str,
// // xdg-dbus-proxy will run in this namespace, };
// //
// // `man xdg-dbus-proxy` provides this example invocation: // given an existing, unfiltered bus at the fs path `upstream`,
// // `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/*` // proxy the bus into the fs path indicated by `downstream`.
// fn setup_dbus_proxy(dbus: restrict::dbus_subset) void = { // clients attaching to the `downstream` path are provided access only to the
// let dbus_socket = errors::ext::check("setup_dbus_proxy: get_dbus_socket", get_dbus_socket()); // resources indicated by `dbus`.
// match (os::exec::fork()) { fn dbus_restrict(dbus: dbus_resources, upstream: str, downstream: str) void = {
// case let child_pid: os::exec::process => match (ps::fork_and_die_with_parent()) {
// // parent process: continue execution case let child_pid: os::exec::process =>
// void; let proxy_args: []str = [
// case void => "xdg-dbus-proxy",
// // child process: TODO: spawn xdg-dbus-proxy "--filter",
// void; ];
// case let e: os::exec::error => for (let spec .. dbus.talk) {
// errors::ext::check("setup_dbus_proxy: fork", e); 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) = { fn parse_dbus_address(address: (str | void)) (str | errors::invalid) = {
// dbus address is specified like: // dbus address is specified like: