From 1bf703b012521ac8b887be8a50b01bc7b62ce677 Mon Sep 17 00:00:00 2001 From: AsamK Date: Fri, 9 Feb 2024 17:45:41 +0100 Subject: [PATCH] Add --bus-name option to use different D-Bus bus name --- CHANGELOG.md | 2 + man/signal-cli.1.adoc | 6 ++ src/main/java/org/asamk/signal/App.java | 7 ++- .../asamk/signal/commands/DaemonCommand.java | 37 +++++++----- .../asamk/signal/dbus/DbusCommandHandler.java | 57 +++++++++++-------- .../org/asamk/signal/dbus/DbusHandler.java | 20 +++++-- .../asamk/signal/dbus/DbusManagerImpl.java | 7 ++- .../dbus/DbusMultiAccountManagerImpl.java | 15 +++-- 8 files changed, 98 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd76af67..39950184 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Sending to the self number (+XXXX) now behaves the same as the `--note-to-self` parameter. To get the previous behavior, the `--notify-self` parameter can be added - New `--unrestricted-unidentified-sender` parameter for `updateAccount command` +- New `--bus-name` parameter for `daemon` command to use another D-Bus bus name ### Improved @@ -23,6 +24,7 @@ ## [0.12.8] - 2024-02-06 ### Fixes + - Update user agent ## [0.12.7] - 2023-12-15 diff --git a/man/signal-cli.1.adoc b/man/signal-cli.1.adoc index 110f8021..af11a2df 100644 --- a/man/signal-cli.1.adoc +++ b/man/signal-cli.1.adoc @@ -71,6 +71,9 @@ Make request via user dbus. *--dbus-system*:: Make request via system dbus. +*--bus-name*:: +Connect to another D-Bus bus name than the default. + *-o* OUTPUT-MODE, *--output* OUTPUT-MODE:: Specify if you want commands to output in either "plain-text" mode or in "json". Defaults to "plain-text" @@ -746,6 +749,9 @@ See **signal-cli-dbus**(5) for info on the dbus interface. Export DBus interface on system bus. + See **signal-cli-dbus**(5) for info on the dbus interface. +*--bus-name*:: +Claim another D-Bus bus name than the default. + *--ignore-attachments*:: Don’t download attachments of received messages. diff --git a/src/main/java/org/asamk/signal/App.java b/src/main/java/org/asamk/signal/App.java index d9ffa622..f8585386 100644 --- a/src/main/java/org/asamk/signal/App.java +++ b/src/main/java/org/asamk/signal/App.java @@ -76,6 +76,10 @@ public class App { .dest("global-dbus-system") .help("Make request via system dbus.") .action(Arguments.storeTrue()); + parser.addArgument("--bus-name") + .dest("global-bus-name") + .setDefault(DbusConfig.getBusname()) + .help("Specify the D-Bus bus name to connect to."); parser.addArgument("-o", "--output") .help("Choose to output in plain text or JSON") @@ -125,8 +129,9 @@ public class App { final var useDbus = Boolean.TRUE.equals(ns.getBoolean("global-dbus")); final var useDbusSystem = Boolean.TRUE.equals(ns.getBoolean("global-dbus-system")); if (useDbus || useDbusSystem) { + final var busName = ns.getString("global-bus-name"); // If account is null, it will connect to the default object path - initDbusClient(command, account, useDbusSystem, commandHandler); + initDbusClient(command, account, useDbusSystem, busName, commandHandler); return; } diff --git a/src/main/java/org/asamk/signal/commands/DaemonCommand.java b/src/main/java/org/asamk/signal/commands/DaemonCommand.java index f4d701b1..e4a14f4a 100644 --- a/src/main/java/org/asamk/signal/commands/DaemonCommand.java +++ b/src/main/java/org/asamk/signal/commands/DaemonCommand.java @@ -4,6 +4,7 @@ import net.sourceforge.argparse4j.impl.Arguments; import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Subparser; +import org.asamk.signal.DbusConfig; import org.asamk.signal.OutputType; import org.asamk.signal.ReceiveMessageHandler; import org.asamk.signal.Shutdown; @@ -50,6 +51,9 @@ public class DaemonCommand implements MultiLocalCommand, LocalCommand { subparser.addArgument("--dbus-system", "--system") .action(Arguments.storeTrue()) .help("Expose a DBus interface on the system bus."); + subparser.addArgument("--bus-name") + .setDefault(DbusConfig.getBusname()) + .help("Specify the D-Bus bus name to connect to."); subparser.addArgument("--socket") .nargs("?") .type(File.class) @@ -177,20 +181,25 @@ public class DaemonCommand implements MultiLocalCommand, LocalCommand { final var isDbusSystem = Boolean.TRUE.equals(ns.getBoolean("dbus-system")); if (isDbusSystem) { - daemonHandler.runDbus(true); + final var busName = ns.getString("bus-name"); + daemonHandler.runDbus(true, busName); } final var isDbusSession = Boolean.TRUE.equals(ns.getBoolean("dbus")); - if (isDbusSession || ( - !isDbusSystem - && socketFile == null - && tcpAddress == null - && httpAddress == null - && inheritedChannel == null - )) { + if (isDbusSession) { + final var busName = ns.getString("bus-name"); + daemonHandler.runDbus(false, busName); + } + + if (!isDbusSystem + && !isDbusSession + && socketFile == null + && tcpAddress == null + && httpAddress == null + && inheritedChannel == null) { logger.warn( "Running daemon command without explicit mode is deprecated. Use --dbus to use the dbus interface."); - daemonHandler.runDbus(false); + daemonHandler.runDbus(false, DbusConfig.getBusname()); } } @@ -214,7 +223,7 @@ public class DaemonCommand implements MultiLocalCommand, LocalCommand { public abstract void runSocket(ServerSocketChannel serverChannel) throws CommandException; - public abstract void runDbus(boolean isDbusSystem) throws CommandException; + public abstract void runDbus(boolean isDbusSystem, final String busname) throws CommandException; public abstract void runHttp(InetSocketAddress address) throws CommandException; @@ -267,8 +276,8 @@ public class DaemonCommand implements MultiLocalCommand, LocalCommand { } @Override - public void runDbus(final boolean isDbusSystem) throws CommandException { - runDbus(new DbusHandler(isDbusSystem, m, receiveMode != ReceiveMode.ON_START)); + public void runDbus(final boolean isDbusSystem, final String busname) throws CommandException { + runDbus(new DbusHandler(isDbusSystem, busname, m, receiveMode != ReceiveMode.ON_START)); } @Override @@ -292,8 +301,8 @@ public class DaemonCommand implements MultiLocalCommand, LocalCommand { } @Override - public void runDbus(final boolean isDbusSystem) throws CommandException { - runDbus(new DbusHandler(isDbusSystem, c, receiveMode != ReceiveMode.ON_START)); + public void runDbus(final boolean isDbusSystem, final String busname) throws CommandException { + runDbus(new DbusHandler(isDbusSystem, busname, c, receiveMode != ReceiveMode.ON_START)); } @Override diff --git a/src/main/java/org/asamk/signal/dbus/DbusCommandHandler.java b/src/main/java/org/asamk/signal/dbus/DbusCommandHandler.java index 4f320ad8..5e272895 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusCommandHandler.java +++ b/src/main/java/org/asamk/signal/dbus/DbusCommandHandler.java @@ -24,12 +24,16 @@ import java.io.IOException; public class DbusCommandHandler { public static void initDbusClient( - final Command command, final String account, final boolean systemBus, final CommandHandler commandHandler + final Command command, + final String account, + final boolean systemBus, + final String busname, + final CommandHandler commandHandler ) throws CommandException { try { final var busType = systemBus ? DBusConnection.DBusBusType.SYSTEM : DBusConnection.DBusBusType.SESSION; try (var dBusConn = DBusConnectionBuilder.forType(busType).build()) { - handleCommand(command, account, dBusConn, commandHandler); + handleCommand(command, account, dBusConn, busname, commandHandler); } } catch (ServiceUnknown e) { throw new UserErrorException("signal-cli DBus daemon not running on " @@ -45,6 +49,7 @@ public class DbusCommandHandler { final Command command, final String account, final DBusConnection dBusConn, + final String busname, final CommandHandler commandHandler ) throws CommandException, DBusException { try { @@ -53,27 +58,27 @@ public class DbusCommandHandler { throw new UserErrorException("You cannot specify a account (phone number) when linking"); } - handleProvisioningCommand(c, dBusConn, commandHandler); + handleProvisioningCommand(c, dBusConn, busname, commandHandler); return; } if (account == null && command instanceof MultiLocalCommand c) { - handleMultiLocalCommand(c, dBusConn, commandHandler); + handleMultiLocalCommand(c, dBusConn, busname, commandHandler); return; } if (account != null && command instanceof RegistrationCommand c) { - handleRegistrationCommand(c, account, dBusConn, commandHandler); + handleRegistrationCommand(c, account, dBusConn, busname, commandHandler); return; } if (!(command instanceof LocalCommand localCommand)) { throw new UserErrorException("Command only works in multi-account mode"); } - var accountObjectPath = account == null ? tryGetSingleAccountObjectPath(dBusConn) : null; + var accountObjectPath = account == null ? tryGetSingleAccountObjectPath(dBusConn, busname) : null; if (accountObjectPath == null) { accountObjectPath = DbusConfig.getObjectPath(account); } - handleLocalCommand(localCommand, accountObjectPath, dBusConn, commandHandler); + handleLocalCommand(localCommand, accountObjectPath, dBusConn, busname, commandHandler); } catch (UnsupportedOperationException e) { throw new UserErrorException("Command is not yet implemented via dbus", e); } catch (DBusExecutionException e) { @@ -81,10 +86,10 @@ public class DbusCommandHandler { } } - private static String tryGetSingleAccountObjectPath(final DBusConnection dBusConn) throws DBusException, CommandException { - var control = dBusConn.getRemoteObject(DbusConfig.getBusname(), - DbusConfig.getObjectPath(), - SignalControl.class); + private static String tryGetSingleAccountObjectPath( + final DBusConnection dBusConn, final String busname + ) throws DBusException, CommandException { + var control = dBusConn.getRemoteObject(busname, DbusConfig.getObjectPath(), SignalControl.class); try { final var accounts = control.listAccounts(); if (accounts.isEmpty()) { @@ -102,12 +107,13 @@ public class DbusCommandHandler { } private static void handleMultiLocalCommand( - final MultiLocalCommand c, final DBusConnection dBusConn, final CommandHandler commandHandler + final MultiLocalCommand c, + final DBusConnection dBusConn, + final String busname, + final CommandHandler commandHandler ) throws CommandException, DBusException { - final var signalControl = dBusConn.getRemoteObject(DbusConfig.getBusname(), - DbusConfig.getObjectPath(), - SignalControl.class); - try (final var multiAccountManager = new DbusMultiAccountManagerImpl(signalControl, dBusConn)) { + final var signalControl = dBusConn.getRemoteObject(busname, DbusConfig.getObjectPath(), SignalControl.class); + try (final var multiAccountManager = new DbusMultiAccountManagerImpl(signalControl, dBusConn, busname)) { commandHandler.handleMultiLocalCommand(c, multiAccountManager); } } @@ -116,10 +122,11 @@ public class DbusCommandHandler { final LocalCommand c, String accountObjectPath, final DBusConnection dBusConn, + final String busname, final CommandHandler commandHandler ) throws CommandException, DBusException { - var signal = dBusConn.getRemoteObject(DbusConfig.getBusname(), accountObjectPath, Signal.class); - try (final var manager = new DbusManagerImpl(signal, dBusConn)) { + var signal = dBusConn.getRemoteObject(busname, accountObjectPath, Signal.class); + try (final var manager = new DbusManagerImpl(signal, dBusConn, busname)) { commandHandler.handleLocalCommand(c, manager); } } @@ -128,24 +135,24 @@ public class DbusCommandHandler { final RegistrationCommand c, String account, final DBusConnection dBusConn, + final String busname, final CommandHandler commandHandler ) throws CommandException, DBusException { - final var signalControl = dBusConn.getRemoteObject(DbusConfig.getBusname(), - DbusConfig.getObjectPath(), - SignalControl.class); + final var signalControl = dBusConn.getRemoteObject(busname, DbusConfig.getObjectPath(), SignalControl.class); try (final var registrationManager = new DbusRegistrationManagerImpl(account, signalControl, dBusConn)) { commandHandler.handleRegistrationCommand(c, registrationManager); } } private static void handleProvisioningCommand( - final ProvisioningCommand c, final DBusConnection dBusConn, final CommandHandler commandHandler + final ProvisioningCommand c, + final DBusConnection dBusConn, + final String busname, + final CommandHandler commandHandler ) throws CommandException, DBusException { - final var signalControl = dBusConn.getRemoteObject(DbusConfig.getBusname(), - DbusConfig.getObjectPath(), - SignalControl.class); + final var signalControl = dBusConn.getRemoteObject(busname, DbusConfig.getObjectPath(), SignalControl.class); final var provisioningManager = new DbusProvisioningManagerImpl(signalControl, dBusConn); commandHandler.handleProvisioningCommand(c, provisioningManager); } diff --git a/src/main/java/org/asamk/signal/dbus/DbusHandler.java b/src/main/java/org/asamk/signal/dbus/DbusHandler.java index 8b1dd61e..e71d7281 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusHandler.java +++ b/src/main/java/org/asamk/signal/dbus/DbusHandler.java @@ -21,12 +21,15 @@ public class DbusHandler implements AutoCloseable { private final boolean isDbusSystem; private DBusConnection dBusConnection; + private final String busname; private final List closeables = new ArrayList<>(); private final DbusRunner dbusRunner; private final boolean noReceiveOnStart; - public DbusHandler(final boolean isDbusSystem, final Manager m, final boolean noReceiveOnStart) { + public DbusHandler( + final boolean isDbusSystem, final String busname, final Manager m, final boolean noReceiveOnStart + ) { this.isDbusSystem = isDbusSystem; this.dbusRunner = (connection) -> { try { @@ -35,9 +38,15 @@ public class DbusHandler implements AutoCloseable { } }; this.noReceiveOnStart = noReceiveOnStart; + this.busname = busname; } - public DbusHandler(final boolean isDbusSystem, final MultiAccountManager c, final boolean noReceiveOnStart) { + public DbusHandler( + final boolean isDbusSystem, + final String busname, + final MultiAccountManager c, + final boolean noReceiveOnStart + ) { this.isDbusSystem = isDbusSystem; this.dbusRunner = (connection) -> { final var signalControl = new DbusSignalControlImpl(c, DbusConfig.getObjectPath()); @@ -72,6 +81,7 @@ public class DbusHandler implements AutoCloseable { } }; this.noReceiveOnStart = noReceiveOnStart; + this.busname = busname; } public void init() throws CommandException { @@ -79,7 +89,7 @@ public class DbusHandler implements AutoCloseable { throw new AssertionError("DbusHandler already initialized"); } final var busType = isDbusSystem ? DBusConnection.DBusBusType.SYSTEM : DBusConnection.DBusBusType.SESSION; - logger.debug("Starting DBus server on {} bus: {}", busType, DbusConfig.getBusname()); + logger.debug("Starting DBus server on {} bus: {}", busType, busname); try { dBusConnection = DBusConnectionBuilder.forType(busType).build(); dbusRunner.run(dBusConnection); @@ -90,13 +100,13 @@ public class DbusHandler implements AutoCloseable { } try { - dBusConnection.requestBusName(DbusConfig.getBusname()); + dBusConnection.requestBusName(busname); } catch (DBusException e) { throw new UnexpectedErrorException("Dbus command failed, maybe signal-cli dbus daemon is already running: " + e.getMessage(), e); } - logger.info("Started DBus server on {} bus: {}", busType, DbusConfig.getBusname()); + logger.info("Started DBus server on {} bus: {}", busType, busname); } @Override diff --git a/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java b/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java index 3d0e2263..f56a3ba4 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java @@ -1,7 +1,6 @@ package org.asamk.signal.dbus; import org.asamk.Signal; -import org.asamk.signal.DbusConfig; import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.api.AlreadyReceivingException; import org.asamk.signal.manager.api.AttachmentInvalidException; @@ -90,14 +89,16 @@ public class DbusManagerImpl implements Manager { private final Set weakHandlers = new HashSet<>(); private final Set messageHandlers = new HashSet<>(); private final List closedListeners = new ArrayList<>(); + private final String busname; private DBusSigHandler dbusMsgHandler; private DBusSigHandler dbusEditMsgHandler; private DBusSigHandler dbusRcptHandler; private DBusSigHandler dbusSyncHandler; - public DbusManagerImpl(final Signal signal, DBusConnection connection) { + public DbusManagerImpl(final Signal signal, DBusConnection connection, final String busname) { this.signal = signal; this.connection = connection; + this.busname = busname; } @Override @@ -820,7 +821,7 @@ public class DbusManagerImpl implements Manager { private T getRemoteObject(final DBusPath path, final Class type) { try { - return connection.getRemoteObject(DbusConfig.getBusname(), path.getPath(), type); + return connection.getRemoteObject(busname, path.getPath(), type); } catch (DBusException e) { throw new AssertionError(e); } diff --git a/src/main/java/org/asamk/signal/dbus/DbusMultiAccountManagerImpl.java b/src/main/java/org/asamk/signal/dbus/DbusMultiAccountManagerImpl.java index 2c5f720f..27e28779 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusMultiAccountManagerImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusMultiAccountManagerImpl.java @@ -2,7 +2,6 @@ package org.asamk.signal.dbus; import org.asamk.Signal; import org.asamk.SignalControl; -import org.asamk.signal.DbusConfig; import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.MultiAccountManager; import org.asamk.signal.manager.ProvisioningManager; @@ -32,10 +31,14 @@ public class DbusMultiAccountManagerImpl implements MultiAccountManager { // TODO add listeners for added/removed accounts private final Set> onManagerAddedHandlers = new HashSet<>(); private final Set> onManagerRemovedHandlers = new HashSet<>(); + private final String busname; - public DbusMultiAccountManagerImpl(final SignalControl signalControl, DBusConnection connection) { + public DbusMultiAccountManagerImpl( + final SignalControl signalControl, DBusConnection connection, final String busname + ) { this.signalControl = signalControl; this.connection = connection; + this.busname = busname; } @Override @@ -50,7 +53,7 @@ public class DbusMultiAccountManagerImpl implements MultiAccountManager { public List getManagers() { return signalControl.listAccounts() .stream() - .map(a -> (Manager) new DbusManagerImpl(getRemoteObject(a, Signal.class), connection)) + .map(a -> (Manager) new DbusManagerImpl(getRemoteObject(a, Signal.class), connection, busname)) .toList(); } @@ -70,7 +73,9 @@ public class DbusMultiAccountManagerImpl implements MultiAccountManager { @Override public Manager getManager(final String phoneNumber) { - return new DbusManagerImpl(getRemoteObject(signalControl.getAccount(phoneNumber), Signal.class), connection); + return new DbusManagerImpl(getRemoteObject(signalControl.getAccount(phoneNumber), Signal.class), + connection, + busname); } @Override @@ -98,7 +103,7 @@ public class DbusMultiAccountManagerImpl implements MultiAccountManager { private T getRemoteObject(final DBusPath path, final Class type) { try { - return connection.getRemoteObject(DbusConfig.getBusname(), path.getPath(), type); + return connection.getRemoteObject(busname, path.getPath(), type); } catch (DBusException e) { throw new AssertionError(e); } -- 2.50.1