From 06404667a1539a9107099a52aabf21edbfb0a066 Mon Sep 17 00:00:00 2001 From: AsamK Date: Sat, 16 Jan 2021 15:38:38 +0100 Subject: [PATCH] Use exit 4 when sending a single recipient message fails due to untrusted identity key Fixes #88 --- man/signal-cli.1.adoc | 1 + src/main/java/org/asamk/Signal.java | 19 +++++-------- .../asamk/signal/commands/SendCommand.java | 9 +++++++ .../org/asamk/signal/dbus/DbusSignalImpl.java | 27 ++++++++++++++++--- .../org/asamk/signal/manager/Manager.java | 6 ++--- .../org/asamk/signal/util/ErrorUtils.java | 20 +++++++++----- 6 files changed, 57 insertions(+), 25 deletions(-) diff --git a/man/signal-cli.1.adoc b/man/signal-cli.1.adoc index 3ae54ff0..16b684ea 100644 --- a/man/signal-cli.1.adoc +++ b/man/signal-cli.1.adoc @@ -404,6 +404,7 @@ signal-cli -u USERNAME trust -a NUMBER * *1*: Error is probably caused and fixable by the user * *2*: Some unexpected error * *3*: Server or IO error +* *4*: Sending failed due to untrusted key == Files diff --git a/src/main/java/org/asamk/Signal.java b/src/main/java/org/asamk/Signal.java index 16aec7c9..7f5d54d6 100644 --- a/src/main/java/org/asamk/Signal.java +++ b/src/main/java/org/asamk/Signal.java @@ -15,21 +15,21 @@ public interface Signal extends DBusInterface { long sendMessage( String message, List attachments, String recipient - ) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber; + ) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.UntrustedIdentity; long sendMessage( String message, List attachments, List recipients - ) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.UnregisteredUser, Error.UntrustedIdentity; + ) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.UntrustedIdentity; long sendNoteToSelfMessage( String message, List attachments - ) throws Error.AttachmentInvalid, Error.Failure, Error.UnregisteredUser, Error.UntrustedIdentity; + ) throws Error.AttachmentInvalid, Error.Failure; - void sendEndSessionMessage(List recipients) throws Error.Failure, Error.InvalidNumber, Error.UnregisteredUser, Error.UntrustedIdentity; + void sendEndSessionMessage(List recipients) throws Error.Failure, Error.InvalidNumber, Error.UntrustedIdentity; long sendGroupMessage( String message, List attachments, byte[] groupId - ) throws Error.GroupNotFound, Error.Failure, Error.AttachmentInvalid, Error.UnregisteredUser, Error.UntrustedIdentity; + ) throws Error.GroupNotFound, Error.Failure, Error.AttachmentInvalid; String getContactName(String number) throws Error.InvalidNumber; @@ -47,7 +47,7 @@ public interface Signal extends DBusInterface { byte[] updateGroup( byte[] groupId, String name, List members, String avatar - ) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.GroupNotFound, Error.UnregisteredUser, Error.UntrustedIdentity; + ) throws Error.AttachmentInvalid, Error.Failure, Error.InvalidNumber, Error.GroupNotFound; boolean isRegistered(); @@ -198,13 +198,6 @@ public interface Signal extends DBusInterface { } } - class UnregisteredUser extends DBusExecutionException { - - public UnregisteredUser(final String message) { - super(message); - } - } - class UntrustedIdentity extends DBusExecutionException { public UntrustedIdentity(final String message) { diff --git a/src/main/java/org/asamk/signal/commands/SendCommand.java b/src/main/java/org/asamk/signal/commands/SendCommand.java index 6d806abc..73d8f2ed 100644 --- a/src/main/java/org/asamk/signal/commands/SendCommand.java +++ b/src/main/java/org/asamk/signal/commands/SendCommand.java @@ -66,6 +66,9 @@ public class SendCommand implements DbusCommand { } catch (AssertionError e) { handleAssertionError(e); return 1; + } catch (Signal.Error.UntrustedIdentity e) { + System.err.println("Failed to send message: " + e.getMessage()); + return 4; } catch (DBusExecutionException e) { System.err.println("Failed to send message: " + e.getMessage()); return 2; @@ -118,6 +121,9 @@ public class SendCommand implements DbusCommand { } catch (AssertionError e) { handleAssertionError(e); return 1; + } catch (Signal.Error.UntrustedIdentity e) { + System.err.println("Failed to send message: " + e.getMessage()); + return 4; } catch (DBusExecutionException e) { System.err.println("Failed to send note to self message: " + e.getMessage()); return 2; @@ -134,6 +140,9 @@ public class SendCommand implements DbusCommand { } catch (UnknownObject e) { System.err.println("Failed to find dbus object, maybe missing the -u flag: " + e.getMessage()); return 1; + } catch (Signal.Error.UntrustedIdentity e) { + System.err.println("Failed to send message: " + e.getMessage()); + return 4; } catch (DBusExecutionException e) { System.err.println("Failed to send message: " + e.getMessage()); return 2; diff --git a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java index 77341491..a2f6cace 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java @@ -45,9 +45,30 @@ public class DbusSignalImpl implements Signal { return sendMessage(message, attachments, recipients); } + private static void checkSendMessageResult(long timestamp, SendMessageResult result) throws DBusExecutionException { + String error = ErrorUtils.getErrorMessageFromSendMessageResult(result); + + if (error == null) { + return; + } + + final String message = timestamp + "\nFailed to send message:\n" + error + '\n'; + + if (result.getIdentityFailure() != null) { + throw new Error.UntrustedIdentity(message); + } else { + throw new Error.Failure(message); + } + } + private static void checkSendMessageResults( long timestamp, List results ) throws DBusExecutionException { + if (results.size() == 1) { + checkSendMessageResult(timestamp, results.get(0)); + return; + } + List errors = ErrorUtils.getErrorMessagesFromSendMessageResults(results); if (errors.size() == 0) { return; @@ -81,10 +102,10 @@ public class DbusSignalImpl implements Signal { @Override public long sendNoteToSelfMessage( final String message, final List attachments - ) throws Error.AttachmentInvalid, Error.Failure, Error.UnregisteredUser, Error.UntrustedIdentity { + ) throws Error.AttachmentInvalid, Error.Failure, Error.UntrustedIdentity { try { - final Pair> results = m.sendSelfMessage(message, attachments); - checkSendMessageResults(results.first(), results.second()); + final Pair results = m.sendSelfMessage(message, attachments); + checkSendMessageResult(results.first(), results.second()); return results.first(); } catch (AttachmentInvalidException e) { throw new Error.AttachmentInvalid(e.getMessage()); diff --git a/src/main/java/org/asamk/signal/manager/Manager.java b/src/main/java/org/asamk/signal/manager/Manager.java index 38c43753..3c352cd4 100644 --- a/src/main/java/org/asamk/signal/manager/Manager.java +++ b/src/main/java/org/asamk/signal/manager/Manager.java @@ -953,7 +953,7 @@ public class Manager implements Closeable { return sendMessage(messageBuilder, getSignalServiceAddresses(recipients)); } - public Pair> sendSelfMessage( + public Pair sendSelfMessage( String messageText, List attachments ) throws IOException, AttachmentInvalidException { final SignalServiceDataMessage.Builder messageBuilder = SignalServiceDataMessage.newBuilder() @@ -1278,7 +1278,7 @@ public class Manager implements Closeable { } } - private Pair> sendSelfMessage( + private Pair sendSelfMessage( SignalServiceDataMessage.Builder messageBuilder ) throws IOException { final long timestamp = System.currentTimeMillis(); @@ -1294,7 +1294,7 @@ public class Manager implements Closeable { SignalServiceDataMessage message = messageBuilder.build(); final SendMessageResult result = sendSelfMessage(message); - return new Pair<>(timestamp, List.of(result)); + return new Pair<>(timestamp, result); } finally { account.save(); } diff --git a/src/main/java/org/asamk/signal/util/ErrorUtils.java b/src/main/java/org/asamk/signal/util/ErrorUtils.java index e9553f98..f7115ea9 100644 --- a/src/main/java/org/asamk/signal/util/ErrorUtils.java +++ b/src/main/java/org/asamk/signal/util/ErrorUtils.java @@ -33,18 +33,26 @@ public class ErrorUtils { public static List getErrorMessagesFromSendMessageResults(List results) { List errors = new ArrayList<>(); for (SendMessageResult result : results) { - if (result.isNetworkFailure()) { - errors.add(String.format("Network failure for \"%s\"", result.getAddress().getLegacyIdentifier())); - } else if (result.isUnregisteredFailure()) { - errors.add(String.format("Unregistered user \"%s\"", result.getAddress().getLegacyIdentifier())); - } else if (result.getIdentityFailure() != null) { - errors.add(String.format("Untrusted Identity for \"%s\"", result.getAddress().getLegacyIdentifier())); + String error = getErrorMessageFromSendMessageResult(result); + if (error != null) { + errors.add(error); } } return errors; } + public static String getErrorMessageFromSendMessageResult(SendMessageResult result) { + if (result.isNetworkFailure()) { + return String.format("Network failure for \"%s\"", result.getAddress().getLegacyIdentifier()); + } else if (result.isUnregisteredFailure()) { + return String.format("Unregistered user \"%s\"", result.getAddress().getLegacyIdentifier()); + } else if (result.getIdentityFailure() != null) { + return String.format("Untrusted Identity for \"%s\"", result.getAddress().getLegacyIdentifier()); + } + return null; + } + private static int handleSendMessageResultErrors(List errors) { if (errors.size() == 0) { return 0; -- 2.50.1