From e3e2f7ddfd6e5ab79cfd9f11148275e5aecaa9c9 Mon Sep 17 00:00:00 2001
From: Greg V <greg@unrelenting.technology>
Date: Mon, 16 Nov 2020 03:11:44 +0300
Subject: [PATCH] zb: Authenticate using SCM_CREDS on FreeBSD/DragonFlyBSD

The D-Bus daemon expects an SCM_CREDS first message on these OS.
It should be possible to add support for LOCAL_PEERCRED to the daemon
to make this optional, but the existing versions do require it.
---
 zbus/src/handshake.rs | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/zbus/src/handshake.rs b/zbus/src/handshake.rs
index 35fa97176..a9a13baa9 100644
--- a/zbus/src/handshake.rs
+++ b/zbus/src/handshake.rs
@@ -417,6 +417,28 @@ impl<S: Socket> Handshake<S> for ClientHandshake<S> {
             } else {
                 cmd.into()
             };
+            // The dbus daemon on these platforms currently requires sending the zero byte
+            // as a separate message with SCM_CREDS
+            #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
+            if self.step == Init {
+                use nix::sys::socket::{sendmsg, ControlMessage, MsgFlags};
+
+                let zero = &[self.send_buffer.drain(..1).next().unwrap()];
+                let iov = [nix::sys::uio::IoVec::from_slice(zero)];
+
+                if sendmsg(
+                    self.socket.as_raw_fd(),
+                    &iov,
+                    &[ControlMessage::ScmCreds],
+                    MsgFlags::empty(),
+                    None,
+                ) != Ok(1)
+                {
+                    return Err(Error::Handshake(
+                        "Could not send zero byte with credentials".to_string(),
+                    ));
+                }
+            }
             self.step = next_step;
         }
     }
-- 
GitLab