1
0
Fork 0
forked from wry/wry

config: add uid client criteria

This commit is contained in:
Julian Orth 2025-05-03 12:48:44 +02:00
parent 9bf79bf23c
commit 587ffc7ee5
13 changed files with 63 additions and 2 deletions

View file

@ -82,6 +82,7 @@ pub enum ClientCriterionIpc {
regex: bool, regex: bool,
}, },
Sandboxed, Sandboxed,
Uid(i32),
} }
#[derive(Serialize, Deserialize, Clone, Debug, Hash, Eq, PartialEq)] #[derive(Serialize, Deserialize, Clone, Debug, Hash, Eq, PartialEq)]

View file

@ -1542,6 +1542,7 @@ impl ConfigClient {
ClientCriterion::SandboxInstanceId(t) => string!(t, SandboxInstanceId, false), ClientCriterion::SandboxInstanceId(t) => string!(t, SandboxInstanceId, false),
ClientCriterion::SandboxInstanceIdRegex(t) => string!(t, SandboxInstanceId, true), ClientCriterion::SandboxInstanceIdRegex(t) => string!(t, SandboxInstanceId, true),
ClientCriterion::Sandboxed => ClientCriterionIpc::Sandboxed, ClientCriterion::Sandboxed => ClientCriterionIpc::Sandboxed,
ClientCriterion::Uid(p) => ClientCriterionIpc::Uid(p),
}; };
let res = self.send_with_response(&ClientMessage::CreateClientMatcher { criterion }); let res = self.send_with_response(&ClientMessage::CreateClientMatcher { criterion });
get_response!( get_response!(

View file

@ -77,6 +77,8 @@ pub enum ClientCriterion<'a> {
SandboxInstanceIdRegex(&'a str), SandboxInstanceIdRegex(&'a str),
/// Matches if the client is sandboxed. /// Matches if the client is sandboxed.
Sandboxed, Sandboxed,
/// Matches the user ID of the client.
Uid(i32),
} }
impl ClientCriterion<'_> { impl ClientCriterion<'_> {

View file

@ -1885,6 +1885,7 @@ impl ConfigProxyHandler {
} }
} }
ClientCriterionIpc::Sandboxed => mgr.sandboxed(), ClientCriterionIpc::Sandboxed => mgr.sandboxed(),
ClientCriterionIpc::Uid(p) => mgr.uid(*p),
}; };
let cached = Rc::new(CachedCriterion { let cached = Rc::new(CachedCriterion {
crit: criterion.clone(), crit: criterion.clone(),

View file

@ -11,6 +11,7 @@ use {
clmm_string::{ clmm_string::{
ClmMatchSandboxAppId, ClmMatchSandboxEngine, ClmMatchSandboxInstanceId, ClmMatchSandboxAppId, ClmMatchSandboxEngine, ClmMatchSandboxInstanceId,
}, },
clmm_uid::ClmMatchUid,
}, },
crit_graph::{ crit_graph::{
CritMgr, CritRoot, CritRootFixed, CritTarget, CritTargetOwner, WeakCritTargetOwner, CritMgr, CritRoot, CritRootFixed, CritTarget, CritTargetOwner, WeakCritTargetOwner,
@ -52,6 +53,7 @@ pub struct RootMatchers {
sandbox_app_id: ClmRootMatcherMap<ClmMatchSandboxAppId>, sandbox_app_id: ClmRootMatcherMap<ClmMatchSandboxAppId>,
sandbox_engine: ClmRootMatcherMap<ClmMatchSandboxEngine>, sandbox_engine: ClmRootMatcherMap<ClmMatchSandboxEngine>,
sandbox_instance_id: ClmRootMatcherMap<ClmMatchSandboxInstanceId>, sandbox_instance_id: ClmRootMatcherMap<ClmMatchSandboxInstanceId>,
uid: ClmRootMatcherMap<ClmMatchUid>,
} }
pub async fn handle_cl_changes(state: Rc<State>) { pub async fn handle_cl_changes(state: Rc<State>) {
@ -151,6 +153,7 @@ impl ClMatcherManager {
unconditional!(sandbox_instance_id); unconditional!(sandbox_instance_id);
unconditional!(sandbox_app_id); unconditional!(sandbox_app_id);
unconditional!(sandbox_engine); unconditional!(sandbox_engine);
unconditional!(uid);
fixed!(sandboxed); fixed!(sandboxed);
self.constant[true].handle(data); self.constant[true].handle(data);
} }
@ -171,6 +174,10 @@ impl ClMatcherManager {
pub fn sandboxed(&self) -> Rc<ClmUpstreamNode> { pub fn sandboxed(&self) -> Rc<ClmUpstreamNode> {
self.sandboxed[true].clone() self.sandboxed[true].clone()
} }
pub fn uid(&self, pid: i32) -> Rc<ClmUpstreamNode> {
self.root(ClmMatchUid(pid as _))
}
} }
impl CritTarget for Rc<Client> { impl CritTarget for Rc<Client> {

View file

@ -19,3 +19,4 @@ macro_rules! fixed_root_criterion {
pub mod clmm_sandboxed; pub mod clmm_sandboxed;
pub mod clmm_string; pub mod clmm_string;
pub mod clmm_uid;

View file

@ -0,0 +1,20 @@
use {
crate::{
client::Client,
criteria::{RootMatcherMap, clm::RootMatchers, crit_graph::CritRootCriterion},
},
std::rc::Rc,
uapi::c,
};
pub struct ClmMatchUid(pub c::uid_t);
impl CritRootCriterion<Rc<Client>> for ClmMatchUid {
fn matches(&self, data: &Rc<Client>) -> bool {
data.pid_info.uid == self.0
}
fn nodes(roots: &RootMatchers) -> Option<&RootMatcherMap<Rc<Client>, Self>> {
Some(&roots.uid)
}
}

View file

@ -232,6 +232,7 @@ pub struct ClientMatch {
pub sandbox_instance_id: Option<String>, pub sandbox_instance_id: Option<String>,
pub sandbox_instance_id_regex: Option<String>, pub sandbox_instance_id_regex: Option<String>,
pub sandboxed: Option<bool>, pub sandboxed: Option<bool>,
pub uid: Option<i32>,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View file

@ -3,7 +3,7 @@ use {
config::{ config::{
ClientMatch, GenericMatch, MatchExactly, ClientMatch, GenericMatch, MatchExactly,
context::Context, context::Context,
extractor::{Extractor, ExtractorError, arr, bol, n32, opt, str, val}, extractor::{Extractor, ExtractorError, arr, bol, n32, opt, s32, str, val},
parser::{DataType, ParseResult, Parser, UnexpectedDataType}, parser::{DataType, ParseResult, Parser, UnexpectedDataType},
}, },
toml::{ toml::{
@ -49,7 +49,7 @@ impl Parser for ClientMatchParser<'_> {
sandbox_app_id, sandbox_app_id,
sandbox_app_id_regex, sandbox_app_id_regex,
), ),
(sandbox_instance_id, sandbox_instance_id_regex), (sandbox_instance_id, sandbox_instance_id_regex, uid),
) = ext.extract(( ) = ext.extract((
( (
opt(str("name")), opt(str("name")),
@ -66,6 +66,7 @@ impl Parser for ClientMatchParser<'_> {
( (
opt(str("sandbox-instance-id")), opt(str("sandbox-instance-id")),
opt(str("sandbox-instance-id-regex")), opt(str("sandbox-instance-id-regex")),
opt(s32("uid")),
), ),
))?; ))?;
let mut not = None; let mut not = None;
@ -106,6 +107,7 @@ impl Parser for ClientMatchParser<'_> {
sandbox_instance_id: sandbox_instance_id.despan_into(), sandbox_instance_id: sandbox_instance_id.despan_into(),
sandbox_instance_id_regex: sandbox_instance_id_regex.despan_into(), sandbox_instance_id_regex: sandbox_instance_id_regex.despan_into(),
sandboxed: sandboxed.despan(), sandboxed: sandboxed.despan(),
uid: uid.despan(),
}) })
} }
} }

View file

@ -95,6 +95,13 @@ impl Rule for ClientRule {
} }
}; };
} }
macro_rules! value {
($ty:ident, $field:ident) => {
if let Some(value) = match_.$field {
all.push(m(ClientCriterion::$ty(value)));
}
};
}
macro_rules! bool { macro_rules! bool {
($ty:ident, $field:ident) => { ($ty:ident, $field:ident) => {
if let Some(value) = &match_.$field { if let Some(value) = &match_.$field {
@ -113,6 +120,7 @@ impl Rule for ClientRule {
value_ref!(SandboxAppIdRegex, sandbox_app_id_regex); value_ref!(SandboxAppIdRegex, sandbox_app_id_regex);
value_ref!(SandboxInstanceId, sandbox_instance_id); value_ref!(SandboxInstanceId, sandbox_instance_id);
value_ref!(SandboxInstanceIdRegex, sandbox_instance_id_regex); value_ref!(SandboxInstanceIdRegex, sandbox_instance_id_regex);
value!(Uid, uid);
bool!(Sandboxed, sandboxed); bool!(Sandboxed, sandboxed);
Some(()) Some(())
} }

View file

@ -559,6 +559,10 @@
"sandbox-instance-id-regex": { "sandbox-instance-id-regex": {
"type": "string", "type": "string",
"description": "Matches the instance id of the client's sandbox with a regular expression.\n" "description": "Matches the instance id of the client's sandbox with a regular expression.\n"
},
"uid": {
"type": "integer",
"description": "Matches the user ID of the client."
} }
}, },
"required": [] "required": []

View file

@ -871,6 +871,14 @@ The table has the following fields:
The value of this field should be a string. The value of this field should be a string.
- `uid` (optional):
Matches the user ID of the client.
The value of this field should be a number.
The numbers should be integers.
<a name="types-ClientMatchExactly"></a> <a name="types-ClientMatchExactly"></a>
### `ClientMatchExactly` ### `ClientMatchExactly`

View file

@ -3237,6 +3237,11 @@ ClientMatch:
required: false required: false
description: | description: |
Matches the instance id of the client's sandbox with a regular expression. Matches the instance id of the client's sandbox with a regular expression.
uid:
kind: number
integer_only: true
required: false
description: Matches the user ID of the client.
ClientMatchExactly: ClientMatchExactly: