https://gitlab.freedesktop.org/dbus/zbus/-/commit/807909a6c7bf https://gitlab.freedesktop.org/dbus/zbus/-/commit/e3e2f7ddfd6e https://gitlab.freedesktop.org/dbus/zbus/-/commit/35d1b8778754 --- cargo-crates/zbus-1.9.3/src/address.rs.orig 1970-01-01 00:00:00 UTC +++ cargo-crates/zbus-1.9.3/src/address.rs @@ -57,8 +57,9 @@ impl Address { match env::var("DBUS_SESSION_BUS_ADDRESS") { Ok(val) => Self::from_str(&val), _ => { - let uid = Uid::current(); - let path = format!("unix:path=/run/user/{}/bus", uid); + let runtime_dir = env::var("XDG_RUNTIME_DIR") + .unwrap_or_else(|_| format!("/run/user/{}", Uid::current())); + let path = format!("unix:path={}/bus", runtime_dir); Self::from_str(&path) } --- cargo-crates/zbus-1.9.3/src/azync/connection.rs.orig 1970-01-01 00:00:00 UTC +++ cargo-crates/zbus-1.9.3/src/azync/connection.rs @@ -177,13 +177,29 @@ where /// Upon successful return, the connection is fully established and negotiated: D-Bus messages /// can be sent and received. pub async fn new_server(stream: S, guid: &Guid) -> Result { - use nix::sys::socket::{getsockopt, sockopt::PeerCredentials}; + #[cfg(any(target_os = "android", target_os = "linux"))] + let client_uid = { + use nix::sys::socket::{getsockopt, sockopt::PeerCredentials}; - // FIXME: Could and should this be async? - let creds = getsockopt(stream.as_raw_fd(), PeerCredentials) - .map_err(|e| Error::Handshake(format!("Failed to get peer credentials: {}", e)))?; + let creds = getsockopt(stream.as_raw_fd(), PeerCredentials) + .map_err(|e| Error::Handshake(format!("Failed to get peer credentials: {}", e)))?; - let auth = Authenticated::server(Async::new(stream)?, guid.clone(), creds.uid()).await?; + creds.uid() + }; + #[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "openbsd", + target_os = "netbsd" + ))] + let client_uid = nix::unistd::getpeereid(stream.as_raw_fd()) + .map_err(|e| Error::Handshake(format!("Failed to get peer credentials: {}", e)))? + .0 + .into(); + + let auth = Authenticated::server(Async::new(stream)?, guid.clone(), client_uid).await?; Ok(Self::new_authenticated(auth)) } --- cargo-crates/zbus-1.9.3/src/connection.rs.orig 1970-01-01 00:00:00 UTC +++ cargo-crates/zbus-1.9.3/src/connection.rs @@ -160,12 +160,29 @@ impl Connection { /// Upon successful return, the connection is fully established and negotiated: D-Bus messages /// can be sent and received. pub fn new_unix_server(stream: UnixStream, guid: &Guid) -> Result { - use nix::sys::socket::{getsockopt, sockopt::PeerCredentials}; + #[cfg(any(target_os = "android", target_os = "linux"))] + let client_uid = { + use nix::sys::socket::{getsockopt, sockopt::PeerCredentials}; - let creds = getsockopt(stream.as_raw_fd(), PeerCredentials) - .map_err(|e| Error::Handshake(format!("Failed to get peer credentials: {}", e)))?; + let creds = getsockopt(stream.as_raw_fd(), PeerCredentials) + .map_err(|e| Error::Handshake(format!("Failed to get peer credentials: {}", e)))?; - let handshake = ServerHandshake::new(stream, guid.clone(), creds.uid()); + creds.uid() + }; + #[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "openbsd", + target_os = "netbsd" + ))] + let client_uid = nix::unistd::getpeereid(stream.as_raw_fd()) + .map_err(|e| Error::Handshake(format!("Failed to get peer credentials: {}", e)))? + .0 + .into(); + + let handshake = ServerHandshake::new(stream, guid.clone(), client_uid); handshake .blocking_finish() .map(Connection::new_authenticated_unix) --- cargo-crates/zbus-1.9.3/src/handshake.rs.orig 1970-01-01 00:00:00 UTC +++ cargo-crates/zbus-1.9.3/src/handshake.rs @@ -124,7 +124,7 @@ impl ClientHandshake { fn flush_buffer(&mut self) -> Result<()> { while !self.buffer.is_empty() { - let written = self.socket.sendmsg(&self.buffer, &[])?; + let written = self.socket.sendmsg(&self.buffer, &[], false)?; self.buffer.drain(..written); } Ok(()) @@ -182,6 +182,15 @@ impl Handshake for ClientHandshake { self.step = ClientHandshakeStep::SendingOauth; } ClientHandshakeStep::SendingOauth => { + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + { + let zero = self.buffer.drain(..1).next().unwrap(); + if self.socket.sendmsg(&[zero], &[], true)? != 1 { + return Err(Error::Handshake( + "Could not send zero byte with credentials".to_string(), + )); + } + } self.flush_buffer()?; self.step = ClientHandshakeStep::WaitOauth; } @@ -385,7 +394,7 @@ impl ServerHandshake { fn flush_buffer(&mut self) -> Result<()> { while !self.buffer.is_empty() { - let written = self.socket.sendmsg(&self.buffer, &[])?; + let written = self.socket.sendmsg(&self.buffer, &[], false)?; self.buffer.drain(..written); } Ok(()) --- cargo-crates/zbus-1.9.3/src/raw/connection.rs.orig 1970-01-01 00:00:00 UTC +++ cargo-crates/zbus-1.9.3/src/raw/connection.rs @@ -47,7 +47,7 @@ impl Connection { // VecDeque should never return an empty front buffer if the VecDeque // itself is not empty debug_assert!(!front.is_empty()); - let written = self.socket.sendmsg(front, &[])?; + let written = self.socket.sendmsg(front, &[], false)?; self.raw_out_buffer.drain(..written); } @@ -55,14 +55,14 @@ impl Connection { while let Some(msg) = self.msg_out_buffer.front() { let mut data = msg.as_bytes(); let fds = msg.fds(); - let written = self.socket.sendmsg(data, &fds)?; + let written = self.socket.sendmsg(data, &fds, false)?; // at least some part of the message has been sent, see if we can/need to send more // now the message must be removed from msg_out_buffer and any leftover bytes // must be stored into raw_out_buffer let msg = self.msg_out_buffer.pop_front().unwrap(); data = &msg.as_bytes()[written..]; while !data.is_empty() { - match self.socket.sendmsg(data, &[]) { + match self.socket.sendmsg(data, &[], false) { Ok(n) => data = &data[n..], Err(e) => { // an error occured, we cannot send more, store the remaining into --- cargo-crates/zbus-1.9.3/src/raw/socket.rs.orig 1970-01-01 00:00:00 UTC +++ cargo-crates/zbus-1.9.3/src/raw/socket.rs @@ -47,7 +47,7 @@ pub trait Socket { /// /// If the underlying transport does not support transmitting file descriptors, this /// will return `Err(ErrorKind::InvalidInput)`. - fn sendmsg(&mut self, buffer: &[u8], fds: &[RawFd]) -> io::Result; + fn sendmsg(&mut self, buffer: &[u8], fds: &[RawFd], creds: bool) -> io::Result; /// Close the socket. /// @@ -74,6 +74,10 @@ impl Socket for UnixStream { Ok(msg) => { let mut fds = vec![]; for cmsg in msg.cmsgs() { + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + if let ControlMessageOwned::ScmCreds(_) = cmsg { + continue; + } if let ControlMessageOwned::ScmRights(fd) = cmsg { fds.extend(fd.iter().map(|&f| unsafe { OwnedFd::from_raw_fd(f) })); } else { @@ -89,12 +93,23 @@ impl Socket for UnixStream { } } - fn sendmsg(&mut self, buffer: &[u8], fds: &[RawFd]) -> io::Result { - let cmsg = if !fds.is_empty() { + fn sendmsg(&mut self, buffer: &[u8], fds: &[RawFd], creds: bool) -> io::Result { + let mut cmsg = if !fds.is_empty() { vec![ControlMessage::ScmRights(fds)] } else { vec![] }; + #[cfg(any(target_os = "android", target_os = "linux"))] + let unix_creds; + if creds { + #[cfg(any(target_os = "android", target_os = "linux"))] + { + unix_creds = Some(nix::sys::socket::UnixCredentials::new()); + cmsg.push(ControlMessage::ScmCredentials(unix_creds.as_ref().unwrap())); + } + #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] + cmsg.push(ControlMessage::ScmCreds); + } let iov = [IoVec::from_slice(buffer)]; match sendmsg(self.as_raw_fd(), &iov, &cmsg, MsgFlags::empty(), None) { // can it really happen? @@ -122,8 +137,8 @@ where self.get_mut().recvmsg(buffer) } - fn sendmsg(&mut self, buffer: &[u8], fds: &[RawFd]) -> io::Result { - self.get_mut().sendmsg(buffer, fds) + fn sendmsg(&mut self, buffer: &[u8], fds: &[RawFd], creds: bool) -> io::Result { + self.get_mut().sendmsg(buffer, fds, creds) } fn close(&self) -> io::Result<()> {