diff --git a/cmd/hpkg/build.nix b/cmd/hpkg/build.nix index 3733f42..5e2f55a 100644 --- a/cmd/hpkg/build.nix +++ b/cmd/hpkg/build.nix @@ -45,7 +45,7 @@ allow_wayland ? true, allow_x11 ? false, allow_dbus ? true, - allow_pulse ? true, + allow_audio ? true, gpu ? allow_wayland || allow_x11, }: @@ -175,7 +175,8 @@ let wayland = allow_wayland; x11 = allow_x11; dbus = allow_dbus; - pulse = allow_pulse; + pipewire = allow_audio; + pulse = allow_audio; }; mesa = if gpu then mesaWrappers else null; diff --git a/cmd/hpkg/test/test.py b/cmd/hpkg/test/test.py index 790377c..ef6a626 100644 --- a/cmd/hpkg/test/test.py +++ b/cmd/hpkg/test/test.py @@ -90,7 +90,7 @@ wait_for_window("hakurei@machine-foot") machine.send_chars("clear; wayland-info && touch /tmp/success-client\n") machine.wait_for_file("/tmp/hakurei.0/tmpdir/2/success-client") collect_state_ui("app_wayland") -check_state("foot", {"wayland": True, "dbus": True, "pulse": True}) +check_state("foot", {"wayland": True, "dbus": True, "pipewire": True, "pulse": True}) # Verify acl on XDG_RUNTIME_DIR: print(machine.succeed("getfacl --absolute-names --omit-header --numeric /run/user/1000 | grep 10002")) machine.send_chars("exit\n") diff --git a/hst/config.go b/hst/config.go index c6cd790..23c21cc 100644 --- a/hst/config.go +++ b/hst/config.go @@ -60,6 +60,9 @@ var ( // ErrEnviron is returned by [Config.Validate] if an environment variable name contains '=' or NUL. ErrEnviron = errors.New("invalid environment variable name") + + // ErrInsecure is returned by [Config.Validate] if the configuration is considered insecure. + ErrInsecure = errors.New("configuration is insecure") ) // Validate checks [Config] and returns [AppError] if an invalid value is encountered. @@ -106,6 +109,13 @@ func (config *Config) Validate() error { } } + // EPulse without EPipeWire is insecure + if et := config.Enablements.Unwrap(); !config.DirectPulse && + et&EPipeWire == 0 && et&EPulse != 0 { + return &AppError{Step: "validate configuration", Err: ErrInsecure, + Msg: "enablement PulseAudio requires PipeWire, which is not set"} + } + return nil } diff --git a/hst/config_test.go b/hst/config_test.go index 6bc878a..731a131 100644 --- a/hst/config_test.go +++ b/hst/config_test.go @@ -53,6 +53,12 @@ func TestConfigValidate(t *testing.T) { Env: map[string]string{"TERM\x00": ""}, }}, &hst.AppError{Step: "validate configuration", Err: hst.ErrEnviron, Msg: `invalid environment variable "TERM\x00"`}}, + {"insecure pulse", &hst.Config{Enablements: hst.NewEnablements(hst.EPulse), Container: &hst.ContainerConfig{ + Home: fhs.AbsTmp, + Shell: fhs.AbsTmp, + Path: fhs.AbsTmp, + }}, &hst.AppError{Step: "validate configuration", Err: hst.ErrInsecure, + Msg: "enablement PulseAudio requires PipeWire, which is not set"}}, {"valid", &hst.Config{Container: &hst.ContainerConfig{ Home: fhs.AbsTmp, Shell: fhs.AbsTmp, diff --git a/hst/hst.go b/hst/hst.go index a7f9092..94bcd09 100644 --- a/hst/hst.go +++ b/hst/hst.go @@ -92,7 +92,6 @@ func Template() *Config { Log: false, Filter: true, }, - DirectWayland: false, ExtraPerms: []ExtraPermConfig{ {Path: fhs.AbsVarLib.Append("hakurei/u0"), Ensure: true, Execute: true}, diff --git a/options.nix b/options.nix index a1b76e0..effa655 100644 --- a/options.nix +++ b/options.nix @@ -218,7 +218,7 @@ in type = nullOr bool; default = true; description = '' - Whether to share the Wayland socket. + Whether to share the Wayland server via security-context-v1. ''; }; @@ -238,11 +238,19 @@ in ''; }; + pipewire = mkOption { + type = nullOr bool; + default = true; + description = '' + Whether to share the PipeWire server via SecurityContext. + ''; + }; + pulse = mkOption { type = nullOr bool; default = true; description = '' - Whether to share the PulseAudio socket and cookie. + Whether to run the PulseAudio compatibility daemon. ''; }; }; diff --git a/test/configuration.nix b/test/configuration.nix index 1c3cce0..5bc50e7 100644 --- a/test/configuration.nix +++ b/test/configuration.nix @@ -133,6 +133,7 @@ wait_delay = 1; enablements = { wayland = false; + pipewire = false; pulse = false; }; }; @@ -152,6 +153,7 @@ command = "foot"; enablements = { dbus = false; + pipewire = false; pulse = false; }; }; @@ -167,6 +169,7 @@ command = "foot"; enablements = { dbus = false; + pipewire = false; pulse = false; }; }; @@ -199,6 +202,7 @@ wayland = false; x11 = true; dbus = false; + pipewire = false; pulse = false; }; }; @@ -218,6 +222,7 @@ command = "foot"; enablements = { dbus = false; + pipewire = false; pulse = false; }; }; @@ -232,6 +237,7 @@ wayland = false; x11 = false; dbus = false; + pipewire = false; pulse = false; }; }; diff --git a/test/test.py b/test/test.py index 30b4ac5..305614f 100644 --- a/test/test.py +++ b/test/test.py @@ -225,7 +225,7 @@ wait_for_window(f"u0_a{hakurei_identity(1)}@machine") machine.send_chars("clear; pactl info && touch /var/tmp/pulse-ok\n") machine.wait_for_file("/var/tmp/pulse-ok", timeout=15) collect_state_ui("pulse_wayland") -check_state("pa-foot", {"wayland": True, "pulse": True}) +check_state("pa-foot", {"wayland": True, "pipewire": True, "pulse": True}) machine.send_chars("exit\n") machine.wait_until_fails("pgrep foot", timeout=5)