]> nmode's Git Repositories - signal-cli/commitdiff
Renew session if message decryption fails with ProtocolInvalidMessageException
authorAsamK <asamk@gmx.de>
Wed, 5 May 2021 18:20:02 +0000 (20:20 +0200)
committerAsamK <asamk@gmx.de>
Wed, 5 May 2021 18:20:02 +0000 (20:20 +0200)
lib/src/main/java/org/asamk/signal/manager/HandleAction.java
lib/src/main/java/org/asamk/signal/manager/Manager.java
src/main/java/org/asamk/signal/ReceiveMessageHandler.java

index 7fb80c34812a6d5197389b5a318de8ec72a56261..08f51590308666ea4bbb8af2600c0c81fda59937 100644 (file)
@@ -187,3 +187,32 @@ class RetrieveProfileAction implements HandleAction {
         return recipientId.hashCode();
     }
 }
+
+class RenewSessionAction implements HandleAction {
+
+    private final RecipientId recipientId;
+
+    public RenewSessionAction(final RecipientId recipientId) {
+        this.recipientId = recipientId;
+    }
+
+    @Override
+    public void execute(Manager m) throws Throwable {
+        m.renewSession(recipientId);
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        final RenewSessionAction that = (RenewSessionAction) o;
+
+        return recipientId.equals(that.recipientId);
+    }
+
+    @Override
+    public int hashCode() {
+        return recipientId.hashCode();
+    }
+}
index 05aec952aa02bfe33544883d376dc78eb93bf8a0..f1639eabdcbf8aba8369cd45f9c2d7db8232100a 100644 (file)
@@ -1088,6 +1088,11 @@ public class Manager implements Closeable {
         }
     }
 
+    SendMessageResult renewSession(RecipientId recipientId) throws IOException {
+        account.getSessionStore().archiveSessions(recipientId);
+        return sendNullMessage(recipientId);
+    }
+
     public String getContactName(String number) throws InvalidNumberException {
         var contact = account.getContactStore().getContact(canonicalizeAndResolveRecipient(number));
         return contact == null || contact.getName() == null ? "" : contact.getName();
@@ -1468,6 +1473,23 @@ public class Manager implements Closeable {
         }
     }
 
+    private SendMessageResult sendNullMessage(RecipientId recipientId) throws IOException {
+        var messageSender = createMessageSender();
+
+        final var address = resolveSignalServiceAddress(recipientId);
+        try {
+            try {
+                return messageSender.sendNullMessage(address, unidentifiedAccessHelper.getAccessFor(recipientId));
+            } catch (UnregisteredUserException e) {
+                final var newRecipientId = refreshRegisteredUser(recipientId);
+                final var newAddress = resolveSignalServiceAddress(newRecipientId);
+                return messageSender.sendNullMessage(newAddress, unidentifiedAccessHelper.getAccessFor(newRecipientId));
+            }
+        } catch (UntrustedIdentityException e) {
+            return SendMessageResult.identityFailure(address, e.getIdentityKey());
+        }
+    }
+
     private SignalServiceContent decryptMessage(SignalServiceEnvelope envelope) throws InvalidMetadataMessageException, ProtocolInvalidMessageException, ProtocolDuplicateMessageException, ProtocolLegacyMessageException, ProtocolInvalidKeyIdException, InvalidMetadataVersionException, ProtocolInvalidVersionException, ProtocolNoSessionException, ProtocolInvalidKeyException, SelfSendException, UnsupportedDataMessageException, org.whispersystems.libsignal.UntrustedIdentityException {
         var cipher = new SignalServiceCipher(account.getSelfAddress(),
                 account.getSignalProtocolStore(),
@@ -1812,6 +1834,11 @@ public class Manager implements Closeable {
                     exception = e;
                 }
                 var actions = handleMessage(envelope, content, ignoreAttachments);
+                if (exception instanceof ProtocolInvalidMessageException) {
+                    final var sender = resolveRecipient(((ProtocolInvalidMessageException) exception).getSender());
+                    logger.debug("Received invalid message, queuing renew session action.");
+                    actions.add(new RenewSessionAction(sender));
+                }
                 if (hasCaughtUpWithOldMessages) {
                     for (var action : actions) {
                         try {
index 2aa7dfca546b64c72a9ea64d6141189f5078b404..ce4f10686e630077cca42b560b910e5081b9157c 100644 (file)
@@ -84,7 +84,7 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler {
                 }
             }
             if (content == null) {
-                writer.println("Failed to decrypt message.");
+                writer.println("No message content");
             } else {
                 writer.println("Sender: {} (device: {})",
                         formatContact(content.getSender()),