This commit is contained in:
Niels Andriesse 2019-10-08 14:10:16 +11:00
parent bf958fffe1
commit a44c3fcd57
6 changed files with 54 additions and 64 deletions

View File

@ -84,14 +84,14 @@ public class TypingStatusSender {
private void sendTyping(long threadId, boolean typingStarted) { private void sendTyping(long threadId, boolean typingStarted) {
LokiStorageAPI storageAPI = LokiStorageAPI.Companion.getShared(); LokiStorageAPI storageAPI = LokiStorageAPI.Companion.getShared();
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context);
Recipient originalRecipient = threadDatabase.getRecipientForThreadId(threadId); Recipient recipient = threadDatabase.getRecipientForThreadId(threadId);
if (originalRecipient == null) { if (recipient == null) {
ApplicationContext.getInstance(context).getJobManager().add(new TypingSendJob(threadId, typingStarted)); ApplicationContext.getInstance(context).getJobManager().add(new TypingSendJob(threadId, typingStarted));
return; return;
} }
MultiDeviceUtilitiesKt.getAllDevicePublicKeys(context, originalRecipient.getAddress().serialize(), storageAPI, (devicePublicKey, isFriend, friendCount) -> { MultiDeviceUtilitiesKt.getAllDevicePublicKeys(context, recipient.getAddress().serialize(), storageAPI, (devicePublicKey, isFriend, friendCount) -> {
Recipient device = Recipient.from(context, Address.fromSerialized(devicePublicKey), false); Recipient device = Recipient.from(context, Address.fromSerialized(devicePublicKey), false);
long deviceThreadID = threadDatabase.getThreadIdIfExistsFor(device); long deviceThreadID = threadDatabase.getThreadIdIfExistsFor(device);
if (deviceThreadID > -1) { if (deviceThreadID > -1) {

View File

@ -306,7 +306,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
// TODO: Deleting the display name // TODO: Deleting the display name
if (content.getPairingAuthorisation().isPresent()) { if (content.getPairingAuthorisation().isPresent()) {
handlePairingAuthorisation(content.getPairingAuthorisation().get(), envelope, content); handlePairingMessage(content.getPairingAuthorisation().get(), envelope, content);
} else if (content.getDataMessage().isPresent()) { } else if (content.getDataMessage().isPresent()) {
SignalServiceDataMessage message = content.getDataMessage().get(); SignalServiceDataMessage message = content.getDataMessage().get();
boolean isMediaMessage = message.getAttachments().isPresent() || message.getQuote().isPresent() || message.getSharedContacts().isPresent() || message.getPreviews().isPresent() || message.getSticker().isPresent(); boolean isMediaMessage = message.getAttachments().isPresent() || message.getQuote().isPresent() || message.getSharedContacts().isPresent() || message.getPreviews().isPresent() || message.getSticker().isPresent();
@ -1030,91 +1030,82 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
} }
} }
private boolean isValidAuthorisation(@NonNull PairingAuthorisation authorisation) { private boolean isValidPairingMessage(@NonNull PairingAuthorisation authorisation) {
boolean isSecondaryDevice = TextSecurePreferences.isSecondaryDevice(context); boolean isSecondaryDevice = TextSecurePreferences.getMasterHexEncodedPublicKey(context) != null;
String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context); String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context);
boolean isRequest = (authorisation.getType() == PairingAuthorisation.Type.REQUEST); boolean isRequest = (authorisation.getType() == PairingAuthorisation.Type.REQUEST);
if (authorisation.getRequestSignature() == null) { if (authorisation.getRequestSignature() == null) {
Log.d("Loki", "Ignoring pairing message without a request signature."); Log.d("Loki", "Ignoring pairing request message without a request signature.");
return false; return false;
} else if (isRequest && isSecondaryDevice) { } else if (isRequest && isSecondaryDevice) {
Log.d("Loki", "Ignoring pairing message while in slave mode."); Log.d("Loki", "Ignoring unexpected pairing request message (the device is already paired as a secondary device).");
return false; return false;
} else if (isRequest && !authorisation.getPrimaryDevicePublicKey().equals(userHexEncodedPublicKey)) { } else if (isRequest && !authorisation.getPrimaryDevicePublicKey().equals(userHexEncodedPublicKey)) {
Log.d("Loki", "Ignoring pairing message addressed to another user."); Log.d("Loki", "Ignoring pairing request message addressed to another user.");
return false; return false;
} else if (isRequest && authorisation.getSecondaryDevicePublicKey().equals(userHexEncodedPublicKey)) { } else if (isRequest && authorisation.getSecondaryDevicePublicKey().equals(userHexEncodedPublicKey)) {
Log.d("Loki", "Ignoring pairing message from self."); Log.d("Loki", "Ignoring pairing request message from self.");
return false; return false;
} }
return authorisation.verify(); return authorisation.verify();
} }
private void handlePairingAuthorisation(@NonNull PairingAuthorisation authorisation, @NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceContent content) { private void handlePairingMessage(@NonNull PairingAuthorisation authorisation, @NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceContent content) {
String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context); String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context);
if (authorisation.getType() == PairingAuthorisation.Type.REQUEST) { if (authorisation.getType() == PairingAuthorisation.Type.REQUEST) {
handlePairingRequest(authorisation, envelope); handlePairingRequestMessage(authorisation, envelope);
} else if (authorisation.getSecondaryDevicePublicKey().equals(userHexEncodedPublicKey)) { } else if (authorisation.getSecondaryDevicePublicKey().equals(userHexEncodedPublicKey)) {
// If we were listed as the secondary device, it means we got a confirmation back from the primary device handlePairingAuthorisationMessage(authorisation, envelope, content);
handlePairingAuthorisationForSelf(authorisation, envelope, content);
} }
} }
private void handlePairingRequest(@NonNull PairingAuthorisation authorisation, @NonNull SignalServiceEnvelope envelope) { private void handlePairingRequestMessage(@NonNull PairingAuthorisation authorisation, @NonNull SignalServiceEnvelope envelope) {
boolean isValid = isValidAuthorisation(authorisation); boolean isValid = isValidPairingMessage(authorisation);
DeviceLinkingSession linkingSession = DeviceLinkingSession.Companion.getShared(); DeviceLinkingSession linkingSession = DeviceLinkingSession.Companion.getShared();
if (isValid && linkingSession.isListeningForLinkingRequests()) { if (isValid && linkingSession.isListeningForLinkingRequests()) {
linkingSession.processLinkingRequest(authorisation); linkingSession.processLinkingRequest(authorisation);
} }
} }
private void handlePairingAuthorisationForSelf(@NonNull PairingAuthorisation authorisation, @NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceContent content) { private void handlePairingAuthorisationMessage(@NonNull PairingAuthorisation authorisation, @NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceContent content) {
if (TextSecurePreferences.isSecondaryDevice(context)) { // Prepare
Log.d("Loki", "Ignoring unexpected pairing authorisation (the device is already paired as a secondary device)."); boolean isSecondaryDevice = TextSecurePreferences.getMasterHexEncodedPublicKey(context) != null;
if (isSecondaryDevice) {
Log.d("Loki", "Ignoring unexpected pairing authorisation message (the device is already paired as a secondary device).");
return; return;
} }
boolean isValid = isValidPairingMessage(authorisation);
if (!isValidAuthorisation(authorisation)) { if (!isValid) {
Log.d("Loki", "Ignoring invalid pairing authorisation."); Log.d("Loki", "Ignoring invalid pairing authorisation message.");
return; return;
} }
if (!DeviceLinkingSession.Companion.getShared().isListeningForLinkingRequests()) { if (!DeviceLinkingSession.Companion.getShared().isListeningForLinkingRequests()) {
Log.d("Loki", "Ignoring pairing authorisation."); Log.d("Loki", "Ignoring pairing authorisation message.");
return; return;
} }
// Unimplemented for REQUEST
if (authorisation.getType() != PairingAuthorisation.Type.GRANT) { return; } if (authorisation.getType() != PairingAuthorisation.Type.GRANT) { return; }
Log.d("Loki", "Receiving pairing authorisation from: " + authorisation.getPrimaryDevicePublicKey() + "."); Log.d("Loki", "Received pairing authorisation message from: " + authorisation.getPrimaryDevicePublicKey() + ".");
// Process
// Process authorisation
DeviceLinkingSession.Companion.getShared().processLinkingAuthorization(authorisation); DeviceLinkingSession.Companion.getShared().processLinkingAuthorization(authorisation);
// Store the primary device's public key
// Set the current device as secondary and update our authorisations
String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context); String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context);
DatabaseFactory.getLokiAPIDatabase(context).removePairingAuthorisations(userHexEncodedPublicKey); DatabaseFactory.getLokiAPIDatabase(context).removePairingAuthorisations(userHexEncodedPublicKey);
DatabaseFactory.getLokiAPIDatabase(context).insertOrUpdatePairingAuthorisation(authorisation); DatabaseFactory.getLokiAPIDatabase(context).insertOrUpdatePairingAuthorisation(authorisation);
TextSecurePreferences.setIsSecondaryDevice(context, true); TextSecurePreferences.setMasterHexEncodedPublicKey(context, authorisation.getPrimaryDevicePublicKey());
// Send a background message to the primary device // Send a background message to the primary device
sendBackgroundMessage(authorisation.getPrimaryDevicePublicKey()); sendBackgroundMessage(authorisation.getPrimaryDevicePublicKey());
// Propagate the updates to the file server // Propagate the updates to the file server
LokiStorageAPI storageAPI = LokiStorageAPI.Companion.getShared(); LokiStorageAPI storageAPI = LokiStorageAPI.Companion.getShared();
storageAPI.updateUserDeviceMappings(); 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) {
setDisplayName(envelope.getSource(), content.senderDisplayName.get()); setDisplayName(envelope.getSource(), content.senderDisplayName.get());
} }
} }
private void setDisplayName(String pubKey, String profileName) { private void setDisplayName(String hexEncodedPublicKey, String profileName) {
String senderDisplayName = profileName + " (..." + pubKey.substring(pubKey.length() - 8) + ")"; String displayName = profileName + " (..." + hexEncodedPublicKey.substring(hexEncodedPublicKey.length() - 8) + ")";
DatabaseFactory.getLokiUserDatabase(context).setDisplayName(pubKey, senderDisplayName); DatabaseFactory.getLokiUserDatabase(context).setDisplayName(hexEncodedPublicKey, displayName);
} }
private void updateGroupChatMessageServerID(Optional<Long> messageServerIDOrNull, Optional<InsertResult> insertResult) { private void updateGroupChatMessageServerID(Optional<Long> messageServerIDOrNull, Optional<InsertResult> insertResult) {
@ -1126,9 +1117,8 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
} }
private void acceptFriendRequestIfNeeded(@NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceContent content) { private void acceptFriendRequestIfNeeded(@NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceContent content) {
if (envelope.isFriendRequest()) { return; }
// If we get anything other than a friend request, we can assume that we have a session with the other user // If we get anything other than a friend request, we can assume that we have a session with the other user
if (envelope.isFriendRequest()) { return; }
becomeFriendsWithContact(content.getSender()); becomeFriendsWithContact(content.getSender());
} }
@ -1142,10 +1132,10 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
// it must be a friend request accepted message. Declining a friend request doesn't send a message. // it must be a friend request accepted message. Declining a friend request doesn't send a message.
lokiThreadDatabase.setFriendRequestStatus(threadID, LokiThreadFriendRequestStatus.FRIENDS); lokiThreadDatabase.setFriendRequestStatus(threadID, LokiThreadFriendRequestStatus.FRIENDS);
// Update the last message if needed // Update the last message if needed
SmsDatabase messageDatabase = DatabaseFactory.getSmsDatabase(context); SmsDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context);
LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context); LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context);
int messageCount = messageDatabase.getMessageCountForThread(threadID); int messageCount = smsDatabase.getMessageCountForThread(threadID);
long messageID = messageDatabase.getIDForMessageAtIndex(threadID, messageCount - 1); long messageID = smsDatabase.getIDForMessageAtIndex(threadID, messageCount - 1);
if (messageID > -1 && lokiMessageDatabase.getFriendRequestStatus(messageID) != LokiMessageFriendRequestStatus.REQUEST_ACCEPTED) { if (messageID > -1 && lokiMessageDatabase.getFriendRequestStatus(messageID) != LokiMessageFriendRequestStatus.REQUEST_ACCEPTED) {
lokiMessageDatabase.setFriendRequestStatus(messageID, LokiMessageFriendRequestStatus.REQUEST_ACCEPTED); lokiMessageDatabase.setFriendRequestStatus(messageID, LokiMessageFriendRequestStatus.REQUEST_ACCEPTED);
} }

View File

@ -198,7 +198,7 @@ public class PushTextSendJob extends PushSendJob implements InjectableType {
// Loki - Include a pre key bundle if the message is a friend request or an end session message // Loki - Include a pre key bundle if the message is a friend request or an end session message
PreKeyBundle preKeyBundle; PreKeyBundle preKeyBundle;
if (isFriendRequest|| message.isEndSession()) { if (isFriendRequest || message.isEndSession()) {
preKeyBundle = DatabaseFactory.getLokiPreKeyBundleDatabase(context).generatePreKeyBundle(address.getNumber()); preKeyBundle = DatabaseFactory.getLokiPreKeyBundleDatabase(context).generatePreKeyBundle(address.getNumber());
} else { } else {
preKeyBundle = null; preKeyBundle = null;

View File

@ -189,7 +189,7 @@ class SeedActivity : BaseActionBarActivity(), DeviceLinkingDialogDelegate {
when (mode) { when (mode) {
Mode.Register -> Analytics.shared.track("Seed Created") Mode.Register -> Analytics.shared.track("Seed Created")
Mode.Restore -> Analytics.shared.track("Seed Restored") Mode.Restore -> Analytics.shared.track("Seed Restored")
Mode.Link -> Analytics.shared.track("Device Linked") Mode.Link -> Analytics.shared.track("Device Linking Attempted")
} }
if (mode == Mode.Link) { if (mode == Mode.Link) {
TextSecurePreferences.setHasSeenWelcomeScreen(this, true) TextSecurePreferences.setHasSeenWelcomeScreen(this, true)