From: AsamK Date: Mon, 21 Dec 2020 09:25:36 +0000 (+0100) Subject: Update libsignal X-Git-Tag: v0.8.0~16 X-Git-Url: https://git.nmode.ca/signal-cli/commitdiff_plain/644aacf59516dd1ecafc58878d287557f20dc112?ds=sidebyside Update libsignal --- diff --git a/CHANGELOG.md b/CHANGELOG.md index 9092711d..ef4d240b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog ## [Unreleased] +**Attention**: For all functionality an additional native library is now required: [libsignal-client](https://github.com/signalapp/libsignal-client/). +See https://github.com/AsamK/signal-cli/wiki/Provide-native-lib-for-libsignal for more information. ## [0.7.4] - 2021-01-19 ### Changed diff --git a/build.gradle b/build.gradle index 764ad99e..9eaf7b8a 100644 --- a/build.gradle +++ b/build.gradle @@ -17,7 +17,8 @@ repositories { } dependencies { - implementation 'com.github.turasa:signal-service-java:2.15.3_unofficial_17' + implementation 'com.google.protobuf:protobuf-javalite:3.10.0' + implementation 'com.github.turasa:signal-service-java:2.15.3_unofficial_18' implementation 'org.bouncycastle:bcprov-jdk15on:1.68' implementation 'net.sourceforge.argparse4j:argparse4j:0.8.1' implementation 'com.github.hypfvieh:dbus-java:3.2.4' diff --git a/src/main/java/org/asamk/signal/ReceiveMessageHandler.java b/src/main/java/org/asamk/signal/ReceiveMessageHandler.java index 0bb2e012..da1be271 100644 --- a/src/main/java/org/asamk/signal/ReceiveMessageHandler.java +++ b/src/main/java/org/asamk/signal/ReceiveMessageHandler.java @@ -318,6 +318,9 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler { if (receiptMessage.isReadReceipt()) { System.out.println(" - Is read receipt"); } + if (receiptMessage.isViewedReceipt()) { + System.out.println(" - Is viewed receipt"); + } System.out.println(" - Timestamps:"); for (long timestamp : receiptMessage.getTimestamps()) { System.out.println(" " + DateUtils.formatTimestamp(timestamp)); @@ -397,6 +400,11 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler { System.out.println(" Has signed group change: " + groupInfo.hasSignedGroupChange()); } } + if (message.getGroupCallUpdate().isPresent()) { + final SignalServiceDataMessage.GroupCallUpdate groupCallUpdate = message.getGroupCallUpdate().get(); + System.out.println("Group call update:"); + System.out.println(" - Era id: " + groupCallUpdate.getEraId()); + } if (message.getPreviews().isPresent()) { final List previews = message.getPreviews().get(); System.out.println("Previews:"); diff --git a/src/main/java/org/asamk/signal/manager/Manager.java b/src/main/java/org/asamk/signal/manager/Manager.java index 96dbe212..c4f32460 100644 --- a/src/main/java/org/asamk/signal/manager/Manager.java +++ b/src/main/java/org/asamk/signal/manager/Manager.java @@ -219,6 +219,7 @@ public class Manager implements Closeable { account.getDeviceId()), userAgent, groupsV2Operations, + ServiceConfig.AUTOMATIC_NETWORK_RETRY, timer); this.groupsV2Api = accountManager.getGroupsV2Api(); final KeyBackupService keyBackupService = ServiceConfig.createKeyBackupService(accountManager); @@ -234,7 +235,8 @@ public class Manager implements Closeable { userAgent, null, timer, - clientZkProfileOperations); + clientZkProfileOperations, + ServiceConfig.AUTOMATIC_NETWORK_RETRY); this.account.setResolver(this::resolveSignalServiceAddress); @@ -352,10 +354,19 @@ public class Manager implements Closeable { * if it's Optional.absent(), the avatar will be removed */ public void setProfile(String name, Optional avatar) throws IOException { + // TODO + String about = null; + String aboutEmoji = null; + try (final StreamDetails streamDetails = avatar == null ? avatarStore.retrieveProfileAvatar(getSelfAddress()) : avatar.isPresent() ? Utils.createStreamDetailsFromFile(avatar.get()) : null) { - accountManager.setVersionedProfile(account.getUuid(), account.getProfileKey(), name, streamDetails); + accountManager.setVersionedProfile(account.getUuid(), + account.getProfileKey(), + name, + about, + aboutEmoji, + streamDetails); } if (avatar != null) { @@ -378,6 +389,7 @@ public class Manager implements Closeable { // If this is the master device, other users can't send messages to this number anymore. // If this is a linked device, other users can still send messages, but this device doesn't receive them anymore. accountManager.setGcmId(Optional.absent()); + accountManager.deleteAccount(); account.setRegistered(false); account.save(); @@ -499,7 +511,8 @@ public class Manager implements Closeable { Optional.absent(), clientZkProfileOperations, executor, - ServiceConfig.MAX_ENVELOPE_SIZE); + ServiceConfig.MAX_ENVELOPE_SIZE, + ServiceConfig.AUTOMATIC_NETWORK_RETRY); } private SignalProfile getRecipientProfile( @@ -1250,7 +1263,7 @@ public class Manager implements Closeable { private Map getRegisteredUsers(final Set numbersMissingUuid) throws IOException { try { return accountManager.getRegisteredUsers(getIasKeyStore(), numbersMissingUuid, CDS_MRENCLAVE); - } catch (Quote.InvalidQuoteFormatException | UnauthenticatedQuoteException | SignatureException | UnauthenticatedResponseException e) { + } catch (Quote.InvalidQuoteFormatException | UnauthenticatedQuoteException | SignatureException | UnauthenticatedResponseException | InvalidKeyException e) { throw new IOException(e); } } @@ -1391,10 +1404,13 @@ public class Manager implements Closeable { if (e.getCause() instanceof org.whispersystems.libsignal.UntrustedIdentityException) { org.whispersystems.libsignal.UntrustedIdentityException identityException = (org.whispersystems.libsignal.UntrustedIdentityException) e .getCause(); - account.getSignalProtocolStore() - .saveIdentity(resolveSignalServiceAddress(identityException.getName()), - identityException.getUntrustedIdentity(), - TrustLevel.UNTRUSTED); + final IdentityKey untrustedIdentity = identityException.getUntrustedIdentity(); + if (untrustedIdentity != null) { + account.getSignalProtocolStore() + .saveIdentity(resolveSignalServiceAddress(identityException.getName()), + untrustedIdentity, + TrustLevel.UNTRUSTED); + } throw identityException; } throw new AssertionError(e); diff --git a/src/main/java/org/asamk/signal/manager/ProvisioningManager.java b/src/main/java/org/asamk/signal/manager/ProvisioningManager.java index 535cecc6..0c26cf77 100644 --- a/src/main/java/org/asamk/signal/manager/ProvisioningManager.java +++ b/src/main/java/org/asamk/signal/manager/ProvisioningManager.java @@ -70,6 +70,7 @@ public class ProvisioningManager { new DynamicCredentialsProvider(null, null, password, null, SignalServiceAddress.DEFAULT_DEVICE_ID), userAgent, groupsV2Operations, + ServiceConfig.AUTOMATIC_NETWORK_RETRY, timer); } diff --git a/src/main/java/org/asamk/signal/manager/RegistrationManager.java b/src/main/java/org/asamk/signal/manager/RegistrationManager.java index d6bf78b1..506948ba 100644 --- a/src/main/java/org/asamk/signal/manager/RegistrationManager.java +++ b/src/main/java/org/asamk/signal/manager/RegistrationManager.java @@ -70,7 +70,7 @@ public class RegistrationManager implements Closeable { account.getUsername(), account.getPassword(), account.getSignalingKey(), - SignalServiceAddress.DEFAULT_DEVICE_ID), userAgent, null, timer); + SignalServiceAddress.DEFAULT_DEVICE_ID), userAgent, null, ServiceConfig.AUTOMATIC_NETWORK_RETRY, timer); final KeyBackupService keyBackupService = ServiceConfig.createKeyBackupService(accountManager); this.pinHelper = new PinHelper(keyBackupService); } diff --git a/src/main/java/org/asamk/signal/manager/ServiceConfig.java b/src/main/java/org/asamk/signal/manager/ServiceConfig.java index b6d4f4fd..c68e5773 100644 --- a/src/main/java/org/asamk/signal/manager/ServiceConfig.java +++ b/src/main/java/org/asamk/signal/manager/ServiceConfig.java @@ -36,8 +36,9 @@ public class ServiceConfig { final static int PREKEY_MINIMUM_COUNT = 20; final static int PREKEY_BATCH_SIZE = 100; final static int MAX_ATTACHMENT_SIZE = 150 * 1024 * 1024; - final static int MAX_ENVELOPE_SIZE = 0; + final static long MAX_ENVELOPE_SIZE = 0; final static long AVATAR_DOWNLOAD_FAILSAFE_MAX_SIZE = 10 * 1024 * 1024; + final static boolean AUTOMATIC_NETWORK_RETRY = true; final static String CDS_MRENCLAVE = "c98e00a4e3ff977a56afefe7362a27e4961e4f19e211febfbb19b897e6b80b15"; diff --git a/src/main/java/org/asamk/signal/manager/helper/PinHelper.java b/src/main/java/org/asamk/signal/manager/helper/PinHelper.java index b4fa04c4..090b20b6 100644 --- a/src/main/java/org/asamk/signal/manager/helper/PinHelper.java +++ b/src/main/java/org/asamk/signal/manager/helper/PinHelper.java @@ -1,6 +1,7 @@ package org.asamk.signal.manager.helper; import org.asamk.signal.manager.util.PinHashing; +import org.whispersystems.libsignal.InvalidKeyException; import org.whispersystems.signalservice.api.KbsPinData; import org.whispersystems.signalservice.api.KeyBackupService; import org.whispersystems.signalservice.api.KeyBackupServicePinException; @@ -82,7 +83,7 @@ public class PinHelper { throw new AssertionError("Null not expected"); } return kbsData; - } catch (UnauthenticatedResponseException e) { + } catch (UnauthenticatedResponseException | InvalidKeyException e) { throw new IOException(e); } } diff --git a/src/main/java/org/asamk/signal/manager/storage/protocol/JsonIdentityKeyStore.java b/src/main/java/org/asamk/signal/manager/storage/protocol/JsonIdentityKeyStore.java index 28d64cbf..9f01b719 100644 --- a/src/main/java/org/asamk/signal/manager/storage/protocol/JsonIdentityKeyStore.java +++ b/src/main/java/org/asamk/signal/manager/storage/protocol/JsonIdentityKeyStore.java @@ -194,47 +194,43 @@ public class JsonIdentityKeyStore implements IdentityKeyStore { ) throws IOException { JsonNode node = jsonParser.getCodec().readTree(jsonParser); - try { - int localRegistrationId = node.get("registrationId").asInt(); - IdentityKeyPair identityKeyPair = new IdentityKeyPair(Base64.getDecoder() - .decode(node.get("identityKey").asText())); - - JsonIdentityKeyStore keyStore = new JsonIdentityKeyStore(identityKeyPair, localRegistrationId); - - JsonNode trustedKeysNode = node.get("trustedKeys"); - if (trustedKeysNode.isArray()) { - for (JsonNode trustedKey : trustedKeysNode) { - String trustedKeyName = trustedKey.hasNonNull("name") ? trustedKey.get("name").asText() : null; - - if (UuidUtil.isUuid(trustedKeyName)) { - // Ignore identities that were incorrectly created with UUIDs as name - continue; - } - - UUID uuid = trustedKey.hasNonNull("uuid") ? UuidUtil.parseOrNull(trustedKey.get("uuid") - .asText()) : null; - final SignalServiceAddress serviceAddress = uuid == null - ? Utils.getSignalServiceAddressFromIdentifier(trustedKeyName) - : new SignalServiceAddress(uuid, trustedKeyName); - try { - IdentityKey id = new IdentityKey(Base64.getDecoder() - .decode(trustedKey.get("identityKey").asText()), 0); - TrustLevel trustLevel = trustedKey.hasNonNull("trustLevel") - ? TrustLevel.fromInt(trustedKey.get("trustLevel").asInt()) - : TrustLevel.TRUSTED_UNVERIFIED; - Date added = trustedKey.hasNonNull("addedTimestamp") ? new Date(trustedKey.get( - "addedTimestamp").asLong()) : new Date(); - keyStore.saveIdentity(serviceAddress, id, trustLevel, added); - } catch (InvalidKeyException e) { - logger.warn("Error while decoding key for {}: {}", trustedKeyName, e.getMessage()); - } + int localRegistrationId = node.get("registrationId").asInt(); + IdentityKeyPair identityKeyPair = new IdentityKeyPair(Base64.getDecoder() + .decode(node.get("identityKey").asText())); + + JsonIdentityKeyStore keyStore = new JsonIdentityKeyStore(identityKeyPair, localRegistrationId); + + JsonNode trustedKeysNode = node.get("trustedKeys"); + if (trustedKeysNode.isArray()) { + for (JsonNode trustedKey : trustedKeysNode) { + String trustedKeyName = trustedKey.hasNonNull("name") ? trustedKey.get("name").asText() : null; + + if (UuidUtil.isUuid(trustedKeyName)) { + // Ignore identities that were incorrectly created with UUIDs as name + continue; } - } - return keyStore; - } catch (InvalidKeyException e) { - throw new IOException(e); + UUID uuid = trustedKey.hasNonNull("uuid") + ? UuidUtil.parseOrNull(trustedKey.get("uuid").asText()) + : null; + final SignalServiceAddress serviceAddress = uuid == null + ? Utils.getSignalServiceAddressFromIdentifier(trustedKeyName) + : new SignalServiceAddress(uuid, trustedKeyName); + try { + IdentityKey id = new IdentityKey(Base64.getDecoder() + .decode(trustedKey.get("identityKey").asText()), 0); + TrustLevel trustLevel = trustedKey.hasNonNull("trustLevel") ? TrustLevel.fromInt(trustedKey.get( + "trustLevel").asInt()) : TrustLevel.TRUSTED_UNVERIFIED; + Date added = trustedKey.hasNonNull("addedTimestamp") ? new Date(trustedKey.get("addedTimestamp") + .asLong()) : new Date(); + keyStore.saveIdentity(serviceAddress, id, trustLevel, added); + } catch (InvalidKeyException e) { + logger.warn("Error while decoding key for {}: {}", trustedKeyName, e.getMessage()); + } + } } + + return keyStore; } }