mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Add app group, share keychain. Take a first pass at file migration to shared data directory.
This commit is contained in:
parent
1ccf5132c1
commit
cd11ec5698
8 changed files with 221 additions and 39 deletions
|
@ -2052,6 +2052,9 @@
|
|||
LastSwiftMigration = 0800;
|
||||
ProvisioningStyle = Automatic;
|
||||
SystemCapabilities = {
|
||||
com.apple.ApplicationGroups.iOS = {
|
||||
enabled = 1;
|
||||
};
|
||||
com.apple.DataProtection = {
|
||||
enabled = 1;
|
||||
};
|
||||
|
@ -2061,6 +2064,9 @@
|
|||
com.apple.InterAppAudio = {
|
||||
enabled = 0;
|
||||
};
|
||||
com.apple.Keychain = {
|
||||
enabled = 1;
|
||||
};
|
||||
com.apple.Push = {
|
||||
enabled = 1;
|
||||
};
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
<dict>
|
||||
<key>aps-environment</key>
|
||||
<string>development</string>
|
||||
<key>com.apple.developer.default-data-protection</key>
|
||||
<string>NSFileProtectionComplete</string>
|
||||
<key>com.apple.developer.icloud-container-identifiers</key>
|
||||
<array>
|
||||
<string>iCloud.$(CFBundleIdentifier)</string>
|
||||
|
@ -16,5 +18,13 @@
|
|||
<array>
|
||||
<string>iCloud.$(CFBundleIdentifier)</string>
|
||||
</array>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.org.whispersystems.signal.group</string>
|
||||
</array>
|
||||
<key>keychain-access-groups</key>
|
||||
<array>
|
||||
<string>$(AppIdentifierPrefix)org.whispersystems.signal</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -1389,9 +1389,17 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
|
|||
static NSString *profileAvatarsDirPath = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSString *documentsPath =
|
||||
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
|
||||
profileAvatarsDirPath = [documentsPath stringByAppendingPathComponent:@"ProfileAvatars"];
|
||||
NSString *documentDirPath = [OWSFileSystem appDocumentDirectoryPath];
|
||||
NSString *sharedDataDirPath = [OWSFileSystem appSharedDataDirectoryPath];
|
||||
|
||||
NSString *oldProfileAvatarsDirPath = [documentDirPath stringByAppendingPathComponent:@"ProfileAvatars"];
|
||||
NSString *newProfileAvatarsDirPath = [sharedDataDirPath stringByAppendingPathComponent:@"ProfileAvatars"];
|
||||
|
||||
[OWSFileSystem moveAppFilePath:oldProfileAvatarsDirPath
|
||||
sharedDataFilePath:newProfileAvatarsDirPath
|
||||
exceptionName:@"ProfileManagerCouldNotMigrateProfileDirectory"];
|
||||
|
||||
profileAvatarsDirPath = newProfileAvatarsDirPath;
|
||||
|
||||
BOOL isDirectory;
|
||||
BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:profileAvatarsDirPath isDirectory:&isDirectory];
|
||||
|
|
|
@ -185,9 +185,17 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
static NSString *attachmentsFolder = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSString *documentsPath =
|
||||
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
|
||||
attachmentsFolder = [documentsPath stringByAppendingPathComponent:@"Attachments"];
|
||||
NSString *documentDirPath = [OWSFileSystem appDocumentDirectoryPath];
|
||||
NSString *sharedDataDirPath = [OWSFileSystem appSharedDataDirectoryPath];
|
||||
|
||||
NSString *oldAttachmentsDirPath = [documentDirPath stringByAppendingPathComponent:@"Attachments"];
|
||||
NSString *newAttachmentsDirPath = [sharedDataDirPath stringByAppendingPathComponent:@"Attachments"];
|
||||
|
||||
[OWSFileSystem moveAppFilePath:oldAttachmentsDirPath
|
||||
sharedDataFilePath:newAttachmentsDirPath
|
||||
exceptionName:@"CouldNotMigrateAttachmentsDirectory"];
|
||||
|
||||
attachmentsFolder = newAttachmentsDirPath;
|
||||
|
||||
BOOL isDirectory;
|
||||
BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:attachmentsFolder isDirectory:&isDirectory];
|
||||
|
|
|
@ -63,10 +63,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@property (nullable, nonatomic, readonly) YapDatabaseConnection *dbReadConnection;
|
||||
@property (nullable, nonatomic, readonly) YapDatabaseConnection *dbReadWriteConnection;
|
||||
|
||||
#pragma mark - Utilities
|
||||
|
||||
- (void)protectFolderAtPath:(NSString *)path;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -24,13 +24,18 @@
|
|||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
NSString *const TSStorageManagerExceptionNameDatabasePasswordInaccessible = @"TSStorageManagerExceptionNameDatabasePasswordInaccessible";
|
||||
NSString *const TSStorageManagerExceptionNameDatabasePasswordInaccessibleWhileBackgrounded =
|
||||
@"TSStorageManagerExceptionNameDatabasePasswordInaccessibleWhileBackgrounded";
|
||||
NSString *const TSStorageManagerExceptionNameDatabasePasswordUnwritable = @"TSStorageManagerExceptionNameDatabasePasswordUnwritable";
|
||||
NSString *const TSStorageManagerExceptionNameNoDatabase = @"TSStorageManagerExceptionNameNoDatabase";
|
||||
NSString *const TSStorageManagerExceptionName_DatabasePasswordInaccessible
|
||||
= @"TSStorageManagerExceptionName_DatabasePasswordInaccessible";
|
||||
NSString *const TSStorageManagerExceptionName_DatabasePasswordInaccessibleWhileBackgrounded
|
||||
= @"TSStorageManagerExceptionName_DatabasePasswordInaccessibleWhileBackgrounded";
|
||||
NSString *const TSStorageManagerExceptionName_DatabasePasswordUnwritable
|
||||
= @"TSStorageManagerExceptionName_DatabasePasswordUnwritable";
|
||||
NSString *const TSStorageManagerExceptionName_NoDatabase = @"TSStorageManagerExceptionName_NoDatabase";
|
||||
NSString *const TSStorageManagerExceptionName_CouldNotMoveDatabaseFile
|
||||
= @"TSStorageManagerExceptionName_CouldNotMoveDatabaseFile";
|
||||
NSString *const TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory
|
||||
= @"TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory";
|
||||
|
||||
static const NSString *const databaseName = @"Signal.sqlite";
|
||||
static NSString *keychainService = @"TSKeyChainService";
|
||||
static NSString *keychainDBPassAccount = @"TSDatabasePass";
|
||||
|
||||
|
@ -231,7 +236,7 @@ void setDatabaseInitialized()
|
|||
// Sleep to give analytics events time to be delivered.
|
||||
[NSThread sleepForTimeInterval:15.0f];
|
||||
|
||||
[NSException raise:TSStorageManagerExceptionNameNoDatabase format:@"Failed to initialize database."];
|
||||
[NSException raise:TSStorageManagerExceptionName_NoDatabase format:@"Failed to initialize database."];
|
||||
}
|
||||
|
||||
OWSSingletonAssert();
|
||||
|
@ -253,6 +258,7 @@ void setDatabaseInitialized()
|
|||
options.cipherKeyBlock = ^{
|
||||
return databasePassword;
|
||||
};
|
||||
options.enableMultiProcessSupport = YES;
|
||||
|
||||
#ifdef DEBUG
|
||||
_database = [[OWSDatabase alloc] initWithPath:[self dbPath]
|
||||
|
@ -350,9 +356,14 @@ void setDatabaseInitialized()
|
|||
}
|
||||
|
||||
- (void)protectSignalFiles {
|
||||
[OWSFileSystem protectFolderAtPath:[self dbPath]];
|
||||
[OWSFileSystem protectFolderAtPath:[[self dbPath] stringByAppendingString:@"-shm"]];
|
||||
[OWSFileSystem protectFolderAtPath:[[self dbPath] stringByAppendingString:@"-wal"]];
|
||||
// The old database location was in the Document directory,
|
||||
// so protect the database files individually.
|
||||
[OWSFileSystem protectFolderAtPath:[self oldDatabaseFilePath]];
|
||||
[OWSFileSystem protectFolderAtPath:[self oldDatabaseFilePath_SHM]];
|
||||
[OWSFileSystem protectFolderAtPath:[self oldDatabaseFilePath_WAL]];
|
||||
|
||||
// Protect the entire new database directory.
|
||||
[OWSFileSystem protectFolderAtPath:[self newDatabaseDirPath]];
|
||||
}
|
||||
|
||||
- (nullable YapDatabaseConnection *)newDatabaseConnection
|
||||
|
@ -364,33 +375,118 @@ void setDatabaseInitialized()
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
- (BOOL)dbExists {
|
||||
return [[NSFileManager defaultManager] fileExistsAtPath:[self dbPath]];
|
||||
- (NSString *)oldDatabaseDirPath
|
||||
{
|
||||
return [OWSFileSystem appDocumentDirectoryPath];
|
||||
}
|
||||
|
||||
- (NSString *)dbPath {
|
||||
NSString *databasePath;
|
||||
- (NSString *)newDatabaseDirPath
|
||||
{
|
||||
NSString *databaseDirPath = [[OWSFileSystem appSharedDataDirectoryPath] stringByAppendingPathComponent:@"database"];
|
||||
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
#if TARGET_OS_IPHONE
|
||||
NSURL *fileURL = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
|
||||
NSString *path = [fileURL path];
|
||||
databasePath = [path stringByAppendingPathComponent:databaseName];
|
||||
#elif TARGET_OS_MAC
|
||||
if (![fileManager fileExistsAtPath:databaseDirPath]) {
|
||||
NSError *_Nullable error;
|
||||
BOOL success = [fileManager createDirectoryAtPath:databaseDirPath
|
||||
withIntermediateDirectories:NO
|
||||
attributes:nil
|
||||
error:&error];
|
||||
if (!success || error) {
|
||||
NSString *errorDescription =
|
||||
[NSString stringWithFormat:@"%@ Could not create new database directory: %@, error: %@",
|
||||
self.logTag,
|
||||
databaseDirPath,
|
||||
error];
|
||||
OWSFail(@"%@", errorDescription);
|
||||
[NSException raise:TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory
|
||||
format:@"%@", errorDescription];
|
||||
}
|
||||
}
|
||||
return databaseDirPath;
|
||||
}
|
||||
|
||||
NSString *bundleID = [[NSBundle mainBundle] bundleIdentifier];
|
||||
NSArray *urlPaths = [fileManager URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask];
|
||||
- (NSString *)databaseFilename
|
||||
{
|
||||
return @"Signal.sqlite";
|
||||
}
|
||||
|
||||
NSURL *appDirectory = [[urlPaths objectAtIndex:0] URLByAppendingPathComponent:bundleID isDirectory:YES];
|
||||
- (NSString *)databaseFilename_SHM
|
||||
{
|
||||
return [self.databaseFilename stringByAppendingString:@"-shm"];
|
||||
}
|
||||
|
||||
if (![fileManager fileExistsAtPath:[appDirectory path]]) {
|
||||
[fileManager createDirectoryAtURL:appDirectory withIntermediateDirectories:NO attributes:nil error:nil];
|
||||
- (NSString *)databaseFilename_WAL
|
||||
{
|
||||
return [self.databaseFilename stringByAppendingString:@"-wal"];
|
||||
}
|
||||
|
||||
- (NSString *)oldDatabaseFilePath
|
||||
{
|
||||
return [self.oldDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename];
|
||||
}
|
||||
|
||||
- (NSString *)oldDatabaseFilePath_SHM
|
||||
{
|
||||
return [self.oldDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_SHM];
|
||||
}
|
||||
|
||||
- (NSString *)oldDatabaseFilePath_WAL
|
||||
{
|
||||
return [self.oldDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_WAL];
|
||||
}
|
||||
|
||||
- (NSString *)newDatabaseFilePath
|
||||
{
|
||||
return [self.newDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename];
|
||||
}
|
||||
|
||||
- (NSString *)newDatabaseFilePath_SHM
|
||||
{
|
||||
return [self.newDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_SHM];
|
||||
}
|
||||
|
||||
- (NSString *)newDatabaseFilePath_WAL
|
||||
{
|
||||
return [self.newDatabaseDirPath stringByAppendingPathComponent:self.databaseFilename_WAL];
|
||||
}
|
||||
|
||||
- (NSString *)dbPath
|
||||
{
|
||||
[OWSFileSystem moveAppFilePath:self.oldDatabaseFilePath
|
||||
sharedDataFilePath:self.newDatabaseFilePath
|
||||
exceptionName:TSStorageManagerExceptionName_CouldNotMoveDatabaseFile];
|
||||
[OWSFileSystem moveAppFilePath:self.oldDatabaseFilePath_SHM
|
||||
sharedDataFilePath:self.newDatabaseFilePath_SHM
|
||||
exceptionName:TSStorageManagerExceptionName_CouldNotMoveDatabaseFile];
|
||||
[OWSFileSystem moveAppFilePath:self.oldDatabaseFilePath_WAL
|
||||
sharedDataFilePath:self.newDatabaseFilePath_WAL
|
||||
exceptionName:TSStorageManagerExceptionName_CouldNotMoveDatabaseFile];
|
||||
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
BOOL hasAllNewFiles = ([fileManager fileExistsAtPath:self.newDatabaseFilePath] &&
|
||||
[fileManager fileExistsAtPath:self.newDatabaseFilePath_SHM] &&
|
||||
[fileManager fileExistsAtPath:self.newDatabaseFilePath_WAL]);
|
||||
BOOL hasAnyNewFiles = ([fileManager fileExistsAtPath:self.newDatabaseFilePath] ||
|
||||
[fileManager fileExistsAtPath:self.newDatabaseFilePath_SHM] ||
|
||||
[fileManager fileExistsAtPath:self.newDatabaseFilePath_WAL]);
|
||||
if (!hasAllNewFiles && !hasAnyNewFiles) {
|
||||
for (NSString *filePath in @[
|
||||
self.newDatabaseFilePath,
|
||||
self.newDatabaseFilePath_SHM,
|
||||
self.newDatabaseFilePath_WAL,
|
||||
self.newDatabaseFilePath,
|
||||
self.newDatabaseFilePath_SHM,
|
||||
self.newDatabaseFilePath_WAL,
|
||||
]) {
|
||||
DDLogInfo(@"%@ Database file %@ exists %d", self.logTag, filePath, [fileManager fileExistsAtPath:filePath]);
|
||||
}
|
||||
OWSFail(@"%@ Incomplete set of database files.", self.logTag);
|
||||
}
|
||||
|
||||
databasePath = [appDirectory.filePathURL.absoluteString stringByAppendingPathComponent:databaseName];
|
||||
#endif
|
||||
DDLogError(@"databasePath: %@", self.newDatabaseFilePath);
|
||||
[DDLog flushLog];
|
||||
|
||||
return databasePath;
|
||||
return self.newDatabaseFilePath;
|
||||
}
|
||||
|
||||
+ (BOOL)isDatabasePasswordAccessible
|
||||
|
@ -421,7 +517,7 @@ void setDatabaseInitialized()
|
|||
// Presumably this happened in response to a push notification. It's possible that the keychain is corrupted
|
||||
// but it could also just be that the user hasn't yet unlocked their device since our password is
|
||||
// kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
|
||||
[NSException raise:TSStorageManagerExceptionNameDatabasePasswordInaccessibleWhileBackgrounded
|
||||
[NSException raise:TSStorageManagerExceptionName_DatabasePasswordInaccessibleWhileBackgrounded
|
||||
format:@"%@", errorDescription];
|
||||
}
|
||||
|
||||
|
@ -483,7 +579,7 @@ void setDatabaseInitialized()
|
|||
// Sleep to give analytics events time to be delivered.
|
||||
[NSThread sleepForTimeInterval:15.0f];
|
||||
|
||||
[NSException raise:TSStorageManagerExceptionNameDatabasePasswordUnwritable
|
||||
[NSException raise:TSStorageManagerExceptionName_DatabasePasswordUnwritable
|
||||
format:@"Setting DB password failed with error: %@", keySetError];
|
||||
} else {
|
||||
DDLogWarn(@"Succesfully set new DB password.");
|
||||
|
|
|
@ -10,6 +10,14 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
+ (void)protectFolderAtPath:(NSString *)path;
|
||||
|
||||
+ (NSString *)appDocumentDirectoryPath;
|
||||
|
||||
+ (NSString *)appSharedDataDirectoryPath;
|
||||
|
||||
+ (void)moveAppFilePath:(NSString *)oldFilePath
|
||||
sharedDataFilePath:(NSString *)newFilePath
|
||||
exceptionName:(NSString *)exceptionName;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -28,6 +28,56 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
}
|
||||
}
|
||||
|
||||
+ (NSString *)appDocumentDirectoryPath
|
||||
{
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSURL *documentDirectoryURL =
|
||||
[[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
|
||||
return [documentDirectoryURL path];
|
||||
}
|
||||
|
||||
+ (NSString *)appSharedDataDirectoryPath
|
||||
{
|
||||
NSURL *groupContainerDirectoryURL = [[NSFileManager defaultManager]
|
||||
containerURLForSecurityApplicationGroupIdentifier:@"group.org.whispersystems.signal.group"];
|
||||
return [groupContainerDirectoryURL path];
|
||||
}
|
||||
|
||||
+ (void)moveAppFilePath:(NSString *)oldFilePath
|
||||
sharedDataFilePath:(NSString *)newFilePath
|
||||
exceptionName:(NSString *)exceptionName
|
||||
{
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
if (![fileManager fileExistsAtPath:oldFilePath]) {
|
||||
return;
|
||||
}
|
||||
if ([fileManager fileExistsAtPath:newFilePath]) {
|
||||
DDLogError(@"");
|
||||
return;
|
||||
}
|
||||
|
||||
NSDate *startDate = [NSDate new];
|
||||
|
||||
NSError *_Nullable error;
|
||||
BOOL success = [fileManager moveItemAtPath:oldFilePath toPath:newFilePath error:&error];
|
||||
if (!success || error) {
|
||||
NSString *errorDescription =
|
||||
[NSString stringWithFormat:@"%@ Could not move database file from %@ to %@, error: %@",
|
||||
self.logTag,
|
||||
oldFilePath,
|
||||
newFilePath,
|
||||
error];
|
||||
OWSFail(@"%@", errorDescription);
|
||||
[NSException raise:exceptionName format:@"%@", errorDescription];
|
||||
}
|
||||
|
||||
DDLogInfo(@"%@ Moving file or directory from %@ to %@ in: %f",
|
||||
self.logTag,
|
||||
oldFilePath,
|
||||
newFilePath,
|
||||
fabs([startDate timeIntervalSinceNow]));
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
Loading…
Reference in a new issue