mirror of
https://github.com/oxen-io/session-android.git
synced 2025-01-11 16:13:57 +00:00
Updated to follow LokiSessionResetProtocol.
Refactor some code to be less confusing.
This commit is contained in:
parent
bcc219bd1f
commit
3bbcbc8873
@ -10,11 +10,11 @@ import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.whispersystems.libsignal.SignalProtocolAddress;
|
||||
import org.whispersystems.libsignal.protocol.CiphertextMessage;
|
||||
import org.whispersystems.libsignal.state.SessionRecord;
|
||||
import org.whispersystems.signalservice.loki.messaging.LokiSessionDatabaseProtocol;
|
||||
import org.whispersystems.libsignal.state.SessionStore;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TextSecureSessionStore implements LokiSessionDatabaseProtocol {
|
||||
public class TextSecureSessionStore implements SessionStore {
|
||||
|
||||
private static final String TAG = TextSecureSessionStore.class.getSimpleName();
|
||||
|
||||
|
@ -7,7 +7,6 @@ import org.thoughtcrime.securesms.ApplicationContext;
|
||||
import org.thoughtcrime.securesms.CreateProfileActivity;
|
||||
import org.thoughtcrime.securesms.DeviceListFragment;
|
||||
import org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl;
|
||||
import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.events.ReminderUpdateEvent;
|
||||
import org.thoughtcrime.securesms.gcm.FcmService;
|
||||
@ -48,6 +47,7 @@ import org.thoughtcrime.securesms.jobs.StickerPackDownloadJob;
|
||||
import org.thoughtcrime.securesms.jobs.TypingSendJob;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.loki.LokiSessionResetImplementation;
|
||||
import org.thoughtcrime.securesms.loki.PushMessageSyncSendJob;
|
||||
import org.thoughtcrime.securesms.preferences.AppProtectionPreferenceFragment;
|
||||
import org.thoughtcrime.securesms.push.MessageSenderEventListener;
|
||||
@ -160,7 +160,7 @@ public class SignalCommunicationModule {
|
||||
DatabaseFactory.getLokiThreadDatabase(context),
|
||||
DatabaseFactory.getLokiMessageDatabase(context),
|
||||
DatabaseFactory.getLokiPreKeyBundleDatabase(context),
|
||||
new TextSecureSessionStore(context),
|
||||
new LokiSessionResetImplementation(context),
|
||||
DatabaseFactory.getLokiUserDatabase(context),
|
||||
((ApplicationContext)context.getApplicationContext()).broadcaster);
|
||||
} else {
|
||||
|
@ -69,12 +69,12 @@ import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.loki.FriendRequestHandler;
|
||||
import org.thoughtcrime.securesms.loki.LokiMessageDatabase;
|
||||
import org.thoughtcrime.securesms.loki.LokiSessionResetImplementation;
|
||||
import org.thoughtcrime.securesms.loki.LokiThreadDatabase;
|
||||
import org.thoughtcrime.securesms.loki.MultiDeviceUtilities;
|
||||
import org.thoughtcrime.securesms.loki.redesign.activities.HomeActivity;
|
||||
import org.thoughtcrime.securesms.loki.redesign.messaging.LokiAPIUtilities;
|
||||
import org.thoughtcrime.securesms.loki.redesign.messaging.LokiPreKeyBundleDatabase;
|
||||
import org.thoughtcrime.securesms.loki.redesign.messaging.LokiPreKeyRecordDatabase;
|
||||
import org.thoughtcrime.securesms.mms.IncomingMediaMessage;
|
||||
import org.thoughtcrime.securesms.mms.MmsException;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingExpirationUpdateMessage;
|
||||
@ -101,6 +101,8 @@ import org.thoughtcrime.securesms.util.IdentityUtil;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.libsignal.loki.LokiSessionResetProtocol;
|
||||
import org.whispersystems.libsignal.loki.LokiSessionResetStatus;
|
||||
import org.whispersystems.libsignal.state.PreKeyBundle;
|
||||
import org.whispersystems.libsignal.state.SignalProtocolStore;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
@ -137,7 +139,6 @@ import org.whispersystems.signalservice.loki.crypto.LokiServiceCipher;
|
||||
import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus;
|
||||
import org.whispersystems.signalservice.loki.messaging.LokiServiceMessage;
|
||||
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus;
|
||||
import org.whispersystems.signalservice.loki.messaging.LokiThreadSessionResetStatus;
|
||||
import org.whispersystems.signalservice.loki.utilities.PromiseUtil;
|
||||
|
||||
import java.io.InputStream;
|
||||
@ -270,9 +271,9 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
|
||||
SignalProtocolStore axolotlStore = new SignalProtocolStoreImpl(context);
|
||||
LokiThreadDatabase lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context);
|
||||
LokiPreKeyRecordDatabase lokiPreKeyRecordDatabase = DatabaseFactory.getLokiPreKeyRecordDatabase(context);
|
||||
LokiSessionResetProtocol lokiSessionResetProtocol = new LokiSessionResetImplementation(context);
|
||||
SignalServiceAddress localAddress = new SignalServiceAddress(TextSecurePreferences.getLocalNumber(context));
|
||||
LokiServiceCipher cipher = new LokiServiceCipher(localAddress, axolotlStore, lokiThreadDatabase, lokiPreKeyRecordDatabase, UnidentifiedAccessUtil.getCertificateValidator());
|
||||
LokiServiceCipher cipher = new LokiServiceCipher(localAddress, axolotlStore, lokiSessionResetProtocol, UnidentifiedAccessUtil.getCertificateValidator());
|
||||
|
||||
SignalServiceContent content = cipher.decrypt(envelope);
|
||||
|
||||
@ -363,6 +364,18 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
handleNeedsDeliveryReceipt(content, message);
|
||||
}
|
||||
|
||||
// If we received a friend request, but we were already friends with the user, reset the session
|
||||
if (content.isFriendRequest() && !message.isGroupMessage()) {
|
||||
Recipient sender = Recipient.from(context, Address.fromSerialized(content.getSender()), false);
|
||||
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context);
|
||||
long threadID = threadDatabase.getThreadIdIfExistsFor(sender);
|
||||
if (lokiThreadDatabase.getFriendRequestStatus(threadID) == LokiThreadFriendRequestStatus.FRIENDS) {
|
||||
resetSession(content.getSender());
|
||||
// Let our other devices know that we have reset the session
|
||||
MessageSender.syncContact(context, sender.getAddress());
|
||||
}
|
||||
}
|
||||
|
||||
// Loki - Handle friend request logic if needed
|
||||
updateFriendRequestStatusIfNeeded(content, message);
|
||||
}
|
||||
@ -403,11 +416,6 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
if (envelope.isPreKeySignalMessage()) {
|
||||
ApplicationContext.getInstance(context).getJobManager().add(new RefreshPreKeysJob());
|
||||
}
|
||||
|
||||
// Loki - Handle session reset logic
|
||||
if (!content.isFriendRequest()) {
|
||||
cipher.handleSessionResetRequestIfNeeded(content, cipher.getSessionStatus(content));
|
||||
}
|
||||
} catch (ProtocolInvalidVersionException e) {
|
||||
Log.w(TAG, e);
|
||||
handleInvalidVersionMessage(e.getSender(), e.getSenderDevice(), envelope.getTimestamp(), smsMessageId);
|
||||
@ -540,19 +548,19 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
}
|
||||
|
||||
if (threadId != null) {
|
||||
resetSession(content.getSender(), threadId);
|
||||
resetSession(content.getSender());
|
||||
MessageNotifier.updateNotification(context, threadId);
|
||||
}
|
||||
}
|
||||
|
||||
private void resetSession(String hexEncodedPublicKey, long threadId) {
|
||||
private void resetSession(String hexEncodedPublicKey) {
|
||||
TextSecureSessionStore sessionStore = new TextSecureSessionStore(context);
|
||||
LokiThreadDatabase lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context);
|
||||
|
||||
Log.d("Loki", "Received a session reset request from: " + hexEncodedPublicKey + "; archiving the session.");
|
||||
|
||||
sessionStore.archiveAllSessions(hexEncodedPublicKey);
|
||||
lokiThreadDatabase.setSessionResetStatus(threadId, LokiThreadSessionResetStatus.REQUEST_RECEIVED);
|
||||
lokiThreadDatabase.setSessionResetStatus(hexEncodedPublicKey, LokiSessionResetStatus.REQUEST_RECEIVED);
|
||||
|
||||
Log.d("Loki", "Sending a ping back to " + hexEncodedPublicKey + ".");
|
||||
MessageSender.sendBackgroundMessage(context, hexEncodedPublicKey);
|
||||
@ -1203,21 +1211,11 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
if (lokiMessage.getPreKeyBundleMessage() == null) { return; }
|
||||
int registrationID = TextSecurePreferences.getLocalRegistrationId(context);
|
||||
LokiPreKeyBundleDatabase lokiPreKeyBundleDatabase = DatabaseFactory.getLokiPreKeyBundleDatabase(context);
|
||||
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context);
|
||||
LokiThreadDatabase lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context);
|
||||
if (registrationID <= 0) { return; }
|
||||
Log.d("Loki", "Received a pre key bundle from: " + content.getSender() + ".");
|
||||
PreKeyBundle preKeyBundle = lokiMessage.getPreKeyBundleMessage().getPreKeyBundle(registrationID);
|
||||
lokiPreKeyBundleDatabase.setPreKeyBundle(content.getSender(), preKeyBundle);
|
||||
// If we received a friend request, but we were already friends with the user, reset the session
|
||||
if (content.isFriendRequest()) {
|
||||
long threadID = threadDatabase.getThreadIdIfExistsFor(sender);
|
||||
if (lokiThreadDatabase.getFriendRequestStatus(threadID) == LokiThreadFriendRequestStatus.FRIENDS) {
|
||||
resetSession(content.getSender(), threadID);
|
||||
// Let our other devices know that we have reset the session
|
||||
MessageSender.syncContact(context, sender.getAddress());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void handleSessionRequestIfNeeded(@NonNull SignalServiceContent content) {
|
||||
|
@ -0,0 +1,34 @@
|
||||
package org.thoughtcrime.securesms.loki
|
||||
|
||||
import android.content.Context
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||
import org.thoughtcrime.securesms.sms.MessageSender
|
||||
import org.whispersystems.libsignal.loki.LokiSessionResetProtocol
|
||||
import org.whispersystems.libsignal.loki.LokiSessionResetStatus
|
||||
import org.whispersystems.libsignal.protocol.PreKeySignalMessage
|
||||
|
||||
class LokiSessionResetImplementation(private val context: Context) : LokiSessionResetProtocol {
|
||||
|
||||
override fun getSessionResetStatus(hexEncodedPublicKey: String): LokiSessionResetStatus {
|
||||
return DatabaseFactory.getLokiThreadDatabase(context).getSessionResetStatus(hexEncodedPublicKey)
|
||||
}
|
||||
|
||||
override fun setSessionResetStatus(hexEncodedPublicKey: String, sessionResetStatus: LokiSessionResetStatus) {
|
||||
return DatabaseFactory.getLokiThreadDatabase(context).setSessionResetStatus(hexEncodedPublicKey, sessionResetStatus)
|
||||
}
|
||||
|
||||
override fun onNewSessionAdopted(hexEncodedPublicKey: String, oldSessionResetStatus: LokiSessionResetStatus) {
|
||||
if (oldSessionResetStatus == LokiSessionResetStatus.IN_PROGRESS) {
|
||||
// Send a message back to the contact to finalise session reset
|
||||
MessageSender.sendBackgroundMessage(context, hexEncodedPublicKey)
|
||||
}
|
||||
|
||||
// TODO: Show session reset succeed message
|
||||
}
|
||||
|
||||
override fun validatePreKeySignalMessage(sender: String, message: PreKeySignalMessage) {
|
||||
val preKeyRecord = DatabaseFactory.getLokiPreKeyRecordDatabase(context).getPreKeyRecord(sender)
|
||||
check(preKeyRecord != null) { "Received a background message from a user without an associated pre key record." }
|
||||
check(preKeyRecord.id == (message.preKeyId ?: -1)) { "Received a background message from an unknown source." }
|
||||
}
|
||||
}
|
@ -10,11 +10,11 @@ import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
|
||||
import org.thoughtcrime.securesms.loki.redesign.utilities.*
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
import org.whispersystems.libsignal.loki.LokiSessionResetStatus
|
||||
import org.whispersystems.signalservice.internal.util.JsonUtil
|
||||
import org.whispersystems.signalservice.loki.api.LokiPublicChat
|
||||
import org.whispersystems.signalservice.loki.messaging.LokiThreadDatabaseProtocol
|
||||
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus
|
||||
import org.whispersystems.signalservice.loki.messaging.LokiThreadSessionResetStatus
|
||||
import org.whispersystems.signalservice.loki.utilities.PublicKeyValidation
|
||||
|
||||
class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), LokiThreadDatabaseProtocol {
|
||||
@ -23,11 +23,11 @@ class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa
|
||||
companion object {
|
||||
private val friendRequestTableName = "loki_thread_friend_request_database"
|
||||
private val sessionResetTableName = "loki_thread_session_reset_database"
|
||||
public val publicChatTableName = "loki_public_chat_database"
|
||||
public val threadID = "thread_id"
|
||||
val publicChatTableName = "loki_public_chat_database"
|
||||
val threadID = "thread_id"
|
||||
private val friendRequestStatus = "friend_request_status"
|
||||
private val sessionResetStatus = "session_reset_status"
|
||||
public val publicChat = "public_chat"
|
||||
val publicChat = "public_chat"
|
||||
@JvmStatic val createFriendRequestTableCommand = "CREATE TABLE $friendRequestTableName ($threadID INTEGER PRIMARY KEY, $friendRequestStatus INTEGER DEFAULT 0);"
|
||||
@JvmStatic val createSessionResetTableCommand = "CREATE TABLE $sessionResetTableName ($threadID INTEGER PRIMARY KEY, $sessionResetStatus INTEGER DEFAULT 0);"
|
||||
@JvmStatic val createPublicChatTableCommand = "CREATE TABLE $publicChatTableName ($threadID INTEGER PRIMARY KEY, $publicChat TEXT);"
|
||||
@ -79,19 +79,21 @@ class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa
|
||||
|| friendRequestStatus == LokiThreadFriendRequestStatus.REQUEST_RECEIVED
|
||||
}
|
||||
|
||||
override fun getSessionResetStatus(threadID: Long): LokiThreadSessionResetStatus {
|
||||
fun getSessionResetStatus(hexEncodedPublicKey: String): LokiSessionResetStatus {
|
||||
val threadID = getThreadID(hexEncodedPublicKey)
|
||||
val database = databaseHelper.readableDatabase
|
||||
val result = database.get(sessionResetTableName, "${Companion.threadID} = ?", arrayOf( threadID.toString() )) { cursor ->
|
||||
cursor.getInt(sessionResetStatus)
|
||||
}
|
||||
return if (result != null) {
|
||||
LokiThreadSessionResetStatus.values().first { it.rawValue == result }
|
||||
LokiSessionResetStatus.values().first { it.rawValue == result }
|
||||
} else {
|
||||
LokiThreadSessionResetStatus.NONE
|
||||
LokiSessionResetStatus.NONE
|
||||
}
|
||||
}
|
||||
|
||||
override fun setSessionResetStatus(threadID: Long, sessionResetStatus: LokiThreadSessionResetStatus) {
|
||||
fun setSessionResetStatus(hexEncodedPublicKey: String, sessionResetStatus: LokiSessionResetStatus) {
|
||||
val threadID = getThreadID(hexEncodedPublicKey)
|
||||
val database = databaseHelper.writableDatabase
|
||||
val contentValues = ContentValues(2)
|
||||
contentValues.put(Companion.threadID, threadID)
|
||||
|
Loading…
x
Reference in New Issue
Block a user