Skip to content

Commit

Permalink
♻️ Extract XML-specific data structures
Browse files Browse the repository at this point in the history
  • Loading branch information
jokeyrhyme committed Nov 15, 2024
1 parent 01a703d commit 7bb570e
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 129 deletions.
141 changes: 12 additions & 129 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ use anyhow::{Error, Result};
use quick_xml::{events::Event, Reader};
use serde::Deserialize;

mod xml;

use xml::{
Document, Element, PolicyContext, PolicyElement, RuleAttributes, RuleElement, TypeElement,
};

const EXPECTED_DOCTYPE_PARTS: &[&str] = &[
"busconfig",
"PUBLIC",
Expand All @@ -27,7 +33,12 @@ pub enum Access {
Deny,
}

/// implements [`dbus-daemon`'s Configuration File](https://dbus.freedesktop.org/doc/dbus-daemon.1.html#configuration_file)
/// The bus configuration.
///
/// This is currently only loaded from the [XML configuration files] defined by the specification.
/// We plan to add support for other formats (e.g JSON) in the future.
///
/// [XML configuration files]: https://dbus.freedesktop.org/doc/dbus-daemon.1.html#configuration_file
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
#[serde(try_from = "Document")]
pub struct BusConfig {
Expand Down Expand Up @@ -255,39 +266,6 @@ pub enum BusType {
System,
}

#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
struct Document {
#[serde(rename = "$value", default)]
busconfig: Vec<Element>,
}

#[derive(Clone, Debug, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
enum Element {
AllowAnonymous,
Auth(String),
Fork,
KeepUmask,
// TODO: support `<include ignore_missing=(yes|no) if_selinux_enabled=(yes|no)
// selinux_root_relative=(yes|no)>` TODO: support `<includedir>`
Listen(String),
Limit,
Pidfile(PathBuf),
Policy(PolicyElement),
Servicedir(PathBuf),
Servicehelper(PathBuf),
/// Requests a standard set of session service directories.
/// Its effect is similar to specifying a series of <servicedir/> elements for each of the data
/// directories, in the order given here.
StandardSessionServicedirs,
/// Specifies the standard system-wide activation directories that should be searched for
/// service files.
StandardSystemServicedirs,
Syslog,
Type(TypeElement),
User(String),
}

#[derive(Clone, Debug, Default, PartialEq)]
pub struct Limits {
/// total size in bytes of messages incoming from a single connection
Expand Down Expand Up @@ -474,27 +452,6 @@ impl TryFrom<PolicyElement> for OptionalPolicy {
}
}

#[derive(Clone, Debug, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
enum PolicyContext {
Default,
Mandatory,
}

#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
struct PolicyElement {
#[serde(rename = "@at_console")]
at_console: Option<String>,
#[serde(rename = "@context")]
context: Option<PolicyContext>,
#[serde(rename = "@group")]
group: Option<String>,
#[serde(rename = "$value", default)]
rules: Vec<RuleElement>,
#[serde(rename = "@user")]
user: Option<String>,
}

#[derive(Clone, Debug, PartialEq)]
pub struct ReceiveOperation {
pub error: String,
Expand Down Expand Up @@ -637,74 +594,6 @@ fn rules_try_from_rule_elements(value: Vec<RuleElement>) -> Result<Vec<Rule>> {

pub type Rule = (Access, Operation);

#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
struct RuleAttributes {
#[serde(rename = "@max_fds")]
max_fds: Option<u32>,
#[serde(rename = "@min_fds")]
min_fds: Option<u32>,

#[serde(rename = "@receive_error")]
receive_error: Option<String>,
#[serde(rename = "@receive_interface")]
receive_interface: Option<String>,
/// deprecated and ignored
#[serde(rename = "@receive_member")]
receive_member: Option<String>,
#[serde(rename = "@receive_path")]
receive_path: Option<String>,
#[serde(rename = "@receive_sender")]
receive_sender: Option<String>,
#[serde(rename = "@receive_type")]
receive_type: Option<MessageType>,

#[serde(rename = "@send_broadcast")]
send_broadcast: Option<bool>,
#[serde(rename = "@send_destination")]
send_destination: Option<String>,
#[serde(rename = "@send_destination_prefix")]
send_destination_prefix: Option<String>,
#[serde(rename = "@send_error")]
send_error: Option<String>,
#[serde(rename = "@send_interface")]
send_interface: Option<String>,
/// deprecated and ignored: https://github.com/dbus2/busd/issues/79
#[serde(rename = "@send_member")]
send_member: Option<String>,
#[serde(rename = "@send_path")]
send_path: Option<String>,
#[serde(rename = "@send_type")]
send_type: Option<MessageType>,

/// deprecated and ignored
#[serde(rename = "@receive_requested_reply")]
receive_requested_reply: Option<bool>,
/// deprecated and ignored
#[serde(rename = "@send_requested_reply")]
send_requested_reply: Option<bool>,

/// deprecated and ignored
#[serde(rename = "@eavesdrop")]
eavesdrop: Option<bool>,

#[serde(rename = "@own")]
own: Option<String>,
#[serde(rename = "@own_prefix")]
own_prefix: Option<String>,

#[serde(rename = "@group")]
group: Option<String>,
#[serde(rename = "@user")]
user: Option<String>,
}

#[derive(Clone, Debug, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
enum RuleElement {
Allow(RuleAttributes),
Deny(RuleAttributes),
}

#[derive(Clone, Debug, PartialEq)]
pub struct SendOperation {
pub broadcast: Option<bool>,
Expand Down Expand Up @@ -748,12 +637,6 @@ impl From<RuleAttributes> for SendOperation {
}
}

#[derive(Clone, Debug, Deserialize, PartialEq)]
struct TypeElement {
#[serde(rename = "$text")]
r#type: BusType,
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
139 changes: 139 additions & 0 deletions src/config/xml.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
use std::path::PathBuf;

use serde::Deserialize;

use super::{BusType, MessageType};

/// The bus configuration.
///
/// This is currently only loaded from the [XML configuration files] defined by the specification.
/// We plan to add support for other formats (e.g JSON) in the future.
///
/// [XML configuration files]: https://dbus.freedesktop.org/doc/dbus-daemon.1.html#configuration_file
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
pub struct Document {
#[serde(rename = "$value", default)]
pub busconfig: Vec<Element>,
}

#[derive(Clone, Debug, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum Element {
AllowAnonymous,
Auth(String),
Fork,
KeepUmask,
// TODO: support `<include ignore_missing=(yes|no) if_selinux_enabled=(yes|no)
// selinux_root_relative=(yes|no)>` TODO: support `<includedir>`
Listen(String),
Limit,
Pidfile(PathBuf),
Policy(PolicyElement),
Servicedir(PathBuf),
Servicehelper(PathBuf),
/// Requests a standard set of session service directories.
/// Its effect is similar to specifying a series of <servicedir/> elements for each of the data
/// directories, in the order given here.
StandardSessionServicedirs,
/// Specifies the standard system-wide activation directories that should be searched for
/// service files.
StandardSystemServicedirs,
Syslog,
Type(TypeElement),
User(String),
}

#[derive(Clone, Debug, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum PolicyContext {
Default,
Mandatory,
}

#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
pub struct PolicyElement {
#[serde(rename = "@at_console")]
pub at_console: Option<String>,
#[serde(rename = "@context")]
pub context: Option<PolicyContext>,
#[serde(rename = "@group")]
pub group: Option<String>,
#[serde(rename = "$value", default)]
pub rules: Vec<RuleElement>,
#[serde(rename = "@user")]
pub user: Option<String>,
}

#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
pub struct RuleAttributes {
#[serde(rename = "@max_fds")]
pub max_fds: Option<u32>,
#[serde(rename = "@min_fds")]
pub min_fds: Option<u32>,

#[serde(rename = "@receive_error")]
pub receive_error: Option<String>,
#[serde(rename = "@receive_interface")]
pub receive_interface: Option<String>,
/// deprecated and ignored
#[serde(rename = "@receive_member")]
pub receive_member: Option<String>,
#[serde(rename = "@receive_path")]
pub receive_path: Option<String>,
#[serde(rename = "@receive_sender")]
pub receive_sender: Option<String>,
#[serde(rename = "@receive_type")]
pub receive_type: Option<MessageType>,

#[serde(rename = "@send_broadcast")]
pub send_broadcast: Option<bool>,
#[serde(rename = "@send_destination")]
pub send_destination: Option<String>,
#[serde(rename = "@send_destination_prefix")]
pub send_destination_prefix: Option<String>,
#[serde(rename = "@send_error")]
pub send_error: Option<String>,
#[serde(rename = "@send_interface")]
pub send_interface: Option<String>,
/// deprecated and ignored: https://github.com/dbus2/busd/issues/79
#[serde(rename = "@send_member")]
pub send_member: Option<String>,
#[serde(rename = "@send_path")]
pub send_path: Option<String>,
#[serde(rename = "@send_type")]
pub send_type: Option<MessageType>,

/// deprecated and ignored
#[serde(rename = "@receive_requested_reply")]
pub receive_requested_reply: Option<bool>,
/// deprecated and ignored
#[serde(rename = "@send_requested_reply")]
pub send_requested_reply: Option<bool>,

/// deprecated and ignored
#[serde(rename = "@eavesdrop")]
pub eavesdrop: Option<bool>,

#[serde(rename = "@own")]
pub own: Option<String>,
#[serde(rename = "@own_prefix")]
pub own_prefix: Option<String>,

#[serde(rename = "@group")]
pub group: Option<String>,
#[serde(rename = "@user")]
pub user: Option<String>,
}

#[derive(Clone, Debug, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum RuleElement {
Allow(RuleAttributes),
Deny(RuleAttributes),
}

#[derive(Clone, Debug, Deserialize, PartialEq)]
pub struct TypeElement {
#[serde(rename = "$text")]
pub r#type: BusType,
}

0 comments on commit 7bb570e

Please sign in to comment.