Add protocol context to protocol kit.

This commit is contained in:
Matthew Chen 2018-01-22 16:48:17 -05:00
parent 169c455d11
commit 122ef91e57
12 changed files with 102 additions and 108 deletions

View File

@ -9,8 +9,9 @@ def shared_pods
pod 'SQLCipher', :git => 'https://github.com/sqlcipher/sqlcipher.git', :commit => 'd5c2bec'
# pod 'YapDatabase/SQLCipher', path: '../YapDatabase'
pod 'YapDatabase/SQLCipher', :git => 'https://github.com/WhisperSystems/YapDatabase.git', branch: 'release/unencryptedHeaders'
pod 'AxolotlKit', path: '../SignalProtocolKit'
pod 'SignalServiceKit', path: '.'
pod 'AxolotlKit', git: 'https://github.com/WhisperSystems/SignalProtocolKit.git', branch: 'mkirk/framework-friendly'
# pod 'AxolotlKit', git: 'https://github.com/WhisperSystems/SignalProtocolKit.git', branch: 'mkirk/framework-friendly'
#pod 'AxolotlKit', path: '../SignalProtocolKit'
pod 'HKDFKit', git: 'https://github.com/WhisperSystems/HKDFKit.git', branch: 'mkirk/framework-friendly'
#pod 'HKDFKit', path: '../HKDFKit'

View File

@ -129,7 +129,7 @@ PODS:
DEPENDENCIES:
- AFNetworking
- ATAppUpdater
- AxolotlKit (from `https://github.com/WhisperSystems/SignalProtocolKit.git`, branch `mkirk/framework-friendly`)
- AxolotlKit (from `../SignalProtocolKit`)
- Curve25519Kit (from `https://github.com/WhisperSystems/Curve25519Kit`, branch `mkirk/framework-friendly`)
- GRKOpenSSLFramework (from `https://github.com/WhisperSystems/GRKOpenSSLFramework`)
- HKDFKit (from `https://github.com/WhisperSystems/HKDFKit.git`, branch `mkirk/framework-friendly`)
@ -146,8 +146,7 @@ DEPENDENCIES:
EXTERNAL SOURCES:
AxolotlKit:
:branch: mkirk/framework-friendly
:git: https://github.com/WhisperSystems/SignalProtocolKit.git
:path: ../SignalProtocolKit
Curve25519Kit:
:branch: mkirk/framework-friendly
:git: https://github.com/WhisperSystems/Curve25519Kit
@ -171,9 +170,6 @@ EXTERNAL SOURCES:
:git: https://github.com/WhisperSystems/YapDatabase.git
CHECKOUT OPTIONS:
AxolotlKit:
:commit: 6dd55895b523e887c633bd31b9eedbfb515b8a5d
:git: https://github.com/WhisperSystems/SignalProtocolKit.git
Curve25519Kit:
:commit: 03a19c80aafc10a3464f0c086b1eb38239c507ac
:git: https://github.com/WhisperSystems/Curve25519Kit
@ -221,6 +217,6 @@ SPEC CHECKSUMS:
YapDatabase: 299a32de9d350d37a9ac5b0532609d87d5d2a5de
YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54
PODFILE CHECKSUM: 0d804514eb2db34b9874b653e543255d8c2f5751
PODFILE CHECKSUM: d1c081f5e8cda394caa2bfbb157d628f33352cff
COCOAPODS: 1.3.1

View File

@ -3152,11 +3152,7 @@
"DEBUG=1",
"$(inherited)",
);
"GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = (
"DEBUG=1",
"$(inherited)",
"SSK_BUILDING_FOR_TESTS=1",
);
"GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = "DEBUG=1 $(inherited) SSK_BUILDING_FOR_TESTS=1";
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;

View File

