Update for desktop protocol changes

pull/225/head
nielsandriesse 5 years ago
parent 2b41a5b84e
commit 1f4d991036

@ -94,12 +94,12 @@ public final class SessionManagementProtocol : NSObject {
// Check that we don't already have a session // Check that we don't already have a session
let hasSession = storage.containsSession(publicKey, deviceId: Int32(OWSDevicePrimaryDeviceId), protocolContext: transaction) let hasSession = storage.containsSession(publicKey, deviceId: Int32(OWSDevicePrimaryDeviceId), protocolContext: transaction)
guard !hasSession else { return } guard !hasSession else { return }
// Check that we didn't already send a session request // Check that we didn't already send or process a session request
var hasSentSessionRequest = false var hasSentOrProcessedSessionRequest = false
storage.dbReadConnection.read { transaction in storage.dbReadConnection.read { transaction in
hasSentSessionRequest = storage.getSessionRequestTimestamp(for: publicKey, in: transaction) != nil hasSentOrProcessedSessionRequest = storage.getSessionRequestTimestamp(for: publicKey, in: transaction) != nil
} }
guard !hasSentSessionRequest else { return } guard !hasSentOrProcessedSessionRequest else { return }
// Create the thread if needed // Create the thread if needed
let thread = TSContactThread.getOrCreateThread(withContactId: publicKey, transaction: transaction) let thread = TSContactThread.getOrCreateThread(withContactId: publicKey, transaction: transaction)
thread.save(with: transaction) thread.save(with: transaction)
@ -184,9 +184,9 @@ public final class SessionManagementProtocol : NSObject {
return print("[Loki] Couldn't parse pre key bundle received from: \(publicKey).") return print("[Loki] Couldn't parse pre key bundle received from: \(publicKey).")
} }
if isSessionRequestMessage(protoContent.dataMessage), if isSessionRequestMessage(protoContent.dataMessage),
let sentSessionRequestTimestamp = storage.getSessionRequestTimestamp(for: publicKey, in: transaction), let sessionRequestTimestamp = storage.getSessionRequestTimestamp(for: publicKey, in: transaction),
envelope.timestamp < NSDate.ows_millisecondsSince1970(for: sentSessionRequestTimestamp) { envelope.timestamp < NSDate.ows_millisecondsSince1970(for: sessionRequestTimestamp) {
// We sent a session request after this one was sent // We sent or processed a session request after this one was sent
return print("[Loki] Ignoring session request from: \(publicKey).") return print("[Loki] Ignoring session request from: \(publicKey).")
} }
storage.setPreKeyBundle(preKeyBundle, forContact: publicKey, transaction: transaction) storage.setPreKeyBundle(preKeyBundle, forContact: publicKey, transaction: transaction)
@ -199,10 +199,11 @@ public final class SessionManagementProtocol : NSObject {
let publicKey = envelope.source! // Set during UD decryption let publicKey = envelope.source! // Set during UD decryption
if let sentSessionRequestTimestamp = storage.getSessionRequestTimestamp(for: publicKey, in: transaction), if let sentSessionRequestTimestamp = storage.getSessionRequestTimestamp(for: publicKey, in: transaction),
envelope.timestamp < NSDate.ows_millisecondsSince1970(for: sentSessionRequestTimestamp) { envelope.timestamp < NSDate.ows_millisecondsSince1970(for: sentSessionRequestTimestamp) {
// We sent a session request after this one was sent // We sent or processed a session request after this one was sent
print("[Loki] Ignoring session request from: \(publicKey).") print("[Loki] Ignoring session request from: \(publicKey).")
return false return false
} }
storage.setSessionRequestTimestamp(for: publicKey, to: Date(), in: transaction)
sendSessionEstablishedMessage(to: publicKey, in: transaction) sendSessionEstablishedMessage(to: publicKey, in: transaction)
return true return true
} }

