X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/6cb867cbebec69a7652fec0b9e6cb2860e99bcbf..7f64a9812ca5bb10e8f57cacf3d22b904bd200b4:/lib/src/main/java/org/asamk/signal/manager/ProvisioningManager.java diff --git a/lib/src/main/java/org/asamk/signal/manager/ProvisioningManager.java b/lib/src/main/java/org/asamk/signal/manager/ProvisioningManager.java index e813340e..80c214f7 100644 --- a/lib/src/main/java/org/asamk/signal/manager/ProvisioningManager.java +++ b/lib/src/main/java/org/asamk/signal/manager/ProvisioningManager.java @@ -20,6 +20,7 @@ import org.asamk.signal.manager.config.ServiceConfig; import org.asamk.signal.manager.config.ServiceEnvironment; import org.asamk.signal.manager.config.ServiceEnvironmentConfig; import org.asamk.signal.manager.storage.SignalAccount; +import org.asamk.signal.manager.storage.identities.TrustNewIdentity; import org.asamk.signal.manager.util.KeyUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,9 +30,8 @@ import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.groupsv2.ClientZkOperations; import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations; import org.whispersystems.signalservice.api.push.SignalServiceAddress; +import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException; import org.whispersystems.signalservice.api.util.DeviceNameUtil; -import org.whispersystems.signalservice.api.util.SleepTimer; -import org.whispersystems.signalservice.api.util.UptimeSleepTimer; import org.whispersystems.signalservice.internal.util.DynamicCredentialsProvider; import java.io.File; @@ -60,7 +60,6 @@ public class ProvisioningManager { tempIdentityKey = KeyUtils.generateIdentityKeyPair(); registrationId = KeyHelper.generateRegistrationId(false); password = KeyUtils.createPassword(); - final SleepTimer timer = new UptimeSleepTimer(); GroupsV2Operations groupsV2Operations; try { groupsV2Operations = new GroupsV2Operations(ClientZkOperations.create(serviceEnvironmentConfig.getSignalServiceConfiguration())); @@ -71,8 +70,7 @@ public class ProvisioningManager { new DynamicCredentialsProvider(null, null, password, SignalServiceAddress.DEFAULT_DEVICE_ID), userAgent, groupsV2Operations, - ServiceConfig.AUTOMATIC_NETWORK_RETRY, - timer); + ServiceConfig.AUTOMATIC_NETWORK_RETRY); } public static ProvisioningManager init( @@ -95,7 +93,9 @@ public class ProvisioningManager { var ret = accountManager.getNewDeviceRegistration(tempIdentityKey); var number = ret.getNumber(); - if (SignalAccount.userExists(pathConfig.getDataPath(), number)) { + logger.info("Received link information from {}, linking in progress ...", number); + + if (SignalAccount.userExists(pathConfig.getDataPath(), number) && !canRelinkExistingAccount(number)) { throw new UserAlreadyExists(number, SignalAccount.getFileName(pathConfig.getDataPath(), number)); } @@ -114,7 +114,7 @@ public class ProvisioningManager { SignalAccount account = null; try { - account = SignalAccount.createLinkedAccount(pathConfig.getDataPath(), + account = SignalAccount.createOrUpdateLinkedAccount(pathConfig.getDataPath(), number, ret.getUuid(), password, @@ -122,7 +122,8 @@ public class ProvisioningManager { deviceId, ret.getIdentity(), registrationId, - profileKey); + profileKey, + TrustNewIdentity.ON_FIRST_USE); Manager m = null; try { @@ -131,7 +132,7 @@ public class ProvisioningManager { try { m.refreshPreKeys(); } catch (Exception e) { - logger.error("Failed to refresh prekeys."); + logger.error("Failed to check new account state."); throw e; } @@ -158,4 +159,31 @@ public class ProvisioningManager { } } } + + private boolean canRelinkExistingAccount(final String number) throws IOException { + final SignalAccount signalAccount; + try { + signalAccount = SignalAccount.load(pathConfig.getDataPath(), number, false, TrustNewIdentity.ON_FIRST_USE); + } catch (IOException e) { + logger.debug("Account in use or failed to load.", e); + return false; + } + + try (signalAccount) { + if (signalAccount.isMasterDevice()) { + logger.debug("Account is a master device."); + return false; + } + + final var m = new Manager(signalAccount, pathConfig, serviceEnvironmentConfig, userAgent); + try (m) { + m.checkAccountState(); + } catch (AuthorizationFailedException ignored) { + return true; + } + + logger.debug("Account is still successfully linked."); + return false; + } + } }