Prevent destroying user database after resetting device.

// FREEBIE
pull/1/head
Michael Kirk 8 years ago
parent 8f81015730
commit dd1aa26827

@ -23,6 +23,7 @@
NSString *const TSUIDatabaseConnectionDidUpdateNotification = @"TSUIDatabaseConnectionDidUpdateNotification";
NSString *const TSStorageManagerExceptionNameDatabasePasswordInaccessible = @"TSStorageManagerExceptionNameDatabasePasswordInaccessible";
NSString *const TSStorageManagerExceptionNameDatabasePasswordInaccessibleWhileBackgrounded = @"TSStorageManagerExceptionNameDatabasePasswordInaccessibleWhileBackgrounded";
NSString *const TSStorageManagerExceptionNameDatabasePasswordUnwritable = @"TSStorageManagerExceptionNameDatabasePasswordUnwritable";
NSString *const TSStorageManagerExceptionNameNoDatabase = @"TSStorageManagerExceptionNameNoDatabase";
@ -287,6 +288,17 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass";
return NO;
}
- (void)backgroundedAppDatabasePasswordInaccessibleWithError:(NSError *)error
{
OWSAssert([UIApplication sharedApplication].applicationState == UIApplicationStateBackground);
// 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
format:@"Unable to access database password. No unlock since device restart? Error: %@", error];
}
- (NSData *)databasePassword
{
[SAMKeychain setAccessibilityType:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly];
@ -296,7 +308,14 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass";
[SAMKeychain passwordForService:keychainService account:keychainDBPassAccount error:&keyFetchError];
if (keyFetchError) {
// Either this is a new install so there's no existing password to retrieve
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
// TODO: Rather than crash here, we should detect the situation earlier
// and exit gracefully - (in the app delegate?). See the `
// This is a last ditch effort to avoid blowing away the user's database.
[self backgroundedAppDatabasePasswordInaccessibleWithError:keyFetchError];
}
// At this point, either this is a new install so there's no existing password to retrieve
// or the keychain has become corrupt. Either way, we want to get back to a
// "known good state" and behave like a new install.

Loading…
Cancel
Save