@ -25,6 +25,7 @@
#import "OWSIncomingSentMessageTranscript.h" #import "OWSIncomingSentMessageTranscript.h"
#import "OWSMessageSender.h" #import "OWSMessageSender.h"
#import "OWSMessageUtils.h" #import "OWSMessageUtils.h"
#import "OWSOutgoingNullMessage.h"
#import "OWSOutgoingReceiptManager.h" #import "OWSOutgoingReceiptManager.h"
#import "OWSPrimaryStorage+SessionStore.h" #import "OWSPrimaryStorage+SessionStore.h"
#import "OWSPrimaryStorage+Loki.h" #import "OWSPrimaryStorage+Loki.h"
@ -482,7 +483,53 @@ NS_ASSUME_NONNULL_BEGIN
} else if (contentProto.typingMessage) { } else if (contentProto.typingMessage) {
[self handleIncomingEnvelope:envelope withTypingMessage:contentProto.typingMessage transaction:transaction]; [self handleIncomingEnvelope:envelope withTypingMessage:contentProto.typingMessage transaction:transaction];
} else if (contentProto.nullMessage) { } else if (contentProto.nullMessage) {
OWSLogInfo(@"Received null message."); // Loki: This is needed for compatibility with refactored desktop clients
// ========
NSString *publicKey = envelope.source;
if (envelope.type == SSKProtoEnvelopeTypeFriendRequest) {
TSContactThread *thread = [TSContactThread getOrCreateThreadWithContactId:publicKey transaction:transaction];
[thread saveWithTransaction:transaction];
OWSOutgoingNullMessage *sessionEstablishedMessage = [[OWSOutgoingNullMessage alloc] initOutgoingMessageWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:thread
messageBody:nil
attachmentIds:[NSMutableArray new]
expiresInSeconds:0
expireStartedAt:0
isVoiceMessage:NO
groupMetaMessage:TSGroupMetaMessageUnspecified
quotedMessage:nil
contactShare:nil
linkPreview:nil];
SSKMessageSenderJobQueue *messageSenderJobQueue = SSKEnvironment.shared.messageSenderJobQueue;
[messageSenderJobQueue addMessage:sessionEstablishedMessage transaction:transaction];
} else {
OWSLogWarn(@"Ignoring null message from: %@.", publicKey);
}
LKFriendRequestStatus friendRequestStatus = [self.primaryStorage getFriendRequestStatusForContact:publicKey transaction:transaction];
if (friendRequestStatus == LKFriendRequestStatusNone || friendRequestStatus == LKFriendRequestStatusRequestExpired) {
[self.primaryStorage setFriendRequestStatus:LKFriendRequestStatusRequestReceived forContact:publicKey transaction:transaction];
} else if (friendRequestStatus == LKFriendRequestStatusRequestSent) {
// Loki: Update device links in a blocking way
// FIXME: This is horrible for performance
// FIXME: ========
// The envelope source is set during UD decryption
if ([ECKeyPair isValidHexEncodedPublicKeyWithCandidate:publicKey]) {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
[[LKMultiDeviceProtocol updateDeviceLinksIfNeededForPublicKey:envelope.source transaction:transaction].ensureOn(queue, ^() {
dispatch_semaphore_signal(semaphore);
}).catchOn(queue, ^(NSError *error) {
dispatch_semaphore_signal(semaphore);
}) retainUntilComplete];
dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC));
}
// FIXME: ========
[self.primaryStorage setFriendRequestStatus:LKFriendRequestStatusFriends forContact:publicKey transaction:transaction];
[LKFriendRequestProtocol sendFriendRequestAcceptedMessageToPublicKey:publicKey using:transaction];
NSString *masterPublicKey = ([LKDatabaseUtilities getMasterHexEncodedPublicKeyFor:publicKey in:transaction] ?: publicKey);
[LKSyncMessagesProtocol syncContactWithPublicKey:masterPublicKey];
}
// ========
} else if (contentProto.receiptMessage) { } else if (contentProto.receiptMessage) {
[self handleIncomingEnvelope:envelope [self handleIncomingEnvelope:envelope
withReceiptMessage:contentProto.receiptMessage withReceiptMessage:contentProto.receiptMessage
@ -1552,26 +1599,6 @@ NS_ASSUME_NONNULL_BEGIN
// Loki: Handle friend request if needed // Loki: Handle friend request if needed
[LKFriendRequestProtocol handleFriendRequestMessageIfNeededFromEnvelope:envelope using:transaction]; [LKFriendRequestProtocol handleFriendRequestMessageIfNeededFromEnvelope:envelope using:transaction];
if (body.length == 0 && attachmentPointers.count < 1 && !contact) {
if (envelope.type == SSKProtoEnvelopeTypeFriendRequest) {
// Loki: This is needed for compatibility with refactored desktop clients
[LKSessionManagementProtocol sendSessionEstablishedMessageToPublicKey:publicKey transaction:transaction];
} else {
OWSLogWarn(@"Ignoring empty incoming message from: %@ with timestamp: %lu.", publicKey, (unsigned long)timestamp);
}
return nil;
}
// Loki: This is needed for compatibility with refactored desktop clients
LKFriendRequestStatus friendRequestStatus = [self.primaryStorage getFriendRequestStatusForContact:publicKey transaction:transaction];
if (friendRequestStatus == LKFriendRequestStatusNone || friendRequestStatus == LKFriendRequestStatusRequestExpired) {
[self.primaryStorage setFriendRequestStatus:LKFriendRequestStatusRequestReceived forContact:publicKey transaction:transaction];
} else if (friendRequestStatus == LKFriendRequestStatusRequestSent) {
[self.primaryStorage setFriendRequestStatus:LKFriendRequestStatusFriends forContact:publicKey transaction:transaction];
[LKFriendRequestProtocol sendFriendRequestAcceptedMessageToPublicKey:publicKey using:transaction];
[LKSyncMessagesProtocol syncContactWithPublicKey:masterPublicKey];
}
[self finalizeIncomingMessage:incomingMessage [self finalizeIncomingMessage:incomingMessage
thread:thread thread:thread
masterThread:thread masterThread:thread

@ -21,7 +21,7 @@ NS_ASSUME_NONNULL_BEGIN
groupMetaMessage:(TSGroupMetaMessage)groupMetaMessage groupMetaMessage:(TSGroupMetaMessage)groupMetaMessage
quotedMessage:(nullable TSQuotedMessage *)quotedMessage quotedMessage:(nullable TSQuotedMessage *)quotedMessage
contactShare:(nullable OWSContact *)contactShare contactShare:(nullable OWSContact *)contactShare
linkPreview:(nullable OWSLinkPreview *)linkPreview NS_UNAVAILABLE; linkPreview:(nullable OWSLinkPreview *)linkPreview;
- (instancetype)initWithContactThread:(TSContactThread *)contactThread - (instancetype)initWithContactThread:(TSContactThread *)contactThread
verificationStateSyncMessage:(OWSVerificationStateSyncMessage *)verificationStateSyncMessage; verificationStateSyncMessage:(OWSVerificationStateSyncMessage *)verificationStateSyncMessage;

@ -51,7 +51,9 @@ NS_ASSUME_NONNULL_BEGIN
{ {
SSKProtoNullMessageBuilder *nullMessageBuilder = [SSKProtoNullMessage builder]; SSKProtoNullMessageBuilder *nullMessageBuilder = [SSKProtoNullMessage builder];
NSUInteger contentLength = self.verificationStateSyncMessage.unpaddedVerifiedLength; NSUInteger contentLength;
if (self.verificationStateSyncMessage != nil) {
contentLength = self.verificationStateSyncMessage.unpaddedVerifiedLength;
OWSAssertDebug(self.verificationStateSyncMessage.paddingBytesLength > 0); OWSAssertDebug(self.verificationStateSyncMessage.paddingBytesLength > 0);
@ -61,6 +63,9 @@ NS_ASSUME_NONNULL_BEGIN
// padded by the superclass while being sent. The end result is we send a NullMessage of a non-distinct size, and a // padded by the superclass while being sent. The end result is we send a NullMessage of a non-distinct size, and a
// verification sync which is ~1-512 bytes larger then that. // verification sync which is ~1-512 bytes larger then that.
contentLength += self.verificationStateSyncMessage.paddingBytesLength; contentLength += self.verificationStateSyncMessage.paddingBytesLength;
} else {
contentLength = arc4random_uniform(512);
}
OWSAssertDebug(contentLength > 0); OWSAssertDebug(contentLength > 0);
@ -68,8 +73,8 @@ NS_ASSUME_NONNULL_BEGIN
NSError *error; NSError *error;
SSKProtoNullMessage *_Nullable nullMessage = [nullMessageBuilder buildAndReturnError:&error]; SSKProtoNullMessage *_Nullable nullMessage = [nullMessageBuilder buildAndReturnError:&error];
if (error || !nullMessage) { if (error != nil || nullMessage == nil) {
OWSFailDebug(@"could not build protobuf: %@", error); OWSFailDebug(@"Couldn't build protobuf due to error: %@.", error);
return nil; return nil;
} }
@ -77,10 +82,11 @@ NS_ASSUME_NONNULL_BEGIN
contentBuilder.nullMessage = nullMessage; contentBuilder.nullMessage = nullMessage;
NSData *_Nullable contentData = [contentBuilder buildSerializedDataAndReturnError:&error]; NSData *_Nullable contentData = [contentBuilder buildSerializedDataAndReturnError:&error];
if (error || !contentData) { if (error != nil || contentData == nil) {
OWSFailDebug(@"could not serialize protobuf: %@", error); OWSFailDebug(@"Couldn't serialize protobuf due to error: %@.", error);
return nil; return nil;
} }
return contentData; return contentData;
} }

Loading…
Cancel
Save