diff --git a/Pods b/Pods index 1569cfc94..9aac93648 160000 --- a/Pods +++ b/Pods @@ -1 +1 @@ -Subproject commit 1569cfc9475da09be8d415fdc9194fdb2b6388f9 +Subproject commit 9aac93648cd42d0a94d9b04b8456f7183a8c3b8e diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index abf353b28..052b6cf42 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -396,6 +396,7 @@ B6B1013C196D213F007E3930 /* SignalKeyingStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B1013B196D213F007E3930 /* SignalKeyingStorage.m */; }; B6B50AAB1A4192C500F8F607 /* TSMessagesManager+attachments.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B50AAA1A4192C500F8F607 /* TSMessagesManager+attachments.m */; }; B6B9ECFC198B31BA00C620D3 /* PushManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B9ECFB198B31BA00C620D3 /* PushManager.m */; }; + B6BE7EED1AB100250038D0C8 /* BloomFilterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B6BE7EEC1AB100250038D0C8 /* BloomFilterTests.m */; }; B6C6AE551A305ED1006BAF8F /* redphone.cer in Resources */ = {isa = PBXBuildFile; fileRef = B6C6AE531A305ED1006BAF8F /* redphone.cer */; }; B6C6AE561A305ED1006BAF8F /* textsecure.cer in Resources */ = {isa = PBXBuildFile; fileRef = B6C6AE541A305ED1006BAF8F /* textsecure.cer */; }; B6C93C4E199567AD00EDF894 /* DebugLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = B6C93C4D199567AD00EDF894 /* DebugLogger.m */; }; @@ -1071,6 +1072,7 @@ B6B9ECFA198B31BA00C620D3 /* PushManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PushManager.h; sourceTree = ""; }; B6B9ECFB198B31BA00C620D3 /* PushManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PushManager.m; sourceTree = ""; }; B6BC3D0C1AA544B100C2907F /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = translations/da.lproj/Localizable.strings; sourceTree = ""; }; + B6BE7EEC1AB100250038D0C8 /* BloomFilterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BloomFilterTests.m; sourceTree = ""; }; B6C6AE531A305ED1006BAF8F /* redphone.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = redphone.cer; sourceTree = ""; }; B6C6AE541A305ED1006BAF8F /* textsecure.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = textsecure.cer; sourceTree = ""; }; B6C93C4C199567AD00EDF894 /* DebugLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugLogger.h; sourceTree = ""; }; @@ -2021,6 +2023,7 @@ children = ( A157073017F0CD6D007C2BD6 /* PhoneNumberTest.m */, A157073117F0CD6D007C2BD6 /* signaling */, + B6BE7EEC1AB100250038D0C8 /* BloomFilterTests.m */, ); path = phone; sourceTree = ""; @@ -2726,7 +2729,7 @@ }; }; D221A0A9169C9E5F00537ABF = { - DevelopmentTeam = AWR2FBJU75; + DevelopmentTeam = U68MSDN6DR; TestTargetID = D221A088169C9E5E00537ABF; }; }; @@ -3238,6 +3241,7 @@ A157075717F0CD6D007C2BD6 /* AudioFrameTest.m in Sources */, 76EB063F18170B33006006FC /* Operation.m in Sources */, 76EB05AB18170B33006006FC /* SequenceCounter.m in Sources */, + B6BE7EED1AB100250038D0C8 /* BloomFilterTests.m in Sources */, 76EB061D18170B33006006FC /* ArrayUtil.m in Sources */, 76EB05E318170B33006006FC /* SecureEndPoint.m in Sources */, 76EB060D18170B33006006FC /* CategorizingLogger.m in Sources */, diff --git a/Signal/Signal-Info.plist b/Signal/Signal-Info.plist index 6ce577d54..7d07fdfb5 100644 --- a/Signal/Signal-Info.plist +++ b/Signal/Signal-Info.plist @@ -38,7 +38,7 @@ CFBundleVersion - 2.0.17 + 2.0.18 LOGS_EMAIL support@whispersystems.org LOGS_URL diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 163ee2a1e..f0b2eec7c 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -53,6 +53,8 @@ static NSString* const kCallSegue = @"2.0_6.0_Call_Segue"; DDLogError(@"No previous version found. Possibly first launch since install."); } else if(([self isVersion:previousVersion atLeast:@"1.0.2" andLessThan:@"2.0"]) || isCurrentlyMigrating) { [VersionMigrations migrateFrom1Dot0Dot2ToVersion2Dot0]; + } else if(([self isVersion:previousVersion atLeast:@"2.0.0" andLessThan:@"2.0.18"])) { + [VersionMigrations migrateBloomFilter]; } } diff --git a/Signal/src/environment/PreferencesUtil.m b/Signal/src/environment/PreferencesUtil.m index 908036285..faefd6c9c 100644 --- a/Signal/src/environment/PreferencesUtil.m +++ b/Signal/src/environment/PreferencesUtil.m @@ -9,7 +9,6 @@ #define CALL_STREAM_DES_BUFFER_LEVEL_KEY @"CallStreamDesiredBufferLevel" #define PHONE_DIRECTORY_BLOOM_FILTER_HASH_COUNT_KEY @"Directory Bloom Hash Count" -#define PHONE_DIRECTORY_BLOOM_FILTER_DATA_KEY @"Directory Bloom Data" #define PHONE_DIRECTORY_EXPIRATION @"Directory Expiration" #define DEFAULT_CALL_STREAM_DES_BUFFER_LEVEL 0.5 @@ -29,11 +28,13 @@ #define HAS_ARCHIVED_A_MESSAGE_KEY @"User archived a message" #define kSignalVersionKey @"SignalUpdateVersionKey" +#define BloomFilterCacheName @"bloomfilter" + @implementation PropertyListPreferences (PropertyUtil) -(PhoneNumberDirectoryFilter*) tryGetSavedPhoneNumberDirectory { NSUInteger hashCount = [[self tryGetValueForKey:PHONE_DIRECTORY_BLOOM_FILTER_HASH_COUNT_KEY] unsignedIntegerValue]; - NSData* data = [self tryGetValueForKey:PHONE_DIRECTORY_BLOOM_FILTER_DATA_KEY]; + NSData* data = [self tryRetreiveBloomFilter]; NSDate* expiration = [self tryGetValueForKey:PHONE_DIRECTORY_EXPIRATION]; if (hashCount == 0 || data.length == 0 || expiration == nil) return nil; BloomFilter* bloomFilter = [BloomFilter bloomFilterWithHashCount:hashCount andData:data]; @@ -41,7 +42,7 @@ andExpirationDate:expiration]; } -(void) setSavedPhoneNumberDirectory:(PhoneNumberDirectoryFilter*)phoneNumberDirectoryFilter { - [self setValueForKey:PHONE_DIRECTORY_BLOOM_FILTER_DATA_KEY toValue:nil]; + [self storeBloomfilter:nil]; [self setValueForKey:PHONE_DIRECTORY_BLOOM_FILTER_HASH_COUNT_KEY toValue:nil]; [self setValueForKey:PHONE_DIRECTORY_EXPIRATION toValue:nil]; if (phoneNumberDirectoryFilter == nil) return; @@ -49,7 +50,7 @@ NSData* data = [[phoneNumberDirectoryFilter bloomFilter] data]; NSNumber* hashCount = @([[phoneNumberDirectoryFilter bloomFilter] hashCount]); NSDate* expiry = phoneNumberDirectoryFilter.getExpirationDate; - [self setValueForKey:PHONE_DIRECTORY_BLOOM_FILTER_DATA_KEY toValue:data]; + [self storeBloomfilter:data]; [self setValueForKey:PHONE_DIRECTORY_BLOOM_FILTER_HASH_COUNT_KEY toValue:hashCount]; [self setValueForKey:PHONE_DIRECTORY_EXPIRATION toValue:expiry]; [self sendDirectoryUpdateNotification]; @@ -213,4 +214,52 @@ return currentVersion; } +#pragma mark Bloom filter + +- (NSData*)tryRetreiveBloomFilter { + return [NSData dataWithContentsOfFile:[self bloomfilterPath]]; +} + +- (void)storeBloomfilter:(NSData*)bloomFilterData { + if (!bloomFilterData) { + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSError *error; + + if ([fileManager fileExistsAtPath:[self bloomfilterPath]]) { + [fileManager removeItemAtPath:[self bloomfilterPath] error:&error]; + } + + if (error) { + DDLogError(@"Failed to remove bloomfilter with error: %@", error); + } + + return; + } + + NSError *error; + [bloomFilterData writeToFile:[self bloomfilterPath] options:NSDataWritingAtomic error:&error]; + if (error) { + DDLogError(@"Failed to store bloomfilter with error: %@", error); + } +} + +- (NSString*)bloomfilterPath { + NSFileManager *fm = [NSFileManager defaultManager]; + NSArray *cachesDir = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); + NSString *bloomFilterPath = [cachesDir objectAtIndex:0]; + NSError *error; + + if (![fm fileExistsAtPath:bloomFilterPath]) { + [fm createDirectoryAtPath:bloomFilterPath withIntermediateDirectories:YES attributes:@{} error:&error]; + } + + if (error) { + DDLogError(@"Failed to create caches directory with error: %@", error.description); + } + + bloomFilterPath = [bloomFilterPath stringByAppendingPathComponent:BloomFilterCacheName]; + + return bloomFilterPath; +} + @end diff --git a/Signal/src/environment/PropertyListPreferences.m b/Signal/src/environment/PropertyListPreferences.m index 568adfb9e..d9ce25b2d 100644 --- a/Signal/src/environment/PropertyListPreferences.m +++ b/Signal/src/environment/PropertyListPreferences.m @@ -4,6 +4,7 @@ #define SignalDatabaseCollection @"SignalPreferences" + @implementation PropertyListPreferences -(void) clear { @@ -33,6 +34,4 @@ } } - - @end diff --git a/Signal/src/environment/VersionMigrations.h b/Signal/src/environment/VersionMigrations.h index 29699313b..3e6675663 100644 --- a/Signal/src/environment/VersionMigrations.h +++ b/Signal/src/environment/VersionMigrations.h @@ -12,8 +12,11 @@ @interface VersionMigrations : NSObject ++ (void)migrateBloomFilter; + + (void)migrateFrom1Dot0Dot2ToVersion2Dot0; + (BOOL)isMigratingTo2Dot0; + @end diff --git a/Signal/src/environment/VersionMigrations.m b/Signal/src/environment/VersionMigrations.m index 225dc23f5..871351313 100644 --- a/Signal/src/environment/VersionMigrations.m +++ b/Signal/src/environment/VersionMigrations.m @@ -11,6 +11,7 @@ #import "Environment.h" #import "PhoneNumberDirectoryFilterManager.h" #import "PreferencesUtil.h" +#import "PropertyListPreferences.h" #import "PushManager.h" #import "TSAccountManager.h" #import "RecentCallManager.h" @@ -21,6 +22,8 @@ #define IS_MIGRATING_FROM_1DOT0_TO_LARGER_KEY @"Migrating from 1.0 to Larger" + + @interface SignalKeyingStorage(VersionMigrations) +(void)storeString:(NSString*)string forKey:(NSString*)key; @@ -29,6 +32,13 @@ @implementation VersionMigrations ++ (void)migrateBloomFilter { + // The bloom filter had to be moved to the cache folder after rejection of the 2.0.1 + NSString *oldBloomKey = @"Directory Bloom Data"; + [[Environment preferences] setValueForKey:oldBloomKey toValue:nil]; + return; +} + + (void)migrateFrom1Dot0Dot2ToVersion2Dot0 { if (!([self wasRedPhoneRegistered] || [self isMigratingTo2Dot0])) { diff --git a/Signal/test/phone/BloomFilterTests.m b/Signal/test/phone/BloomFilterTests.m new file mode 100644 index 000000000..bba6f9105 --- /dev/null +++ b/Signal/test/phone/BloomFilterTests.m @@ -0,0 +1,49 @@ +// +// BloomFilterTests.m +// Signal +// +// Created by Frederic Jacobs on 11/03/15. +// Copyright (c) 2015 Open Whisper Systems. All rights reserved. +// + +#import +#import +#import "Cryptography.h" +#import "Environment.h" +#import "PropertyListPreferences.h" + +@interface PropertyListPreferences() +- (NSData*)tryRetreiveBloomFilter; +- (void)storeBloomfilter:(NSData*)bloomFilterData; +@end + +@interface BloomFilterTests : XCTestCase + +@end + +@implementation BloomFilterTests + +- (void)tearDown{ + PropertyListPreferences *prefs = [Environment preferences]; + [prefs storeBloomfilter:nil]; +} + +- (void)testCreationRetreivalDeletion{ + NSData *randomData = [Cryptography generateRandomBytes:30]; + PropertyListPreferences *prefs = [Environment preferences]; + + NSData *bloomFilter = [prefs tryRetreiveBloomFilter]; + + XCTAssert(bloomFilter == nil); + + [prefs storeBloomfilter:randomData]; + bloomFilter = [prefs tryRetreiveBloomFilter]; + + XCTAssert([bloomFilter isEqualToData:randomData]); + + [prefs storeBloomfilter:nil]; + bloomFilter = [prefs tryRetreiveBloomFilter]; + XCTAssert(bloomFilter == nil); +} + +@end