Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow sending and receiving Unix file descriptors. #65

Merged
merged 4 commits into from
Aug 22, 2023

Conversation

Dretch
Copy link
Contributor

@Dretch Dretch commented Aug 10, 2023

Fixes issue #64

@@ -297,3 +309,9 @@ assertThrows check f = do
case result of
Left ex -> assertBool ("unexpected exception " ++ show ex) (check ex)
Right _ -> assertFailure "expected exception not thrown"

nonWindowsTestCase :: TestName -> Assertion -> TestTree
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unix file descriptor passing should not work on Windows, so this is a hack to stop running the tests there.

I have not actually tested on anything other than Linux, though.

lib/DBus/Socket.hs Show resolved Hide resolved

-- | An authenticator that implements the D-Bus @EXTERNAL@ mechanism, which uses
-- credential passing over a Unix socket, with support for Unix file descriptor passing.
authenticatorWithUnixFds :: Authenticator SocketTransport
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usage looks something like:

let socketAuthenticator = DBus.authenticatorWithUnixFds
     clientSocketOptions = DBus.defaultSocketOptions {DBus.socketAuthenticator}
     clientOptions = DBus.defaultClientOptions {DBus.clientSocketOptions}
(dbusClient, clientName) <- DBus.connectWithName clientOptions addr

lib/DBus/Internal/Wire.hs Show resolved Hide resolved
lib/DBus.hs Outdated
-- mentioned in the message (the marshaled bytes will contain indices into
-- this list). Although unusual, it is possible for marshaling to fail; if this
-- occurs, an error will be returned instead.
marshal :: Message msg => Endianness -> Serial -> msg -> Either MarshalError (Char8.ByteString, [Fd])
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to avoid changing public API functions? Maybe add marshalWithFds here and in all other methods?

I prefer to avoid breaking existing API and releasing a new major version.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for reviewing @rblaze

I have pushed a commit to make the API backwards compatible in general (except for internal modules).

The library will change behaviour in a backwards incompatible way when it comes to file descriptors, of course. If someone was calling marshal and unmarshal directly and relying on the previous behaviour then their code will now break (likely with an exception during unmarshal when the list of file descriptors is not supplied but is now expected). However, I think the previous behaviour was clearly not how dbus is intended to work, and people relying on a bug should probably not be surprised when their code breaks 😉

--
-- Throws a 'TransportError' if an error occurs.
transportPutWithFds :: t -> ByteString -> [Fd] -> IO ()
transportPutWithFds t bs _fds = transportPut t bs
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default implementation for backwards compatibility. The SocketTransport instance overrides this with an implementation that actually sends the Fds over the socket.

--
-- Throws a 'TransportError' if an error occurs.
transportGetWithFds :: t -> Int -> IO (ByteString, [Fd])
transportGetWithFds t n = do
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default implementation for backwards compatibility.


unmarshalUnixFd :: Unmarshal Fd
unmarshalUnixFd = do
x <- unmarshalWord32
when (toInteger x > toInteger (maxBound :: CInt))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove import Foreign.C.Types (CInt) now

@rblaze rblaze merged commit d72229f into rblaze:master Aug 22, 2023
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants