Merge pull request #208 from pop-os/panel-sec-context_jammy
wayland: Privileged protocol security
This commit is contained in:
commit
f7759a765b
5 changed files with 399 additions and 322 deletions
633
Cargo.lock
generated
633
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -88,4 +88,4 @@ debug = true
|
||||||
lto = "fat"
|
lto = "fat"
|
||||||
|
|
||||||
[patch."https://github.com/Smithay/smithay.git"]
|
[patch."https://github.com/Smithay/smithay.git"]
|
||||||
smithay = { git = "https://github.com/pop-os/smithay", branch = "x11_fixes" }
|
smithay = { git = "https://github.com/smithay//smithay", rev = "a8f3c46" }
|
||||||
|
|
@ -36,7 +36,7 @@ use smithay::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{Config, KeyModifiers, KeyPattern},
|
config::{Config, KeyModifiers, KeyPattern},
|
||||||
state::client_has_security_context,
|
state::client_should_see_privileged_protocols,
|
||||||
utils::prelude::*,
|
utils::prelude::*,
|
||||||
wayland::protocols::{
|
wayland::protocols::{
|
||||||
toplevel_info::ToplevelInfoState,
|
toplevel_info::ToplevelInfoState,
|
||||||
|
|
@ -849,28 +849,22 @@ pub struct InvalidWorkspaceIndex;
|
||||||
|
|
||||||
impl Shell {
|
impl Shell {
|
||||||
pub fn new(config: &Config, dh: &DisplayHandle) -> Self {
|
pub fn new(config: &Config, dh: &DisplayHandle) -> Self {
|
||||||
// TODO: Privileged protocols
|
let layer_shell_state = WlrLayerShellState::new_with_filter::<State, _>(
|
||||||
let layer_shell_state = WlrLayerShellState::new::<State>(dh);
|
|
||||||
let xdg_shell_state = XdgShellState::new::<State>(dh);
|
|
||||||
let toplevel_info_state = ToplevelInfoState::new(
|
|
||||||
dh,
|
dh,
|
||||||
//|client| client.get_data::<ClientState>().map_or(false, |s| s.privileged),
|
client_should_see_privileged_protocols,
|
||||||
client_has_security_context,
|
|
||||||
);
|
);
|
||||||
|
let xdg_shell_state = XdgShellState::new::<State>(dh);
|
||||||
|
let toplevel_info_state =
|
||||||
|
ToplevelInfoState::new(dh, client_should_see_privileged_protocols);
|
||||||
let toplevel_management_state = ToplevelManagementState::new::<State, _>(
|
let toplevel_management_state = ToplevelManagementState::new::<State, _>(
|
||||||
dh,
|
dh,
|
||||||
vec![
|
vec![
|
||||||
ManagementCapabilities::Close,
|
ManagementCapabilities::Close,
|
||||||
ManagementCapabilities::Activate,
|
ManagementCapabilities::Activate,
|
||||||
],
|
],
|
||||||
//|client| client.get_data::<ClientState>().map_or(false, |s| s.privileged),
|
client_should_see_privileged_protocols,
|
||||||
client_has_security_context,
|
|
||||||
);
|
|
||||||
let workspace_state = WorkspaceState::new(
|
|
||||||
dh,
|
|
||||||
//|client| client.get_data::<ClientState>().map_or(false, |s| s.privileged),
|
|
||||||
client_has_security_context,
|
|
||||||
);
|
);
|
||||||
|
let workspace_state = WorkspaceState::new(dh, client_should_see_privileged_protocols);
|
||||||
let theme = cosmic::theme::system_preference();
|
let theme = cosmic::theme::system_preference();
|
||||||
|
|
||||||
Shell {
|
Shell {
|
||||||
|
|
|
||||||
34
src/state.rs
34
src/state.rs
|
|
@ -279,12 +279,34 @@ impl BackendData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn client_has_security_context(client: &Client) -> bool {
|
pub fn client_has_no_security_context(client: &Client) -> bool {
|
||||||
client
|
client
|
||||||
.get_data::<ClientState>()
|
.get_data::<ClientState>()
|
||||||
.map_or(true, |client_state| client_state.security_context.is_none())
|
.map_or(true, |client_state| client_state.security_context.is_none())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn client_is_privileged(client: &Client) -> bool {
|
||||||
|
client
|
||||||
|
.get_data::<ClientState>()
|
||||||
|
.map_or(false, |client_state| client_state.privileged)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn client_should_see_privileged_protocols(client: &Client) -> bool {
|
||||||
|
if std::env::var("COSMIC_ENABLE_WAYLAND_SECURITY")
|
||||||
|
.map(|x| {
|
||||||
|
x == "1"
|
||||||
|
|| x.to_lowercase() == "true"
|
||||||
|
|| x.to_lowercase() == "yes"
|
||||||
|
|| x.to_lowercase() == "y"
|
||||||
|
})
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
|
client_is_privileged(client)
|
||||||
|
} else {
|
||||||
|
client_has_no_security_context(client)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
dh: &DisplayHandle,
|
dh: &DisplayHandle,
|
||||||
|
|
@ -306,14 +328,14 @@ impl State {
|
||||||
let keyboard_shortcuts_inhibit_state = KeyboardShortcutsInhibitState::new::<Self>(dh);
|
let keyboard_shortcuts_inhibit_state = KeyboardShortcutsInhibitState::new::<Self>(dh);
|
||||||
let output_state = OutputManagerState::new_with_xdg_output::<Self>(dh);
|
let output_state = OutputManagerState::new_with_xdg_output::<Self>(dh);
|
||||||
let output_configuration_state =
|
let output_configuration_state =
|
||||||
OutputConfigurationState::new(dh, client_has_security_context);
|
OutputConfigurationState::new(dh, client_should_see_privileged_protocols);
|
||||||
let presentation_state = PresentationState::new::<Self>(dh, clock.id() as u32);
|
let presentation_state = PresentationState::new::<Self>(dh, clock.id() as u32);
|
||||||
let primary_selection_state = PrimarySelectionState::new::<Self>(dh);
|
let primary_selection_state = PrimarySelectionState::new::<Self>(dh);
|
||||||
let screencopy_state = ScreencopyState::new::<Self, _, _>(
|
let screencopy_state = ScreencopyState::new::<Self, _, _>(
|
||||||
dh,
|
dh,
|
||||||
vec![CursorMode::Embedded, CursorMode::Hidden],
|
vec![CursorMode::Embedded, CursorMode::Hidden],
|
||||||
client_has_security_context,
|
client_should_see_privileged_protocols,
|
||||||
); // TODO: privileged
|
);
|
||||||
let shm_state =
|
let shm_state =
|
||||||
ShmState::new::<Self>(dh, vec![wl_shm::Format::Xbgr8888, wl_shm::Format::Abgr8888]);
|
ShmState::new::<Self>(dh, vec![wl_shm::Format::Xbgr8888, wl_shm::Format::Abgr8888]);
|
||||||
let seat_state = SeatState::<Self>::new();
|
let seat_state = SeatState::<Self>::new();
|
||||||
|
|
@ -322,11 +344,11 @@ impl State {
|
||||||
let kde_decoration_state = KdeDecorationState::new::<Self>(&dh, Mode::Client);
|
let kde_decoration_state = KdeDecorationState::new::<Self>(&dh, Mode::Client);
|
||||||
let xdg_decoration_state = XdgDecorationState::new::<Self>(&dh);
|
let xdg_decoration_state = XdgDecorationState::new::<Self>(&dh);
|
||||||
let session_lock_manager_state =
|
let session_lock_manager_state =
|
||||||
SessionLockManagerState::new::<Self, _>(&dh, client_has_security_context);
|
SessionLockManagerState::new::<Self, _>(&dh, client_should_see_privileged_protocols);
|
||||||
XWaylandKeyboardGrabState::new::<Self>(&dh);
|
XWaylandKeyboardGrabState::new::<Self>(&dh);
|
||||||
PointerConstraintsState::new::<Self>(&dh);
|
PointerConstraintsState::new::<Self>(&dh);
|
||||||
PointerGesturesState::new::<Self>(&dh);
|
PointerGesturesState::new::<Self>(&dh);
|
||||||
SecurityContextState::new::<Self, _>(&dh, client_has_security_context);
|
SecurityContextState::new::<Self, _>(&dh, client_has_no_security_context);
|
||||||
|
|
||||||
let shell = Shell::new(&config, dh);
|
let shell = Shell::new(&config, dh);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
use crate::state::{ClientState, State};
|
use crate::state::{ClientState, State};
|
||||||
use smithay::{
|
use smithay::{
|
||||||
|
backend::drm::DrmNode,
|
||||||
delegate_security_context,
|
delegate_security_context,
|
||||||
wayland::security_context::{
|
wayland::security_context::{
|
||||||
SecurityContext, SecurityContextHandler, SecurityContextListenerSource,
|
SecurityContext, SecurityContextHandler, SecurityContextListenerSource,
|
||||||
},
|
},
|
||||||
|
xwayland::XWaylandClientData,
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
|
|
@ -17,10 +19,38 @@ impl SecurityContextHandler for State {
|
||||||
self.common
|
self.common
|
||||||
.event_loop_handle
|
.event_loop_handle
|
||||||
.insert_source(source, move |client_stream, _, state| {
|
.insert_source(source, move |client_stream, _, state| {
|
||||||
|
let client_data = state
|
||||||
|
.common
|
||||||
|
.display_handle
|
||||||
|
.backend_handle()
|
||||||
|
.get_client_data(security_context.creator_client_id.clone())
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
let privileged = client_data
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|data| data.downcast_ref::<ClientState>())
|
||||||
|
.map(|data| data.privileged)
|
||||||
|
.unwrap_or(false);
|
||||||
|
|
||||||
|
let drm_node = client_data
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|data| data.downcast_ref::<ClientState>())
|
||||||
|
.and_then(|data| data.drm_node.clone())
|
||||||
|
.or_else(|| {
|
||||||
|
client_data
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|data| data.downcast_ref::<XWaylandClientData>())
|
||||||
|
.and_then(|data| data.user_data().get::<DrmNode>().cloned())
|
||||||
|
});
|
||||||
|
|
||||||
if let Err(err) = state.common.display_handle.insert_client(
|
if let Err(err) = state.common.display_handle.insert_client(
|
||||||
client_stream,
|
client_stream,
|
||||||
Arc::new(ClientState {
|
Arc::new(ClientState {
|
||||||
security_context: Some(security_context.clone()),
|
security_context: Some(security_context.clone()),
|
||||||
|
privileged: privileged
|
||||||
|
&& security_context.sandbox_engine.as_deref()
|
||||||
|
== Some("com.system76.CosmicPanel"),
|
||||||
|
drm_node,
|
||||||
..state.new_client_state()
|
..state.new_client_state()
|
||||||
}),
|
}),
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue