diff --git a/Cargo.lock b/Cargo.lock index 2fc2db0..3a464a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,6 +79,15 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "bumpalo" version = "3.11.1" @@ -263,6 +272,15 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +[[package]] +name = "cpufeatures" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" +dependencies = [ + "libc", +] + [[package]] name = "crossbeam-channel" version = "0.5.8" @@ -352,6 +370,7 @@ dependencies = [ "crypto-auditing", "futures", "inotify", + "libsystemd", "serde_cbor 0.10.2", "tarpc", "tokio", @@ -376,6 +395,16 @@ dependencies = [ "serde_with", ] +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "cxx" version = "1.0.82" @@ -455,6 +484,17 @@ dependencies = [ "syn", ] +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + [[package]] name = "educe" version = "0.4.22" @@ -606,6 +646,16 @@ dependencies = [ "slab", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.2.8" @@ -665,6 +715,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + [[package]] name = "humantime" version = "2.1.0" @@ -845,6 +904,24 @@ dependencies = [ "winapi", ] +[[package]] +name = "libsystemd" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b9597a67aa1c81a6624603e6bd0bcefb9e0f94c9c54970ec53771082104b4e" +dependencies = [ + "hmac", + "libc", + "log", + "nix", + "nom", + "once_cell", + "serde", + "sha2", + "thiserror", + "uuid", +] + [[package]] name = "link-cplusplus" version = "1.0.7" @@ -1511,6 +1588,17 @@ dependencies = [ "syn", ] +[[package]] +name = "sha2" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sharded-slab" version = "0.1.4" @@ -1585,6 +1673,12 @@ dependencies = [ "syn", ] +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + [[package]] name = "syn" version = "1.0.103" @@ -1924,6 +2018,12 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + [[package]] name = "unicode-ident" version = "1.0.5" @@ -1936,6 +2036,15 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +[[package]] +name = "uuid" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa2982af2eec27de306107c027578ff7f423d65f7250e40ce0fea8f45248b81" +dependencies = [ + "serde", +] + [[package]] name = "valuable" version = "0.1.0" diff --git a/dist/systemd/system/crypto-auditing-event-broker.service b/dist/systemd/system/crypto-auditing-event-broker.service index a11a6b2..8587d0b 100644 --- a/dist/systemd/system/crypto-auditing-event-broker.service +++ b/dist/systemd/system/crypto-auditing-event-broker.service @@ -6,7 +6,6 @@ After=crypto-auditing-agent.service [Service] ExecStart=/usr/bin/crypto-auditing-event-broker -ExecStopPost=rm -f /var/lib/crypto-auditing/audit.sock KillSignal=SIGINT TimeoutSec=60s Restart=on-failure @@ -15,4 +14,4 @@ RestartSec=120s # Group=crypto-auditing [Install] -WantedBy=default.target +Also=crypto-auditing-event-broker.socket diff --git a/dist/systemd/system/crypto-auditing-event-broker.socket b/dist/systemd/system/crypto-auditing-event-broker.socket new file mode 100644 index 0000000..0509da6 --- /dev/null +++ b/dist/systemd/system/crypto-auditing-event-broker.socket @@ -0,0 +1,11 @@ +[Unit] +Description=Event broker socket for crypto-auditing project + +[Socket] +ListenStream=/var/lib/crypto-auditing/audit.sock +# SocketUser=crypto-auditing +# SocketGroup=crypto-auditing +# SocketMode=0660 + +[Install] +WantedBy=sockets.target diff --git a/event-broker/Cargo.toml b/event-broker/Cargo.toml index 56bbe7e..70e8de2 100644 --- a/event-broker/Cargo.toml +++ b/event-broker/Cargo.toml @@ -8,12 +8,16 @@ authors = ["The crypto-auditing developers"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[features] +default = ["libsystemd"] + [dependencies] anyhow = "1.0" clap = { version = "4", features = ["derive"] } crypto-auditing = { path = "../crypto-auditing" } futures = "0.3" inotify = "0.10" +libsystemd = { version = "0.6", optional = true } serde_cbor = "0.10" tarpc = { version = "0.33", features = ["serde-transport", "unix"] } tokio = "1.23" diff --git a/event-broker/src/main.rs b/event-broker/src/main.rs index e12bcfa..50c5083 100644 --- a/event-broker/src/main.rs +++ b/event-broker/src/main.rs @@ -1,16 +1,24 @@ // SPDX-License-Identifier: GPL-3.0-or-later // Copyright (C) 2022-2023 The crypto-auditing developers. +#[cfg(feature = "libsystemd")] +use anyhow::bail; use anyhow::{Context as _, Result}; use crypto_auditing::types::EventGroup; use futures::{future, stream::StreamExt, try_join}; use inotify::{EventMask, Inotify, WatchMask}; +#[cfg(feature = "libsystemd")] +use libsystemd::activation::receive_descriptors; use serde_cbor::de::Deserializer; use std::collections::HashMap; use std::os::fd::{AsRawFd, RawFd}; +#[cfg(feature = "libsystemd")] +use std::os::fd::{FromRawFd, IntoRawFd}; +use std::os::unix::net::UnixListener as StdUnixListener; use std::path::{Path, PathBuf}; use std::sync::{Arc, RwLock}; use tarpc::{client, context, tokio_serde::formats::Cbor}; +use tokio::net::UnixListener; use tokio::sync::mpsc::{self, Receiver, Sender}; use tokio_stream::wrappers::ReceiverStream; use tracing::{debug, info}; @@ -82,16 +90,35 @@ impl Publisher { } } - async fn publish(&self, receiver: Receiver) -> Result<()> { - let mut connecting_subscribers = - tarpc::serde_transport::unix::listen(&self.socket_path, Cbor::default) - .await? - .filter_map(|r| future::ready(r.ok())); + #[cfg(feature = "libsystemd")] + fn get_std_listener(&self) -> Result { + if let Ok(mut descriptors) = receive_descriptors(false) { + if descriptors.len() > 1 { + bail!("too many file descriptors"); + } else if descriptors.len() == 0 { + bail!("no file descriptors received"); + } + let fd = descriptors.pop().unwrap().into_raw_fd(); + Ok(unsafe { StdUnixListener::from_raw_fd(fd) }) + } else { + Ok(StdUnixListener::bind(&self.socket_path)?) + } + } + #[cfg(not(feature = "libsystemd"))] + fn get_std_listener(&self) -> Result { + Ok(StdUnixListener::bind(&self.socket_path)?) + } + + async fn publish(&self, receiver: Receiver) -> Result<()> { + let std_listener = self.get_std_listener()?; + std_listener.set_nonblocking(true)?; + let listener = UnixListener::from_std(std_listener)?; let subscriptions = self.subscriptions.clone(); tokio::spawn(async move { - while let Some(conn) = connecting_subscribers.next().await { + while let Ok((stream, _sock_addr)) = listener.accept().await { + let conn = tarpc::serde_transport::Transport::from((stream, Cbor::default())); let subscriber_fd = conn.get_ref().as_raw_fd(); let tarpc::client::NewClient {