Index: LegacyPasswordGenerator.h ================================================================== --- LegacyPasswordGenerator.h +++ LegacyPasswordGenerator.h @@ -1,7 +1,7 @@ /* - * Copyright (c) 2016, Jonathan Schleifer + * Copyright (c) 2016, 2017, Jonathan Schleifer * * https://heap.zone/git/scrypt-pwgen.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Index: LegacyPasswordGenerator.m ================================================================== --- LegacyPasswordGenerator.m +++ LegacyPasswordGenerator.m @@ -1,7 +1,7 @@ /* - * Copyright (c) 2016, Jonathan Schleifer + * Copyright (c) 2016, 2017, Jonathan Schleifer * * https://heap.zone/git/scrypt-pwgen.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Index: NewPasswordGenerator.h ================================================================== --- NewPasswordGenerator.h +++ NewPasswordGenerator.h @@ -1,7 +1,7 @@ /* - * Copyright (c) 2016, Jonathan Schleifer + * Copyright (c) 2016, 2017, Jonathan Schleifer * * https://heap.zone/git/scrypt-pwgen.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Index: NewPasswordGenerator.m ================================================================== --- NewPasswordGenerator.m +++ NewPasswordGenerator.m @@ -1,7 +1,7 @@ /* - * Copyright (c) 2016, Jonathan Schleifer + * Copyright (c) 2016, 2017, Jonathan Schleifer * * https://heap.zone/git/scrypt-pwgen.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Index: PasswordGenerator.h ================================================================== --- PasswordGenerator.h +++ PasswordGenerator.h @@ -1,7 +1,7 @@ /* - * Copyright (c) 2016, Jonathan Schleifer + * Copyright (c) 2016, 2017, Jonathan Schleifer * * https://heap.zone/git/scrypt-pwgen.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Index: ScryptPWGen.h ================================================================== --- ScryptPWGen.h +++ ScryptPWGen.h @@ -1,7 +1,7 @@ /* - * Copyright (c) 2016, Jonathan Schleifer + * Copyright (c) 2016, 2017, Jonathan Schleifer * * https://heap.zone/git/scrypt-pwgen.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Index: iOS/AboutController.h ================================================================== --- iOS/AboutController.h +++ iOS/AboutController.h @@ -1,7 +1,7 @@ /* - * Copyright (c) 2016, Jonathan Schleifer + * Copyright (c) 2016, 2017, Jonathan Schleifer * * https://heap.zone/git/scrypt-pwgen.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Index: iOS/AboutController.m ================================================================== --- iOS/AboutController.m +++ iOS/AboutController.m @@ -1,7 +1,7 @@ /* - * Copyright (c) 2016, Jonathan Schleifer + * Copyright (c) 2016, 2017, Jonathan Schleifer * * https://heap.zone/git/scrypt-pwgen.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Index: iOS/AddSiteController.h ================================================================== --- iOS/AddSiteController.h +++ iOS/AddSiteController.h @@ -1,7 +1,7 @@ /* - * Copyright (c) 2016, Jonathan Schleifer + * Copyright (c) 2016, 2017, Jonathan Schleifer * * https://heap.zone/git/scrypt-pwgen.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -26,11 +26,12 @@ @interface AddSiteController: UITableViewController @property (nonatomic, retain) IBOutlet UITextField *nameField; @property (nonatomic, retain) IBOutlet UITextField *lengthField; @property (nonatomic, retain) IBOutlet UISwitch *legacySwitch; +@property (nonatomic, copy) NSString *keyFile; @property (nonatomic, retain) IBOutlet UILabel *keyFileLabel; @property (retain) MainViewController *mainViewController; - (IBAction)done: (id)sender; - (IBAction)cancel: (id)sender; @end Index: iOS/AddSiteController.m ================================================================== --- iOS/AddSiteController.m +++ iOS/AddSiteController.m @@ -1,7 +1,7 @@ /* - * Copyright (c) 2016, Jonathan Schleifer + * Copyright (c) 2016, 2017, Jonathan Schleifer * * https://heap.zone/git/scrypt-pwgen.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -21,10 +21,11 @@ */ #import #import "AddSiteController.h" +#import "SelectKeyFileController.h" static void showAlert(UIViewController *controller, NSString *title, NSString *message) { UIAlertController *alert = [UIAlertController @@ -45,10 +46,11 @@ - (void)dealloc { [_nameField release]; [_lengthField release]; [_legacySwitch release]; + [_keyFile release]; [_keyFileLabel release]; [_mainViewController release]; [super dealloc]; } @@ -58,11 +60,12 @@ { [tableView deselectRowAtIndexPath: indexPath animated: YES]; if (indexPath.section == 1 && indexPath.row == 1) - [self selectKeyFile]; + [self performSegueWithIdentifier: @"selectKeyFile" + sender: self]; } - (NSIndexPath *)tableView: (UITableView *)tableView willSelectRowAtIndexPath: (NSIndexPath *)indexPath { @@ -70,15 +73,10 @@ return indexPath; return nil; } -- (void)selectKeyFile -{ - showAlert(self, @"Not Supported", @"Key files are not supported yet"); -} - - (IBAction)done: (id)sender { OFString *name = self.nameField.text.OFObject; OFString *lengthString = self.lengthField.text.OFObject; bool lengthValid = true; @@ -111,16 +109,23 @@ } [self.mainViewController.siteStorage setSite: name length: length legacy: self.legacySwitch.on - keyFile: nil]; + keyFile: self.keyFile.OFObject]; [self.mainViewController reset]; [self.navigationController popViewControllerAnimated: YES]; } - (IBAction)cancel: (id)sender { [self.navigationController popViewControllerAnimated: YES]; } + +- (void)prepareForSegue: (UIStoryboardSegue *)segue + sender: (id)sender +{ + if ([segue.identifier isEqual: @"selectKeyFile"]) + [segue.destinationViewController setAddSiteController: self]; +} @end Index: iOS/AppDelegate.h ================================================================== --- iOS/AppDelegate.h +++ iOS/AppDelegate.h @@ -1,7 +1,7 @@ /* - * Copyright (c) 2016, Jonathan Schleifer + * Copyright (c) 2016, 2017, Jonathan Schleifer * * https://heap.zone/git/scrypt-pwgen.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Index: iOS/AppDelegate.m ================================================================== --- iOS/AppDelegate.m +++ iOS/AppDelegate.m @@ -1,7 +1,7 @@ /* - * Copyright (c) 2016, Jonathan Schleifer + * Copyright (c) 2016, 2017, Jonathan Schleifer * * https://heap.zone/git/scrypt-pwgen.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Index: iOS/Base.lproj/Main.storyboard ================================================================== --- iOS/Base.lproj/Main.storyboard +++ iOS/Base.lproj/Main.storyboard @@ -291,19 +291,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: iOS/Info.plist ================================================================== --- iOS/Info.plist +++ iOS/Info.plist @@ -33,7 +33,9 @@ UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortraitUpsideDown + UIFileSharingEnabled + Index: iOS/MainViewController.h ================================================================== --- iOS/MainViewController.h +++ iOS/MainViewController.h @@ -1,7 +1,7 @@ /* - * Copyright (c) 2016, Jonathan Schleifer + * Copyright (c) 2016, 2017, Jonathan Schleifer * * https://heap.zone/git/scrypt-pwgen.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Index: iOS/MainViewController.m ================================================================== --- iOS/MainViewController.m +++ iOS/MainViewController.m @@ -1,7 +1,7 @@ /* - * Copyright (c) 2016, Jonathan Schleifer + * Copyright (c) 2016, 2017, Jonathan Schleifer * * https://heap.zone/git/scrypt-pwgen.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -58,11 +58,11 @@ } - (NSInteger)tableView: (UITableView *)tableView numberOfRowsInSection: (NSInteger)section { - return [self.sites count]; + return self.sites.count; } - (UITableViewCell *)tableView: (UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath { ADDED iOS/SelectKeyFileController.h Index: iOS/SelectKeyFileController.h ================================================================== --- /dev/null +++ iOS/SelectKeyFileController.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, 2017, Jonathan Schleifer + * + * https://heap.zone/git/scrypt-pwgen.git + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import + +#import "AddSiteController.h" + +@interface SelectKeyFileController: UITableViewController +{ + NSArray *_keyFiles; +} + +@property (retain) AddSiteController *addSiteController; +@end ADDED iOS/SelectKeyFileController.m Index: iOS/SelectKeyFileController.m ================================================================== --- /dev/null +++ iOS/SelectKeyFileController.m @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2016, 2017, Jonathan Schleifer + * + * https://heap.zone/git/scrypt-pwgen.git + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import "SelectKeyFileController.h" + +@implementation SelectKeyFileController +- (void)viewDidLoad +{ + NSString *documentDirectory; + NSArray *keyFiles; + NSError *error; + + [super viewDidLoad]; + + if ((documentDirectory = NSSearchPathForDirectoriesInDomains( + NSDocumentDirectory, NSUserDomainMask, YES).firstObject) == nil) { + NSLog(@"Could not get key files: No documents directory"); + [self.navigationController popViewControllerAnimated: YES]; + return; + } + + keyFiles = [NSFileManager.defaultManager + contentsOfDirectoryAtPath: documentDirectory + error: &error]; + + if (keyFiles == nil) { + NSLog(@"Could not get key files: %@", error); + [self.navigationController popViewControllerAnimated: YES]; + return; + } + + _keyFiles = [[keyFiles sortedArrayUsingSelector: + @selector(compare:)] retain]; +} + +- (void)dealloc +{ + [_keyFiles release]; + + [super dealloc]; +} + +- (NSInteger)tableView: (UITableView *)tableView + numberOfRowsInSection: (NSInteger)section +{ + return _keyFiles.count + 1; +} + +- (UITableViewCell *)tableView: (UITableView *)tableView + cellForRowAtIndexPath: (NSIndexPath *)indexPath +{ + UITableViewCell *cell = [tableView + dequeueReusableCellWithIdentifier: @"keyFile"]; + + if (cell == nil) + cell = [[[UITableViewCell alloc] + initWithStyle: UITableViewCellStyleDefault + reuseIdentifier: @"keyFile"] autorelease]; + + cell.textLabel.text = + (indexPath.row > 0 ? _keyFiles[indexPath.row - 1] : @"None"); + + return cell; +} + +- (void)tableView: (UITableView *)tableView + didSelectRowAtIndexPath: (NSIndexPath *)indexPath +{ + self.addSiteController.keyFile = + (indexPath.row > 0 ? _keyFiles[indexPath.row - 1] : nil); + self.addSiteController.keyFileLabel.text = + (indexPath.row > 0 ? _keyFiles[indexPath.row - 1] : @"None"); + + [self.navigationController popViewControllerAnimated: YES]; +} +@end Index: iOS/ShowDetailsController.h ================================================================== --- iOS/ShowDetailsController.h +++ iOS/ShowDetailsController.h @@ -1,7 +1,7 @@ /* - * Copyright (c) 2016, Jonathan Schleifer + * Copyright (c) 2016, 2017, Jonathan Schleifer * * https://heap.zone/git/scrypt-pwgen.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Index: iOS/ShowDetailsController.m ================================================================== --- iOS/ShowDetailsController.m +++ iOS/ShowDetailsController.m @@ -1,7 +1,7 @@ /* - * Copyright (c) 2016, Jonathan Schleifer + * Copyright (c) 2016, 2017, Jonathan Schleifer * * https://heap.zone/git/scrypt-pwgen.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -183,10 +183,28 @@ else generator = [NewPasswordGenerator generator]; generator.site = _name; generator.length = _length; + + if (_keyFile != nil) { + NSString *documentDirectory; + OFString *keyFilePath; + + if ((documentDirectory = NSSearchPathForDirectoriesInDomains( + NSDocumentDirectory, NSUserDomainMask, YES).firstObject) == + nil) { + NSLog(@"Could not get key files: No documents " + @"directory"); + return; + } + + keyFilePath = [documentDirectory.OFObject + stringByAppendingPathComponent: _keyFile]; + generator.keyFile = [OFMutableData + dataWithContentsOfFile: keyFilePath]; + } passphrase = of_strdup(self.passphraseField.text.UTF8String); generator.passphrase = passphrase; mainStoryboard = [UIStoryboard storyboardWithName: @"Main" @@ -198,10 +216,15 @@ dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ { @try { [generator derivePassword]; } @finally { + if (generator.keyFile != nil) + of_explicit_memset( + (void *)generator.keyFile.items, 0, + generator.keyFile.count); + of_explicit_memset(passphrase, 0, strlen(passphrase)); free(passphrase); } NSMutableString *password = [[[NSMutableString alloc] Index: iOS/SiteStorage.h ================================================================== --- iOS/SiteStorage.h +++ iOS/SiteStorage.h @@ -1,7 +1,7 @@ /* - * Copyright (c) 2016, Jonathan Schleifer + * Copyright (c) 2016, 2017, Jonathan Schleifer * * https://heap.zone/git/scrypt-pwgen.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Index: iOS/SiteStorage.m ================================================================== --- iOS/SiteStorage.m +++ iOS/SiteStorage.m @@ -1,7 +1,7 @@ /* - * Copyright (c) 2016, Jonathan Schleifer + * Copyright (c) 2016, 2017, Jonathan Schleifer * * https://heap.zone/git/scrypt-pwgen.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Index: iOS/main.m ================================================================== --- iOS/main.m +++ iOS/main.m @@ -1,7 +1,7 @@ /* - * Copyright (c) 2016, Jonathan Schleifer + * Copyright (c) 2016, 2017, Jonathan Schleifer * * https://heap.zone/git/scrypt-pwgen.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above Index: iOS/scrypt-pwgen.xcodeproj/project.pbxproj ================================================================== --- iOS/scrypt-pwgen.xcodeproj/project.pbxproj +++ iOS/scrypt-pwgen.xcodeproj/project.pbxproj @@ -21,10 +21,11 @@ 4B95252A1F9953350095F259 /* ObjFW_Bridge.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4B9525241F96BB820095F259 /* ObjFW_Bridge.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 4BA115D21DA9432D007ED4EA /* LegacyPasswordGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BA115CE1DA9432D007ED4EA /* LegacyPasswordGenerator.m */; settings = {COMPILER_FLAGS = "-fconstant-string-class=OFConstantString -fno-constant-cfstrings"; }; }; 4BA115D31DA9432D007ED4EA /* NewPasswordGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BA115D01DA9432D007ED4EA /* NewPasswordGenerator.m */; settings = {COMPILER_FLAGS = "-fconstant-string-class=OFConstantString -fno-constant-cfstrings"; }; }; 4BA115D61DA94390007ED4EA /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BA115D51DA94390007ED4EA /* UIKit.framework */; }; 4BB3CDFD1DA9764300FEE5ED /* AddSiteController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BB3CDFC1DA9764300FEE5ED /* AddSiteController.m */; }; + 4BC29DD51FCB5FAE00A1E786 /* SelectKeyFileController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BC29DD41FCB5FAE00A1E786 /* SelectKeyFileController.m */; }; 4BF4ADEA1DA9A3DB0073B995 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BF4ADE91DA9A3DB0073B995 /* Foundation.framework */; }; 4BF4ADED1DA9A6B00073B995 /* SiteStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BF4ADEC1DA9A6B00073B995 /* SiteStorage.m */; settings = {COMPILER_FLAGS = "-fconstant-string-class=OFConstantString -fno-constant-cfstrings"; }; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -65,10 +66,12 @@ 4BA115D01DA9432D007ED4EA /* NewPasswordGenerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NewPasswordGenerator.m; path = ../NewPasswordGenerator.m; sourceTree = ""; }; 4BA115D11DA9432D007ED4EA /* PasswordGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PasswordGenerator.h; path = ../PasswordGenerator.h; sourceTree = ""; }; 4BA115D51DA94390007ED4EA /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 4BB3CDFB1DA9764300FEE5ED /* AddSiteController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddSiteController.h; sourceTree = ""; }; 4BB3CDFC1DA9764300FEE5ED /* AddSiteController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AddSiteController.m; sourceTree = ""; }; + 4BC29DD41FCB5FAE00A1E786 /* SelectKeyFileController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SelectKeyFileController.m; sourceTree = ""; }; + 4BC29DD61FCB5FC400A1E786 /* SelectKeyFileController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SelectKeyFileController.h; sourceTree = ""; }; 4BF4ADE91DA9A3DB0073B995 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 4BF4ADEB1DA9A6B00073B995 /* SiteStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SiteStorage.h; sourceTree = ""; }; 4BF4ADEC1DA9A6B00073B995 /* SiteStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SiteStorage.m; sourceTree = ""; }; /* End PBXFileReference section */ @@ -118,10 +121,12 @@ 4B2E52F01DA942840040D091 /* Info.plist */, 4B2E52ED1DA942840040D091 /* LaunchScreen.storyboard */, 4B2E52E81DA942840040D091 /* Main.storyboard */, 4B2E52E51DA942840040D091 /* MainViewController.h */, 4B2E52E61DA942840040D091 /* MainViewController.m */, + 4BC29DD61FCB5FC400A1E786 /* SelectKeyFileController.h */, + 4BC29DD41FCB5FAE00A1E786 /* SelectKeyFileController.m */, 4B0719231DAA78D80065997A /* ShowDetailsController.h */, 4B0719241DAA78D80065997A /* ShowDetailsController.m */, 4BF4ADEB1DA9A6B00073B995 /* SiteStorage.h */, 4BF4ADEC1DA9A6B00073B995 /* SiteStorage.m */, 4B2E52E01DA942840040D091 /* main.m */, @@ -224,10 +229,11 @@ 4B2E52D81DA942840040D091 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4B82D1151DAAAFCE00F32B2F /* AboutController.m in Sources */, + 4BC29DD51FCB5FAE00A1E786 /* SelectKeyFileController.m in Sources */, 4BB3CDFD1DA9764300FEE5ED /* AddSiteController.m in Sources */, 4B2E52E41DA942840040D091 /* AppDelegate.m in Sources */, 4BA115D21DA9432D007ED4EA /* LegacyPasswordGenerator.m in Sources */, 4B2E52E71DA942840040D091 /* MainViewController.m in Sources */, 4BA115D31DA9432D007ED4EA /* NewPasswordGenerator.m in Sources */,