diff --git a/SignalServiceKit/src/Contacts/SignalRecipient.m b/SignalServiceKit/src/Contacts/SignalRecipient.m index 991f93352..451c84a32 100644 --- a/SignalServiceKit/src/Contacts/SignalRecipient.m +++ b/SignalServiceKit/src/Contacts/SignalRecipient.m @@ -3,6 +3,7 @@ // #import "SignalRecipient.h" +#import "OWSDevice.h" #import "TSAccountManager.h" #import @@ -52,7 +53,7 @@ NS_ASSUME_NONNULL_BEGIN // // OWSMessageSender will correct this if it is wrong the next time // we send a message to this recipient. - _devices = [NSOrderedSet orderedSetWithObject:@(1)]; + _devices = [NSOrderedSet orderedSetWithObject:@(OWSDevicePrimaryDeviceId)]; } return self; @@ -69,7 +70,8 @@ NS_ASSUME_NONNULL_BEGIN _devices = [NSOrderedSet new]; } - if ([self.uniqueId isEqual:[TSAccountManager localNumber]] && [self.devices containsObject:@(1)]) { + if ([self.uniqueId isEqual:[TSAccountManager localNumber]] && + [self.devices containsObject:@(OWSDevicePrimaryDeviceId)]) { OWSFailDebug(@"self as recipient device"); } @@ -89,8 +91,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)addDevices:(NSSet *)devices { OWSAssertDebug(devices.count > 0); - - if ([self.uniqueId isEqual:[TSAccountManager localNumber]] && [devices containsObject:@(1)]) { + + if ([self.uniqueId isEqual:[TSAccountManager localNumber]] && + [devices containsObject:@(OWSDevicePrimaryDeviceId)]) { OWSFailDebug(@"adding self as recipient device"); return; } diff --git a/SignalServiceKit/src/Messages/OWSMessageDecrypter.h b/SignalServiceKit/src/Messages/OWSMessageDecrypter.h index 0fcd81f9e..dda173286 100644 --- a/SignalServiceKit/src/Messages/OWSMessageDecrypter.h +++ b/SignalServiceKit/src/Messages/OWSMessageDecrypter.h @@ -16,6 +16,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly, nullable) NSData *plaintextData; @property (nonatomic, readonly) NSString *source; @property (nonatomic, readonly) UInt32 sourceDevice; +@property (nonatomic, readonly) BOOL isUDMessage; @end diff --git a/SignalServiceKit/src/Messages/OWSMessageDecrypter.m b/SignalServiceKit/src/Messages/OWSMessageDecrypter.m index 59a9b94c6..44b14d46a 100644 --- a/SignalServiceKit/src/Messages/OWSMessageDecrypter.m +++ b/SignalServiceKit/src/Messages/OWSMessageDecrypter.m @@ -8,6 +8,7 @@ #import "NotificationsProtocol.h" #import "OWSAnalytics.h" #import "OWSBlockingManager.h" +#import "OWSDevice.h" #import "OWSError.h" #import "OWSIdentityManager.h" #import "OWSPrimaryStorage+PreKeyStore.h" @@ -46,6 +47,7 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes @property (nonatomic, nullable) NSData *plaintextData; @property (nonatomic) NSString *source; @property (nonatomic) UInt32 sourceDevice; +@property (nonatomic) BOOL isUDMessage; @end @@ -57,6 +59,7 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes plaintextData:(nullable NSData *)plaintextData source:(NSString *)source sourceDevice:(UInt32)sourceDevice + isUDMessage:(BOOL)isUDMessage { OWSAssertDebug(envelopeData); OWSAssertDebug(source.length > 0); @@ -67,6 +70,7 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes result.plaintextData = plaintextData; result.source = source; result.sourceDevice = sourceDevice; + result.isUDMessage = isUDMessage; return result; } @@ -161,7 +165,15 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes OWSMessageDecryptResult *result, YapDatabaseReadWriteTransaction *transaction) { // Ensure all blocked messages are discarded. if ([self isEnvelopeSenderBlocked:envelope]) { - OWSLogInfo(@"ignoring blocked envelope: %@", envelope.source); + OWSLogInfo(@"Ignoring blocked envelope: %@", envelope.source); + return failureBlock(); + } + + if ([result.source isEqualToString:TSAccountManager.sharedInstance.localNumber] + && result.sourceDevice == OWSDevicePrimaryDeviceId) { + OWSAssertDebug(result.isUDMessage); + + OWSLogInfo(@"Ignoring self-sent sync message."); return failureBlock(); } @@ -237,7 +249,8 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes [OWSMessageDecryptResult resultWithEnvelopeData:envelopeData plaintextData:nil source:envelope.source - sourceDevice:envelope.sourceDevice]; + sourceDevice:envelope.sourceDevice + isUDMessage:NO]; successBlock(result, transaction); }]; // Return to avoid double-acknowledging. @@ -361,11 +374,11 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes // plaintextData may be nil for some envelope types. NSData *_Nullable plaintextData = [[cipher decrypt:cipherMessage protocolContext:transaction] removePadding]; - OWSMessageDecryptResult *result = - [OWSMessageDecryptResult resultWithEnvelopeData:envelopeData - plaintextData:plaintextData - source:envelope.source - sourceDevice:envelope.sourceDevice]; + OWSMessageDecryptResult *result = [OWSMessageDecryptResult resultWithEnvelopeData:envelopeData + plaintextData:plaintextData + source:envelope.source + sourceDevice:envelope.sourceDevice + isUDMessage:NO]; successBlock(result, transaction); } @catch (NSException *exception) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ @@ -471,7 +484,8 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes OWSMessageDecryptResult *result = [OWSMessageDecryptResult resultWithEnvelopeData:newEnvelopeData plaintextData:plaintextData source:source - sourceDevice:(uint32_t)sourceDeviceId]; + sourceDevice:(uint32_t)sourceDeviceId + isUDMessage:YES]; successBlock(result, transaction); } @catch (NSException *exception) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index f4d815cf7..cf2d6d1cd 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -1324,7 +1324,20 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; OWSLogDebug( @"built message: %@ plainTextData.length: %lu", [messageSend.message class], (unsigned long)plainText.length); - for (NSNumber *deviceNumber in messageSend.recipient.devices) { + OWSLogDebug(@"recipient.devices: %@", recipient.devices); + [DDLog flushLog]; + + NSMutableArray *deviceIds = [recipient.devices mutableCopy]; + OWSAssertDebug(deviceIds); + + if (messageSend.isUDSend && messageSend.isLocalNumber) { + const NSUInteger kLocalDeviceId = 1; + OWSAssertDebug(![deviceIds containsObject:@(OWSDevicePrimaryDeviceId)]); + + [deviceIds addObject:@(OWSDevicePrimaryDeviceId)]; + } + + for (NSNumber *deviceId in deviceIds) { @try { __block NSDictionary *messageDict; __block NSException *encryptionException; @@ -1332,7 +1345,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { @try { messageDict = [self encryptedMessageForMessageSend:messageSend - deviceId:deviceNumber + deviceId:deviceId plainText:plainText transaction:transaction]; } @catch (NSException *exception) { @@ -1353,7 +1366,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; } @catch (NSException *exception) { if ([exception.name isEqualToString:OWSMessageSenderInvalidDeviceException]) { [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [recipient removeDevicesFromRecipient:[NSSet setWithObject:deviceNumber] transaction:transaction]; + [recipient removeDevicesFromRecipient:[NSSet setWithObject:deviceId] transaction:transaction]; }]; } else { @throw exception; diff --git a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift index 83841d72d..0c4022eed 100644 --- a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift +++ b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift @@ -94,10 +94,17 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager { return SSKEnvironment.shared.profileManager } + private var tsAccountManager: TSAccountManager { + return TSAccountManager.sharedInstance() + } + // MARK: - Recipient state @objc public func supportsUnidentifiedDelivery(recipientId: String) -> Bool { + if tsAccountManager.localNumber() == recipientId { + return true + } return dbConnection.bool(forKey: recipientId, inCollection: kUDRecipientModeCollection, defaultValue: false) }