@ -55,7 +55,8 @@ NS_ASSUME_NONNULL_BEGIN
actionBlock:^{
dispatch_async([OWSDispatch sessionStoreQueue], ^{
[[TSStorageManager sharedManager]
deleteAllSessionsForContact:thread.contactIdentifier];
deleteAllSessionsForContact:thread.contactIdentifier
protocolContext:protocolContext];
});
}],
[OWSTableItem itemWithTitle:@"Archive all sessions"

View File

@ -392,6 +392,7 @@ if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Precommit script.')
parser.add_argument('--all', action='store_true', help='process all files in or below current dir')
parser.add_argument('--path', help='used to specify a path to process.')
args = parser.parse_args()
if args.all:
@ -399,6 +400,11 @@ if __name__ == "__main__":
for filename in filenames:
file_path = os.path.abspath(os.path.join(rootdir, filename))
process_if_appropriate(file_path)
elif args.path:
for rootdir, dirnames, filenames in os.walk(args.path):
for filename in filenames:
file_path = os.path.abspath(os.path.join(rootdir, filename))
process_if_appropriate(file_path)
else:
filepaths = []

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSRecordTranscriptJob.h"
@ -69,7 +69,7 @@ NS_ASSUME_NONNULL_BEGIN
if (transcript.isEndSessionMessage) {
DDLogInfo(@"%@ EndSession was sent to recipient: %@.", self.logTag, transcript.recipientId);
dispatch_async([OWSDispatch sessionStoreQueue], ^{
[self.storageManager deleteAllSessionsForContact:transcript.recipientId];
[self.storageManager deleteAllSessionsForContact:transcript.recipientId protocolContext:protocolContext];
});
[[[TSInfoMessage alloc] initWithTimestamp:transcript.timestamp
inThread:thread

View File

@ -718,9 +718,7 @@ NS_ASSUME_NONNULL_BEGIN
inThread:thread
messageType:TSInfoMessageTypeSessionDidEnd] saveWithTransaction:transaction];
dispatch_async([OWSDispatch sessionStoreQueue], ^{
[self.storageManager deleteAllSessionsForContact:envelope.source];
});
[self.storageManager deleteAllSessionsForContact:envelope.source protocolContext:transaction];
}
- (void)handleExpirationTimerUpdateMessageWithEnvelope:(OWSSignalServiceProtosEnvelope *)envelope

View File

@ -1107,7 +1107,9 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
if (extraDevices && extraDevices.count > 0) {
DDLogInfo(@"%@ removing extra devices: %@", self.logTag, extraDevices);
for (NSNumber *extraDeviceId in extraDevices) {
[self.storageManager deleteSessionForContact:recipient.uniqueId deviceId:extraDeviceId.intValue];
[self.storageManager deleteSessionForContact:recipient.uniqueId
deviceId:extraDeviceId.intValue
protocolContext:protocolContext];
}
[recipient removeDevices:[NSSet setWithArray:extraDevices]];
@ -1292,7 +1294,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
OWSAssert(deviceNumber);
OWSAssert(storage);
if (![storage containsSession:identifier deviceId:[deviceNumber intValue]]) {
if (![storage containsSession:identifier deviceId:[deviceNumber intValue] protocolContext:protocolContext]) {
__block dispatch_semaphore_t sema = dispatch_semaphore_create(0);
__block PreKeyBundle *_Nullable bundle;
__block NSException *_Nullable exception;
@ -1427,7 +1429,9 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
dispatch_async([OWSDispatch sessionStoreQueue], ^{
for (NSUInteger i = 0; i < [devices count]; i++) {
int deviceNumber = [devices[i] intValue];
[[TSStorageManager sharedManager] deleteSessionForContact:identifier deviceId:deviceNumber];
[[TSStorageManager sharedManager] deleteSessionForContact:identifier
deviceId:deviceNumber
protocolContext:protocolContext];
}
completionHandler();
});

View File

@ -5,6 +5,8 @@
#import "TSStorageManager.h"
#import <AxolotlKit/SessionStore.h>
NS_ASSUME_NONNULL_BEGIN
@interface TSStorageManager (SessionStore) <SessionStore>
- (void)archiveAllSessionsForContact:(NSString *)contactIdentifier;
@ -19,3 +21,5 @@
- (void)printAllSessions;
@end
NS_ASSUME_NONNULL_END

View File

@ -8,18 +8,11 @@
#import <AxolotlKit/SessionRecord.h>
#import <YapDatabase/YapDatabase.h>
NS_ASSUME_NONNULL_BEGIN
NSString *const TSStorageManagerSessionStoreCollection = @"TSStorageManagerSessionStoreCollection";
NSString *const kSessionStoreDBConnectionKey = @"kSessionStoreDBConnectionKey";
void AssertIsOnSessionStoreQueue()
{
#ifdef DEBUG
if (@available(iOS 10.0, *)) {
dispatch_assert_queue([OWSDispatch sessionStoreQueue]);
} // else, skip assert as it's a development convenience.
#endif
}
@implementation TSStorageManager (SessionStore)
/**
@ -27,36 +20,39 @@ void AssertIsOnSessionStoreQueue()
* Note that it's still technically possible to access this collection from a different collection,
* but that should be considered a bug.
*/
+ (YapDatabaseConnection *)sessionDBConnection
+ (YapDatabaseConnection *)protocolStoreDBConnection
{
static dispatch_once_t onceToken;
static YapDatabaseConnection *sessionDBConnection;
static YapDatabaseConnection *protocolStoreDBConnection;
dispatch_once(&onceToken, ^{
sessionDBConnection = [TSStorageManager sharedManager].newDatabaseConnection;
sessionDBConnection.objectCacheEnabled = NO;
protocolStoreDBConnection = [TSStorageManager sharedManager].newDatabaseConnection;
protocolStoreDBConnection.objectCacheEnabled = NO;
#if DEBUG
sessionDBConnection.permittedTransactions = YDB_AnySyncTransaction;
protocolStoreDBConnection.permittedTransactions = YDB_AnySyncTransaction;
#endif
});
return sessionDBConnection;
return protocolStoreDBConnection;
}
- (YapDatabaseConnection *)sessionDBConnection
// TODO: Audit usage of this connection.
- (YapDatabaseConnection *)protocolStoreDBConnection
{
return [[self class] sessionDBConnection];
return [[self class] protocolStoreDBConnection];
}
#pragma mark - SessionStore
- (SessionRecord *)loadSession:(NSString *)contactIdentifier deviceId:(int)deviceId
- (SessionRecord *)loadSession:(NSString *)contactIdentifier deviceId:(int)deviceId protocolContext:(id)protocolContext
{
AssertIsOnSessionStoreQueue();
OWSAssert(contactIdentifier.length > 0);
OWSAssert(deviceId >= 0);
OWSAssert([protocolContext isKindOfClass:[YapDatabaseReadWriteTransaction class]]);
__block NSDictionary *dictionary;
[self.sessionDBConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
dictionary = [transaction objectForKey:contactIdentifier inCollection:TSStorageManagerSessionStoreCollection];
}];
YapDatabaseReadWriteTransaction *transaction = protocolContext;
NSDictionary *_Nullable dictionary =
[transaction objectForKey:contactIdentifier inCollection:TSStorageManagerSessionStoreCollection];
SessionRecord *record;
@ -71,24 +67,33 @@ void AssertIsOnSessionStoreQueue()
return record;
}
- (NSArray *)subDevicesSessions:(NSString *)contactIdentifier
- (NSArray *)subDevicesSessions:(NSString *)contactIdentifier protocolContext:(nullable id)protocolContext
{
OWSAssert(contactIdentifier.length > 0);
OWSAssert([protocolContext isKindOfClass:[YapDatabaseReadWriteTransaction class]]);
// Deprecated. We aren't currently using this anywhere, but it's "required" by the SessionStore protocol.
// If we are going to start using it I'd want to re-verify it works as intended.
OWSFail(@"%@ subDevicesSessions is deprecated", self.logTag);
AssertIsOnSessionStoreQueue();
__block NSDictionary *dictionary;
[self.sessionDBConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
dictionary = [transaction objectForKey:contactIdentifier inCollection:TSStorageManagerSessionStoreCollection];
}];
YapDatabaseReadWriteTransaction *transaction = protocolContext;
NSDictionary *_Nullable dictionary =
[transaction objectForKey:contactIdentifier inCollection:TSStorageManagerSessionStoreCollection];
return dictionary ? dictionary.allKeys : @[];
}
- (void)storeSession:(NSString *)contactIdentifier deviceId:(int)deviceId session:(SessionRecord *)session
- (void)storeSession:(NSString *)contactIdentifier
deviceId:(int)deviceId
session:(SessionRecord *)session
protocolContext:protocolContext
{
AssertIsOnSessionStoreQueue();
OWSAssert(contactIdentifier.length > 0);
OWSAssert(deviceId >= 0);
OWSAssert([protocolContext isKindOfClass:[YapDatabaseReadWriteTransaction class]]);
YapDatabaseReadWriteTransaction *transaction = protocolContext;
// We need to ensure subsequent usage of this SessionRecord does not consider this session as "fresh". Normally this
// is achieved by marking things as "not fresh" at the point of deserialization - when we fetch a SessionRecord from
@ -98,68 +103,65 @@ void AssertIsOnSessionStoreQueue()
// NOTE: this may no longer be necessary now that we have a non-caching session db connection.
[session markAsUnFresh];
__block NSDictionary *immutableDictionary;
[self.sessionDBConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
immutableDictionary =
[transaction objectForKey:contactIdentifier inCollection:TSStorageManagerSessionStoreCollection];
}];
NSDictionary *immutableDictionary =
[transaction objectForKey:contactIdentifier inCollection:TSStorageManagerSessionStoreCollection];
NSMutableDictionary *dictionary = [immutableDictionary mutableCopy];
if (!dictionary) {
dictionary = [NSMutableDictionary dictionary];
}
NSMutableDictionary *dictionary
= (immutableDictionary ? [immutableDictionary mutableCopy] : [NSMutableDictionary new]);
[dictionary setObject:session forKey:@(deviceId)];
[self.sessionDBConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[transaction setObject:[dictionary copy]
forKey:contactIdentifier
inCollection:TSStorageManagerSessionStoreCollection];
}];
[transaction setObject:[dictionary copy]
forKey:contactIdentifier
inCollection:TSStorageManagerSessionStoreCollection];
}
- (BOOL)containsSession:(NSString *)contactIdentifier deviceId:(int)deviceId
- (BOOL)containsSession:(NSString *)contactIdentifier deviceId:(int)deviceId protocolContext:(id)protocolContext
{
AssertIsOnSessionStoreQueue();
OWSAssert(contactIdentifier.length > 0);
OWSAssert(deviceId >= 0);
OWSAssert([protocolContext isKindOfClass:[YapDatabaseReadWriteTransaction class]]);
return [self loadSession:contactIdentifier deviceId:deviceId].sessionState.hasSenderChain;
return [self loadSession:contactIdentifier deviceId:deviceId protocolContext:protocolContext]
.sessionState.hasSenderChain;
}
- (void)deleteSessionForContact:(NSString *)contactIdentifier deviceId:(int)deviceId
- (void)deleteSessionForContact:(NSString *)contactIdentifier
deviceId:(int)deviceId
protocolContext:(nullable id)protocolContext
{
AssertIsOnSessionStoreQueue();
OWSAssert(contactIdentifier.length > 0);
OWSAssert(deviceId >= 0);
OWSAssert([protocolContext isKindOfClass:[YapDatabaseReadWriteTransaction class]]);
YapDatabaseReadWriteTransaction *transaction = protocolContext;
DDLogInfo(
@"[TSStorageManager (SessionStore)] deleting session for contact: %@ device: %d", contactIdentifier, deviceId);
__block NSDictionary *immutableDictionary;
[self.sessionDBConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
immutableDictionary =
[transaction objectForKey:contactIdentifier inCollection:TSStorageManagerSessionStoreCollection];
}];
NSMutableDictionary *dictionary = [immutableDictionary mutableCopy];
NSDictionary *immutableDictionary =
[transaction objectForKey:contactIdentifier inCollection:TSStorageManagerSessionStoreCollection];
if (!dictionary) {
dictionary = [NSMutableDictionary dictionary];
}
NSMutableDictionary *dictionary
= (immutableDictionary ? [immutableDictionary mutableCopy] : [NSMutableDictionary new]);
[dictionary removeObjectForKey:@(deviceId)];
[self.sessionDBConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[transaction setObject:[dictionary copy]
forKey:contactIdentifier
inCollection:TSStorageManagerSessionStoreCollection];
}];
[transaction setObject:[dictionary copy]
forKey:contactIdentifier
inCollection:TSStorageManagerSessionStoreCollection];
}
- (void)deleteAllSessionsForContact:(NSString *)contactIdentifier
- (void)deleteAllSessionsForContact:(NSString *)contactIdentifier protocolContext:(nullable id)protocolContext
{
AssertIsOnSessionStoreQueue();
OWSAssert(contactIdentifier.length > 0);
OWSAssert([protocolContext isKindOfClass:[YapDatabaseReadWriteTransaction class]]);
YapDatabaseReadWriteTransaction *transaction = protocolContext;
DDLogInfo(@"[TSStorageManager (SessionStore)] deleting all sessions for contact:%@", contactIdentifier);
[self.sessionDBConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[transaction removeObjectForKey:contactIdentifier inCollection:TSStorageManagerSessionStoreCollection];
}];
[transaction removeObjectForKey:contactIdentifier inCollection:TSStorageManagerSessionStoreCollection];
}
- (void)archiveAllSessionsForContact:(NSString *)contactIdentifier
@ -272,3 +274,5 @@ void AssertIsOnSessionStoreQueue()
#endif
@end
NS_ASSUME_NONNULL_END

View File

@ -11,12 +11,6 @@ NS_ASSUME_NONNULL_BEGIN
*/
+ (dispatch_queue_t)attachmentsQueue;
/**
* Signal protocol session state must be coordinated on a serial queue. This is sometimes used synchronously,
* so never dispatching sync *from* this queue to avoid deadlock.
*/
+ (dispatch_queue_t)sessionStoreQueue;
/**
* Serial message sending queue
*/

View File

@ -18,16 +18,6 @@ NS_ASSUME_NONNULL_BEGIN
return queue;
}
+ (dispatch_queue_t)sessionStoreQueue
{
static dispatch_once_t onceToken;
static dispatch_queue_t queue;
dispatch_once(&onceToken, ^{
queue = dispatch_queue_create("org.whispersystems.signal.sessionStoreQueue", NULL);
});
return queue;
}
+ (dispatch_queue_t)sendingQueue
{
static dispatch_once_t onceToken;