├── .gitignore ├── Cartfile ├── Cartfile.resolved ├── LICENSE.md ├── README.md ├── ReiKey.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── installer ├── installer.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── installer.xcscheme └── installer │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── icon_128x128.png │ │ ├── icon_128x128@2x.png │ │ ├── icon_16x16.png │ │ ├── icon_16x16@2x.png │ │ ├── icon_256x256.png │ │ ├── icon_256x256@2x.png │ │ ├── icon_32x32.png │ │ ├── icon_32x32@2x.png │ │ ├── icon_512x512.png │ │ └── icon_512x512@2x.png │ ├── Contents.json │ ├── FriendsDigita.imageset │ │ ├── Contents.json │ │ └── digita.pdf │ ├── FriendsMacPaw.imageset │ │ ├── Contents.json │ │ └── macpaw.png │ ├── FriendsMalwarebytes.imageset │ │ ├── Contents.json │ │ └── malwarebytes.pdf │ ├── FriendsSophos.imageset │ │ ├── Contents.json │ │ └── sophos.png │ ├── ObjectiveSee.imageset │ │ ├── Contents.json │ │ └── objectiveSee.pdf │ ├── Refresh.imageset │ │ ├── Contents.json │ │ ├── Refresh.pdf │ │ └── RefreshDark.pdf │ ├── ReiKeyIcon.imageset │ │ ├── Contents.json │ │ ├── Icon.pdf │ │ └── IconDark.pdf │ ├── ReiKeyText.imageset │ │ ├── Contents.json │ │ └── rkText.pdf │ └── Update.imageset │ │ ├── Contents.json │ │ ├── update.pdf │ │ ├── updateDark.pdf │ │ └── updateLight.pdf │ ├── Base.lproj │ └── MainMenu.xib │ ├── Configure.h │ ├── Configure.m │ ├── ConfigureWindowController.h │ ├── ConfigureWindowController.m │ ├── ConfigureWindowController.xib │ ├── Info.plist │ ├── ReiKey Installer.entitlements │ ├── main.h │ └── main.m ├── loginItem ├── loginItem.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── loginItem.xcscheme └── loginItem │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── AppReceipt.h │ ├── AppReceipt.m │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── icon_128x128.png │ │ ├── icon_128x128@2x.png │ │ ├── icon_16x16.png │ │ ├── icon_16x16@2x.png │ │ ├── icon_256x256.png │ │ ├── icon_256x256@2x.png │ │ ├── icon_32x32.png │ │ ├── icon_32x32@2x.png │ │ └── icon_512x512.png │ ├── Contents.json │ ├── ReiKeyIcon.imageset │ │ ├── Contents.json │ │ ├── rkIcon.pdf │ │ └── rkIconDark.pdf │ ├── ReiKeyText.imageset │ │ ├── Contents.json │ │ └── rkText.pdf │ ├── StatusActive.imageset │ │ ├── Active.pdf │ │ └── Contents.json │ └── StatusInactive.imageset │ │ ├── Contents.json │ │ └── Inactive.pdf │ ├── Base.lproj │ └── MainMenu.xib │ ├── Info.plist │ ├── ReiKey Helper.entitlements │ ├── StatusBarItem.h │ ├── StatusBarItem.m │ ├── StatusBarPopover.xib │ ├── StatusBarPopoverController.h │ ├── StatusBarPopoverController.m │ └── main.m ├── mainApp ├── mainApp.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── mainApp.xcscheme └── mainApp │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── icon_128x128.png │ │ ├── icon_128x128@2x.png │ │ ├── icon_16x16.png │ │ ├── icon_16x16@2x.png │ │ ├── icon_256x256.png │ │ ├── icon_256x256@2x.png │ │ ├── icon_32x32.png │ │ ├── icon_32x32@2x.png │ │ ├── icon_512x512.png │ │ └── icon_512x512@2x.png │ ├── Contents.json │ ├── FriendsDigita.imageset │ │ ├── Contents.json │ │ └── digita.pdf │ ├── FriendsMacPaw.imageset │ │ ├── Contents.json │ │ └── macpaw.pdf │ ├── FriendsMalwarebytes.imageset │ │ ├── Contents.json │ │ └── malwarebytes.pdf │ ├── FriendsSophos.imageset │ │ ├── Contents.json │ │ └── sophos.png │ ├── Refresh.imageset │ │ ├── Contents.json │ │ ├── Refresh.pdf │ │ └── RefreshDark.pdf │ ├── ReiKeyIcon.imageset │ │ ├── Contents.json │ │ ├── Icon.pdf │ │ └── IconDark.pdf │ ├── ReiKeyText.imageset │ │ ├── Contents.json │ │ └── rkText.pdf │ └── Update.imageset │ │ ├── Contents.json │ │ ├── update.pdf │ │ ├── updateDark.pdf │ │ └── updateLight.pdf │ ├── Base.lproj │ └── MainMenu.xib │ ├── Info.plist │ ├── NSApplicationKeyEvents.h │ ├── NSApplicationKeyEvents.m │ ├── Preferences.xib │ ├── PrefsWindowController.h │ ├── PrefsWindowController.m │ ├── ReiKey.entitlements │ ├── Scan.xib │ ├── ScanRow.h │ ├── ScanRow.m │ ├── ScanWindowController.h │ ├── ScanWindowController.m │ ├── Welcome.xib │ ├── WelcomeWindowController.h │ ├── WelcomeWindowController.m │ ├── main.h │ ├── main.m │ └── patrons.txt └── shared ├── AboutWindow.xib ├── AboutWindowController.h ├── AboutWindowController.m ├── AppIcon.appiconset ├── Contents.json ├── icon_128x128.png ├── icon_128x128@2x.png ├── icon_16x16.png ├── icon_16x16@2x.png ├── icon_256x256.png ├── icon_256x256@2x.png ├── icon_32x32.png ├── icon_32x32@2x.png └── icon_512x512.png ├── EventTaps.h ├── EventTaps.m ├── Update.h ├── Update.m ├── UpdateWindow.xib ├── UpdateWindowController.h ├── UpdateWindowController.m ├── UserClientShared.h ├── consts.h ├── images ├── objectiveSeeLogo.png └── objectiveSeeText.png ├── logging.h ├── logging.m ├── patrons.txt ├── signing.h ├── signing.m ├── utilities.h └── utilities.m /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Carthage/* 3 | DerivedData/* 4 | ReiKey.xcworkspace/xcuserdata/* 5 | loginItem/loginItem.xcodeproj/xcuserdata/* 6 | mainApp/mainApp.xcodeproj/xcuserdata/* 7 | installer/installer.xcodeproj/xcuserdata/* 8 | 9 | -------------------------------------------------------------------------------- /Cartfile: -------------------------------------------------------------------------------- 1 | github "getsentry/sentry-cocoa" "4.1.0" 2 | -------------------------------------------------------------------------------- /Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "getsentry/sentry-cocoa" "4.1.0" 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ReiKey ([Download](https://objective-see.com/products/reikey.html)) 2 | 3 |

4 | 5 |

6 | 7 | ![ReiKey](https://objective-see.com/images/RK/rk.png) 8 | 9 | Malware and other applications may install persistent keyboard "event taps" to intercept your keystrokes. 10 | ReiKey can scan, detect, and monitor for such taps. [Read More](https://objective-see.com/products/reikey.html) 11 | 12 | Note: to build, first run: `carthage update` (in project directory) 13 | 14 | Mahalo to the "Friends of Objective-See": 15 | * Digita Security 16 | * Sophos 17 | * MacPaw 18 | * Malwarebytes 19 | * SmugMug + Flikr 20 | * Guardian Mobile Firewall 21 | * SecureMac 22 | 23 | Mahalo to the following patrons (2^4+): 24 | 25 | Halo Privacy 26 | 27 | 28 | Aaron Kiemele 29 | Beau Galbraith 30 | Khalil Sehnaoui 31 | Nando Mendonca 32 | Randy Wong 33 | Stuart Ashenbrenner 34 | 35 | 36 | Aaron Blair (XORcat) 37 | Allen Hancock 38 | Andy One 39 | Brad Knowles 40 | Brian Genz 41 | Chris Ferebee 42 | Chris H 43 | Chuck Talk 44 | Clinton Campbell 45 | Colby Bourgeois 46 | Douglas J Unruh 47 | Edmund Harriss 48 | eric mak 49 | Gerso Guillen 50 | James Proud 51 | Jamie Roberts 52 | Jeff Golden 53 | Joaquim Espinhara 54 | Keelian W. 55 | Les Aker 56 | Marc Hedlund 57 | Mark Kenaston 58 | Mauro MOschetta 59 | Ming 60 | Not Invader Zim 61 | PORTHUNTER 62 | Rudolf Coetzee 63 | Russell Imrie 64 | Sam Tilston 65 | Samantha Luber 66 | Sarah Edwards 67 | Shain Singh 68 | Strong Solutions 69 | Terry J Fundak 70 | trifero 71 | William Cole 72 | William Hutchison 73 | -------------------------------------------------------------------------------- /ReiKey.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 9 | 10 | 11 | 14 | 16 | 17 | 18 | 21 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /ReiKey.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /installer/installer.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /installer/installer.xcodeproj/xcshareddata/xcschemes/installer.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 60 | 61 | 67 | 68 | 69 | 70 | 71 | 72 | 82 | 84 | 90 | 91 | 92 | 93 | 94 | 95 | 101 | 103 | 109 | 110 | 111 | 112 | 114 | 115 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /installer/installer/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/31/18. 6 | // Copyright (c) 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AboutWindowController.h" 12 | #import "ConfigureWindowController.h" 13 | 14 | @interface AppDelegate : NSObject 15 | { 16 | 17 | } 18 | 19 | /* PROPERTIES */ 20 | 21 | //about window controller 22 | @property(nonatomic, retain)AboutWindowController* aboutWindowController; 23 | 24 | //configure window controller 25 | @property(nonatomic, retain)ConfigureWindowController* configureWindowController; 26 | 27 | /* METHODS */ 28 | 29 | @end 30 | 31 | 32 | -------------------------------------------------------------------------------- /installer/installer/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/31/18 6 | // Copyright (c) 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #import "consts.h" 10 | #import "Configure.h" 11 | #import "utilities.h" 12 | #import "AppDelegate.h" 13 | 14 | @interface AppDelegate () 15 | 16 | @property (weak) IBOutlet NSWindow *window; 17 | @end 18 | 19 | @implementation AppDelegate 20 | 21 | @synthesize aboutWindowController; 22 | @synthesize configureWindowController; 23 | 24 | //main app interface 25 | // just show configure window... 26 | -(void)applicationDidFinishLaunching:(NSNotification *)aNotification 27 | { 28 | //alloc/init config 29 | configureWindowController = [[ConfigureWindowController alloc] initWithWindowNibName:@"ConfigureWindowController"]; 30 | 31 | //indicated title bar is tranparent (too) 32 | self.configureWindowController.window.titlebarAppearsTransparent = YES; 33 | 34 | //display it 35 | // call this first to so that outlets are connected 36 | [self.configureWindowController display]; 37 | 38 | //configure it 39 | [self.configureWindowController configure]; 40 | 41 | return; 42 | } 43 | 44 | //automatically invoked when user clicks 'About/Info' 45 | -(IBAction)about:(id)sender 46 | { 47 | //alloc/init settings window 48 | if(nil == self.aboutWindowController) 49 | { 50 | //alloc/init 51 | aboutWindowController = [[AboutWindowController alloc] initWithWindowNibName:@"AboutWindow"]; 52 | } 53 | 54 | //center window 55 | [[self.aboutWindowController window] center]; 56 | 57 | //show it 58 | [self.aboutWindowController showWindow:self]; 59 | 60 | return; 61 | } 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "icon_16x16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "icon_16x16@2x.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "icon_32x32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "icon_32x32@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "icon_128x128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "icon_128x128@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "icon_256x256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "icon_256x256@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "icon_512x512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "icon_512x512@2x.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/AppIcon.appiconset/icon_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/AppIcon.appiconset/icon_128x128.png -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/AppIcon.appiconset/icon_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/AppIcon.appiconset/icon_16x16.png -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/AppIcon.appiconset/icon_256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/AppIcon.appiconset/icon_256x256.png -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/AppIcon.appiconset/icon_32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/AppIcon.appiconset/icon_32x32.png -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/AppIcon.appiconset/icon_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/AppIcon.appiconset/icon_512x512.png -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/FriendsDigita.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "digita.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/FriendsDigita.imageset/digita.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/FriendsDigita.imageset/digita.pdf -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/FriendsMacPaw.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "macpaw.png" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/FriendsMacPaw.imageset/macpaw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/FriendsMacPaw.imageset/macpaw.png -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/FriendsMalwarebytes.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "malwarebytes.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/FriendsMalwarebytes.imageset/malwarebytes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/FriendsMalwarebytes.imageset/malwarebytes.pdf -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/FriendsSophos.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "sophos.png" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/FriendsSophos.imageset/sophos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/FriendsSophos.imageset/sophos.png -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/ObjectiveSee.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "objectiveSee.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/ObjectiveSee.imageset/objectiveSee.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/ObjectiveSee.imageset/objectiveSee.pdf -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/Refresh.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "Refresh.pdf" 6 | }, 7 | { 8 | "idiom" : "mac", 9 | "filename" : "Refresh.pdf", 10 | "appearances" : [ 11 | { 12 | "appearance" : "luminosity", 13 | "value" : "light" 14 | } 15 | ] 16 | }, 17 | { 18 | "idiom" : "mac", 19 | "filename" : "RefreshDark.pdf", 20 | "appearances" : [ 21 | { 22 | "appearance" : "luminosity", 23 | "value" : "dark" 24 | } 25 | ] 26 | } 27 | ], 28 | "info" : { 29 | "version" : 1, 30 | "author" : "xcode" 31 | }, 32 | "properties" : { 33 | "template-rendering-intent" : "template", 34 | "preserves-vector-representation" : true 35 | } 36 | } -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/Refresh.imageset/Refresh.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/Refresh.imageset/Refresh.pdf -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/Refresh.imageset/RefreshDark.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/Refresh.imageset/RefreshDark.pdf -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/ReiKeyIcon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "Icon.pdf" 6 | }, 7 | { 8 | "idiom" : "mac", 9 | "filename" : "Icon.pdf", 10 | "appearances" : [ 11 | { 12 | "appearance" : "luminosity", 13 | "value" : "light" 14 | } 15 | ] 16 | }, 17 | { 18 | "idiom" : "mac", 19 | "filename" : "IconDark.pdf", 20 | "appearances" : [ 21 | { 22 | "appearance" : "luminosity", 23 | "value" : "dark" 24 | } 25 | ] 26 | } 27 | ], 28 | "info" : { 29 | "version" : 1, 30 | "author" : "xcode" 31 | }, 32 | "properties" : { 33 | "preserves-vector-representation" : true 34 | } 35 | } -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/ReiKeyIcon.imageset/Icon.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/ReiKeyIcon.imageset/Icon.pdf -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/ReiKeyIcon.imageset/IconDark.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/ReiKeyIcon.imageset/IconDark.pdf -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/ReiKeyText.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "rkText.pdf" 6 | }, 7 | { 8 | "idiom" : "mac", 9 | "filename" : "rkText.pdf", 10 | "appearances" : [ 11 | { 12 | "appearance" : "luminosity", 13 | "value" : "light" 14 | } 15 | ] 16 | }, 17 | { 18 | "idiom" : "mac", 19 | "filename" : "rkText.pdf", 20 | "appearances" : [ 21 | { 22 | "appearance" : "luminosity", 23 | "value" : "dark" 24 | } 25 | ] 26 | } 27 | ], 28 | "info" : { 29 | "version" : 1, 30 | "author" : "xcode" 31 | }, 32 | "properties" : { 33 | "preserves-vector-representation" : true 34 | } 35 | } -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/ReiKeyText.imageset/rkText.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/ReiKeyText.imageset/rkText.pdf -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/Update.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "update.pdf" 6 | }, 7 | { 8 | "idiom" : "mac", 9 | "filename" : "updateLight.pdf", 10 | "appearances" : [ 11 | { 12 | "appearance" : "luminosity", 13 | "value" : "light" 14 | } 15 | ] 16 | }, 17 | { 18 | "idiom" : "mac", 19 | "filename" : "updateDark.pdf", 20 | "appearances" : [ 21 | { 22 | "appearance" : "luminosity", 23 | "value" : "dark" 24 | } 25 | ] 26 | } 27 | ], 28 | "info" : { 29 | "version" : 1, 30 | "author" : "xcode" 31 | }, 32 | "properties" : { 33 | "preserves-vector-representation" : true 34 | } 35 | } -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/Update.imageset/update.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/Update.imageset/update.pdf -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/Update.imageset/updateDark.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/Update.imageset/updateDark.pdf -------------------------------------------------------------------------------- /installer/installer/Assets.xcassets/Update.imageset/updateLight.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/installer/installer/Assets.xcassets/Update.imageset/updateLight.pdf -------------------------------------------------------------------------------- /installer/installer/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /installer/installer/Configure.h: -------------------------------------------------------------------------------- 1 | // 2 | // Configure.h 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/31/18. 6 | // Copyright (c) 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #ifndef Configure_h 10 | #define Configure_h 11 | 12 | #import 13 | 14 | @interface Configure : NSObject 15 | { 16 | 17 | } 18 | 19 | /* METHODS */ 20 | 21 | //invokes appropriate install || uninstall logic 22 | -(BOOL)configure:(NSUInteger)parameter; 23 | 24 | //install 25 | -(BOOL)install; 26 | 27 | //uninstall 28 | -(BOOL)uninstall:(NSUInteger)type; 29 | 30 | @end 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /installer/installer/ConfigureWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ConfigureWindowController.h 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/31/18 6 | // Copyright (c) 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ConfigureWindowController : NSWindowController 12 | { 13 | 14 | } 15 | 16 | /* PROPERTIES */ 17 | @property (weak) IBOutlet NSView *installView; 18 | @property (weak) IBOutlet NSProgressIndicator *activityIndicator; 19 | @property (weak) IBOutlet NSTextField *statusMsg; 20 | @property (weak) IBOutlet NSButton *installButton; 21 | @property (weak) IBOutlet NSButton *uninstallButton; 22 | @property (weak) IBOutlet NSButton *moreInfoButton; 23 | @property (weak) IBOutlet NSButton *supportButton; 24 | @property (strong) IBOutlet NSView *supportView; 25 | 26 | //upgrade flag 27 | @property BOOL isUpgrade; 28 | 29 | /* METHODS */ 30 | 31 | //install/uninstall button handler 32 | -(IBAction)buttonHandler:(id)sender; 33 | 34 | //(more) info button handler 35 | -(IBAction)info:(id)sender; 36 | 37 | //configure window/buttons 38 | -(void)configure; 39 | 40 | //display (show) window 41 | -(void)display; 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /installer/installer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(PRODUCT_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(CURRENT_PROJECT_VERSION) 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright (c) 2019 Objective-See. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /installer/installer/ReiKey Installer.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | com.objective-see.reikey.group 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /installer/installer/main.h: -------------------------------------------------------------------------------- 1 | // 2 | // main.h 3 | // Installer 4 | // 5 | // Created by Patrick Wardle on 9/14/16. 6 | // Copyright © 2016 Objective-See. All rights reserved. 7 | // 8 | 9 | #ifndef main_h 10 | #define main_h 11 | 12 | #import "Consts.h" 13 | #import "Logging.h" 14 | #import "Configure.h" 15 | 16 | #import 17 | 18 | /* FUNCTION DECLARATIONS */ 19 | 20 | //spawn self as root 21 | BOOL spawnAsRoot(const char* path2Self); 22 | 23 | //install 24 | BOOL cmdlineInstall(void); 25 | 26 | //uninstall 27 | BOOL cmdlineUninstall(void); 28 | 29 | #endif /* main_h */ 30 | -------------------------------------------------------------------------------- /installer/installer/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/31/18 6 | // Copyright (c) 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #import "main.h" 10 | #import "consts.h" 11 | #import "logging.h" 12 | #import "utilities.h" 13 | #import "Configure.h" 14 | #import 15 | 16 | //main interface 17 | int main(int argc, const char * argv[]) 18 | { 19 | //status 20 | int status = -1; 21 | 22 | //init crash reporting 23 | initCrashReporting(); 24 | 25 | //cmdline install? 26 | if(YES == [[[NSProcessInfo processInfo] arguments] containsObject:CMD_INSTALL]) 27 | { 28 | //dbg msg 29 | logMsg(LOG_DEBUG, @"performing commandline install"); 30 | 31 | //install 32 | if(YES != [[[Configure alloc] init] configure:ACTION_INSTALL]) 33 | { 34 | //err msg 35 | printf("\nREIKEY ERROR: install failed\n\n"); 36 | 37 | //bail 38 | goto bail; 39 | } 40 | 41 | //dbg msg 42 | printf("REIKEY: install ok\n\n"); 43 | 44 | //happy 45 | status = 0; 46 | 47 | //done 48 | goto bail; 49 | } 50 | 51 | //cmdline uninstall? 52 | else if(YES == [[[NSProcessInfo processInfo] arguments] containsObject:CMD_UNINSTALL]) 53 | { 54 | //dbg msg 55 | logMsg(LOG_DEBUG, @"performing commandline uninstall"); 56 | 57 | //install 58 | if(YES != [[[Configure alloc] init] configure:ACTION_UNINSTALL]) 59 | { 60 | //err msg 61 | printf("\nREIKEY ERROR: uninstall failed\n\n"); 62 | 63 | //bail 64 | goto bail; 65 | } 66 | 67 | //dbg msg 68 | printf("REIKEY: uninstall ok!\n\n"); 69 | 70 | //happy 71 | status = 0; 72 | 73 | //done 74 | goto bail; 75 | } 76 | 77 | //default run mode 78 | // just kick off main app logic 79 | status = NSApplicationMain(argc, (const char **) argv); 80 | 81 | bail: 82 | 83 | return status; 84 | } 85 | -------------------------------------------------------------------------------- /loginItem/loginItem.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /loginItem/loginItem.xcodeproj/xcshareddata/xcschemes/loginItem.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /loginItem/loginItem/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | @import Cocoa; 10 | 11 | #import "StatusBarItem.h" 12 | #import "UpdateWindowController.h" 13 | 14 | @interface AppDelegate : NSObject 15 | 16 | /* METHODS */ 17 | 18 | 19 | /* PROPERTIES */ 20 | 21 | //status bar menu 22 | @property(strong) IBOutlet NSMenu* statusMenu; 23 | 24 | //status bar menu controller 25 | @property(nonatomic, retain)StatusBarItem* statusBarController; 26 | 27 | //touch bar 28 | @property(nonatomic, retain)NSTouchBar* touchBar; 29 | 30 | //update window controller 31 | @property(nonatomic, retain)UpdateWindowController* updateWindowController; 32 | 33 | //(current) alert 34 | @property(nonatomic, retain)NSDictionary* currentAlert; 35 | 36 | //alerts 37 | @property(nonatomic, retain)NSMutableDictionary* alerts; 38 | 39 | /* METHODS */ 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /loginItem/loginItem/AppReceipt.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppReceipt.h 3 | // RansomWhere? 4 | // 5 | // Created by Patrick Wardle on 5/1/16. 6 | // 7 | // note: code inspired by [1] https://gist.github.com/sazameki/3026845 8 | 9 | #ifndef AppReceipt_h 10 | #define AppReceipt_h 11 | 12 | #import 13 | #import 14 | #import 15 | #import 16 | #import 17 | 18 | 19 | //from 'Receipt Fields' section (Apple's 'Receipt Validation Programming Guide') 20 | 21 | //ANS.1 data struct 22 | typedef struct 23 | { 24 | size_t length; 25 | unsigned char *data; 26 | } ASN1_Data; 27 | 28 | //receipt attribute struct 29 | typedef struct 30 | { 31 | ASN1_Data type; // INTEGER 32 | ASN1_Data version; // INTEGER 33 | ASN1_Data value; // OCTET STRING 34 | 35 | } ReceiptAttribute; 36 | 37 | //receipt payload struct 38 | typedef struct 39 | { 40 | ReceiptAttribute **attrs; 41 | 42 | } ReceiptPayload; 43 | 44 | //ASN.1 receipt attribute template (from [1]) 45 | static const SecAsn1Template kReceiptAttributeTemplate[] = 46 | { 47 | { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(ReceiptAttribute) }, 48 | { SEC_ASN1_INTEGER, offsetof(ReceiptAttribute, type), NULL, 0 }, 49 | { SEC_ASN1_INTEGER, offsetof(ReceiptAttribute, version), NULL, 0 }, 50 | { SEC_ASN1_OCTET_STRING, offsetof(ReceiptAttribute, value), NULL, 0 }, 51 | { 0, 0, NULL, 0 } 52 | }; 53 | 54 | //ASN.1 receipt template set (from [1]) 55 | static const SecAsn1Template kSetOfReceiptAttributeTemplate[] = 56 | { 57 | { SEC_ASN1_SET_OF, 0, kReceiptAttributeTemplate, sizeof(ReceiptPayload) }, 58 | { 0, 0, NULL, 0 } 59 | }; 60 | 61 | //attribute type for bundle ID 62 | #define RECEIPT_ATTR_BUNDLE_ID 2 63 | 64 | //attribute type for app version 65 | #define RECEIPT_ATTR_APP_VERSION 3 66 | 67 | //attribute type for opaque value 68 | #define RECEIPT_ATTR_OPAQUE_VALUE 4 69 | 70 | //attribute type for receipt's hash 71 | #define RECEIPT_ATTR_RECEIPT_HASH 5 72 | 73 | //key for bundle id 74 | #define KEY_BUNDLE_ID @"bundleID" 75 | 76 | //key for bundle id data 77 | #define KEY_BUNDLE_DATA @"bundleIDData" 78 | 79 | //key for app version 80 | #define KEY_APP_VERSION @"applicationVersion" 81 | 82 | //key for opaque value 83 | #define KEY_OPAQUE_VALUE @"opaqueValue" 84 | 85 | //key for receipt's sha-1 hash 86 | #define KEY_RECEIPT_HASH @"receiptHash" 87 | 88 | //class interface 89 | @interface AppReceipt : NSObject 90 | { 91 | 92 | } 93 | 94 | /* METHODS */ 95 | 96 | //init with app path 97 | // ->locate/load receipt, etc 98 | -(instancetype)init:(NSBundle *)bundle; 99 | 100 | /* PROPERTIES */ 101 | 102 | //encoded receipt data 103 | @property (nonatomic, retain) NSData* encodedData; 104 | 105 | //decoded receipt data 106 | @property (nonatomic, retain) NSData* decodedData; 107 | 108 | //receipt components 109 | @property(nonatomic, retain)NSMutableDictionary* components; 110 | 111 | //bundle id (from receipt) 112 | @property (nonatomic, strong, readonly) NSString *bundleIdentifier; 113 | 114 | //bundle id data (from receipt) 115 | @property (nonatomic, strong, readonly) NSData *bundleIdentifierData; 116 | 117 | //app version (from receipt) 118 | @property (nonatomic, strong, readonly) NSString *appVersion; 119 | 120 | //opaque value (from receipt) 121 | @property (nonatomic, strong, readonly) NSData *opaqueValue; 122 | 123 | //receipts hash (from receipt) 124 | @property (nonatomic, strong, readonly) NSData *receiptHash; 125 | 126 | @end 127 | 128 | #endif /* AppReceipt_h */ 129 | -------------------------------------------------------------------------------- /loginItem/loginItem/AppReceipt.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppReceipt.m 3 | // RansomWhere? 4 | // 5 | // Created by Patrick Wardle on 5/1/16. 6 | // 7 | 8 | #import "AppReceipt.h" 9 | 10 | //helper function from [1] 11 | // ->extract an int from ASN.1 data 12 | inline static int getIntValueFromASN1Data(const ASN1_Data *asn1Data) 13 | { 14 | int ret = 0; 15 | for (int i = 0; i < asn1Data->length; i++) 16 | { 17 | ret = (ret << 8) | asn1Data->data[i]; 18 | } 19 | return ret; 20 | } 21 | 22 | //helper function from [1] 23 | // ->decode string from ASN.1 data 24 | inline static NSString *decodeUTF8StringFromASN1Data(SecAsn1CoderRef decoder, ASN1_Data srcData) 25 | { 26 | //data struct 27 | ASN1_Data asn1Data = {0}; 28 | 29 | //decoded string 30 | NSString* decodedString = nil; 31 | 32 | //status 33 | OSStatus status = -1; 34 | 35 | //decode 36 | status = SecAsn1Decode(decoder, srcData.data, srcData.length, kSecAsn1UTF8StringTemplate, &asn1Data); 37 | if(noErr != status) 38 | { 39 | //bail 40 | goto bail; 41 | } 42 | 43 | //convert to string 44 | decodedString = [[NSString alloc] initWithBytes:asn1Data.data length:asn1Data.length encoding:NSUTF8StringEncoding]; 45 | 46 | //bail 47 | bail: 48 | 49 | return decodedString; 50 | } 51 | 52 | //class implementation 53 | @implementation AppReceipt 54 | 55 | //synthesize thingz 56 | @synthesize components; 57 | @synthesize encodedData; 58 | @synthesize decodedData; 59 | 60 | //init with app path 61 | // ->locate/load/decode receipt, etc 62 | -(instancetype)init:(NSBundle *)bundle 63 | { 64 | //init 65 | if(self = [super init]) 66 | { 67 | //first check for receipt 68 | if( (nil == bundle.appStoreReceiptURL) || 69 | (YES != [[NSFileManager defaultManager] fileExistsAtPath:bundle.appStoreReceiptURL.path]) ) 70 | { 71 | //bail 72 | return nil; 73 | } 74 | 75 | //load encoded receipt data 76 | self.encodedData = [NSData dataWithContentsOfURL:bundle.appStoreReceiptURL]; 77 | if(nil == self.encodedData) 78 | { 79 | //bail 80 | return nil; 81 | } 82 | 83 | //decode receipt data 84 | self.decodedData = [self decode]; 85 | if(nil == self.decodedData) 86 | { 87 | //bail 88 | return nil; 89 | } 90 | 91 | //parse out values 92 | // ->bundle id, app version, etc 93 | self.components = [self parse]; 94 | if( (nil == self.components) || 95 | (0 == self.components.count) ) 96 | { 97 | //bail 98 | return nil; 99 | } 100 | } 101 | 102 | return self; 103 | } 104 | 105 | //decode receipt data 106 | // ->some validations performed here too 107 | -(NSData*)decode 108 | { 109 | //decoded data 110 | NSData* decoded = nil; 111 | 112 | //decoder 113 | CMSDecoderRef decoder = NULL; 114 | 115 | //policy 116 | SecPolicyRef policy = NULL; 117 | 118 | //trust 119 | SecTrustRef trust = NULL; 120 | 121 | //status 122 | OSStatus status = -1; 123 | 124 | //data 125 | CFDataRef data = NULL; 126 | 127 | //number of signers 128 | size_t signers = 0; 129 | 130 | //signer status 131 | CMSSignerStatus signerStatus = -1; 132 | 133 | //cert verify 134 | OSStatus certVerifyResult = 1; 135 | 136 | //create decoder 137 | status = CMSDecoderCreate(&decoder); 138 | if(noErr != status) 139 | { 140 | //bail 141 | goto bail; 142 | } 143 | 144 | //add encoded data to message 145 | status = CMSDecoderUpdateMessage(decoder, self.encodedData.bytes, self.encodedData.length); 146 | if(noErr != status) 147 | { 148 | //bail 149 | goto bail; 150 | } 151 | 152 | //decode 153 | status = CMSDecoderFinalizeMessage(decoder); 154 | if(noErr != status) 155 | { 156 | //bail 157 | goto bail; 158 | } 159 | 160 | //create policy 161 | policy = SecPolicyCreateBasicX509(); 162 | if(NULL == policy) 163 | { 164 | //bail 165 | goto bail; 166 | } 167 | 168 | //CHECK 1: 169 | // ->make sure there is a signer 170 | status = CMSDecoderGetNumSigners(decoder, &signers); 171 | if( (noErr != status) || 172 | (0 == signers) ) 173 | { 174 | //bail 175 | goto bail; 176 | } 177 | 178 | //CHECK 2: 179 | // ->make sure signer status is ok 180 | status = CMSDecoderCopySignerStatus(decoder, 0, policy, TRUE, &signerStatus, &trust, &certVerifyResult); 181 | if( (noErr != status) || 182 | (kCMSSignerValid != signerStatus) ) 183 | { 184 | //bail 185 | goto bail; 186 | } 187 | 188 | //grab decoded content 189 | status = CMSDecoderCopyContent(decoder, &data); 190 | if(noErr != status) 191 | { 192 | //bail 193 | goto bail; 194 | } 195 | 196 | //convert to NSData 197 | decoded = [NSData dataWithData:(__bridge NSData *)data]; 198 | 199 | //bail 200 | bail: 201 | 202 | //release policy 203 | if(NULL != policy) 204 | { 205 | //release 206 | CFRelease(policy); 207 | } 208 | 209 | //release trust 210 | if(NULL != trust) 211 | { 212 | //release 213 | CFRelease(trust); 214 | } 215 | 216 | //release decoder 217 | if(NULL != decoder) 218 | { 219 | //release 220 | CFRelease(decoder); 221 | } 222 | 223 | //release data 224 | if(NULL != data) 225 | { 226 | //release 227 | CFRelease(data); 228 | } 229 | 230 | return decoded; 231 | } 232 | 233 | //parse decoded receipt 234 | // ->extract out items such as bundle id, app version, etc. 235 | -(NSMutableDictionary*)parse 236 | { 237 | //decoder 238 | SecAsn1CoderRef decoder = NULL; 239 | 240 | //status 241 | OSStatus status = -1; 242 | 243 | //payload struct 244 | ReceiptPayload payload = {0}; 245 | 246 | //attribute 247 | ReceiptAttribute *attribute; 248 | 249 | //dictionary for items 250 | NSMutableDictionary* items = nil; 251 | 252 | //create decoder 253 | status = SecAsn1CoderCreate(&decoder); 254 | if(noErr != status) 255 | { 256 | //bail 257 | goto bail; 258 | } 259 | 260 | //decode 261 | status = SecAsn1Decode(decoder, self.decodedData.bytes, self.decodedData.length, kSetOfReceiptAttributeTemplate, &payload); 262 | if(noErr != status) 263 | { 264 | //bail 265 | goto bail; 266 | } 267 | 268 | //init dictionary for items 269 | items = [NSMutableDictionary dictionary]; 270 | 271 | //extact attributes 272 | // ->save those of interest 273 | for(int i = 0; (attribute = payload.attrs[i]); i++) 274 | { 275 | //process each type 276 | switch(getIntValueFromASN1Data(&attribute->type)) 277 | { 278 | //bundle id 279 | // ->save bundle id and data 280 | case RECEIPT_ATTR_BUNDLE_ID: 281 | { 282 | //save bundle id 283 | items[KEY_BUNDLE_ID] = decodeUTF8StringFromASN1Data(decoder, attribute->value); 284 | 285 | //save bundle id data 286 | items[KEY_BUNDLE_DATA] = [NSData dataWithBytes:attribute->value.data length:attribute->value.length]; 287 | 288 | break; 289 | } 290 | 291 | //app version 292 | case RECEIPT_ATTR_APP_VERSION: 293 | { 294 | //save 295 | items[KEY_APP_VERSION] = decodeUTF8StringFromASN1Data(decoder, attribute->value); 296 | 297 | break; 298 | 299 | } 300 | 301 | //opaque value 302 | case RECEIPT_ATTR_OPAQUE_VALUE: 303 | { 304 | //save 305 | items[KEY_OPAQUE_VALUE] = [NSData dataWithBytes:attribute->value.data length:attribute->value.length]; 306 | 307 | break; 308 | } 309 | 310 | //receipt hash 311 | case RECEIPT_ATTR_RECEIPT_HASH: 312 | { 313 | //save 314 | items[KEY_RECEIPT_HASH] = [NSData dataWithBytes:attribute->value.data length:attribute->value.length]; 315 | 316 | break; 317 | } 318 | 319 | //default 320 | // ->ignore 321 | default: 322 | { 323 | break; 324 | } 325 | 326 | }//switch 327 | 328 | }//for all attributes 329 | 330 | //bail 331 | bail: 332 | 333 | //release decoder 334 | if(NULL != decoder) 335 | { 336 | //release 337 | SecAsn1CoderRelease(decoder); 338 | } 339 | 340 | return items; 341 | } 342 | 343 | //return bundle id 344 | -(NSString*)bundleIdentifier 345 | { 346 | return self.components[KEY_BUNDLE_ID]; 347 | } 348 | 349 | //return bundle id data 350 | -(NSData*)bundleIdentifierData 351 | { 352 | return self.components[KEY_BUNDLE_DATA]; 353 | } 354 | 355 | //return app version 356 | -(NSString*)appVersion 357 | { 358 | return self.components[KEY_APP_VERSION]; 359 | } 360 | 361 | //return opaque data 362 | -(NSData*)opaqueValue 363 | { 364 | return self.components[KEY_OPAQUE_VALUE]; 365 | } 366 | 367 | //return receipt hash 368 | -(NSData*)receiptHash 369 | { 370 | return self.components[KEY_RECEIPT_HASH]; 371 | } 372 | 373 | @end -------------------------------------------------------------------------------- /loginItem/loginItem/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "icon_16x16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "icon_16x16@2x.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "icon_32x32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "icon_32x32@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "icon_128x128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "icon_128x128@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "icon_256x256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "icon_256x256@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "icon_512x512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "idiom" : "mac", 59 | "size" : "512x512", 60 | "scale" : "2x" 61 | } 62 | ], 63 | "info" : { 64 | "version" : 1, 65 | "author" : "xcode" 66 | } 67 | } -------------------------------------------------------------------------------- /loginItem/loginItem/Assets.xcassets/AppIcon.appiconset/icon_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/loginItem/loginItem/Assets.xcassets/AppIcon.appiconset/icon_128x128.png -------------------------------------------------------------------------------- /loginItem/loginItem/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/loginItem/loginItem/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png -------------------------------------------------------------------------------- /loginItem/loginItem/Assets.xcassets/AppIcon.appiconset/icon_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/loginItem/loginItem/Assets.xcassets/AppIcon.appiconset/icon_16x16.png -------------------------------------------------------------------------------- /loginItem/loginItem/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/loginItem/loginItem/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png -------------------------------------------------------------------------------- /loginItem/loginItem/Assets.xcassets/AppIcon.appiconset/icon_256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/loginItem/loginItem/Assets.xcassets/AppIcon.appiconset/icon_256x256.png -------------------------------------------------------------------------------- /loginItem/loginItem/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/loginItem/loginItem/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png -------------------------------------------------------------------------------- /loginItem/loginItem/Assets.xcassets/AppIcon.appiconset/icon_32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/loginItem/loginItem/Assets.xcassets/AppIcon.appiconset/icon_32x32.png -------------------------------------------------------------------------------- /loginItem/loginItem/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/loginItem/loginItem/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png -------------------------------------------------------------------------------- /loginItem/loginItem/Assets.xcassets/AppIcon.appiconset/icon_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/loginItem/loginItem/Assets.xcassets/AppIcon.appiconset/icon_512x512.png -------------------------------------------------------------------------------- /loginItem/loginItem/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /loginItem/loginItem/Assets.xcassets/ReiKeyIcon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "rkIcon.pdf" 6 | }, 7 | { 8 | "idiom" : "mac", 9 | "filename" : "rkIcon.pdf", 10 | "appearances" : [ 11 | { 12 | "appearance" : "luminosity", 13 | "value" : "light" 14 | } 15 | ] 16 | }, 17 | { 18 | "idiom" : "mac", 19 | "filename" : "rkIconDark.pdf", 20 | "appearances" : [ 21 | { 22 | "appearance" : "luminosity", 23 | "value" : "dark" 24 | } 25 | ] 26 | } 27 | ], 28 | "info" : { 29 | "version" : 1, 30 | "author" : "xcode" 31 | }, 32 | "properties" : { 33 | "preserves-vector-representation" : true 34 | } 35 | } -------------------------------------------------------------------------------- /loginItem/loginItem/Assets.xcassets/ReiKeyIcon.imageset/rkIcon.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/loginItem/loginItem/Assets.xcassets/ReiKeyIcon.imageset/rkIcon.pdf -------------------------------------------------------------------------------- /loginItem/loginItem/Assets.xcassets/ReiKeyIcon.imageset/rkIconDark.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/loginItem/loginItem/Assets.xcassets/ReiKeyIcon.imageset/rkIconDark.pdf -------------------------------------------------------------------------------- /loginItem/loginItem/Assets.xcassets/ReiKeyText.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "rkText.pdf" 6 | }, 7 | { 8 | "idiom" : "mac", 9 | "filename" : "rkText.pdf", 10 | "appearances" : [ 11 | { 12 | "appearance" : "luminosity", 13 | "value" : "light" 14 | } 15 | ] 16 | }, 17 | { 18 | "idiom" : "mac", 19 | "filename" : "rkText.pdf", 20 | "appearances" : [ 21 | { 22 | "appearance" : "luminosity", 23 | "value" : "dark" 24 | } 25 | ] 26 | } 27 | ], 28 | "info" : { 29 | "version" : 1, 30 | "author" : "xcode" 31 | }, 32 | "properties" : { 33 | "preserves-vector-representation" : true 34 | } 35 | } -------------------------------------------------------------------------------- /loginItem/loginItem/Assets.xcassets/ReiKeyText.imageset/rkText.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/loginItem/loginItem/Assets.xcassets/ReiKeyText.imageset/rkText.pdf -------------------------------------------------------------------------------- /loginItem/loginItem/Assets.xcassets/StatusActive.imageset/Active.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/loginItem/loginItem/Assets.xcassets/StatusActive.imageset/Active.pdf -------------------------------------------------------------------------------- /loginItem/loginItem/Assets.xcassets/StatusActive.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "Active.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template", 14 | "preserves-vector-representation" : true 15 | } 16 | } -------------------------------------------------------------------------------- /loginItem/loginItem/Assets.xcassets/StatusInactive.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "Inactive.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template", 14 | "preserves-vector-representation" : true 15 | } 16 | } -------------------------------------------------------------------------------- /loginItem/loginItem/Assets.xcassets/StatusInactive.imageset/Inactive.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/loginItem/loginItem/Assets.xcassets/StatusInactive.imageset/Inactive.pdf -------------------------------------------------------------------------------- /loginItem/loginItem/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /loginItem/loginItem/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(CURRENT_PROJECT_VERSION) 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | LSUIElement 28 | 29 | NSHumanReadableCopyright 30 | Copyright (c) 2019 Objective-See. All rights reserved. 31 | NSMainNibFile 32 | MainMenu 33 | NSPrincipalClass 34 | NSApplication 35 | NSUserNotificationAlertStyle 36 | alert 37 | 38 | 39 | -------------------------------------------------------------------------------- /loginItem/loginItem/ReiKey Helper.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.application-groups 8 | 9 | com.objective-see.reikey.group 10 | 11 | com.apple.security.network.client 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /loginItem/loginItem/StatusBarItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // StatusBarMenu.h 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | @import Cocoa; 10 | 11 | @interface StatusBarItem : NSObject 12 | { 13 | 14 | } 15 | 16 | //status item 17 | @property(nonatomic, retain)NSStatusItem* statusItem; 18 | 19 | //popover 20 | @property(retain, nonatomic)NSPopover *popover; 21 | 22 | //disabled flag 23 | @property BOOL isDisabled; 24 | 25 | /* METHODS */ 26 | 27 | //init 28 | -(id)init:(NSMenu*)menu; 29 | 30 | //remove status item 31 | -(void)removeStatusItem; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /loginItem/loginItem/StatusBarItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // StatusBarMenu.m 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #import "consts.h" 10 | #import "logging.h" 11 | #import "utilities.h" 12 | #import "AppDelegate.h" 13 | #import "StatusBarItem.h" 14 | #import "StatusBarPopoverController.h" 15 | 16 | //menu items 17 | enum menuItems 18 | { 19 | status = 100, 20 | toggle, 21 | scan, 22 | preferences, 23 | quit, 24 | end 25 | }; 26 | 27 | @implementation StatusBarItem 28 | 29 | @synthesize isDisabled; 30 | @synthesize statusItem; 31 | 32 | //init method 33 | // set some intial flags, init daemon comms, etc. 34 | -(id)init:(NSMenu*)menu 35 | { 36 | //shared defaults 37 | NSUserDefaults* sharedDefaults = nil; 38 | 39 | //super 40 | self = [super init]; 41 | if(self != nil) 42 | { 43 | //load shared defaults 44 | sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:SUITE_NAME]; 45 | 46 | //create status item 47 | [self createStatusItem:menu]; 48 | 49 | //first time? 50 | // show popover 51 | if(YES != [sharedDefaults boolForKey:SHOWED_POPUP]) 52 | { 53 | //show 54 | [self showPopover]; 55 | 56 | //set 'showed popover' key 57 | [sharedDefaults setBool:YES forKey:SHOWED_POPUP]; 58 | } 59 | 60 | //set state based on (existing) preferences 61 | self.isDisabled = [sharedDefaults boolForKey:PREF_IS_DISABLED]; 62 | 63 | //set initial menu state 64 | [self setState]; 65 | } 66 | 67 | return self; 68 | } 69 | 70 | //create status item 71 | -(void)createStatusItem:(NSMenu*)menu 72 | { 73 | //init status item 74 | statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength]; 75 | 76 | //set menu 77 | self.statusItem.menu = menu; 78 | 79 | //set action handler for all menu items 80 | for(int i=toggle; i 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /loginItem/loginItem/StatusBarPopoverController.h: -------------------------------------------------------------------------------- 1 | // 2 | // StatusBarPopoverController.h 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | @import Cocoa; 10 | 11 | @interface StatusBarPopoverController : NSViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /loginItem/loginItem/StatusBarPopoverController.m: -------------------------------------------------------------------------------- 1 | // 2 | // StatusBarPopoverController.m 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "StatusBarPopoverController.h" 11 | 12 | @implementation StatusBarPopoverController 13 | 14 | //'close' button handler 15 | // simply dismiss/close popover 16 | -(IBAction)closePopover:(NSControl *)sender 17 | { 18 | //close 19 | [[[self view] window] close]; 20 | 21 | return; 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /loginItem/loginItem/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | @import Cocoa; 10 | 11 | #import "consts.h" 12 | #import "logging.h" 13 | #import "utilities.h" 14 | 15 | //main interface 16 | // init crash reporting, check if running, launch 17 | int main(int argc, const char * argv[]) 18 | { 19 | //return var 20 | int iReturn = -1; 21 | 22 | //init crash reporting 23 | initCrashReporting(); 24 | 25 | //dbg msg 26 | logMsg(LOG_DEBUG, [NSString stringWithFormat:@"starting login item (args: %@)", [[NSProcessInfo processInfo] arguments]]); 27 | 28 | //launch app normally 29 | iReturn = NSApplicationMain(argc, argv); 30 | 31 | bail: 32 | 33 | return iReturn; 34 | } 35 | -------------------------------------------------------------------------------- /mainApp/mainApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /mainApp/mainApp.xcodeproj/xcshareddata/xcschemes/mainApp.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 51 | 52 | 53 | 54 | 55 | 56 | 66 | 68 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /mainApp/mainApp/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | @import Cocoa; 10 | 11 | #import "ScanWindowController.h" 12 | #import "AboutWindowController.h" 13 | #import "PrefsWindowController.h" 14 | #import "WelcomeWindowController.h" 15 | 16 | @interface AppDelegate : NSObject 17 | 18 | /* PROPERTIES */ 19 | 20 | //main window 21 | @property(weak)IBOutlet NSWindow* window; 22 | 23 | //welcome view controller 24 | @property(nonatomic, retain)WelcomeWindowController* welcomeWindowController; 25 | 26 | //about window controller 27 | @property(nonatomic, retain)AboutWindowController* aboutWindowController; 28 | 29 | //scan window controller 30 | @property(nonatomic, retain)ScanWindowController* scanWindowController; 31 | 32 | //preferences window controller 33 | @property(nonatomic, retain)PrefsWindowController* prefsWindowController; 34 | 35 | //flag for launch method 36 | @property BOOL urlLaunch; 37 | 38 | /* METHODS */ 39 | 40 | @end 41 | 42 | -------------------------------------------------------------------------------- /mainApp/mainApp/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #import "consts.h" 10 | #import "Update.h" 11 | #import "logging.h" 12 | #import "utilities.h" 13 | #import "AppDelegate.h" 14 | 15 | @implementation AppDelegate 16 | 17 | @synthesize scanWindowController; 18 | @synthesize aboutWindowController; 19 | @synthesize prefsWindowController; 20 | @synthesize welcomeWindowController; 21 | 22 | //center window 23 | // and make front 24 | -(void)awakeFromNib 25 | { 26 | //center 27 | [self.window center]; 28 | 29 | //make it key window 30 | [self.window makeKeyAndOrderFront:self]; 31 | 32 | //make window front 33 | [NSApp activateIgnoringOtherApps:YES]; 34 | 35 | return; 36 | } 37 | 38 | //main app interface 39 | // init user interface, etc... 40 | -(void)applicationDidFinishLaunching:(NSNotification *)aNotification 41 | { 42 | //dbg msg 43 | logMsg(LOG_DEBUG, @"main (rules/pref) app launched"); 44 | 45 | //toggle away 46 | [[[NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.loginwindow"] firstObject] activateWithOptions:NSApplicationActivateIgnoringOtherApps]; 47 | 48 | //toggle back 49 | // work-around for menu not showing since we set Application is agent(UIElement): YES 50 | [[[NSRunningApplication runningApplicationsWithBundleIdentifier:APP_BUNDLE_ID] firstObject] activateWithOptions:NSApplicationActivateIgnoringOtherApps]; 51 | 52 | //when launched via URL handler 53 | // no need to do anything here... 54 | if(YES == self.urlLaunch) 55 | { 56 | //all set 57 | goto bail; 58 | } 59 | 60 | //first time run? 61 | // show welcome window(s) 62 | if(YES != [[[NSUserDefaults alloc] initWithSuiteName:SUITE_NAME] boolForKey:SHOWED_SPLASH]) 63 | { 64 | //show welcome 65 | [self showWelcome]; 66 | } 67 | 68 | //subsequent run(s) 69 | // default to showing scan window 70 | else 71 | { 72 | //show scan window 73 | [self showScan:nil]; 74 | 75 | //if needed 76 | // start login item 77 | if(nil == [[NSRunningApplication runningApplicationsWithBundleIdentifier:LOGIN_ITEM_BUNDLE_ID] firstObject]) 78 | { 79 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), 80 | ^{ 81 | //start 82 | startApplication([NSURL fileURLWithPath:loginItemPath()], NSWorkspaceLaunchWithoutActivation); 83 | }); 84 | } 85 | } 86 | 87 | bail: 88 | 89 | return; 90 | } 91 | 92 | //(custom) url handler 93 | // invoked automatically when user clicks on menu item in login item 94 | -(void)application:(NSApplication *)application openURLs:(NSArray *)urls 95 | { 96 | //url components 97 | NSURLComponents *components = nil; 98 | 99 | //tap ID 100 | NSNumber* tapID = nil; 101 | 102 | //dbg msg 103 | logMsg(LOG_DEBUG, [NSString stringWithFormat:@"main (rules/pref) app launched to handle url(s): %@", urls]); 104 | 105 | //set flag 106 | self.urlLaunch = YES; 107 | 108 | //parse each url 109 | // scan or show prefs... 110 | for(NSURL* url in urls) 111 | { 112 | //show scan? 113 | if(YES == [url.host isEqualToString:@"scan"]) 114 | { 115 | //split 116 | components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO]; 117 | 118 | //parse 119 | // find/extract tap id 120 | for(NSURLQueryItem *item in components.queryItems) 121 | { 122 | //tap id? 123 | if(YES == [item.name isEqualToString:TAP_ID]) 124 | { 125 | //extract tap id 126 | tapID = [NSNumber numberWithInteger:item.value.integerValue]; 127 | 128 | //done 129 | break; 130 | } 131 | } 132 | 133 | //show 134 | [self showScan:tapID]; 135 | } 136 | 137 | //show preferences? 138 | else if(YES == [url.host isEqualToString:@"preferences"]) 139 | { 140 | //show 141 | [self showPreferences:nil]; 142 | } 143 | 144 | //close? 145 | else if(YES == [url.host isEqualToString:@"close"]) 146 | { 147 | //bye! 148 | [NSApp terminate:nil]; 149 | } 150 | } 151 | 152 | return; 153 | } 154 | 155 | //automatically close when user closes last window 156 | -(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication 157 | { 158 | return YES; 159 | } 160 | 161 | //show welcome/splash view 162 | -(void)showWelcome 163 | { 164 | //disable all menu items except 'About ...' 165 | for(NSMenuItem* menuItem in NSApplication.sharedApplication.mainMenu.itemArray.firstObject.submenu.itemArray) 166 | { 167 | //not 'About ...' 168 | // disable menu item 169 | if(YES != [menuItem.title containsString:@"About"]) 170 | { 171 | //disable 172 | menuItem.action = nil; 173 | } 174 | } 175 | 176 | //alloc welcome controller 177 | welcomeWindowController = [[WelcomeWindowController alloc] initWithWindowNibName:@"Welcome"]; 178 | 179 | //center welcome window 180 | [self.welcomeWindowController.window center]; 181 | 182 | //make key and front 183 | [self.welcomeWindowController.window makeKeyAndOrderFront:self]; 184 | 185 | //set 'showed splash' key 186 | [[[NSUserDefaults alloc] initWithSuiteName:SUITE_NAME] setBool:YES forKey:SHOWED_SPLASH]; 187 | 188 | return; 189 | } 190 | 191 | //'Scan' menu item handler 192 | // alloc and show scan window 193 | -(IBAction)showScan:(id)sender 194 | { 195 | //alloc rules window controller 196 | if(nil == self.scanWindowController) 197 | { 198 | //alloc 199 | scanWindowController = [[ScanWindowController alloc] initWithWindowNibName:@"Scan"]; 200 | } 201 | 202 | //set tag id 203 | if( (nil != sender) && 204 | (YES == [sender isKindOfClass:[NSNumber class]]) ) 205 | { 206 | //set 207 | self.scanWindowController.tapID = sender; 208 | } 209 | //otherwise 210 | // reset tag id 211 | else 212 | { 213 | self.scanWindowController.tapID = nil; 214 | } 215 | 216 | //center 217 | [self.scanWindowController.window center]; 218 | 219 | //show it 220 | [self.scanWindowController showWindow:self]; 221 | 222 | //make it key window 223 | [[self.scanWindowController window] makeKeyAndOrderFront:self]; 224 | 225 | //trigger scan 226 | [self.scanWindowController reScan:nil]; 227 | 228 | return; 229 | } 230 | 231 | //'preferences' menu item handler 232 | // alloc and show preferences window 233 | -(IBAction)showPreferences:(id)sender 234 | { 235 | //alloc prefs window controller 236 | if(nil == self.prefsWindowController) 237 | { 238 | //alloc 239 | prefsWindowController = [[PrefsWindowController alloc] initWithWindowNibName:@"Preferences"]; 240 | } 241 | 242 | //center 243 | [self.prefsWindowController.window center]; 244 | 245 | //show it 246 | [self.prefsWindowController showWindow:self]; 247 | 248 | //make it key window 249 | [[self.prefsWindowController window] makeKeyAndOrderFront:self]; 250 | 251 | return; 252 | } 253 | 254 | //'about' menu item handler 255 | // ->alloc/show about window 256 | -(IBAction)showAbout:(id)sender 257 | { 258 | //alloc/init settings window 259 | if(nil == self.aboutWindowController) 260 | { 261 | //alloc/init 262 | aboutWindowController = [[AboutWindowController alloc] initWithWindowNibName:@"AboutWindow"]; 263 | } 264 | 265 | //center window 266 | [[self.aboutWindowController window] center]; 267 | 268 | //show it 269 | [self.aboutWindowController showWindow:self]; 270 | 271 | //invoke function in background that will make window modal 272 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 273 | 274 | //make modal 275 | makeModal(self.aboutWindowController); 276 | 277 | }); 278 | 279 | return; 280 | } 281 | 282 | @end 283 | -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "icon_16x16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "icon_16x16@2x.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "icon_32x32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "icon_32x32@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "icon_128x128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "icon_128x128@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "icon_256x256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "icon_256x256@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "icon_512x512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "icon_512x512@2x.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/AppIcon.appiconset/icon_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/AppIcon.appiconset/icon_128x128.png -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/AppIcon.appiconset/icon_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/AppIcon.appiconset/icon_16x16.png -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/AppIcon.appiconset/icon_256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/AppIcon.appiconset/icon_256x256.png -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/AppIcon.appiconset/icon_32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/AppIcon.appiconset/icon_32x32.png -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/AppIcon.appiconset/icon_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/AppIcon.appiconset/icon_512x512.png -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/FriendsDigita.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "digita.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/FriendsDigita.imageset/digita.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/FriendsDigita.imageset/digita.pdf -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/FriendsMacPaw.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "macpaw.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/FriendsMacPaw.imageset/macpaw.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/FriendsMacPaw.imageset/macpaw.pdf -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/FriendsMalwarebytes.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "malwarebytes.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/FriendsMalwarebytes.imageset/malwarebytes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/FriendsMalwarebytes.imageset/malwarebytes.pdf -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/FriendsSophos.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "sophos.png" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/FriendsSophos.imageset/sophos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/FriendsSophos.imageset/sophos.png -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/Refresh.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "Refresh.pdf" 6 | }, 7 | { 8 | "idiom" : "mac", 9 | "filename" : "Refresh.pdf", 10 | "appearances" : [ 11 | { 12 | "appearance" : "luminosity", 13 | "value" : "light" 14 | } 15 | ] 16 | }, 17 | { 18 | "idiom" : "mac", 19 | "filename" : "RefreshDark.pdf", 20 | "appearances" : [ 21 | { 22 | "appearance" : "luminosity", 23 | "value" : "dark" 24 | } 25 | ] 26 | } 27 | ], 28 | "info" : { 29 | "version" : 1, 30 | "author" : "xcode" 31 | }, 32 | "properties" : { 33 | "template-rendering-intent" : "template", 34 | "preserves-vector-representation" : true 35 | } 36 | } -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/Refresh.imageset/Refresh.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/Refresh.imageset/Refresh.pdf -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/Refresh.imageset/RefreshDark.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/Refresh.imageset/RefreshDark.pdf -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/ReiKeyIcon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "Icon.pdf" 6 | }, 7 | { 8 | "idiom" : "mac", 9 | "filename" : "Icon.pdf", 10 | "appearances" : [ 11 | { 12 | "appearance" : "luminosity", 13 | "value" : "light" 14 | } 15 | ] 16 | }, 17 | { 18 | "idiom" : "mac", 19 | "filename" : "IconDark.pdf", 20 | "appearances" : [ 21 | { 22 | "appearance" : "luminosity", 23 | "value" : "dark" 24 | } 25 | ] 26 | } 27 | ], 28 | "info" : { 29 | "version" : 1, 30 | "author" : "xcode" 31 | }, 32 | "properties" : { 33 | "preserves-vector-representation" : true 34 | } 35 | } -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/ReiKeyIcon.imageset/Icon.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/ReiKeyIcon.imageset/Icon.pdf -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/ReiKeyIcon.imageset/IconDark.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/ReiKeyIcon.imageset/IconDark.pdf -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/ReiKeyText.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "rkText.pdf" 6 | }, 7 | { 8 | "idiom" : "mac", 9 | "filename" : "rkText.pdf", 10 | "appearances" : [ 11 | { 12 | "appearance" : "luminosity", 13 | "value" : "light" 14 | } 15 | ] 16 | }, 17 | { 18 | "idiom" : "mac", 19 | "filename" : "rkText.pdf", 20 | "appearances" : [ 21 | { 22 | "appearance" : "luminosity", 23 | "value" : "dark" 24 | } 25 | ] 26 | } 27 | ], 28 | "info" : { 29 | "version" : 1, 30 | "author" : "xcode" 31 | }, 32 | "properties" : { 33 | "preserves-vector-representation" : true 34 | } 35 | } -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/ReiKeyText.imageset/rkText.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/ReiKeyText.imageset/rkText.pdf -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/Update.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "filename" : "update.pdf" 6 | }, 7 | { 8 | "idiom" : "mac", 9 | "filename" : "updateLight.pdf", 10 | "appearances" : [ 11 | { 12 | "appearance" : "luminosity", 13 | "value" : "light" 14 | } 15 | ] 16 | }, 17 | { 18 | "idiom" : "mac", 19 | "filename" : "updateDark.pdf", 20 | "appearances" : [ 21 | { 22 | "appearance" : "luminosity", 23 | "value" : "dark" 24 | } 25 | ] 26 | } 27 | ], 28 | "info" : { 29 | "version" : 1, 30 | "author" : "xcode" 31 | }, 32 | "properties" : { 33 | "preserves-vector-representation" : true 34 | } 35 | } -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/Update.imageset/update.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/Update.imageset/update.pdf -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/Update.imageset/updateDark.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/Update.imageset/updateDark.pdf -------------------------------------------------------------------------------- /mainApp/mainApp/Assets.xcassets/Update.imageset/updateLight.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/mainApp/mainApp/Assets.xcassets/Update.imageset/updateLight.pdf -------------------------------------------------------------------------------- /mainApp/mainApp/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /mainApp/mainApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleURLTypes 22 | 23 | 24 | CFBundleTypeRole 25 | Editor 26 | CFBundleURLName 27 | com.objective-see.reikey 28 | CFBundleURLSchemes 29 | 30 | reikey 31 | 32 | 33 | 34 | CFBundleVersion 35 | $(CURRENT_PROJECT_VERSION) 36 | LSMinimumSystemVersion 37 | $(MACOSX_DEPLOYMENT_TARGET) 38 | LSUIElement 39 | 40 | NSHumanReadableCopyright 41 | Copyright © 2019 Objective-See. All rights reserved. 42 | NSMainNibFile 43 | MainMenu 44 | NSPrincipalClass 45 | NSApplicationKeyEvents 46 | 47 | 48 | -------------------------------------------------------------------------------- /mainApp/mainApp/NSApplicationKeyEvents.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSApplicationKeyEvents.h 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | @import Cocoa; 10 | 11 | @interface NSApplicationKeyEvents : NSApplication 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /mainApp/mainApp/NSApplicationKeyEvents.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSApplicationKeyEvents.h 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #import "NSApplicationKeyEvents.h" 10 | 11 | @implementation NSApplicationKeyEvents 12 | 13 | //to enable copy/paste etc even though we don't have an 'Edit' menu 14 | // details: http://stackoverflow.com/questions/970707/cocoa-keyboard-shortcuts-in-dialog-without-an-edit-menu 15 | -(void) sendEvent:(NSEvent *)event 16 | { 17 | //keydown? 18 | if([event type] == NSEventTypeKeyDown) 19 | { 20 | //command? 21 | if(([event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask) == NSEventModifierFlagCommand) 22 | { 23 | //+c 24 | // copy 25 | if(YES == [[event charactersIgnoringModifiers] isEqualToString:@"c"]) 26 | { 27 | //copy 28 | if([self sendAction:@selector(copy:) to:nil from:self]) 29 | { 30 | return; 31 | } 32 | } 33 | 34 | //+v 35 | // paste 36 | else if ([[event charactersIgnoringModifiers] isEqualToString:@"v"]) 37 | { 38 | //paste 39 | if([self sendAction:@selector(paste:) to:nil from:self]) 40 | { 41 | return; 42 | } 43 | } 44 | 45 | //+x 46 | // cut 47 | else if ([[event charactersIgnoringModifiers] isEqualToString:@"x"]) 48 | { 49 | //cut 50 | if([self sendAction:@selector(cut:) to:nil from:self]) 51 | { 52 | return; 53 | } 54 | } 55 | 56 | //+a 57 | // select all 58 | else if([[event charactersIgnoringModifiers] isEqualToString:@"a"]) 59 | { 60 | if ([self sendAction:@selector(selectAll:) to:nil from:self]) 61 | { 62 | return; 63 | } 64 | } 65 | } 66 | } 67 | 68 | //super 69 | [super sendEvent:event]; 70 | } 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /mainApp/mainApp/PrefsWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // PrefsWindowController.h 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | @import Cocoa; 10 | 11 | #import "UpdateWindowController.h" 12 | 13 | /* CONSTS */ 14 | 15 | //to select, need string ID 16 | #define TOOLBAR_GENERAL_ID @"General" 17 | 18 | @interface PrefsWindowController : NSWindowController 19 | 20 | /* PROPERTIES */ 21 | 22 | //toolbar 23 | @property (weak) IBOutlet NSToolbar *toolbar; 24 | 25 | //general prefs view 26 | @property (strong) IBOutlet NSView *generalView; 27 | 28 | //update prefs view 29 | @property (strong) IBOutlet NSView *updateView; 30 | 31 | //'start at login' button 32 | @property (weak) IBOutlet NSButton *startAtLogin; 33 | 34 | //'run with icon' button 35 | @property (weak) IBOutlet NSButton *runWithIcon; 36 | 37 | //'ignore apple programs' button 38 | @property (weak) IBOutlet NSButton *ignoreAppleBinaries; 39 | 40 | //disable automatic update check 41 | @property (weak) IBOutlet NSButton *noUpdates; 42 | 43 | //check for update button 44 | @property (weak) IBOutlet NSButtonCell *updateButton; 45 | 46 | //check for update activity indicator 47 | @property (weak) IBOutlet NSProgressIndicator *updateIndicator; 48 | 49 | //check for update label 50 | @property (weak) IBOutlet NSTextField *updateLabel; 51 | 52 | //update window controller 53 | @property(nonatomic, retain)UpdateWindowController* updateWindowController; 54 | 55 | /* METHODS */ 56 | 57 | //button handler for all preference buttons 58 | -(IBAction)toggle:(id)sender; 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /mainApp/mainApp/PrefsWindowController.m: -------------------------------------------------------------------------------- 1 | // 2 | // PrefsWindowController.h 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "consts.h" 12 | #import "Update.h" 13 | #import "logging.h" 14 | #import "utilities.h" 15 | #import "AppDelegate.h" 16 | #import "PrefsWindowController.h" 17 | 18 | //general view 19 | #define TOOLBAR_GENERAL 0 20 | 21 | //update view 22 | #define TOOLBAR_UPDATE 1 23 | 24 | @implementation PrefsWindowController 25 | 26 | @synthesize toolbar; 27 | @synthesize updateLabel; 28 | @synthesize updateButton; 29 | @synthesize updateIndicator; 30 | @synthesize updateWindowController; 31 | 32 | //init 'general' view 33 | // add it, and make it selected 34 | -(void)awakeFromNib 35 | { 36 | //shared defaults 37 | NSUserDefaults* sharedDefaults = nil; 38 | 39 | //load shared defaults 40 | sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:SUITE_NAME]; 41 | 42 | //set title 43 | self.window.title = [NSString stringWithFormat:@"ReiKey (v. %@)", getAppVersion()]; 44 | 45 | //set general prefs as default 46 | [self.toolbar setSelectedItemIdentifier:TOOLBAR_GENERAL_ID]; 47 | 48 | //set general prefs as default 49 | [self toolbarButtonHandler:nil]; 50 | 51 | //set 'start at login' button state 52 | self.startAtLogin.state = [sharedDefaults boolForKey:PREF_START_AT_LOGIN]; 53 | 54 | //set 'run with icon' button state 55 | self.runWithIcon.state = [sharedDefaults boolForKey:PREF_RUN_WITH_ICON]; 56 | 57 | //set 'ingore apple binaries' button state 58 | self.ignoreAppleBinaries.state = [sharedDefaults boolForKey:PREF_IGNORE_APPLE_BINS]; 59 | 60 | //set 'disable update check' button state 61 | self.noUpdates.state = [sharedDefaults boolForKey:PREF_NO_UPDATES]; 62 | 63 | return; 64 | } 65 | 66 | //toolbar view handler 67 | // toggle view based on user selection 68 | -(IBAction)toolbarButtonHandler:(id)sender 69 | { 70 | //view 71 | NSView* view = nil; 72 | 73 | //shared defaults 74 | NSUserDefaults* sharedDefaults = nil; 75 | 76 | //load shared defaults 77 | sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:SUITE_NAME]; 78 | 79 | //when we've prev added a view 80 | // remove the prev view cuz adding a new one 81 | if(nil != sender) 82 | { 83 | //remove 84 | [[[self.window.contentView subviews] lastObject] removeFromSuperview]; 85 | } 86 | 87 | //assign view 88 | switch(((NSToolbarItem*)sender).tag) 89 | { 90 | //general 91 | case TOOLBAR_GENERAL: 92 | { 93 | //set view 94 | view = self.generalView; 95 | 96 | //set 'start at login' button state 97 | self.startAtLogin.state = [sharedDefaults boolForKey:PREF_START_AT_LOGIN]; 98 | 99 | //set 'run with icon' button state 100 | self.runWithIcon.state = [sharedDefaults boolForKey:PREF_RUN_WITH_ICON]; 101 | 102 | break; 103 | } 104 | 105 | //update 106 | case TOOLBAR_UPDATE: 107 | { 108 | //set view 109 | view = self.updateView; 110 | 111 | //set 'disable update check' button state 112 | self.noUpdates.state = [sharedDefaults boolForKey:PREF_NO_UPDATES]; 113 | 114 | break; 115 | } 116 | 117 | default: 118 | return; 119 | } 120 | 121 | //set frame rect 122 | view.frame = CGRectMake(0, 0, self.window.contentView.frame.size.width, self.window.contentView.frame.size.height); 123 | 124 | //add to window 125 | [self.window.contentView addSubview:view]; 126 | 127 | return; 128 | } 129 | 130 | //invoked when user toggles button 131 | // update preferences for that button 132 | -(IBAction)toggle:(id)sender 133 | { 134 | //shared defaults 135 | NSUserDefaults* sharedDefaults = nil; 136 | 137 | //state 138 | NSInteger buttonState = NSControlStateValueOff; 139 | 140 | //load shared defaults 141 | sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:SUITE_NAME]; 142 | 143 | //'start at login' 144 | // toggle login item state 145 | if(sender == self.startAtLogin) 146 | { 147 | //grab state 148 | // dispatch (below) execs code on bg 149 | buttonState = (NSInteger)self.startAtLogin.state; 150 | 151 | //toggle login item in background 152 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), 153 | ^{ 154 | //toggle 155 | if(YES != toggleLoginItem([NSURL fileURLWithPath:loginItemPath()], (int)buttonState)) 156 | { 157 | //err msg 158 | logMsg(LOG_ERR, @"failed to toggle login item"); 159 | } 160 | }); 161 | 162 | //set 'start at login' 163 | [sharedDefaults setBool:(BOOL)self.startAtLogin.state forKey:PREF_START_AT_LOGIN]; 164 | } 165 | 166 | //'run with icon' 167 | // restart login item... 168 | else if(sender == self.runWithIcon) 169 | { 170 | //set 'run with icon' 171 | [sharedDefaults setBool:(BOOL)self.runWithIcon.state forKey:PREF_RUN_WITH_ICON]; 172 | 173 | //broadcast notification 174 | // tells login item to hide/show icon 175 | [[NSDistributedNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_PREFS_CHANGED object:nil userInfo:nil deliverImmediately:YES]; 176 | } 177 | 178 | //'ignore apple binaries' 179 | // ...just set preference 180 | else if(sender == self.ignoreAppleBinaries) 181 | { 182 | //set 'run with icon' 183 | [sharedDefaults setBool:(BOOL)self.ignoreAppleBinaries.state forKey:PREF_IGNORE_APPLE_BINS]; 184 | } 185 | 186 | //'disable update checks' 187 | // ...just set preference 188 | else if(sender == self.noUpdates) 189 | { 190 | //set 'run with icon' 191 | [sharedDefaults setBool:(BOOL)self.noUpdates.state forKey:PREF_NO_UPDATES]; 192 | } 193 | 194 | return; 195 | } 196 | 197 | //'check for update' button handler 198 | -(IBAction)check4Update:(id)sender 199 | { 200 | //update obj 201 | Update* update = nil; 202 | 203 | //disable button 204 | self.updateButton.enabled = NO; 205 | 206 | //reset 207 | self.updateLabel.stringValue = @""; 208 | 209 | //show/start spinner 210 | [self.updateIndicator startAnimation:self]; 211 | 212 | //init update obj 213 | update = [[Update alloc] init]; 214 | 215 | //check for update 216 | // ->'updateResponse newVersion:' method will be called when check is done 217 | [update checkForUpdate:^(NSUInteger result, NSString* newVersion) { 218 | 219 | //process response 220 | [self updateResponse:result newVersion:newVersion]; 221 | 222 | }]; 223 | 224 | return; 225 | } 226 | 227 | //process update response 228 | // error, no update, update/new version 229 | -(void)updateResponse:(NSInteger)result newVersion:(NSString*)newVersion 230 | { 231 | //re-enable button 232 | self.updateButton.enabled = YES; 233 | 234 | //stop/hide spinner 235 | [self.updateIndicator stopAnimation:self]; 236 | 237 | //handle response 238 | // new version, show popup 239 | switch(result) 240 | { 241 | //error 242 | case UPDATE_ERROR: 243 | 244 | //set label 245 | self.updateLabel.stringValue = @"error: update check failed"; 246 | 247 | break; 248 | 249 | //no updates 250 | case UPDATE_NOTHING_NEW: 251 | 252 | //set label 253 | self.updateLabel.stringValue = @"no new versions"; 254 | 255 | break; 256 | 257 | //new version 258 | case UPDATE_NEW_VERSION: 259 | 260 | //alloc update window 261 | updateWindowController = [[UpdateWindowController alloc] initWithWindowNibName:@"UpdateWindow"]; 262 | 263 | //configure 264 | [self.updateWindowController configure:[NSString stringWithFormat:@"a new version (%@) is available!", newVersion] buttonTitle:@"update"]; 265 | 266 | //center window 267 | [[self.updateWindowController window] center]; 268 | 269 | //show it 270 | [self.updateWindowController showWindow:self]; 271 | 272 | //invoke function in background that will make window modal 273 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 274 | 275 | //make modal 276 | makeModal(self.updateWindowController); 277 | 278 | }); 279 | 280 | break; 281 | } 282 | 283 | return; 284 | } 285 | 286 | @end 287 | -------------------------------------------------------------------------------- /mainApp/mainApp/ReiKey.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.application-groups 8 | 9 | com.objective-see.reikey.group 10 | 11 | com.apple.security.network.client 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /mainApp/mainApp/ScanRow.h: -------------------------------------------------------------------------------- 1 | // 2 | // RuleRow.h 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | @import Cocoa; 10 | 11 | @interface ScanRow : NSTableRowView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /mainApp/mainApp/ScanRow.m: -------------------------------------------------------------------------------- 1 | // 2 | // RuleRow.m 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #import "ScanRow.h" 10 | 11 | @implementation ScanRow 12 | 13 | //custom row selection 14 | -(void)drawSelectionInRect:(NSRect)dirtyRect 15 | { 16 | //selection rect 17 | NSRect selectionRect = {0}; 18 | 19 | //selection path 20 | NSBezierPath* selectionPath = nil; 21 | 22 | //selection color 23 | NSColor* selectionColor = nil; 24 | 25 | //highlight selected rows 26 | if(self.selectionHighlightStyle != NSTableViewSelectionHighlightStyleNone) 27 | { 28 | //make selection rect 29 | selectionRect = NSInsetRect(self.bounds, 2.5, 2.5); 30 | 31 | //default color 32 | selectionColor = [NSColor systemGrayColor]; 33 | 34 | //10.4, set to unemphasized 35 | if (@available(macOS 10.14, *)) 36 | { 37 | //set 38 | selectionColor = [NSColor unemphasizedSelectedContentBackgroundColor]; 39 | } 40 | 41 | //set stroke 42 | [selectionColor setStroke]; 43 | 44 | //set fill 45 | [selectionColor setFill]; 46 | 47 | //create selection path 48 | // with rounded corners 49 | selectionPath = [NSBezierPath bezierPathWithRoundedRect:selectionRect xRadius:5 yRadius:5]; 50 | 51 | //fill 52 | [selectionPath fill]; 53 | 54 | //stroke 55 | [selectionPath stroke]; 56 | } 57 | 58 | return; 59 | } 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /mainApp/mainApp/ScanWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ScanWindowController.h 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | @import Cocoa; 10 | 11 | #import "EventTaps.h" 12 | 13 | /* CONSTS */ 14 | 15 | //id (tag) for detailed text in category table 16 | #define TABLE_ROW_NAME_TAG 100 17 | 18 | //id (tag) for detailed text in category table 19 | #define TABLE_ROW_SUB_TEXT_TAG 101 20 | 21 | //menu item for mute/unmute 22 | #define MENU_ITEM_ACTION 0 23 | 24 | //menu item for show in finder 25 | #define MENU_ITEM_SHOW_IN_FINDER 1 26 | 27 | /* INTERFACE */ 28 | 29 | @interface ScanWindowController : NSWindowController 30 | { 31 | 32 | } 33 | 34 | /* PROPERTIES */ 35 | 36 | //event tap obj 37 | @property(nonatomic, retain)EventTaps* eventTapsObj; 38 | 39 | //(optional) tap id to select 40 | @property(nonatomic, retain)NSNumber* tapID; 41 | 42 | //event taps 43 | // array used to populate table 44 | @property(nonatomic, retain)NSMutableArray* eventTaps; 45 | 46 | //refresh/rescan button 47 | @property (weak) IBOutlet NSButton *rescan; 48 | 49 | //'scanning' overlay 50 | @property (weak) IBOutlet NSView *overlay; 51 | 52 | //'scanning' activity indicator 53 | @property (weak) IBOutlet NSProgressIndicator *activityIndicator; 54 | 55 | //'scanning' activity message 56 | @property (weak) IBOutlet NSTextField *activityMessage; 57 | 58 | //scan results 59 | @property (weak) IBOutlet NSTextField *scanResults; 60 | 61 | //top level view 62 | @property (weak) IBOutlet NSView *view; 63 | 64 | //window toolbar 65 | @property (weak) IBOutlet NSToolbar *toolbar; 66 | 67 | //table view 68 | @property (weak) IBOutlet NSTableView *tableView; 69 | 70 | /* METHODS */ 71 | 72 | //(re)scan button handler 73 | // can also call directly to trigger scan... 74 | -(IBAction)reScan:(id)sender; 75 | 76 | @end 77 | -------------------------------------------------------------------------------- /mainApp/mainApp/WelcomeWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // WelcomeWindowController.h 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | @import Cocoa; 10 | 11 | #import 12 | 13 | @interface WelcomeWindowController : NSWindowController 14 | 15 | /* PROPERTIES */ 16 | 17 | //sync view controller 18 | @property(nonatomic, retain)NSViewController* welcomeViewController; 19 | 20 | //welcome view 21 | @property (strong) IBOutlet NSView *welcomeView; 22 | 23 | //config view 24 | @property (strong) IBOutlet NSView *configureView; 25 | 26 | //allow apple bins/apps 27 | @property (weak) IBOutlet NSButton *startAtLogin; 28 | 29 | //allow 3rd-party installed apps 30 | @property (weak) IBOutlet NSButton *runWithIcon; 31 | 32 | //'ignore apple programs' button 33 | @property (weak) IBOutlet NSButton *ignoreAppleBinaries; 34 | 35 | //friends view 36 | @property (strong) IBOutlet NSView *friendsView; 37 | 38 | /* METHODS */ 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /mainApp/mainApp/WelcomeWindowController.m: -------------------------------------------------------------------------------- 1 | // 2 | // file: WelcomeWindowController.m 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #import "consts.h" 10 | #import "logging.h" 11 | #import "utilities.h" 12 | #import "AppDelegate.h" 13 | #import "WelcomeWindowController.h" 14 | 15 | #define VIEW_WELCOME 0 16 | #define VIEW_CONFIGURE 1 17 | #define VIEW_FRIENDS 2 18 | #define VIEW_CLOSE 3 19 | 20 | @implementation WelcomeWindowController 21 | 22 | @synthesize welcomeViewController; 23 | 24 | //welcome! 25 | -(void)windowDidLoad { 26 | 27 | //super 28 | [super windowDidLoad]; 29 | 30 | //center 31 | [self.window center]; 32 | 33 | //not in dark mode? 34 | // make window white 35 | if(YES != isDarkMode()) 36 | { 37 | //make white 38 | self.window.backgroundColor = NSColor.whiteColor; 39 | } 40 | 41 | //when supported 42 | // indicate title bar is transparent (too) 43 | if(YES == [self.window respondsToSelector:@selector(titlebarAppearsTransparent)]) 44 | { 45 | //set transparency 46 | self.window.titlebarAppearsTransparent = YES; 47 | } 48 | 49 | //show first view 50 | // 'welcome' ...blah blah 51 | [self buttonHandler:nil]; 52 | 53 | return; 54 | } 55 | 56 | //button handler for all views 57 | // show next view, sometimes, with view specific logic 58 | -(IBAction)buttonHandler:(id)sender 59 | { 60 | //shared defaults 61 | NSUserDefaults* sharedDefaults = nil; 62 | 63 | //prev view was config? 64 | // save user specified prefs 65 | if((VIEW_CONFIGURE+1) == ((NSToolbarItem*)sender).tag) 66 | { 67 | //load shared defaults 68 | sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:SUITE_NAME]; 69 | 70 | //set 'start at login' 71 | [sharedDefaults setBool:(BOOL)self.startAtLogin.state forKey:PREF_START_AT_LOGIN]; 72 | 73 | //set 'run with icon' 74 | [sharedDefaults setBool:(BOOL)self.runWithIcon.state forKey:PREF_RUN_WITH_ICON]; 75 | 76 | //set 'ignore apple programs' 77 | [sharedDefaults setBool:(BOOL)self.ignoreAppleBinaries.state forKey:PREF_IGNORE_APPLE_BINS]; 78 | 79 | //act on 'start at login' 80 | if(NSControlStateValueOn == self.startAtLogin.state) 81 | { 82 | //enable login item in background 83 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), 84 | ^{ 85 | //enable 86 | if(YES != toggleLoginItem([NSURL fileURLWithPath:loginItemPath()], NSControlStateValueOn)) 87 | { 88 | //err msg 89 | logMsg(LOG_ERR, @"failed to toggle login item"); 90 | } 91 | }); 92 | } 93 | } 94 | 95 | //set next view 96 | switch(((NSButton*)sender).tag) 97 | { 98 | //start: 99 | // show welcome 100 | case 0: 101 | { 102 | //remove prev. subview 103 | [[[self.window.contentView subviews] lastObject] removeFromSuperview]; 104 | 105 | //set view 106 | [self.window.contentView addSubview:self.welcomeView]; 107 | 108 | //make 'next' button first responder 109 | [self.window makeFirstResponder:[self.welcomeView viewWithTag:VIEW_CONFIGURE]]; 110 | 111 | break; 112 | } 113 | 114 | //configure 115 | case VIEW_CONFIGURE: 116 | { 117 | //remove prev. subview 118 | [[[self.window.contentView subviews] lastObject] removeFromSuperview]; 119 | 120 | //set view 121 | [self.window.contentView addSubview:self.configureView]; 122 | 123 | //make 'next' button first responder 124 | [self.window makeFirstResponder:[self.configureView viewWithTag:VIEW_FRIENDS]]; 125 | 126 | break; 127 | } 128 | 129 | //support 130 | case VIEW_FRIENDS: 131 | { 132 | //remove prev. subview 133 | [[[self.window.contentView subviews] lastObject] removeFromSuperview]; 134 | 135 | //set view 136 | [self.window.contentView addSubview:self.friendsView]; 137 | 138 | //make 'close' button first responder 139 | [self.window makeFirstResponder:[self.friendsView viewWithTag:VIEW_CLOSE]]; 140 | 141 | break; 142 | } 143 | 144 | //close 145 | case VIEW_CLOSE: 146 | 147 | //hide window 148 | [self.window orderOut:self]; 149 | 150 | //in background 151 | // start login item, then exit installer 152 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), 153 | ^{ 154 | //start login item 155 | startApplication([NSURL fileURLWithPath:loginItemPath()], NSWorkspaceLaunchWithoutActivation); 156 | 157 | //exit 158 | [NSApp terminate:nil]; 159 | }); 160 | 161 | default: 162 | 163 | break; 164 | } 165 | 166 | return; 167 | } 168 | 169 | @end 170 | -------------------------------------------------------------------------------- /mainApp/mainApp/main.h: -------------------------------------------------------------------------------- 1 | // 2 | // main.h 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/29/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #ifndef main_h 10 | #define main_h 11 | 12 | /* FUNCTIONS */ 13 | 14 | //print usage 15 | void usage(void); 16 | 17 | //perform a cmdline scan 18 | void cmdlineScan(void); 19 | 20 | #endif /* main_h */ 21 | -------------------------------------------------------------------------------- /mainApp/mainApp/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/29/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | @import Cocoa; 10 | 11 | #import "main.h" 12 | #import "consts.h" 13 | #import "logging.h" 14 | #import "signing.h" 15 | #import "EventTaps.h" 16 | #import "utilities.h" 17 | 18 | //main 19 | // process cmdline args, show UI, etc 20 | int main(int argc, const char * argv[]) 21 | { 22 | //return var 23 | int status = -1; 24 | 25 | //args 26 | NSArray* arguments = nil; 27 | 28 | //grab args 29 | arguments = [[NSProcessInfo processInfo] arguments]; 30 | 31 | //disable stderr 32 | // crash reporter dumps info here 33 | disableSTDERR(); 34 | 35 | //init crash reporting 36 | // kicks off sentry.io 37 | initCrashReporting(); 38 | 39 | //dbg msg 40 | logMsg(LOG_DEBUG, [NSString stringWithFormat:@"starting main app (args: %@)", [[NSProcessInfo processInfo] arguments]]); 41 | 42 | //handle '-h' or '-help' 43 | if( (YES == [arguments containsObject:@"-h"]) || 44 | (YES == [arguments containsObject:@"-help"]) ) 45 | { 46 | //print usage 47 | usage(); 48 | 49 | //done 50 | goto bail; 51 | } 52 | 53 | //handle '-scan' 54 | // cmdline scan without UI 55 | if(YES == [arguments containsObject:@"-scan"]) 56 | { 57 | //scan 58 | cmdlineScan(); 59 | 60 | //happy 61 | status = 0; 62 | 63 | //done 64 | goto bail; 65 | } 66 | 67 | //handle invalid args 68 | // allow `-psn_` cuz OS sometimes adds this? 69 | if( (arguments.count > 1) && 70 | (YES != [arguments[1] hasPrefix:@"-psn_"]) && 71 | (YES != [arguments containsObject:@"-NSDocumentRevisionsDebugMode"]) ) 72 | { 73 | //print usage 74 | usage(); 75 | 76 | //done 77 | goto bail; 78 | } 79 | 80 | //running non-cmdline mode 81 | // so, make foreground so app has an dock icon, etc 82 | transformApp(kProcessTransformToForegroundApplication); 83 | 84 | //launch app normally 85 | status = NSApplicationMain(argc, argv); 86 | 87 | bail: 88 | 89 | return status; 90 | } 91 | 92 | //print usage 93 | void usage() 94 | { 95 | //usage 96 | printf("\nREIKEY USAGE:\n"); 97 | printf(" -h or -help display this usage info\n"); 98 | printf(" -scan enumerate all keyboard event taps\n"); 99 | printf(" -pretty JSON output is 'pretty-printed' for readability\n"); 100 | printf(" -skipApple ignore event taps that belong to Apple processes \n\n"); 101 | 102 | return; 103 | } 104 | 105 | //perform a cmdline scan 106 | void cmdlineScan() 107 | { 108 | //event taps 109 | NSMutableArray* eventTaps = nil; 110 | 111 | //current tap 112 | NSDictionary* eventTap = nil; 113 | 114 | //signing info 115 | NSDictionary* signingInfo = nil; 116 | 117 | //output 118 | NSMutableString* output = nil; 119 | 120 | //scan 121 | eventTaps = [[[[[EventTaps alloc] init] enumerate] allValues] mutableCopy]; 122 | 123 | //ingore apple signed event taps? 124 | if(YES == [[[NSProcessInfo processInfo] arguments] containsObject:@"-skipApple"]) 125 | { 126 | //remove any apple event taps 127 | // iterate backwards so we can enumerate and remove at same time 128 | for(NSInteger index = eventTaps.count-1; index >= 0; index--) 129 | { 130 | //tap 131 | eventTap = eventTaps[index]; 132 | 133 | //generate signing info 134 | // first dynamically (via pid) 135 | signingInfo = extractSigningInfo([eventTap[TAP_SOURCE_PID] intValue], nil, kSecCSDefaultFlags); 136 | if(nil == signingInfo) 137 | { 138 | //extract signing info statically 139 | signingInfo = extractSigningInfo(0, eventTap[TAP_SOURCE_PATH], kSecCSCheckAllArchitectures | kSecCSCheckNestedCode | kSecCSDoNotValidateResources); 140 | } 141 | 142 | //ignore if signed by apple 143 | if( (noErr == [signingInfo[KEY_SIGNATURE_STATUS] intValue]) && 144 | (Apple == [signingInfo[KEY_SIGNATURE_SIGNER] intValue]) ) 145 | { 146 | //ignore 147 | [eventTaps removeObjectAtIndex:index]; 148 | } 149 | } 150 | } 151 | 152 | //init output string 153 | output = [NSMutableString string]; 154 | 155 | //start JSON 156 | [output appendString:@"["]; 157 | 158 | //add each tap 159 | for(NSDictionary* eventTap in eventTaps) 160 | { 161 | [output appendFormat:@"{\"%@\": \"%@\", \"%@\": \"%@\", \"%@\": \"%@\", \"%@\": \"%@\", \"%@\": \"%@\"},", TAP_ID, eventTap[TAP_ID], TAP_SOURCE_PID, eventTap[TAP_SOURCE_PID], TAP_SOURCE_PATH, eventTap[TAP_SOURCE_PATH], TAP_DESTINATION_PID, eventTap[TAP_DESTINATION_PID], TAP_DESTINATION_PATH, eventTap[TAP_DESTINATION_PATH]]; 162 | } 163 | 164 | //remove last ',' 165 | if(YES == [output hasSuffix:@","]) 166 | { 167 | //remove 168 | [output deleteCharactersInRange:NSMakeRange([output length]-1, 1)]; 169 | } 170 | 171 | //terminate list 172 | [output appendString:@"]"]; 173 | 174 | //pretty print? 175 | if(YES == [[[NSProcessInfo processInfo] arguments] containsObject:@"-pretty"]) 176 | { 177 | //make me pretty! 178 | printf("%s\n", prettifyJSON(output).UTF8String); 179 | } 180 | else 181 | { 182 | //output 183 | printf("%s\n", output.UTF8String); 184 | } 185 | 186 | return; 187 | } 188 | -------------------------------------------------------------------------------- /mainApp/mainApp/patrons.txt: -------------------------------------------------------------------------------- 1 | Patrons (2^6+): 2 | Halo Privacy, Ash Morgan, Stuart Ashenbrenner, Beau Galbraith, Aaron Kiemele, Nando Mendonca, Khalil Sehnaoui, Geoffrey Weber, Randy Wong, Gamer_Bot 3 | 4 | Friends of Objective-See: 5 | Digita Security, Sophos, CleanMyMac X, Malwarebytes, SmugMug, Guardian Mobile Firewall, SecureMac 6 | -------------------------------------------------------------------------------- /shared/AboutWindow.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 105 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /shared/AboutWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // AboutWindowController.h 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | @import Cocoa; 10 | 11 | @interface AboutWindowController : NSWindowController 12 | { 13 | 14 | } 15 | 16 | /* PROPERTIES */ 17 | 18 | //version label/string 19 | @property (weak) IBOutlet NSTextField *versionLabel; 20 | 21 | //patrons 22 | @property (unsafe_unretained) IBOutlet NSTextView *patrons; 23 | 24 | /* METHODS */ 25 | 26 | //automatically invoked when user clicks any of the buttons 27 | // perform actions, such as loading patreon or products URL 28 | -(IBAction)buttonHandler:(id)sender; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /shared/AboutWindowController.m: -------------------------------------------------------------------------------- 1 | // 2 | // AboutWindowController.m 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #import "consts.h" 10 | #import "utilities.h" 11 | #import "AboutWindowController.h" 12 | 13 | @implementation AboutWindowController 14 | 15 | @synthesize patrons; 16 | @synthesize versionLabel; 17 | 18 | //automatically called when nib is loaded 19 | // ->center window 20 | -(void)awakeFromNib 21 | { 22 | //center 23 | [self.window center]; 24 | } 25 | 26 | //automatically invoked when window is loaded 27 | // set to window to white, set app version, patrons, etc 28 | -(void)windowDidLoad 29 | { 30 | //version 31 | NSString* version = nil; 32 | 33 | //super 34 | [super windowDidLoad]; 35 | 36 | //not in dark mode? 37 | // make window white 38 | if(YES != isDarkMode()) 39 | { 40 | //make white 41 | self.window.backgroundColor = NSColor.whiteColor; 42 | } 43 | 44 | //grab app version 45 | version = getAppVersion(); 46 | if(nil == version) 47 | { 48 | //default 49 | version = @"unknown"; 50 | } 51 | 52 | //set version sting 53 | self.versionLabel.stringValue = version; 54 | 55 | //load patrons 56 | // <3 you guys & girls 57 | self.patrons.string = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"patrons" ofType:@"txt"] encoding:NSUTF8StringEncoding error:NULL]; 58 | if(nil == self.patrons.string) 59 | { 60 | //default 61 | self.patrons.string = @"error: failed to load patrons :/"; 62 | } 63 | 64 | //make 'Support Us' button first responder 65 | [self.window makeFirstResponder:[self.window.contentView viewWithTag:BUTTON_SUPPORT_US]]; 66 | 67 | return; 68 | } 69 | 70 | //automatically invoked when window is closing 71 | // ->make window unmodal 72 | -(void)windowWillClose:(NSNotification *)notification 73 | { 74 | //make un-modal 75 | [[NSApplication sharedApplication] stopModal]; 76 | 77 | return; 78 | } 79 | 80 | //automatically invoked when user clicks any of the buttons 81 | // ->perform actions, such as loading patreon or products URL 82 | -(IBAction)buttonHandler:(id)sender 83 | { 84 | //support us button 85 | if(((NSButton*)sender).tag == BUTTON_SUPPORT_US) 86 | { 87 | //open URL 88 | // ->invokes user's default browser 89 | [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:PATREON_URL]]; 90 | } 91 | 92 | //more info button 93 | else if(((NSButton*)sender).tag == BUTTON_MORE_INFO) 94 | { 95 | //open URL 96 | // ->invokes user's default browser 97 | [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:PRODUCT_URL]]; 98 | } 99 | 100 | return; 101 | } 102 | @end 103 | -------------------------------------------------------------------------------- /shared/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "icon_16x16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "icon_16x16@2x.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "icon_32x32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "icon_32x32@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "icon_128x128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "icon_128x128@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "icon_256x256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "icon_256x256@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "icon_512x512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "idiom" : "mac", 59 | "size" : "512x512", 60 | "scale" : "2x" 61 | } 62 | ], 63 | "info" : { 64 | "version" : 1, 65 | "author" : "xcode" 66 | } 67 | } -------------------------------------------------------------------------------- /shared/AppIcon.appiconset/icon_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/shared/AppIcon.appiconset/icon_128x128.png -------------------------------------------------------------------------------- /shared/AppIcon.appiconset/icon_128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/shared/AppIcon.appiconset/icon_128x128@2x.png -------------------------------------------------------------------------------- /shared/AppIcon.appiconset/icon_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/shared/AppIcon.appiconset/icon_16x16.png -------------------------------------------------------------------------------- /shared/AppIcon.appiconset/icon_16x16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/shared/AppIcon.appiconset/icon_16x16@2x.png -------------------------------------------------------------------------------- /shared/AppIcon.appiconset/icon_256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/shared/AppIcon.appiconset/icon_256x256.png -------------------------------------------------------------------------------- /shared/AppIcon.appiconset/icon_256x256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/shared/AppIcon.appiconset/icon_256x256@2x.png -------------------------------------------------------------------------------- /shared/AppIcon.appiconset/icon_32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/shared/AppIcon.appiconset/icon_32x32.png -------------------------------------------------------------------------------- /shared/AppIcon.appiconset/icon_32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/shared/AppIcon.appiconset/icon_32x32@2x.png -------------------------------------------------------------------------------- /shared/AppIcon.appiconset/icon_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/shared/AppIcon.appiconset/icon_512x512.png -------------------------------------------------------------------------------- /shared/EventTaps.h: -------------------------------------------------------------------------------- 1 | // 2 | // EventTaps.h 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /* TYPEDEFS */ 12 | 13 | //callback 14 | typedef void (^TapCallbackBlock)(NSDictionary*); 15 | 16 | @interface EventTaps : NSObject 17 | 18 | /* PROPERTIES */ 19 | 20 | //previous event taps 21 | @property(nonatomic, retain)NSMutableDictionary* previousTaps; 22 | 23 | /* METHODS */ 24 | 25 | //listen for new taps 26 | // note: method doesn't return! 27 | -(void)observe:(TapCallbackBlock)callback; 28 | 29 | //enumerate event taps 30 | // activated keyboard taps 31 | -(NSMutableDictionary*)enumerate; 32 | 33 | @end 34 | 35 | -------------------------------------------------------------------------------- /shared/EventTaps.m: -------------------------------------------------------------------------------- 1 | // 2 | // EventTaps.m 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "consts.h" 12 | #import "logging.h" 13 | #import "signing.h" 14 | #import "utilities.h" 15 | #import "EventTaps.h" 16 | 17 | @implementation EventTaps 18 | 19 | @synthesize previousTaps; 20 | 21 | //enumerate event taps 22 | // activated keyboard taps 23 | -(NSMutableDictionary*)enumerate 24 | { 25 | //keyboard taps 26 | NSMutableDictionary* keyboardTaps = nil; 27 | 28 | //event taps 29 | uint32_t eventTapCount = 0; 30 | 31 | //taps 32 | CGEventTapInformation *taps = NULL; 33 | 34 | //current tap 35 | CGEventTapInformation tap = {0}; 36 | 37 | //tapping process 38 | NSString* sourcePath = nil; 39 | 40 | //target process 41 | NSString* destinationPath = nil; 42 | 43 | //options (type) 44 | NSString* options = nil; 45 | 46 | //alloc 47 | keyboardTaps = [NSMutableDictionary dictionary]; 48 | 49 | //get number of existing taps 50 | if( (kCGErrorSuccess != CGGetEventTapList(0, NULL, &eventTapCount)) || 51 | (0 == eventTapCount) ) 52 | { 53 | //bail 54 | goto bail; 55 | } 56 | 57 | //alloc 58 | taps = malloc(sizeof(CGEventTapInformation) * eventTapCount); 59 | if(NULL == taps) 60 | { 61 | //bail 62 | goto bail; 63 | } 64 | 65 | //get all taps 66 | if(kCGErrorSuccess != CGGetEventTapList(eventTapCount, taps, &eventTapCount)) 67 | { 68 | //bail 69 | goto bail; 70 | } 71 | 72 | //iterate/process all taps 73 | for(int i=0; i"; 99 | } 100 | 101 | //when target is 0 102 | // means all/system-wide 103 | if(0 == tap.processBeingTapped) 104 | { 105 | //set 106 | destinationPath = GLOBAL_EVENT_TAP; 107 | } 108 | //specific target 109 | // get path for target process 110 | else 111 | { 112 | //get path to target process 113 | destinationPath = getProcessPath(tap.processBeingTapped); 114 | if(0 == destinationPath.length) 115 | { 116 | //default 117 | destinationPath = @""; 118 | } 119 | } 120 | 121 | //set option 122 | switch (tap.options) 123 | { 124 | //filter 125 | case kCGEventTapOptionDefault: 126 | options = @"Active filter"; 127 | break; 128 | 129 | //listener 130 | case kCGEventTapOptionListenOnly: 131 | options = @"Passive listener"; 132 | break; 133 | 134 | //unknown 135 | default: 136 | options = @""; 137 | break; 138 | } 139 | 140 | //add 141 | keyboardTaps[@(tap.eventTapID)] = @{TAP_ID:@(tap.eventTapID), TAP_OPTIONS:options, TAP_SOURCE_PATH:sourcePath, TAP_SOURCE_PID:@(tap.tappingProcess), TAP_DESTINATION_PATH:destinationPath, TAP_DESTINATION_PID:@(tap.processBeingTapped)}; 142 | } 143 | 144 | bail: 145 | 146 | //free taps 147 | if(NULL != taps) 148 | { 149 | //free 150 | free(taps); 151 | taps = NULL; 152 | } 153 | 154 | return keyboardTaps; 155 | } 156 | 157 | //listen for new taps 158 | // note: method doesn't return! 159 | -(void)observe:(TapCallbackBlock)callback; 160 | { 161 | //token 162 | int notifyToken = NOTIFY_TOKEN_INVALID; 163 | 164 | //current taps 165 | // ...that include any news ones 166 | __block NSMutableDictionary* currentTaps = nil; 167 | 168 | //signing info 169 | __block NSMutableDictionary* signingInfo = nil; 170 | 171 | //grab existing taps 172 | self.previousTaps = [self enumerate]; 173 | 174 | //register 'kCGNotifyEventTapAdded' notification 175 | notify_register_dispatch(kCGNotifyEventTapAdded, ¬ifyToken, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(int token) { 176 | 177 | //sync to assure thread safety 178 | @synchronized(self) 179 | { 180 | //grab current taps 181 | // ...should now include any new ones 182 | currentTaps = [self enumerate]; 183 | 184 | //identify any new taps 185 | // invoke callback for those... 186 | for(NSNumber* tapID in currentTaps.allKeys) 187 | { 188 | //not new? 189 | if(nil != self.previousTaps[tapID]) 190 | { 191 | //skip 192 | continue; 193 | } 194 | 195 | //dbg msg 196 | logMsg(LOG_DEBUG, [NSString stringWithFormat:@"kCGNotifyEventTapAdded fired (new tap: %@)", currentTaps[tapID]]); 197 | 198 | //ignore taps from vmware 199 | // it creates a temporary event tap while one interacts with a VM 200 | if(YES == [[currentTaps[tapID][TAP_SOURCE_PATH] lastPathComponent] isEqualToString:@"vmware-vmx"]) 201 | { 202 | //generate signing info 203 | // and make sure its vmware 204 | signingInfo = extractSigningInfo([currentTaps[tapID][TAP_SOURCE_PID] intValue], nil, kSecCSDefaultFlags); 205 | if( (nil != signingInfo) && 206 | (noErr == [signingInfo[KEY_SIGNATURE_STATUS] intValue]) && 207 | (DevID == [signingInfo[KEY_SIGNATURE_SIGNER] intValue]) && 208 | (YES == [signingInfo[KEY_SIGNATURE_IDENTIFIER] isEqualToString:@"com.vmware.vmware-vmx"]) ) 209 | { 210 | //dbg msg 211 | logMsg(LOG_DEBUG, @"ingoring alert: 'com.vmware.vmware-vmx'"); 212 | 213 | //skip 214 | continue; 215 | } 216 | } 217 | 218 | //just nap a bit 219 | // some notifications seem temporary 220 | else 221 | { 222 | //wait a few seconds and recheck 223 | // some notifications seem temporary (i.e. vmware) 224 | [NSThread sleepForTimeInterval:1.0f]; 225 | } 226 | 227 | //(re)enumerate 228 | // ignore if the tap went away 229 | if(YES != [[[self enumerate] allKeys] containsObject:tapID]) 230 | { 231 | //dbg msg 232 | logMsg(LOG_DEBUG, [NSString stringWithFormat:@"tap %@, was temporary, so ignoring", currentTaps[tapID]]); 233 | 234 | //skip 235 | continue; 236 | } 237 | 238 | //new 239 | // and not temporary... 240 | callback(currentTaps[tapID]); 241 | 242 | }//all taps 243 | 244 | //update taps 245 | self.previousTaps = currentTaps; 246 | 247 | } //sync 248 | 249 | }); 250 | 251 | //run loop 252 | [[NSRunLoop currentRunLoop] run]; 253 | 254 | return; 255 | } 256 | 257 | @end 258 | -------------------------------------------------------------------------------- /shared/Update.h: -------------------------------------------------------------------------------- 1 | // 2 | // Update.h 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #ifndef Update_h 10 | #define Update_h 11 | 12 | @import Cocoa; 13 | @import Foundation; 14 | 15 | @interface Update : NSObject 16 | 17 | //check for an update 18 | // will invoke app delegate method to update UI when check completes 19 | -(void)checkForUpdate:(void (^)(NSUInteger result, NSString* latestVersion))completionHandler; 20 | 21 | @end 22 | 23 | #endif /* Update_h */ 24 | -------------------------------------------------------------------------------- /shared/Update.m: -------------------------------------------------------------------------------- 1 | // 2 | // Update.m 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #import "consts.h" 10 | #import "Update.h" 11 | #import "utilities.h" 12 | #import "AppDelegate.h" 13 | 14 | @implementation Update 15 | 16 | //check for an update 17 | // ->will invoke app delegate method to update UI when check completes 18 | -(void)checkForUpdate:(void (^)(NSUInteger result, NSString* latestVersion))completionHandler 19 | { 20 | //latest version 21 | __block NSString* latestVersion = nil; 22 | 23 | //result 24 | __block NSInteger result = -1; 25 | 26 | //get latest version in background 27 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 28 | 29 | //grab latest version 30 | latestVersion = [self getLatestVersion]; 31 | if(nil != latestVersion) 32 | { 33 | //check 34 | result = (NSOrderedAscending == [getAppVersion() compare:latestVersion options:NSNumericSearch]); 35 | } 36 | 37 | //invoke app delegate method 38 | // ->will update UI/show popup if necessart 39 | dispatch_async(dispatch_get_main_queue(), 40 | ^{ 41 | completionHandler(result, latestVersion); 42 | }); 43 | 44 | }); 45 | 46 | return; 47 | } 48 | 49 | //query interwebz to get latest version 50 | -(NSString*)getLatestVersion 51 | { 52 | //product version(s) data 53 | NSData* productsVersionData = nil; 54 | 55 | //version dictionary 56 | NSDictionary* productsVersionDictionary = nil; 57 | 58 | //latest version 59 | NSString* latestVersion = nil; 60 | 61 | //get version from remote URL 62 | productsVersionData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:PRODUCT_VERSIONS_URL]]; 63 | if(nil == productsVersionData) 64 | { 65 | //bail 66 | goto bail; 67 | } 68 | 69 | //convert JSON to dictionary 70 | // ->wrap as may throw exception 71 | @try 72 | { 73 | //convert 74 | productsVersionDictionary = [NSJSONSerialization JSONObjectWithData:productsVersionData options:0 error:nil]; 75 | if(nil == productsVersionDictionary) 76 | { 77 | //bail 78 | goto bail; 79 | } 80 | } 81 | @catch(NSException* exception) 82 | { 83 | //bail 84 | goto bail; 85 | } 86 | 87 | //extract latest version 88 | latestVersion = [[productsVersionDictionary objectForKey:PRODUCT_NAME] objectForKey:@"version"]; 89 | 90 | bail: 91 | 92 | return latestVersion; 93 | } 94 | 95 | @end 96 | -------------------------------------------------------------------------------- /shared/UpdateWindow.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 58 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /shared/UpdateWindowController.h: -------------------------------------------------------------------------------- 1 | // 2 | // UpdateWindowController.m 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | @import Cocoa; 10 | 11 | @interface UpdateWindowController : NSWindowController 12 | { 13 | 14 | } 15 | 16 | /* PROPERTIES */ 17 | 18 | //version label/string 19 | @property(weak)IBOutlet NSTextField *infoLabel; 20 | 21 | //action button 22 | @property(weak)IBOutlet NSButton *actionButton; 23 | 24 | //label string 25 | @property(nonatomic, retain)NSString* infoLabelString; 26 | 27 | //first button ('update check') 28 | @property(weak)IBOutlet NSView *firstButton; 29 | 30 | //button title 31 | @property(nonatomic, retain)NSString* actionButtonTitle; 32 | 33 | //overlay view 34 | @property(weak)IBOutlet NSView *overlayView; 35 | 36 | //spinner 37 | @property(weak)IBOutlet NSProgressIndicator *progressIndicator; 38 | 39 | /* METHODS */ 40 | 41 | //save the main label's & button title's text 42 | -(void)configure:(NSString*)label buttonTitle:(NSString*)buttonTitle; 43 | 44 | //invoked when user clicks button 45 | // ->trigger action such as opening product website, updating, etc 46 | -(IBAction)buttonHandler:(id)sender; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /shared/UpdateWindowController.m: -------------------------------------------------------------------------------- 1 | // 2 | // UpdateWindowController.m 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #import "consts.h" 10 | #import "utilities.h" 11 | #import "AppDelegate.h" 12 | #import "UpdateWindowController.h" 13 | 14 | @implementation UpdateWindowController 15 | 16 | @synthesize infoLabel; 17 | @synthesize overlayView; 18 | @synthesize firstButton; 19 | @synthesize actionButton; 20 | @synthesize infoLabelString; 21 | @synthesize actionButtonTitle; 22 | @synthesize progressIndicator; 23 | 24 | //automatically called when nib is loaded 25 | // ->center window 26 | -(void)awakeFromNib 27 | { 28 | //center 29 | [self.window center]; 30 | 31 | return; 32 | } 33 | 34 | //automatically invoked when window is loaded 35 | -(void)windowDidLoad 36 | { 37 | //super 38 | [super windowDidLoad]; 39 | 40 | //not in dark mode? 41 | // make window white 42 | if(YES != isDarkMode()) 43 | { 44 | //make white 45 | self.window.backgroundColor = NSColor.whiteColor; 46 | } 47 | 48 | //indicated title bar is tranparent (too) 49 | self.window.titlebarAppearsTransparent = YES; 50 | 51 | //set main label 52 | [self.infoLabel setStringValue:self.infoLabelString]; 53 | 54 | //set button text 55 | self.actionButton.title = self.actionButtonTitle; 56 | 57 | //hide first button when action is 'update' 58 | // ->don't need update check button ;) 59 | if(YES == [self.actionButton.title isEqualToString:@"Update"]) 60 | { 61 | //hide 62 | self.firstButton.hidden = YES; 63 | 64 | //then make action button first responder 65 | [self.window makeFirstResponder:self.actionButton]; 66 | } 67 | 68 | //make it key window 69 | [self.window makeKeyAndOrderFront:self]; 70 | 71 | //make window front 72 | [NSApp activateIgnoringOtherApps:YES]; 73 | 74 | return; 75 | } 76 | 77 | //automatically invoked when window is closing 78 | // ->make ourselves unmodal 79 | -(void)windowWillClose:(NSNotification *)notification 80 | { 81 | //make un-modal 82 | [[NSApplication sharedApplication] stopModal]; 83 | 84 | return; 85 | } 86 | 87 | //save the main label's & button title's text 88 | // ->invoked before window is loaded (and thus buttons, etc are nil) 89 | -(void)configure:(NSString*)label buttonTitle:(NSString*)buttonTitle 90 | { 91 | //save label's string 92 | self.infoLabelString = label; 93 | 94 | //save button's title 95 | self.actionButtonTitle = buttonTitle; 96 | 97 | return; 98 | } 99 | 100 | //invoked when user clicks button 101 | // trigger action such as opening product website, updating, etc 102 | -(IBAction)buttonHandler:(id)sender 103 | { 104 | //handle 'update' / 'more info', etc 105 | // open product webpage, if they *didn't* click 'Close' 106 | if(YES != [((NSButton*)sender).title isEqualToString:@"Close"]) 107 | { 108 | //open URL 109 | // invokes user's default browser 110 | [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:PRODUCT_URL]]; 111 | } 112 | 113 | //always close window 114 | [[self window] close]; 115 | 116 | return; 117 | } 118 | 119 | @end 120 | -------------------------------------------------------------------------------- /shared/UserClientShared.h: -------------------------------------------------------------------------------- 1 | // 2 | // file: UserClientShared.h 3 | // project: lulu (shared) 4 | // description: dispatch selectors and data structs shared between user and kernel mode 5 | // 6 | // created by Patrick Wardle 7 | // copyright (c) 2017 Objective-See. All rights reserved. 8 | // 9 | 10 | #ifndef userClientShared_h 11 | #define userClientShared_h 12 | 13 | #include 14 | 15 | #if defined (KERNEL) 16 | extern "C" { 17 | #endif 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #if defined (KERNEL) 25 | } 26 | #endif 27 | 28 | //user client method dispatch selectors. 29 | enum dispatchSelectors { 30 | 31 | kTestUserClientEnable, 32 | kTestUserClientDisable, 33 | kTestUserClientLockdown, 34 | kTestUserClientAddRule, 35 | kTestUserClientRemoveRule, 36 | kTestUserClientMethodCount 37 | }; 38 | 39 | //type 40 | struct genericEvent_s 41 | { 42 | //type 43 | UInt32 type; 44 | }; 45 | 46 | //network out event struct 47 | struct networkOutEvent_s { 48 | 49 | //type 50 | UInt32 type; 51 | 52 | //process pid 53 | UInt32 pid; 54 | 55 | //socket type 56 | int socketType; 57 | 58 | //local socket address 59 | struct sockaddr_in6 localAddress; 60 | 61 | //remote socket address 62 | struct sockaddr_in6 remoteAddress; 63 | }; 64 | 65 | //dns response out event struct 66 | struct dnsResponseEvent_s { 67 | 68 | //type 69 | UInt32 type; 70 | 71 | //response 72 | unsigned char response[512]; 73 | }; 74 | 75 | //firewall event union 76 | // holds various structs, but max size will be 'padding' 77 | typedef union 78 | { 79 | //generic event 80 | struct genericEvent_s genericEvent; 81 | 82 | //network out event 83 | struct networkOutEvent_s networkOutEvent; 84 | 85 | //dns response event 86 | struct dnsResponseEvent_s dnsResponseEvent; 87 | 88 | //padding 89 | unsigned char padding[sizeof(UInt32) + 512]; 90 | 91 | } firewallEvent; 92 | 93 | //dns header struct 94 | // from: http://www.nersc.gov/~scottc/software/snort/dns_head.html 95 | #pragma pack(push,1) 96 | struct dnsHeader { 97 | unsigned short id; 98 | unsigned short flags; 99 | unsigned short qdcount; 100 | unsigned short ancount; 101 | unsigned short nscount; 102 | unsigned short arcount; 103 | }; 104 | #pragma pack(pop) 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /shared/consts.h: -------------------------------------------------------------------------------- 1 | // 2 | // consts.h 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #ifndef consts_h 10 | #define consts_h 11 | 12 | //install cmd 13 | #define CMD_INSTALL @"-install" 14 | 15 | //uninstall cmd 16 | #define CMD_UNINSTALL @"-uninstall" 17 | 18 | //button install 19 | #define UI_INSTALL @"Install" 20 | 21 | //button uninstall 22 | #define UI_UNINSTALL @"Uninstall" 23 | 24 | //button title 25 | #define UI_CLOSE @"Close" 26 | 27 | //button title 28 | #define UI_NEXT @"Next »" 29 | 30 | //button title 31 | #define UI_NO @"No" 32 | 33 | //button title 34 | #define UI_YES @"Yes!" 35 | 36 | //flag to uninstall 37 | #define ACTION_UNINSTALL 0 38 | 39 | //flag to install 40 | #define ACTION_INSTALL 1 41 | 42 | //flag for partial uninstall 43 | #define UNINSTALL_PARTIAL 0 44 | 45 | //flag for full uninstall 46 | #define UNINSTALL_FULL 1 47 | 48 | //system applications 49 | #define SYSTEM_APPS_FOLDER @"/Applications" 50 | 51 | //user applications 52 | #define USER_APPS_FOLDER @"~/Applications" 53 | 54 | //path to killall 55 | #define KILL @"/usr/bin/killall" 56 | 57 | //path to xattr 58 | #define XATTR @"/usr/bin/xattr" 59 | 60 | //suite name 61 | // for shared preferences 62 | #define SUITE_NAME @"com.objective-see.reikey.group" 63 | 64 | //main app bundle id 65 | #define APP_BUNDLE_ID @"com.objective-see.reikey" 66 | 67 | //login item bundle id 68 | #define LOGIN_ITEM_BUNDLE_ID @"com.objective-see.reikey.helper" 69 | 70 | //showed splash screen 71 | #define SHOWED_SPLASH @"showedSplash" 72 | 73 | //showed status bar popup 74 | #define SHOWED_POPUP @"showedPopup" 75 | 76 | //muted items (paths) 77 | #define MUTED_ITEMS @"mutedItems" 78 | 79 | //prefs changed notification 80 | #define NOTIFICATION_PREFS_CHANGED @"com.objective-see.reikey.preferences" 81 | 82 | //patreon url 83 | #define PATREON_URL @"https://www.patreon.com/bePatron?c=701171" 84 | 85 | //sentry crash reporting URL 86 | #define CRASH_REPORTING_URL @"https://cc60a04750ff4daeaa2d0d9e090e21c7@sentry.io/1360726" 87 | 88 | //signing auth 89 | #define SIGNING_AUTH @"Developer ID Application: Objective-See, LLC (VBG97UB4TA)" 90 | 91 | //product url 92 | #define PRODUCT_URL @"https://objective-see.com/products/reikey.html" 93 | 94 | //product version url 95 | #define PRODUCT_VERSIONS_URL @"https://objective-see.com/products.json" 96 | 97 | //error(s) url 98 | #define ERRORS_URL @"https://objective-see.com/errors.html" 99 | 100 | //support us button tag 101 | #define BUTTON_SUPPORT_US 100 102 | 103 | //more info button tag 104 | #define BUTTON_MORE_INFO 101 105 | 106 | //login item name 107 | #define LOGIN_ITEM_NAME @"ReiKey Helper" 108 | 109 | //prefs 110 | // disabled status 111 | #define PREF_IS_DISABLED @"disabled" 112 | 113 | //prefs 114 | // start at login 115 | #define PREF_START_AT_LOGIN @"startAtLogin" 116 | 117 | //prefs 118 | // run with icon 119 | #define PREF_RUN_WITH_ICON @"runWithIcon" 120 | 121 | //prefs 122 | // ignore apple binaries 123 | #define PREF_IGNORE_APPLE_BINS @"ignoreAppleBins" 124 | 125 | //pref 126 | // disable update check 127 | #define PREF_NO_UPDATES @"noUpdates" 128 | 129 | //app name 130 | #define APP_NAME @"ReiKey.app" 131 | 132 | //cmdline flag 133 | #define CMDLINE_FLAG_SCAN @"-scan" 134 | 135 | //all procs 136 | #define GLOBAL_EVENT_TAP @"All processes" 137 | 138 | //tap id 139 | #define TAP_ID @"tapID" 140 | 141 | //tap options 142 | #define TAP_OPTIONS @"tapOptions" 143 | 144 | //tap source path 145 | #define TAP_SOURCE_PATH @"sourcePath" 146 | 147 | //tap source pid 148 | #define TAP_SOURCE_PID @"sourcePID" 149 | 150 | //tap destination path 151 | #define TAP_DESTINATION_PATH @"destinationPath" 152 | 153 | //tap destination pid 154 | #define TAP_DESTINATION_PID @"destinationPID" 155 | 156 | //product name 157 | // ...for version check 158 | #define PRODUCT_NAME @"ReiKey" 159 | 160 | //product version url 161 | #define PRODUCT_VERSIONS_URL @"https://objective-see.com/products.json" 162 | 163 | //update error 164 | #define UPDATE_ERROR -1 165 | 166 | //update no new version 167 | #define UPDATE_NOTHING_NEW 0 168 | 169 | //update new version 170 | #define UPDATE_NEW_VERSION 1 171 | 172 | //signers 173 | enum Signer{None, Apple, AppStore, DevID, AdHoc}; 174 | 175 | //signature status 176 | #define KEY_SIGNATURE_STATUS @"signatureStatus" 177 | 178 | //signer 179 | #define KEY_SIGNATURE_SIGNER @"signatureSigner" 180 | 181 | //signing auths 182 | #define KEY_SIGNATURE_AUTHORITIES @"signatureAuthorities" 183 | 184 | //code signing id 185 | #define KEY_SIGNATURE_IDENTIFIER @"signatureIdentifier" 186 | 187 | //entitlements 188 | #define KEY_SIGNATURE_ENTITLEMENTS @"signatureEntitlements" 189 | 190 | //dismiss alert 191 | #define ALERT_DISMISS 0 192 | 193 | //details alert 194 | #define ALERT_DETAILS 1 195 | 196 | #endif /* const_h */ 197 | -------------------------------------------------------------------------------- /shared/images/objectiveSeeLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/shared/images/objectiveSeeLogo.png -------------------------------------------------------------------------------- /shared/images/objectiveSeeText.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/objective-see/ReiKey/83ceb8fca9e08dbc4e92a43ddf6ecd39c36bb37f/shared/images/objectiveSeeText.png -------------------------------------------------------------------------------- /shared/logging.h: -------------------------------------------------------------------------------- 1 | // 2 | // logging.h 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #ifndef Logging_h 10 | #define Logging_h 11 | 12 | #import 13 | 14 | @import Cocoa; 15 | @import Foundation; 16 | 17 | //log a msg to syslog 18 | // also disk, if error 19 | void logMsg(int level, NSString* msg); 20 | 21 | //prep/open log file 22 | BOOL initLogging(NSString* logPath); 23 | 24 | //get path to log file 25 | NSString* logFilePath(void); 26 | 27 | //de-init logging 28 | void deinitLogging(void); 29 | 30 | //log to file 31 | void log2File(NSString* msg); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /shared/logging.m: -------------------------------------------------------------------------------- 1 | // 2 | // logging.m 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #import "consts.h" 10 | #import "logging.h" 11 | 12 | //log a msg 13 | // default to syslog, and if an err msg, to disk 14 | void logMsg(int level, NSString* msg) 15 | { 16 | //log prefix 17 | NSMutableString* logPrefix = nil; 18 | 19 | //alloc/init 20 | // always start w/ name + pid 21 | logPrefix = [NSMutableString stringWithFormat:@"ReiKey(%d)", getpid()]; 22 | 23 | //if its error, add error to prefix 24 | if(LOG_ERR == level) 25 | { 26 | //add 27 | [logPrefix appendString:@" ERROR"]; 28 | } 29 | 30 | //debug mode logic 31 | #ifdef DEBUG 32 | 33 | //in debug mode promote debug msgs to LOG_NOTICE 34 | // OS X only shows LOG_NOTICE and above 35 | if(LOG_DEBUG == level) 36 | { 37 | //promote 38 | level = LOG_NOTICE; 39 | } 40 | 41 | #endif 42 | 43 | //dump to syslog? 44 | // function can be invoked just to log to file... 45 | if(0 != level) 46 | { 47 | //syslog 48 | syslog(level, "%s: %s", [logPrefix UTF8String], [msg UTF8String]); 49 | } 50 | 51 | return; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /shared/patrons.txt: -------------------------------------------------------------------------------- 1 | Patrons (2^6+): 2 | Christian Blümlein, Brock Gunter-Smith, Jan Koum 3 | 4 | Friends of Objective-See: 5 | Airo, SmugMug, Guardian Mobile Firewall, SecureMac, iVerify, Halo Privacy -------------------------------------------------------------------------------- /shared/signing.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: Signing.h 3 | // Project: Proc Info 4 | // 5 | // Created by: Patrick Wardle 6 | // Copyright: 2017 Objective-See 7 | // License: Creative Commons Attribution-NonCommercial 4.0 International License 8 | // 9 | 10 | #ifndef Signing_h 11 | #define Signing_h 12 | 13 | #import 14 | #import 15 | 16 | /* FUNCTIONS */ 17 | 18 | //get the signing info of a item 19 | // pid specified: extract dynamic code signing info 20 | // path specified: generate static code signing info 21 | NSMutableDictionary* extractSigningInfo(pid_t pid, NSString* path, SecCSFlags flags); 22 | 23 | //determine who signed item 24 | NSNumber* extractSigner(SecStaticCodeRef code, SecCSFlags flags, BOOL isDynamic); 25 | 26 | //validate a requirement 27 | OSStatus validateRequirement(SecStaticCodeRef code, SecRequirementRef requirement, SecCSFlags flags, BOOL isDynamic); 28 | 29 | //extract (names) of signing auths 30 | NSMutableArray* extractSigningAuths(NSDictionary* signingDetails); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /shared/signing.m: -------------------------------------------------------------------------------- 1 | // 2 | // File: Signing.m 3 | // Project: Proc Info 4 | // 5 | // Created by: Patrick Wardle 6 | // Copyright: 2017 Objective-See 7 | // License: Creative Commons Attribution-NonCommercial 4.0 International License 8 | // 9 | 10 | #import "consts.h" 11 | #import "signing.h" 12 | #import "utilities.h" 13 | 14 | #import 15 | #import 16 | 17 | //get the signing info of a item 18 | // pid specified: extract dynamic code signing info 19 | // path specified: generate static code signing info 20 | NSMutableDictionary* extractSigningInfo(pid_t pid, NSString* path, SecCSFlags flags) 21 | { 22 | //info dictionary 23 | NSMutableDictionary* signingInfo = nil; 24 | 25 | //status 26 | OSStatus status = !errSecSuccess; 27 | 28 | //static code ref 29 | SecStaticCodeRef staticCode = NULL; 30 | 31 | //dynamic code ref 32 | SecCodeRef dynamicCode = NULL; 33 | 34 | //signing details 35 | CFDictionaryRef signingDetails = NULL; 36 | 37 | //signing authorities 38 | NSMutableArray* signingAuths = nil; 39 | 40 | //init signing status 41 | signingInfo = [NSMutableDictionary dictionary]; 42 | 43 | //dynamic code checks 44 | // no path, dynamic check via pid 45 | if(nil == path) 46 | { 47 | //generate dynamic code ref via pid 48 | status = SecCodeCopyGuestWithAttributes(NULL, (__bridge CFDictionaryRef _Nullable)(@{(__bridge NSString *)kSecGuestAttributePid : [NSNumber numberWithInt:pid]}), kSecCSDefaultFlags, &dynamicCode); 49 | if(errSecSuccess != status) 50 | { 51 | //set error 52 | signingInfo[KEY_SIGNATURE_STATUS] = [NSNumber numberWithInt:status]; 53 | 54 | //bail 55 | goto bail; 56 | } 57 | 58 | //validate code 59 | status = SecCodeCheckValidity(dynamicCode, flags, NULL); 60 | if(errSecSuccess != status) 61 | { 62 | //set error 63 | signingInfo[KEY_SIGNATURE_STATUS] = [NSNumber numberWithInt:status]; 64 | 65 | //bail 66 | goto bail; 67 | } 68 | 69 | //happily signed 70 | signingInfo[KEY_SIGNATURE_STATUS] = [NSNumber numberWithInt:errSecSuccess]; 71 | 72 | //determine signer 73 | // apple, app store, dev id, adhoc, etc... 74 | signingInfo[KEY_SIGNATURE_SIGNER] = extractSigner(dynamicCode, flags, YES); 75 | 76 | //extract signing info 77 | status = SecCodeCopySigningInformation(dynamicCode, kSecCSSigningInformation, &signingDetails); 78 | if(errSecSuccess != status) 79 | { 80 | //bail 81 | goto bail; 82 | } 83 | } 84 | 85 | //static code checks 86 | else 87 | { 88 | //create static code ref via path 89 | status = SecStaticCodeCreateWithPath((__bridge CFURLRef)([NSURL fileURLWithPath:path]), kSecCSDefaultFlags, &staticCode); 90 | if(errSecSuccess != status) 91 | { 92 | //set error 93 | signingInfo[KEY_SIGNATURE_STATUS] = [NSNumber numberWithInt:status]; 94 | 95 | //bail 96 | goto bail; 97 | } 98 | 99 | //check signature 100 | status = SecStaticCodeCheckValidity(staticCode, flags, NULL); 101 | if(errSecSuccess != status) 102 | { 103 | //set error 104 | signingInfo[KEY_SIGNATURE_STATUS] = [NSNumber numberWithInt:status]; 105 | 106 | //bail 107 | goto bail; 108 | } 109 | 110 | //happily signed 111 | signingInfo[KEY_SIGNATURE_STATUS] = [NSNumber numberWithInt:errSecSuccess]; 112 | 113 | //determine signer 114 | // apple, app store, dev id, adhoc, etc... 115 | signingInfo[KEY_SIGNATURE_SIGNER] = extractSigner(staticCode, flags, NO); 116 | 117 | //extract signing info 118 | status = SecCodeCopySigningInformation(staticCode, kSecCSSigningInformation, &signingDetails); 119 | if(errSecSuccess != status) 120 | { 121 | //bail 122 | goto bail; 123 | } 124 | } 125 | 126 | //extract code signing id 127 | if(nil != [(__bridge NSDictionary*)signingDetails objectForKey:(__bridge NSString*)kSecCodeInfoIdentifier]) 128 | { 129 | //extract/save 130 | signingInfo[KEY_SIGNATURE_IDENTIFIER] = [(__bridge NSDictionary*)signingDetails objectForKey:(__bridge NSString*)kSecCodeInfoIdentifier]; 131 | } 132 | 133 | //extract entitlements 134 | if(nil != [(__bridge NSDictionary*)signingDetails objectForKey:(__bridge NSString*)kSecCodeInfoEntitlementsDict]) 135 | { 136 | //extract/save 137 | signingInfo[KEY_SIGNATURE_ENTITLEMENTS] = [(__bridge NSDictionary*)signingDetails objectForKey:(__bridge NSString*)kSecCodeInfoEntitlementsDict]; 138 | } 139 | 140 | //extract signing authorities 141 | signingAuths = extractSigningAuths((__bridge NSDictionary *)(signingDetails)); 142 | if(0 != signingAuths.count) 143 | { 144 | //save 145 | signingInfo[KEY_SIGNATURE_AUTHORITIES] = signingAuths; 146 | } 147 | 148 | bail: 149 | 150 | //free signing info 151 | if(NULL != signingDetails) 152 | { 153 | //free 154 | CFRelease(signingDetails); 155 | 156 | //unset 157 | signingDetails = NULL; 158 | } 159 | 160 | //free dynamic code 161 | if(NULL != dynamicCode) 162 | { 163 | //free 164 | CFRelease(dynamicCode); 165 | 166 | //unset 167 | dynamicCode = NULL; 168 | } 169 | 170 | //free static code 171 | if(NULL != staticCode) 172 | { 173 | //free 174 | CFRelease(staticCode); 175 | 176 | //unset 177 | staticCode = NULL; 178 | } 179 | 180 | return signingInfo; 181 | } 182 | 183 | //determine who signed item 184 | NSNumber* extractSigner(SecStaticCodeRef code, SecCSFlags flags, BOOL isDynamic) 185 | { 186 | //result 187 | NSNumber* signer = nil; 188 | 189 | //"anchor apple" 190 | static SecRequirementRef isApple = nil; 191 | 192 | //"anchor apple generic" 193 | static SecRequirementRef isDevID = nil; 194 | 195 | //"anchor apple generic and certificate leaf [subject.CN] = \"Apple Mac OS Application Signing\"" 196 | static SecRequirementRef isAppStore = nil; 197 | 198 | //token 199 | static dispatch_once_t onceToken = 0; 200 | 201 | //only once 202 | // init requirements 203 | dispatch_once(&onceToken, ^{ 204 | 205 | //init apple signing requirement 206 | SecRequirementCreateWithString(CFSTR("anchor apple"), kSecCSDefaultFlags, &isApple); 207 | 208 | //init dev id signing requirement 209 | SecRequirementCreateWithString(CFSTR("anchor apple generic"), kSecCSDefaultFlags, &isDevID); 210 | 211 | //init app store signing requirement 212 | SecRequirementCreateWithString(CFSTR("anchor apple generic and certificate leaf [subject.CN] = \"Apple Mac OS Application Signing\""), kSecCSDefaultFlags, &isAppStore); 213 | }); 214 | 215 | //check 1: "is apple" (proper) 216 | if(errSecSuccess == validateRequirement(code, isApple, flags, isDynamic)) 217 | { 218 | //set signer to apple 219 | signer = [NSNumber numberWithInt:Apple]; 220 | } 221 | 222 | //check 2: "is app store" 223 | // note: this is more specific than dev id, so do it first 224 | else if(errSecSuccess == validateRequirement(code, isAppStore, flags, isDynamic)) 225 | { 226 | //set signer to app store 227 | signer = [NSNumber numberWithInt:AppStore]; 228 | } 229 | 230 | //check 3: "is dev id" 231 | else if(errSecSuccess == validateRequirement(code, isDevID, flags, isDynamic)) 232 | { 233 | //set signer to dev id 234 | signer = [NSNumber numberWithInt:DevID]; 235 | } 236 | 237 | //otherwise 238 | // has to be adhoc? 239 | else 240 | { 241 | //set signer to ad hoc 242 | signer = [NSNumber numberWithInt:AdHoc]; 243 | } 244 | 245 | return signer; 246 | } 247 | 248 | //validate a requirement 249 | OSStatus validateRequirement(SecStaticCodeRef code, SecRequirementRef requirement, SecCSFlags flags, BOOL isDynamic) 250 | { 251 | //result 252 | OSStatus result = -1; 253 | 254 | //dynamic check? 255 | if(YES == isDynamic) 256 | { 257 | //validate dynamically 258 | result = SecCodeCheckValidity((SecCodeRef)code, flags, requirement); 259 | } 260 | //static check 261 | else 262 | { 263 | //validate statically 264 | result = SecStaticCodeCheckValidity(code, flags, requirement); 265 | } 266 | 267 | return result; 268 | } 269 | 270 | //extract (names) of signing auths 271 | NSMutableArray* extractSigningAuths(NSDictionary* signingDetails) 272 | { 273 | //signing auths 274 | NSMutableArray* authorities = nil; 275 | 276 | //cert chain 277 | NSArray* certificateChain = nil; 278 | 279 | //index 280 | NSUInteger index = 0; 281 | 282 | //cert 283 | SecCertificateRef certificate = NULL; 284 | 285 | //common name on chert 286 | CFStringRef commonName = NULL; 287 | 288 | //init array for certificate names 289 | authorities = [NSMutableArray array]; 290 | 291 | //get cert chain 292 | certificateChain = [signingDetails objectForKey:(__bridge NSString*)kSecCodeInfoCertificates]; 293 | if(0 == certificateChain.count) 294 | { 295 | //no certs 296 | goto bail; 297 | } 298 | 299 | //extract/save name of all certs 300 | for(index = 0; index < certificateChain.count; index++) 301 | { 302 | //reset 303 | commonName = NULL; 304 | 305 | //extract cert 306 | certificate = (__bridge SecCertificateRef)([certificateChain objectAtIndex:index]); 307 | 308 | //get common name 309 | if( (errSecSuccess == SecCertificateCopyCommonName(certificate, &commonName)) && 310 | (NULL != commonName) ) 311 | { 312 | //save 313 | [authorities addObject:(__bridge id _Nonnull)(commonName)]; 314 | 315 | //release 316 | CFRelease(commonName); 317 | } 318 | } 319 | 320 | bail: 321 | 322 | return authorities; 323 | } 324 | -------------------------------------------------------------------------------- /shared/utilities.h: -------------------------------------------------------------------------------- 1 | // 2 | // utilities.h 3 | // ReiKey 4 | // 5 | // Created by Patrick Wardle on 12/24/18. 6 | // Copyright © 2018 Objective-See. All rights reserved. 7 | // 8 | 9 | #ifndef utilities_h 10 | #define utilities_h 11 | 12 | #import 13 | #import 14 | 15 | /* FUNCTIONS */ 16 | 17 | //disable std err 18 | void disableSTDERR(void); 19 | 20 | //init crash reporting 21 | void initCrashReporting(void); 22 | 23 | //get app's version 24 | // extracted from Info.plist 25 | NSString* getAppVersion(void); 26 | 27 | //determine if installed 28 | // simply checks if application exists in /Applications or ~/Applications 29 | BOOL isInstalled(void); 30 | 31 | //path to installed app 32 | // if admin: /Applications/ 33 | // if user: ~/Applications/ 34 | NSString* appPath(void); 35 | 36 | //given a path to binary 37 | // parse it back up to find app's bundle 38 | NSBundle* findAppBundle(NSString* binaryPath); 39 | 40 | //get process's path 41 | NSString* getProcessPath(pid_t pid); 42 | 43 | //path to login item 44 | NSString* loginItemPath(void); 45 | 46 | //get process name 47 | // either via app bundle, or path 48 | NSString* getProcessName(NSString* path); 49 | 50 | //given a process path and user 51 | // return array of all matching pids 52 | NSMutableArray* getProcessIDs(NSString* processPath, int userID); 53 | 54 | //given a pid, get its parent (ppid) 55 | pid_t getParentID(int pid); 56 | 57 | //enable/disable a menu 58 | void toggleMenu(NSMenu* menu, BOOL shouldEnable); 59 | 60 | //toggle login item 61 | // either add (install) or remove (uninstall) 62 | BOOL toggleLoginItem(NSURL* loginItem, int toggleFlag); 63 | 64 | //add a login item 65 | BOOL addLoginItem(NSURL* loginItem); 66 | 67 | //remove a login item 68 | BOOL removeLoginItem(NSURL* loginItem); 69 | 70 | //start app 71 | BOOL startApplication(NSURL* appPath, NSUInteger launchOptions); 72 | 73 | //get an icon for a process 74 | // for apps, this will be app's icon, otherwise just a standard system one 75 | NSImage* getIconForProcess(NSString* path); 76 | 77 | //wait until a window is non nil 78 | // then make it modal 79 | void makeModal(NSWindowController* windowController); 80 | 81 | //find a process by name 82 | pid_t findProcess(NSString* processName); 83 | 84 | //exec a process 85 | BOOL execTask(NSString* binaryPath, NSArray* arguments, BOOL wait); 86 | 87 | //extract a DNS name 88 | NSMutableString* extractDNSName(unsigned char* start, unsigned char* chunk, unsigned char* end); 89 | 90 | //loads a framework 91 | // note: assumes is in 'Framework' dir 92 | NSBundle* loadFramework(NSString* name); 93 | 94 | //restart 95 | void restart(void); 96 | 97 | //bring an app to foreground 98 | // based on: https://stackoverflow.com/questions/7596643/when-calling-transformprocesstype-the-app-menu-doesnt-show-up 99 | void foregroundApp(void); 100 | 101 | //send an app to the background 102 | void backgroundApp(void); 103 | 104 | //transform app state 105 | OSStatus transformApp(ProcessApplicationTransformState newState); 106 | 107 | //check if (full) dark mode 108 | // meaning, Mojave+ and dark mode enabled 109 | BOOL isDarkMode(void); 110 | 111 | //check if process is alive 112 | BOOL isProcessAlive(pid_t processID); 113 | 114 | //prettify JSON 115 | NSString* prettifyJSON(NSString* output); 116 | 117 | #endif 118 | --------------------------------------------------------------------------------