From: AsamK Date: Mon, 16 Oct 2023 16:28:08 +0000 (+0200) Subject: Refactor creating linked account files X-Git-Tag: v0.12.3~7 X-Git-Url: https://git.nmode.ca/signal-cli/commitdiff_plain/400dcf28990e75f395b44b80c70279ae132e877b Refactor creating linked account files --- diff --git a/lib/src/main/java/org/asamk/signal/manager/SignalAccountFiles.java b/lib/src/main/java/org/asamk/signal/manager/SignalAccountFiles.java index da8a3f3a..ef160621 100644 --- a/lib/src/main/java/org/asamk/signal/manager/SignalAccountFiles.java +++ b/lib/src/main/java/org/asamk/signal/manager/SignalAccountFiles.java @@ -14,7 +14,6 @@ import org.asamk.signal.manager.internal.RegistrationManagerImpl; import org.asamk.signal.manager.storage.SignalAccount; import org.asamk.signal.manager.storage.accounts.AccountsStore; import org.asamk.signal.manager.util.KeyUtils; -import org.signal.libsignal.protocol.util.KeyHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.whispersystems.signalservice.api.push.exceptions.DeprecatedVersionException; @@ -160,8 +159,6 @@ public class SignalAccountFiles { final var newAccountPath = accountPath == null ? accountsStore.addAccount(number, null) : accountPath; var aciIdentityKey = KeyUtils.generateIdentityKeyPair(); var pniIdentityKey = KeyUtils.generateIdentityKeyPair(); - var registrationId = KeyHelper.generateRegistrationId(false); - var pniRegistrationId = KeyHelper.generateRegistrationId(false); var profileKey = KeyUtils.createProfileKey(); var account = SignalAccount.create(pathConfig.dataPath(), @@ -170,8 +167,6 @@ public class SignalAccountFiles { serviceEnvironment, aciIdentityKey, pniIdentityKey, - registrationId, - pniRegistrationId, profileKey, settings); diff --git a/lib/src/main/java/org/asamk/signal/manager/internal/ProvisioningManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/internal/ProvisioningManagerImpl.java index 405657b0..155756c9 100644 --- a/lib/src/main/java/org/asamk/signal/manager/internal/ProvisioningManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/internal/ProvisioningManagerImpl.java @@ -27,12 +27,12 @@ import org.asamk.signal.manager.storage.SignalAccount; import org.asamk.signal.manager.storage.accounts.AccountsStore; import org.asamk.signal.manager.util.KeyUtils; import org.signal.libsignal.protocol.IdentityKeyPair; -import org.signal.libsignal.protocol.util.KeyHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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.ServiceIdType; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException; import org.whispersystems.signalservice.api.util.DeviceNameUtil; @@ -59,8 +59,6 @@ public class ProvisioningManagerImpl implements ProvisioningManager { private final SignalServiceAccountManager accountManager; private final IdentityKeyPair tempIdentityKey; - private final int registrationId; - private final int pniRegistrationId; private final String password; public ProvisioningManagerImpl( @@ -77,8 +75,6 @@ public class ProvisioningManagerImpl implements ProvisioningManager { this.accountsStore = accountsStore; tempIdentityKey = KeyUtils.generateIdentityKeyPair(); - registrationId = KeyHelper.generateRegistrationId(false); - pniRegistrationId = KeyHelper.generateRegistrationId(false); password = KeyUtils.createPassword(); GroupsV2Operations groupsV2Operations; try { @@ -114,9 +110,9 @@ public class ProvisioningManagerImpl implements ProvisioningManager { if (accountPath == null) { accountPath = accountsStore.getPathByNumber(number); } - if (accountPath != null - && SignalAccount.accountFileExists(pathConfig.dataPath(), accountPath) - && !canRelinkExistingAccount(accountPath)) { + final var accountExists = accountPath != null && SignalAccount.accountFileExists(pathConfig.dataPath(), + accountPath); + if (accountExists && !canRelinkExistingAccount(accountPath)) { throw new UserAlreadyExistsException(number, SignalAccount.getFileName(pathConfig.dataPath(), accountPath)); } if (accountPath == null) { @@ -128,38 +124,42 @@ public class ProvisioningManagerImpl implements ProvisioningManager { var encryptedDeviceName = deviceName == null ? null : DeviceNameUtil.encryptDeviceName(deviceName, ret.getAciIdentity().getPrivateKey()); - - logger.debug("Finishing new device registration"); - var deviceId = accountManager.finishNewDeviceRegistration(ret.getProvisioningCode(), - new ConfirmCodeMessage(false, - true, - registrationId, - pniRegistrationId, - encryptedDeviceName, - getCapabilities(false))); - // Create new account with the synced identity var profileKey = ret.getProfileKey() == null ? KeyUtils.createProfileKey() : ret.getProfileKey(); SignalAccount account = null; try { - account = SignalAccount.createOrUpdateLinkedAccount(pathConfig.dataPath(), - accountPath, - number, - serviceEnvironmentConfig.type(), + if (!accountExists) { + account = SignalAccount.createLinkedAccount(pathConfig.dataPath(), + accountPath, + serviceEnvironmentConfig.type(), + Settings.DEFAULT); + } else { + account = SignalAccount.load(pathConfig.dataPath(), accountPath, true, Settings.DEFAULT); + } + + account.setProvisioningData(number, aci, pni, password, encryptedDeviceName, - deviceId, ret.getAciIdentity(), ret.getPniIdentity(), - registrationId, - pniRegistrationId, - profileKey, - Settings.DEFAULT); + profileKey); + account.getConfigurationStore().setReadReceipts(ret.isReadReceipts()); + logger.debug("Finishing new device registration"); + var deviceId = accountManager.finishNewDeviceRegistration(ret.getProvisioningCode(), + new ConfirmCodeMessage(false, + true, + account.getAccountData(ServiceIdType.ACI).getLocalRegistrationId(), + account.getAccountData(ServiceIdType.PNI).getLocalRegistrationId(), + encryptedDeviceName, + getCapabilities(false))); + + account.finishLinking(deviceId); + ManagerImpl m = null; try { m = new ManagerImpl(account, diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/SignalAccount.java b/lib/src/main/java/org/asamk/signal/manager/storage/SignalAccount.java index a51136a0..57300b11 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/SignalAccount.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/SignalAccount.java @@ -130,7 +130,7 @@ public class SignalAccount implements Closeable { private String number; private String username; private String encryptedDeviceName; - private int deviceId = SignalServiceAddress.DEFAULT_DEVICE_ID; + private int deviceId = 0; private String password; private String registrationLockPin; private MasterKey pinMasterKey; @@ -204,8 +204,6 @@ public class SignalAccount implements Closeable { ServiceEnvironment serviceEnvironment, IdentityKeyPair aciIdentityKey, IdentityKeyPair pniIdentityKey, - int registrationId, - int pniRegistrationId, ProfileKey profileKey, final Settings settings ) throws IOException { @@ -223,160 +221,91 @@ public class SignalAccount implements Closeable { signalAccount.serviceEnvironment = serviceEnvironment; signalAccount.profileKey = profileKey; signalAccount.password = KeyUtils.createPassword(); + signalAccount.deviceId = SignalServiceAddress.DEFAULT_DEVICE_ID; signalAccount.dataPath = dataPath; signalAccount.aciAccountData.setIdentityKeyPair(aciIdentityKey); signalAccount.pniAccountData.setIdentityKeyPair(pniIdentityKey); - signalAccount.aciAccountData.setLocalRegistrationId(registrationId); - signalAccount.pniAccountData.setLocalRegistrationId(pniRegistrationId); + signalAccount.aciAccountData.setLocalRegistrationId(KeyHelper.generateRegistrationId(false)); + signalAccount.pniAccountData.setLocalRegistrationId(KeyHelper.generateRegistrationId(false)); signalAccount.settings = settings; signalAccount.registered = false; signalAccount.previousStorageVersion = CURRENT_STORAGE_VERSION; signalAccount.migrateLegacyConfigs(); - signalAccount.clearAllPreKeys(); signalAccount.save(); return signalAccount; } - private static SignalAccount createLinkedAccount( - File dataPath, - String accountPath, - String number, - ServiceEnvironment serviceEnvironment, - ACI aci, - PNI pni, - String password, - String encryptedDeviceName, - int deviceId, - IdentityKeyPair aciIdentityKey, - IdentityKeyPair pniIdentityKey, - int registrationId, - int pniRegistrationId, - ProfileKey profileKey, + public static SignalAccount createLinkedAccount( + final File dataPath, + final String accountPath, + final ServiceEnvironment serviceEnvironment, final Settings settings ) throws IOException { + IOUtils.createPrivateDirectories(dataPath); var fileName = getFileName(dataPath, accountPath); IOUtils.createPrivateFile(fileName); final var pair = openFileChannel(fileName, true); - var signalAccount = new SignalAccount(pair.first(), pair.second()); + final var signalAccount = new SignalAccount(pair.first(), pair.second()); signalAccount.dataPath = dataPath; signalAccount.accountPath = accountPath; signalAccount.serviceEnvironment = serviceEnvironment; - signalAccount.aciAccountData.setLocalRegistrationId(registrationId); - signalAccount.pniAccountData.setLocalRegistrationId(pniRegistrationId); + signalAccount.aciAccountData.setLocalRegistrationId(KeyHelper.generateRegistrationId(false)); + signalAccount.pniAccountData.setLocalRegistrationId(KeyHelper.generateRegistrationId(false)); signalAccount.settings = settings; - signalAccount.setProvisioningData(number, - aci, - pni, - password, - encryptedDeviceName, - deviceId, - aciIdentityKey, - pniIdentityKey, - profileKey); - signalAccount.getRecipientTrustedResolver() - .resolveSelfRecipientTrusted(signalAccount.getSelfRecipientAddress()); signalAccount.previousStorageVersion = CURRENT_STORAGE_VERSION; - signalAccount.migrateLegacyConfigs(); - signalAccount.clearAllPreKeys(); - signalAccount.save(); - - return signalAccount; - } - public static SignalAccount createOrUpdateLinkedAccount( - File dataPath, - String accountPath, - String number, - ServiceEnvironment serviceEnvironment, - ACI aci, - PNI pni, - String password, - String encryptedDeviceName, - int deviceId, - IdentityKeyPair aciIdentityKey, - IdentityKeyPair pniIdentityKey, - int registrationId, - int pniRegistrationId, - ProfileKey profileKey, - final Settings settings - ) throws IOException { - IOUtils.createPrivateDirectories(dataPath); - var fileName = getFileName(dataPath, accountPath); - if (!fileName.exists()) { - return createLinkedAccount(dataPath, - accountPath, - number, - serviceEnvironment, - aci, - pni, - password, - encryptedDeviceName, - deviceId, - aciIdentityKey, - pniIdentityKey, - registrationId, - pniRegistrationId, - profileKey, - settings); - } - - final var signalAccount = load(dataPath, accountPath, true, settings); - signalAccount.setProvisioningData(number, - aci, - pni, - password, - encryptedDeviceName, - deviceId, - aciIdentityKey, - pniIdentityKey, - profileKey); - signalAccount.getRecipientTrustedResolver() - .resolveSelfRecipientTrusted(signalAccount.getSelfRecipientAddress()); - signalAccount.aciAccountData.getSessionStore().archiveAllSessions(); - signalAccount.pniAccountData.getSessionStore().archiveAllSessions(); - signalAccount.getSenderKeyStore().deleteAll(); - signalAccount.clearAllPreKeys(); return signalAccount; } - private void setProvisioningData( + public void setProvisioningData( final String number, final ACI aci, final PNI pni, final String password, final String encryptedDeviceName, - final int deviceId, final IdentityKeyPair aciIdentity, final IdentityKeyPair pniIdentity, final ProfileKey profileKey ) { + this.deviceId = 0; this.number = number; this.aciAccountData.setServiceId(aci); this.pniAccountData.setServiceId(pni); + getRecipientTrustedResolver().resolveSelfRecipientTrusted(getSelfRecipientAddress()); this.password = password; this.profileKey = profileKey; getProfileStore().storeSelfProfileKey(getSelfRecipientId(), getProfileKey()); this.encryptedDeviceName = encryptedDeviceName; - this.deviceId = deviceId; this.aciAccountData.setIdentityKeyPair(aciIdentity); this.pniAccountData.setIdentityKeyPair(pniIdentity); - this.registered = true; + this.registered = false; this.isMultiDevice = true; getKeyValueStore().storeEntry(lastReceiveTimestamp, 0L); this.pinMasterKey = null; getKeyValueStore().storeEntry(storageManifestVersion, -1L); this.setStorageManifest(null); this.storageKey = null; + getSenderKeyStore().deleteAll(); trustSelfIdentity(ServiceIdType.ACI); trustSelfIdentity(ServiceIdType.PNI); + aciAccountData.getSessionStore().archiveAllSessions(); + pniAccountData.getSessionStore().archiveAllSessions(); + clearAllPreKeys(); getKeyValueStore().storeEntry(lastRecipientsRefresh, null); + save(); + } + + public void finishLinking(final int deviceId) { + this.registered = true; + this.deviceId = deviceId; + save(); } public void finishRegistration( @@ -476,7 +405,7 @@ public class SignalAccount implements Closeable { return false; } var f = getFileName(dataPath, account); - return !(!f.exists() || f.isDirectory()); + return f.exists() && !f.isDirectory() && f.length() > 0L; } private void load(