mirror of
https://github.com/oxen-io/session-android.git
synced 2025-01-12 03:53:50 +00:00
Update for core changes
This commit is contained in:
parent
4f46c6317b
commit
19ec4db687
@ -81,11 +81,17 @@ 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.IdentityKeyPair;
|
|
||||||
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.internal.push.SignalServiceProtos;
|
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
|
||||||
import org.whispersystems.signalservice.loki.api.*;
|
import org.whispersystems.signalservice.loki.api.LokiAPIDatabaseProtocol;
|
||||||
|
import org.whispersystems.signalservice.loki.api.LokiGroupChat;
|
||||||
|
import org.whispersystems.signalservice.loki.api.LokiGroupChatAPI;
|
||||||
|
import org.whispersystems.signalservice.loki.api.LokiLongPoller;
|
||||||
|
import org.whispersystems.signalservice.loki.api.LokiP2PAPI;
|
||||||
|
import org.whispersystems.signalservice.loki.api.LokiP2PAPIDelegate;
|
||||||
|
import org.whispersystems.signalservice.loki.api.LokiRSSFeed;
|
||||||
|
import org.whispersystems.signalservice.loki.api.LokiStorageAPI;
|
||||||
import org.whispersystems.signalservice.loki.utilities.Analytics;
|
import org.whispersystems.signalservice.loki.utilities.Analytics;
|
||||||
|
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
@ -428,7 +434,8 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
|
|||||||
if (userHexEncodedPublicKey != null && IdentityKeyUtil.hasIdentityKey(this)) {
|
if (userHexEncodedPublicKey != null && IdentityKeyUtil.hasIdentityKey(this)) {
|
||||||
byte[] userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(this).getPrivateKey().serialize();
|
byte[] userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(this).getPrivateKey().serialize();
|
||||||
LokiAPIDatabaseProtocol database = DatabaseFactory.getLokiAPIDatabase(this);
|
LokiAPIDatabaseProtocol database = DatabaseFactory.getLokiAPIDatabase(this);
|
||||||
LokiStorageAPI.Companion.configure(userHexEncodedPublicKey, userPrivateKey, database);
|
boolean isDebugMode = BuildConfig.DEBUG;
|
||||||
|
LokiStorageAPI.Companion.configure(isDebugMode, userHexEncodedPublicKey, userPrivateKey, database);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,9 +39,21 @@ import org.thoughtcrime.securesms.crypto.SecurityEvent;
|
|||||||
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
|
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
|
||||||
import org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl;
|
import org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl;
|
||||||
import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore;
|
import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore;
|
||||||
import org.thoughtcrime.securesms.database.*;
|
import org.thoughtcrime.securesms.database.Address;
|
||||||
|
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||||
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
|
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||||
|
import org.thoughtcrime.securesms.database.GroupReceiptDatabase;
|
||||||
|
import org.thoughtcrime.securesms.database.MessagingDatabase;
|
||||||
import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult;
|
import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult;
|
||||||
import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId;
|
import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId;
|
||||||
|
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||||
|
import org.thoughtcrime.securesms.database.NoSuchMessageException;
|
||||||
|
import org.thoughtcrime.securesms.database.PushDatabase;
|
||||||
|
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||||
|
import org.thoughtcrime.securesms.database.SmsDatabase;
|
||||||
|
import org.thoughtcrime.securesms.database.StickerDatabase;
|
||||||
|
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
|
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.StickerRecord;
|
import org.thoughtcrime.securesms.database.model.StickerRecord;
|
||||||
@ -110,9 +122,9 @@ import org.whispersystems.signalservice.api.messages.multidevice.StickerPackOper
|
|||||||
import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage;
|
import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage;
|
||||||
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
|
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
|
||||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||||
import org.whispersystems.signalservice.loki.api.LokiDeviceLinkingSession;
|
import org.whispersystems.signalservice.loki.api.DeviceLinkingSession;
|
||||||
import org.whispersystems.signalservice.loki.api.LokiPairingAuthorisation;
|
|
||||||
import org.whispersystems.signalservice.loki.api.LokiStorageAPI;
|
import org.whispersystems.signalservice.loki.api.LokiStorageAPI;
|
||||||
|
import org.whispersystems.signalservice.loki.api.PairingAuthorisation;
|
||||||
import org.whispersystems.signalservice.loki.crypto.LokiServiceCipher;
|
import org.whispersystems.signalservice.loki.crypto.LokiServiceCipher;
|
||||||
import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus;
|
import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus;
|
||||||
import org.whispersystems.signalservice.loki.messaging.LokiServiceMessage;
|
import org.whispersystems.signalservice.loki.messaging.LokiServiceMessage;
|
||||||
@ -267,8 +279,8 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
acceptFriendRequestIfNeeded(envelope, content);
|
acceptFriendRequestIfNeeded(envelope, content);
|
||||||
|
|
||||||
// Loki - Store pre key bundle if needed
|
// Loki - Store pre key bundle if needed
|
||||||
if (content.lokiMessage.isPresent()) {
|
if (content.lokiServiceMessage.isPresent()) {
|
||||||
LokiServiceMessage lokiMessage = content.lokiMessage.get();
|
LokiServiceMessage lokiMessage = content.lokiServiceMessage.get();
|
||||||
if (lokiMessage.getPreKeyBundleMessage() != null) {
|
if (lokiMessage.getPreKeyBundleMessage() != null) {
|
||||||
Log.d("Loki", "Received a pre key bundle from: " + envelope.getSource() + ".");
|
Log.d("Loki", "Received a pre key bundle from: " + envelope.getSource() + ".");
|
||||||
int registrationID = TextSecurePreferences.getLocalRegistrationId(context);
|
int registrationID = TextSecurePreferences.getLocalRegistrationId(context);
|
||||||
@ -1015,10 +1027,10 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAuthorisationValid(@NonNull LokiPairingAuthorisation authorisation) {
|
private boolean isAuthorisationValid(@NonNull PairingAuthorisation authorisation) {
|
||||||
boolean isSecondaryDevice = TextSecurePreferences.isSecondaryDevice(context);
|
boolean isSecondaryDevice = TextSecurePreferences.isSecondaryDevice(context);
|
||||||
String ourPubKey = TextSecurePreferences.getLocalNumber(context);
|
String ourPubKey = TextSecurePreferences.getLocalNumber(context);
|
||||||
boolean isRequest = authorisation.getType() == LokiPairingAuthorisation.Type.REQUEST;
|
boolean isRequest = authorisation.getType() == PairingAuthorisation.Type.REQUEST;
|
||||||
|
|
||||||
if (authorisation.getRequestSignature() == null) {
|
if (authorisation.getRequestSignature() == null) {
|
||||||
Log.w("Loki", "Received a pairing request with missing request signature. Ignored.");
|
Log.w("Loki", "Received a pairing request with missing request signature. Ignored.");
|
||||||
@ -1037,9 +1049,9 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
return authorisation.verify();
|
return authorisation.verify();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handlePairingAuthorisation(@NonNull LokiPairingAuthorisation authorisation, @NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceContent content) {
|
private void handlePairingAuthorisation(@NonNull PairingAuthorisation authorisation, @NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceContent content) {
|
||||||
String ourNumber = TextSecurePreferences.getLocalNumber(context);
|
String ourNumber = TextSecurePreferences.getLocalNumber(context);
|
||||||
if (authorisation.getType() == LokiPairingAuthorisation.Type.REQUEST) {
|
if (authorisation.getType() == PairingAuthorisation.Type.REQUEST) {
|
||||||
handlePairingRequest(authorisation, envelope);
|
handlePairingRequest(authorisation, envelope);
|
||||||
} else if (authorisation.getSecondaryDevicePublicKey().equals(ourNumber)) {
|
} else if (authorisation.getSecondaryDevicePublicKey().equals(ourNumber)) {
|
||||||
// If we were listed as a secondary device, it means we got a confirmation back from the primary device
|
// If we were listed as a secondary device, it means we got a confirmation back from the primary device
|
||||||
@ -1047,18 +1059,18 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handlePairingRequest(@NonNull LokiPairingAuthorisation authorisation, @NonNull SignalServiceEnvelope envelope) {
|
private void handlePairingRequest(@NonNull PairingAuthorisation authorisation, @NonNull SignalServiceEnvelope envelope) {
|
||||||
boolean valid = isAuthorisationValid(authorisation);
|
boolean valid = isAuthorisationValid(authorisation);
|
||||||
LokiDeviceLinkingSession linkingSession = LokiDeviceLinkingSession.Companion.getShared();
|
DeviceLinkingSession linkingSession = DeviceLinkingSession.Companion.getShared();
|
||||||
if (valid && linkingSession.isListeningForLinkingRequest()) {
|
if (valid && linkingSession.isListeningForLinkingRequests()) {
|
||||||
linkingSession.receivedLinkingRequest(authorisation);
|
linkingSession.processLinkingRequest(authorisation);
|
||||||
} else {
|
} else {
|
||||||
// Remove pre key bundle from the user
|
// Remove pre key bundle from the user
|
||||||
DatabaseFactory.getLokiPreKeyBundleDatabase(context).removePreKeyBundle(envelope.getSource());
|
DatabaseFactory.getLokiPreKeyBundleDatabase(context).removePreKeyBundle(envelope.getSource());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handlePairingAuthorisationForSelf(@NonNull LokiPairingAuthorisation authorisation, @NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceContent content) {
|
private void handlePairingAuthorisationForSelf(@NonNull PairingAuthorisation authorisation, @NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceContent content) {
|
||||||
if (TextSecurePreferences.isSecondaryDevice(context)) {
|
if (TextSecurePreferences.isSecondaryDevice(context)) {
|
||||||
Log.w("Loki", "Received an unexpected pairing authorisation (device is already paired as secondary device). Ignoring.");
|
Log.w("Loki", "Received an unexpected pairing authorisation (device is already paired as secondary device). Ignoring.");
|
||||||
return;
|
return;
|
||||||
@ -1069,17 +1081,17 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!LokiDeviceLinkingSession.Companion.getShared().isListeningForLinkingRequest()) {
|
if (!DeviceLinkingSession.Companion.getShared().isListeningForLinkingRequests()) {
|
||||||
Log.w("Loki", "Received authorisation but device is not is listening.");
|
Log.w("Loki", "Received authorisation but device is not is listening.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unimplemented for REQUEST
|
// Unimplemented for REQUEST
|
||||||
if (authorisation.getType() != LokiPairingAuthorisation.Type.GRANT) { return; }
|
if (authorisation.getType() != PairingAuthorisation.Type.GRANT) { return; }
|
||||||
Log.d("Loki", "Receiving pairing authorisation from: " + authorisation.getPrimaryDevicePublicKey());
|
Log.d("Loki", "Receiving pairing authorisation from: " + authorisation.getPrimaryDevicePublicKey());
|
||||||
|
|
||||||
// Send out accept event
|
// Send out accept event
|
||||||
LokiDeviceLinkingSession.Companion.getShared().acceptedLinkingRequest(authorisation);
|
DeviceLinkingSession.Companion.getShared().processLinkingAuthorization(authorisation);
|
||||||
|
|
||||||
// Set the current device as secondary and update our authorisations
|
// Set the current device as secondary and update our authorisations
|
||||||
String ourNumber = TextSecurePreferences.getLocalNumber(context);
|
String ourNumber = TextSecurePreferences.getLocalNumber(context);
|
||||||
@ -1092,7 +1104,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
|
|
||||||
// Propagate the updates to the file server
|
// Propagate the updates to the file server
|
||||||
LokiStorageAPI storageAPI = LokiStorageAPI.Companion.getShared();
|
LokiStorageAPI storageAPI = LokiStorageAPI.Companion.getShared();
|
||||||
if (storageAPI != null) { storageAPI.updateOurDeviceMappings(); }
|
if (storageAPI != null) { storageAPI.updateUserDeviceMappings(); }
|
||||||
|
|
||||||
// Update display names
|
// Update display names
|
||||||
if (content.senderDisplayName.isPresent() && content.senderDisplayName.get().length() > 0) {
|
if (content.senderDisplayName.isPresent() && content.senderDisplayName.get().length() > 0) {
|
||||||
|
@ -5,14 +5,14 @@ import android.support.v7.app.AlertDialog
|
|||||||
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||||
import org.thoughtcrime.securesms.logging.Log
|
import org.thoughtcrime.securesms.logging.Log
|
||||||
import org.whispersystems.signalservice.loki.api.LokiDeviceLinkingSession
|
|
||||||
import org.whispersystems.signalservice.loki.api.LokiDeviceLinkingSessionListener
|
|
||||||
import org.whispersystems.signalservice.loki.api.LokiPairingAuthorisation
|
|
||||||
import org.whispersystems.signalservice.loki.api.LokiStorageAPI
|
|
||||||
import org.whispersystems.signalservice.loki.utilities.retryIfNeeded
|
|
||||||
import org.thoughtcrime.securesms.util.Util
|
import org.thoughtcrime.securesms.util.Util
|
||||||
|
import org.whispersystems.signalservice.loki.api.DeviceLinkingSession
|
||||||
|
import org.whispersystems.signalservice.loki.api.DeviceLinkingSessionListener
|
||||||
|
import org.whispersystems.signalservice.loki.api.LokiStorageAPI
|
||||||
|
import org.whispersystems.signalservice.loki.api.PairingAuthorisation
|
||||||
|
import org.whispersystems.signalservice.loki.utilities.retryIfNeeded
|
||||||
|
|
||||||
class DeviceLinkingDialog private constructor(private val context: Context, private val mode: DeviceLinkingView.Mode, private val delegate: DeviceLinkingDialogDelegate? = null): DeviceLinkingViewDelegate, LokiDeviceLinkingSessionListener {
|
class DeviceLinkingDialog private constructor(private val context: Context, private val mode: DeviceLinkingView.Mode, private val delegate: DeviceLinkingDialogDelegate? = null): DeviceLinkingViewDelegate, DeviceLinkingSessionListener {
|
||||||
private lateinit var view: DeviceLinkingView
|
private lateinit var view: DeviceLinkingView
|
||||||
private lateinit var dialog: AlertDialog
|
private lateinit var dialog: AlertDialog
|
||||||
|
|
||||||
@ -42,20 +42,20 @@ class DeviceLinkingDialog private constructor(private val context: Context, priv
|
|||||||
|
|
||||||
// region Private functions
|
// region Private functions
|
||||||
private fun startListening() {
|
private fun startListening() {
|
||||||
LokiDeviceLinkingSession.shared.startListeningForLinkingRequests()
|
DeviceLinkingSession.shared.startListeningForLinkingRequests()
|
||||||
LokiDeviceLinkingSession.shared.addListener(this)
|
DeviceLinkingSession.shared.addListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun stopListening() {
|
private fun stopListening() {
|
||||||
LokiDeviceLinkingSession.shared.stopListeningForLinkingRequests()
|
DeviceLinkingSession.shared.stopListeningForLinkingRequests()
|
||||||
LokiDeviceLinkingSession.shared.removeListener(this)
|
DeviceLinkingSession.shared.removeListener(this)
|
||||||
}
|
}
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region Dialog View Delegate
|
// region Dialog View Delegate
|
||||||
override fun authorise(pairing: LokiPairingAuthorisation): Boolean {
|
override fun authorise(pairing: PairingAuthorisation): Boolean {
|
||||||
val signedAuthorisation = pairing.sign(LokiPairingAuthorisation.Type.GRANT, userPrivateKey)
|
val signedAuthorisation = pairing.sign(PairingAuthorisation.Type.GRANT, userPrivateKey)
|
||||||
if (signedAuthorisation == null || signedAuthorisation.type != LokiPairingAuthorisation.Type.GRANT) {
|
if (signedAuthorisation == null || signedAuthorisation.type != PairingAuthorisation.Type.GRANT) {
|
||||||
Log.e("Loki", "Failed to sign grant authorisation")
|
Log.e("Loki", "Failed to sign grant authorisation")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -71,7 +71,7 @@ class DeviceLinkingDialog private constructor(private val context: Context, priv
|
|||||||
DatabaseFactory.getLokiAPIDatabase(context).insertOrUpdatePairingAuthorisation(signedAuthorisation)
|
DatabaseFactory.getLokiAPIDatabase(context).insertOrUpdatePairingAuthorisation(signedAuthorisation)
|
||||||
|
|
||||||
// Update the api
|
// Update the api
|
||||||
LokiStorageAPI.shared?.updateOurDeviceMappings()
|
LokiStorageAPI.shared?.updateUserDeviceMappings()
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -93,22 +93,22 @@ class DeviceLinkingDialog private constructor(private val context: Context, priv
|
|||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region Loki Device Session Listener
|
// region Loki Device Session Listener
|
||||||
override fun onDeviceLinkingRequestReceived(authorisation: LokiPairingAuthorisation) {
|
override fun requestUserAuthorization(authorisation: PairingAuthorisation) {
|
||||||
Util.runOnMain {
|
Util.runOnMain {
|
||||||
view.requestUserAuthorization(authorisation)
|
view.requestUserAuthorization(authorisation)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop listening to any more requests
|
// Stop listening to any more requests
|
||||||
LokiDeviceLinkingSession.shared.stopListeningForLinkingRequests()
|
DeviceLinkingSession.shared.stopListeningForLinkingRequests()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDeviceLinkRequestAccepted(authorisation: LokiPairingAuthorisation) {
|
override fun onDeviceLinkRequestAuthorized(authorisation: PairingAuthorisation) {
|
||||||
Util.runOnMain {
|
Util.runOnMain {
|
||||||
view.onDeviceLinkAuthorized(authorisation)
|
view.onDeviceLinkAuthorized(authorisation)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop listening to any more requests
|
// Stop listening to any more requests
|
||||||
LokiDeviceLinkingSession.shared.stopListeningForLinkingRequests()
|
DeviceLinkingSession.shared.stopListeningForLinkingRequests()
|
||||||
}
|
}
|
||||||
// endregion
|
// endregion
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
package org.thoughtcrime.securesms.loki
|
package org.thoughtcrime.securesms.loki
|
||||||
|
|
||||||
import org.whispersystems.signalservice.loki.api.LokiPairingAuthorisation
|
import org.whispersystems.signalservice.loki.api.PairingAuthorisation
|
||||||
|
|
||||||
interface DeviceLinkingDialogDelegate {
|
interface DeviceLinkingDialogDelegate {
|
||||||
fun handleDeviceLinkAuthorized() {}
|
fun handleDeviceLinkAuthorized() {}
|
||||||
@ -8,5 +8,5 @@ interface DeviceLinkingDialogDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface DeviceLinkingViewDelegate: DeviceLinkingDialogDelegate {
|
interface DeviceLinkingViewDelegate: DeviceLinkingDialogDelegate {
|
||||||
fun authorise(pairing: LokiPairingAuthorisation): Boolean { return false }
|
fun authorise(pairing: PairingAuthorisation): Boolean { return false }
|
||||||
}
|
}
|
@ -4,22 +4,14 @@ import android.content.Context
|
|||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.PorterDuff
|
import android.graphics.PorterDuff
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import kotlinx.android.synthetic.main.view_device_linking.view.*
|
import kotlinx.android.synthetic.main.view_device_linking.view.*
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
import org.thoughtcrime.securesms.ApplicationContext
|
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
import org.whispersystems.libsignal.util.guava.Optional
|
import org.whispersystems.signalservice.loki.api.PairingAuthorisation
|
||||||
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair
|
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage
|
|
||||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress
|
|
||||||
import org.whispersystems.signalservice.loki.api.LokiDeviceLinkingSession
|
|
||||||
import org.whispersystems.signalservice.loki.api.LokiPairingAuthorisation
|
|
||||||
import org.whispersystems.signalservice.loki.crypto.MnemonicCodec
|
import org.whispersystems.signalservice.loki.crypto.MnemonicCodec
|
||||||
import org.whispersystems.signalservice.loki.utilities.removing05PrefixIfNeeded
|
import org.whispersystems.signalservice.loki.utilities.removing05PrefixIfNeeded
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@ -28,7 +20,7 @@ import java.io.FileOutputStream
|
|||||||
class DeviceLinkingView private constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, private val mode: Mode, private var delegate: DeviceLinkingViewDelegate) : LinearLayout(context, attrs, defStyleAttr) {
|
class DeviceLinkingView private constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, private val mode: Mode, private var delegate: DeviceLinkingViewDelegate) : LinearLayout(context, attrs, defStyleAttr) {
|
||||||
private lateinit var languageFileDirectory: File
|
private lateinit var languageFileDirectory: File
|
||||||
var dismiss: (() -> Unit)? = null
|
var dismiss: (() -> Unit)? = null
|
||||||
var pairingAuthorisation: LokiPairingAuthorisation? = null
|
var pairingAuthorisation: PairingAuthorisation? = null
|
||||||
private set
|
private set
|
||||||
|
|
||||||
// region Types
|
// region Types
|
||||||
@ -91,14 +83,14 @@ class DeviceLinkingView private constructor(context: Context, attrs: AttributeSe
|
|||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region Device Linking
|
// region Device Linking
|
||||||
fun requestUserAuthorization(authorisation: LokiPairingAuthorisation) {
|
fun requestUserAuthorization(authorisation: PairingAuthorisation) {
|
||||||
// To be called when a linking request has been received
|
// To be called when a linking request has been received
|
||||||
if (mode != Mode.Master) {
|
if (mode != Mode.Master) {
|
||||||
Log.w("Loki", "Received request for pairing authorisation on a slave device")
|
Log.w("Loki", "Received request for pairing authorisation on a slave device")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (authorisation.type != LokiPairingAuthorisation.Type.REQUEST) {
|
if (authorisation.type != PairingAuthorisation.Type.REQUEST) {
|
||||||
Log.w("Loki", "Received request for GRANT pairing authorisation! It shouldn't be possible!!")
|
Log.w("Loki", "Received request for GRANT pairing authorisation! It shouldn't be possible!!")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -132,7 +124,7 @@ class DeviceLinkingView private constructor(context: Context, attrs: AttributeSe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onDeviceLinkAuthorized(authorisation: LokiPairingAuthorisation) {
|
fun onDeviceLinkAuthorized(authorisation: PairingAuthorisation) {
|
||||||
// To be called when a device link was accepted by the primary device
|
// To be called when a device link was accepted by the primary device
|
||||||
if (mode == Mode.Master || pairingAuthorisation != null) { return }
|
if (mode == Mode.Master || pairingAuthorisation != null) { return }
|
||||||
pairingAuthorisation = authorisation
|
pairingAuthorisation = authorisation
|
||||||
|
@ -8,7 +8,7 @@ import org.thoughtcrime.securesms.util.Base64
|
|||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
import org.whispersystems.signalservice.loki.api.LokiAPIDatabaseProtocol
|
import org.whispersystems.signalservice.loki.api.LokiAPIDatabaseProtocol
|
||||||
import org.whispersystems.signalservice.loki.api.LokiAPITarget
|
import org.whispersystems.signalservice.loki.api.LokiAPITarget
|
||||||
import org.whispersystems.signalservice.loki.api.LokiPairingAuthorisation
|
import org.whispersystems.signalservice.loki.api.PairingAuthorisation
|
||||||
|
|
||||||
// TODO: Clean this up a bit
|
// TODO: Clean this up a bit
|
||||||
|
|
||||||
@ -105,14 +105,14 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
|
|||||||
database.insertOrUpdate(receivedMessageHashValuesCache, row, "$userID = ?", wrap(userPublicKey))
|
database.insertOrUpdate(receivedMessageHashValuesCache, row, "$userID = ?", wrap(userPublicKey))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getGroupChatAuthToken(server: String): String? {
|
override fun getAuthToken(server: String): String? {
|
||||||
val database = databaseHelper.readableDatabase
|
val database = databaseHelper.readableDatabase
|
||||||
return database.get(groupChatAuthTokenTable, "${Companion.server} = ?", wrap(server)) { cursor ->
|
return database.get(groupChatAuthTokenTable, "${Companion.server} = ?", wrap(server)) { cursor ->
|
||||||
cursor.getString(cursor.getColumnIndexOrThrow(token))
|
cursor.getString(cursor.getColumnIndexOrThrow(token))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setGroupChatAuthToken(server: String, newValue: String?) {
|
override fun setAuthToken(server: String, newValue: String?) {
|
||||||
val database = databaseHelper.writableDatabase
|
val database = databaseHelper.writableDatabase
|
||||||
if (newValue != null) {
|
if (newValue != null) {
|
||||||
val row = wrap(mapOf(Companion.server to server, token to newValue))
|
val row = wrap(mapOf(Companion.server to server, token to newValue))
|
||||||
@ -152,18 +152,18 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
|
|||||||
database.insertOrUpdate(lastDeletionServerIDCache, row, "$lastDeletionServerIDCacheIndex = ?", wrap(index))
|
database.insertOrUpdate(lastDeletionServerIDCache, row, "$lastDeletionServerIDCacheIndex = ?", wrap(index))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPairingAuthorisations(pubKey: String): List<LokiPairingAuthorisation> {
|
override fun getPairingAuthorisations(hexEncodedPublicKey: String): List<PairingAuthorisation> {
|
||||||
val database = databaseHelper.readableDatabase
|
val database = databaseHelper.readableDatabase
|
||||||
return database.getAll(multiDeviceAuthTable, "$primaryDevice = ? OR $secondaryDevice = ?", arrayOf(pubKey, pubKey)) { cursor ->
|
return database.getAll(multiDeviceAuthTable, "$primaryDevice = ? OR $secondaryDevice = ?", arrayOf(hexEncodedPublicKey, hexEncodedPublicKey)) { cursor ->
|
||||||
val primaryDevicePubKey = cursor.getString(primaryDevice)
|
val primaryDevicePubKey = cursor.getString(primaryDevice)
|
||||||
val secondaryDevicePubKey = cursor.getString(secondaryDevice)
|
val secondaryDevicePubKey = cursor.getString(secondaryDevice)
|
||||||
val requestSignature: ByteArray? = if (cursor.isNull(cursor.getColumnIndexOrThrow(requestSignature))) null else cursor.getBase64EncodedData(requestSignature)
|
val requestSignature: ByteArray? = if (cursor.isNull(cursor.getColumnIndexOrThrow(requestSignature))) null else cursor.getBase64EncodedData(requestSignature)
|
||||||
val grantSignature: ByteArray? = if (cursor.isNull(cursor.getColumnIndexOrThrow(grantSignature))) null else cursor.getBase64EncodedData(grantSignature)
|
val grantSignature: ByteArray? = if (cursor.isNull(cursor.getColumnIndexOrThrow(grantSignature))) null else cursor.getBase64EncodedData(grantSignature)
|
||||||
LokiPairingAuthorisation(primaryDevicePubKey, secondaryDevicePubKey, requestSignature, grantSignature)
|
PairingAuthorisation(primaryDevicePubKey, secondaryDevicePubKey, requestSignature, grantSignature)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun insertOrUpdatePairingAuthorisation(authorisation: LokiPairingAuthorisation) {
|
override fun insertOrUpdatePairingAuthorisation(authorisation: PairingAuthorisation) {
|
||||||
val database = databaseHelper.writableDatabase
|
val database = databaseHelper.writableDatabase
|
||||||
val values = ContentValues()
|
val values = ContentValues()
|
||||||
values.put(primaryDevice, authorisation.primaryDevicePublicKey)
|
values.put(primaryDevice, authorisation.primaryDevicePublicKey)
|
||||||
@ -173,9 +173,9 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
|
|||||||
database.insertOrUpdate(multiDeviceAuthTable, values, "$primaryDevice = ? AND $secondaryDevice = ?", arrayOf(authorisation.primaryDevicePublicKey, authorisation.secondaryDevicePublicKey))
|
database.insertOrUpdate(multiDeviceAuthTable, values, "$primaryDevice = ? AND $secondaryDevice = ?", arrayOf(authorisation.primaryDevicePublicKey, authorisation.secondaryDevicePublicKey))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun removePairingAuthorisations(pubKey: String) {
|
override fun removePairingAuthorisations(hexEncodedPublicKey: String) {
|
||||||
val database = databaseHelper.readableDatabase
|
val database = databaseHelper.readableDatabase
|
||||||
database.delete(multiDeviceAuthTable, "$primaryDevice = ? OR $secondaryDevice = ?", arrayOf(pubKey, pubKey))
|
database.delete(multiDeviceAuthTable, "$primaryDevice = ? OR $secondaryDevice = ?", arrayOf(hexEncodedPublicKey, hexEncodedPublicKey))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,35 +1,27 @@
|
|||||||
package org.thoughtcrime.securesms.loki
|
package org.thoughtcrime.securesms.loki
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Handler
|
|
||||||
import android.os.Looper
|
|
||||||
import nl.komponents.kovenant.Promise
|
import nl.komponents.kovenant.Promise
|
||||||
import nl.komponents.kovenant.deferred
|
import nl.komponents.kovenant.deferred
|
||||||
import nl.komponents.kovenant.functional.map
|
|
||||||
import org.thoughtcrime.securesms.ApplicationContext
|
import org.thoughtcrime.securesms.ApplicationContext
|
||||||
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.jobs.BaseJob
|
|
||||||
import org.thoughtcrime.securesms.jobs.PushTextSendJob
|
|
||||||
import org.thoughtcrime.securesms.logging.Log
|
import org.thoughtcrime.securesms.logging.Log
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient
|
import org.thoughtcrime.securesms.recipients.Recipient
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
import org.whispersystems.libsignal.util.guava.Optional
|
import org.whispersystems.libsignal.util.guava.Optional
|
||||||
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair
|
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceContent
|
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage
|
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope
|
|
||||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress
|
import org.whispersystems.signalservice.api.push.SignalServiceAddress
|
||||||
import org.whispersystems.signalservice.loki.api.LokiGroupChatAPI
|
|
||||||
import org.whispersystems.signalservice.loki.api.LokiPairingAuthorisation
|
|
||||||
import org.whispersystems.signalservice.loki.api.LokiStorageAPI
|
import org.whispersystems.signalservice.loki.api.LokiStorageAPI
|
||||||
|
import org.whispersystems.signalservice.loki.api.PairingAuthorisation
|
||||||
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus
|
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus
|
||||||
|
|
||||||
fun getAllDevices(context: Context, pubKey: String, storageAPI: LokiStorageAPI, block: (devicePubKey: String, isFriend: Boolean, friendCount: Int) -> Unit) {
|
fun getAllDevices(context: Context, pubKey: String, storageAPI: LokiStorageAPI, block: (devicePubKey: String, isFriend: Boolean, friendCount: Int) -> Unit) {
|
||||||
val ourPubKey = TextSecurePreferences.getLocalNumber(context)
|
val ourPubKey = TextSecurePreferences.getLocalNumber(context)
|
||||||
|
|
||||||
// Get all the devices and run our logic on them
|
// Get all the devices and run our logic on them
|
||||||
storageAPI.getAllDevices(pubKey).success { items ->
|
storageAPI.getAllDevicePublicKeys(pubKey).success { items ->
|
||||||
val devices = items.toMutableSet()
|
val devices = items.toMutableSet()
|
||||||
// Remove our self if we intended this message to go to another recipient
|
// Remove our self if we intended this message to go to another recipient
|
||||||
if (pubKey != ourPubKey) {
|
if (pubKey != ourPubKey) {
|
||||||
@ -51,7 +43,7 @@ fun shouldAutomaticallyBecomeFriendsWithDevice(pubKey: String, context: Context)
|
|||||||
// If so then we add them automatically as a friend
|
// If so then we add them automatically as a friend
|
||||||
|
|
||||||
val deferred = deferred<Boolean, Unit>()
|
val deferred = deferred<Boolean, Unit>()
|
||||||
storageAPI.getPrimaryDevice(pubKey).success { primaryDevicePubKey ->
|
storageAPI.getPrimaryDevicePublicKey(pubKey).success { primaryDevicePubKey ->
|
||||||
// Make sure we have a primary device
|
// Make sure we have a primary device
|
||||||
if (primaryDevicePubKey == null) {
|
if (primaryDevicePubKey == null) {
|
||||||
deferred.resolve(false)
|
deferred.resolve(false)
|
||||||
@ -63,7 +55,7 @@ fun shouldAutomaticallyBecomeFriendsWithDevice(pubKey: String, context: Context)
|
|||||||
if (primaryDevicePubKey == ourPubKey) {
|
if (primaryDevicePubKey == ourPubKey) {
|
||||||
// If the friend request is from our secondary device then we need to confirm and check that we have it registered.
|
// If the friend request is from our secondary device then we need to confirm and check that we have it registered.
|
||||||
// If we do then add it
|
// If we do then add it
|
||||||
storageAPI.getSecondaryDevices(ourPubKey).success { secondaryDevices ->
|
storageAPI.getSecondaryDevicePublicKeys(ourPubKey).success { secondaryDevices ->
|
||||||
// We should become friends if the pubKey is in our secondary device list
|
// We should become friends if the pubKey is in our secondary device list
|
||||||
deferred.resolve(secondaryDevices.contains(pubKey))
|
deferred.resolve(secondaryDevices.contains(pubKey))
|
||||||
}.fail {
|
}.fail {
|
||||||
@ -88,13 +80,13 @@ fun shouldAutomaticallyBecomeFriendsWithDevice(pubKey: String, context: Context)
|
|||||||
return deferred.promise
|
return deferred.promise
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sendAuthorisationMessage(context: Context, contactHexEncodedPublicKey: String, authorisation: LokiPairingAuthorisation): Promise<Unit, Exception> {
|
fun sendAuthorisationMessage(context: Context, contactHexEncodedPublicKey: String, authorisation: PairingAuthorisation): Promise<Unit, Exception> {
|
||||||
val messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender()
|
val messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender()
|
||||||
val address = SignalServiceAddress(contactHexEncodedPublicKey)
|
val address = SignalServiceAddress(contactHexEncodedPublicKey)
|
||||||
val message = SignalServiceDataMessage.newBuilder().withBody("").withPairingAuthorisation(authorisation)
|
val message = SignalServiceDataMessage.newBuilder().withBody("").withPairingAuthorisation(authorisation)
|
||||||
|
|
||||||
// A REQUEST should always act as a friend request. A GRANT should always be replying back as a normal message.
|
// A REQUEST should always act as a friend request. A GRANT should always be replying back as a normal message.
|
||||||
if (authorisation.type == LokiPairingAuthorisation.Type.REQUEST) {
|
if (authorisation.type == PairingAuthorisation.Type.REQUEST) {
|
||||||
val preKeyBundle = DatabaseFactory.getLokiPreKeyBundleDatabase(context).generatePreKeyBundle(address.number)
|
val preKeyBundle = DatabaseFactory.getLokiPreKeyBundleDatabase(context).generatePreKeyBundle(address.number)
|
||||||
message.asFriendRequest(true).withPreKeyBundle(preKeyBundle)
|
message.asFriendRequest(true).withPreKeyBundle(preKeyBundle)
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ import org.thoughtcrime.securesms.util.Hex
|
|||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
import org.whispersystems.curve25519.Curve25519
|
import org.whispersystems.curve25519.Curve25519
|
||||||
import org.whispersystems.libsignal.util.KeyHelper
|
import org.whispersystems.libsignal.util.KeyHelper
|
||||||
import org.whispersystems.signalservice.loki.api.LokiPairingAuthorisation
|
import org.whispersystems.signalservice.loki.api.PairingAuthorisation
|
||||||
import org.whispersystems.signalservice.loki.crypto.MnemonicCodec
|
import org.whispersystems.signalservice.loki.crypto.MnemonicCodec
|
||||||
import org.whispersystems.signalservice.loki.utilities.Analytics
|
import org.whispersystems.signalservice.loki.utilities.Analytics
|
||||||
import org.whispersystems.signalservice.loki.utilities.PublicKeyValidation
|
import org.whispersystems.signalservice.loki.utilities.PublicKeyValidation
|
||||||
@ -206,7 +206,7 @@ class SeedActivity : BaseActionBarActivity() {
|
|||||||
|
|
||||||
// Build the pairing request
|
// Build the pairing request
|
||||||
val primaryDevicePublicKey = publicKeyEditText.text.trim().toString()
|
val primaryDevicePublicKey = publicKeyEditText.text.trim().toString()
|
||||||
val authorisation = LokiPairingAuthorisation(primaryDevicePublicKey, hexEncodedPublicKey).sign(LokiPairingAuthorisation.Type.REQUEST, keyPair.privateKey.serialize())
|
val authorisation = PairingAuthorisation(primaryDevicePublicKey, hexEncodedPublicKey).sign(PairingAuthorisation.Type.REQUEST, keyPair.privateKey.serialize())
|
||||||
if (authorisation == null) {
|
if (authorisation == null) {
|
||||||
Log.w("Loki", "Failed to sign outgoing pairing request :(")
|
Log.w("Loki", "Failed to sign outgoing pairing request :(")
|
||||||
resetRegistration()
|
resetRegistration()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user