X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/de273586b4106171a3940ce5ec2c2b3712430c8c..afb22deadaa4c8058db65af7e65b242568319bf6:/lib/src/main/java/org/asamk/signal/manager/Manager.java diff --git a/lib/src/main/java/org/asamk/signal/manager/Manager.java b/lib/src/main/java/org/asamk/signal/manager/Manager.java index caedf2f1..c1189df3 100644 --- a/lib/src/main/java/org/asamk/signal/manager/Manager.java +++ b/lib/src/main/java/org/asamk/signal/manager/Manager.java @@ -156,6 +156,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.function.Function; import java.util.stream.Collectors; import static org.asamk.signal.manager.config.ServiceConfig.capabilities; @@ -262,7 +263,7 @@ public class Manager implements Closeable { } private IdentityKeyPair getIdentityKeyPair() { - return account.getSignalProtocolStore().getIdentityKeyPair(); + return account.getIdentityKeyPair(); } public int getDeviceId() { @@ -335,7 +336,7 @@ public class Manager implements Closeable { public void updateAccountAttributes() throws IOException { accountManager.setAccountAttributes(null, - account.getSignalProtocolStore().getLocalRegistrationId(), + account.getLocalRegistrationId(), true, // set legacy pin only if no KBS master key is set account.getPinMasterKey() == null ? account.getRegistrationLockPin() : null, @@ -481,7 +482,6 @@ public class Manager implements Closeable { var records = KeyUtils.generatePreKeyRecords(offset, ServiceConfig.PREKEY_BATCH_SIZE); account.addPreKeys(records); - account.save(); return records; } @@ -491,7 +491,6 @@ public class Manager implements Closeable { var record = KeyUtils.generateSignedPreKeyRecord(identityKeyPair, signedPreKeyId); account.addSignedPreKey(record); - account.save(); return record; } @@ -528,7 +527,7 @@ public class Manager implements Closeable { ServiceConfig.AUTOMATIC_NETWORK_RETRY); } - private SignalProfile getRecipientProfile( + public SignalProfile getRecipientProfile( SignalServiceAddress address ) { return getRecipientProfile(address, false); @@ -991,6 +990,22 @@ public class Manager implements Closeable { return sendSelfMessage(messageBuilder); } + public Pair> sendRemoteDeleteMessage( + long targetSentTimestamp, List recipients + ) throws IOException, InvalidNumberException { + var delete = new SignalServiceDataMessage.RemoteDelete(targetSentTimestamp); + final var messageBuilder = SignalServiceDataMessage.newBuilder().withRemoteDelete(delete); + return sendMessage(messageBuilder, getSignalServiceAddresses(recipients)); + } + + public Pair> sendGroupRemoteDeleteMessage( + long targetSentTimestamp, GroupId groupId + ) throws IOException, NotAGroupMemberException, GroupNotFoundException { + var delete = new SignalServiceDataMessage.RemoteDelete(targetSentTimestamp); + final var messageBuilder = SignalServiceDataMessage.newBuilder().withRemoteDelete(delete); + return sendGroupMessage(messageBuilder, groupId); + } + public Pair> sendMessageReaction( String emoji, boolean remove, String targetAuthor, long targetSentTimestamp, List recipients ) throws IOException, InvalidNumberException { @@ -1211,10 +1226,12 @@ public class Manager implements Closeable { try { messageSender.sendMessage(message, unidentifiedAccessHelper.getAccessForSync()); } catch (UntrustedIdentityException e) { - account.getSignalProtocolStore() - .saveIdentity(resolveSignalServiceAddress(e.getIdentifier()), - e.getIdentityKey(), - TrustLevel.UNTRUSTED); + if (e.getIdentityKey() != null) { + account.getSignalProtocolStore() + .saveIdentity(resolveSignalServiceAddress(e.getIdentifier()), + e.getIdentityKey(), + TrustLevel.UNTRUSTED); + } throw e; } } @@ -1296,10 +1313,12 @@ public class Manager implements Closeable { } return new Pair<>(timestamp, result); } catch (UntrustedIdentityException e) { - account.getSignalProtocolStore() - .saveIdentity(resolveSignalServiceAddress(e.getIdentifier()), - e.getIdentityKey(), - TrustLevel.UNTRUSTED); + if (e.getIdentityKey() != null) { + account.getSignalProtocolStore() + .saveIdentity(resolveSignalServiceAddress(e.getIdentifier()), + e.getIdentityKey(), + TrustLevel.UNTRUSTED); + } return new Pair<>(timestamp, List.of()); } } else { @@ -1369,10 +1388,12 @@ public class Manager implements Closeable { false, System.currentTimeMillis() - startTime); } catch (UntrustedIdentityException e) { - account.getSignalProtocolStore() - .saveIdentity(resolveSignalServiceAddress(e.getIdentifier()), - e.getIdentityKey(), - TrustLevel.UNTRUSTED); + if (e.getIdentityKey() != null) { + account.getSignalProtocolStore() + .saveIdentity(resolveSignalServiceAddress(e.getIdentifier()), + e.getIdentityKey(), + TrustLevel.UNTRUSTED); + } return SendMessageResult.identityFailure(recipient, e.getIdentityKey()); } } @@ -1385,10 +1406,12 @@ public class Manager implements Closeable { try { return messageSender.sendMessage(address, unidentifiedAccessHelper.getAccessFor(address), message); } catch (UntrustedIdentityException e) { - account.getSignalProtocolStore() - .saveIdentity(resolveSignalServiceAddress(e.getIdentifier()), - e.getIdentityKey(), - TrustLevel.UNTRUSTED); + if (e.getIdentityKey() != null) { + account.getSignalProtocolStore() + .saveIdentity(resolveSignalServiceAddress(e.getIdentifier()), + e.getIdentityKey(), + TrustLevel.UNTRUSTED); + } return SendMessageResult.identityFailure(address, e.getIdentityKey()); } } @@ -1416,7 +1439,7 @@ public class Manager implements Closeable { } private void handleEndSession(SignalServiceAddress source) { - account.getSignalProtocolStore().deleteAllSessions(source); + account.getSessionStore().deleteAllSessions(source.getIdentifier()); } private List handleSignalServiceDataMessage( @@ -2356,9 +2379,8 @@ public class Manager implements Closeable { final var profileEntry = account.getProfileStore().getProfileEntry(address); if (profileEntry != null && profileEntry.getProfile() != null) { - return profileEntry.getProfile().getName(); + return profileEntry.getProfile().getDisplayName(); } - return null; } @@ -2388,26 +2410,7 @@ public class Manager implements Closeable { */ public boolean trustIdentityVerified(String name, byte[] fingerprint) throws InvalidNumberException { var address = canonicalizeAndResolveSignalServiceAddress(name); - var ids = account.getSignalProtocolStore().getIdentities(address); - if (ids == null) { - return false; - } - for (var id : ids) { - if (!Arrays.equals(id.getIdentityKey().serialize(), fingerprint)) { - continue; - } - - account.getSignalProtocolStore() - .setIdentityTrustLevel(address, id.getIdentityKey(), TrustLevel.TRUSTED_VERIFIED); - try { - sendVerifiedMessage(address, id.getIdentityKey(), TrustLevel.TRUSTED_VERIFIED); - } catch (IOException | UntrustedIdentityException e) { - logger.warn("Failed to send verification sync message: {}", e.getMessage()); - } - account.save(); - return true; - } - return false; + return trustIdentity(address, (identityKey) -> Arrays.equals(identityKey.serialize(), fingerprint)); } /** @@ -2418,26 +2421,46 @@ public class Manager implements Closeable { */ public boolean trustIdentityVerifiedSafetyNumber(String name, String safetyNumber) throws InvalidNumberException { var address = canonicalizeAndResolveSignalServiceAddress(name); + return trustIdentity(address, (identityKey) -> safetyNumber.equals(computeSafetyNumber(address, identityKey))); + } + + private boolean trustIdentity(SignalServiceAddress address, Function verifier) { var ids = account.getSignalProtocolStore().getIdentities(address); if (ids == null) { return false; } + + IdentityInfo foundIdentity = null; + for (var id : ids) { - if (!safetyNumber.equals(computeSafetyNumber(address, id.getIdentityKey()))) { - continue; + if (verifier.apply(id.getIdentityKey())) { + foundIdentity = id; + break; } + } - account.getSignalProtocolStore() - .setIdentityTrustLevel(address, id.getIdentityKey(), TrustLevel.TRUSTED_VERIFIED); - try { - sendVerifiedMessage(address, id.getIdentityKey(), TrustLevel.TRUSTED_VERIFIED); - } catch (IOException | UntrustedIdentityException e) { - logger.warn("Failed to send verification sync message: {}", e.getMessage()); + if (foundIdentity == null) { + return false; + } + + account.getSignalProtocolStore() + .setIdentityTrustLevel(address, foundIdentity.getIdentityKey(), TrustLevel.TRUSTED_VERIFIED); + try { + sendVerifiedMessage(address, foundIdentity.getIdentityKey(), TrustLevel.TRUSTED_VERIFIED); + } catch (IOException | UntrustedIdentityException e) { + logger.warn("Failed to send verification sync message: {}", e.getMessage()); + } + + // Successfully trusted the new identity, now remove all other identities for that number + for (var id : ids) { + if (id == foundIdentity) { + continue; } - account.save(); - return true; + account.getSignalProtocolStore().removeIdentity(address, id.getIdentityKey()); } - return false; + + account.save(); + return true; } /**