diff --git a/KeePassKit b/KeePassKit index 4ca467dc..fcb5063c 160000 --- a/KeePassKit +++ b/KeePassKit @@ -1 +1 @@ -Subproject commit 4ca467dce9e1e316cee98d0b02b160d5fd375e42 +Subproject commit fcb5063c788865e0c02bf1cc9edf24f72b785ec3 diff --git a/MacPass/Base.lproj/DatabaseSettingsWindow.xib b/MacPass/Base.lproj/DatabaseSettingsWindow.xib index 959c032e..00a2f108 100644 --- a/MacPass/Base.lproj/DatabaseSettingsWindow.xib +++ b/MacPass/Base.lproj/DatabaseSettingsWindow.xib @@ -1,5 +1,5 @@ - + @@ -16,11 +16,15 @@ + + + + @@ -33,10 +37,10 @@ - - + + - + - + - + - + @@ -76,7 +80,7 @@ DQ - + @@ -85,7 +89,7 @@ DQ - + @@ -138,20 +142,20 @@ DQ - + - + - + - + - + @@ -162,7 +166,7 @@ DQ - + @@ -191,51 +195,66 @@ DQ - + - + @@ -244,7 +263,7 @@ DQ - + @@ -256,7 +275,7 @@ DQ - + @@ -333,7 +357,7 @@ DQ - + @@ -345,12 +369,12 @@ DQ - + - + @@ -362,7 +386,7 @@ DQ - + @@ -371,7 +395,7 @@ DQ - + @@ -380,12 +404,12 @@ DQ - + - + @@ -394,7 +418,7 @@ DQ - + @@ -406,7 +430,7 @@ DQ - + @@ -418,7 +442,7 @@ DQ - + @@ -432,6 +456,53 @@ DQ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -451,13 +522,10 @@ DQ - - - @@ -466,7 +534,25 @@ DQ - + + + + + + + + + + + + + + + + + + + diff --git a/MacPass/Base.lproj/InspectorView.xib b/MacPass/Base.lproj/InspectorView.xib index 14404bb7..3eb44c3e 100644 --- a/MacPass/Base.lproj/InspectorView.xib +++ b/MacPass/Base.lproj/InspectorView.xib @@ -85,7 +85,7 @@ - + diff --git a/MacPass/MPAutotypeCommand.m b/MacPass/MPAutotypeCommand.m index d293a8bd..42d31027 100644 --- a/MacPass/MPAutotypeCommand.m +++ b/MacPass/MPAutotypeCommand.m @@ -276,15 +276,19 @@ NSInteger value; if([numberScanner scanInteger:&value]) { if([kKPKAutotypeDelay isEqualToString:command]) { + if(MAX(0, value) <= 0) { + return; // Value too low, just skipp + } [commands addObject:[[MPAutotypeDelay alloc] initWithDelay:value]]; return; // Done } else if([kKPKAutotypeVirtualKey isEqualToString:command]) { + NSLog(@"Virutal key strokes aren't supported yet!"); // TODO add key } } else { - NSLog(@"Unable to determine delay!"); + NSLog(@"Unable to value part in command:%@", commandString); } } else { diff --git a/MacPass/MPAutotypeDelay.m b/MacPass/MPAutotypeDelay.m index f0aa012f..12996619 100644 --- a/MacPass/MPAutotypeDelay.m +++ b/MacPass/MPAutotypeDelay.m @@ -24,13 +24,14 @@ - (instancetype)initWithDelay:(NSUInteger)delay { self = [super init]; if(self) { - _delay = delay; + /* Delays longer than a minute are a bit lon */ + _delay = MIN(60,delay); } return self; } - (void)execute { - usleep((useconds_t)(_delay*1000*1000)); + usleep((useconds_t)(_delay*NSEC_PER_MSEC)); } @end diff --git a/MacPass/MPDatabaseSettingsWindowController.h b/MacPass/MPDatabaseSettingsWindowController.h index 3f7a43c9..fa55c3a5 100644 --- a/MacPass/MPDatabaseSettingsWindowController.h +++ b/MacPass/MPDatabaseSettingsWindowController.h @@ -44,6 +44,10 @@ typedef NS_ENUM(NSUInteger, MPDatabaseSettingsTab) { @property (weak) IBOutlet NSTextField *defaultUsernameTextField; @property (weak) IBOutlet NSPopUpButton *templateGroupPopUpButton; +@property (weak) IBOutlet NSButton *recommendKeyChangeCheckButton; +@property (weak) IBOutlet NSButton *enforceKeyChangeCheckButton; +@property (weak) IBOutlet NSTextField *recommendKeyChangeIntervalTextField; +@property (weak) IBOutlet NSTextField *enforceKeyChangeIntervalTextField; - (id)initWithDocument:(MPDocument *)document; diff --git a/MacPass/MPDatabaseSettingsWindowController.m b/MacPass/MPDatabaseSettingsWindowController.m index 4fa23742..29a74538 100644 --- a/MacPass/MPDatabaseSettingsWindowController.m +++ b/MacPass/MPDatabaseSettingsWindowController.m @@ -37,6 +37,33 @@ @implementation MPDatabaseSettingsWindowController +NSInteger _MPStateForBool(BOOL flag) { + return flag ? NSOnState : NSOffState; +} + +BOOL _MPBoolFotState(NSInteger state) { + switch (state) { + case NSOnState: + return YES; + default: + case NSMixedState: + NSLog(@"Indetermined state!"); + case NSOffState: + return NO; + break; + } +} + +void _MPSetState(id stateItem, BOOL isOn) { + if([stateItem respondsToSelector:@selector(setState:)]) { + [stateItem setState:_MPStateForBool(isOn)]; + } + else { + NSLog(@"%@ does not respond to setState:", stateItem); + assert(false); + } +} + - (NSString *)windowNibName { return @"DatabaseSettingsWindow"; } @@ -94,17 +121,27 @@ KPKGroup *templateGroup = [templateMenuItem representedObject]; _document.templates = templateGroup; - BOOL protectNotes = [self.protectNotesCheckButton state] == NSOnState; - BOOL protectPassword = [self.protectPasswortCheckButton state] == NSOnState; - BOOL protectTitle = [self.protectTitleCheckButton state] == NSOnState; - BOOL protectURL = [self.protectURLCheckButton state] == NSOnState; - BOOL protectUsername = [self.protectUserNameCheckButton state] == NSOnState; - metaData.protectNotes = protectNotes; - metaData.protectPassword = protectPassword; - metaData.protectTitle = protectTitle; - metaData.protectUrl = protectURL; - metaData.protectUserName = protectUsername; + BOOL enforceMasterKeyChange = _MPBoolFotState([self.enforceKeyChangeCheckButton state]); + BOOL recommendMasterKeyChange = _MPBoolFotState([self.recommendKeyChangeCheckButton state]); + + enforceMasterKeyChange &= ([[self.enforceKeyChangeIntervalTextField stringValue] length] != 0); + recommendMasterKeyChange &= ([[self.recommendKeyChangeIntervalTextField stringValue] length] != 0); + + NSInteger enfoceInterval = [self.enforceKeyChangeIntervalTextField integerValue]; + NSInteger recommendInterval = [self.recommendKeyChangeIntervalTextField integerValue]; + + metaData.masterKeyChangeEnforcementInterval = enforceMasterKeyChange ? enfoceInterval : -1; + metaData.masterKeyChangeRecommendationInterval = recommendMasterKeyChange ? recommendInterval : -1; + + /* Security */ + + metaData.protectNotes = _MPBoolFotState([self.protectNotesCheckButton state]); + metaData.protectPassword = _MPBoolFotState([self.protectPasswortCheckButton state]); + metaData.protectTitle = _MPBoolFotState([self.protectTitleCheckButton state]); + metaData.protectUrl = _MPBoolFotState([self.protectURLCheckButton state]); + metaData.protectUserName = _MPBoolFotState([self.protectUserNameCheckButton state]); + metaData.defaultUserName = [self.defaultUsernameTextField stringValue]; /* @@ -178,16 +215,18 @@ } - (void)_setupProtectionTab:(KPKMetaData *)metaData { - [self.protectNotesCheckButton setState:metaData.protectNotes ? NSOnState : NSOffState ]; - [self.protectPasswortCheckButton setState:metaData.protectPassword ? NSOnState : NSOffState]; - [self.protectTitleCheckButton setState:metaData.protectTitle ? NSOnState : NSOffState]; - [self.protectURLCheckButton setState:metaData.protectUrl ? NSOnState : NSOffState]; - [self.protectUserNameCheckButton setState:metaData.protectUserName ? NSOnState : NSOffState]; + _MPSetState(self.protectNotesCheckButton, metaData.protectNotes); + _MPSetState(self.protectPasswortCheckButton, metaData.protectPassword); + _MPSetState(self.protectTitleCheckButton, metaData.protectTitle); + _MPSetState(self.protectURLCheckButton, metaData.protectUrl); + _MPSetState(self.protectUserNameCheckButton, metaData.protectUserName); + [self.encryptionRoundsTextField setIntegerValue:metaData.rounds]; [self.benchmarkButton setEnabled:YES]; } - (void)_setupAdvancedTab:(KPKTree *)tree { + /* TODO Do not use bindings, as the user should be able to cancel */ [self bind:@"trashEnabled" toObject:tree.metaData withKeyPath:@"recycleBinEnabled" options:nil]; [self.enableRecycleBinCheckButton bind:NSValueBinding toObject:self withKeyPath:@"trashEnabled" options:nil]; [self.selectRecycleBinGroupPopUpButton bind:NSEnabledBinding toObject:self withKeyPath:@"trashEnabled" options:nil]; @@ -196,6 +235,26 @@ [self.defaultUsernameTextField setStringValue:tree.metaData.defaultUserName]; [self.defaultUsernameTextField setEditable:YES]; [self _updateTemplateGroup:tree]; + + _MPSetState(self.enforceKeyChangeCheckButton, tree.metaData.enforceMasterKeyChange); + _MPSetState(self.recommendKeyChangeCheckButton, tree.metaData.recommendMasterKeyChange); + [self.enforceKeyChangeIntervalTextField setEnabled:tree.metaData.enforceMasterKeyChange]; + [self.recommendKeyChangeIntervalTextField setEnabled:tree.metaData.recommendMasterKeyChange]; + + if(tree.metaData.enforceMasterKeyChange) { + [self.enforceKeyChangeIntervalTextField setIntegerValue:tree.metaData.masterKeyChangeEnforcementInterval]; + } + else { + [self.enforceKeyChangeIntervalTextField setStringValue:@""]; + } + if(tree.metaData.recommendMasterKeyChange) { + [self.recommendKeyChangeIntervalTextField setIntegerValue:tree.metaData.masterKeyChangeRecommendationInterval]; + } + else { + [self.recommendKeyChangeIntervalTextField setStringValue:@""]; + } + [self.enforceKeyChangeCheckButton bind:NSValueBinding toObject:self.enforceKeyChangeIntervalTextField withKeyPath:NSEnabledBinding options:nil]; + [self.recommendKeyChangeCheckButton bind:NSValueBinding toObject:self.recommendKeyChangeIntervalTextField withKeyPath:NSEnabledBinding options:nil]; } - (void)_updateFirstResponder {