Handle GateKeeper and write permissions in the auto updater
This commit is contained in:
parent
3c4bfd2a1b
commit
004c20d8e2
@ -5,6 +5,7 @@
|
|||||||
#import <Carbon/Carbon.h>
|
#import <Carbon/Carbon.h>
|
||||||
#import <JoyKit/JoyKit.h>
|
#import <JoyKit/JoyKit.h>
|
||||||
#import <WebKit/WebKit.h>
|
#import <WebKit/WebKit.h>
|
||||||
|
#import <mach-o/dyld.h>
|
||||||
|
|
||||||
#define UPDATE_SERVER "https://sameboy.github.io"
|
#define UPDATE_SERVER "https://sameboy.github.io"
|
||||||
|
|
||||||
@ -31,6 +32,7 @@ static uint32_t color_to_int(NSColor *color)
|
|||||||
UPDATE_FAILED,
|
UPDATE_FAILED,
|
||||||
} _updateState;
|
} _updateState;
|
||||||
NSString *_downloadDirectory;
|
NSString *_downloadDirectory;
|
||||||
|
AuthorizationRef _auth;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) applicationDidFinishLaunching:(NSNotification *)notification
|
- (void) applicationDidFinishLaunching:(NSNotification *)notification
|
||||||
@ -366,8 +368,55 @@ static uint32_t color_to_int(NSColor *color)
|
|||||||
[self.updateWindow performClose:sender];
|
[self.updateWindow performClose:sender];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (bool)executePath:(NSString *)path withArguments:(NSArray <NSString *> *)arguments
|
||||||
|
{
|
||||||
|
if (!_auth) {
|
||||||
|
NSTask *task = [[NSTask alloc] init];
|
||||||
|
task.launchPath = path;
|
||||||
|
task.arguments = arguments;
|
||||||
|
[task launch];
|
||||||
|
[task waitUntilExit];
|
||||||
|
return task.terminationStatus == 0 && task.terminationReason == NSTaskTerminationReasonExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *argv[arguments.count + 1];
|
||||||
|
argv[arguments.count] = NULL;
|
||||||
|
for (unsigned i = 0; i < arguments.count; i++) {
|
||||||
|
argv[i] = (char *)arguments[i].UTF8String;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AuthorizationExecuteWithPrivileges(_auth, path.UTF8String, kAuthorizationFlagDefaults, argv, NULL) == errAuthorizationSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)deauthorize
|
||||||
|
{
|
||||||
|
if (_auth) {
|
||||||
|
AuthorizationFree(_auth, kAuthorizationFlagDefaults);
|
||||||
|
_auth = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (IBAction)installUpdate:(id)sender
|
- (IBAction)installUpdate:(id)sender
|
||||||
{
|
{
|
||||||
|
bool needsAuthorization = false;
|
||||||
|
if ([self executePath:@"/usr/sbin/spctl" withArguments:@[@"--status"]]) { // Succeeds when GateKeeper is on
|
||||||
|
// GateKeeper is on, we need to --add ourselves as root, else we might get a GateKeeper crash
|
||||||
|
needsAuthorization = true;
|
||||||
|
}
|
||||||
|
else if (access(_dyld_get_image_name(0), W_OK)) {
|
||||||
|
// We don't have write access, so we need authorization to update as root
|
||||||
|
needsAuthorization = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needsAuthorization && !_auth) {
|
||||||
|
AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagPreAuthorize | kAuthorizationFlagInteractionAllowed, &_auth);
|
||||||
|
// Make sure we can modify the bundle
|
||||||
|
if (![self executePath:@"/usr/sbin/chown" withArguments:@[@"-R", [NSString stringWithFormat:@"%d:%d", getuid(), getgid()], [NSBundle mainBundle].bundlePath]]) {
|
||||||
|
[self deauthorize];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[self.updateProgressSpinner startAnimation:nil];
|
[self.updateProgressSpinner startAnimation:nil];
|
||||||
self.updateProgressButton.title = @"Cancel";
|
self.updateProgressButton.title = @"Cancel";
|
||||||
self.updateProgressButton.enabled = true;
|
self.updateProgressButton.enabled = true;
|
||||||
@ -386,8 +435,8 @@ static uint32_t color_to_int(NSColor *color)
|
|||||||
appropriateForURL:[[NSBundle mainBundle] bundleURL]
|
appropriateForURL:[[NSBundle mainBundle] bundleURL]
|
||||||
create:true
|
create:true
|
||||||
error:nil] path];
|
error:nil] path];
|
||||||
NSTask *unzipTask;
|
|
||||||
if (!_downloadDirectory) {
|
if (!_downloadDirectory) {
|
||||||
|
[self deauthorize];
|
||||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||||
self.updateProgressButton.enabled = false;
|
self.updateProgressButton.enabled = false;
|
||||||
self.updateProgressLabel.stringValue = @"Failed to extract update.";
|
self.updateProgressLabel.stringValue = @"Failed to extract update.";
|
||||||
@ -399,12 +448,14 @@ static uint32_t color_to_int(NSColor *color)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NSTask *unzipTask;
|
||||||
unzipTask = [[NSTask alloc] init];
|
unzipTask = [[NSTask alloc] init];
|
||||||
unzipTask.launchPath = @"/usr/bin/unzip";
|
unzipTask.launchPath = @"/usr/bin/unzip";
|
||||||
unzipTask.arguments = @[location.path, @"-d", _downloadDirectory];
|
unzipTask.arguments = @[location.path, @"-d", _downloadDirectory];
|
||||||
[unzipTask launch];
|
[unzipTask launch];
|
||||||
[unzipTask waitUntilExit];
|
[unzipTask waitUntilExit];
|
||||||
if (unzipTask.terminationStatus != 0 || unzipTask.terminationReason != NSTaskTerminationReasonExit) {
|
if (unzipTask.terminationStatus != 0 || unzipTask.terminationReason != NSTaskTerminationReasonExit) {
|
||||||
|
[self deauthorize];
|
||||||
[[NSFileManager defaultManager] removeItemAtPath:_downloadDirectory error:nil];
|
[[NSFileManager defaultManager] removeItemAtPath:_downloadDirectory error:nil];
|
||||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||||
self.updateProgressButton.enabled = false;
|
self.updateProgressButton.enabled = false;
|
||||||
@ -449,6 +500,7 @@ static uint32_t color_to_int(NSColor *color)
|
|||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
[[NSFileManager defaultManager] moveItemAtPath:contentsPath toPath:contentsTempPath error:&error];
|
[[NSFileManager defaultManager] moveItemAtPath:contentsPath toPath:contentsTempPath error:&error];
|
||||||
if (error) {
|
if (error) {
|
||||||
|
[self deauthorize];
|
||||||
[[NSFileManager defaultManager] removeItemAtPath:_downloadDirectory error:nil];
|
[[NSFileManager defaultManager] removeItemAtPath:_downloadDirectory error:nil];
|
||||||
_downloadDirectory = nil;
|
_downloadDirectory = nil;
|
||||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||||
@ -463,6 +515,7 @@ static uint32_t color_to_int(NSColor *color)
|
|||||||
}
|
}
|
||||||
[[NSFileManager defaultManager] moveItemAtPath:updateContentsPath toPath:contentsPath error:&error];
|
[[NSFileManager defaultManager] moveItemAtPath:updateContentsPath toPath:contentsPath error:&error];
|
||||||
if (error) {
|
if (error) {
|
||||||
|
[self deauthorize];
|
||||||
[[NSFileManager defaultManager] moveItemAtPath:contentsTempPath toPath:contentsPath error:nil];
|
[[NSFileManager defaultManager] moveItemAtPath:contentsTempPath toPath:contentsPath error:nil];
|
||||||
[[NSFileManager defaultManager] removeItemAtPath:_downloadDirectory error:nil];
|
[[NSFileManager defaultManager] removeItemAtPath:_downloadDirectory error:nil];
|
||||||
_downloadDirectory = nil;
|
_downloadDirectory = nil;
|
||||||
|
2
Makefile
2
Makefile
@ -163,7 +163,7 @@ endif
|
|||||||
|
|
||||||
CFLAGS += -F/Library/Frameworks -mmacosx-version-min=10.9 -isysroot $(SYSROOT)
|
CFLAGS += -F/Library/Frameworks -mmacosx-version-min=10.9 -isysroot $(SYSROOT)
|
||||||
OCFLAGS += -x objective-c -fobjc-arc -Wno-deprecated-declarations -isysroot $(SYSROOT)
|
OCFLAGS += -x objective-c -fobjc-arc -Wno-deprecated-declarations -isysroot $(SYSROOT)
|
||||||
LDFLAGS += -framework AppKit -framework PreferencePanes -framework Carbon -framework QuartzCore -weak_framework Metal -weak_framework MetalKit -mmacosx-version-min=10.9 -isysroot $(SYSROOT)
|
LDFLAGS += -framework AppKit -framework PreferencePanes -framework Carbon -framework QuartzCore -framework Security -weak_framework Metal -weak_framework MetalKit -mmacosx-version-min=10.9 -isysroot $(SYSROOT)
|
||||||
GL_LDFLAGS := -framework OpenGL
|
GL_LDFLAGS := -framework OpenGL
|
||||||
endif
|
endif
|
||||||
CFLAGS += -Wno-deprecated-declarations
|
CFLAGS += -Wno-deprecated-declarations
|
||||||
|
Loading…
Reference in New Issue
Block a user