├── .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 | 
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 |
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 |
26 |
27 |
30 |
31 |
34 |
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 |
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 |
63 |
64 |
65 |
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 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
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 |
--------------------------------------------------------------------------------