diff --git a/Cargo.lock b/Cargo.lock index 6e12c7415..e957a3802 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3947,7 +3947,7 @@ checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "smithay" version = "0.3.0" -source = "git+https://github.com/pop-os/smithay?branch=x11_fixes#15dd1675840295062cee4494fa6d49440ec0f04c" +source = "git+https://github.com/pop-os/smithay?branch=panel_security#8e55572af02e415883249b84b2beb8923eef643a" dependencies = [ "appendlist", "ash", diff --git a/Cargo.toml b/Cargo.toml index 548b8db27..524c8a65f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -88,4 +88,4 @@ debug = true lto = "fat" [patch."https://github.com/Smithay/smithay.git"] -smithay = { git = "https://github.com/pop-os/smithay", branch = "x11_fixes" } \ No newline at end of file +smithay = { git = "https://github.com/pop-os/smithay", branch = "panel_security" } \ No newline at end of file diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 87b0f2872..565294f52 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -36,7 +36,7 @@ use smithay::{ use crate::{ config::{Config, KeyModifiers, KeyPattern}, - state::client_has_security_context, + state::client_is_privileged, utils::prelude::*, wayland::protocols::{ toplevel_info::ToplevelInfoState, @@ -849,28 +849,19 @@ pub struct InvalidWorkspaceIndex; impl Shell { pub fn new(config: &Config, dh: &DisplayHandle) -> Self { - // TODO: Privileged protocols - let layer_shell_state = WlrLayerShellState::new::(dh); + let layer_shell_state = + WlrLayerShellState::new_with_filter::(dh, client_is_privileged); let xdg_shell_state = XdgShellState::new::(dh); - let toplevel_info_state = ToplevelInfoState::new( - dh, - //|client| client.get_data::().map_or(false, |s| s.privileged), - client_has_security_context, - ); + let toplevel_info_state = ToplevelInfoState::new(dh, client_is_privileged); let toplevel_management_state = ToplevelManagementState::new::( dh, vec![ ManagementCapabilities::Close, ManagementCapabilities::Activate, ], - //|client| client.get_data::().map_or(false, |s| s.privileged), - client_has_security_context, - ); - let workspace_state = WorkspaceState::new( - dh, - //|client| client.get_data::().map_or(false, |s| s.privileged), - client_has_security_context, + client_is_privileged, ); + let workspace_state = WorkspaceState::new(dh, client_is_privileged); let theme = cosmic::theme::system_preference(); Shell { diff --git a/src/state.rs b/src/state.rs index e2cd81ffb..9c925e844 100644 --- a/src/state.rs +++ b/src/state.rs @@ -279,12 +279,26 @@ impl BackendData { } } -pub fn client_has_security_context(client: &Client) -> bool { +pub fn client_has_no_security_context(client: &Client) -> bool { client .get_data::() .map_or(true, |client_state| client_state.security_context.is_none()) } +pub fn client_is_privileged(client: &Client) -> bool { + std::env::var("COSMIC_DISABLE_WAYLAND_SECURITY") + .map(|x| { + x == "1" + || x.to_lowercase() == "true" + || x.to_lowercase() == "yes" + || x.to_lowercase() == "y" + }) + .unwrap_or(false) + || client + .get_data::() + .map_or(false, |client_state| client_state.privileged) +} + impl State { pub fn new( dh: &DisplayHandle, @@ -305,15 +319,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, client_has_security_context); + let output_configuration_state = OutputConfigurationState::new(dh, client_is_privileged); 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], - client_has_security_context, - ); // TODO: privileged + client_is_privileged, + ); let shm_state = ShmState::new::(dh, vec![wl_shm::Format::Xbgr8888, wl_shm::Format::Abgr8888]); let seat_state = SeatState::::new(); @@ -322,11 +335,11 @@ impl State { let kde_decoration_state = KdeDecorationState::new::(&dh, Mode::Client); let xdg_decoration_state = XdgDecorationState::new::(&dh); let session_lock_manager_state = - SessionLockManagerState::new::(&dh, client_has_security_context); + SessionLockManagerState::new::(&dh, client_is_privileged); XWaylandKeyboardGrabState::new::(&dh); PointerConstraintsState::new::(&dh); PointerGesturesState::new::(&dh); - SecurityContextState::new::(&dh, client_has_security_context); + SecurityContextState::new::(&dh, client_has_no_security_context); let shell = Shell::new(&config, dh); diff --git a/src/wayland/handlers/security_context.rs b/src/wayland/handlers/security_context.rs index 50abd04d6..085c6b8bd 100644 --- a/src/wayland/handlers/security_context.rs +++ b/src/wayland/handlers/security_context.rs @@ -1,9 +1,11 @@ use crate::state::{ClientState, State}; use smithay::{ + backend::drm::DrmNode, delegate_security_context, wayland::security_context::{ SecurityContext, SecurityContextHandler, SecurityContextListenerSource, }, + xwayland::XWaylandClientData, }; use std::sync::Arc; use tracing::warn; @@ -17,10 +19,38 @@ impl SecurityContextHandler for State { self.common .event_loop_handle .insert_source(source, move |client_stream, _, state| { + let client_data = state + .common + .display_handle + .backend_handle() + .get_client_data(security_context.client_id.clone()) + .ok(); + + let privileged = client_data + .as_ref() + .and_then(|data| data.downcast_ref::()) + .map(|data| data.privileged) + .unwrap_or(false); + + let drm_node = client_data + .as_ref() + .and_then(|data| data.downcast_ref::()) + .and_then(|data| data.drm_node.clone()) + .or_else(|| { + client_data + .as_ref() + .and_then(|data| data.downcast_ref::()) + .and_then(|data| data.user_data().get::().cloned()) + }); + if let Err(err) = state.common.display_handle.insert_client( client_stream, Arc::new(ClientState { security_context: Some(security_context.clone()), + privileged: privileged + && security_context.sandbox_engine.as_deref() + == Some("com.system76.CosmicPanel"), + drm_node, ..state.new_client_state() }), ) {