Code comments explain the promises a bit more, tl;dr:
    main() {
        pledge("stdio rpath wpath cpath inet mcast flock chown unix dns proc 
exec audio", NULL)
        [CLI arg and config parsing]
        if (on-song-change-hook)
            pledge("stdio rpath wpath cpath inet mcast unix dns proc exec 
audio", NULL)
        else
            pledge("stdio rpath wpath cpath inet mcast unix dns audio", NULL)
        [...]
    }

Daemon or in foreground, static credentials or --*-cmd or zeroconf discovery,
cache or no persistent files, rc.d script or manually run, MPRIS interaction
via playerctl(1):  it all works for me.

Unveil looks viable and doable, but as a second step.

Please try to break this.
Feedback? OK?

Only REVISION conflicts with 'spotifyd:  add user and rc.d script".

Index: Makefile
===================================================================
RCS file: /cvs/ports/audio/spotifyd/Makefile,v
diff -u -p -r1.4 Makefile
--- Makefile    31 Dec 2023 18:45:17 -0000      1.4
+++ Makefile    1 Jan 2024 00:08:15 -0000
@@ -4,7 +4,7 @@ NOT_FOR_ARCHS =         powerpc64 riscv6
 COMMENT =              Spotify client running as UNIX daemon
 DIST_TUPLE =           github  Spotifyd        spotifyd        v0.3.5  .
 CATEGORIES =           audio net
-REVISION =             2
+REVISION =             4
 
 MAINTAINER =           Klemens Nanni <k...@openbsd.org>
 
@@ -13,6 +13,7 @@ HOMEPAGE =            https://spotifyd.rs
 # GPLv3.0
 PERMIT_PACKAGE =       Yes
 
+# uses pledge()
 WANTLIB =              ${MODCARGO_WANTLIB} dbus-1 m portaudio
 
 MODULES =              devel/cargo
Index: crates.inc
===================================================================
RCS file: /cvs/ports/audio/spotifyd/crates.inc,v
diff -u -p -r1.2 crates.inc
--- crates.inc  31 Dec 2023 18:45:17 -0000      1.2
+++ crates.inc  1 Jan 2024 00:39:11 -0000
@@ -218,6 +218,7 @@ MODCARGO_CRATES +=  petgraph        0.6.3   # MIT 
 MODCARGO_CRATES +=     pin-project-lite        0.2.9   # Apache-2.0 OR MIT
 MODCARGO_CRATES +=     pin-utils       0.1.0   # MIT OR Apache-2.0
 MODCARGO_CRATES +=     pkg-config      0.3.26  # MIT OR Apache-2.0
+MODCARGO_CRATES +=     pledge  0.4.2   # MIT
 MODCARGO_CRATES +=     polling 2.6.0   # Apache-2.0 OR MIT
 MODCARGO_CRATES +=     portaudio-rs    0.3.2   # MIT
 MODCARGO_CRATES +=     portaudio-sys   0.1.1   # MIT
Index: distinfo
===================================================================
RCS file: /cvs/ports/audio/spotifyd/distinfo,v
diff -u -p -r1.2 distinfo
--- distinfo    31 Dec 2023 18:45:17 -0000      1.2
+++ distinfo    1 Jan 2024 00:38:30 -0000
@@ -219,6 +219,7 @@ SHA256 (cargo/petgraph-0.6.3.tar.gz) = T
 SHA256 (cargo/pin-project-lite-0.2.9.tar.gz) = 
4KeuOsLxFzCF05hTHHBXVslKTFaEN4XfhaYMGgr6wRY=
 SHA256 (cargo/pin-utils-0.1.0.tar.gz) = 
i4cNjBUbby+5PoShMUYTjwXQLtEcfnxU+IJqqvfJ8YQ=
 SHA256 (cargo/pkg-config-0.3.26.tar.gz) = 
asmln3NHPxuNhSQh5Z5kgJ8CWZSDfvdDYVxtDFswUWA=
+SHA256 (cargo/pledge-0.4.2.tar.gz) = 
JSWZQXt9mkO3/cY915CwhIZmqJELLr4aJRGDCcPJgeU=
 SHA256 (cargo/polling-2.6.0.tar.gz) = 
fh+HmymYCZwtaauWBdFF1bZhGVYn7MxoAALEkYp/tvo=
 SHA256 (cargo/portaudio-rs-0.3.2.tar.gz) = 
zba17/lszJv0TTTDeasDrpREJtg9FpQ0W9+BWdVh1WI=
 SHA256 (cargo/portaudio-sys-0.1.1.tar.gz) = 
UZSk+pU7T/2FHDIO9vBITNcnjLcWnqnWxDPkmyP3t/U=
@@ -595,6 +596,7 @@ SIZE (cargo/petgraph-0.6.3.tar.gz) = 185
 SIZE (cargo/pin-project-lite-0.2.9.tar.gz) = 27713
 SIZE (cargo/pin-utils-0.1.0.tar.gz) = 7580
 SIZE (cargo/pkg-config-0.3.26.tar.gz) = 18662
+SIZE (cargo/pledge-0.4.2.tar.gz) = 4779
 SIZE (cargo/polling-2.6.0.tar.gz) = 41714
 SIZE (cargo/portaudio-rs-0.3.2.tar.gz) = 13267
 SIZE (cargo/portaudio-sys-0.1.1.tar.gz) = 2327
Index: patches/patch-Cargo_lock
===================================================================
RCS file: /cvs/ports/audio/spotifyd/patches/patch-Cargo_lock,v
diff -u -p -r1.1 patch-Cargo_lock
--- patches/patch-Cargo_lock    31 Dec 2023 18:45:18 -0000      1.1
+++ patches/patch-Cargo_lock    1 Jan 2024 02:10:26 -0000
@@ -1,6 +1,8 @@
 Bump keyring to latest release 2.3.0 to add OpenBSD support
 https://github.com/Spotifyd/spotifyd/pull/1254
 
+use pledge(2)
+
 Index: Cargo.lock
 --- Cargo.lock.orig
 +++ Cargo.lock
@@ -16,3 +18,27 @@ Index: Cargo.lock
  dependencies = [
   "byteorder",
   "lazy_static",
+@@ -2277,6 +2277,15 @@ source = "registry+https://github.com/rust-lang/crates
+ checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
+ 
+ [[package]]
++name = "pledge"
++version = "0.4.2"
++source = "registry+https://github.com/rust-lang/crates.io-index";
++checksum = "252599417b7d9a43b7fdc63dd790b0848666a8910b2ebe1a25118309c3c981e5"
++dependencies = [
++ "libc",
++]
++
++[[package]]
+ name = "polling"
+ version = "2.6.0"
+ source = "registry+https://github.com/rust-lang/crates.io-index";
+@@ -2905,6 +2914,7 @@ dependencies = [
+  "librespot-discovery",
+  "librespot-playback",
+  "log",
++ "pledge",
+  "rspotify",
+  "serde",
+  "sha-1 0.10.1",
Index: patches/patch-Cargo_toml
===================================================================
RCS file: patches/patch-Cargo_toml
diff -N patches/patch-Cargo_toml
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-Cargo_toml    1 Jan 2024 00:43:51 -0000
@@ -0,0 +1,13 @@
+Index: Cargo.toml
+--- Cargo.toml.orig
++++ Cargo.toml
+@@ -39,6 +39,9 @@ librespot-connect = { version = "0.4" }
+ toml = "0.7"
+ color-eyre = "0.6"
+ 
++[target."cfg(target_os = \"openbsd\")".dependencies]
++pledge = "0.4.2"
++
+ [target."cfg(target_os = \"macos\")".dependencies]
+ whoami = "1"
+ 
Index: patches/patch-src_main_rs
===================================================================
RCS file: patches/patch-src_main_rs
diff -N patches/patch-src_main_rs
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_main_rs   1 Jan 2024 13:48:11 -0000
@@ -0,0 +1,61 @@
+use pledge(2)
+
+Index: src/main.rs
+--- src/main.rs.orig
++++ src/main.rs
+@@ -9,6 +9,7 @@ use daemonize::Daemonize;
+ use log::{error, info, trace, LevelFilter};
+ use structopt::StructOpt;
+ use tokio::runtime::Runtime;
++use pledge::{pledge, pledge_promises, Promise, ToPromiseString};
+ 
+ #[cfg(feature = "alsa_backend")]
+ mod alsa_mixer;
+@@ -60,6 +61,10 @@ fn setup_logger(log_target: LogTarget, verbose: bool) 
+ }
+ 
+ fn main() -> eyre::Result<()> {
++    // Start with superset of all potential promises.
++    // Drop later after CLI arguments and configuration files were parsed.
++    pledge_promises![Stdio Rpath Wpath Cpath Inet Mcast Flock Chown Unix Dns 
Proc Exec Audio].unwrap();
++
+     color_eyre::install().wrap_err("Couldn't initialize error reporting")?;
+ 
+     let mut cli_config: CliConfig = CliConfig::from_args();
+@@ -101,6 +106,36 @@ fn main() -> eyre::Result<()> {
+             Err(e) => error!("Something went wrong while daemonizing: {}", e),
+         };
+     }
++
++    // At this point:
++    //   * --username-cmd, --password-cmd were handled
++    //     => no "proc exec"
++    //   * --pid, daemon(3) were handled
++    //     => no "cpath flock chown" for PID file
++    //     => no "proc" for double-fork(2)
++    //
++    // Minimum subset of permanent promises:
++    let mut promises = vec![
++        Promise::Stdio,  // logging
++        Promise::Rpath,  // 1. ${TMPDIR}/.tmp*  
O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC
++        Promise::Wpath,  // ...
++        Promise::Cpath,  // 2. --cache-path aka. "cache_path"
++        Promise::Inet,   // internet Spotify
++        Promise::Mcast,  // local Zeroconf Discovery
++        Promise::Unix,   // sndio(7), D-Bus (keyring, MPRIS)
++        Promise::Dns,    // internet Spotify
++        Promise::Audio,  // sndio(7)
++    ];
++
++    // --on-song-change-hook aka. "onevent"
++    if internal_config.onevent.is_some() {
++        promises.push(Promise::Proc); // always run through --shell aka. 
"shell"
++        promises.push(Promise::Exec); // defaults to "sh"
++    }
++
++    // Second and final pledge before runtime starts.
++    // "mcast" could go if a) username is given and b) password/keyring 
worked.
++    pledge(&*promises.to_promise_string(), None).unwrap();
+ 
+     let runtime = Runtime::new().unwrap();
+     runtime.block_on(async {

Reply via email to