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;
private final SignalServiceAccountManager accountManager;
private final IdentityKeyPair tempIdentityKey;
- private final int registrationId;
- private final int pniRegistrationId;
private final String password;
public ProvisioningManagerImpl(
this.accountsStore = accountsStore;
tempIdentityKey = KeyUtils.generateIdentityKeyPair();
- registrationId = KeyHelper.generateRegistrationId(false);
- pniRegistrationId = KeyHelper.generateRegistrationId(false);
password = KeyUtils.createPassword();
GroupsV2Operations groupsV2Operations;
try {
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) {
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,
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;
ServiceEnvironment serviceEnvironment,
IdentityKeyPair aciIdentityKey,
IdentityKeyPair pniIdentityKey,
- int registrationId,
- int pniRegistrationId,
ProfileKey profileKey,
final Settings settings
) throws IOException {
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(
return false;
}
var f = getFileName(dataPath, account);
- return !(!f.exists() || f.isDirectory());
+ return f.exists() && !f.isDirectory() && f.length() > 0L;
}
private void load(