Make session handling logic consistent with desktop

This commit is contained in:
nielsandriesse 2020-07-10 09:46:14 +10:00
parent 4799c13816
commit 5a64e1cf3a
3 changed files with 30 additions and 11 deletions

View File

@ -38,6 +38,7 @@ import org.thoughtcrime.securesms.components.TypingStatusSender;
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil; import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
import org.thoughtcrime.securesms.crypto.MasterSecretUtil; import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore;
import org.thoughtcrime.securesms.database.Address; import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.dependencies.AxolotlStorageModule; import org.thoughtcrime.securesms.dependencies.AxolotlStorageModule;
@ -91,8 +92,10 @@ import org.webrtc.PeerConnectionFactory;
import org.webrtc.PeerConnectionFactory.InitializationOptions; import org.webrtc.PeerConnectionFactory.InitializationOptions;
import org.webrtc.voiceengine.WebRtcAudioManager; import org.webrtc.voiceengine.WebRtcAudioManager;
import org.webrtc.voiceengine.WebRtcAudioUtils; import org.webrtc.voiceengine.WebRtcAudioUtils;
import org.whispersystems.libsignal.SignalProtocolAddress;
import org.whispersystems.libsignal.logging.SignalProtocolLoggerProvider; import org.whispersystems.libsignal.logging.SignalProtocolLoggerProvider;
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope; import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.util.StreamDetails; import org.whispersystems.signalservice.api.util.StreamDetails;
import org.whispersystems.signalservice.internal.push.SignalServiceProtos; import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
import org.whispersystems.signalservice.loki.api.Poller; import org.whispersystems.signalservice.loki.api.Poller;
@ -588,6 +591,18 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
@Override @Override
public void sendSessionRequest(@NotNull String publicKey) { public void sendSessionRequest(@NotNull String publicKey) {
// It's never necessary to establish a session with self
String userPublicKey = TextSecurePreferences.getLocalNumber(this);
if (publicKey.equals(userPublicKey)) { return; }
// Check that we don't already have a session
SignalProtocolAddress address = new SignalProtocolAddress(publicKey, SignalServiceAddress.DEFAULT_DEVICE_ID);
boolean hasSession = new TextSecureSessionStore(this).containsSession(address);
if (hasSession) { return; }
// Check that we didn't already send or process a session request
LokiAPIDatabase apiDB = DatabaseFactory.getLokiAPIDatabase(this);
boolean hasSentOrProcessedSessionRequest = (apiDB.getSessionRequestTimestamp(publicKey) != null);
if (hasSentOrProcessedSessionRequest) { return; }
// Send the session request
DatabaseFactory.getLokiAPIDatabase(this).setSessionRequestTimestamp(publicKey, new Date().getTime()); DatabaseFactory.getLokiAPIDatabase(this).setSessionRequestTimestamp(publicKey, new Date().getTime());
EphemeralMessage sessionRequest = EphemeralMessage.createSessionRequest(publicKey); EphemeralMessage sessionRequest = EphemeralMessage.createSessionRequest(publicKey);
jobManager.add(new PushEphemeralMessageSendJob(sessionRequest)); jobManager.add(new PushEphemeralMessageSendJob(sessionRequest));

View File

@ -106,13 +106,7 @@ object ClosedGroupsProtocol {
allDevices.remove(userPublicKey) allDevices.remove(userPublicKey)
} }
for (device in allDevices) { for (device in allDevices) {
val deviceAsAddress = SignalProtocolAddress(device, SignalServiceAddress.DEFAULT_DEVICE_ID) ApplicationContext.getInstance(context).sendSessionRequest(device)
val hasSession = TextSecureSessionStore(context).containsSession(deviceAsAddress)
if (hasSession) { continue }
if (DatabaseFactory.getLokiAPIDatabase(context).getSessionRequestTimestamp(device) != null) { return }
DatabaseFactory.getLokiAPIDatabase(context).setSessionRequestTimestamp(device, Date().time)
val sessionRequest = EphemeralMessage.createSessionRequest(device)
ApplicationContext.getInstance(context).jobManager.add(PushEphemeralMessageSendJob(sessionRequest))
} }
} }
} }

