Skip to content

Commit

Permalink
chore(xml): extract Policy... and Rule... out into separate module
Browse files Browse the repository at this point in the history
  • Loading branch information
jokeyrhyme committed Oct 7, 2024
1 parent f88031f commit 7ec0995
Show file tree
Hide file tree
Showing 3 changed files with 279 additions and 267 deletions.
272 changes: 7 additions & 265 deletions src/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
use std::{path::PathBuf, str::FromStr};

use raw::{RawConfiguration, RawPolicy, RawPolicyContext, RawRule, RawRuleAttributes};
use serde::Deserialize;

mod policy;
mod raw;

use crate::configuration::{policy::Policy, raw::RawConfiguration};

#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum ApparmorMode {
Expand Down Expand Up @@ -114,12 +116,6 @@ impl TryFrom<RawConfiguration> for Configuration {
}
}

#[derive(Clone, Debug, Default, PartialEq)]
pub struct ConnectRule {
group: Option<RuleMatch>,
user: Option<RuleMatch>,
}

#[derive(Clone, Debug)]
pub enum Error {
DeserializeXml(quick_xml::DeError),
Expand Down Expand Up @@ -174,271 +170,13 @@ pub enum LimitName {
ReplyTimeout,
}

#[derive(Clone, Debug, Default, PartialEq)]
pub struct OwnRule {
own: Option<RuleMatch>,
own_prefix: Option<String>,
}

#[derive(Clone, Debug, PartialEq)]
pub enum Policy {
Console { rules: Vec<Rule> },
DefaultContext { rules: Vec<Rule> },
Group { group: Principal, rules: Vec<Rule> },
MandatoryContext { rules: Vec<Rule> },
NoConsole { rules: Vec<Rule> },
User { user: Principal, rules: Vec<Rule> },
}
impl TryFrom<RawPolicy> for Policy {
type Error = Error;
fn try_from(value: RawPolicy) -> Result<Self, Self::Error> {
let mut rules: Vec<Rule> = Vec::with_capacity(value.rules.len());
for rule in value.rules {
match Rule::try_from(rule) {
Ok(ok) => rules.push(ok),
Err(err) => return Err(err),
}
}

match value {
RawPolicy {
at_console: Some(b),
context: None,
group: None,
user: None,
..
} => Ok(match b {
true => Self::Console { rules },
false => Self::NoConsole { rules },
}),
RawPolicy {
at_console: None,
context: Some(pc),
group: None,
user: None,
..
} => Ok(match pc {
RawPolicyContext::Default => Self::DefaultContext { rules },
RawPolicyContext::Mandatory => Self::MandatoryContext { rules },
}),
RawPolicy {
at_console: None,
context: None,
group: Some(p),
user: None,
..
} => Ok(Self::Group { group: p, rules }),
RawPolicy {
at_console: None,
context: None,
group: None,
user: Some(p),
..
} => Ok(Self::User { user: p, rules }),
_ => Err(Error::PolicyHasMultipleAttributes),
}
}
}
// TODO: impl PartialOrd/Ord for Policy, for order in which policies are applied to a connection

#[derive(Clone, Debug, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase", untagged)]
pub enum Principal {
Id(u32),
Name(String),
}

#[derive(Clone, Debug, Default, PartialEq)]
pub struct ReceiveRule {
eavesdrop: Option<bool>,
receive_error: Option<RuleMatch>,
receive_interface: Option<RuleMatch>,
receive_member: Option<RuleMatch>,
receive_path: Option<RuleMatch>,
receive_requested_reply: Option<bool>,
receive_sender: Option<RuleMatch>,
receive_type: Option<RuleMatchType>,
}

pub type Rule = (RuleEffect, RulePhase);
impl TryFrom<RawRule> for Rule {
type Error = Error;

fn try_from(value: RawRule) -> Result<Self, Self::Error> {
let (effect, attributes) = match value {
RawRule::Allow(attributes) => (RuleEffect::Allow, attributes),
RawRule::Deny(attributes) => (RuleEffect::Deny, attributes),
};
match attributes {
RawRuleAttributes {
eavesdrop,
group: None,
own: None,
own_prefix: None,
receive_error,
receive_interface,
receive_member,
receive_path,
receive_requested_reply,
receive_sender,
receive_type,
send_broadcast: None,
send_destination: None,
send_destination_prefix: None,
send_error: None,
send_interface: None,
send_member: None,
send_path: None,
send_requested_reply: None,
send_type: None,
user: None,
} => Ok((
effect,
RulePhase::Receive(ReceiveRule {
eavesdrop,
receive_error,
receive_interface,
receive_member,
receive_path,
receive_requested_reply,
receive_sender,
receive_type,
}),
)),
RawRuleAttributes {
eavesdrop,
group: None,
own: None,
own_prefix: None,
receive_error: None,
receive_interface: None,
receive_member: None,
receive_path: None,
receive_requested_reply: None,
receive_sender: None,
receive_type: None,
send_broadcast,
send_destination,
send_destination_prefix,
send_error,
send_interface,
send_member,
send_path,
send_requested_reply,
send_type,
user: None,
} => Ok((
effect,
RulePhase::Send(SendRule {
eavesdrop,
send_broadcast,
send_destination,
send_destination_prefix,
send_error,
send_interface,
send_member,
send_path,
send_requested_reply,
send_type,
}),
)),
RawRuleAttributes {
eavesdrop: None,
group: None,
own,
own_prefix,
receive_error: None,
receive_interface: None,
receive_member: None,
receive_path: None,
receive_requested_reply: None,
receive_sender: None,
receive_type: None,
send_broadcast: None,
send_destination: None,
send_destination_prefix: None,
send_error: None,
send_interface: None,
send_member: None,
send_path: None,
send_requested_reply: None,
send_type: None,
user: None,
} => Ok((effect, RulePhase::Own(OwnRule { own, own_prefix }))),
RawRuleAttributes {
eavesdrop: None,
group,
own: None,
own_prefix: None,
receive_error: None,
receive_interface: None,
receive_member: None,
receive_path: None,
receive_requested_reply: None,
receive_sender: None,
receive_type: None,
send_broadcast: None,
send_destination: None,
send_destination_prefix: None,
send_error: None,
send_interface: None,
send_member: None,
send_path: None,
send_requested_reply: None,
send_type: None,
user,
} => Ok((effect, RulePhase::Connect(ConnectRule { group, user }))),
_ => Err(Error::RuleHasInvalidCombinationOfAttributes),
}
}
}

#[derive(Clone, Debug, PartialEq)]
pub enum RuleEffect {
Allow,
Deny,
}

#[derive(Clone, Debug, PartialEq)]
pub enum RulePhase {
Connect(ConnectRule),
Own(OwnRule),
Receive(ReceiveRule),
Send(SendRule),
}

#[derive(Clone, Debug, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case", untagged)]
pub enum RuleMatch {
#[serde(rename = "*")]
Any,
One(String),
}
#[derive(Clone, Debug, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum RuleMatchType {
#[serde(rename = "*")]
Any,
Error,
MethodCall,
MethodReturn,
Signal,
}

#[derive(Clone, Debug, Default, PartialEq)]
pub struct SendRule {
eavesdrop: Option<bool>,
send_broadcast: Option<bool>,
send_destination: Option<RuleMatch>,
send_destination_prefix: Option<String>,
send_error: Option<RuleMatch>,
send_interface: Option<RuleMatch>,
send_member: Option<RuleMatch>,
send_path: Option<RuleMatch>,
send_requested_reply: Option<bool>,
send_type: Option<RuleMatchType>,
}

#[derive(Clone, Debug, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum Type {
Expand All @@ -448,6 +186,10 @@ pub enum Type {

#[cfg(test)]
mod tests {
use crate::configuration::policy::{
OwnRule, ReceiveRule, RuleEffect, RuleMatch, RulePhase, SendRule,
};

use super::*;

#[test]
Expand Down
Loading

0 comments on commit 7ec0995

Please sign in to comment.