// SPDX-FileCopyrightText: 2022 Matteo Settenvini <matteo.settenvini@montecristosoftware.eu> // SPDX-License-Identifier: GPL-3.0-or-later use { nix::unistd::Uid, serde::{Deserialize, Serialize}, std::net::IpAddr, zbus::{dbus_proxy, Result}, }; #[dbus_proxy( default_service = "com.endlessm.ParentalControls", interface = "com.endlessm.ParentalControls.Dns", default_path = "/com/endlessm/ParentalControls/Dns", gen_blocking = false )] trait MalcontentDns { fn get_restrictions(&self, uid: u32) -> Result<Restrictions>; } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, zvariant::Type)] pub struct Restriction { pub ip: IpAddr, pub hostname: String, } pub type Restrictions = Vec<Restriction>; pub async fn restrictions_for(user: Uid) -> anyhow::Result<Vec<Restriction>, anyhow::Error> { #[cfg(not(feature = "integration_test"))] let proxy = { // This is the normal behavior let connection = zbus::Connection::system().await?; MalcontentDnsProxy::new(&connection).await? }; #[cfg(feature = "integration_test")] let proxy = { use tokio::net::UnixStream; // During integration testing, we want to connect to a private // bus name to avoid clashes with existing system services. let socket_path = std::env::var("TEST_DBUS_SOCKET") .expect("The test has not set the TEST_DBUS_SOCKET environment variable to the unix socket to connect to"); let socket = loop { match UnixStream::connect(&socket_path).await { Ok(stream) => break stream, Err(e) if e.kind() == std::io::ErrorKind::ConnectionRefused => { tokio::task::yield_now().await; continue; } Err(e) => anyhow::bail!(e), } }; let connection = zbus::ConnectionBuilder::unix_stream(socket) .p2p() .build() .await?; MalcontentDnsProxy::builder(&connection) .build() .await .expect("Unable to build DBus proxy object") }; let restrictions = proxy.get_restrictions(user.as_raw()).await; log::trace!( "malcontent-nss: user {} restrictions are {:?}", user, &restrictions ); Ok(restrictions?) }