From affea49e49a9e991a1d3f22ce5ed865f5eab6fde Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Mon, 1 Apr 2024 13:16:34 +0200 Subject: [PATCH] config: allow running commands privileged --- jay-config/src/_private/client.rs | 6 ++++++ jay-config/src/_private/ipc.rs | 4 ++++ jay-config/src/exec.rs | 15 +++++++++++++++ src/config/handler.rs | 14 ++++++++++++++ toml-config/src/config.rs | 1 + toml-config/src/config/parsers/exec.rs | 15 +++++++++++---- toml-config/src/default-config.toml | 2 +- toml-config/src/lib.rs | 3 +++ toml-spec/spec/spec.generated.json | 4 ++++ toml-spec/spec/spec.generated.md | 8 ++++++++ toml-spec/spec/spec.yaml | 7 +++++++ 11 files changed, 74 insertions(+), 5 deletions(-) diff --git a/jay-config/src/_private/client.rs b/jay-config/src/_private/client.rs index 6ad8d154..eb2d061f 100644 --- a/jay-config/src/_private/client.rs +++ b/jay-config/src/_private/client.rs @@ -944,6 +944,12 @@ impl Client { }) } + pub fn get_socket_path(&self) -> Option { + let res = self.send_with_response(&ClientMessage::GetSocketPath); + get_response!(res, None, GetSocketPath { path }); + Some(path) + } + pub fn create_pollable(&self, fd: i32) -> Result { let res = self.send_with_response(&ClientMessage::AddPollable { fd }); get_response!( diff --git a/jay-config/src/_private/ipc.rs b/jay-config/src/_private/ipc.rs index 24854645..702c9428 100644 --- a/jay-config/src/_private/ipc.rs +++ b/jay-config/src/_private/ipc.rs @@ -431,6 +431,7 @@ pub enum ClientMessage<'a> { SetExplicitSyncEnabled { enabled: bool, }, + GetSocketPath, } #[derive(Serialize, Deserialize, Debug)] @@ -576,6 +577,9 @@ pub enum Response { GetInputDeviceDevnode { devnode: String, }, + GetSocketPath { + path: String, + }, } #[derive(Serialize, Deserialize, Debug)] diff --git a/jay-config/src/exec.rs b/jay-config/src/exec.rs index 4c858900..183d8f94 100644 --- a/jay-config/src/exec.rs +++ b/jay-config/src/exec.rs @@ -82,6 +82,21 @@ impl Command { self.fd(2, fd) } + /// Runs the application with access to privileged wayland protocols. + /// + /// The default is `false`. + pub fn privileged(&mut self) -> &mut Self { + match get!(self).get_socket_path() { + Some(path) => { + self.env("WAYLAND_DISPLAY", &format!("{path}.jay")); + } + _ => { + log::error!("Compositor did not send the socket path"); + } + } + self + } + /// Executes the command. /// /// This consumes all attached file descriptors. diff --git a/src/config/handler.rs b/src/config/handler.rs index 8940cfc5..a2aa0014 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -804,6 +804,19 @@ impl ConfigProxyHandler { self.state.explicit_sync_enabled.set(enabled); } + fn handle_get_socket_path(&self) { + match self.state.acceptor.get() { + Some(a) => { + self.respond(Response::GetSocketPath { + path: a.socket_name().to_string(), + }); + } + _ => { + log::warn!("There is no acceptor"); + } + } + } + fn handle_connector_connected(&self, connector: Connector) -> Result<(), CphError> { let connector = self.get_connector(connector)?; self.respond(Response::ConnectorConnected { @@ -1732,6 +1745,7 @@ impl ConfigProxyHandler { ClientMessage::SetExplicitSyncEnabled { enabled } => { self.handle_set_explicit_sync_enabled(enabled) } + ClientMessage::GetSocketPath => self.handle_get_socket_path(), } Ok(()) } diff --git a/toml-config/src/config.rs b/toml-config/src/config.rs index 23e6153e..514f424e 100644 --- a/toml-config/src/config.rs +++ b/toml-config/src/config.rs @@ -245,6 +245,7 @@ pub struct Exec { pub prog: String, pub args: Vec, pub envs: Vec<(String, String)>, + pub privileged: bool, } #[derive(Debug, Clone)] diff --git a/toml-config/src/config/parsers/exec.rs b/toml-config/src/config/parsers/exec.rs index 41ed9e89..d247fd1d 100644 --- a/toml-config/src/config/parsers/exec.rs +++ b/toml-config/src/config/parsers/exec.rs @@ -2,7 +2,7 @@ use { crate::{ config::{ context::Context, - extractor::{arr, opt, str, val, Extractor, ExtractorError}, + extractor::{arr, bol, opt, recover, str, val, Extractor, ExtractorError}, parser::{DataType, ParseResult, Parser, UnexpectedDataType}, parsers::{ env::{EnvParser, EnvParserError}, @@ -11,7 +11,7 @@ use { Exec, }, toml::{ - toml_span::{Span, Spanned, SpannedExt}, + toml_span::{DespanExt, Span, Spanned, SpannedExt}, toml_value::Value, }, }, @@ -45,6 +45,7 @@ impl Parser for ExecParser<'_> { prog: string.to_string(), args: vec![], envs: vec![], + privileged: false, }) } @@ -61,6 +62,7 @@ impl Parser for ExecParser<'_> { prog, args, envs: vec![], + privileged: false, }) } @@ -70,8 +72,12 @@ impl Parser for ExecParser<'_> { table: &IndexMap, Spanned>, ) -> ParseResult { let mut ext = Extractor::new(self.0, span, table); - let (prog, args_val, envs_val) = - ext.extract((str("prog"), opt(arr("args")), opt(val("env"))))?; + let (prog, args_val, envs_val, privileged) = ext.extract(( + str("prog"), + opt(arr("args")), + opt(val("env")), + recover(opt(bol("privileged"))), + ))?; let mut args = vec![]; if let Some(args_val) = args_val { for arg in args_val.value { @@ -86,6 +92,7 @@ impl Parser for ExecParser<'_> { prog: prog.value.to_string(), args, envs, + privileged: privileged.despan().unwrap_or(false), }) } } diff --git a/toml-config/src/default-config.toml b/toml-config/src/default-config.toml index 1b65db26..2507bf36 100644 --- a/toml-config/src/default-config.toml +++ b/toml-config/src/default-config.toml @@ -7,7 +7,7 @@ keymap = """ }; """ -on-graphics-initialized = { type = "exec", exec = "mako" } +on-graphics-initialized = { type = "exec", exec = { prog = "mako", privileged = true } } [shortcuts] alt-h = "focus-left" diff --git a/toml-config/src/lib.rs b/toml-config/src/lib.rs index 6d107d03..cd11f70b 100644 --- a/toml-config/src/lib.rs +++ b/toml-config/src/lib.rs @@ -823,6 +823,9 @@ fn create_command(exec: &Exec) -> Command { for (k, v) in &exec.envs { command.env(k, v); } + if exec.privileged { + command.privileged(); + } command } diff --git a/toml-spec/spec/spec.generated.json b/toml-spec/spec/spec.generated.json index 581b20a6..8fa28507 100644 --- a/toml-spec/spec/spec.generated.json +++ b/toml-spec/spec/spec.generated.json @@ -677,6 +677,10 @@ "type": "string", "description": "" } + }, + "privileged": { + "type": "boolean", + "description": "If `true`, the executable gets access to privileged wayland protocols.\n\nThe default is `false`.\n" } }, "required": [ diff --git a/toml-spec/spec/spec.generated.md b/toml-spec/spec/spec.generated.md index 93646c40..a83d4b20 100644 --- a/toml-spec/spec/spec.generated.md +++ b/toml-spec/spec/spec.generated.md @@ -1308,6 +1308,14 @@ The table has the following fields: The value of this field should be a table whose values are strings. +- `privileged` (optional): + + If `true`, the executable gets access to privileged wayland protocols. + + The default is `false`. + + The value of this field should be a boolean. + ### `GfxApi` diff --git a/toml-spec/spec/spec.yaml b/toml-spec/spec/spec.yaml index 2d4a7d43..560ee880 100644 --- a/toml-spec/spec/spec.yaml +++ b/toml-spec/spec/spec.yaml @@ -583,6 +583,13 @@ Exec: values: kind: string description: The environment variables to pass to the executable. + privileged: + kind: boolean + required: false + description: | + If `true`, the executable gets access to privileged wayland protocols. + + The default is `false`. SimpleActionName: