diff --git a/src/config.rs b/src/config.rs index 2293fbf..701938b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -365,7 +365,13 @@ impl TryFrom for OptionalOperation { || value.send_path.is_some() || value.send_requested_reply.is_some() || value.send_type.is_some(); - let has_receive = value.receive_sender.is_some(); + let has_receive = value.receive_error.is_some() + || value.receive_interface.is_some() + || value.receive_member.is_some() + || value.receive_path.is_some() + || value.receive_sender.is_some() + || value.receive_requested_reply.is_some() + || value.receive_type.is_some(); let operations_count: i8 = vec![has_connect, has_own, has_receive, has_send] .into_iter() @@ -376,6 +382,12 @@ impl TryFrom for OptionalOperation { return Err(Error::msg(format!("do not mix rule attributes for connect, own, receive, and/or send operations in the same rule: {value:?}"))); } + // https://github.com/dbus2/busd/issues/79 + if value.receive_member.is_some() { + eprintln!( + "warning: busd does not implement `<(allow|deny) receive_member=...`: {value:?}" + ); + } if value.send_member.is_some() { eprintln!( "warning: busd does not implement `<(allow|deny) send_member=...`: {value:?}" @@ -387,10 +399,7 @@ impl TryFrom for OptionalOperation { } else if has_own { Ok(Some(Operation::Own)) } else if has_receive { - Ok(Some(Operation::Receive(ReceiveOperation { - sender: value.receive_sender.unwrap_or(String::from("*")), - ..Default::default() - }))) + Ok(Some(Operation::Receive(ReceiveOperation::from(value)))) } else if has_send { Ok(Some(Operation::Send(SendOperation::from(value)))) } else { @@ -488,16 +497,37 @@ struct PolicyElement { #[derive(Clone, Debug, PartialEq)] pub struct ReceiveOperation { - pub sender: String, + pub error: String, + pub interface: String, pub max_fds: u32, pub min_fds: u32, + pub path: String, + pub sender: String, + pub r#type: MessageType, } impl Default for ReceiveOperation { fn default() -> Self { Self { - sender: String::default(), + error: String::from("*"), + interface: String::from("*"), max_fds: u32::MAX, min_fds: 0, + path: String::from("*"), + r#type: MessageType::Any, + sender: String::default(), + } + } +} +impl From for ReceiveOperation { + fn from(value: RuleAttributes) -> Self { + Self { + error: value.receive_error.unwrap_or(String::from("*")), + interface: value.receive_interface.unwrap_or(String::from("*")), + max_fds: value.max_fds.unwrap_or(u32::MAX), + min_fds: value.min_fds.unwrap_or(0), + path: value.receive_path.unwrap_or(String::from("*")), + sender: value.receive_sender.unwrap_or(String::from("*")), + r#type: value.receive_type.unwrap_or_default(), } } } @@ -609,22 +639,25 @@ pub type Rule = (Access, Operation); #[derive(Clone, Debug, Default, Deserialize, PartialEq)] struct RuleAttributes { - /// deprecated and ignored - #[serde(rename = "@eavesdrop")] - eavesdrop: Option, - #[serde(rename = "@group")] - group: Option, #[serde(rename = "@max_fds")] max_fds: Option, #[serde(rename = "@min_fds")] min_fds: Option, - #[serde(rename = "@own")] - own: Option, + + #[serde(rename = "@receive_error")] + receive_error: Option, + #[serde(rename = "@receive_interface")] + receive_interface: Option, + /// deprecated and ignored + #[serde(rename = "@receive_member")] + receive_member: Option, + #[serde(rename = "@receive_path")] + receive_path: Option, #[serde(rename = "@receive_sender")] receive_sender: Option, - /// deprecated and ignored - #[serde(rename = "@receive_requested_reply")] - receive_requested_reply: Option, + #[serde(rename = "@receive_type")] + receive_type: Option, + #[serde(rename = "@send_broadcast")] send_broadcast: Option, #[serde(rename = "@send_destination")] @@ -640,11 +673,27 @@ struct RuleAttributes { send_member: Option, #[serde(rename = "@send_path")] send_path: Option, + #[serde(rename = "@send_type")] + send_type: Option, + + /// deprecated and ignored + #[serde(rename = "@receive_requested_reply")] + receive_requested_reply: Option, /// deprecated and ignored #[serde(rename = "@send_requested_reply")] send_requested_reply: Option, - #[serde(rename = "@send_type")] - send_type: Option, + + /// deprecated and ignored + #[serde(rename = "@eavesdrop")] + eavesdrop: Option, + + #[serde(rename = "@own")] + own: Option, + #[serde(rename = "@own_prefix")] + own_prefix: Option, + + #[serde(rename = "@group")] + group: Option, #[serde(rename = "@user")] user: Option, } @@ -879,10 +928,19 @@ mod tests { max_fds="128" min_fds="12" /> + - + @@ -898,20 +956,34 @@ mod tests { policies: vec![ Policy::DefaultContext(vec![(Access::Allow, Operation::Own),]), Policy::User( - vec![( - Access::Allow, - Operation::Send(SendOperation { - broadcast: Some(true), - destination: String::from("org.freedesktop.DBus"), - destination_prefix: String::from("org.freedesktop"), - error: String::from("something bad"), - interface: String::from("org.freedesktop.systemd1.Activator"), - max_fds: 128, - min_fds: 12, - path: String::from("/org/freedesktop"), - r#type: MessageType::Signal - }) - ),], + vec![ + ( + Access::Allow, + Operation::Send(SendOperation { + broadcast: Some(true), + destination: String::from("org.freedesktop.DBus"), + destination_prefix: String::from("org.freedesktop"), + error: String::from("something bad"), + interface: String::from("org.freedesktop.systemd1.Activator"), + max_fds: 128, + min_fds: 12, + path: String::from("/org/freedesktop"), + r#type: MessageType::Signal + }) + ), + ( + Access::Allow, + Operation::Receive(ReceiveOperation { + error: String::from("something bad"), + interface: String::from("org.freedesktop.systemd1.Activator"), + max_fds: 128, + min_fds: 12, + path: String::from("/org/freedesktop"), + sender: String::from("org.freedesktop.DBus"), + r#type: MessageType::Signal + }) + ) + ], String::from("root") ), Policy::Group(