mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 10:30:38 +00:00
Update libsignal
This commit is contained in:
parent
b4311c7b76
commit
644aacf595
9 changed files with 72 additions and 46 deletions
|
@ -1,6 +1,8 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## [Unreleased]
|
## [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
|
## [0.7.4] - 2021-01-19
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
@ -17,7 +17,8 @@ repositories {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
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 'org.bouncycastle:bcprov-jdk15on:1.68'
|
||||||
implementation 'net.sourceforge.argparse4j:argparse4j:0.8.1'
|
implementation 'net.sourceforge.argparse4j:argparse4j:0.8.1'
|
||||||
implementation 'com.github.hypfvieh:dbus-java:3.2.4'
|
implementation 'com.github.hypfvieh:dbus-java:3.2.4'
|
||||||
|
|
|
@ -318,6 +318,9 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler {
|
||||||
if (receiptMessage.isReadReceipt()) {
|
if (receiptMessage.isReadReceipt()) {
|
||||||
System.out.println(" - Is read receipt");
|
System.out.println(" - Is read receipt");
|
||||||
}
|
}
|
||||||
|
if (receiptMessage.isViewedReceipt()) {
|
||||||
|
System.out.println(" - Is viewed receipt");
|
||||||
|
}
|
||||||
System.out.println(" - Timestamps:");
|
System.out.println(" - Timestamps:");
|
||||||
for (long timestamp : receiptMessage.getTimestamps()) {
|
for (long timestamp : receiptMessage.getTimestamps()) {
|
||||||
System.out.println(" " + DateUtils.formatTimestamp(timestamp));
|
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());
|
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()) {
|
if (message.getPreviews().isPresent()) {
|
||||||
final List<SignalServiceDataMessage.Preview> previews = message.getPreviews().get();
|
final List<SignalServiceDataMessage.Preview> previews = message.getPreviews().get();
|
||||||
System.out.println("Previews:");
|
System.out.println("Previews:");
|
||||||
|
|
|
@ -219,6 +219,7 @@ public class Manager implements Closeable {
|
||||||
account.getDeviceId()),
|
account.getDeviceId()),
|
||||||
userAgent,
|
userAgent,
|
||||||
groupsV2Operations,
|
groupsV2Operations,
|
||||||
|
ServiceConfig.AUTOMATIC_NETWORK_RETRY,
|
||||||
timer);
|
timer);
|
||||||
this.groupsV2Api = accountManager.getGroupsV2Api();
|
this.groupsV2Api = accountManager.getGroupsV2Api();
|
||||||
final KeyBackupService keyBackupService = ServiceConfig.createKeyBackupService(accountManager);
|
final KeyBackupService keyBackupService = ServiceConfig.createKeyBackupService(accountManager);
|
||||||
|
@ -234,7 +235,8 @@ public class Manager implements Closeable {
|
||||||
userAgent,
|
userAgent,
|
||||||
null,
|
null,
|
||||||
timer,
|
timer,
|
||||||
clientZkProfileOperations);
|
clientZkProfileOperations,
|
||||||
|
ServiceConfig.AUTOMATIC_NETWORK_RETRY);
|
||||||
|
|
||||||
this.account.setResolver(this::resolveSignalServiceAddress);
|
this.account.setResolver(this::resolveSignalServiceAddress);
|
||||||
|
|
||||||
|
@ -352,10 +354,19 @@ public class Manager implements Closeable {
|
||||||
* if it's Optional.absent(), the avatar will be removed
|
* if it's Optional.absent(), the avatar will be removed
|
||||||
*/
|
*/
|
||||||
public void setProfile(String name, Optional<File> avatar) throws IOException {
|
public void setProfile(String name, Optional<File> avatar) throws IOException {
|
||||||
|
// TODO
|
||||||
|
String about = null;
|
||||||
|
String aboutEmoji = null;
|
||||||
|
|
||||||
try (final StreamDetails streamDetails = avatar == null
|
try (final StreamDetails streamDetails = avatar == null
|
||||||
? avatarStore.retrieveProfileAvatar(getSelfAddress())
|
? avatarStore.retrieveProfileAvatar(getSelfAddress())
|
||||||
: avatar.isPresent() ? Utils.createStreamDetailsFromFile(avatar.get()) : null) {
|
: 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) {
|
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 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.
|
// 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.setGcmId(Optional.absent());
|
||||||
|
accountManager.deleteAccount();
|
||||||
|
|
||||||
account.setRegistered(false);
|
account.setRegistered(false);
|
||||||
account.save();
|
account.save();
|
||||||
|
@ -499,7 +511,8 @@ public class Manager implements Closeable {
|
||||||
Optional.absent(),
|
Optional.absent(),
|
||||||
clientZkProfileOperations,
|
clientZkProfileOperations,
|
||||||
executor,
|
executor,
|
||||||
ServiceConfig.MAX_ENVELOPE_SIZE);
|
ServiceConfig.MAX_ENVELOPE_SIZE,
|
||||||
|
ServiceConfig.AUTOMATIC_NETWORK_RETRY);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SignalProfile getRecipientProfile(
|
private SignalProfile getRecipientProfile(
|
||||||
|
@ -1250,7 +1263,7 @@ public class Manager implements Closeable {
|
||||||
private Map<String, UUID> getRegisteredUsers(final Set<String> numbersMissingUuid) throws IOException {
|
private Map<String, UUID> getRegisteredUsers(final Set<String> numbersMissingUuid) throws IOException {
|
||||||
try {
|
try {
|
||||||
return accountManager.getRegisteredUsers(getIasKeyStore(), numbersMissingUuid, CDS_MRENCLAVE);
|
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);
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1391,10 +1404,13 @@ public class Manager implements Closeable {
|
||||||
if (e.getCause() instanceof org.whispersystems.libsignal.UntrustedIdentityException) {
|
if (e.getCause() instanceof org.whispersystems.libsignal.UntrustedIdentityException) {
|
||||||
org.whispersystems.libsignal.UntrustedIdentityException identityException = (org.whispersystems.libsignal.UntrustedIdentityException) e
|
org.whispersystems.libsignal.UntrustedIdentityException identityException = (org.whispersystems.libsignal.UntrustedIdentityException) e
|
||||||
.getCause();
|
.getCause();
|
||||||
account.getSignalProtocolStore()
|
final IdentityKey untrustedIdentity = identityException.getUntrustedIdentity();
|
||||||
.saveIdentity(resolveSignalServiceAddress(identityException.getName()),
|
if (untrustedIdentity != null) {
|
||||||
identityException.getUntrustedIdentity(),
|
account.getSignalProtocolStore()
|
||||||
TrustLevel.UNTRUSTED);
|
.saveIdentity(resolveSignalServiceAddress(identityException.getName()),
|
||||||
|
untrustedIdentity,
|
||||||
|
TrustLevel.UNTRUSTED);
|
||||||
|
}
|
||||||
throw identityException;
|
throw identityException;
|
||||||
}
|
}
|
||||||
throw new AssertionError(e);
|
throw new AssertionError(e);
|
||||||
|
|
|
@ -70,6 +70,7 @@ public class ProvisioningManager {
|
||||||
new DynamicCredentialsProvider(null, null, password, null, SignalServiceAddress.DEFAULT_DEVICE_ID),
|
new DynamicCredentialsProvider(null, null, password, null, SignalServiceAddress.DEFAULT_DEVICE_ID),
|
||||||
userAgent,
|
userAgent,
|
||||||
groupsV2Operations,
|
groupsV2Operations,
|
||||||
|
ServiceConfig.AUTOMATIC_NETWORK_RETRY,
|
||||||
timer);
|
timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ public class RegistrationManager implements Closeable {
|
||||||
account.getUsername(),
|
account.getUsername(),
|
||||||
account.getPassword(),
|
account.getPassword(),
|
||||||
account.getSignalingKey(),
|
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);
|
final KeyBackupService keyBackupService = ServiceConfig.createKeyBackupService(accountManager);
|
||||||
this.pinHelper = new PinHelper(keyBackupService);
|
this.pinHelper = new PinHelper(keyBackupService);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,8 +36,9 @@ public class ServiceConfig {
|
||||||
final static int PREKEY_MINIMUM_COUNT = 20;
|
final static int PREKEY_MINIMUM_COUNT = 20;
|
||||||
final static int PREKEY_BATCH_SIZE = 100;
|
final static int PREKEY_BATCH_SIZE = 100;
|
||||||
final static int MAX_ATTACHMENT_SIZE = 150 * 1024 * 1024;
|
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 long AVATAR_DOWNLOAD_FAILSAFE_MAX_SIZE = 10 * 1024 * 1024;
|
||||||
|
final static boolean AUTOMATIC_NETWORK_RETRY = true;
|
||||||
|
|
||||||
final static String CDS_MRENCLAVE = "c98e00a4e3ff977a56afefe7362a27e4961e4f19e211febfbb19b897e6b80b15";
|
final static String CDS_MRENCLAVE = "c98e00a4e3ff977a56afefe7362a27e4961e4f19e211febfbb19b897e6b80b15";
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.asamk.signal.manager.helper;
|
package org.asamk.signal.manager.helper;
|
||||||
|
|
||||||
import org.asamk.signal.manager.util.PinHashing;
|
import org.asamk.signal.manager.util.PinHashing;
|
||||||
|
import org.whispersystems.libsignal.InvalidKeyException;
|
||||||
import org.whispersystems.signalservice.api.KbsPinData;
|
import org.whispersystems.signalservice.api.KbsPinData;
|
||||||
import org.whispersystems.signalservice.api.KeyBackupService;
|
import org.whispersystems.signalservice.api.KeyBackupService;
|
||||||
import org.whispersystems.signalservice.api.KeyBackupServicePinException;
|
import org.whispersystems.signalservice.api.KeyBackupServicePinException;
|
||||||
|
@ -82,7 +83,7 @@ public class PinHelper {
|
||||||
throw new AssertionError("Null not expected");
|
throw new AssertionError("Null not expected");
|
||||||
}
|
}
|
||||||
return kbsData;
|
return kbsData;
|
||||||
} catch (UnauthenticatedResponseException e) {
|
} catch (UnauthenticatedResponseException | InvalidKeyException e) {
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,47 +194,43 @@ public class JsonIdentityKeyStore implements IdentityKeyStore {
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
JsonNode node = jsonParser.getCodec().readTree(jsonParser);
|
JsonNode node = jsonParser.getCodec().readTree(jsonParser);
|
||||||
|
|
||||||
try {
|
int localRegistrationId = node.get("registrationId").asInt();
|
||||||
int localRegistrationId = node.get("registrationId").asInt();
|
IdentityKeyPair identityKeyPair = new IdentityKeyPair(Base64.getDecoder()
|
||||||
IdentityKeyPair identityKeyPair = new IdentityKeyPair(Base64.getDecoder()
|
.decode(node.get("identityKey").asText()));
|
||||||
.decode(node.get("identityKey").asText()));
|
|
||||||
|
|
||||||
JsonIdentityKeyStore keyStore = new JsonIdentityKeyStore(identityKeyPair, localRegistrationId);
|
JsonIdentityKeyStore keyStore = new JsonIdentityKeyStore(identityKeyPair, localRegistrationId);
|
||||||
|
|
||||||
JsonNode trustedKeysNode = node.get("trustedKeys");
|
JsonNode trustedKeysNode = node.get("trustedKeys");
|
||||||
if (trustedKeysNode.isArray()) {
|
if (trustedKeysNode.isArray()) {
|
||||||
for (JsonNode trustedKey : trustedKeysNode) {
|
for (JsonNode trustedKey : trustedKeysNode) {
|
||||||
String trustedKeyName = trustedKey.hasNonNull("name") ? trustedKey.get("name").asText() : null;
|
String trustedKeyName = trustedKey.hasNonNull("name") ? trustedKey.get("name").asText() : null;
|
||||||
|
|
||||||
if (UuidUtil.isUuid(trustedKeyName)) {
|
if (UuidUtil.isUuid(trustedKeyName)) {
|
||||||
// Ignore identities that were incorrectly created with UUIDs as name
|
// Ignore identities that were incorrectly created with UUIDs as name
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
UUID uuid = trustedKey.hasNonNull("uuid") ? UuidUtil.parseOrNull(trustedKey.get("uuid")
|
UUID uuid = trustedKey.hasNonNull("uuid")
|
||||||
.asText()) : null;
|
? UuidUtil.parseOrNull(trustedKey.get("uuid").asText())
|
||||||
final SignalServiceAddress serviceAddress = uuid == null
|
: null;
|
||||||
? Utils.getSignalServiceAddressFromIdentifier(trustedKeyName)
|
final SignalServiceAddress serviceAddress = uuid == null
|
||||||
: new SignalServiceAddress(uuid, trustedKeyName);
|
? Utils.getSignalServiceAddressFromIdentifier(trustedKeyName)
|
||||||
try {
|
: new SignalServiceAddress(uuid, trustedKeyName);
|
||||||
IdentityKey id = new IdentityKey(Base64.getDecoder()
|
try {
|
||||||
.decode(trustedKey.get("identityKey").asText()), 0);
|
IdentityKey id = new IdentityKey(Base64.getDecoder()
|
||||||
TrustLevel trustLevel = trustedKey.hasNonNull("trustLevel")
|
.decode(trustedKey.get("identityKey").asText()), 0);
|
||||||
? TrustLevel.fromInt(trustedKey.get("trustLevel").asInt())
|
TrustLevel trustLevel = trustedKey.hasNonNull("trustLevel") ? TrustLevel.fromInt(trustedKey.get(
|
||||||
: TrustLevel.TRUSTED_UNVERIFIED;
|
"trustLevel").asInt()) : TrustLevel.TRUSTED_UNVERIFIED;
|
||||||
Date added = trustedKey.hasNonNull("addedTimestamp") ? new Date(trustedKey.get(
|
Date added = trustedKey.hasNonNull("addedTimestamp") ? new Date(trustedKey.get("addedTimestamp")
|
||||||
"addedTimestamp").asLong()) : new Date();
|
.asLong()) : new Date();
|
||||||
keyStore.saveIdentity(serviceAddress, id, trustLevel, added);
|
keyStore.saveIdentity(serviceAddress, id, trustLevel, added);
|
||||||
} catch (InvalidKeyException e) {
|
} catch (InvalidKeyException e) {
|
||||||
logger.warn("Error while decoding key for {}: {}", trustedKeyName, e.getMessage());
|
logger.warn("Error while decoding key for {}: {}", trustedKeyName, e.getMessage());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return keyStore;
|
|
||||||
} catch (InvalidKeyException e) {
|
|
||||||
throw new IOException(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return keyStore;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue