public void checkAccountState() throws IOException {
if (accountManager.getPreKeysCount() < ServiceConfig.PREKEY_MINIMUM_COUNT) {
refreshPreKeys();
- account.save();
}
if (account.getUuid() == null) {
account.setUuid(accountManager.getOwnUuid());
- account.save();
}
updateAccountAttributes();
}
accountManager.deleteAccount();
account.setRegistered(false);
- account.save();
}
public List<DeviceInfo> getLinkedDevices() throws IOException {
var devices = accountManager.getDevices();
account.setMultiDevice(devices.size() > 1);
- account.save();
return devices;
}
accountManager.removeDevice(deviceId);
var devices = accountManager.getDevices();
account.setMultiDevice(devices.size() > 1);
- account.save();
}
public void addDeviceLink(URI linkUri) throws IOException, InvalidKeyException {
Optional.of(account.getProfileKey().serialize()),
verificationCode);
account.setMultiDevice(true);
- account.save();
}
public void setRegistrationLockPin(Optional<String> pin) throws IOException, UnauthenticatedResponseException {
pinHelper.setRegistrationLockPin(pin.get(), masterKey);
- account.setRegistrationLockPin(pin.get());
- account.setPinMasterKey(masterKey);
+ account.setRegistrationLockPin(pin.get(), masterKey);
} else {
// Remove legacy registration lock
accountManager.removeRegistrationLockV1();
// Remove KBS Pin
pinHelper.removeRegistrationLockPin();
- account.setRegistrationLockPin(null);
- account.setPinMasterKey(null);
+ account.setRegistrationLockPin(null, null);
}
- account.save();
}
void refreshPreKeys() throws IOException {
for (var address : signalServiceAddresses) {
handleEndSession(address);
}
- account.save();
throw e;
}
}
var contact = account.getContactStore().getContact(recipientId);
final var builder = contact == null ? Contact.newBuilder() : Contact.newBuilder(contact);
account.getContactStore().storeContact(recipientId, builder.withName(name).build());
- account.save();
}
public void setContactBlocked(String number, boolean blocked) throws InvalidNumberException {
var contact = account.getContactStore().getContact(recipientId);
final var builder = contact == null ? Contact.newBuilder() : Contact.newBuilder(contact);
account.getContactStore().storeContact(recipientId, builder.withBlocked(blocked).build());
- account.save();
}
public void setGroupBlocked(final GroupId groupId, final boolean blocked) throws GroupNotFoundException {
group.setBlocked(blocked);
account.getGroupStore().updateGroup(group);
- account.save();
}
private void setExpirationTimer(RecipientId recipientId, int messageExpirationTimer) {
var recipientId = canonicalizeAndResolveRecipient(number);
setExpirationTimer(recipientId, messageExpirationTimer);
sendExpirationTimerUpdate(recipientId);
- account.save();
}
/**
var sticker = new Sticker(StickerPackId.deserialize(Hex.fromStringCondensed(packId)), packKey);
account.getStickerStore().updateSticker(sticker);
- account.save();
try {
return new URI("https",
handleEndSession(recipient);
}
}
- account.save();
}
}
messageBuilder.withTimestamp(timestamp);
getOrCreateMessagePipe();
getOrCreateUnidentifiedMessagePipe();
- try {
- final var recipientId = account.getSelfRecipientId();
+ final var recipientId = account.getSelfRecipientId();
- final var contact = account.getContactStore().getContact(recipientId);
- final var expirationTime = contact != null ? contact.getMessageExpirationTime() : 0;
- messageBuilder.withExpiration(expirationTime);
+ final var contact = account.getContactStore().getContact(recipientId);
+ final var expirationTime = contact != null ? contact.getMessageExpirationTime() : 0;
+ messageBuilder.withExpiration(expirationTime);
- var message = messageBuilder.build();
- final var result = sendSelfMessage(message);
- return new Pair<>(timestamp, result);
- } finally {
- account.save();
- }
+ var message = messageBuilder.build();
+ final var result = sendSelfMessage(message);
+ return new Pair<>(timestamp, result);
}
private SendMessageResult sendSelfMessage(SignalServiceDataMessage message) throws IOException {
}
actions = handleMessage(envelope, content, ignoreAttachments);
}
- account.save();
handler.handleMessage(envelope, content, null);
cachedMessage.delete();
return actions;
logger.warn("Message action failed.", e);
}
}
- account.save();
queuedActions.clear();
queuedActions = null;
}
queuedActions.addAll(actions);
}
}
- account.save();
if (isMessageBlocked(envelope, content)) {
logger.info("Ignoring a message from blocked user/group: {}", envelope.getTimestamp());
} else if (notAGroupMember) {
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.kbs.MasterKey;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.util.SleepTimer;
import org.whispersystems.signalservice.api.util.UptimeSleepTimer;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
-import java.util.Date;
import java.util.Locale;
public class RegistrationManager implements Closeable {
identityKey,
registrationId,
profileKey);
- account.save();
return new RegistrationManager(account, pathConfig, serviceConfiguration, userAgent);
}
}
public void register(boolean voiceVerification, String captcha) throws IOException {
- if (account.getPassword() == null) {
- account.setPassword(KeyUtils.createPassword());
- }
-
if (voiceVerification) {
accountManager.requestVoiceVerificationCode(Locale.getDefault(),
Optional.fromNullable(captcha),
} else {
accountManager.requestSmsVerificationCode(false, Optional.fromNullable(captcha), Optional.absent());
}
-
- account.save();
}
public Manager verifyAccount(
) throws IOException, KeyBackupSystemNoDataException, KeyBackupServicePinException {
verificationCode = verificationCode.replace("-", "");
VerifyAccountResponse response;
+ MasterKey masterKey;
try {
response = verifyAccountWithCode(verificationCode, pin, null);
- account.setPinMasterKey(null);
+
+ masterKey = null;
} catch (LockedException e) {
if (pin == null) {
throw e;
} catch (LockedException _e) {
throw new AssertionError("KBS Pin appeared to matched but reg lock still failed!");
}
- account.setPinMasterKey(registrationLockData.getMasterKey());
+ masterKey = registrationLockData.getMasterKey();
}
// TODO response.isStorageCapable()
//accountManager.setGcmId(Optional.of(GoogleCloudMessaging.getInstance(this).register(REGISTRATION_ID)));
-
- account.setDeviceId(SignalServiceAddress.DEFAULT_DEVICE_ID);
- account.setMultiDevice(false);
- account.setRegistered(true);
- account.setUuid(UuidUtil.parseOrNull(response.getUuid()));
- account.setRegistrationLockPin(pin);
- account.getSessionStore().archiveAllSessions();
- final var recipientId = account.getRecipientStore().resolveRecipientTrusted(account.getSelfAddress());
- final var publicKey = account.getIdentityKeyPair().getPublicKey();
- account.getIdentityKeyStore().saveIdentity(recipientId, publicKey, new Date());
- account.getIdentityKeyStore().setIdentityTrustLevel(recipientId, publicKey, TrustLevel.TRUSTED_VERIFIED);
+ account.finishRegistration(UuidUtil.parseOrNull(response.getUuid()), masterKey, pin);
Manager m = null;
try {
m = new Manager(account, pathConfig, serviceEnvironmentConfig, userAgent);
+ account = null;
m.refreshPreKeys();
- account.save();
-
final var result = m;
- account = null;
m = null;
return result;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
+import org.asamk.signal.manager.TrustLevel;
import org.asamk.signal.manager.groups.GroupId;
import org.asamk.signal.manager.storage.contacts.ContactsStore;
import org.asamk.signal.manager.storage.contacts.LegacyJsonContactsStore;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.Base64;
+import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.UUID;
account.registered = false;
account.migrateLegacyConfigs();
+ account.save();
return account;
}
account.recipientStore.resolveRecipientTrusted(account.getSelfAddress());
account.migrateLegacyConfigs();
+ account.save();
return account;
}
- public void migrateLegacyConfigs() {
+ private void migrateLegacyConfigs() {
+ if (getPassword() == null) {
+ setPassword(KeyUtils.createPassword());
+ }
+
if (getProfileKey() == null && isRegistered()) {
// Old config file, creating new profile key
setProfileKey(KeyUtils.createProfileKey());
- save();
}
// Ensure our profile key is stored in profile store
getProfileStore().storeProfileKey(getSelfRecipientId(), getProfileKey());
return new File(dataPath, username + ".d");
}
- public static File getMessageCachePath(File dataPath, String username) {
+ private static File getMessageCachePath(File dataPath, String username) {
return new File(getUserPath(dataPath, username), "msg-cache");
}
}
}
+ var migratedLegacyConfig = false;
final var legacySignalProtocolStore = rootNode.hasNonNull("axolotlStore")
? jsonProcessor.convertValue(Utils.getNotNullNode(rootNode, "axolotlStore"),
LegacyJsonSignalProtocolStore.class)
if (legacySignalProtocolStore != null && legacySignalProtocolStore.getLegacyIdentityKeyStore() != null) {
identityKeyPair = legacySignalProtocolStore.getLegacyIdentityKeyStore().getIdentityKeyPair();
registrationId = legacySignalProtocolStore.getLegacyIdentityKeyStore().getLocalRegistrationId();
+ migratedLegacyConfig = true;
}
initStores(dataPath, identityKeyPair, registrationId);
- loadLegacyStores(rootNode, legacySignalProtocolStore);
+ migratedLegacyConfig = loadLegacyStores(rootNode, legacySignalProtocolStore) || migratedLegacyConfig;
if (rootNode.hasNonNull("groupStore")) {
groupStoreStorage = jsonProcessor.convertValue(rootNode.get("groupStore"), GroupStore.Storage.class);
stickerStore = new StickerStore(this::saveStickerStore);
}
- loadLegacyThreadStore(rootNode);
+ migratedLegacyConfig = loadLegacyThreadStore(rootNode) || migratedLegacyConfig;
+
+ if (migratedLegacyConfig) {
+ save();
+ }
}
- private void loadLegacyStores(
+ private boolean loadLegacyStores(
final JsonNode rootNode, final LegacyJsonSignalProtocolStore legacySignalProtocolStore
) {
+ var migrated = false;
var legacyRecipientStoreNode = rootNode.get("recipientStore");
if (legacyRecipientStoreNode != null) {
logger.debug("Migrating legacy recipient store.");
recipientStore.resolveRecipientsTrusted(legacyRecipientStore.getAddresses());
}
recipientStore.resolveRecipientTrusted(getSelfAddress());
+ migrated = true;
}
if (legacySignalProtocolStore != null && legacySignalProtocolStore.getLegacyPreKeyStore() != null) {
logger.warn("Failed to migrate pre key, ignoring", e);
}
}
+ migrated = true;
}
if (legacySignalProtocolStore != null && legacySignalProtocolStore.getLegacySignedPreKeyStore() != null) {
logger.warn("Failed to migrate signed pre key, ignoring", e);
}
}
+ migrated = true;
}
if (legacySignalProtocolStore != null && legacySignalProtocolStore.getLegacySessionStore() != null) {
logger.warn("Failed to migrate session, ignoring", e);
}
}
+ migrated = true;
}
if (legacySignalProtocolStore != null && legacySignalProtocolStore.getLegacyIdentityKeyStore() != null) {
identity.getIdentityKey(),
identity.getTrustLevel());
}
+ migrated = true;
}
if (rootNode.hasNonNull("contactStore")) {
}
}
}
+ migrated = true;
}
if (rootNode.hasNonNull("profileStore")) {
}
}
}
+
+ return migrated;
}
- private void loadLegacyThreadStore(final JsonNode rootNode) {
+ private boolean loadLegacyThreadStore(final JsonNode rootNode) {
var threadStoreNode = rootNode.get("threadStore");
if (threadStoreNode != null && !threadStoreNode.isNull()) {
var threadStore = jsonProcessor.convertValue(threadStoreNode, LegacyJsonThreadStore.class);
logger.warn("Failed to read legacy thread info: {}", e.getMessage());
}
}
+ return true;
}
+
+ return false;
}
private void saveStickerStore(StickerStore.Storage storage) {
save();
}
- public void save() {
+ private void save() {
synchronized (fileChannel) {
var rootNode = jsonProcessor.createObjectNode();
rootNode.put("username", username)
public void setUuid(final UUID uuid) {
this.uuid = uuid;
+ save();
}
public SignalServiceAddress getSelfAddress() {
return deviceId;
}
- public void setDeviceId(final int deviceId) {
- this.deviceId = deviceId;
- }
-
public boolean isMasterDevice() {
return deviceId == SignalServiceAddress.DEFAULT_DEVICE_ID;
}
return password;
}
- public void setPassword(final String password) {
+ private void setPassword(final String password) {
this.password = password;
+ save();
}
public String getRegistrationLockPin() {
return registrationLockPin;
}
- public void setRegistrationLockPin(final String registrationLockPin) {
+ public void setRegistrationLockPin(final String registrationLockPin, final MasterKey pinMasterKey) {
this.registrationLockPin = registrationLockPin;
+ this.pinMasterKey = pinMasterKey;
+ save();
}
public MasterKey getPinMasterKey() {
return pinMasterKey;
}
- public void setPinMasterKey(final MasterKey pinMasterKey) {
- this.pinMasterKey = pinMasterKey;
- }
-
public StorageKey getStorageKey() {
if (pinMasterKey != null) {
return pinMasterKey.deriveStorageServiceKey();
}
public void setStorageKey(final StorageKey storageKey) {
+ if (storageKey.equals(this.storageKey)) {
+ return;
+ }
this.storageKey = storageKey;
+ save();
}
public ProfileKey getProfileKey() {
}
public void setProfileKey(final ProfileKey profileKey) {
+ if (profileKey.equals(this.profileKey)) {
+ return;
+ }
this.profileKey = profileKey;
+ save();
}
public byte[] getSelfUnidentifiedAccessKey() {
public void setRegistered(final boolean registered) {
this.registered = registered;
+ save();
}
public boolean isMultiDevice() {
}
public void setMultiDevice(final boolean multiDevice) {
+ if (isMultiDevice == multiDevice) {
+ return;
+ }
isMultiDevice = multiDevice;
+ save();
}
public boolean isUnrestrictedUnidentifiedAccess() {
return true;
}
+ public void finishRegistration(final UUID uuid, final MasterKey masterKey, final String pin) {
+ this.pinMasterKey = masterKey;
+ this.deviceId = SignalServiceAddress.DEFAULT_DEVICE_ID;
+ this.isMultiDevice = false;
+ this.registered = true;
+ this.uuid = uuid;
+ this.registrationLockPin = pin;
+ save();
+
+ getSessionStore().archiveAllSessions();
+ final var recipientId = getRecipientStore().resolveRecipientTrusted(getSelfAddress());
+ final var publicKey = getIdentityKeyPair().getPublicKey();
+ getIdentityKeyStore().saveIdentity(recipientId, publicKey, new Date());
+ getIdentityKeyStore().setIdentityTrustLevel(recipientId, publicKey, TrustLevel.TRUSTED_VERIFIED);
+ }
+
@Override
public void close() throws IOException {
- if (fileChannel.isOpen()) {
- save();
- }
synchronized (fileChannel) {
try {
lock.close();