From b6ef5f0b7f818797a04d5ac5f91a8a3af848835c Mon Sep 17 00:00:00 2001 From: Frederic Jacobs Date: Thu, 12 Mar 2015 00:46:31 +0100 Subject: [PATCH] Bloomfilter moves to Cache folder The bloom filter is not user generated content so Apple is not going to let us store it into the Documents folder. Moving it to the Cache folder. --- Pods | 2 +- Signal.xcodeproj/project.pbxproj | 6 +- Signal/Signal-Info.plist | 2 +- Signal/src/AppDelegate.m | 2 + Signal/src/environment/PreferencesUtil.m | 57 +++++++++++++++++-- .../src/environment/PropertyListPreferences.m | 3 +- Signal/src/environment/VersionMigrations.h | 3 + Signal/src/environment/VersionMigrations.m | 10 ++++ Signal/test/phone/BloomFilterTests.m | 49 ++++++++++++++++ 9 files changed, 125 insertions(+), 9 deletions(-) create mode 100644 Signal/test/phone/BloomFilterTests.m 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