]> nmode's Git Repositories - signal-cli/blobdiff - lib/src/main/java/org/asamk/signal/manager/Manager.java
Handle queued actions also when thread is interrupted
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / Manager.java
index cde2714f25012ad39634b39a0bea5163283436bd..80c5fbbb3a7758886e04d980f58ca7966f54dee3 100644 (file)
@@ -81,6 +81,9 @@ import org.whispersystems.libsignal.IdentityKeyPair;
 import org.whispersystems.libsignal.InvalidKeyException;
 import org.whispersystems.libsignal.InvalidMessageException;
 import org.whispersystems.libsignal.ecc.ECPublicKey;
+import org.whispersystems.libsignal.fingerprint.Fingerprint;
+import org.whispersystems.libsignal.fingerprint.FingerprintParsingException;
+import org.whispersystems.libsignal.fingerprint.FingerprintVersionMismatchException;
 import org.whispersystems.libsignal.state.PreKeyRecord;
 import org.whispersystems.libsignal.state.SignedPreKeyRecord;
 import org.whispersystems.libsignal.util.Pair;
@@ -1787,16 +1790,7 @@ public class Manager implements Closeable {
                 queuedActions.addAll(actions);
             }
         }
-        for (var action : queuedActions) {
-            try {
-                action.execute(this);
-            } catch (Throwable e) {
-                if (e instanceof AssertionError && e.getCause() instanceof InterruptedException) {
-                    Thread.currentThread().interrupt();
-                }
-                logger.warn("Message action failed.", e);
-            }
-        }
+        handleQueuedActions(queuedActions);
     }
 
     private List<HandleAction> retryFailedReceivedMessage(
@@ -1840,7 +1834,7 @@ public class Manager implements Closeable {
             boolean returnOnTimeout,
             boolean ignoreAttachments,
             ReceiveMessageHandler handler
-    ) throws IOException, InterruptedException {
+    ) throws IOException {
         retryFailedReceivedMessages(handler, ignoreAttachments);
 
         Set<HandleAction> queuedActions = new HashSet<>();
@@ -1872,16 +1866,7 @@ public class Manager implements Closeable {
                     // Received indicator that server queue is empty
                     hasCaughtUpWithOldMessages = true;
 
-                    for (var action : queuedActions) {
-                        try {
-                            action.execute(this);
-                        } catch (Throwable e) {
-                            if (e instanceof AssertionError && e.getCause() instanceof InterruptedException) {
-                                Thread.currentThread().interrupt();
-                            }
-                            logger.warn("Message action failed.", e);
-                        }
-                    }
+                    handleQueuedActions(queuedActions);
                     queuedActions.clear();
 
                     // Continue to wait another timeout for new messages
@@ -1889,7 +1874,8 @@ public class Manager implements Closeable {
                 }
             } catch (AssertionError e) {
                 if (e.getCause() instanceof InterruptedException) {
-                    throw (InterruptedException) e.getCause();
+                    Thread.currentThread().interrupt();
+                    break;
                 } else {
                     throw e;
                 }
@@ -1967,6 +1953,20 @@ public class Manager implements Closeable {
                 }
             }
         }
+        handleQueuedActions(queuedActions);
+    }
+
+    private void handleQueuedActions(final Set<HandleAction> queuedActions) {
+        for (var action : queuedActions) {
+            try {
+                action.execute(this);
+            } catch (Throwable e) {
+                if (e instanceof AssertionError && e.getCause() instanceof InterruptedException) {
+                    Thread.currentThread().interrupt();
+                }
+                logger.warn("Message action failed.", e);
+            }
+        }
     }
 
     private boolean isMessageBlocked(
@@ -2668,6 +2668,25 @@ public class Manager implements Closeable {
                 TrustLevel.TRUSTED_VERIFIED);
     }
 
+    /**
+     * Trust this the identity with this scannable safety number
+     *
+     * @param name         username of the identity
+     * @param safetyNumber Scannable safety number
+     */
+    public boolean trustIdentityVerifiedSafetyNumber(String name, byte[] safetyNumber) throws InvalidNumberException {
+        var recipientId = canonicalizeAndResolveRecipient(name);
+        var address = account.getRecipientStore().resolveServiceAddress(recipientId);
+        return trustIdentity(recipientId, identityKey -> {
+            final var fingerprint = computeSafetyNumberFingerprint(address, identityKey);
+            try {
+                return fingerprint != null && fingerprint.getScannableFingerprint().compareTo(safetyNumber);
+            } catch (FingerprintVersionMismatchException | FingerprintParsingException e) {
+                return false;
+            }
+        }, TrustLevel.TRUSTED_VERIFIED);
+    }
+
     /**
      * Trust all keys of this identity without verification
      *
@@ -2717,21 +2736,23 @@ public class Manager implements Closeable {
     }
 
     public String computeSafetyNumber(SignalServiceAddress theirAddress, IdentityKey theirIdentityKey) {
-        final var fingerprint = Utils.computeSafetyNumber(capabilities.isUuid(),
-                account.getSelfAddress(),
-                getIdentityKeyPair().getPublicKey(),
-                theirAddress,
-                theirIdentityKey);
+        final Fingerprint fingerprint = computeSafetyNumberFingerprint(theirAddress, theirIdentityKey);
         return fingerprint == null ? null : fingerprint.getDisplayableFingerprint().getDisplayText();
     }
 
     public byte[] computeSafetyNumberForScanning(SignalServiceAddress theirAddress, IdentityKey theirIdentityKey) {
-        final var fingerprint = Utils.computeSafetyNumber(capabilities.isUuid(),
+        final Fingerprint fingerprint = computeSafetyNumberFingerprint(theirAddress, theirIdentityKey);
+        return fingerprint == null ? null : fingerprint.getScannableFingerprint().getSerialized();
+    }
+
+    private Fingerprint computeSafetyNumberFingerprint(
+            final SignalServiceAddress theirAddress, final IdentityKey theirIdentityKey
+    ) {
+        return Utils.computeSafetyNumber(capabilities.isUuid(),
                 account.getSelfAddress(),
                 getIdentityKeyPair().getPublicKey(),
                 theirAddress,
                 theirIdentityKey);
-        return fingerprint == null ? null : fingerprint.getScannableFingerprint().getSerialized();
     }
 
     @Deprecated