diff --git a/MacPass.xcodeproj/project.pbxproj b/MacPass.xcodeproj/project.pbxproj index 5adf29ab..8311789b 100644 --- a/MacPass.xcodeproj/project.pbxproj +++ b/MacPass.xcodeproj/project.pbxproj @@ -28,6 +28,7 @@ 4C17F109184E6B6C00E85625 /* 30_TerminalTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C17F107184E6B6C00E85625 /* 30_TerminalTemplate.pdf */; }; 4C1DDCDD1711ECEB00C98DA3 /* PasswordCreatorWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4C1DDCDC1711ECEB00C98DA3 /* PasswordCreatorWindow.xib */; }; 4C1E9885185F71A800943563 /* MPContextBarViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1E9884185F71A800943563 /* MPContextBarViewController.m */; }; + 4C1F7FA21E3A12E600D6A40E /* MPModifiedKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1F7FA11E3A12E600D6A40E /* MPModifiedKey.m */; }; 4C1FA07B18231900003A3F8C /* MPDocument+Autotype.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1FA07A18231900003A3F8C /* MPDocument+Autotype.m */; }; 4C224B4217DFCB2400FF6AEE /* MPNumericalInputFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C224B4117DFCB2400FF6AEE /* MPNumericalInputFormatter.m */; }; 4C25703F1BF11C2300D39416 /* MPPluginSettingsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C25703D1BF11C2300D39416 /* MPPluginSettingsController.m */; }; @@ -324,6 +325,8 @@ 4C1DDCDC1711ECEB00C98DA3 /* PasswordCreatorWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PasswordCreatorWindow.xib; sourceTree = ""; }; 4C1E9883185F71A800943563 /* MPContextBarViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPContextBarViewController.h; sourceTree = ""; }; 4C1E9884185F71A800943563 /* MPContextBarViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPContextBarViewController.m; sourceTree = ""; }; + 4C1F7FA01E3A12E600D6A40E /* MPModifiedKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPModifiedKey.h; sourceTree = ""; }; + 4C1F7FA11E3A12E600D6A40E /* MPModifiedKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPModifiedKey.m; sourceTree = ""; }; 4C1FA07A18231900003A3F8C /* MPDocument+Autotype.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MPDocument+Autotype.m"; sourceTree = ""; }; 4C21F29D195B39B9002D610D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/MainMenu.strings; sourceTree = ""; }; 4C21F29F195B3A48002D610D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/MainMenu.strings; sourceTree = ""; }; @@ -1261,6 +1264,8 @@ 4CD2B9051849424B0051B395 /* MPAutotypeContext.m */, 4CA3530918A53CB800839B0F /* MPKeyMapper.h */, 4CA3530A18A53CB800839B0F /* MPKeyMapper.m */, + 4C1F7FA01E3A12E600D6A40E /* MPModifiedKey.h */, + 4C1F7FA11E3A12E600D6A40E /* MPModifiedKey.m */, ); name = Autotype; sourceTree = ""; @@ -1730,6 +1735,7 @@ 4C89F524182FB4740069C73C /* MPAutotypeCommand.m in Sources */, 4CFC53BF16E94729007396BE /* MPShadowBox.m in Sources */, 4C0AF62F195C1F2B009E658D /* MPEntrySearchContext.m in Sources */, + 4C1F7FA21E3A12E600D6A40E /* MPModifiedKey.m in Sources */, 4C888C9316EB6F5E003D34A1 /* MPToolbarItem.m in Sources */, 4C888C9716EB754B003D34A1 /* MPActionHelper.m in Sources */, 4C811C8316ECD06E00C4BAC6 /* MPKeyfilePathControlDelegate.m in Sources */, diff --git a/MacPass/MPAutotypeCommand.h b/MacPass/MPAutotypeCommand.h index abadbef5..59ab898a 100644 --- a/MacPass/MPAutotypeCommand.h +++ b/MacPass/MPAutotypeCommand.h @@ -7,7 +7,7 @@ // #import - +#import "MPModifiedKey.h" @class MPAutotypeContext; /** @@ -39,6 +39,7 @@ * @param flags modifier flags for the key press event */ - (void)sendPressKey:(CGKeyCode)keyCode modifierFlags:(CGEventFlags)flags; +- (void)sendPressKey:(MPModifiedKey)key; /** * Convenience message to be sent for executing a simple paste command diff --git a/MacPass/MPAutotypeCommand.m b/MacPass/MPAutotypeCommand.m index a458b4fd..0390e398 100644 --- a/MacPass/MPAutotypeCommand.m +++ b/MacPass/MPAutotypeCommand.m @@ -261,10 +261,9 @@ typedef struct { * http://keepass.info/help/v2/autotype_obfuscation.html */ - NSString *paste = @""; + NSMutableString *paste = [@"" mutableCopy]; - NSMutableArray *typeKeys = [[NSMutableArray alloc] init]; - NSMutableArray *modifiers = [[NSMutableArray alloc] init]; + NSMutableArray *typeKeys = [[NSMutableArray alloc] init]; /* * seed the random number generator using the first 4 bytes of the string's SHA1 @@ -279,29 +278,21 @@ typedef struct { for (NSUInteger i = 0; i < pasteContent.length; i++) { NSUInteger part = random() % 2; - unichar key = [pasteContent characterAtIndex:i]; - MPModifiedKey mKey = [MPKeyMapper modifiedKeyForCharacter:[NSString stringWithFormat:@"%c", key]]; + NSString *key = [pasteContent substringWithRange:NSMakeRange(i, 1)]; + MPModifiedKey mKey = [MPKeyMapper modifiedKeyForCharacter:key]; /* append unknown keycodes to the paste since we can't type them */ if (part == 0 || mKey.keyCode == kMPUnknownKeyCode) { - paste = [paste stringByAppendingFormat:@"%c", key]; - - [typeKeys addObject:@(kVK_RightArrow)]; - [modifiers addObject:@0]; + [paste appendString:key]; + [typeKeys addObject:[NSValue valueWithModifiedKey:MPMakeModifiedKey(0, kVK_RightArrow)]]; } else { - [typeKeys addObject:@(mKey.keyCode)]; - - if ([[NSCharacterSet uppercaseLetterCharacterSet] characterIsMember:key]) - [modifiers addObject:@(kCGEventFlagMaskShift)]; - else - [modifiers addObject:@0]; + [typeKeys addObject:[NSValue valueWithModifiedKey:mKey ]]; } } /* move to the end of the content */ for (NSUInteger i = typeKeys.count; i < pasteContent.length; i++) { - [typeKeys addObject:@(kVK_RightArrow)]; - [modifiers addObject:@0]; + [typeKeys addObject:[NSValue valueWithModifiedKey:MPMakeModifiedKey(0, kVK_RightArrow)]]; } /* add paste command */ @@ -315,7 +306,7 @@ typedef struct { } for (NSUInteger i = 0; i < typeKeys.count; i++) { - [commands addObject:[[MPAutotypeKeyPress alloc] initWithModifierMask:[modifiers[i] longLongValue] keyCode:[typeKeys[i] unsignedShortValue]]]; + [commands addObject:[[MPAutotypeKeyPress alloc] initWithModifiedKey:typeKeys[i].modifiedKeyValue]]; } } } @@ -412,6 +403,10 @@ typedef struct { return YES; } +- (void)sendPressKey:(MPModifiedKey)key { + [self sendPressKey:key.keyCode modifierFlags:key.modifier]; +} + - (void)sendPressKey:(CGKeyCode)keyCode modifierFlags:(CGEventFlags)flags { CGEventSourceRef eventSource = CGEventSourceCreate(kCGEventSourceStatePrivate); diff --git a/MacPass/MPAutotypeKeyPress.h b/MacPass/MPAutotypeKeyPress.h index 8a197a6e..f7c56ad2 100644 --- a/MacPass/MPAutotypeKeyPress.h +++ b/MacPass/MPAutotypeKeyPress.h @@ -7,15 +7,15 @@ // #import "MPAutotypeCommand.h" - +#import "MPModifiedKey.h" /** * Autotype command to press a single key. Can be used with modifier keys as well */ @interface MPAutotypeKeyPress : MPAutotypeCommand -@property (assign) CGEventFlags modifierMask; -@property (assign) CGKeyCode keyCode; +@property (readonly, assign) MPModifiedKey key; +- (instancetype)initWithModifiedKey:(MPModifiedKey)key; - (instancetype)initWithModifierMask:(CGEventFlags)modiferMask keyCode:(CGKeyCode)code; - (instancetype)initWithModifierMask:(CGEventFlags)modiferMask character:(NSString *)character; diff --git a/MacPass/MPAutotypeKeyPress.m b/MacPass/MPAutotypeKeyPress.m index 26224959..474745e2 100644 --- a/MacPass/MPAutotypeKeyPress.m +++ b/MacPass/MPAutotypeKeyPress.m @@ -22,14 +22,18 @@ static CGEventFlags _updateModifierMaskForCurrentDefaults(CGEventFlags modifiers return modifiers; } -- (instancetype)initWithModifierMask:(CGEventFlags)modiferMask keyCode:(CGKeyCode)code { +- (instancetype)initWithModifiedKey:(MPModifiedKey)key { self = [super init]; if(self) { - _modifierMask = _updateModifierMaskForCurrentDefaults(modiferMask); - _keyCode = code; + _key = key; + _key.modifier = _updateModifierMaskForCurrentDefaults(_key.modifier); } return self; } +- (instancetype)initWithModifierMask:(CGEventFlags)modiferMask keyCode:(CGKeyCode)code { + self = [self initWithModifiedKey:MPMakeModifiedKey(modiferMask, code)]; + return self; +} - (instancetype)initWithModifierMask:(CGEventFlags)modiferMask character:(NSString *)character { MPModifiedKey mappedKey = [MPKeyMapper modifiedKeyForCharacter:character]; @@ -40,13 +44,13 @@ static CGEventFlags _updateModifierMaskForCurrentDefaults(CGEventFlags modifiers if(mappedKey.modifier && (modiferMask != mappedKey.modifier)) { NSLog(@"Supplied modifiers for character %@ do not match required modifiers", character); } - self = [self initWithModifierMask:modiferMask keyCode:mappedKey.modifier]; + self = [self initWithModifierMask:modiferMask keyCode:mappedKey.keyCode]; } return self; } - (NSString *)description { - return [[NSString alloc] initWithFormat:@"%@: modifierMaks:%llu keyCode:%d", [self class], self.modifierMask, self.keyCode]; + return [[NSString alloc] initWithFormat:@"%@: modifierMaks:%llu keyCode:%d", [self class], self.key.modifier, self.key.keyCode]; } - (void)execute { @@ -54,7 +58,7 @@ static CGEventFlags _updateModifierMaskForCurrentDefaults(CGEventFlags modifiers return; // no valid command. Stop. } //CGKeyCode mappedKey = [self _transformKeyCode]; - [self sendPressKey:self.keyCode modifierFlags:self.modifierMask]; + [self sendPressKey:self.key]; } - (BOOL)isValid { diff --git a/MacPass/MPKeyMapper.h b/MacPass/MPKeyMapper.h index b12a87ee..4bf3369e 100644 --- a/MacPass/MPKeyMapper.h +++ b/MacPass/MPKeyMapper.h @@ -7,21 +7,10 @@ // #import +#import "MPModifiedKey.h" FOUNDATION_EXTERN uint16_t const kMPUnknownKeyCode; -typedef struct { - CGEventFlags modifier; - CGKeyCode keyCode; -} MPModifiedKey; - -NS_INLINE MPModifiedKey MPMakeModifiedKey(CGEventFlags modifier, CGKeyCode keyCode) { - MPModifiedKey k; - k.keyCode = keyCode; - k.modifier = modifier; - return k; -} - @interface MPKeyMapper : NSObject /** diff --git a/MacPass/MPKeyMapper.m b/MacPass/MPKeyMapper.m index 8de5f9fd..f638e3ab 100644 --- a/MacPass/MPKeyMapper.m +++ b/MacPass/MPKeyMapper.m @@ -22,7 +22,7 @@ #import "MPKeyMapper.h" #import -#define MPSafeSetPointer(pointer, value) if(pointer != 0) { *pointer = value; } +#define MPArrayCount(array) (sizeof(array) / sizeof(array[0])) uint16_t const kMPUnknownKeyCode = UINT16_MAX; @@ -106,12 +106,11 @@ uint16_t const kMPUnknownKeyCode = UINT16_MAX; /* Loop through every keycode (0 - 127) to find its current mapping. */ /* Loop throuhg every control key compbination for every virtual key */ for(CGKeyCode keyCode = 0; keyCode < 128; ++keyCode) { - for(int modifierIndex = 0; modifierIndex < sizeof(modifierCombinations); modifierIndex++) { + for(int modifierIndex = 0; modifierIndex < MPArrayCount(modifierCombinations); modifierIndex++) { MPModifiedKey mKey = MPMakeModifiedKey(modifierCombinations[modifierIndex], keyCode); NSString *string = [self stringForModifiedKey:mKey]; if(string != nil && string.length > 0 && nil == tempCharToCodeDict[string]) { - NSValue *value = [NSValue valueWithBytes:&mKey objCType:@encode(MPModifiedKey)]; - tempCharToCodeDict[string] = value; + tempCharToCodeDict[string] = [NSValue valueWithModifiedKey:mKey]; } } } @@ -123,9 +122,7 @@ uint16_t const kMPUnknownKeyCode = UINT16_MAX; if(!result) { return MPMakeModifiedKey(0, kMPUnknownKeyCode); } - MPModifiedKey mKey; - [result getValue:&mKey]; - return mKey; + return result.modifiedKeyValue; } @end diff --git a/MacPass/MPModifiedKey.h b/MacPass/MPModifiedKey.h new file mode 100644 index 00000000..2956a36f --- /dev/null +++ b/MacPass/MPModifiedKey.h @@ -0,0 +1,26 @@ +// +// MPModifiedKey.h +// MacPass +// +// Created by Michael Starke on 26/01/2017. +// Copyright © 2017 HicknHack Software GmbH. All rights reserved. +// + +#import + +typedef struct { + CGEventFlags modifier; + CGKeyCode keyCode; +} MPModifiedKey; + +NS_INLINE MPModifiedKey MPMakeModifiedKey(CGEventFlags modifier, CGKeyCode keyCode) { + MPModifiedKey k; + k.keyCode = keyCode; + k.modifier = modifier; + return k; +} + +@interface NSValue(NSValueMPModifiedKeyExtensions) +@property (nonatomic, readonly, assign) MPModifiedKey modifiedKeyValue; ++ (instancetype)valueWithModifiedKey:(MPModifiedKey)key; +@end diff --git a/MacPass/MPModifiedKey.m b/MacPass/MPModifiedKey.m new file mode 100644 index 00000000..821a2a58 --- /dev/null +++ b/MacPass/MPModifiedKey.m @@ -0,0 +1,24 @@ +// +// MPModifiedKey.m +// MacPass +// +// Created by Michael Starke on 26/01/2017. +// Copyright © 2017 HicknHack Software GmbH. All rights reserved. +// + +#import "MPModifiedKey.h" + +@implementation NSValue(NSValueMPModifiedKeyExtensions) + +- (MPModifiedKey)modifiedKeyValue { + MPModifiedKey key; + [self getValue:&key]; + return key; +} + ++ (instancetype)valueWithModifiedKey:(MPModifiedKey)key { + return [NSValue valueWithBytes:&key objCType:@encode(MPModifiedKey)]; +} + +@end +