Implement SignalServiceAccountDataStore for PNI

This commit is contained in:
AsamK 2022-06-09 22:27:05 +02:00
parent 484daa4c69
commit dc8b83a110
5 changed files with 72 additions and 25 deletions

View file

@ -167,7 +167,8 @@ class ManagerImpl implements Manager {
}); });
disposable.add(account.getIdentityKeyStore().getIdentityChanges().subscribe(recipientId -> { disposable.add(account.getIdentityKeyStore().getIdentityChanges().subscribe(recipientId -> {
logger.trace("Archiving old sessions for {}", recipientId); logger.trace("Archiving old sessions for {}", recipientId);
account.getSessionStore().archiveSessions(recipientId); account.getAciSessionStore().archiveSessions(recipientId);
account.getPniSessionStore().archiveSessions(recipientId);
account.getSenderKeyStore().deleteSharedWith(recipientId); account.getSenderKeyStore().deleteSharedWith(recipientId);
final var profile = account.getProfileStore().getProfile(recipientId); final var profile = account.getProfileStore().getProfile(recipientId);
if (profile != null) { if (profile != null) {
@ -688,7 +689,7 @@ class ManagerImpl implements Manager {
} catch (UnregisteredRecipientException e) { } catch (UnregisteredRecipientException e) {
continue; continue;
} }
account.getSessionStore().deleteAllSessions(recipientId); account.getAciSessionStore().deleteAllSessions(recipientId);
} }
} }
} }

View file

@ -13,7 +13,7 @@ public class RenewSessionAction implements HandleAction {
@Override @Override
public void execute(Context context) throws Throwable { public void execute(Context context) throws Throwable {
context.getAccount().getSessionStore().archiveSessions(recipientId); context.getAccount().getAciSessionStore().archiveSessions(recipientId);
if (!recipientId.equals(context.getAccount().getSelfRecipientId())) { if (!recipientId.equals(context.getAccount().getSelfRecipientId())) {
context.getSendHelper().sendNullMessage(recipientId); context.getSendHelper().sendNullMessage(recipientId);
} }

View file

@ -29,7 +29,7 @@ public class SendRetryMessageRequestAction implements HandleAction {
@Override @Override
public void execute(Context context) throws Throwable { public void execute(Context context) throws Throwable {
context.getAccount().getSessionStore().archiveSessions(recipientId); context.getAccount().getAciSessionStore().archiveSessions(recipientId);
int senderDevice = protocolException.getSenderDevice(); int senderDevice = protocolException.getSenderDevice();
Optional<GroupId> groupId = protocolException.getGroupId().isPresent() ? Optional.of(GroupId.unknownVersion( Optional<GroupId> groupId = protocolException.getGroupId().isPresent() ? Optional.of(GroupId.unknownVersion(

View file

@ -214,6 +214,7 @@ public final class IncomingMessageHandler {
final var senderPair = getSender(envelope, content); final var senderPair = getSender(envelope, content);
final var sender = senderPair.first(); final var sender = senderPair.first();
final var senderDeviceId = senderPair.second(); final var senderDeviceId = senderPair.second();
final var destination = getDestination(envelope);
if (content.getReceiptMessage().isPresent()) { if (content.getReceiptMessage().isPresent()) {
final var message = content.getReceiptMessage().get(); final var message = content.getReceiptMessage().get();
@ -274,7 +275,7 @@ public final class IncomingMessageHandler {
actions.addAll(handleSignalServiceDataMessage(message, actions.addAll(handleSignalServiceDataMessage(message,
false, false,
sender, sender,
account.getSelfRecipientId(), destination,
receiveConfig.ignoreAttachments())); receiveConfig.ignoreAttachments()));
} }
@ -305,13 +306,14 @@ public final class IncomingMessageHandler {
} }
if (message.getRatchetKey().isPresent()) { if (message.getRatchetKey().isPresent()) {
if (account.getSessionStore().isCurrentRatchetKey(sender, senderDeviceId, message.getRatchetKey().get())) { if (account.getAciSessionStore()
.isCurrentRatchetKey(sender, senderDeviceId, message.getRatchetKey().get())) {
if (logEntries.isEmpty()) { if (logEntries.isEmpty()) {
logger.debug("Renewing the session with sender"); logger.debug("Renewing the session with sender");
actions.add(new RenewSessionAction(sender)); actions.add(new RenewSessionAction(sender));
} else { } else {
logger.trace("Archiving the session with sender, a resend message has already been queued"); logger.trace("Archiving the session with sender, a resend message has already been queued");
context.getAccount().getSessionStore().archiveSessions(sender); context.getAccount().getAciSessionStore().archiveSessions(sender);
} }
} }
return; return;
@ -641,7 +643,7 @@ public final class IncomingMessageHandler {
final var conversationPartnerAddress = isSync ? destination : source; final var conversationPartnerAddress = isSync ? destination : source;
if (conversationPartnerAddress != null && message.isEndSession()) { if (conversationPartnerAddress != null && message.isEndSession()) {
account.getSessionStore().deleteAllSessions(conversationPartnerAddress); account.getAciSessionStore().deleteAllSessions(conversationPartnerAddress);
} }
if (message.isExpirationUpdate() || message.getBody().isPresent()) { if (message.isExpirationUpdate() || message.getBody().isPresent()) {
if (message.getGroupContext().isPresent()) { if (message.getGroupContext().isPresent()) {
@ -776,4 +778,15 @@ public final class IncomingMessageHandler {
content.getSenderDevice()); content.getSenderDevice());
} }
} }
private RecipientId getDestination(SignalServiceEnvelope envelope) {
if (!envelope.hasDestinationUuid()) {
return account.getSelfRecipientId();
}
final var addressOptional = SignalServiceAddress.fromRaw(envelope.getDestinationUuid(), null);
if (addressOptional.isEmpty()) {
return account.getSelfRecipientId();
}
return context.getRecipientHelper().resolveRecipient(addressOptional.get());
}
} }

View file

@ -137,14 +137,17 @@ public class SignalAccount implements Closeable {
private boolean registered = false; private boolean registered = false;
private SignalProtocolStore signalProtocolStore; private SignalProtocolStore aciSignalProtocolStore;
private SignalProtocolStore pniSignalProtocolStore;
private PreKeyStore aciPreKeyStore; private PreKeyStore aciPreKeyStore;
private SignedPreKeyStore aciSignedPreKeyStore; private SignedPreKeyStore aciSignedPreKeyStore;
private PreKeyStore pniPreKeyStore; private PreKeyStore pniPreKeyStore;
private SignedPreKeyStore pniSignedPreKeyStore; private SignedPreKeyStore pniSignedPreKeyStore;
private SessionStore sessionStore; private SessionStore aciSessionStore;
private SessionStore pniSessionStore;
private IdentityKeyStore identityKeyStore; private IdentityKeyStore identityKeyStore;
private SignalIdentityKeyStore aciIdentityKeyStore; private SignalIdentityKeyStore aciIdentityKeyStore;
private SignalIdentityKeyStore pniIdentityKeyStore;
private SenderKeyStore senderKeyStore; private SenderKeyStore senderKeyStore;
private GroupStore groupStore; private GroupStore groupStore;
private RecipientStore recipientStore; private RecipientStore recipientStore;
@ -275,7 +278,8 @@ public class SignalAccount implements Closeable {
profileKey); profileKey);
signalAccount.getRecipientTrustedResolver() signalAccount.getRecipientTrustedResolver()
.resolveSelfRecipientTrusted(signalAccount.getSelfRecipientAddress()); .resolveSelfRecipientTrusted(signalAccount.getSelfRecipientAddress());
signalAccount.getSessionStore().archiveAllSessions(); signalAccount.getAciSessionStore().archiveAllSessions();
signalAccount.getPniSessionStore().archiveAllSessions();
signalAccount.getSenderKeyStore().deleteAll(); signalAccount.getSenderKeyStore().deleteAll();
signalAccount.clearAllPreKeys(); signalAccount.clearAllPreKeys();
return signalAccount; return signalAccount;
@ -393,7 +397,8 @@ public class SignalAccount implements Closeable {
} }
private void mergeRecipients(RecipientId recipientId, RecipientId toBeMergedRecipientId) { private void mergeRecipients(RecipientId recipientId, RecipientId toBeMergedRecipientId) {
getSessionStore().mergeRecipients(recipientId, toBeMergedRecipientId); getAciSessionStore().mergeRecipients(recipientId, toBeMergedRecipientId);
getPniSessionStore().mergeRecipients(recipientId, toBeMergedRecipientId);
getIdentityKeyStore().mergeRecipients(recipientId, toBeMergedRecipientId); getIdentityKeyStore().mergeRecipients(recipientId, toBeMergedRecipientId);
getMessageCache().mergeRecipients(recipientId, toBeMergedRecipientId); getMessageCache().mergeRecipients(recipientId, toBeMergedRecipientId);
getGroupStore().mergeRecipients(recipientId, toBeMergedRecipientId); getGroupStore().mergeRecipients(recipientId, toBeMergedRecipientId);
@ -401,7 +406,8 @@ public class SignalAccount implements Closeable {
} }
public void removeRecipient(final RecipientId recipientId) { public void removeRecipient(final RecipientId recipientId) {
getSessionStore().deleteAllSessions(recipientId); getAciSessionStore().deleteAllSessions(recipientId);
getPniSessionStore().deleteAllSessions(recipientId);
getIdentityKeyStore().deleteIdentity(recipientId); getIdentityKeyStore().deleteIdentity(recipientId);
getMessageCache().deleteMessages(recipientId); getMessageCache().deleteMessages(recipientId);
getSenderKeyStore().deleteAll(recipientId); getSenderKeyStore().deleteAll(recipientId);
@ -637,7 +643,7 @@ public class SignalAccount implements Closeable {
} }
final var legacySessionsPath = getSessionsPath(dataPath, accountPath); final var legacySessionsPath = getSessionsPath(dataPath, accountPath);
if (legacySessionsPath.exists()) { if (legacySessionsPath.exists()) {
LegacySessionStore.migrate(legacySessionsPath, getRecipientResolver(), getSessionStore()); LegacySessionStore.migrate(legacySessionsPath, getRecipientResolver(), getAciSessionStore());
migratedLegacyConfig = true; migratedLegacyConfig = true;
} }
final var legacySignalProtocolStore = rootNode.hasNonNull("axolotlStore") final var legacySignalProtocolStore = rootNode.hasNonNull("axolotlStore")
@ -734,7 +740,7 @@ public class SignalAccount implements Closeable {
logger.debug("Migrating legacy session store."); logger.debug("Migrating legacy session store.");
for (var session : legacySignalProtocolStore.getLegacySessionStore().getSessions()) { for (var session : legacySignalProtocolStore.getLegacySessionStore().getSessions()) {
try { try {
getSessionStore().storeSession(new SignalProtocolAddress(session.address.getIdentifier(), getAciSessionStore().storeSession(new SignalProtocolAddress(session.address.getIdentifier(),
session.deviceId), new SessionRecord(session.sessionRecord)); session.deviceId), new SessionRecord(session.sessionRecord));
} catch (Exception e) { } catch (Exception e) {
logger.warn("Failed to migrate session, ignoring", e); logger.warn("Failed to migrate session, ignoring", e);
@ -1016,9 +1022,9 @@ public class SignalAccount implements Closeable {
@Override @Override
public SignalServiceAccountDataStore get(final ServiceId accountIdentifier) { public SignalServiceAccountDataStore get(final ServiceId accountIdentifier) {
if (accountIdentifier.equals(aci)) { if (accountIdentifier.equals(aci)) {
return getAciSignalServiceAccountDataStore(); return aci();
} else if (accountIdentifier.equals(pni)) { } else if (accountIdentifier.equals(pni)) {
throw new AssertionError("PNI not to be used yet!"); return pni();
} else { } else {
throw new IllegalArgumentException("No matching store found for " + accountIdentifier); throw new IllegalArgumentException("No matching store found for " + accountIdentifier);
} }
@ -1031,7 +1037,7 @@ public class SignalAccount implements Closeable {
@Override @Override
public SignalServiceAccountDataStore pni() { public SignalServiceAccountDataStore pni() {
throw new AssertionError("PNI not to be used yet!"); return getPniSignalServiceAccountDataStore();
} }
@Override @Override
@ -1042,15 +1048,25 @@ public class SignalAccount implements Closeable {
} }
private SignalServiceAccountDataStore getAciSignalServiceAccountDataStore() { private SignalServiceAccountDataStore getAciSignalServiceAccountDataStore() {
return getOrCreate(() -> signalProtocolStore, return getOrCreate(() -> aciSignalProtocolStore,
() -> signalProtocolStore = new SignalProtocolStore(getAciPreKeyStore(), () -> aciSignalProtocolStore = new SignalProtocolStore(getAciPreKeyStore(),
getAciSignedPreKeyStore(), getAciSignedPreKeyStore(),
getSessionStore(), getAciSessionStore(),
getAciIdentityKeyStore(), getAciIdentityKeyStore(),
getSenderKeyStore(), getSenderKeyStore(),
this::isMultiDevice)); this::isMultiDevice));
} }
private SignalServiceAccountDataStore getPniSignalServiceAccountDataStore() {
return getOrCreate(() -> pniSignalProtocolStore,
() -> pniSignalProtocolStore = new SignalProtocolStore(getPniPreKeyStore(),
getPniSignedPreKeyStore(),
getPniSessionStore(),
getPniIdentityKeyStore(),
getSenderKeyStore(),
this::isMultiDevice));
}
private PreKeyStore getAciPreKeyStore() { private PreKeyStore getAciPreKeyStore() {
return getOrCreate(() -> aciPreKeyStore, return getOrCreate(() -> aciPreKeyStore,
() -> aciPreKeyStore = new PreKeyStore(getAccountDatabase(), ServiceIdType.ACI)); () -> aciPreKeyStore = new PreKeyStore(getAccountDatabase(), ServiceIdType.ACI));
@ -1071,14 +1087,22 @@ public class SignalAccount implements Closeable {
() -> pniSignedPreKeyStore = new SignedPreKeyStore(getAccountDatabase(), ServiceIdType.PNI)); () -> pniSignedPreKeyStore = new SignedPreKeyStore(getAccountDatabase(), ServiceIdType.PNI));
} }
public SessionStore getSessionStore() { public SessionStore getAciSessionStore() {
return getOrCreate(() -> sessionStore, return getOrCreate(() -> aciSessionStore,
() -> sessionStore = new SessionStore(getAccountDatabase(), () -> aciSessionStore = new SessionStore(getAccountDatabase(),
ServiceIdType.ACI, ServiceIdType.ACI,
getRecipientResolver(), getRecipientResolver(),
getRecipientIdCreator())); getRecipientIdCreator()));
} }
public SessionStore getPniSessionStore() {
return getOrCreate(() -> pniSessionStore,
() -> pniSessionStore = new SessionStore(getAccountDatabase(),
ServiceIdType.PNI,
getRecipientResolver(),
getRecipientIdCreator()));
}
public IdentityKeyStore getIdentityKeyStore() { public IdentityKeyStore getIdentityKeyStore() {
return getOrCreate(() -> identityKeyStore, return getOrCreate(() -> identityKeyStore,
() -> identityKeyStore = new IdentityKeyStore(getIdentitiesPath(dataPath, accountPath), () -> identityKeyStore = new IdentityKeyStore(getIdentitiesPath(dataPath, accountPath),
@ -1094,6 +1118,14 @@ public class SignalAccount implements Closeable {
getIdentityKeyStore())); getIdentityKeyStore()));
} }
public SignalIdentityKeyStore getPniIdentityKeyStore() {
return getOrCreate(() -> pniIdentityKeyStore,
() -> pniIdentityKeyStore = new SignalIdentityKeyStore(getRecipientResolver(),
() -> pniIdentityKeyPair,
localRegistrationId,
getIdentityKeyStore()));
}
public GroupStore getGroupStore() { public GroupStore getGroupStore() {
return getOrCreate(() -> groupStore, return getOrCreate(() -> groupStore,
() -> groupStore = new GroupStore(getAccountDatabase(), () -> groupStore = new GroupStore(getAccountDatabase(),
@ -1500,7 +1532,8 @@ public class SignalAccount implements Closeable {
save(); save();
clearAllPreKeys(); clearAllPreKeys();
getSessionStore().archiveAllSessions(); getAciSessionStore().archiveAllSessions();
getPniSessionStore().archiveAllSessions();
getSenderKeyStore().deleteAll(); getSenderKeyStore().deleteAll();
final var recipientId = getRecipientTrustedResolver().resolveSelfRecipientTrusted(getSelfRecipientAddress()); final var recipientId = getRecipientTrustedResolver().resolveSelfRecipientTrusted(getSelfRecipientAddress());
final var publicKey = getAciIdentityKeyPair().getPublicKey(); final var publicKey = getAciIdentityKeyPair().getPublicKey();