View File

@ -16,7 +16,7 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.libsignal.loki.LokiSessionResetStatus import org.whispersystems.libsignal.loki.LokiSessionResetStatus
import org.whispersystems.signalservice.api.messages.SignalServiceContent import org.whispersystems.signalservice.api.messages.SignalServiceContent
import org.whispersystems.signalservice.loki.protocol.multidevice.MultiDeviceProtocol import org.whispersystems.signalservice.loki.protocol.multidevice.MultiDeviceProtocol
import org.whispersystems.signalservice.loki.protocol.todo.LokiThreadFriendRequestStatus import java.util.*
object SessionManagementProtocol { object SessionManagementProtocol {
@ -59,6 +59,14 @@ object SessionManagementProtocol {
val registrationID = TextSecurePreferences.getLocalRegistrationId(context) // TODO: It seems wrong to use the local registration ID for this? val registrationID = TextSecurePreferences.getLocalRegistrationId(context) // TODO: It seems wrong to use the local registration ID for this?
val lokiPreKeyBundleDatabase = DatabaseFactory.getLokiPreKeyBundleDatabase(context) val lokiPreKeyBundleDatabase = DatabaseFactory.getLokiPreKeyBundleDatabase(context)
Log.d("Loki", "Received a pre key bundle from: " + content.sender.toString() + ".") Log.d("Loki", "Received a pre key bundle from: " + content.sender.toString() + ".")
if (content.dataMessage.isPresent && content.dataMessage.get().isSessionRequest) {
val sessionRequestTimestamp = DatabaseFactory.getLokiAPIDatabase(context).getSessionRequestTimestamp(content.sender)
if (sessionRequestTimestamp != null && content.timestamp < sessionRequestTimestamp) {
// We sent or processed a session request after this one was sent
Log.d("Loki", "Ignoring session request from: ${content.sender}.")
return
}
}
val preKeyBundle = preKeyBundleMessage.getPreKeyBundle(registrationID) val preKeyBundle = preKeyBundleMessage.getPreKeyBundle(registrationID)
lokiPreKeyBundleDatabase.setPreKeyBundle(content.sender, preKeyBundle) lokiPreKeyBundleDatabase.setPreKeyBundle(content.sender, preKeyBundle)
} }
@ -66,11 +74,13 @@ object SessionManagementProtocol {
@JvmStatic @JvmStatic
fun handleSessionRequestIfNeeded(context: Context, content: SignalServiceContent): Boolean { fun handleSessionRequestIfNeeded(context: Context, content: SignalServiceContent): Boolean {
if (!content.dataMessage.isPresent || !content.dataMessage.get().isSessionRequest) { return false } if (!content.dataMessage.isPresent || !content.dataMessage.get().isSessionRequest) { return false }
val sentSessionRequestTimestamp = DatabaseFactory.getLokiAPIDatabase(context).getSessionRequestTimestamp(content.sender) val sessionRequestTimestamp = DatabaseFactory.getLokiAPIDatabase(context).getSessionRequestTimestamp(content.sender)
if (sentSessionRequestTimestamp != null && content.timestamp < sentSessionRequestTimestamp) { if (sessionRequestTimestamp != null && content.timestamp < sessionRequestTimestamp) {
// We sent a session request after this one was sent // We sent or processed a session request after this one was sent
Log.d("Loki", "Ignoring session request from: ${content.sender}.")
return false return false
} }
DatabaseFactory.getLokiAPIDatabase(context).setSessionRequestTimestamp(content.sender, Date().time)
val ephemeralMessage = EphemeralMessage.create(content.sender) val ephemeralMessage = EphemeralMessage.create(content.sender)
ApplicationContext.getInstance(context).jobManager.add(PushEphemeralMessageSendJob(ephemeralMessage)) ApplicationContext.getInstance(context).jobManager.add(PushEphemeralMessageSendJob(ephemeralMessage))
return true return true