started on install/uninstall logic (as root, etc)
TODOs/code cleanup
This commit is contained in:
parent
5173869913
commit
d14d33fbd1
|
@ -54,6 +54,7 @@
|
||||||
7D17C5031D658DEC0066232A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Installer/Base.lproj/MainMenu.xib; sourceTree = SOURCE_ROOT; };
|
7D17C5031D658DEC0066232A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Installer/Base.lproj/MainMenu.xib; sourceTree = SOURCE_ROOT; };
|
||||||
7D24C8651D2CDEA7009932EE /* Installer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Installer.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
7D24C8651D2CDEA7009932EE /* Installer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Installer.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
7D6245821D87C3D700870565 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = Images/Images.xcassets; sourceTree = "<group>"; };
|
7D6245821D87C3D700870565 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = Images/Images.xcassets; sourceTree = "<group>"; };
|
||||||
|
7D9A7DE91D8A8BDA0091C1AF /* main.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = main.h; path = Installer/main.h; sourceTree = SOURCE_ROOT; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
@ -117,6 +118,7 @@
|
||||||
children = (
|
children = (
|
||||||
7D17C5021D658DEC0066232A /* MainMenu.xib */,
|
7D17C5021D658DEC0066232A /* MainMenu.xib */,
|
||||||
7D17C4EC1D658DB90066232A /* Configure.m */,
|
7D17C4EC1D658DB90066232A /* Configure.m */,
|
||||||
|
7D17C4F61D658DB90066232A /* AppDelegate.h */,
|
||||||
7D17C4ED1D658DB90066232A /* AppDelegate.m */,
|
7D17C4ED1D658DB90066232A /* AppDelegate.m */,
|
||||||
7D17C4EE1D658DB90066232A /* ConfigureWindowController.m */,
|
7D17C4EE1D658DB90066232A /* ConfigureWindowController.m */,
|
||||||
7D17C4EF1D658DB90066232A /* ConfigureWindowController.xib */,
|
7D17C4EF1D658DB90066232A /* ConfigureWindowController.xib */,
|
||||||
|
@ -124,7 +126,6 @@
|
||||||
7D17C4F11D658DB90066232A /* ConfigureWindowController.h */,
|
7D17C4F11D658DB90066232A /* ConfigureWindowController.h */,
|
||||||
7D17C4F21D658DB90066232A /* ErrorWindowController.h */,
|
7D17C4F21D658DB90066232A /* ErrorWindowController.h */,
|
||||||
7D17C4F31D658DB90066232A /* ErrorWindowController.m */,
|
7D17C4F31D658DB90066232A /* ErrorWindowController.m */,
|
||||||
7D17C4F61D658DB90066232A /* AppDelegate.h */,
|
|
||||||
7D17C4F81D658DB90066232A /* ErrorWindowController.xib */,
|
7D17C4F81D658DB90066232A /* ErrorWindowController.xib */,
|
||||||
7D24C86B1D2CDEA7009932EE /* Supporting Files */,
|
7D24C86B1D2CDEA7009932EE /* Supporting Files */,
|
||||||
);
|
);
|
||||||
|
@ -137,6 +138,7 @@
|
||||||
children = (
|
children = (
|
||||||
7D17C4F51D658DB90066232A /* Info.plist */,
|
7D17C4F51D658DB90066232A /* Info.plist */,
|
||||||
7D17C4F41D658DB90066232A /* main.m */,
|
7D17C4F41D658DB90066232A /* main.m */,
|
||||||
|
7D9A7DE91D8A8BDA0091C1AF /* main.h */,
|
||||||
);
|
);
|
||||||
name = "Supporting Files";
|
name = "Supporting Files";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
|
|
@ -87,14 +87,13 @@ bail:
|
||||||
-(BOOL)isInstalled
|
-(BOOL)isInstalled
|
||||||
{
|
{
|
||||||
//check if extension exists
|
//check if extension exists
|
||||||
return [[NSFileManager defaultManager] fileExistsAtPath:[[EXTENSION_FOLDER stringByExpandingTildeInPath] stringByAppendingPathComponent:EXTENSION_NAME]];
|
return [[NSFileManager defaultManager] fileExistsAtPath:[APPS_FOLDER stringByAppendingPathComponent:APP_NAME]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//install
|
//install
|
||||||
// a) create and copy extension to ~/Library/WhatsYourSign
|
// a) copy to /Applications
|
||||||
// b) add extension: 'pluginkit -a /path/2/WhatsYourSign.appex'
|
// b) chown/chmod XPC component
|
||||||
// c) enable extension: 'pluginkit -e use -i com.objective-see.WhatsYourSignExt.FinderSync'
|
|
||||||
-(BOOL)install
|
-(BOOL)install
|
||||||
{
|
{
|
||||||
//return/status var
|
//return/status var
|
||||||
|
@ -103,75 +102,34 @@ bail:
|
||||||
//error
|
//error
|
||||||
NSError* error = nil;
|
NSError* error = nil;
|
||||||
|
|
||||||
//path to finder sync (src)
|
//path to app (src)
|
||||||
NSString* extensionPathSrc = nil;
|
NSString* appPathSrc = nil;
|
||||||
|
|
||||||
//path to finder sync (dest)
|
//path to app (dest)
|
||||||
NSString* extensionPathDest = nil;
|
NSString* appPathDest = nil;
|
||||||
|
|
||||||
//results from 'pluginkit' cmd
|
|
||||||
NSData* results = nil;
|
|
||||||
|
|
||||||
//set src path
|
//set src path
|
||||||
// ->orginally stored in installer app's /Resource bundle
|
// ->orginally stored in installer app's /Resource bundle
|
||||||
extensionPathSrc = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:EXTENSION_NAME];
|
appPathSrc = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:APP_NAME];
|
||||||
|
|
||||||
//set dest path
|
//set dest path
|
||||||
extensionPathDest = [[EXTENSION_FOLDER stringByExpandingTildeInPath] stringByAppendingPathComponent:EXTENSION_NAME];
|
appPathDest = [APPS_FOLDER stringByAppendingPathComponent:APP_NAME];
|
||||||
|
|
||||||
//check if extension folder needs to be created
|
//move app into /Applications
|
||||||
if(YES != [[NSFileManager defaultManager] fileExistsAtPath:[EXTENSION_FOLDER stringByExpandingTildeInPath]])
|
if(YES != [[NSFileManager defaultManager] copyItemAtPath:appPathSrc toPath:appPathDest error:&error])
|
||||||
{
|
|
||||||
//create it
|
|
||||||
if(YES != [[NSFileManager defaultManager] createDirectoryAtPath:[EXTENSION_FOLDER stringByExpandingTildeInPath] withIntermediateDirectories:YES attributes:nil error:&error])
|
|
||||||
{
|
{
|
||||||
//err msg
|
//err msg
|
||||||
logMsg(LOG_ERR, [NSString stringWithFormat:@"failed to create extension's directory %@ (%@)", EXTENSION_FOLDER, error]);
|
logMsg(LOG_ERR, [NSString stringWithFormat:@"failed to copy %@ -> %@ (%@)", appPathSrc, appPathDest, error]);
|
||||||
|
|
||||||
//bail
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//move extension into persistent location
|
|
||||||
// ->'/Library/WhatsYourSign/' + extension name
|
|
||||||
if(YES != [[NSFileManager defaultManager] copyItemAtPath:extensionPathSrc toPath:extensionPathDest error:&error])
|
|
||||||
{
|
|
||||||
//err msg
|
|
||||||
logMsg(LOG_ERR, [NSString stringWithFormat:@"failed to copy %@ -> %@ (%@)", extensionPathSrc, extensionPathDest, error]);
|
|
||||||
|
|
||||||
//bail
|
//bail
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
//dbg msg
|
//dbg msg
|
||||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"copied %@ -> %@", extensionPathSrc, extensionPathDest]);
|
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"copied %@ -> %@", appPathSrc, appPathDest]);
|
||||||
|
|
||||||
//install extension via 'pluginkit -a <path 2 ext>
|
//always set group/owner to root/wheel
|
||||||
results = execTask(PLUGIN_KIT, @[@"-a", extensionPathDest]);
|
setFileOwner(appPathDest, @0, @0, YES);
|
||||||
if(0 != results.length)
|
|
||||||
{
|
|
||||||
//err msg
|
|
||||||
logMsg(LOG_ERR, [NSString stringWithFormat:@"pluginkit failed to install extension (%@)", [[NSString alloc] initWithData:results encoding:NSUTF8StringEncoding]]);
|
|
||||||
|
|
||||||
//bail
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
|
|
||||||
//nap
|
|
||||||
// ->VM sometimes didn't enable
|
|
||||||
[NSThread sleepForTimeInterval:0.5];
|
|
||||||
|
|
||||||
//enable extension via 'pluginkit -e use -i <ext bundle id>
|
|
||||||
results = execTask(PLUGIN_KIT, @[@"-e", @"use", @"-i", EXTENSION_BUNDLE_ID]);
|
|
||||||
if(0 != results.length)
|
|
||||||
{
|
|
||||||
//err msg
|
|
||||||
logMsg(LOG_ERR, [NSString stringWithFormat:@"pluginkit failed to enable extension (%@)", [[NSString alloc] initWithData:results encoding:NSUTF8StringEncoding]]);
|
|
||||||
|
|
||||||
//bail
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
|
|
||||||
//no error
|
//no error
|
||||||
wasInstalled = YES;
|
wasInstalled = YES;
|
||||||
|
@ -195,23 +153,19 @@ bail:
|
||||||
BOOL bAnyErrors = NO;
|
BOOL bAnyErrors = NO;
|
||||||
|
|
||||||
//path to finder sync
|
//path to finder sync
|
||||||
NSString* extensionPath = nil;
|
NSString* appPath = nil;
|
||||||
|
|
||||||
//error
|
//error
|
||||||
NSError* error = nil;
|
NSError* error = nil;
|
||||||
|
|
||||||
//init path
|
//init path
|
||||||
extensionPath = [[EXTENSION_FOLDER stringByExpandingTildeInPath] stringByAppendingPathComponent:EXTENSION_NAME];
|
appPath = [APPS_FOLDER stringByAppendingPathComponent:APP_NAME];
|
||||||
|
|
||||||
//this always seem to 'fail' with 'remove: no plugin at <path/2/FinderSync.appex>'
|
|
||||||
// ->but yet works, so just ignore any return from this invocation of execTask()
|
|
||||||
execTask(PLUGIN_KIT, @[@"-r", extensionPath]);
|
|
||||||
|
|
||||||
//delete folder
|
//delete folder
|
||||||
if(YES != [[NSFileManager defaultManager] removeItemAtPath:[EXTENSION_FOLDER stringByExpandingTildeInPath] error:&error])
|
if(YES != [[NSFileManager defaultManager] removeItemAtPath:appPath error:&error])
|
||||||
{
|
{
|
||||||
//err msg
|
//err msg
|
||||||
logMsg(LOG_ERR, [NSString stringWithFormat:@"failed to delete extension directory %@ (%@)", EXTENSION_FOLDER, error]);
|
logMsg(LOG_ERR, [NSString stringWithFormat:@"failed to delete app %@ (%@)", appPath, error]);
|
||||||
|
|
||||||
//set flag
|
//set flag
|
||||||
bAnyErrors = YES;
|
bAnyErrors = YES;
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
//
|
||||||
|
// main.h
|
||||||
|
// Installer
|
||||||
|
//
|
||||||
|
// Created by Patrick Wardle on 9/14/16.
|
||||||
|
// Copyright © 2016 Objective-See. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef main_h
|
||||||
|
#define main_h
|
||||||
|
|
||||||
|
#import "Consts.h"
|
||||||
|
#import "Logging.h"
|
||||||
|
#import "Configure.h"
|
||||||
|
|
||||||
|
#import <syslog.h>
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
/* FUNCTION DECLARATIONS */
|
||||||
|
|
||||||
|
//spawn self as root
|
||||||
|
BOOL spawnAsRoot(const char* path2Self);
|
||||||
|
|
||||||
|
#endif /* main_h */
|
112
Installer/main.m
112
Installer/main.m
|
@ -6,8 +6,116 @@
|
||||||
// Copyright (c) 2016 Objective-See. All rights reserved.
|
// Copyright (c) 2016 Objective-See. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#import "main.h"
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
int main(int argc, const char * argv[]) {
|
int main(int argc, const char * argv[])
|
||||||
return NSApplicationMain(argc, argv);
|
{
|
||||||
|
//return var
|
||||||
|
int retVar = -1;
|
||||||
|
|
||||||
|
@autoreleasepool
|
||||||
|
{
|
||||||
|
|
||||||
|
//check for r00t
|
||||||
|
// ->then spawn self via auth exec
|
||||||
|
if(0 != geteuid())
|
||||||
|
{
|
||||||
|
//dbg msg
|
||||||
|
logMsg(LOG_DEBUG, @"non-root installer instance");
|
||||||
|
|
||||||
|
//spawn as root
|
||||||
|
if(YES != spawnAsRoot(argv[0]))
|
||||||
|
{
|
||||||
|
//err msg
|
||||||
|
logMsg(LOG_ERR, @"failed to spawn self as r00t");
|
||||||
|
|
||||||
|
//bail
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
//happy
|
||||||
|
retVar = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//otherwise
|
||||||
|
// ->just kick off app, as we're root now
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//dbg msg
|
||||||
|
logMsg(LOG_DEBUG, @"root installer instance");
|
||||||
|
|
||||||
|
//app away
|
||||||
|
retVar = NSApplicationMain(argc, (const char **)argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
}//pool
|
||||||
|
|
||||||
|
//bail
|
||||||
|
bail:
|
||||||
|
|
||||||
|
return retVar;
|
||||||
|
}
|
||||||
|
|
||||||
|
//spawn self as root
|
||||||
|
BOOL spawnAsRoot(const char* path2Self)
|
||||||
|
{
|
||||||
|
//return/status var
|
||||||
|
BOOL bRet = NO;
|
||||||
|
|
||||||
|
//authorization ref
|
||||||
|
AuthorizationRef authorizatioRef = {0};
|
||||||
|
|
||||||
|
//args
|
||||||
|
char *args[] = {NULL};
|
||||||
|
|
||||||
|
//flag creation of ref
|
||||||
|
BOOL authRefCreated = NO;
|
||||||
|
|
||||||
|
//status code
|
||||||
|
OSStatus osStatus = -1;
|
||||||
|
|
||||||
|
//create authorization ref
|
||||||
|
// ->and check
|
||||||
|
osStatus = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizatioRef);
|
||||||
|
if(errAuthorizationSuccess != osStatus)
|
||||||
|
{
|
||||||
|
//err msg
|
||||||
|
logMsg(LOG_ERR, [NSString stringWithFormat:@"AuthorizationCreate() failed with %d", osStatus]);
|
||||||
|
|
||||||
|
//bail
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
//set flag indicating auth ref was created
|
||||||
|
authRefCreated = YES;
|
||||||
|
|
||||||
|
//spawn self as r00t w/ install flag (will ask user for password)
|
||||||
|
// ->and check
|
||||||
|
osStatus = AuthorizationExecuteWithPrivileges(authorizatioRef, path2Self, 0, args, NULL);
|
||||||
|
|
||||||
|
//check
|
||||||
|
if(errAuthorizationSuccess != osStatus)
|
||||||
|
{
|
||||||
|
//err msg
|
||||||
|
logMsg(LOG_ERR, [NSString stringWithFormat:@"AuthorizationExecuteWithPrivileges() failed with %d", osStatus]);
|
||||||
|
|
||||||
|
//bail
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
//no errors
|
||||||
|
bRet = YES;
|
||||||
|
|
||||||
|
//bail
|
||||||
|
bail:
|
||||||
|
|
||||||
|
//free auth ref
|
||||||
|
if(YES == authRefCreated)
|
||||||
|
{
|
||||||
|
//free
|
||||||
|
AuthorizationFree(authorizatioRef, kAuthorizationFlagDefaults);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bRet;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
// Copyright (c) 2015 Objective-See. All rights reserved.
|
// Copyright (c) 2015 Objective-See. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
//TODO: NSLOg -> logmSg
|
|
||||||
|
|
||||||
#import "Consts.h"
|
#import "Consts.h"
|
||||||
#import "Logging.h"
|
#import "Logging.h"
|
||||||
#import "Utilities.h"
|
#import "Utilities.h"
|
||||||
|
|
|
@ -39,20 +39,17 @@
|
||||||
|
|
||||||
//check for updates
|
//check for updates
|
||||||
// ->but only when user has not disabled that feature
|
// ->but only when user has not disabled that feature
|
||||||
// TODO: change to YES
|
if(YES == [[NSUserDefaults standardUserDefaults] boolForKey:CHECK_4_UPDATES])
|
||||||
if(NO == [[NSUserDefaults standardUserDefaults] boolForKey:CHECK_4_UPDATES])
|
|
||||||
{
|
{
|
||||||
//TODO: make a min!
|
|
||||||
//after a minute
|
//after a minute
|
||||||
//->check for updates in background
|
//->check for updates in background
|
||||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 60 * NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
|
||||||
{
|
{
|
||||||
//dbg msg
|
//dbg msg
|
||||||
logMsg(LOG_DEBUG, @"checking for update");
|
logMsg(LOG_DEBUG, @"checking for update");
|
||||||
|
|
||||||
//check
|
//check
|
||||||
[self isThereAndUpdate];
|
[self isThereAndUpdate];
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -262,9 +262,6 @@ bail:
|
||||||
//TODO: ignore self!!
|
//TODO: ignore self!!
|
||||||
//Sample analysis of process 18340 written to file /tmp/OverSight_Helper_2016-09-12_211234_StAd.sample.txt
|
//Sample analysis of process 18340 written to file /tmp/OverSight_Helper_2016-09-12_211234_StAd.sample.txt
|
||||||
|
|
||||||
//save to baseline
|
|
||||||
// TODO: test that this works, esp if cnt goes down!! (facetime battery mode)
|
|
||||||
//[self.machSenders addEntriesFromDictionary:currentSenders];
|
|
||||||
//update
|
//update
|
||||||
self.machSenders = currentSenders;
|
self.machSenders = currentSenders;
|
||||||
|
|
||||||
|
|
|
@ -9,16 +9,10 @@
|
||||||
#import "Logging.h"
|
#import "Logging.h"
|
||||||
#import "Enumerator.h"
|
#import "Enumerator.h"
|
||||||
#import "OverSightXPC.h"
|
#import "OverSightXPC.h"
|
||||||
|
|
||||||
|
|
||||||
#import "../Shared/Utilities.h"
|
#import "../Shared/Utilities.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@implementation OverSightXPC
|
@implementation OverSightXPC
|
||||||
|
|
||||||
//TODO: method to set flag, that's sync'd~!?
|
|
||||||
|
|
||||||
@synthesize machSenders;
|
@synthesize machSenders;
|
||||||
@synthesize videoActive;
|
@synthesize videoActive;
|
||||||
|
|
||||||
|
|
|
@ -12,12 +12,18 @@
|
||||||
//success
|
//success
|
||||||
#define STATUS_SUCCESS 0
|
#define STATUS_SUCCESS 0
|
||||||
|
|
||||||
|
//apps folder
|
||||||
|
#define APPS_FOLDER @"/Applications"
|
||||||
|
|
||||||
|
//app name
|
||||||
|
#define APP_NAME @"OverSight.app"
|
||||||
|
|
||||||
//product url
|
//product url
|
||||||
#define PRODUCT_URL @"https://objective-see.com/products/oversight.html"
|
#define PRODUCT_URL @"https://objective-see.com/products/oversight.html"
|
||||||
|
|
||||||
//product version url
|
//product version url
|
||||||
//TODO: change back!
|
//TODO: test final/with page
|
||||||
#define PRODUCT_VERSION_URL @"https://objective-see.com/products/versions/ransomwhere.json"
|
#define PRODUCT_VERSION_URL @"https://objective-see.com/products/versions/oversight.json"
|
||||||
|
|
||||||
//frame shift
|
//frame shift
|
||||||
// ->for status msg to avoid activity indicator
|
// ->for status msg to avoid activity indicator
|
||||||
|
|
|
@ -20,6 +20,12 @@
|
||||||
// ->extracted from Info.plist
|
// ->extracted from Info.plist
|
||||||
NSString* getAppVersion();
|
NSString* getAppVersion();
|
||||||
|
|
||||||
|
//set dir's|file's group/owner
|
||||||
|
BOOL setFileOwner(NSString* path, NSNumber* groupID, NSNumber* ownerID, BOOL recursive);
|
||||||
|
|
||||||
|
//set permissions for file
|
||||||
|
void setFilePermissions(NSString* file, int permissions);
|
||||||
|
|
||||||
//exec a process and grab it's output
|
//exec a process and grab it's output
|
||||||
NSData* execTask(NSString* binaryPath, NSArray* arguments);
|
NSData* execTask(NSString* binaryPath, NSArray* arguments);
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,13 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#import "Consts.h"
|
#import "Consts.h"
|
||||||
|
#import "Logging.h"
|
||||||
#import "Utilities.h"
|
#import "Utilities.h"
|
||||||
|
|
||||||
#import <signal.h>
|
#import <signal.h>
|
||||||
#import <unistd.h>
|
#import <unistd.h>
|
||||||
#import <libproc.h>
|
#import <libproc.h>
|
||||||
|
#import <sys/stat.h>
|
||||||
#import <sys/sysctl.h>
|
#import <sys/sysctl.h>
|
||||||
#import <Security/Security.h>
|
#import <Security/Security.h>
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
@ -71,6 +73,116 @@ NSBundle* findAppBundle(NSString* binaryPath)
|
||||||
return appBundle;
|
return appBundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//set dir's|file's group/owner
|
||||||
|
BOOL setFileOwner(NSString* path, NSNumber* groupID, NSNumber* ownerID, BOOL recursive)
|
||||||
|
{
|
||||||
|
//ret var
|
||||||
|
BOOL bRet = NO;
|
||||||
|
|
||||||
|
//owner dictionary
|
||||||
|
NSDictionary* fileOwner = nil;
|
||||||
|
|
||||||
|
//sub paths
|
||||||
|
NSArray *subPaths = nil;
|
||||||
|
|
||||||
|
//full path
|
||||||
|
// ->for recursive
|
||||||
|
NSString* fullPath = nil;
|
||||||
|
|
||||||
|
//init permissions dictionary
|
||||||
|
fileOwner = @{NSFileGroupOwnerAccountID:groupID, NSFileOwnerAccountID:ownerID};
|
||||||
|
|
||||||
|
//set group/owner
|
||||||
|
if(YES != [[NSFileManager defaultManager] setAttributes:fileOwner ofItemAtPath:path error:NULL])
|
||||||
|
{
|
||||||
|
//err msg
|
||||||
|
logMsg(LOG_ERR, [NSString stringWithFormat:@"failed to set ownership for %@ (%@)", path, fileOwner]);
|
||||||
|
|
||||||
|
//bail
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
//dbg msg
|
||||||
|
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"set ownership for %@ (%@)", path, fileOwner]);
|
||||||
|
|
||||||
|
//do it recursively
|
||||||
|
if(YES == recursive)
|
||||||
|
{
|
||||||
|
//sanity check
|
||||||
|
// ->make sure root starts with '/'
|
||||||
|
if(YES != [path hasSuffix:@"/"])
|
||||||
|
{
|
||||||
|
//add '/'
|
||||||
|
path = [NSString stringWithFormat:@"%@/", path];
|
||||||
|
}
|
||||||
|
|
||||||
|
//get all subpaths
|
||||||
|
subPaths = [[NSFileManager defaultManager] subpathsAtPath:path];
|
||||||
|
for(NSString *subPath in subPaths)
|
||||||
|
{
|
||||||
|
//init full path
|
||||||
|
fullPath = [path stringByAppendingString:subPath];
|
||||||
|
|
||||||
|
//set group/owner
|
||||||
|
if(YES != [[NSFileManager defaultManager] setAttributes:fileOwner ofItemAtPath:fullPath error:NULL])
|
||||||
|
{
|
||||||
|
//err msg
|
||||||
|
logMsg(LOG_ERR, [NSString stringWithFormat:@"failed to set ownership for %@ (%@)", fullPath, fileOwner]);
|
||||||
|
|
||||||
|
//bail
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//no errors
|
||||||
|
bRet = YES;
|
||||||
|
|
||||||
|
//bail
|
||||||
|
bail:
|
||||||
|
|
||||||
|
return bRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
//set permissions for file
|
||||||
|
void setFilePermissions(NSString* file, int permissions)
|
||||||
|
{
|
||||||
|
//file permissions
|
||||||
|
NSDictionary* filePermissions = nil;
|
||||||
|
|
||||||
|
//new permissions
|
||||||
|
//newPermissions =
|
||||||
|
|
||||||
|
//get current file attributes
|
||||||
|
filePermissions = [[NSFileManager defaultManager] attributesOfItemAtPath:file error:NULL];
|
||||||
|
|
||||||
|
//int currentPermissions = [[filePermissions objectForKey:@"NSFilePosixPermissions"] intValue];
|
||||||
|
//permissions |= (S_IRSUR | S_IRGRP | S_IROTH);
|
||||||
|
// NSDictionary *newattribs = [NSDict dictionaryWithObject:[NSNumber numberWithInt:permissions]
|
||||||
|
// forKey:NSFilePosixPermissions];
|
||||||
|
//[fm setAttributes:dict ofItemAtPath:[file path] error:&error];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//init dictionary
|
||||||
|
filePermissions = @{NSFilePosixPermissions: [NSNumber numberWithInt:permissions]};
|
||||||
|
|
||||||
|
//set permissions
|
||||||
|
if(YES != [[NSFileManager defaultManager] setAttributes:filePermissions ofItemAtPath:file error:NULL])
|
||||||
|
{
|
||||||
|
//err msg
|
||||||
|
logMsg(LOG_ERR, [NSString stringWithFormat:@"failed to set permissions for %@ (%@)", file, filePermissions]);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//dbg msg
|
||||||
|
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"set permissions for %@ (%@)", file, filePermissions]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//exec a process and grab it's output
|
//exec a process and grab it's output
|
||||||
NSData* execTask(NSString* binaryPath, NSArray* arguments)
|
NSData* execTask(NSString* binaryPath, NSArray* arguments)
|
||||||
{
|
{
|
||||||
|
@ -385,3 +497,5 @@ void makeModal(NSWindowController* windowController)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue