diff --git a/src/org/thoughtcrime/securesms/ApplicationContext.java b/src/org/thoughtcrime/securesms/ApplicationContext.java index 9c346f5a20..c83193444d 100644 --- a/src/org/thoughtcrime/securesms/ApplicationContext.java +++ b/src/org/thoughtcrime/securesms/ApplicationContext.java @@ -38,6 +38,7 @@ import org.thoughtcrime.securesms.components.TypingStatusSender; import org.thoughtcrime.securesms.crypto.IdentityKeyUtil; import org.thoughtcrime.securesms.crypto.MasterSecretUtil; import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; +import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore; import org.thoughtcrime.securesms.database.Address; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.dependencies.AxolotlStorageModule; @@ -91,8 +92,10 @@ import org.webrtc.PeerConnectionFactory; import org.webrtc.PeerConnectionFactory.InitializationOptions; import org.webrtc.voiceengine.WebRtcAudioManager; import org.webrtc.voiceengine.WebRtcAudioUtils; +import org.whispersystems.libsignal.SignalProtocolAddress; import org.whispersystems.libsignal.logging.SignalProtocolLoggerProvider; 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.internal.push.SignalServiceProtos; import org.whispersystems.signalservice.loki.api.Poller; @@ -588,6 +591,18 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc @Override 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()); EphemeralMessage sessionRequest = EphemeralMessage.createSessionRequest(publicKey); jobManager.add(new PushEphemeralMessageSendJob(sessionRequest)); diff --git a/src/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocol.kt b/src/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocol.kt index 8e7e84111c..40311e35cf 100644 --- a/src/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocol.kt +++ b/src/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocol.kt @@ -106,13 +106,7 @@ object ClosedGroupsProtocol { allDevices.remove(userPublicKey) } for (device in allDevices) { - val deviceAsAddress = SignalProtocolAddress(device, SignalServiceAddress.DEFAULT_DEVICE_ID) - 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)) + ApplicationContext.getInstance(context).sendSessionRequest(device) } } } \ No newline at end of file diff --git a/src/org/thoughtcrime/securesms/loki/protocol/SessionManagementProtocol.kt b/src/org/thoughtcrime/securesms/loki/protocol/SessionManagementProtocol.kt index 81ca56eaa0..be4663ba4e 100644 --- a/src/org/thoughtcrime/securesms/loki/protocol/SessionManagementProtocol.kt +++ b/src/org/thoughtcrime/securesms/loki/protocol/SessionManagementProtocol.kt @@ -16,7 +16,7 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.libsignal.loki.LokiSessionResetStatus import org.whispersystems.signalservice.api.messages.SignalServiceContent import org.whispersystems.signalservice.loki.protocol.multidevice.MultiDeviceProtocol -import org.whispersystems.signalservice.loki.protocol.todo.LokiThreadFriendRequestStatus +import java.util.* 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 lokiPreKeyBundleDatabase = DatabaseFactory.getLokiPreKeyBundleDatabase(context) 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) lokiPreKeyBundleDatabase.setPreKeyBundle(content.sender, preKeyBundle) } @@ -66,11 +74,13 @@ object SessionManagementProtocol { @JvmStatic fun handleSessionRequestIfNeeded(context: Context, content: SignalServiceContent): Boolean { if (!content.dataMessage.isPresent || !content.dataMessage.get().isSessionRequest) { return false } - val sentSessionRequestTimestamp = DatabaseFactory.getLokiAPIDatabase(context).getSessionRequestTimestamp(content.sender) - if (sentSessionRequestTimestamp != null && content.timestamp < sentSessionRequestTimestamp) { - // We sent a session request after this one was sent + 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 false } + DatabaseFactory.getLokiAPIDatabase(context).setSessionRequestTimestamp(content.sender, Date().time) val ephemeralMessage = EphemeralMessage.create(content.sender) ApplicationContext.getInstance(context).jobManager.add(PushEphemeralMessageSendJob(ephemeralMessage)) return true