security: remove context protocol
This commit is contained in:
parent
6f913d5f69
commit
8a35bc3ca4
16 changed files with 42 additions and 423 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
async_engine::SpawnedFuture,
|
async_engine::SpawnedFuture,
|
||||||
security_context_acceptor::AcceptorMetadata,
|
client::ClientMetadata,
|
||||||
state::State,
|
state::State,
|
||||||
utils::{
|
utils::{
|
||||||
errorfmt::ErrorFmt,
|
errorfmt::ErrorFmt,
|
||||||
|
|
@ -138,7 +138,7 @@ impl Acceptor {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn accept(fd: Rc<OwnedFd>, state: Rc<State>) {
|
async fn accept(fd: Rc<OwnedFd>, state: Rc<State>) {
|
||||||
let metadata = Rc::new(AcceptorMetadata::default());
|
let metadata = Rc::new(ClientMetadata::default());
|
||||||
loop {
|
loop {
|
||||||
let fd = match state.ring.accept(&fd, c::SOCK_CLOEXEC).await {
|
let fd = match state.ring.accept(&fd, c::SOCK_CLOEXEC).await {
|
||||||
Ok(fd) => fd,
|
Ok(fd) => fd,
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ use {
|
||||||
},
|
},
|
||||||
leaks::Tracker,
|
leaks::Tracker,
|
||||||
object::{Interface, Object, ObjectId, WL_DISPLAY_ID},
|
object::{Interface, Object, ObjectId, WL_DISPLAY_ID},
|
||||||
security_context_acceptor::AcceptorMetadata,
|
|
||||||
state::State,
|
state::State,
|
||||||
utils::{
|
utils::{
|
||||||
asyncevent::AsyncEvent,
|
asyncevent::AsyncEvent,
|
||||||
|
|
@ -95,6 +94,14 @@ pub struct Clients {
|
||||||
shutdown_clients: RefCell<AHashMap<ClientId, ClientHolder>>,
|
shutdown_clients: RefCell<AHashMap<ClientId, ClientHolder>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct ClientMetadata {
|
||||||
|
pub sandboxed: bool,
|
||||||
|
pub sandbox_engine: Option<String>,
|
||||||
|
pub app_id: Option<String>,
|
||||||
|
pub instance_id: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Clients {
|
impl Clients {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -126,12 +133,12 @@ impl Clients {
|
||||||
id: ClientId,
|
id: ClientId,
|
||||||
global: &Rc<State>,
|
global: &Rc<State>,
|
||||||
socket: Rc<OwnedFd>,
|
socket: Rc<OwnedFd>,
|
||||||
acceptor: &Rc<AcceptorMetadata>,
|
metadata: &Rc<ClientMetadata>,
|
||||||
) -> Result<(), ClientError> {
|
) -> Result<(), ClientError> {
|
||||||
let Some((uid, pid)) = get_socket_creds(&socket) else {
|
let Some((uid, pid)) = get_socket_creds(&socket) else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
self.spawn2(id, global, socket, uid, pid, false, acceptor)?;
|
self.spawn2(id, global, socket, uid, pid, false, metadata)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -143,7 +150,7 @@ impl Clients {
|
||||||
uid: c::uid_t,
|
uid: c::uid_t,
|
||||||
pid: c::pid_t,
|
pid: c::pid_t,
|
||||||
is_xwayland: bool,
|
is_xwayland: bool,
|
||||||
acceptor: &Rc<AcceptorMetadata>,
|
metadata: &Rc<ClientMetadata>,
|
||||||
) -> Result<Rc<Client>, ClientError> {
|
) -> Result<Rc<Client>, ClientError> {
|
||||||
let data = Rc::new_cyclic(|slf| Client {
|
let data = Rc::new_cyclic(|slf| Client {
|
||||||
id,
|
id,
|
||||||
|
|
@ -173,7 +180,7 @@ impl Clients {
|
||||||
focus_stealing_serial: Default::default(),
|
focus_stealing_serial: Default::default(),
|
||||||
changed_properties: Default::default(),
|
changed_properties: Default::default(),
|
||||||
destroyed: Default::default(),
|
destroyed: Default::default(),
|
||||||
acceptor: acceptor.clone(),
|
metadata: metadata.clone(),
|
||||||
});
|
});
|
||||||
track!(data, data);
|
track!(data, data);
|
||||||
let display = Rc::new(WlDisplay::new(&data));
|
let display = Rc::new(WlDisplay::new(&data));
|
||||||
|
|
@ -292,7 +299,7 @@ pub struct Client {
|
||||||
pub focus_stealing_serial: Cell<Option<u64>>,
|
pub focus_stealing_serial: Cell<Option<u64>>,
|
||||||
pub changed_properties: Cell<ClMatcherChange>,
|
pub changed_properties: Cell<ClMatcherChange>,
|
||||||
pub destroyed: CopyHashMap<CritMatcherId, Weak<dyn CritDestroyListener<Self>>>,
|
pub destroyed: CopyHashMap<CritMatcherId, Weak<dyn CritDestroyListener<Self>>>,
|
||||||
pub acceptor: Rc<AcceptorMetadata>,
|
pub metadata: Rc<ClientMetadata>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const NUM_CACHED_SERIAL_RANGES: usize = 64;
|
pub const NUM_CACHED_SERIAL_RANGES: usize = 64;
|
||||||
|
|
|
||||||
|
|
@ -325,7 +325,6 @@ fn start_compositor2(
|
||||||
explicit_sync_supported: Default::default(),
|
explicit_sync_supported: Default::default(),
|
||||||
keyboard_state_ids: Default::default(),
|
keyboard_state_ids: Default::default(),
|
||||||
physical_keyboard_ids: Default::default(),
|
physical_keyboard_ids: Default::default(),
|
||||||
security_context_acceptors: Default::default(),
|
|
||||||
cursor_user_group_ids: Default::default(),
|
cursor_user_group_ids: Default::default(),
|
||||||
cursor_user_ids: Default::default(),
|
cursor_user_ids: Default::default(),
|
||||||
cursor_user_groups: Default::default(),
|
cursor_user_groups: Default::default(),
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,6 @@ fixed_root_criterion!(ClmMatchSandboxed, sandboxed);
|
||||||
|
|
||||||
impl CritFixedRootCriterion<Client> for ClmMatchSandboxed {
|
impl CritFixedRootCriterion<Client> for ClmMatchSandboxed {
|
||||||
fn matches(&self, data: &Client) -> bool {
|
fn matches(&self, data: &Client) -> bool {
|
||||||
data.acceptor.sandboxed
|
data.metadata.sandboxed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,44 +1,43 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
client::Client,
|
client::{Client, ClientMetadata},
|
||||||
criteria::{
|
criteria::{
|
||||||
clm::{ClmRootMatcherMap, RootMatchers},
|
clm::{ClmRootMatcherMap, RootMatchers},
|
||||||
crit_matchers::critm_string::{CritMatchString, StringAccess},
|
crit_matchers::critm_string::{CritMatchString, StringAccess},
|
||||||
},
|
},
|
||||||
security_context_acceptor::AcceptorMetadata,
|
|
||||||
},
|
},
|
||||||
std::marker::PhantomData,
|
std::marker::PhantomData,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type ClmMatchString<T> = CritMatchString<Client, T>;
|
pub type ClmMatchString<T> = CritMatchString<Client, T>;
|
||||||
|
|
||||||
pub type ClmMatchSandboxEngine = ClmMatchString<AcceptorMetadataAccess<SandboxEngineField>>;
|
pub type ClmMatchSandboxEngine = ClmMatchString<ClientMetadataAccess<SandboxEngineField>>;
|
||||||
pub type ClmMatchSandboxAppId = ClmMatchString<AcceptorMetadataAccess<SandboxAppIdField>>;
|
pub type ClmMatchSandboxAppId = ClmMatchString<ClientMetadataAccess<SandboxAppIdField>>;
|
||||||
pub type ClmMatchSandboxInstanceId = ClmMatchString<AcceptorMetadataAccess<SandboxInstanceIdField>>;
|
pub type ClmMatchSandboxInstanceId = ClmMatchString<ClientMetadataAccess<SandboxInstanceIdField>>;
|
||||||
pub type ClmMatchComm = ClmMatchString<CommAccess>;
|
pub type ClmMatchComm = ClmMatchString<CommAccess>;
|
||||||
pub type ClmMatchExe = ClmMatchString<ExeAccess>;
|
pub type ClmMatchExe = ClmMatchString<ExeAccess>;
|
||||||
|
|
||||||
pub struct AcceptorMetadataAccess<T>(PhantomData<T>);
|
pub struct ClientMetadataAccess<T>(PhantomData<T>);
|
||||||
pub struct CommAccess;
|
pub struct CommAccess;
|
||||||
pub struct ExeAccess;
|
pub struct ExeAccess;
|
||||||
|
|
||||||
trait AcceptorMetadataField: Sized + 'static {
|
trait ClientMetadataField: Sized + 'static {
|
||||||
fn field(meta: &AcceptorMetadata) -> &Option<String>;
|
fn field(meta: &ClientMetadata) -> &Option<String>;
|
||||||
fn nodes(
|
fn nodes(
|
||||||
roots: &RootMatchers,
|
roots: &RootMatchers,
|
||||||
) -> &ClmRootMatcherMap<ClmMatchString<AcceptorMetadataAccess<Self>>>;
|
) -> &ClmRootMatcherMap<ClmMatchString<ClientMetadataAccess<Self>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SandboxEngineField;
|
pub struct SandboxEngineField;
|
||||||
pub struct SandboxAppIdField;
|
pub struct SandboxAppIdField;
|
||||||
pub struct SandboxInstanceIdField;
|
pub struct SandboxInstanceIdField;
|
||||||
|
|
||||||
impl<T> StringAccess<Client> for AcceptorMetadataAccess<T>
|
impl<T> StringAccess<Client> for ClientMetadataAccess<T>
|
||||||
where
|
where
|
||||||
T: AcceptorMetadataField,
|
T: ClientMetadataField,
|
||||||
{
|
{
|
||||||
fn with_string(data: &Client, f: impl FnOnce(&str) -> bool) -> bool {
|
fn with_string(data: &Client, f: impl FnOnce(&str) -> bool) -> bool {
|
||||||
f(T::field(&data.acceptor).as_deref().unwrap_or_default())
|
f(T::field(&data.metadata).as_deref().unwrap_or_default())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn nodes(roots: &RootMatchers) -> &ClmRootMatcherMap<ClmMatchString<Self>> {
|
fn nodes(roots: &RootMatchers) -> &ClmRootMatcherMap<ClmMatchString<Self>> {
|
||||||
|
|
@ -46,38 +45,38 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AcceptorMetadataField for SandboxEngineField {
|
impl ClientMetadataField for SandboxEngineField {
|
||||||
fn field(meta: &AcceptorMetadata) -> &Option<String> {
|
fn field(meta: &ClientMetadata) -> &Option<String> {
|
||||||
&meta.sandbox_engine
|
&meta.sandbox_engine
|
||||||
}
|
}
|
||||||
|
|
||||||
fn nodes(
|
fn nodes(
|
||||||
roots: &RootMatchers,
|
roots: &RootMatchers,
|
||||||
) -> &ClmRootMatcherMap<ClmMatchString<AcceptorMetadataAccess<Self>>> {
|
) -> &ClmRootMatcherMap<ClmMatchString<ClientMetadataAccess<Self>>> {
|
||||||
&roots.sandbox_engine
|
&roots.sandbox_engine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AcceptorMetadataField for SandboxAppIdField {
|
impl ClientMetadataField for SandboxAppIdField {
|
||||||
fn field(meta: &AcceptorMetadata) -> &Option<String> {
|
fn field(meta: &ClientMetadata) -> &Option<String> {
|
||||||
&meta.app_id
|
&meta.app_id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn nodes(
|
fn nodes(
|
||||||
roots: &RootMatchers,
|
roots: &RootMatchers,
|
||||||
) -> &ClmRootMatcherMap<ClmMatchString<AcceptorMetadataAccess<Self>>> {
|
) -> &ClmRootMatcherMap<ClmMatchString<ClientMetadataAccess<Self>>> {
|
||||||
&roots.sandbox_app_id
|
&roots.sandbox_app_id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AcceptorMetadataField for SandboxInstanceIdField {
|
impl ClientMetadataField for SandboxInstanceIdField {
|
||||||
fn field(meta: &AcceptorMetadata) -> &Option<String> {
|
fn field(meta: &ClientMetadata) -> &Option<String> {
|
||||||
&meta.instance_id
|
&meta.instance_id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn nodes(
|
fn nodes(
|
||||||
roots: &RootMatchers,
|
roots: &RootMatchers,
|
||||||
) -> &ClmRootMatcherMap<ClmMatchString<AcceptorMetadataAccess<Self>>> {
|
) -> &ClmRootMatcherMap<ClmMatchString<ClientMetadataAccess<Self>>> {
|
||||||
&roots.sandbox_instance_id
|
&roots.sandbox_instance_id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,6 @@ use {
|
||||||
wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1Global,
|
wp_fractional_scale_manager_v1::WpFractionalScaleManagerV1Global,
|
||||||
wp_linux_drm_syncobj_manager_v1::WpLinuxDrmSyncobjManagerV1Global,
|
wp_linux_drm_syncobj_manager_v1::WpLinuxDrmSyncobjManagerV1Global,
|
||||||
wp_presentation::WpPresentationGlobal,
|
wp_presentation::WpPresentationGlobal,
|
||||||
wp_security_context_manager_v1::WpSecurityContextManagerV1Global,
|
|
||||||
wp_single_pixel_buffer_manager_v1::WpSinglePixelBufferManagerV1Global,
|
wp_single_pixel_buffer_manager_v1::WpSinglePixelBufferManagerV1Global,
|
||||||
wp_tearing_control_manager_v1::WpTearingControlManagerV1Global,
|
wp_tearing_control_manager_v1::WpTearingControlManagerV1Global,
|
||||||
wp_viewporter::WpViewporterGlobal,
|
wp_viewporter::WpViewporterGlobal,
|
||||||
|
|
@ -205,7 +204,6 @@ singletons! {
|
||||||
ZwpVirtualKeyboardManagerV1,
|
ZwpVirtualKeyboardManagerV1,
|
||||||
ZwpInputMethodManagerV2,
|
ZwpInputMethodManagerV2,
|
||||||
ZwpTextInputManagerV3,
|
ZwpTextInputManagerV3,
|
||||||
WpSecurityContextManagerV1,
|
|
||||||
XdgWmDialogV1,
|
XdgWmDialogV1,
|
||||||
ExtTransientSeatManagerV1,
|
ExtTransientSeatManagerV1,
|
||||||
ZwpPointerGesturesV1,
|
ZwpPointerGesturesV1,
|
||||||
|
|
|
||||||
|
|
@ -74,8 +74,6 @@ pub mod wp_linux_drm_syncobj_manager_v1;
|
||||||
pub mod wp_linux_drm_syncobj_timeline_v1;
|
pub mod wp_linux_drm_syncobj_timeline_v1;
|
||||||
pub mod wp_presentation;
|
pub mod wp_presentation;
|
||||||
pub mod wp_presentation_feedback;
|
pub mod wp_presentation_feedback;
|
||||||
pub mod wp_security_context_manager_v1;
|
|
||||||
pub mod wp_security_context_v1;
|
|
||||||
pub mod wp_single_pixel_buffer_manager_v1;
|
pub mod wp_single_pixel_buffer_manager_v1;
|
||||||
pub mod wp_tearing_control_manager_v1;
|
pub mod wp_tearing_control_manager_v1;
|
||||||
pub mod wp_viewporter;
|
pub mod wp_viewporter;
|
||||||
|
|
|
||||||
|
|
@ -71,25 +71,25 @@ impl JayClientQueryRequestHandler for JayClientQuery {
|
||||||
exe: &client.pid_info.exe,
|
exe: &client.pid_info.exe,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if client.acceptor.sandboxed {
|
if client.metadata.sandboxed {
|
||||||
self.client.event(Sandboxed { self_id: self.id });
|
self.client.event(Sandboxed { self_id: self.id });
|
||||||
}
|
}
|
||||||
if client.is_xwayland {
|
if client.is_xwayland {
|
||||||
self.client.event(IsXwayland { self_id: self.id });
|
self.client.event(IsXwayland { self_id: self.id });
|
||||||
}
|
}
|
||||||
if let Some(engine) = &client.acceptor.sandbox_engine {
|
if let Some(engine) = &client.metadata.sandbox_engine {
|
||||||
self.client.event(SandboxEngine {
|
self.client.event(SandboxEngine {
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
engine,
|
engine,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(app_id) = &client.acceptor.app_id {
|
if let Some(app_id) = &client.metadata.app_id {
|
||||||
self.client.event(SandboxAppId {
|
self.client.event(SandboxAppId {
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
app_id,
|
app_id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(instance_id) = &client.acceptor.instance_id {
|
if let Some(instance_id) = &client.metadata.instance_id {
|
||||||
self.client.event(SandboxInstanceId {
|
self.client.event(SandboxInstanceId {
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
instance_id,
|
instance_id,
|
||||||
|
|
|
||||||
|
|
@ -1,103 +0,0 @@
|
||||||
use {
|
|
||||||
crate::{
|
|
||||||
client::{Client, ClientError},
|
|
||||||
globals::{Global, GlobalName},
|
|
||||||
ifs::wp_security_context_v1::WpSecurityContextV1,
|
|
||||||
leaks::Tracker,
|
|
||||||
object::{Object, Version},
|
|
||||||
wire::{WpSecurityContextManagerV1Id, wp_security_context_manager_v1::*},
|
|
||||||
},
|
|
||||||
std::rc::Rc,
|
|
||||||
thiserror::Error,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct WpSecurityContextManagerV1Global {
|
|
||||||
pub name: GlobalName,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WpSecurityContextManagerV1Global {
|
|
||||||
pub fn new(name: GlobalName) -> Self {
|
|
||||||
Self { name }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bind_(
|
|
||||||
self: Rc<Self>,
|
|
||||||
id: WpSecurityContextManagerV1Id,
|
|
||||||
client: &Rc<Client>,
|
|
||||||
version: Version,
|
|
||||||
) -> Result<(), WpSecurityContextManagerV1Error> {
|
|
||||||
let obj = Rc::new(WpSecurityContextManagerV1 {
|
|
||||||
id,
|
|
||||||
client: client.clone(),
|
|
||||||
tracker: Default::default(),
|
|
||||||
version,
|
|
||||||
});
|
|
||||||
track!(client, obj);
|
|
||||||
client.add_client_obj(&obj)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
global_base!(
|
|
||||||
WpSecurityContextManagerV1Global,
|
|
||||||
WpSecurityContextManagerV1,
|
|
||||||
WpSecurityContextManagerV1Error
|
|
||||||
);
|
|
||||||
|
|
||||||
impl Global for WpSecurityContextManagerV1Global {
|
|
||||||
fn version(&self) -> u32 {
|
|
||||||
1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
simple_add_global!(WpSecurityContextManagerV1Global);
|
|
||||||
|
|
||||||
pub struct WpSecurityContextManagerV1 {
|
|
||||||
pub id: WpSecurityContextManagerV1Id,
|
|
||||||
pub client: Rc<Client>,
|
|
||||||
pub tracker: Tracker<Self>,
|
|
||||||
pub version: Version,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WpSecurityContextManagerV1RequestHandler for WpSecurityContextManagerV1 {
|
|
||||||
type Error = WpSecurityContextManagerV1Error;
|
|
||||||
|
|
||||||
fn destroy(&self, _req: Destroy, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
|
||||||
self.client.remove_obj(self)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_listener(&self, req: CreateListener, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
|
||||||
let obj = Rc::new(WpSecurityContextV1 {
|
|
||||||
id: req.id,
|
|
||||||
client: self.client.clone(),
|
|
||||||
tracker: Default::default(),
|
|
||||||
version: self.version,
|
|
||||||
listen_fd: req.listen_fd,
|
|
||||||
close_fd: req.close_fd,
|
|
||||||
sandbox_engine: Default::default(),
|
|
||||||
app_id: Default::default(),
|
|
||||||
instance_id: Default::default(),
|
|
||||||
committed: Default::default(),
|
|
||||||
});
|
|
||||||
track!(self.client, obj);
|
|
||||||
self.client.add_client_obj(&obj)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object_base! {
|
|
||||||
self = WpSecurityContextManagerV1;
|
|
||||||
version = self.version;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Object for WpSecurityContextManagerV1 {}
|
|
||||||
|
|
||||||
simple_add_obj!(WpSecurityContextManagerV1);
|
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
|
||||||
pub enum WpSecurityContextManagerV1Error {
|
|
||||||
#[error(transparent)]
|
|
||||||
ClientError(Box<ClientError>),
|
|
||||||
}
|
|
||||||
efrom!(WpSecurityContextManagerV1Error, ClientError);
|
|
||||||
|
|
@ -1,117 +0,0 @@
|
||||||
use {
|
|
||||||
crate::{
|
|
||||||
client::{Client, ClientError},
|
|
||||||
leaks::Tracker,
|
|
||||||
object::{Object, Version},
|
|
||||||
wire::{WpSecurityContextV1Id, wp_security_context_v1::*},
|
|
||||||
},
|
|
||||||
std::{
|
|
||||||
cell::{Cell, RefCell},
|
|
||||||
rc::Rc,
|
|
||||||
},
|
|
||||||
thiserror::Error,
|
|
||||||
uapi::OwnedFd,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct WpSecurityContextV1 {
|
|
||||||
pub id: WpSecurityContextV1Id,
|
|
||||||
pub client: Rc<Client>,
|
|
||||||
pub tracker: Tracker<Self>,
|
|
||||||
pub version: Version,
|
|
||||||
pub listen_fd: Rc<OwnedFd>,
|
|
||||||
pub close_fd: Rc<OwnedFd>,
|
|
||||||
pub sandbox_engine: RefCell<Option<String>>,
|
|
||||||
pub app_id: RefCell<Option<String>>,
|
|
||||||
pub instance_id: RefCell<Option<String>>,
|
|
||||||
pub committed: Cell<bool>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WpSecurityContextV1 {
|
|
||||||
fn check_committed(&self) -> Result<(), WpSecurityContextV1Error> {
|
|
||||||
if self.committed.get() {
|
|
||||||
return Err(WpSecurityContextV1Error::Committed);
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WpSecurityContextV1RequestHandler for WpSecurityContextV1 {
|
|
||||||
type Error = WpSecurityContextV1Error;
|
|
||||||
|
|
||||||
fn destroy(&self, _req: Destroy, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
|
||||||
self.client.remove_obj(self)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_sandbox_engine(
|
|
||||||
&self,
|
|
||||||
req: SetSandboxEngine<'_>,
|
|
||||||
_slf: &Rc<Self>,
|
|
||||||
) -> Result<(), Self::Error> {
|
|
||||||
self.check_committed()?;
|
|
||||||
let val = &mut *self.sandbox_engine.borrow_mut();
|
|
||||||
if val.is_some() {
|
|
||||||
return Err(WpSecurityContextV1Error::EnginSet);
|
|
||||||
}
|
|
||||||
*val = Some(req.name.to_string());
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_app_id(&self, req: SetAppId<'_>, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
|
||||||
self.check_committed()?;
|
|
||||||
let val = &mut *self.app_id.borrow_mut();
|
|
||||||
if val.is_some() {
|
|
||||||
return Err(WpSecurityContextV1Error::AppSet);
|
|
||||||
}
|
|
||||||
*val = Some(req.app_id.to_string());
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_instance_id(&self, req: SetInstanceId<'_>, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
|
||||||
self.check_committed()?;
|
|
||||||
let val = &mut *self.instance_id.borrow_mut();
|
|
||||||
if val.is_some() {
|
|
||||||
return Err(WpSecurityContextV1Error::InstanceSet);
|
|
||||||
}
|
|
||||||
*val = Some(req.instance_id.to_string());
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn commit(&self, _req: Commit, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
|
||||||
self.check_committed()?;
|
|
||||||
self.committed.set(true);
|
|
||||||
self.client.state.security_context_acceptors.spawn(
|
|
||||||
&self.client.state,
|
|
||||||
self.sandbox_engine.take(),
|
|
||||||
self.app_id.take(),
|
|
||||||
self.instance_id.take(),
|
|
||||||
&self.listen_fd,
|
|
||||||
&self.close_fd,
|
|
||||||
);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object_base! {
|
|
||||||
self = WpSecurityContextV1;
|
|
||||||
version = self.version;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Object for WpSecurityContextV1 {}
|
|
||||||
|
|
||||||
simple_add_obj!(WpSecurityContextV1);
|
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
|
||||||
pub enum WpSecurityContextV1Error {
|
|
||||||
#[error(transparent)]
|
|
||||||
ClientError(Box<ClientError>),
|
|
||||||
#[error("The sandbox engine has already been set")]
|
|
||||||
EnginSet,
|
|
||||||
#[error("The app id has already been set")]
|
|
||||||
AppSet,
|
|
||||||
#[error("The instance id has already been set")]
|
|
||||||
InstanceSet,
|
|
||||||
#[error("The context has already been committed")]
|
|
||||||
Committed,
|
|
||||||
}
|
|
||||||
efrom!(WpSecurityContextV1Error, ClientError);
|
|
||||||
|
|
@ -97,7 +97,6 @@ mod rect;
|
||||||
mod renderer;
|
mod renderer;
|
||||||
mod scale;
|
mod scale;
|
||||||
mod screenshoter;
|
mod screenshoter;
|
||||||
mod security_context_acceptor;
|
|
||||||
mod sighand;
|
mod sighand;
|
||||||
mod state;
|
mod state;
|
||||||
mod tasks;
|
mod tasks;
|
||||||
|
|
|
||||||
|
|
@ -1,132 +0,0 @@
|
||||||
use {
|
|
||||||
crate::{
|
|
||||||
async_engine::SpawnedFuture,
|
|
||||||
state::State,
|
|
||||||
utils::{copyhashmap::CopyHashMap, errorfmt::ErrorFmt, hash_map_ext::HashMapExt},
|
|
||||||
},
|
|
||||||
std::{
|
|
||||||
cell::Cell,
|
|
||||||
fmt::{Display, Formatter},
|
|
||||||
rc::Rc,
|
|
||||||
},
|
|
||||||
uapi::{OwnedFd, c},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct SecurityContextAcceptors {
|
|
||||||
ids: AcceptorIds,
|
|
||||||
acceptors: CopyHashMap<AcceptorId, Rc<Acceptor>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
linear_ids!(AcceptorIds, AcceptorId, u64);
|
|
||||||
|
|
||||||
struct Acceptor {
|
|
||||||
id: AcceptorId,
|
|
||||||
state: Rc<State>,
|
|
||||||
metadata: Rc<AcceptorMetadata>,
|
|
||||||
listen_fd: Rc<OwnedFd>,
|
|
||||||
close_fd: Rc<OwnedFd>,
|
|
||||||
listen_future: Cell<Option<SpawnedFuture<()>>>,
|
|
||||||
close_future: Cell<Option<SpawnedFuture<()>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct AcceptorMetadata {
|
|
||||||
pub sandboxed: bool,
|
|
||||||
pub sandbox_engine: Option<String>,
|
|
||||||
pub app_id: Option<String>,
|
|
||||||
pub instance_id: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SecurityContextAcceptors {
|
|
||||||
pub fn clear(&self) {
|
|
||||||
for acceptor in self.acceptors.lock().drain_values() {
|
|
||||||
acceptor.kill();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spawn(
|
|
||||||
&self,
|
|
||||||
state: &Rc<State>,
|
|
||||||
sandbox_engine: Option<String>,
|
|
||||||
app_id: Option<String>,
|
|
||||||
instance_id: Option<String>,
|
|
||||||
listen_fd: &Rc<OwnedFd>,
|
|
||||||
close_fd: &Rc<OwnedFd>,
|
|
||||||
) {
|
|
||||||
let acceptor = Rc::new(Acceptor {
|
|
||||||
id: self.ids.next(),
|
|
||||||
state: state.clone(),
|
|
||||||
metadata: Rc::new(AcceptorMetadata {
|
|
||||||
sandboxed: true,
|
|
||||||
sandbox_engine,
|
|
||||||
app_id,
|
|
||||||
instance_id,
|
|
||||||
}),
|
|
||||||
listen_fd: listen_fd.clone(),
|
|
||||||
close_fd: close_fd.clone(),
|
|
||||||
listen_future: Cell::new(None),
|
|
||||||
close_future: Cell::new(None),
|
|
||||||
});
|
|
||||||
log::info!("Creating security acceptor {acceptor}");
|
|
||||||
acceptor.listen_future.set(Some(
|
|
||||||
state
|
|
||||||
.eng
|
|
||||||
.spawn("security accept", acceptor.clone().accept()),
|
|
||||||
));
|
|
||||||
acceptor.close_future.set(Some(
|
|
||||||
state
|
|
||||||
.eng
|
|
||||||
.spawn("security await close", acceptor.clone().close()),
|
|
||||||
));
|
|
||||||
self.acceptors.set(acceptor.id, acceptor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Acceptor {
|
|
||||||
fn kill(&self) {
|
|
||||||
log::info!("Destroying security acceptor {self}");
|
|
||||||
self.listen_future.take();
|
|
||||||
self.close_future.take();
|
|
||||||
self.state
|
|
||||||
.security_context_acceptors
|
|
||||||
.acceptors
|
|
||||||
.remove(&self.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn accept(self: Rc<Self>) {
|
|
||||||
let s = &self.state;
|
|
||||||
loop {
|
|
||||||
let fd = match s.ring.accept(&self.listen_fd, c::SOCK_CLOEXEC).await {
|
|
||||||
Ok(fd) => fd,
|
|
||||||
Err(e) => {
|
|
||||||
log::error!("Could not accept a client: {}", ErrorFmt(e));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let id = s.clients.id();
|
|
||||||
if let Err(e) = s.clients.spawn(id, s, fd, &self.metadata) {
|
|
||||||
log::error!("Could not spawn a client: {}", ErrorFmt(e));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.kill();
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn close(self: Rc<Self>) {
|
|
||||||
let _ = self.state.ring.poll(&self.close_fd, 0).await;
|
|
||||||
self.kill();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for Acceptor {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(
|
|
||||||
f,
|
|
||||||
"{}/{}/{}",
|
|
||||||
self.metadata.sandbox_engine.as_deref().unwrap_or(""),
|
|
||||||
self.metadata.app_id.as_deref().unwrap_or(""),
|
|
||||||
self.metadata.instance_id.as_deref().unwrap_or(""),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -108,7 +108,6 @@ use {
|
||||||
rect::{Rect, Region},
|
rect::{Rect, Region},
|
||||||
renderer::Renderer,
|
renderer::Renderer,
|
||||||
scale::Scale,
|
scale::Scale,
|
||||||
security_context_acceptor::SecurityContextAcceptors,
|
|
||||||
theme::{BarPosition, Color, Theme, ThemeColor, ThemeSized},
|
theme::{BarPosition, Color, Theme, ThemeColor, ThemeSized},
|
||||||
time::Time,
|
time::Time,
|
||||||
tree::{
|
tree::{
|
||||||
|
|
@ -343,7 +342,6 @@ pub struct State {
|
||||||
pub explicit_sync_supported: Cell<bool>,
|
pub explicit_sync_supported: Cell<bool>,
|
||||||
pub keyboard_state_ids: KeyboardStateIds,
|
pub keyboard_state_ids: KeyboardStateIds,
|
||||||
pub physical_keyboard_ids: PhysicalKeyboardIds,
|
pub physical_keyboard_ids: PhysicalKeyboardIds,
|
||||||
pub security_context_acceptors: SecurityContextAcceptors,
|
|
||||||
pub cursor_user_group_ids: CursorUserGroupIds,
|
pub cursor_user_group_ids: CursorUserGroupIds,
|
||||||
pub cursor_user_ids: CursorUserIds,
|
pub cursor_user_ids: CursorUserIds,
|
||||||
pub cursor_user_groups: CopyHashMap<CursorUserGroupId, Rc<CursorUserGroup>>,
|
pub cursor_user_groups: CopyHashMap<CursorUserGroupId, Rc<CursorUserGroup>>,
|
||||||
|
|
@ -1249,7 +1247,6 @@ impl State {
|
||||||
self.render_ctx_watchers.clear();
|
self.render_ctx_watchers.clear();
|
||||||
self.workspace_watchers.clear();
|
self.workspace_watchers.clear();
|
||||||
self.toplevel_lists.clear();
|
self.toplevel_lists.clear();
|
||||||
self.security_context_acceptors.clear();
|
|
||||||
self.slow_clients.clear();
|
self.slow_clients.clear();
|
||||||
for h in self.input_device_handlers.borrow_mut().drain_values() {
|
for h in self.input_device_handlers.borrow_mut().drain_values() {
|
||||||
h.async_event.clear();
|
h.async_event.clear();
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ mod xwm;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
client::ClientError,
|
client::{ClientError, ClientMetadata},
|
||||||
compositor::DISPLAY,
|
compositor::DISPLAY,
|
||||||
forker::{ForkerError, ForkerProxy},
|
forker::{ForkerError, ForkerProxy},
|
||||||
ifs::{
|
ifs::{
|
||||||
|
|
@ -12,7 +12,6 @@ use {
|
||||||
wl_surface::x_surface::xwindow::{Xwindow, XwindowData},
|
wl_surface::x_surface::xwindow::{Xwindow, XwindowData},
|
||||||
},
|
},
|
||||||
io_uring::IoUringError,
|
io_uring::IoUringError,
|
||||||
security_context_acceptor::AcceptorMetadata,
|
|
||||||
state::State,
|
state::State,
|
||||||
user_session::import_environment,
|
user_session::import_environment,
|
||||||
utils::{
|
utils::{
|
||||||
|
|
@ -192,7 +191,7 @@ async fn run(
|
||||||
uapi::getuid(),
|
uapi::getuid(),
|
||||||
pid,
|
pid,
|
||||||
true,
|
true,
|
||||||
&Rc::new(AcceptorMetadata::default()),
|
&Rc::new(ClientMetadata::default()),
|
||||||
);
|
);
|
||||||
let client = match client {
|
let client = match client {
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
request destroy (destructor) {
|
|
||||||
}
|
|
||||||
|
|
||||||
request create_listener {
|
|
||||||
id: id(wp_security_context_v1) (new),
|
|
||||||
listen_fd: fd,
|
|
||||||
close_fd: fd,
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
request destroy (destructor) {
|
|
||||||
}
|
|
||||||
|
|
||||||
request set_sandbox_engine {
|
|
||||||
name: str,
|
|
||||||
}
|
|
||||||
|
|
||||||
request set_app_id {
|
|
||||||
app_id: str,
|
|
||||||
}
|
|
||||||
|
|
||||||
request set_instance_id {
|
|
||||||
instance_id: str,
|
|
||||||
}
|
|
||||||
|
|
||||||
request commit {
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue