Decouple message decryption and processing.

// FREEBIE
This commit is contained in:
Matthew Chen 2017-09-13 12:14:22 -04:00
parent 3abcbdf981
commit c498e4b354
5 changed files with 257 additions and 194 deletions

View File

@ -29,6 +29,7 @@
#import <SignalServiceKit/OWSFailedAttachmentDownloadsJob.h>
#import <SignalServiceKit/OWSFailedMessagesJob.h>
#import <SignalServiceKit/OWSIncomingMessageReadObserver.h>
#import <SignalServiceKit/OWSMessageDecrypter.h>
#import <SignalServiceKit/OWSMessageSender.h>
#import <SignalServiceKit/TSAccountManager.h>
#import <SignalServiceKit/TSDatabaseView.h>
@ -816,6 +817,7 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
// If there were any messages in our local queue which we hadn't yet processed.
[[OWSMessageReceiver sharedInstance] handleAnyUnprocessedEnvelopesAsync];
// [[OWSMessageDecrypter sharedInstance] handleAnyUnprocessedEnvelopesAsync];
[OWSProfileManager.sharedManager fetchLocalUsersProfile];
}

View File

@ -15,6 +15,7 @@
NS_ASSUME_NONNULL_BEGIN
#pragma mark - Persisted data model
@class OWSSignalServiceProtosEnvelope;
@interface OWSMessageProcessingJob : TSYapDatabaseObject
@ -27,12 +28,16 @@ NS_ASSUME_NONNULL_BEGIN
@end
#pragma mark -
@interface OWSMessageProcessingJob ()
@property (nonatomic, readonly) NSData *envelopeData;
@end
#pragma mark -
@implementation OWSMessageProcessingJob
- (instancetype)initWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
@ -70,12 +75,16 @@ NSString *const OWSMessageProcessingJobFinderExtensionGroup = @"OWSMessageProces
@end
#pragma mark -
@interface OWSMessageProcessingJobFinder ()
@property (nonatomic, readonly) YapDatabaseConnection *dbConnection;
@end
#pragma mark -
@implementation OWSMessageProcessingJobFinder
- (instancetype)initWithDBConnection:(YapDatabaseConnection *)dbConnection
@ -118,7 +127,7 @@ NSString *const OWSMessageProcessingJobFinderExtensionGroup = @"OWSMessageProces
}];
}
+ (YapDatabaseView *)databaseExension
+ (YapDatabaseView *)databaseExtension
{
YapDatabaseViewSorting *sorting =
[YapDatabaseViewSorting withObjectBlock:^NSComparisonResult(YapDatabaseReadTransaction *transaction,
@ -175,7 +184,7 @@ NSString *const OWSMessageProcessingJobFinderExtensionGroup = @"OWSMessageProces
// already initialized
return;
}
[database registerExtension:[self databaseExension] withName:OWSMessageProcessingJobFinderExtensionName];
[database registerExtension:[self databaseExtension] withName:OWSMessageProcessingJobFinderExtensionName];
}
@end
@ -194,6 +203,8 @@ NSString *const OWSMessageProcessingJobFinderExtensionGroup = @"OWSMessageProces
@end
#pragma mark -
@implementation OWSMessageProcessingQueue
- (instancetype)initWithMessagesManager:(TSMessagesManager *)messagesManager
@ -248,17 +259,25 @@ NSString *const OWSMessageProcessingJobFinderExtensionGroup = @"OWSMessageProces
DDLogVerbose(@"%@ completed job. %lu jobs left.",
self.tag,
(unsigned long)[OWSMessageProcessingJob numberOfKeysInCollection]);
[self.finder removeJobWithId:job.uniqueId];
[self drainQueueWorkStep];
}];
}
- (void)processJob:(OWSMessageProcessingJob *)job completion:(void (^)())completion
{
[self.messagesManager processEnvelope:job.envelopeProto
completion:^{
[self.finder removeJobWithId:job.uniqueId];
completion();
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self.messagesManager decryptEnvelope:job.envelopeProto
successBlock:^(NSData *_Nullable plaintextData) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.messagesManager processEnvelope:job.envelopeProto plaintextData:plaintextData];
completion();
});
}
failureBlock:^{
completion();
}];
});
}
#pragma mark Logging
@ -284,6 +303,8 @@ NSString *const OWSMessageProcessingJobFinderExtensionGroup = @"OWSMessageProces
@end
#pragma mark -
@implementation OWSMessageReceiver
- (instancetype)initWithDBConnection:(YapDatabaseConnection *)dbConnection

View File

@ -17,6 +17,8 @@ NS_ASSUME_NONNULL_BEGIN
@protocol ContactsManagerProtocol;
@protocol OWSCallMessageHandler;
typedef void (^DecryptSuccessBlock)(NSData *_Nullable plaintextData);
typedef void (^DecryptFailureBlock)();
typedef void (^MessageManagerCompletionBlock)();
@interface TSMessagesManager : NSObject
@ -28,8 +30,13 @@ typedef void (^MessageManagerCompletionBlock)();
@property (nonatomic, readonly) TSNetworkManager *networkManager;
@property (nonatomic, readonly) ContactsUpdater *contactsUpdater;
- (void)processEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
completion:(nullable MessageManagerCompletionBlock)completion;
// decryptEnvelope: can be called from any thread.
// successBlock & failureBlock may be called on any thread.
- (void)decryptEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
successBlock:(DecryptSuccessBlock)successBlock
failureBlock:(DecryptFailureBlock)failureBlock;
- (void)processEnvelope:(OWSSignalServiceProtosEnvelope *)envelope plaintextData:(NSData *_Nullable)plaintextData;
- (NSUInteger)unreadMessagesCount;
- (NSUInteger)unreadMessagesCountExcept:(TSThread *)thread;

View File

@ -260,84 +260,89 @@ NS_ASSUME_NONNULL_BEGIN
return description;
}
#pragma mark - message handling
#pragma mark - Blocking
- (void)processEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
completion:(nullable MessageManagerCompletionBlock)completionHandler
- (BOOL)isEnvelopeBlocked:(OWSSignalServiceProtosEnvelope *)envelope
{
OWSAssert([NSThread isMainThread]);
OWSAssert(envelope);
return [_blockingManager.blockedPhoneNumbers containsObject:envelope.source];
}
#pragma mark - Decryption
- (void)decryptEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
successBlock:(DecryptSuccessBlock)successBlockParameter
failureBlock:(DecryptFailureBlock)failureBlockParameter
{
OWSAssert(envelope);
OWSAssert(successBlockParameter);
OWSAssert(failureBlockParameter);
OWSAssert([TSAccountManager isRegistered]);
// Ensure that completionHandler is called on the main thread,
// and handle the nil case.
MessageManagerCompletionBlock completion = ^{
dispatch_async(dispatch_get_main_queue(), ^{
if (completionHandler) {
completionHandler();
}
// Ensure that successBlock and failureBlock are called on a worker queue.
DecryptSuccessBlock successBlock = ^(NSData *_Nullable plaintextData) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
successBlockParameter(plaintextData);
});
};
DDLogInfo(@"%@ received envelope: %@", self.tag, [self descriptionForEnvelope:envelope]);
DecryptFailureBlock failureBlock = ^() {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
failureBlockParameter();
});
};
DDLogInfo(@"%@ decrypting envelope: %@", self.tag, [self descriptionForEnvelope:envelope]);
OWSAssert(envelope.source.length > 0);
BOOL isEnvelopeBlocked = [_blockingManager.blockedPhoneNumbers containsObject:envelope.source];
if (isEnvelopeBlocked) {
if ([self isEnvelopeBlocked:envelope]) {
DDLogInfo(@"%@ ignoring blocked envelope: %@", self.tag, envelope.source);
completion();
failureBlock();
return;
}
@try {
switch (envelope.type) {
case OWSSignalServiceProtosEnvelopeTypeCiphertext: {
[self handleSecureMessageAsync:envelope
completion:^(NSError *_Nullable error) {
DDLogDebug(@"%@ handled secure message.", self.tag);
if (error) {
DDLogError(
@"%@ handling secure message from address: %@ failed with error: %@",
self.tag,
envelopeAddress(envelope),
error);
OWSProdError(
[OWSAnalyticsEvents messageManagerErrorCouldNotHandleSecureMessage]);
}
completion();
}];
[self decryptSecureMessage:envelope
successBlock:^(NSData *_Nullable plaintextData) {
DDLogDebug(@"%@ decrypted secure message.", self.tag);
successBlock(plaintextData);
}
failureBlock:^(NSError *_Nullable error) {
DDLogError(@"%@ decrypting secure message from address: %@ failed with error: %@",
self.tag,
envelopeAddress(envelope),
error);
OWSProdError([OWSAnalyticsEvents messageManagerErrorCouldNotHandleSecureMessage]);
failureBlock();
}];
// Return to avoid double-acknowledging.
return;
}
case OWSSignalServiceProtosEnvelopeTypePrekeyBundle: {
[self handlePreKeyBundleAsync:envelope
completion:^(NSError *_Nullable error) {
DDLogDebug(@"%@ handled pre-key whisper message", self.tag);
if (error) {
DDLogError(@"%@ handling pre-key whisper message from address: %@ failed "
@"with error: %@",
self.tag,
envelopeAddress(envelope),
error);
OWSProdError(
[OWSAnalyticsEvents messageManagerErrorCouldNotHandlePrekeyBundle]);
}
completion();
}];
[self decryptPreKeyBundle:envelope
successBlock:^(NSData *_Nullable plaintextData) {
DDLogDebug(@"%@ decrypted pre-key whisper message", self.tag);
successBlock(plaintextData);
}
failureBlock:^(NSError *_Nullable error) {
DDLogError(@"%@ decrypting pre-key whisper message from address: %@ failed "
@"with error: %@",
self.tag,
envelopeAddress(envelope),
error);
OWSProdError([OWSAnalyticsEvents messageManagerErrorCouldNotHandlePrekeyBundle]);
failureBlock();
}];
// Return to avoid double-acknowledging.
return;
}
case OWSSignalServiceProtosEnvelopeTypeReceipt:
[self handleDeliveryReceipt:envelope];
break;
// Other messages are just dismissed for now.
case OWSSignalServiceProtosEnvelopeTypeKeyExchange:
DDLogWarn(@"Received Key Exchange Message, not supported");
break;
case OWSSignalServiceProtosEnvelopeTypeUnknown:
DDLogWarn(@"Received an unknown message type");
break;
successBlock(nil);
// Return to avoid double-acknowledging.
return;
default:
DDLogWarn(@"Received unhandled envelope type: %d", (int)envelope.type);
break;
@ -347,13 +352,140 @@ NS_ASSUME_NONNULL_BEGIN
OWSProdFail([OWSAnalyticsEvents messageManagerErrorInvalidProtocolMessage]);
}
completion();
failureBlock();
}
- (void)decryptSecureMessage:(OWSSignalServiceProtosEnvelope *)messageEnvelope
successBlock:(DecryptSuccessBlock)successBlock
failureBlock:(void (^)(NSError *_Nullable error))failureBlock
{
OWSAssert(messageEnvelope);
OWSAssert(successBlock);
OWSAssert(failureBlock);
TSStorageManager *storageManager = [TSStorageManager sharedManager];
NSString *recipientId = messageEnvelope.source;
int deviceId = messageEnvelope.sourceDevice;
dispatch_async([OWSDispatch sessionStoreQueue], ^{
// DEPRECATED - Remove after all clients have been upgraded.
NSData *encryptedData = messageEnvelope.hasContent ? messageEnvelope.content : messageEnvelope.legacyMessage;
if (!encryptedData) {
OWSProdFail([OWSAnalyticsEvents messageManagerErrorMessageEnvelopeHasNoContent]);
failureBlock(nil);
return;
}
@try {
WhisperMessage *message = [[WhisperMessage alloc] initWithData:encryptedData];
SessionCipher *cipher = [[SessionCipher alloc] initWithSessionStore:storageManager
preKeyStore:storageManager
signedPreKeyStore:storageManager
identityKeyStore:self.identityManager
recipientId:recipientId
deviceId:deviceId];
NSData *plaintextData = [[cipher decrypt:message] removePadding];
successBlock(plaintextData);
} @catch (NSException *exception) {
dispatch_async(dispatch_get_main_queue(), ^{
[self processException:exception envelope:messageEnvelope];
NSString *errorDescription =
[NSString stringWithFormat:@"Exception while decrypting: %@", exception.description];
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptMessage, errorDescription);
failureBlock(error);
});
}
});
}
- (void)decryptPreKeyBundle:(OWSSignalServiceProtosEnvelope *)preKeyEnvelope
successBlock:(DecryptSuccessBlock)successBlock
failureBlock:(void (^)(NSError *_Nullable error))failureBlock
{
OWSAssert(preKeyEnvelope);
OWSAssert(successBlock);
OWSAssert(failureBlock);
TSStorageManager *storageManager = [TSStorageManager sharedManager];
NSString *recipientId = preKeyEnvelope.source;
int deviceId = preKeyEnvelope.sourceDevice;
// DEPRECATED - Remove after all clients have been upgraded.
NSData *encryptedData = preKeyEnvelope.hasContent ? preKeyEnvelope.content : preKeyEnvelope.legacyMessage;
if (!encryptedData) {
OWSProdFail([OWSAnalyticsEvents messageManagerErrorPrekeyBundleEnvelopeHasNoContent]);
failureBlock(nil);
return;
}
dispatch_async([OWSDispatch sessionStoreQueue], ^{
@try {
// Check whether we need to refresh our PreKeys every time we receive a PreKeyWhisperMessage.
[TSPreKeyManager checkPreKeys];
PreKeyWhisperMessage *message = [[PreKeyWhisperMessage alloc] initWithData:encryptedData];
SessionCipher *cipher = [[SessionCipher alloc] initWithSessionStore:storageManager
preKeyStore:storageManager
signedPreKeyStore:storageManager
identityKeyStore:self.identityManager
recipientId:recipientId
deviceId:deviceId];
NSData *plaintextData = [[cipher decrypt:message] removePadding];
successBlock(plaintextData);
} @catch (NSException *exception) {
dispatch_async(dispatch_get_main_queue(), ^{
[self processException:exception envelope:preKeyEnvelope];
NSString *errorDescription =
[NSString stringWithFormat:@"Exception while decrypting PreKey Bundle: %@", exception.description];
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptMessage, errorDescription);
failureBlock(error);
});
}
});
}
#pragma mark - message handling
// TODO: Add transaction parameter.
- (void)processEnvelope:(OWSSignalServiceProtosEnvelope *)envelope plaintextData:(NSData *_Nullable)plaintextData
{
OWSAssert([TSAccountManager isRegistered]);
DDLogInfo(@"%@ received envelope: %@", self.tag, [self descriptionForEnvelope:envelope]);
OWSAssert(envelope.source.length > 0);
OWSAssert(![self isEnvelopeBlocked:envelope]);
switch (envelope.type) {
case OWSSignalServiceProtosEnvelopeTypeCiphertext:
case OWSSignalServiceProtosEnvelopeTypePrekeyBundle:
if (plaintextData) {
[self handleEnvelope:envelope plaintextData:plaintextData];
} else {
OWSFail(
@"%@ missing decrypted data for envelope: %@", self.tag, [self descriptionForEnvelope:envelope]);
}
break;
case OWSSignalServiceProtosEnvelopeTypeReceipt:
OWSAssert(!plaintextData);
[self handleDeliveryReceipt:envelope];
break;
// Other messages are just dismissed for now.
case OWSSignalServiceProtosEnvelopeTypeKeyExchange:
DDLogWarn(@"Received Key Exchange Message, not supported");
break;
case OWSSignalServiceProtosEnvelopeTypeUnknown:
DDLogWarn(@"Received an unknown message type");
break;
default:
DDLogWarn(@"Received unhandled envelope type: %d", (int)envelope.type);
break;
}
}
- (void)handleDeliveryReceipt:(OWSSignalServiceProtosEnvelope *)envelope
{
OWSAssert([NSThread isMainThread]);
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
TSInteraction *interaction =
[TSInteraction interactionForTimestamp:envelope.timestamp withTransaction:transaction];
@ -364,110 +496,8 @@ NS_ASSUME_NONNULL_BEGIN
}];
}
- (void)handleSecureMessageAsync:(OWSSignalServiceProtosEnvelope *)messageEnvelope
completion:(void (^)(NSError *_Nullable error))completion
{
OWSAssert([NSThread isMainThread]);
@synchronized(self) {
TSStorageManager *storageManager = [TSStorageManager sharedManager];
NSString *recipientId = messageEnvelope.source;
int deviceId = messageEnvelope.sourceDevice;
dispatch_async([OWSDispatch sessionStoreQueue], ^{
// DEPRECATED - Remove after all clients have been upgraded.
NSData *encryptedData
= messageEnvelope.hasContent ? messageEnvelope.content : messageEnvelope.legacyMessage;
if (!encryptedData) {
OWSProdFail([OWSAnalyticsEvents messageManagerErrorMessageEnvelopeHasNoContent]);
completion(nil);
return;
}
NSData *plaintextData;
@try {
WhisperMessage *message = [[WhisperMessage alloc] initWithData:encryptedData];
SessionCipher *cipher = [[SessionCipher alloc] initWithSessionStore:storageManager
preKeyStore:storageManager
signedPreKeyStore:storageManager
identityKeyStore:self.identityManager
recipientId:recipientId
deviceId:deviceId];
plaintextData = [[cipher decrypt:message] removePadding];
} @catch (NSException *exception) {
dispatch_async(dispatch_get_main_queue(), ^{
[self processException:exception envelope:messageEnvelope];
NSString *errorDescription =
[NSString stringWithFormat:@"Exception while decrypting: %@", exception.description];
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptMessage, errorDescription);
completion(error);
});
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
[self handleEnvelope:messageEnvelope plaintextData:plaintextData];
completion(nil);
});
});
}
}
- (void)handlePreKeyBundleAsync:(OWSSignalServiceProtosEnvelope *)preKeyEnvelope
completion:(void (^)(NSError *_Nullable error))completion
{
OWSAssert([NSThread isMainThread]);
@synchronized(self) {
TSStorageManager *storageManager = [TSStorageManager sharedManager];
NSString *recipientId = preKeyEnvelope.source;
int deviceId = preKeyEnvelope.sourceDevice;
// DEPRECATED - Remove after all clients have been upgraded.
NSData *encryptedData = preKeyEnvelope.hasContent ? preKeyEnvelope.content : preKeyEnvelope.legacyMessage;
if (!encryptedData) {
OWSProdFail([OWSAnalyticsEvents messageManagerErrorPrekeyBundleEnvelopeHasNoContent]);
completion(nil);
return;
}
dispatch_async([OWSDispatch sessionStoreQueue], ^{
NSData *plaintextData;
@try {
// Check whether we need to refresh our PreKeys every time we receive a PreKeyWhisperMessage.
[TSPreKeyManager checkPreKeys];
PreKeyWhisperMessage *message = [[PreKeyWhisperMessage alloc] initWithData:encryptedData];
SessionCipher *cipher = [[SessionCipher alloc] initWithSessionStore:storageManager
preKeyStore:storageManager
signedPreKeyStore:storageManager
identityKeyStore:self.identityManager
recipientId:recipientId
deviceId:deviceId];
plaintextData = [[cipher decrypt:message] removePadding];
} @catch (NSException *exception) {
dispatch_async(dispatch_get_main_queue(), ^{
[self processException:exception envelope:preKeyEnvelope];
NSString *errorDescription = [NSString stringWithFormat:@"Exception while decrypting PreKey Bundle: %@", exception.description];
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptMessage, errorDescription);
completion(error);
});
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
[self handleEnvelope:preKeyEnvelope plaintextData:plaintextData];
completion(nil);
});
});
}
}
- (void)handleEnvelope:(OWSSignalServiceProtosEnvelope *)envelope plaintextData:(NSData *)plaintextData
{
OWSAssert([NSThread isMainThread]);
OWSAssert(envelope.hasTimestamp && envelope.timestamp > 0);
OWSAssert(envelope.hasSource && envelope.source.length > 0);
OWSAssert(envelope.hasSourceDevice && envelope.sourceDevice > 0);
@ -1120,6 +1150,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)processException:(NSException *)exception envelope:(OWSSignalServiceProtosEnvelope *)envelope
{
OWSAssert([NSThread isMainThread]);
DDLogError(@"%@ Got exception: %@ of type: %@ with reason: %@",
self.tag,
exception.description,
@ -1128,40 +1159,40 @@ NS_ASSUME_NONNULL_BEGIN
__block TSErrorMessage *errorMessage;
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
if ([exception.name isEqualToString:NoSessionException]) {
OWSProdErrorWEnvelope([OWSAnalyticsEvents messageManagerErrorNoSession], envelope);
errorMessage = [TSErrorMessage missingSessionWithEnvelope:envelope withTransaction:transaction];
} else if ([exception.name isEqualToString:InvalidKeyException]) {
OWSProdErrorWEnvelope([OWSAnalyticsEvents messageManagerErrorInvalidKey], envelope);
errorMessage = [TSErrorMessage invalidKeyExceptionWithEnvelope:envelope withTransaction:transaction];
} else if ([exception.name isEqualToString:InvalidKeyIdException]) {
OWSProdErrorWEnvelope([OWSAnalyticsEvents messageManagerErrorInvalidKeyId], envelope);
errorMessage = [TSErrorMessage invalidKeyExceptionWithEnvelope:envelope withTransaction:transaction];
} else if ([exception.name isEqualToString:DuplicateMessageException]) {
// Duplicate messages are dismissed
return;
} else if ([exception.name isEqualToString:InvalidVersionException]) {
OWSProdErrorWEnvelope([OWSAnalyticsEvents messageManagerErrorInvalidMessageVersion], envelope);
errorMessage = [TSErrorMessage invalidVersionWithEnvelope:envelope withTransaction:transaction];
} else if ([exception.name isEqualToString:UntrustedIdentityKeyException]) {
// Should no longer get here, since we now record the new identity for incoming messages.
OWSProdErrorWEnvelope([OWSAnalyticsEvents messageManagerErrorUntrustedIdentityKeyException], envelope);
OWSFail(@"%@ Failed to trust identity on incoming message from: %@", self.tag, envelopeAddress(envelope));
return;
} else {
OWSProdErrorWEnvelope([OWSAnalyticsEvents messageManagerErrorCorruptMessage], envelope);
errorMessage = [TSErrorMessage corruptedMessageWithEnvelope:envelope withTransaction:transaction];
}
if ([exception.name isEqualToString:NoSessionException]) {
OWSProdErrorWEnvelope([OWSAnalyticsEvents messageManagerErrorNoSession], envelope);
errorMessage = [TSErrorMessage missingSessionWithEnvelope:envelope withTransaction:transaction];
} else if ([exception.name isEqualToString:InvalidKeyException]) {
OWSProdErrorWEnvelope([OWSAnalyticsEvents messageManagerErrorInvalidKey], envelope);
errorMessage = [TSErrorMessage invalidKeyExceptionWithEnvelope:envelope withTransaction:transaction];
} else if ([exception.name isEqualToString:InvalidKeyIdException]) {
OWSProdErrorWEnvelope([OWSAnalyticsEvents messageManagerErrorInvalidKeyId], envelope);
errorMessage = [TSErrorMessage invalidKeyExceptionWithEnvelope:envelope withTransaction:transaction];
} else if ([exception.name isEqualToString:DuplicateMessageException]) {
// Duplicate messages are dismissed
return;
} else if ([exception.name isEqualToString:InvalidVersionException]) {
OWSProdErrorWEnvelope([OWSAnalyticsEvents messageManagerErrorInvalidMessageVersion], envelope);
errorMessage = [TSErrorMessage invalidVersionWithEnvelope:envelope withTransaction:transaction];
} else if ([exception.name isEqualToString:UntrustedIdentityKeyException]) {
// Should no longer get here, since we now record the new identity for incoming messages.
OWSProdErrorWEnvelope([OWSAnalyticsEvents messageManagerErrorUntrustedIdentityKeyException], envelope);
OWSFail(@"%@ Failed to trust identity on incoming message from: %@", self.tag, envelopeAddress(envelope));
return;
} else {
OWSProdErrorWEnvelope([OWSAnalyticsEvents messageManagerErrorCorruptMessage], envelope);
errorMessage = [TSErrorMessage corruptedMessageWithEnvelope:envelope withTransaction:transaction];
}
[errorMessage saveWithTransaction:transaction];
[errorMessage saveWithTransaction:transaction];
}];
if (errorMessage != nil) {
[self notififyForErrorMessage:errorMessage withEnvelope:envelope];
[self notifyForErrorMessage:errorMessage withEnvelope:envelope];
}
}
- (void)notififyForErrorMessage:(TSErrorMessage *)errorMessage withEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
- (void)notifyForErrorMessage:(TSErrorMessage *)errorMessage withEnvelope:(OWSSignalServiceProtosEnvelope *)envelope
{
TSThread *contactThread = [TSContactThread getOrCreateThreadWithContactId:envelope.source];
[[TextSecureKitEnv sharedEnv].notificationsManager notifyUserForErrorMessage:errorMessage inThread:contactThread];

View File

@ -18,6 +18,7 @@
#import "TSThread.h"
#import <25519/Randomness.h>
#import <SAMKeychain/SAMKeychain.h>
#import <SignalServiceKit/OWSMessageDecrypter.h>
#import <SignalServiceKit/OWSMessageReceiver.h>
#import <YapDatabase/YapDatabaseRelationship.h>
@ -305,6 +306,7 @@ void setDatabaseInitialized()
[TSDatabaseView registerUnreadDatabaseView];
[self.database registerExtension:[TSDatabaseSecondaryIndexes registerTimeStampIndex] withName:@"idx"];
[OWSMessageReceiver syncRegisterDatabaseExtension:self.database];
// [OWSMessageDecrypter syncRegisterDatabaseExtension:self.database];
// See comments on OWSDatabaseConnection.
//