From 5157ec823ffb9243cdddc889f83287d4c21e1623 Mon Sep 17 00:00:00 2001 From: Julius Zint Date: Sun, 16 Aug 2020 12:19:48 +0200 Subject: [PATCH] Enables TouchID unlock for multiple Database files. This changeset adds the optional fileURL parameter to the requestPasswordWithMessage function in MPPasswordInputController. The controller uses this URL as a key to store the encrypted masterpassword in a dictionary. In my opinion edge cases like when a file is moved or replaced do not have to get special handling since the worst case scenario is that TouchID unlock does not work and users have still the option to unlock with the masterpassword. Also this changeset removes the unused requestPasswordWithCompletionHandler function --- MacPass/MPDocument.m | 2 +- MacPass/MPDocumentWindowController.m | 6 +++++- MacPass/MPPasswordInputController.h | 3 +-- MacPass/MPPasswordInputController.m | 17 ++++++++++++----- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/MacPass/MPDocument.m b/MacPass/MPDocument.m index 4b27c35c..602c88f0 100644 --- a/MacPass/MPDocument.m +++ b/MacPass/MPDocument.m @@ -440,7 +440,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou } // just return yes regardless since we will display the sheet again if needed! return YES; - }]; + } forFile:nil]; sheet.contentViewController = passwordInputController; [self.windowForSheet beginSheet:sheet completionHandler:^(NSModalResponse returnCode) { /* nothing to do, rest is done in other handler! */ }]; } diff --git a/MacPass/MPDocumentWindowController.m b/MacPass/MPDocumentWindowController.m index 0b7cb1db..d7b2e2f4 100644 --- a/MacPass/MPDocumentWindowController.m +++ b/MacPass/MPDocumentWindowController.m @@ -325,13 +325,17 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword); self.passwordInputController = [[MPPasswordInputController alloc] init]; } self.contentViewController = self.passwordInputController; + NSURL* fileURL = nil; + if(self.document != nil) { + fileURL = [self.document fileURL]; + } [self.passwordInputController requestPasswordWithMessage:message cancelLabel:nil completionHandler:^BOOL(NSString *password, NSURL *keyURL, BOOL didCancel, NSError *__autoreleasing *error) { if(didCancel) { return NO; } return [((MPDocument *)self.document) unlockWithPassword:password keyFileURL:keyURL error:error]; - }]; + } forFile:fileURL]; } - (void)editPassword:(id)sender { diff --git a/MacPass/MPPasswordInputController.h b/MacPass/MPPasswordInputController.h index 26ffd2b1..a8e3ee62 100644 --- a/MacPass/MPPasswordInputController.h +++ b/MacPass/MPPasswordInputController.h @@ -28,8 +28,7 @@ typedef BOOL (^passwordInputCompletionBlock)(NSString *password, NSURL *keyURL, BOOL didCancel, NSError *__autoreleasing*error); -- (void)requestPasswordWithCompletionHandler:(passwordInputCompletionBlock)completionHandler; -- (void)requestPasswordWithMessage:(NSString *)message cancelLabel:(NSString *)cancelLabel completionHandler:(passwordInputCompletionBlock)completionHandler; +- (void)requestPasswordWithMessage:(NSString *)message cancelLabel:(NSString *)cancelLabel completionHandler:(passwordInputCompletionBlock)completionHandler forFile:(NSURL*) fileURL; @end diff --git a/MacPass/MPPasswordInputController.m b/MacPass/MPPasswordInputController.m index ed6c3787..6002b161 100644 --- a/MacPass/MPPasswordInputController.m +++ b/MacPass/MPPasswordInputController.m @@ -50,6 +50,7 @@ static NSMutableDictionary* touchIDSecuredPasswords; @property (copy) NSString *message; @property (copy) NSString *cancelLabel; +@property (copy) NSString *absoluteURLString; @property (assign) BOOL showPassword; @property (nonatomic, assign) BOOL enablePassword; @@ -94,15 +95,21 @@ static NSMutableDictionary* touchIDSecuredPasswords; return self.passwordTextField; } -- (void)requestPasswordWithMessage:(NSString *)message cancelLabel:(NSString *)cancelLabel completionHandler:(passwordInputCompletionBlock)completionHandler { +- (void)requestPasswordWithMessage:(NSString *)message cancelLabel:(NSString *)cancelLabel completionHandler:(passwordInputCompletionBlock)completionHandler forFile:(NSURL*) fileURL{ self.completionHandler = completionHandler; self.message = message; self.cancelLabel = cancelLabel; + if(fileURL) { + self.absoluteURLString = [fileURL absoluteString]; + } + else { + self.absoluteURLString = nil; + } [self _reset]; } - (void)requestPasswordWithCompletionHandler:(passwordInputCompletionBlock)completionHandler { - [self requestPasswordWithMessage:nil cancelLabel:nil completionHandler:completionHandler]; + [self requestPasswordWithMessage:nil cancelLabel:nil completionHandler:completionHandler forFile:nil]; } #pragma mark Properties @@ -136,7 +143,7 @@ static NSMutableDictionary* touchIDSecuredPasswords; BOOL result = self.completionHandler(password, self.keyPathControl.URL, cancel, &error); if(cancel || result) { if(result && self.keyPathControl.URL == nil) { - [self _storePasswordForTouchIDUnlock:password forDatabase:@"DatabaseID"]; + [self _storePasswordForTouchIDUnlock:password forDatabase:self.absoluteURLString]; } return; } @@ -306,7 +313,7 @@ static NSMutableDictionary* touchIDSecuredPasswords; self.enablePassword = YES; self.passwordTextField.stringValue = @""; self.messageInfoTextField.hidden = (nil == self.message); - self.touchIdButton.hidden = [touchIDSecuredPasswords valueForKey:@"DatabaseID"] == nil; + self.touchIdButton.hidden = [touchIDSecuredPasswords valueForKey:self.absoluteURLString] == nil; if(self.message) { self.messageInfoTextField.stringValue = self.message; @@ -392,7 +399,7 @@ static NSMutableDictionary* touchIDSecuredPasswords; } - (IBAction)unlockWithTouchID:(id)sender { - NSString* password = [self _loadPasswordForTochIDUnlock:@"DatabaseID"]; + NSString* password = [self _loadPasswordForTochIDUnlock:self.absoluteURLString]; if(password != nil) { NSError* error; self.completionHandler(password, nil, false, &error);