config: allow matching on client tag
This commit is contained in:
parent
596909cd25
commit
8b19315f50
13 changed files with 76 additions and 8 deletions
|
|
@ -204,6 +204,7 @@ The full specification of client criteria can be found in
|
||||||
- `is-xwayland` - Matches if the client is/isn't Xwayland.
|
- `is-xwayland` - Matches if the client is/isn't Xwayland.
|
||||||
- `comm`, `comm-regex` - Matches the `/proc/self/comm` of the client.
|
- `comm`, `comm-regex` - Matches the `/proc/self/comm` of the client.
|
||||||
- `exe`, `exe-regex` - Matches the `/proc/self/exe` of the client.
|
- `exe`, `exe-regex` - Matches the `/proc/self/exe` of the client.
|
||||||
|
- `tag`, `tag-regex` - Matches the tag of the client.
|
||||||
|
|
||||||
## Window Rules
|
## Window Rules
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,7 @@ pub enum ClientCriterionStringField {
|
||||||
SandboxInstanceId,
|
SandboxInstanceId,
|
||||||
Comm,
|
Comm,
|
||||||
Exe,
|
Exe,
|
||||||
|
Tag,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, Hash, Eq, PartialEq)]
|
#[derive(Serialize, Deserialize, Clone, Debug, Hash, Eq, PartialEq)]
|
||||||
|
|
|
||||||
|
|
@ -1764,6 +1764,8 @@ impl ConfigClient {
|
||||||
ClientCriterion::CommRegex(t) => string!(t, Comm, true),
|
ClientCriterion::CommRegex(t) => string!(t, Comm, true),
|
||||||
ClientCriterion::Exe(t) => string!(t, Exe, false),
|
ClientCriterion::Exe(t) => string!(t, Exe, false),
|
||||||
ClientCriterion::ExeRegex(t) => string!(t, Exe, true),
|
ClientCriterion::ExeRegex(t) => string!(t, Exe, true),
|
||||||
|
ClientCriterion::Tag(t) => string!(t, Tag, false),
|
||||||
|
ClientCriterion::TagRegex(t) => string!(t, Tag, true),
|
||||||
};
|
};
|
||||||
let res = self.send_with_response(&ClientMessage::CreateClientMatcher { criterion });
|
let res = self.send_with_response(&ClientMessage::CreateClientMatcher { criterion });
|
||||||
get_response!(
|
get_response!(
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,10 @@ pub enum ClientCriterion<'a> {
|
||||||
Exe(&'a str),
|
Exe(&'a str),
|
||||||
/// Matches the `/proc/pid/exe` of the client with a regular expression.
|
/// Matches the `/proc/pid/exe` of the client with a regular expression.
|
||||||
ExeRegex(&'a str),
|
ExeRegex(&'a str),
|
||||||
|
/// Matches the tag of the client verbatim.
|
||||||
|
Tag(&'a str),
|
||||||
|
/// Matches the tag of the client with a regular expression.
|
||||||
|
TagRegex(&'a str),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClientCriterion<'_> {
|
impl ClientCriterion<'_> {
|
||||||
|
|
|
||||||
|
|
@ -2107,6 +2107,7 @@ impl ConfigProxyHandler {
|
||||||
}
|
}
|
||||||
ClientCriterionStringField::Comm => mgr.comm(needle),
|
ClientCriterionStringField::Comm => mgr.comm(needle),
|
||||||
ClientCriterionStringField::Exe => mgr.exe(needle),
|
ClientCriterionStringField::Exe => mgr.exe(needle),
|
||||||
|
ClientCriterionStringField::Tag => mgr.tag(needle),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ClientCriterionIpc::Sandboxed => mgr.sandboxed(),
|
ClientCriterionIpc::Sandboxed => mgr.sandboxed(),
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use {
|
||||||
clmm_sandboxed::ClmMatchSandboxed,
|
clmm_sandboxed::ClmMatchSandboxed,
|
||||||
clmm_string::{
|
clmm_string::{
|
||||||
ClmMatchComm, ClmMatchExe, ClmMatchSandboxAppId, ClmMatchSandboxEngine,
|
ClmMatchComm, ClmMatchExe, ClmMatchSandboxAppId, ClmMatchSandboxEngine,
|
||||||
ClmMatchSandboxInstanceId,
|
ClmMatchSandboxInstanceId, ClmMatchTag,
|
||||||
},
|
},
|
||||||
clmm_uid::ClmMatchUid,
|
clmm_uid::ClmMatchUid,
|
||||||
},
|
},
|
||||||
|
|
@ -61,6 +61,7 @@ pub struct RootMatchers {
|
||||||
pid: ClmRootMatcherMap<ClmMatchPid>,
|
pid: ClmRootMatcherMap<ClmMatchPid>,
|
||||||
comm: ClmRootMatcherMap<ClmMatchComm>,
|
comm: ClmRootMatcherMap<ClmMatchComm>,
|
||||||
exe: ClmRootMatcherMap<ClmMatchExe>,
|
exe: ClmRootMatcherMap<ClmMatchExe>,
|
||||||
|
tag: ClmRootMatcherMap<ClmMatchTag>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RootMatchers {
|
impl RootMatchers {
|
||||||
|
|
@ -72,6 +73,7 @@ impl RootMatchers {
|
||||||
self.pid.clear();
|
self.pid.clear();
|
||||||
self.comm.clear();
|
self.comm.clear();
|
||||||
self.exe.clear();
|
self.exe.clear();
|
||||||
|
self.tag.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -181,6 +183,7 @@ impl ClMatcherManager {
|
||||||
unconditional!(pid);
|
unconditional!(pid);
|
||||||
unconditional!(comm);
|
unconditional!(comm);
|
||||||
unconditional!(exe);
|
unconditional!(exe);
|
||||||
|
unconditional!(tag);
|
||||||
fixed!(sandboxed);
|
fixed!(sandboxed);
|
||||||
fixed!(is_xwayland);
|
fixed!(is_xwayland);
|
||||||
self.constant[true].handle(data);
|
self.constant[true].handle(data);
|
||||||
|
|
@ -222,6 +225,10 @@ impl ClMatcherManager {
|
||||||
pub fn exe(&self, string: CritLiteralOrRegex) -> Rc<ClmUpstreamNode> {
|
pub fn exe(&self, string: CritLiteralOrRegex) -> Rc<ClmUpstreamNode> {
|
||||||
self.root(ClmMatchExe::new(string))
|
self.root(ClmMatchExe::new(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn tag(&self, string: CritLiteralOrRegex) -> Rc<ClmUpstreamNode> {
|
||||||
|
self.root(ClmMatchTag::new(string))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CritTarget for Rc<Client> {
|
impl CritTarget for Rc<Client> {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ pub type ClmMatchString<T> = CritMatchString<Rc<Client>, T>;
|
||||||
pub type ClmMatchSandboxEngine = ClmMatchString<AcceptorMetadataAccess<SandboxEngineField>>;
|
pub type ClmMatchSandboxEngine = ClmMatchString<AcceptorMetadataAccess<SandboxEngineField>>;
|
||||||
pub type ClmMatchSandboxAppId = ClmMatchString<AcceptorMetadataAccess<SandboxAppIdField>>;
|
pub type ClmMatchSandboxAppId = ClmMatchString<AcceptorMetadataAccess<SandboxAppIdField>>;
|
||||||
pub type ClmMatchSandboxInstanceId = ClmMatchString<AcceptorMetadataAccess<SandboxInstanceIdField>>;
|
pub type ClmMatchSandboxInstanceId = ClmMatchString<AcceptorMetadataAccess<SandboxInstanceIdField>>;
|
||||||
|
pub type ClmMatchTag = ClmMatchString<AcceptorMetadataAccess<TagField>>;
|
||||||
pub type ClmMatchComm = ClmMatchString<CommAccess>;
|
pub type ClmMatchComm = ClmMatchString<CommAccess>;
|
||||||
pub type ClmMatchExe = ClmMatchString<ExeAccess>;
|
pub type ClmMatchExe = ClmMatchString<ExeAccess>;
|
||||||
|
|
||||||
|
|
@ -22,7 +23,7 @@ pub struct AcceptorMetadataAccess<T>(PhantomData<T>);
|
||||||
pub struct CommAccess;
|
pub struct CommAccess;
|
||||||
pub struct ExeAccess;
|
pub struct ExeAccess;
|
||||||
|
|
||||||
trait SandboxField: Sized + 'static {
|
trait AcceptorMetadataField: Sized + 'static {
|
||||||
fn field(meta: &AcceptorMetadata) -> &Option<String>;
|
fn field(meta: &AcceptorMetadata) -> &Option<String>;
|
||||||
fn nodes(
|
fn nodes(
|
||||||
roots: &RootMatchers,
|
roots: &RootMatchers,
|
||||||
|
|
@ -32,10 +33,11 @@ trait SandboxField: Sized + 'static {
|
||||||
pub struct SandboxEngineField;
|
pub struct SandboxEngineField;
|
||||||
pub struct SandboxAppIdField;
|
pub struct SandboxAppIdField;
|
||||||
pub struct SandboxInstanceIdField;
|
pub struct SandboxInstanceIdField;
|
||||||
|
pub struct TagField;
|
||||||
|
|
||||||
impl<T> StringAccess<Rc<Client>> for AcceptorMetadataAccess<T>
|
impl<T> StringAccess<Rc<Client>> for AcceptorMetadataAccess<T>
|
||||||
where
|
where
|
||||||
T: SandboxField,
|
T: AcceptorMetadataField,
|
||||||
{
|
{
|
||||||
fn with_string(data: &Rc<Client>, f: impl FnOnce(&str) -> bool) -> bool {
|
fn with_string(data: &Rc<Client>, f: impl FnOnce(&str) -> bool) -> bool {
|
||||||
f(T::field(&data.acceptor).as_deref().unwrap_or_default())
|
f(T::field(&data.acceptor).as_deref().unwrap_or_default())
|
||||||
|
|
@ -46,7 +48,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SandboxField for SandboxEngineField {
|
impl AcceptorMetadataField for SandboxEngineField {
|
||||||
fn field(meta: &AcceptorMetadata) -> &Option<String> {
|
fn field(meta: &AcceptorMetadata) -> &Option<String> {
|
||||||
&meta.sandbox_engine
|
&meta.sandbox_engine
|
||||||
}
|
}
|
||||||
|
|
@ -58,7 +60,7 @@ impl SandboxField for SandboxEngineField {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SandboxField for SandboxAppIdField {
|
impl AcceptorMetadataField for SandboxAppIdField {
|
||||||
fn field(meta: &AcceptorMetadata) -> &Option<String> {
|
fn field(meta: &AcceptorMetadata) -> &Option<String> {
|
||||||
&meta.app_id
|
&meta.app_id
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +72,7 @@ impl SandboxField for SandboxAppIdField {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SandboxField for SandboxInstanceIdField {
|
impl AcceptorMetadataField for SandboxInstanceIdField {
|
||||||
fn field(meta: &AcceptorMetadata) -> &Option<String> {
|
fn field(meta: &AcceptorMetadata) -> &Option<String> {
|
||||||
&meta.instance_id
|
&meta.instance_id
|
||||||
}
|
}
|
||||||
|
|
@ -82,6 +84,18 @@ impl SandboxField for SandboxInstanceIdField {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AcceptorMetadataField for TagField {
|
||||||
|
fn field(meta: &AcceptorMetadata) -> &Option<String> {
|
||||||
|
&meta.tag
|
||||||
|
}
|
||||||
|
|
||||||
|
fn nodes(
|
||||||
|
roots: &RootMatchers,
|
||||||
|
) -> &ClmRootMatcherMap<ClmMatchString<AcceptorMetadataAccess<Self>>> {
|
||||||
|
&roots.tag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl StringAccess<Rc<Client>> for CommAccess {
|
impl StringAccess<Rc<Client>> for CommAccess {
|
||||||
fn with_string(data: &Rc<Client>, f: impl FnOnce(&str) -> bool) -> bool {
|
fn with_string(data: &Rc<Client>, f: impl FnOnce(&str) -> bool) -> bool {
|
||||||
f(&data.pid_info.comm)
|
f(&data.pid_info.comm)
|
||||||
|
|
|
||||||
|
|
@ -278,6 +278,8 @@ pub struct ClientMatch {
|
||||||
pub comm_regex: Option<String>,
|
pub comm_regex: Option<String>,
|
||||||
pub exe: Option<String>,
|
pub exe: Option<String>,
|
||||||
pub exe_regex: Option<String>,
|
pub exe_regex: Option<String>,
|
||||||
|
pub tag: Option<String>,
|
||||||
|
pub tag_regex: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
|
||||||
|
|
@ -54,12 +54,14 @@ impl Parser for ClientMatchParser<'_> {
|
||||||
sandbox_instance_id_regex,
|
sandbox_instance_id_regex,
|
||||||
uid,
|
uid,
|
||||||
pid,
|
pid,
|
||||||
is_xwayland,
|
|
||||||
comm,
|
comm,
|
||||||
comm_regex,
|
comm_regex,
|
||||||
exe,
|
exe,
|
||||||
exe_regex,
|
exe_regex,
|
||||||
|
tag,
|
||||||
|
tag_regex,
|
||||||
),
|
),
|
||||||
|
(is_xwayland,),
|
||||||
) = ext.extract((
|
) = ext.extract((
|
||||||
(
|
(
|
||||||
opt(str("name")),
|
opt(str("name")),
|
||||||
|
|
@ -78,12 +80,14 @@ impl Parser for ClientMatchParser<'_> {
|
||||||
opt(str("sandbox-instance-id-regex")),
|
opt(str("sandbox-instance-id-regex")),
|
||||||
opt(s32("uid")),
|
opt(s32("uid")),
|
||||||
opt(s32("pid")),
|
opt(s32("pid")),
|
||||||
opt(bol("is-xwayland")),
|
|
||||||
opt(str("comm")),
|
opt(str("comm")),
|
||||||
opt(str("comm-regex")),
|
opt(str("comm-regex")),
|
||||||
opt(str("exe")),
|
opt(str("exe")),
|
||||||
opt(str("exe-regex")),
|
opt(str("exe-regex")),
|
||||||
|
opt(str("tag")),
|
||||||
|
opt(str("tag-regex")),
|
||||||
),
|
),
|
||||||
|
(opt(bol("is-xwayland")),),
|
||||||
))?;
|
))?;
|
||||||
let mut not = None;
|
let mut not = None;
|
||||||
if let Some(value) = not_val {
|
if let Some(value) = not_val {
|
||||||
|
|
@ -130,6 +134,8 @@ impl Parser for ClientMatchParser<'_> {
|
||||||
comm_regex: comm_regex.despan_into(),
|
comm_regex: comm_regex.despan_into(),
|
||||||
exe: exe.despan_into(),
|
exe: exe.despan_into(),
|
||||||
exe_regex: exe_regex.despan_into(),
|
exe_regex: exe_regex.despan_into(),
|
||||||
|
tag: tag.despan_into(),
|
||||||
|
tag_regex: tag_regex.despan_into(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,8 @@ impl Rule for ClientRule {
|
||||||
value_ref!(CommRegex, comm_regex);
|
value_ref!(CommRegex, comm_regex);
|
||||||
value_ref!(Exe, exe);
|
value_ref!(Exe, exe);
|
||||||
value_ref!(ExeRegex, exe_regex);
|
value_ref!(ExeRegex, exe_regex);
|
||||||
|
value_ref!(Tag, tag);
|
||||||
|
value_ref!(TagRegex, tag_regex);
|
||||||
value!(Uid, uid);
|
value!(Uid, uid);
|
||||||
value!(Pid, pid);
|
value!(Pid, pid);
|
||||||
bool!(Sandboxed, sandboxed);
|
bool!(Sandboxed, sandboxed);
|
||||||
|
|
|
||||||
|
|
@ -742,6 +742,14 @@
|
||||||
"exe-regex": {
|
"exe-regex": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Matches the `/proc/pid/exe` of the client with a regular expression."
|
"description": "Matches the `/proc/pid/exe` of the client with a regular expression."
|
||||||
|
},
|
||||||
|
"tag": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Matches the tag of the client verbatim."
|
||||||
|
},
|
||||||
|
"tag-regex": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Matches the tag of the client with a regular expression."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": []
|
"required": []
|
||||||
|
|
|
||||||
|
|
@ -1242,6 +1242,18 @@ The table has the following fields:
|
||||||
|
|
||||||
The value of this field should be a string.
|
The value of this field should be a string.
|
||||||
|
|
||||||
|
- `tag` (optional):
|
||||||
|
|
||||||
|
Matches the tag of the client verbatim.
|
||||||
|
|
||||||
|
The value of this field should be a string.
|
||||||
|
|
||||||
|
- `tag-regex` (optional):
|
||||||
|
|
||||||
|
Matches the tag of the client with a regular expression.
|
||||||
|
|
||||||
|
The value of this field should be a string.
|
||||||
|
|
||||||
|
|
||||||
<a name="types-ClientMatchExactly"></a>
|
<a name="types-ClientMatchExactly"></a>
|
||||||
### `ClientMatchExactly`
|
### `ClientMatchExactly`
|
||||||
|
|
|
||||||
|
|
@ -3823,6 +3823,14 @@ ClientMatch:
|
||||||
kind: string
|
kind: string
|
||||||
required: false
|
required: false
|
||||||
description: Matches the `/proc/pid/exe` of the client with a regular expression.
|
description: Matches the `/proc/pid/exe` of the client with a regular expression.
|
||||||
|
tag:
|
||||||
|
kind: string
|
||||||
|
required: false
|
||||||
|
description: Matches the tag of the client verbatim.
|
||||||
|
tag-regex:
|
||||||
|
kind: string
|
||||||
|
required: false
|
||||||
|
description: Matches the tag of the client with a regular expression.
|
||||||
|
|
||||||
|
|
||||||
ClientMatchExactly:
|
ClientMatchExactly:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue