From: AsamK Date: Mon, 20 Dec 2021 16:48:36 +0000 (+0100) Subject: Retry failed messages after trusting a new identity X-Git-Tag: v0.10.1~53 X-Git-Url: https://git.nmode.ca/signal-cli/commitdiff_plain/172011234b1778c7f02a406e8143cfafa07ce2ad Retry failed messages after trusting a new identity --- diff --git a/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java index cb9e4730..2fb3ae56 100644 --- a/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java @@ -151,6 +151,7 @@ public class ManagerImpl implements Manager { private final Set messageHandlers = new HashSet<>(); private final List closedListeners = new ArrayList<>(); private boolean isReceivingSynchronous; + private boolean needsToRetryFailedMessages = false; ManagerImpl( SignalAccount account, @@ -1102,7 +1103,7 @@ public class ManagerImpl implements Manager { private void receiveMessagesInternal( Duration timeout, boolean returnOnTimeout, ReceiveMessageHandler handler ) throws IOException { - retryFailedReceivedMessages(handler); + needsToRetryFailedMessages = true; // Use a Map here because java Set doesn't have a get method ... Map queuedActions = new HashMap<>(); @@ -1121,6 +1122,10 @@ public class ManagerImpl implements Manager { final var MAX_BACKOFF_COUNTER = 9; while (!Thread.interrupted()) { + if (needsToRetryFailedMessages) { + retryFailedReceivedMessages(handler); + needsToRetryFailedMessages = false; + } SignalServiceEnvelope envelope; final CachedMessage[] cachedMessage = {null}; final var nowMillis = System.currentTimeMillis(); @@ -1365,7 +1370,11 @@ public class ManagerImpl implements Manager { } catch (IOException e) { return false; } - return identityHelper.trustIdentityVerified(recipientId, fingerprint); + final var updated = identityHelper.trustIdentityVerified(recipientId, fingerprint); + if (updated && this.isReceiving()) { + needsToRetryFailedMessages = true; + } + return updated; } /** @@ -1382,7 +1391,11 @@ public class ManagerImpl implements Manager { } catch (IOException e) { return false; } - return identityHelper.trustIdentityVerifiedSafetyNumber(recipientId, safetyNumber); + final var updated = identityHelper.trustIdentityVerifiedSafetyNumber(recipientId, safetyNumber); + if (updated && this.isReceiving()) { + needsToRetryFailedMessages = true; + } + return updated; } /** @@ -1399,7 +1412,11 @@ public class ManagerImpl implements Manager { } catch (IOException e) { return false; } - return identityHelper.trustIdentityVerifiedSafetyNumber(recipientId, safetyNumber); + final var updated = identityHelper.trustIdentityVerifiedSafetyNumber(recipientId, safetyNumber); + if (updated && this.isReceiving()) { + needsToRetryFailedMessages = true; + } + return updated; } /** @@ -1415,7 +1432,11 @@ public class ManagerImpl implements Manager { } catch (IOException e) { return false; } - return identityHelper.trustIdentityAllKeys(recipientId); + final var updated = identityHelper.trustIdentityAllKeys(recipientId); + if (updated && this.isReceiving()) { + needsToRetryFailedMessages = true; + } + return updated; } @Override diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/IncomingMessageHandler.java b/lib/src/main/java/org/asamk/signal/manager/helper/IncomingMessageHandler.java index 3fc040bc..db854ef6 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/IncomingMessageHandler.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/IncomingMessageHandler.java @@ -106,6 +106,7 @@ public final class IncomingMessageHandler { SignalServiceContent content = null; if (!envelope.isReceipt()) { + account.getIdentityKeyStore().setRetryingDecryption(true); try { content = dependencies.getCipher().decrypt(envelope); } catch (ProtocolUntrustedIdentityException e) { @@ -115,6 +116,8 @@ public final class IncomingMessageHandler { return new Pair<>(List.of(), exception); } catch (Exception e) { return new Pair<>(List.of(), e); + } finally { + account.getIdentityKeyStore().setRetryingDecryption(false); } } actions.addAll(checkAndHandleMessage(envelope, content, ignoreAttachments, handler, null)); diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/identities/IdentityKeyStore.java b/lib/src/main/java/org/asamk/signal/manager/storage/identities/IdentityKeyStore.java index d7b25d23..5a651edd 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/identities/IdentityKeyStore.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/identities/IdentityKeyStore.java @@ -43,6 +43,8 @@ public class IdentityKeyStore implements org.whispersystems.libsignal.state.Iden private final int localRegistrationId; private final TrustNewIdentity trustNewIdentity; + private boolean isRetryingDecryption = false; + public IdentityKeyStore( final File identitiesPath, final RecipientResolver resolver, @@ -75,6 +77,9 @@ public class IdentityKeyStore implements org.whispersystems.libsignal.state.Iden } public boolean saveIdentity(final RecipientId recipientId, final IdentityKey identityKey, Date added) { + if (isRetryingDecryption) { + return false; + } synchronized (cachedIdentities) { final var identityInfo = loadIdentityLocked(recipientId); if (identityInfo != null && identityInfo.getIdentityKey().equals(identityKey)) { @@ -92,13 +97,19 @@ public class IdentityKeyStore implements org.whispersystems.libsignal.state.Iden } } + public void setRetryingDecryption(final boolean retryingDecryption) { + isRetryingDecryption = retryingDecryption; + } + public boolean setIdentityTrustLevel( RecipientId recipientId, IdentityKey identityKey, TrustLevel trustLevel ) { synchronized (cachedIdentities) { final var identityInfo = loadIdentityLocked(recipientId); - if (identityInfo == null || !identityInfo.getIdentityKey().equals(identityKey)) { - // Identity not found, not updating the trust level + if (identityInfo == null + || !identityInfo.getIdentityKey().equals(identityKey) + || identityInfo.getTrustLevel() == trustLevel) { + // Identity not found or trust not changed, not updating the trust level return false; }