From d47ddd112dfadcd5e217687d8f3472eb1c3d0a8c Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Sat, 1 Apr 2017 16:47:16 -0400 Subject: [PATCH] Filter outgoing messages using the blacklist. // FREEBIE --- src/Messages/OWSMessageSender.h | 3 ++ src/Messages/OWSMessageSender.m | 57 ++++++++++++++++++++++++++++---- src/Messages/TSBlockingManager.m | 4 +++ src/Messages/TSMessagesManager.m | 1 + src/Util/OWSError.h | 2 ++ src/Util/OWSError.m | 7 ++++ 6 files changed, 67 insertions(+), 7 deletions(-) diff --git a/src/Messages/OWSMessageSender.h b/src/Messages/OWSMessageSender.h index 7d8c865bf..62c2b113d 100644 --- a/src/Messages/OWSMessageSender.h +++ b/src/Messages/OWSMessageSender.h @@ -7,6 +7,7 @@ NS_ASSUME_NONNULL_BEGIN @class ContactsUpdater; @class OWSUploadingService; @class SignalRecipient; +@class TSBlockingManager; @class TSInvalidIdentityKeySendingErrorMessage; @class TSNetworkManager; @class TSOutgoingMessage; @@ -31,6 +32,8 @@ NS_SWIFT_NAME(MessageSender) contactsManager:(id)contactsManager contactsUpdater:(ContactsUpdater *)contactsUpdater; +- (void)setBlockingManager:(TSBlockingManager *)blockingManager; + /** * Send and resend text messages or resend messages with existing attachments. * If you haven't yet created the attachment, see the `sendAttachmentData:` variants. diff --git a/src/Messages/OWSMessageSender.m b/src/Messages/OWSMessageSender.m index 136f59c9b..0fe690a71 100644 --- a/src/Messages/OWSMessageSender.m +++ b/src/Messages/OWSMessageSender.m @@ -17,6 +17,7 @@ #import "SignalRecipient.h" #import "TSAccountManager.h" #import "TSAttachmentStream.h" +#import "TSBlockingManager.h" #import "TSContactThread.h" #import "TSGroupThread.h" #import "TSIncomingMessage.h" @@ -257,6 +258,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; @property (nonatomic, readonly) TSNetworkManager *networkManager; @property (nonatomic, readonly) TSStorageManager *storageManager; +@property (nonatomic, readonly) TSBlockingManager *blockingManager; @property (nonatomic, readonly) OWSUploadingService *uploadingService; @property (nonatomic, readonly) YapDatabaseConnection *dbConnection; @property (nonatomic, readonly) id contactsManager; @@ -293,6 +295,14 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; return self; } +- (void)setBlockingManager:(TSBlockingManager *)blockingManager +{ + OWSAssert(blockingManager); + OWSAssert(!_blockingManager); + + _blockingManager = blockingManager; +} + - (NSOperationQueue *)sendingQueueForMessage:(TSOutgoingMessage *)message { OWSAssert(message); @@ -516,10 +526,12 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; if (recipients.count == 0) { if (error) { - return failureHandler(error); + failureHandler(error); + return; } else { DDLogError(@"%@ Unknown error finding contacts", self.tag); - return failureHandler(OWSErrorMakeFailedToSendOutgoingMessageError()); + failureHandler(OWSErrorMakeFailedToSendOutgoingMessageError()); + return; } } @@ -541,6 +553,15 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; ? self.storageManager.localNumber : contactThread.contactIdentifier; + OWSAssert(recipientContactId.length > 0); + NSArray *blockedPhoneNumbers = _blockingManager.blockedPhoneNumbers; + if ([blockedPhoneNumbers containsObject:recipientContactId]) { + DDLogInfo(@"%@ skipping 1:1 send to blocked contact: %@", self.tag, recipientContactId); + NSError *error = OWSErrorMakeMessageSendFailedToBlocklistError(); + failureHandler(error); + return; + } + SignalRecipient *recipient = [SignalRecipient recipientWithTextSecureIdentifier:recipientContactId]; if (!recipient) { NSError *error; @@ -554,14 +575,16 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; } DDLogError(@"%@ contact lookup failed with error: %@", self.tag, error); - return failureHandler(error); + failureHandler(error); + return; } } if (!recipient) { NSError *error = OWSErrorMakeFailedToSendOutgoingMessageError(); DDLogWarn(@"recipient contact still not found after attempting lookup."); - return failureHandler(error); + failureHandler(error); + return; } [self sendMessage:message @@ -609,11 +632,31 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; [self saveGroupMessage:message inThread:thread]; NSMutableArray *futures = [NSMutableArray array]; + NSArray *blockedPhoneNumbers = _blockingManager.blockedPhoneNumbers; + int blockedCount = 0; for (SignalRecipient *rec in recipients) { - // we don't need to send the message to ourselves, but otherwise we send - if (![[rec uniqueId] isEqualToString:[TSStorageManager localNumber]]) { - [futures addObject:[self sendMessageFuture:message recipient:rec thread:thread]]; + // We don't need to send the message to ourselves... + if ([[rec uniqueId] isEqualToString:[TSStorageManager localNumber]]) { + continue; } + // ...or to anyone on our blocklist... + OWSAssert([rec uniqueId].length > 0); + if ([blockedPhoneNumbers containsObject:[rec uniqueId]]) { + DDLogInfo(@"%@ skipping group send to blocked contact: %@", self.tag, [rec uniqueId]); + blockedCount++; + continue; + } + + // ...otherwise we send. + [futures addObject:[self sendMessageFuture:message recipient:rec thread:thread]]; + } + + // If all recipients in the group are in our blocklist, + // there's nothing to do. + if (blockedCount > 0 && futures.count == 0) { + NSError *error = OWSErrorMakeMessageSendFailedToBlocklistError(); + failureHandler(error); + return; } TOCFuture *completionFuture = futures.toc_thenAll; diff --git a/src/Messages/TSBlockingManager.m b/src/Messages/TSBlockingManager.m index c10357402..e73ba5af1 100644 --- a/src/Messages/TSBlockingManager.m +++ b/src/Messages/TSBlockingManager.m @@ -68,6 +68,10 @@ NSString *const kTSStorageManager_SyncedBlockedPhoneNumbersKey = @"kTSStorageMan OWSSingletonAssert(); + // Register this manager with the message sender. + // This is a circular dependency. + [messageSender setBlockingManager:self]; + return self; } diff --git a/src/Messages/TSMessagesManager.m b/src/Messages/TSMessagesManager.m index af1af9cfb..bc0bbf206 100644 --- a/src/Messages/TSMessagesManager.m +++ b/src/Messages/TSMessagesManager.m @@ -159,6 +159,7 @@ NS_ASSUME_NONNULL_BEGIN DDLogInfo(@"%@ received envelope: %@", self.tag, [self descriptionForEnvelope:envelope]); // TODO: Can we trust envelope.source to be properly formatted? + OWSAssert(envelope.source.length > 0); BOOL isEnvelopeBlocked = [_blockingManager.blockedPhoneNumbers containsObject:envelope.source]; if (isEnvelopeBlocked) { DDLogInfo(@"%@ ignoring blocked envelope: %@", self.tag, envelope.source); diff --git a/src/Util/OWSError.h b/src/Util/OWSError.h index c3d400945..22605621e 100644 --- a/src/Util/OWSError.h +++ b/src/Util/OWSError.h @@ -22,6 +22,7 @@ typedef NS_ENUM(NSInteger, OWSErrorCode) { OWSErrorCodeUserError = 2001, OWSErrorCodeNoSuchSignalRecipient = 777404, OWSErrorCodeMessageSendDisabledDueToPreKeyUpdateFailures = 777405, + OWSErrorCodeMessageSendFailedToBlocklist = 777406, }; extern NSError *OWSErrorWithCodeDescription(OWSErrorCode code, NSString *description); @@ -30,5 +31,6 @@ extern NSError *OWSErrorMakeFailedToSendOutgoingMessageError(); extern NSError *OWSErrorMakeNoSuchSignalRecipientError(); extern NSError *OWSErrorMakeAssertionError(); extern NSError *OWSErrorMakeMessageSendDisabledDueToPreKeyUpdateFailuresError(); +extern NSError *OWSErrorMakeMessageSendFailedToBlocklistError(); NS_ASSUME_NONNULL_END diff --git a/src/Util/OWSError.m b/src/Util/OWSError.m index e423070ee..cb0bde385 100644 --- a/src/Util/OWSError.m +++ b/src/Util/OWSError.m @@ -47,4 +47,11 @@ NSError *OWSErrorMakeMessageSendDisabledDueToPreKeyUpdateFailuresError() @"Error mesage indicating that message send is disabled due to prekey update failures")); } +NSError *OWSErrorMakeMessageSendFailedToBlocklistError() +{ + return OWSErrorWithCodeDescription(OWSErrorCodeMessageSendFailedToBlocklist, + NSLocalizedString(@"ERROR_DESCRIPTION_MESSAGE_SEND_FAILED_DUE_TO_BLOCKLIST", + @"Error mesage indicating that message send failed due to blocklist")); +} + NS_ASSUME_NONNULL_END