diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 84a3a477..d07046c1 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -37,6 +37,7 @@ use smithay::{ use crate::{ config::{Config, KeyModifiers, KeyPattern, OutputConfig, WorkspaceMode as ConfigMode}, + state::client_has_security_context, utils::prelude::*, wayland::protocols::{ toplevel_info::ToplevelInfoState, @@ -583,7 +584,7 @@ impl Shell { let toplevel_info_state = ToplevelInfoState::new( dh, //|client| client.get_data::().map_or(false, |s| s.privileged), - |_| true, + client_has_security_context, ); let toplevel_management_state = ToplevelManagementState::new::( dh, @@ -592,12 +593,12 @@ impl Shell { ManagementCapabilities::Activate, ], //|client| client.get_data::().map_or(false, |s| s.privileged), - |_| true, + client_has_security_context, ); let mut workspace_state = WorkspaceState::new( dh, //|client| client.get_data::().map_or(false, |s| s.privileged), - |_| true, + client_has_security_context, ); let tiling_enabled = config.static_conf.tiling_enabled; diff --git a/src/state.rs b/src/state.rs index cd8de043..02a3c714 100644 --- a/src/state.rs +++ b/src/state.rs @@ -54,7 +54,7 @@ use smithay::{ wayland_server::{ backend::{ClientData, ClientId, DisconnectReason}, protocol::wl_shm, - Display, DisplayHandle, + Client, Display, DisplayHandle, }, }, utils::{Clock, IsAlive, Monotonic}, @@ -69,6 +69,7 @@ use smithay::{ presentation::PresentationState, primary_selection::PrimarySelectionState, seat::WaylandFocus, + security_context::{SecurityContext, SecurityContextState}, shell::{kde::decoration::KdeDecorationState, xdg::decoration::XdgDecorationState}, shm::ShmState, viewporter::ViewporterState, @@ -103,6 +104,7 @@ pub struct ClientState { pub drm_node: Option, pub privileged: bool, pub evls: LoopSignal, + pub security_context: Option, } impl ClientData for ClientState { fn initialized(&self, _client_id: ClientId) {} @@ -268,6 +270,12 @@ impl BackendData { } } +pub fn client_has_security_context(client: &Client) -> bool { + client + .get_data::() + .map_or(true, |client_state| client_state.security_context.is_none()) +} + impl State { pub fn new( dh: &DisplayHandle, @@ -288,13 +296,14 @@ impl State { let fractional_scale_state = FractionalScaleManagerState::new::(dh); let keyboard_shortcuts_inhibit_state = KeyboardShortcutsInhibitState::new::(dh); let output_state = OutputManagerState::new_with_xdg_output::(dh); - let output_configuration_state = OutputConfigurationState::new(dh, |_| true); + let output_configuration_state = + OutputConfigurationState::new(dh, client_has_security_context); let presentation_state = PresentationState::new::(dh, clock.id() as u32); let primary_selection_state = PrimarySelectionState::new::(dh); let screencopy_state = ScreencopyState::new::( dh, vec![CursorMode::Embedded, CursorMode::Hidden], - |_| true, + client_has_security_context, ); // TODO: privileged let shm_state = ShmState::new::(dh, vec![wl_shm::Format::Xbgr8888, wl_shm::Format::Abgr8888]); @@ -305,6 +314,7 @@ impl State { let xdg_decoration_state = XdgDecorationState::new::(&dh); XWaylandKeyboardGrabState::new::(&dh); PointerGesturesState::new::(&dh); + SecurityContextState::new::(&dh, client_has_security_context); let shell = Shell::new(&config, dh); @@ -377,6 +387,7 @@ impl State { }, privileged: false, evls: self.common.event_loop_signal.clone(), + security_context: None, } } @@ -387,6 +398,7 @@ impl State { drm_node: Some(drm_node), privileged: false, evls: self.common.event_loop_signal.clone(), + security_context: None, } } @@ -400,6 +412,7 @@ impl State { }, privileged: true, evls: self.common.event_loop_signal.clone(), + security_context: None, } } } diff --git a/src/wayland/handlers/mod.rs b/src/wayland/handlers/mod.rs index f9243fb6..d8eac626 100644 --- a/src/wayland/handlers/mod.rs +++ b/src/wayland/handlers/mod.rs @@ -16,6 +16,7 @@ pub mod primary_selection; pub mod relative_pointer; pub mod screencopy; pub mod seat; +pub mod security_context; pub mod shm; pub mod toplevel_info; pub mod toplevel_management; diff --git a/src/wayland/handlers/security_context.rs b/src/wayland/handlers/security_context.rs new file mode 100644 index 00000000..0695f70e --- /dev/null +++ b/src/wayland/handlers/security_context.rs @@ -0,0 +1,33 @@ +use crate::state::{ClientState, State}; +use smithay::{ + delegate_security_context, + wayland::security_context::{ + SecurityContext, SecurityContextHandler, SecurityContextListenerSource, + }, +}; +use std::sync::Arc; +use tracing::warn; + +impl SecurityContextHandler for State { + fn context_created( + &mut self, + source: SecurityContextListenerSource, + security_context: SecurityContext, + ) { + self.common + .event_loop_handle + .insert_source(source, move |client_stream, _, data| { + if let Err(err) = data.display.handle().insert_client( + client_stream, + Arc::new(ClientState { + security_context: Some(security_context.clone()), + ..data.state.new_client_state() + }), + ) { + warn!(?err, "Error adding wayland client"); + }; + }) + .expect("Failed to init the wayland socket source."); + } +} +delegate_security_context!(State);