diff --git a/MacPass/MPPasswordCreatorViewController.m b/MacPass/MPPasswordCreatorViewController.m index 2c895788..6fa6f962 100644 --- a/MacPass/MPPasswordCreatorViewController.m +++ b/MacPass/MPPasswordCreatorViewController.m @@ -166,11 +166,12 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) { - (IBAction)_generatePassword:(id)sender { self.password = [NSString passwordWithCharactersets:self.characterFlags withCustomCharacters:self._customCharacters + ensureOccurence:NO length:self.passwordLength]; } - (NSString*)_customCharacters{ - if(self.useCustomString && [[self.customCharactersTextField stringValue] length] > 0) { + if(self.useCustomString && self.customCharactersTextField.stringValue.length > 0) { return self.customCharactersTextField.stringValue; } else{ @@ -187,7 +188,7 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) { - (IBAction)_usePassword:(id)sender { if(self.shouldCopyPasswordToPasteboardButton.state == NSOnState) { - [[MPPasteBoardController defaultController] copyObjects:@[self.password]]; + [MPPasteBoardController.defaultController copyObjects:@[self.password]]; } KPKEntry *entry = self.representedObject; if(entry && self.password.length > 0) { @@ -227,13 +228,13 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) { availableDefaults = [[NSMutableDictionary alloc] initWithCapacity:1]; } availableDefaults[[self.representedObject uuid].UUIDString] = entryDefaults; - [[NSUserDefaults standardUserDefaults] setObject:availableDefaults forKey:kMPSettingsKeyPasswordDefaultsForEntry]; + [NSUserDefaults.standardUserDefaults setObject:availableDefaults forKey:kMPSettingsKeyPasswordDefaultsForEntry]; } else if(!self.useEntryDefaults) { - [[NSUserDefaults standardUserDefaults] setInteger:self.passwordLength forKey:kMPSettingsKeyDefaultPasswordLength]; - [[NSUserDefaults standardUserDefaults] setInteger:self.characterFlags forKey:kMPSettingsKeyPasswordCharacterFlags]; - [[NSUserDefaults standardUserDefaults] setBool:self.useCustomString forKey:kMPSettingsKeyPasswordUseCustomString]; - [[NSUserDefaults standardUserDefaults] setObject:[self.customCharactersTextField stringValue] forKey:kMPSettingsKeyPasswordCustomString]; + [NSUserDefaults.standardUserDefaults setInteger:self.passwordLength forKey:kMPSettingsKeyDefaultPasswordLength]; + [NSUserDefaults.standardUserDefaults setInteger:self.characterFlags forKey:kMPSettingsKeyPasswordCharacterFlags]; + [NSUserDefaults.standardUserDefaults setBool:self.useCustomString forKey:kMPSettingsKeyPasswordUseCustomString]; + [NSUserDefaults.standardUserDefaults setObject:[self.customCharactersTextField stringValue] forKey:kMPSettingsKeyPasswordCustomString]; } else { NSLog(@"Cannot set password generator defaults. Inconsistent state. Aborting."); @@ -249,7 +250,7 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) { NSMutableDictionary *availableDefaults = [[self _availableEntryDefaults] mutableCopy]; NSAssert(availableDefaults, @"Password generator defaults for should be present!"); [availableDefaults removeObjectForKey:[self.representedObject uuid].UUIDString]; - [[NSUserDefaults standardUserDefaults] setObject:availableDefaults forKey:kMPSettingsKeyPasswordDefaultsForEntry]; + [NSUserDefaults.standardUserDefaults setObject:availableDefaults forKey:kMPSettingsKeyPasswordDefaultsForEntry]; self.useEntryDefaults = NO; /* Resetting the UI and Defaults is handled via the setter */ [self _updateSetDefaultsButton:NO]; } @@ -322,12 +323,12 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) { } - (NSDictionary *)_availableEntryDefaults { - return [[NSUserDefaults standardUserDefaults] dictionaryForKey:kMPSettingsKeyPasswordDefaultsForEntry]; + return [NSUserDefaults.standardUserDefaults dictionaryForKey:kMPSettingsKeyPasswordDefaultsForEntry]; } - (NSDictionary *)_currentEntryDefaults { if(self.representedObject) { - NSAssert([self.representedObject isKindOfClass:[KPKEntry class]], @"Only KPKEntry as represented object supported!"); + NSAssert([self.representedObject isKindOfClass:KPKEntry.class], @"Only KPKEntry as represented object supported!"); return [self _availableEntryDefaults][[self.representedObject uuid].UUIDString]; } return nil; diff --git a/MacPass/MPSettingsHelper.h b/MacPass/MPSettingsHelper.h index 9ceac17a..de9fe4b1 100644 --- a/MacPass/MPSettingsHelper.h +++ b/MacPass/MPSettingsHelper.h @@ -105,6 +105,7 @@ typedef NS_ENUM(NSUInteger, MPDoubleClickTitleAction) { APPKIT_EXTERN NSString *const kMPSettingsKeyCopyGeneratedPasswordToClipboard; APPKIT_EXTERN NSString *const kMPSettingsKeyDefaultPasswordLength; APPKIT_EXTERN NSString *const kMPSettingsKeyPasswordCharacterFlags; +APPKIT_EXTERN NSString *const kMPSettingsKeyPasswordEnsureOccurance; APPKIT_EXTERN NSString *const kMPSettingsKeyPasswordUseCustomString; APPKIT_EXTERN NSString *const kMPSettingsKeyPasswordCustomString; diff --git a/MacPass/MPSettingsHelper.m b/MacPass/MPSettingsHelper.m index 2848ae15..dab8612a 100644 --- a/MacPass/MPSettingsHelper.m +++ b/MacPass/MPSettingsHelper.m @@ -67,6 +67,7 @@ NSString *const kMPSettingsKeyCopyGeneratedPasswordToClipboard = @"CopyGe NSString *const kMPSettingsKeyDefaultPasswordLength = @"DefaultPasswordLength"; NSString *const kMPSettingsKeyPasswordCharacterFlags = @"PasswordCharacterFlags"; +NSString *const kMPSettingsKeyPasswordEnsureOccurance = @"PasswordEnsureOccurance"; NSString *const kMPSettingsKeyPasswordUseCustomString = @"PasswordUseCustomString"; NSString *const kMPSettingsKeyPasswordCustomString = @"PasswordCustomString"; @@ -134,7 +135,7 @@ NSString *const kMPDepricatedSettingsKeyLoadUnsecurePlugins = @"MP kMPSettingsKeyRememberKeyFilesForDatabases: @NO, kMPSettingsKeySendCommandForControlKey: @YES, kMPSettingsKeyEnableGlobalAutotype: @NO, - kMPSettingsKeyGlobalAutotypeKeyDataKey: [DDHotKey defaultHotKeyData], + kMPSettingsKeyGlobalAutotypeKeyDataKey: DDHotKey.defaultHotKeyData, kMPSettingsKeyDefaultGlobalAutotypeSequence: @"{USERNAME}{TAB}{PASSWORD}{ENTER}", kMPSettingsKeyAutotypeMatchTitle: @YES, kMPSettingsKeyAutotypeMatchURL: @NO, @@ -146,6 +147,7 @@ NSString *const kMPDepricatedSettingsKeyLoadUnsecurePlugins = @"MP kMPSettingsKeyPasswordCharacterFlags: @(MPPasswordCharactersAll), kMPSettingsKeyPasswordUseCustomString: @NO, kMPSettingsKeyPasswordCustomString: @"", + kMPSettingsKeyPasswordEnsureOccurance: @NO, kMPSettingsKeyDoubleClickURLAction: @(MPDoubleClickURLActionCopy), kMPSettingsKeyDoubleClickTitleAction: @(MPDoubleClickTitleActionInspect), kMPSettingsKeyLoadUnsecurePlugins: @NO, diff --git a/MacPass/NSString+MPPasswordCreation.h b/MacPass/NSString+MPPasswordCreation.h index 9888ade8..6b40d82d 100644 --- a/MacPass/NSString+MPPasswordCreation.h +++ b/MacPass/NSString+MPPasswordCreation.h @@ -42,7 +42,8 @@ typedef NS_OPTIONS(NSUInteger, MPPasswordCharacterFlags) { */ + (NSString *)passwordWithCharactersets:(MPPasswordCharacterFlags)allowedCharacters withCustomCharacters:(NSString*)customCharacters - length:(NSUInteger)theLength; + ensureOccurence:(BOOL)ensureOccurence + length:(NSUInteger)length; /** * Creats a password based on the supplied string * @@ -59,6 +60,10 @@ typedef NS_OPTIONS(NSUInteger, MPPasswordCharacterFlags) { * @return returns a random character from the string */ @property (nonatomic, readonly, copy) NSString *randomCharacter; +/** + * @return returns a shuffled copy of the receiving string + */ +@property (nonatomic, readonly, copy) NSString *shuffledString; /** * diff --git a/MacPass/NSString+MPPasswordCreation.m b/MacPass/NSString+MPPasswordCreation.m index cfa9a423..d8392cee 100644 --- a/MacPass/NSString+MPPasswordCreation.m +++ b/MacPass/NSString+MPPasswordCreation.m @@ -71,7 +71,8 @@ static NSString *mergeWithoutDuplicates(NSString* baseCharacters, NSString* cust } + (NSString *)passwordWithCharactersets:(MPPasswordCharacterFlags)allowedCharacters - withCustomCharacters:(NSString*)customCharacters + withCustomCharacters:(NSString *)customCharacters + ensureOccurence:(BOOL)ensureOccurence length:(NSUInteger)length { NSMutableString *password = [NSMutableString stringWithCapacity:length]; NSString *characters = mergeWithoutDuplicates( @@ -99,9 +100,7 @@ static NSString *mergeWithoutDuplicates(NSString* baseCharacters, NSString* cust if(useCustomString && customString.length > 0) { return [customString passwordWithLength:passwordLength]; } - return [NSString passwordWithCharactersets:characterFlags - withCustomCharacters:@"" - length:passwordLength]; + return [NSString passwordWithCharactersets:characterFlags withCustomCharacters:@"" ensureOccurence:NO length:passwordLength]; } - (NSString *)passwordWithLength:(NSUInteger)length { @@ -112,7 +111,7 @@ static NSString *mergeWithoutDuplicates(NSString* baseCharacters, NSString* cust if(self.length == 0) { return nil; } - return [self composedCharacterAtIndex:arc4random_uniform((int)self.length)]; + return [self composedCharacterAtIndex:arc4random_uniform((int)self.composedCharacterLength)]; } - (CGFloat)entropyWhithPossibleCharacterSet:(MPPasswordCharacterFlags)allowedCharacters orCustomCharacters:(NSString *)customCharacters { @@ -127,4 +126,17 @@ static NSString *mergeWithoutDuplicates(NSString* baseCharacters, NSString* cust CGFloat passwordLength = self.composedCharacterLength; return passwordLength * ( log10(alphabetCount) / log10(2) ); } + +- (NSString *)shuffledString { + NSMutableArray *characters = [self.composedCharacters mutableCopy]; + NSMutableString *shuffled = [[NSMutableString alloc] init]; + while(characters.count > 0) { + NSUInteger index = arc4random_uniform((int)characters.count); + [shuffled appendString:characters[index]]; + [characters removeObjectAtIndex:index]; + } + return [shuffled copy]; +} + + @end