hypfvieh / dbus-java

Improved version of java DBus library provided by freedesktop.org (https://dbus.freedesktop.org/doc/dbus-java/)
https://hypfvieh.github.io/dbus-java/
MIT License
180 stars 72 forks source link

Crash with anonymous auth mechanism. #214

Closed Prototik closed 1 year ago

Prototik commented 1 year ago

In my current project we're using dbus-java as client side implementation of p2p ipc. The server is written in rust using zbus library. While using External auth works fine, we also want to run on platforms where is unix sockets not supported (i'm looking at you, windows). So we need to use something else, eg tcp transport is fine, but External auth not applicable to it, so we left over with cookie and anonymous. As a POC I tried to launch unix (not related to the transport, tcp affected too) anonymous p2p server, but dbus-java crashing somewhere in the auth logic:

rust # Listening at unix:path=/tmp/dbus-p2p-9HPTIaoCQZPday0R,guid=b85440800bab87f0e91b7d996479847e
java # 13:56:15,478 [BusAddress] Parsing bus address: unix:path=/tmp/dbus-p2p-9HPTIaoCQZPday0R,guid=b85440800bab87f0e91b7d996479847e
java # 13:56:15,479 [BusAddress] Transport type: unix
java # 13:56:15,479 [BusAddress] Transport options: {path=/tmp/dbus-p2p-9HPTIaoCQZPday0R, guid=b85440800bab87f0e91b7d996479847e}
java # 13:56:15,499 [MethodTuple] new MethodTuple(Ping, )
java # 13:56:15,505 [Marshalling] Converted Java type: class java.lang.String to D-Bus Type: s
java # 13:56:15,507 [MethodTuple] new MethodTuple(GetMachineId, )
java # 13:56:15,510 [MethodTuple] new MethodTuple(Introspect, )
java # 13:56:15,520 [TransportBuilder] Found provider 'TcpTransportProvider' named 'dbus-java-transport-tcp' providing bustype 'TCP'
java # 13:56:15,521 [TransportBuilder] Found provider 'JUnixSocketTransportProvider' named 'dbus-transport-junixsocket' providing bustype 'UNIX'
java # 13:56:15,525 [TransportBuilder] Using transport dbus-transport-junixsocket for address unix:path=/tmp/dbus-p2p-9HPTIaoCQZPday0R,guid=b85440800bab87f0e91b7d996479847e
java # 13:56:15,638 [SASL] Mode: CLIENT AUTH state: INITIAL_STATE
java # 13:56:15,640 [SASL] sending: AUTH
java # 
java # 13:56:15,640 [SASL] Mode: CLIENT AUTH state: WAIT_DATA
java # 13:56:15,641 [SASL] received: REJECTED ANONYMOUS
java # 13:56:15,643 [SASL$Command] Creating command from: [REJECTED, ANONYMOUS]
java # 13:56:15,652 [SASL$Command] Created command: Command(REJECTED, 4, null)
java # 13:56:15,652 [SASL] sending: AUTH ANONYMOUS
java # 
java # 13:56:15,653 [SASL] Mode: CLIENT AUTH state: WAIT_DATA
java # 13:56:15,653 [SASL] received: DATA
java # 13:56:15,653 [SASL$Command] Creating command from: [DATA]
java # 13:56:15,654 [SASL] Cannot create command.
java # java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
java #  at org.freedesktop.dbus.connections.SASL$Command.<init>(SASL.java:868)
java #  at org.freedesktop.dbus.connections.SASL.receive(SASL.java:297)
java #  at org.freedesktop.dbus.connections.SASL.auth(SASL.java:510)
java #  at org.freedesktop.dbus.connections.transports.AbstractTransport.authenticate(AbstractTransport.java:197)
java #  at org.freedesktop.dbus.connections.transports.AbstractTransport.internalConnect(AbstractTransport.java:172)
java #  at org.freedesktop.dbus.connections.transports.AbstractTransport.connect(AbstractTransport.java:141)
java #  at org.freedesktop.dbus.connections.transports.TransportBuilder.build(TransportBuilder.java:339)
java #  at org.freedesktop.dbus.connections.AbstractConnection.<init>(AbstractConnection.java:151)
java #  at org.freedesktop.dbus.connections.impl.DirectConnection.<init>(DirectConnection.java:69)
java #  at org.freedesktop.dbus.connections.impl.DirectConnectionBuilder.build(DirectConnectionBuilder.java:45)
java # 13:56:15,656 [DirectConnection] Error creating transport
java # org.freedesktop.dbus.exceptions.AuthenticationException: Failed to authenticate.
java #  at org.freedesktop.dbus.connections.SASL.receive(SASL.java:300)
java #  at org.freedesktop.dbus.connections.SASL.auth(SASL.java:510)
java #  at org.freedesktop.dbus.connections.transports.AbstractTransport.authenticate(AbstractTransport.java:197)
java #  at org.freedesktop.dbus.connections.transports.AbstractTransport.internalConnect(AbstractTransport.java:172)
java #  at org.freedesktop.dbus.connections.transports.AbstractTransport.connect(AbstractTransport.java:141)
java #  at org.freedesktop.dbus.connections.transports.TransportBuilder.build(TransportBuilder.java:339)
java #  at org.freedesktop.dbus.connections.AbstractConnection.<init>(AbstractConnection.java:151)
java #  at org.freedesktop.dbus.connections.impl.DirectConnection.<init>(DirectConnection.java:69)
java #  at org.freedesktop.dbus.connections.impl.DirectConnectionBuilder.build(DirectConnectionBuilder.java:45)
java # Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
java #  at org.freedesktop.dbus.connections.SASL$Command.<init>(SASL.java:868)
java #  at org.freedesktop.dbus.connections.SASL.receive(SASL.java:297)
java #  ... 10 more
rust # Error: Handshake("Unexpected EOF during handshake")
java # 13:56:15,657 [DirectConnection] Ignoring disconnect, already disconnected
java # Process finished with exit code 1

It happens because auth logic assumes DATA message from SASL will always contains some data:

            } else if (0 == COL.compare(ss[0], "DATA")) {
                command = DATA;
                data = ss[1];
...

But as you can see it's not always the case and zbus sending empty DATA for some reason. Seems like it's valid case as it's documented in dbus specification: Some SASL mechanisms support sending an "empty string"; FIXME we need some way to do this.

hypfvieh commented 1 year ago

I've fixed the handling of DATA when no actual data is given.

While using External auth works fine, we also want to run on platforms where is unix sockets not supported (i'm looking at you, windows)

Windows does support Unix socket since Windows 10. Using TCP should always work but is a lot slower than using UnixSockets.

Prototik commented 1 year ago

Windows does support Unix socket since Windows 10.

Yeah, I know that, but we have users on win7 (even couple on winxp), so we cannot relay on that. TCP is fine, IPC don't transfer a lot of data, speed should not be issue.

Thanks for fix!