parent
c7aa22fda4
commit
579edd3435
|
@ -21,7 +21,7 @@
|
|||
{
|
||||
//return var
|
||||
BOOL wasConfigured = NO;
|
||||
|
||||
|
||||
//install
|
||||
// ->starts on success
|
||||
if(ACTION_INSTALL_FLAG == parameter)
|
||||
|
@ -139,6 +139,9 @@ bail:
|
|||
//path to login item
|
||||
NSString* loginItem = nil;
|
||||
|
||||
//logged in user
|
||||
NSString* user = nil;
|
||||
|
||||
//set src path
|
||||
// ->orginally stored in installer app's /Resource bundle
|
||||
appPathSrc = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:APP_NAME];
|
||||
|
@ -169,9 +172,20 @@ bail:
|
|||
//init path to login item
|
||||
loginItem = [appPathDest stringByAppendingPathComponent:@"Contents/Library/LoginItems/OverSight Helper.app/Contents/MacOS/OverSight Helper"];
|
||||
|
||||
//get user
|
||||
user = loggedinUser();
|
||||
if(nil == user)
|
||||
{
|
||||
//err msg
|
||||
logMsg(LOG_ERR, @"failed to determine logged-in user");
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//call into login item to install itself
|
||||
// ->runs as non-root, so can access user's login items, etc
|
||||
execTask(loginItem, @[ACTION_INSTALL]);
|
||||
// ->runs as logged in user, so can access user's login items, etc
|
||||
execTask(SUDO, @[@"-u", user, loginItem, ACTION_INSTALL]);
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"persisted %@", loginItem]);
|
||||
|
@ -280,6 +294,9 @@ bail:
|
|||
|
||||
//path to login item
|
||||
NSString* loginItem = nil;
|
||||
|
||||
//logged in user
|
||||
NSString* user = nil;
|
||||
|
||||
//init path
|
||||
appPath = [APPS_FOLDER stringByAppendingPathComponent:APP_NAME];
|
||||
|
@ -287,13 +304,31 @@ bail:
|
|||
//init path to login item
|
||||
loginItem = [appPath stringByAppendingPathComponent:@"Contents/Library/LoginItems/OverSight Helper.app/Contents/MacOS/OverSight Helper"];
|
||||
|
||||
//call into login item to install itself
|
||||
// ->runs as non-root, so can access user's login items, etc
|
||||
execTask(loginItem, @[ACTION_UNINSTALL]);
|
||||
//get user
|
||||
user = loggedinUser();
|
||||
if(nil == user)
|
||||
{
|
||||
//err msg
|
||||
logMsg(LOG_ERR, @"failed to determine logged-in user");
|
||||
|
||||
//set flag
|
||||
bAnyErrors = YES;
|
||||
|
||||
//keep uninstalling...
|
||||
|
||||
}
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"unpersisted %@", loginItem]);
|
||||
|
||||
//unistall login item
|
||||
else
|
||||
{
|
||||
//call into login item to uninstall itself
|
||||
// ->runs as logged in user, so can access user's login items, etc
|
||||
execTask(SUDO, @[@"-u", user, loginItem, ACTION_UNINSTALL]);
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"unpersisted %@", loginItem]);
|
||||
}
|
||||
|
||||
//delete folder
|
||||
if(YES != [[NSFileManager defaultManager] removeItemAtPath:appPath error:&error])
|
||||
{
|
||||
|
@ -306,7 +341,6 @@ bail:
|
|||
//keep uninstalling...
|
||||
}
|
||||
|
||||
|
||||
//only success when there were no errors
|
||||
if(YES != bAnyErrors)
|
||||
{
|
||||
|
|
|
@ -21,4 +21,10 @@
|
|||
//spawn self as root
|
||||
BOOL spawnAsRoot(const char* path2Self);
|
||||
|
||||
//install
|
||||
BOOL cmdlineInstall();
|
||||
|
||||
//uninstall
|
||||
BOOL cmdlineUninstall();
|
||||
|
||||
#endif /* main_h */
|
||||
|
|
143
Installer/main.m
143
Installer/main.m
|
@ -7,6 +7,8 @@
|
|||
//
|
||||
|
||||
#import "main.h"
|
||||
#import "Consts.h"
|
||||
#import "Configure.h"
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
|
@ -16,38 +18,106 @@ int main(int argc, const char * argv[])
|
|||
|
||||
@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]))
|
||||
//handle '-install' / '-uninstall'
|
||||
// ->this performs non-UI logic for easier automated deployment
|
||||
if( (argc >= 2) &&
|
||||
(YES != [[NSString stringWithUTF8String:argv[1]] hasPrefix:@"-psn_"]) )
|
||||
{
|
||||
//err msg
|
||||
logMsg(LOG_ERR, @"failed to spawn self as r00t");
|
||||
//first check rooot
|
||||
if(0 != geteuid())
|
||||
{
|
||||
//err msg
|
||||
printf("\nERROR: '%s' option, requires root\n\n", argv[1]);
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
//handle install
|
||||
if(0 == strcmp(argv[1], CMD_INSTALL))
|
||||
{
|
||||
//install
|
||||
if(YES != cmdlineInstall())
|
||||
{
|
||||
//err msg
|
||||
printf("\nERROR: install failed\n\n");
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//dbg msg
|
||||
printf("OVERSIGHT: install ok!\n");
|
||||
|
||||
//happy
|
||||
retVar = 0;
|
||||
}
|
||||
|
||||
//handle uninstall
|
||||
else if(0 == strcmp(argv[1], CMD_UNINSTALL))
|
||||
{
|
||||
//uninstall
|
||||
if(YES != cmdlineUninstall())
|
||||
{
|
||||
//err msg
|
||||
printf("\nERROR: install failed\n\n");
|
||||
}
|
||||
|
||||
//dbg msg
|
||||
printf("OVERSIGHT: uninstall ok!\n");
|
||||
|
||||
//happy
|
||||
retVar = 0;
|
||||
}
|
||||
|
||||
//invalid arg
|
||||
else
|
||||
{
|
||||
//err msg
|
||||
printf("\nERROR: '%s', is an invalid option\n\n", argv[1]);
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
}//args
|
||||
|
||||
//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);
|
||||
}
|
||||
//no args
|
||||
else
|
||||
{
|
||||
//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);
|
||||
}
|
||||
|
||||
}//no args
|
||||
|
||||
}//pool
|
||||
|
||||
|
@ -119,3 +189,18 @@ bail:
|
|||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
//install
|
||||
BOOL cmdlineInstall()
|
||||
{
|
||||
//do it!
|
||||
return [[[Configure alloc] init] configure:ACTION_INSTALL_FLAG];
|
||||
}
|
||||
|
||||
//uninstall
|
||||
BOOL cmdlineUninstall()
|
||||
{
|
||||
//do it!
|
||||
return [[[Configure alloc] init] configure:ACTION_UNINSTALL_FLAG];
|
||||
}
|
||||
|
||||
|
|
|
@ -942,7 +942,7 @@ bail:
|
|||
processName = getProcessName([event[EVENT_PROCESS_ID] intValue]);
|
||||
|
||||
//set other button title
|
||||
notification.otherButtonTitle = @"allow";
|
||||
notification.otherButtonTitle = @"allowz";
|
||||
|
||||
//set action title
|
||||
notification.actionButtonTitle = @"block";
|
||||
|
@ -1023,7 +1023,7 @@ bail:
|
|||
}
|
||||
|
||||
//automatically invoked when user interacts w/ the notification popup
|
||||
// ->only action we care about, is killing the process if they click 'block'
|
||||
// ->handle rule creation, blocking/killing proc, etc
|
||||
-(void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification
|
||||
{
|
||||
//xpc connection
|
||||
|
@ -1044,10 +1044,22 @@ bail:
|
|||
//alloc log msg
|
||||
sysLogMsg = [NSMutableString string];
|
||||
|
||||
//log event?
|
||||
// ->but only allow/blocks (i.e. webcam activations)
|
||||
if( (YES == [preferences[PREF_LOG_ACTIVITY] boolValue]) &&
|
||||
(YES == [notification.actionButtonTitle isEqualToString:@"block"]) )
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"user responded to notification: %@", notification]);
|
||||
|
||||
//for alerts without an action
|
||||
// ->don't need to do anything!
|
||||
if(YES != notification.hasActionButton)
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"popup w/o an action, no need to do anything");
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//log user's response?
|
||||
if(YES == [preferences[PREF_LOG_ACTIVITY] boolValue])
|
||||
{
|
||||
//init msg
|
||||
[sysLogMsg appendString:@"OVERSIGHT: "];
|
||||
|
@ -1069,14 +1081,23 @@ bail:
|
|||
syslog(LOG_ERR, "%s\n", sysLogMsg.UTF8String);
|
||||
}
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"use responded to notification: %@", notification]);
|
||||
|
||||
//for video
|
||||
// ->kill process if user clicked 'block'
|
||||
if( (YES == [notification.actionButtonTitle isEqualToString:@"block"]) &&
|
||||
(notification.activationType == NSUserNotificationActivationTypeActionButtonClicked))
|
||||
//when user clicks 'allow'
|
||||
// ->show popup w/ option to whitelist
|
||||
if(notification.activationType == NSUserNotificationActivationTypeAdditionalActionClicked)
|
||||
{
|
||||
//TODO: show popup
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"user clicked 'allow'");
|
||||
}
|
||||
|
||||
//when user clicks 'block'
|
||||
// ->kill the process to block it
|
||||
else if(notification.activationType == NSUserNotificationActivationTypeActionButtonClicked)
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"user clicked 'block'");
|
||||
|
||||
//extract process id
|
||||
processID = notification.userInfo[EVENT_PROCESS_ID];
|
||||
if(nil == processID)
|
||||
|
@ -1087,7 +1108,7 @@ bail:
|
|||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
|
||||
//alloc XPC connection
|
||||
xpcConnection = [[NSXPCConnection alloc] initWithServiceName:@"com.objective-see.OverSightXPC"];
|
||||
|
||||
|
@ -1102,22 +1123,22 @@ bail:
|
|||
|
||||
//invoke XPC method 'killProcess' to terminate
|
||||
[[xpcConnection remoteObjectProxy] killProcess:processID reply:^(BOOL wasKilled)
|
||||
{
|
||||
//check for err
|
||||
if(YES != wasKilled)
|
||||
{
|
||||
//err msg
|
||||
logMsg(LOG_ERR, [NSString stringWithFormat:@"failed to kill/block: %@", processID]);
|
||||
|
||||
}
|
||||
|
||||
//close connection
|
||||
[xpcConnection invalidate];
|
||||
|
||||
//nil out
|
||||
xpcConnection = nil;
|
||||
}];
|
||||
|
||||
{
|
||||
//check for err
|
||||
if(YES != wasKilled)
|
||||
{
|
||||
//err msg
|
||||
logMsg(LOG_ERR, [NSString stringWithFormat:@"failed to kill/block: %@", processID]);
|
||||
|
||||
}
|
||||
|
||||
//close connection
|
||||
[xpcConnection invalidate];
|
||||
|
||||
//nil out
|
||||
xpcConnection = nil;
|
||||
}];
|
||||
|
||||
}//user clicked 'block'
|
||||
|
||||
//bail
|
||||
|
@ -1126,7 +1147,6 @@ bail:
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
//monitor for new procs (video only at the moment)
|
||||
// ->runs until video is no longer in use (set elsewhere)
|
||||
-(void)monitor4Procs
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//
|
||||
|
||||
#import "main.h"
|
||||
#import "Logging.h"
|
||||
#import "Utilities.h"
|
||||
|
||||
//go go go
|
||||
|
@ -17,38 +18,57 @@ int main(int argc, const char * argv[])
|
|||
int iReturn = 0;
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"starting login item");
|
||||
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"starting login item (args: %@/user: %@)", [[NSProcessInfo processInfo] arguments], NSUserName()]);
|
||||
|
||||
//check for uninstall/install flags
|
||||
if(2 == argc)
|
||||
{
|
||||
//install
|
||||
if(0 == strcmp(argv[1], ACTION_INSTALL.UTF8String))
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"running install logic");
|
||||
|
||||
//drop user privs
|
||||
setuid(getuid());
|
||||
|
||||
//install
|
||||
toggleLoginItem([NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]], ACTION_INSTALL_FLAG);
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"installed login item");
|
||||
|
||||
//create default prefs
|
||||
[@{PREF_LOG_ACTIVITY:@YES, PREF_START_AT_LOGIN:@YES, PREF_RUN_HEADLESS:@NO, PREF_CHECK_4_UPDATES:@YES} writeToFile:[APP_PREFERENCES stringByExpandingTildeInPath] atomically:NO];
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"created preferences at: %@", [APP_PREFERENCES stringByExpandingTildeInPath]]);
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
//uninstall
|
||||
else if(0 == strcmp(argv[1], ACTION_UNINSTALL.UTF8String))
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"running uninstall logic");
|
||||
|
||||
//drop user privs
|
||||
setuid(getuid());
|
||||
|
||||
//unistall
|
||||
toggleLoginItem([NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]], ACTION_UNINSTALL_FLAG);
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"removed login item");
|
||||
|
||||
//delete prefs
|
||||
[[NSFileManager defaultManager] removeItemAtPath:[APP_PREFERENCES stringByExpandingTildeInPath] error:nil];
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"removed preferences from: %@", [APP_PREFERENCES stringByExpandingTildeInPath]]);
|
||||
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
|
|
@ -52,6 +52,18 @@
|
|||
// ->for now, just cmd+q to quit app
|
||||
[self registerKeypressHandler];
|
||||
|
||||
//create default prefs if there aren't any
|
||||
// ->should only happen if new user runs the app
|
||||
if(YES != [[NSFileManager defaultManager] fileExistsAtPath:[APP_PREFERENCES stringByExpandingTildeInPath]])
|
||||
{
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"preference file not found; manually creating");
|
||||
|
||||
//write em out
|
||||
// ->note; set 'start at login' to false, since no prefs here, mean installer wasn't run (user can later toggle)
|
||||
[@{PREF_LOG_ACTIVITY:@YES, PREF_START_AT_LOGIN:@NO, PREF_RUN_HEADLESS:@NO, PREF_CHECK_4_UPDATES:@YES} writeToFile:[APP_PREFERENCES stringByExpandingTildeInPath] atomically:NO];
|
||||
}
|
||||
|
||||
//start login item in background
|
||||
// ->checks if already running though
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
|
||||
|
|
|
@ -57,9 +57,6 @@
|
|||
// ->ensures its only invoke while camera is not in use, so these are all just baselined procs
|
||||
-(void)start;
|
||||
|
||||
//find 'VDCAssistant' or 'AppleCameraAssistant'
|
||||
-(pid_t)findCameraAssistant;
|
||||
|
||||
//enumerate all (recent) process that appear to be using the mic
|
||||
-(NSMutableArray*)enumAudioProcs;
|
||||
|
||||
|
|
|
@ -75,174 +75,13 @@ static NSArray* ignoredProcs = nil;
|
|||
return sharedEnumerator;
|
||||
}
|
||||
|
||||
//find a process by name
|
||||
-(pid_t)findProcess:(NSString*)processName
|
||||
{
|
||||
//pid
|
||||
pid_t processID = 0;
|
||||
|
||||
//status
|
||||
int status = -1;
|
||||
|
||||
//# of procs
|
||||
int numberOfProcesses = 0;
|
||||
|
||||
//array of pids
|
||||
pid_t* pids = NULL;
|
||||
|
||||
//process path
|
||||
NSString* processPath = nil;
|
||||
|
||||
//get # of procs
|
||||
numberOfProcesses = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0);
|
||||
|
||||
//alloc buffer for pids
|
||||
pids = calloc(numberOfProcesses, sizeof(pid_t));
|
||||
|
||||
//get list of pids
|
||||
status = proc_listpids(PROC_ALL_PIDS, 0, pids, numberOfProcesses * sizeof(pid_t));
|
||||
if(status < 0)
|
||||
{
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//iterate over all pids
|
||||
// ->get name for each via helper function
|
||||
for(int i = 0; i < numberOfProcesses; ++i)
|
||||
{
|
||||
//skip blank pids
|
||||
if(0 == pids[i])
|
||||
{
|
||||
//skip
|
||||
continue;
|
||||
}
|
||||
|
||||
//get name
|
||||
processPath = getProcessPath(pids[i]);
|
||||
if( (nil == processPath) ||
|
||||
(0 == processPath.length) )
|
||||
{
|
||||
//skip
|
||||
continue;
|
||||
}
|
||||
|
||||
//match?
|
||||
if(YES == [processPath isEqualToString:processName])
|
||||
{
|
||||
//save
|
||||
processID = pids[i];
|
||||
|
||||
//pau
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//bail
|
||||
bail:
|
||||
|
||||
//free buffer
|
||||
if(NULL != pids)
|
||||
{
|
||||
//free
|
||||
free(pids);
|
||||
}
|
||||
|
||||
return processID;
|
||||
}
|
||||
|
||||
//TODO: replace with [self findProcess]!!
|
||||
//find 'VDCAssistant' or 'AppleCameraAssistant'
|
||||
-(pid_t)findCameraAssistant
|
||||
{
|
||||
//pid of assistant
|
||||
pid_t cameraAssistant = 0;
|
||||
|
||||
//status
|
||||
int status = -1;
|
||||
|
||||
//# of procs
|
||||
int numberOfProcesses = 0;
|
||||
|
||||
//array of pids
|
||||
pid_t* pids = NULL;
|
||||
|
||||
//process path
|
||||
NSString* processPath = nil;
|
||||
|
||||
//get # of procs
|
||||
numberOfProcesses = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0);
|
||||
|
||||
//alloc buffer for pids
|
||||
pids = calloc(numberOfProcesses, sizeof(pid_t));
|
||||
|
||||
//get list of pids
|
||||
status = proc_listpids(PROC_ALL_PIDS, 0, pids, numberOfProcesses * sizeof(pid_t));
|
||||
if(status < 0)
|
||||
{
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//iterate over all pids
|
||||
// ->get name for each via helper function
|
||||
for(int i = 0; i < numberOfProcesses; ++i)
|
||||
{
|
||||
//skip blank pids
|
||||
if(0 == pids[i])
|
||||
{
|
||||
//skip
|
||||
continue;
|
||||
}
|
||||
|
||||
//get name
|
||||
processPath = getProcessPath(pids[i]);
|
||||
if( (nil == processPath) ||
|
||||
(0 == processPath.length) )
|
||||
{
|
||||
//skip
|
||||
continue;
|
||||
}
|
||||
|
||||
//is 'VDCAssistant'?
|
||||
if(YES == [processPath isEqualToString:VDC_ASSISTANT])
|
||||
{
|
||||
//save
|
||||
cameraAssistant = pids[i];
|
||||
|
||||
//pau
|
||||
break;
|
||||
}
|
||||
|
||||
//is 'AppleCameraAssistant'?
|
||||
else if(YES == [processPath isEqualToString:APPLE_CAMERA_ASSISTANT])
|
||||
{
|
||||
//save
|
||||
cameraAssistant = pids[i];
|
||||
|
||||
//pau
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//bail
|
||||
bail:
|
||||
|
||||
//free buffer
|
||||
if(NULL != pids)
|
||||
{
|
||||
//free
|
||||
free(pids);
|
||||
}
|
||||
|
||||
return cameraAssistant;
|
||||
}
|
||||
|
||||
//forever, baseline by getting all current procs that have sent a mach msg to *Assistant / coreaudio
|
||||
// ->logic only exec'd while camera/mic is not in use, so these are all just baselined procs
|
||||
-(void)start
|
||||
{
|
||||
//camera assistant
|
||||
pid_t cameraAssistant = 0;
|
||||
|
||||
//baseline forever
|
||||
// ->though logic will skip if video or mic is active (respectively)
|
||||
while(YES)
|
||||
|
@ -256,8 +95,27 @@ bail:
|
|||
//dbg msg
|
||||
logMsg(LOG_DEBUG, @"baselining mach senders for video...");
|
||||
|
||||
//find camera assistant
|
||||
// ->first look for 'VDCAssistant'
|
||||
cameraAssistant = findProcess(VDC_ASSISTANT);
|
||||
if(0 == cameraAssistant)
|
||||
{
|
||||
//look for 'AppleCameraAssistant'
|
||||
cameraAssistant = findProcess(APPLE_CAMERA_ASSISTANT);
|
||||
}
|
||||
|
||||
//sanity check
|
||||
if(0 == cameraAssistant)
|
||||
{
|
||||
//nap for a minute
|
||||
[NSThread sleepForTimeInterval:60];
|
||||
|
||||
//next
|
||||
continue;
|
||||
}
|
||||
|
||||
//enumerate procs that have send mach messages
|
||||
self.machSendersVideo = [self enumMachSenders:[self findCameraAssistant]];
|
||||
self.machSendersVideo = [self enumMachSenders:cameraAssistant];
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"found %lu baselined mach senders: %@", (unsigned long)self.machSendersVideo.count, self.machSendersVideo]);
|
||||
|
@ -270,7 +128,7 @@ bail:
|
|||
logMsg(LOG_DEBUG, @"baselining mach senders for audio...");
|
||||
|
||||
//enumerate procs that have send mach messages
|
||||
self.machSendersAudio = [self enumMachSenders:[self findProcess:CORE_AUDIO]];
|
||||
self.machSendersAudio = [self enumMachSenders:findProcess(CORE_AUDIO)];
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"found %lu baselined mach senders: %@", (unsigned long)self.machSendersAudio.count, self.machSendersVideo]);
|
||||
|
@ -317,8 +175,15 @@ bail:
|
|||
@synchronized(self)
|
||||
{
|
||||
|
||||
//find 'VDCAssistant' or 'AppleCameraAssistant'
|
||||
cameraAssistant = [self findCameraAssistant];
|
||||
//first look for 'VDCAssistant'
|
||||
cameraAssistant = findProcess(VDC_ASSISTANT);
|
||||
if(0 == cameraAssistant)
|
||||
{
|
||||
//look for 'AppleCameraAssistant'
|
||||
cameraAssistant = findProcess(APPLE_CAMERA_ASSISTANT);
|
||||
}
|
||||
|
||||
//sanity check
|
||||
if(0 == cameraAssistant)
|
||||
{
|
||||
//err msg
|
||||
|
@ -327,7 +192,7 @@ bail:
|
|||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
|
||||
//get procs that currrently have sent Mach msg to *Assistant
|
||||
// ->returns dictionary of process id, and number of mach messages
|
||||
currentSenders = [self enumMachSenders:cameraAssistant];
|
||||
|
@ -414,7 +279,7 @@ bail:
|
|||
@synchronized(self)
|
||||
{
|
||||
//find coreaudio
|
||||
coreAudio = [self findProcess:CORE_AUDIO];
|
||||
coreAudio = findProcess(CORE_AUDIO);
|
||||
if(0 == coreAudio)
|
||||
{
|
||||
//err msg
|
||||
|
@ -803,7 +668,7 @@ bail:
|
|||
}
|
||||
|
||||
//sampling a process creates a temp file
|
||||
//->delete it!
|
||||
//->make sure we delete it this file to clean up ;)
|
||||
[self deleteSampleFile:processPath];
|
||||
|
||||
//for now, just check for 'CMIOGraph::DoWork'
|
||||
|
@ -885,6 +750,9 @@ bail:
|
|||
// ->extra logic is executed to 'refresh' iVars when video is disabled
|
||||
-(void)updateVideoStatus:(BOOL)isEnabled
|
||||
{
|
||||
//camera assistant
|
||||
pid_t cameraAssistant = 0;
|
||||
|
||||
//sync
|
||||
@synchronized(self)
|
||||
{
|
||||
|
@ -895,10 +763,32 @@ bail:
|
|||
// ->re-enumerate mach senders
|
||||
if(YES != isEnabled)
|
||||
{
|
||||
//first, look for 'VDCAssistant'
|
||||
cameraAssistant = findProcess(VDC_ASSISTANT);
|
||||
if(0 == cameraAssistant)
|
||||
{
|
||||
//look for 'AppleCameraAssistant'
|
||||
cameraAssistant = findProcess(APPLE_CAMERA_ASSISTANT);
|
||||
}
|
||||
|
||||
//sanity check
|
||||
if(0 == cameraAssistant)
|
||||
{
|
||||
//err msg
|
||||
logMsg(LOG_ERR, @"failed to find VDCAssistant/AppleCameraAssistant process");
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//enumerate mach senders
|
||||
self.machSendersVideo = [self enumMachSenders:[self findCameraAssistant]];
|
||||
self.machSendersVideo = [self enumMachSenders:cameraAssistant];
|
||||
}
|
||||
}
|
||||
|
||||
}//sync
|
||||
|
||||
//bail
|
||||
bail:
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -918,7 +808,7 @@ bail:
|
|||
if(YES != isEnabled)
|
||||
{
|
||||
//enumerate mach senders
|
||||
self.machSendersAudio = [self enumMachSenders:[self findProcess:CORE_AUDIO]];
|
||||
self.machSendersAudio = [self enumMachSenders:findProcess(CORE_AUDIO)];
|
||||
|
||||
//enumerate i/o registry user clients
|
||||
self.userClients = [self enumDomainUserClients];
|
||||
|
|
|
@ -36,6 +36,12 @@
|
|||
//OS minor version el capitan
|
||||
#define OS_MINOR_VERSION_EL_CAPITAN 11
|
||||
|
||||
//install flag
|
||||
#define CMD_INSTALL "-install"
|
||||
|
||||
//uninstall flag
|
||||
#define CMD_UNINSTALL "-uninstall"
|
||||
|
||||
//action to install
|
||||
// ->also button title
|
||||
#define ACTION_INSTALL @"Install"
|
||||
|
@ -92,8 +98,13 @@
|
|||
//path to xattr
|
||||
#define XATTR @"/usr/bin/xattr"
|
||||
|
||||
//path to sudo
|
||||
#define SUDO @"/usr/bin/sudo"
|
||||
|
||||
//path to facetime
|
||||
#define FACE_TIME @"/Applications/FaceTime.app/Contents/MacOS/FaceTime"
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -67,4 +67,10 @@ void makeModal(NSWindowController* windowController);
|
|||
// ->either add (install) or remove (uninstall)
|
||||
BOOL toggleLoginItem(NSURL* loginItem, int toggleFlag);
|
||||
|
||||
//get logged in user
|
||||
NSString* loggedinUser();
|
||||
|
||||
//find a process by name
|
||||
pid_t findProcess(NSString* processName);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#import <CommonCrypto/CommonDigest.h>
|
||||
#import <SystemConfiguration/SystemConfiguration.h>
|
||||
|
||||
|
||||
//get OS version
|
||||
NSDictionary* getOSVersion()
|
||||
{
|
||||
|
@ -295,6 +296,9 @@ NSData* execTask(NSString* binaryPath, NSArray* arguments)
|
|||
//set task's output
|
||||
[task setStandardOutput:outPipe];
|
||||
|
||||
//dbg msg
|
||||
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"@exec'ing %@ (args: %@)", binaryPath, arguments]);
|
||||
|
||||
//wrap task launch
|
||||
@try
|
||||
{
|
||||
|
@ -727,7 +731,7 @@ BOOL toggleLoginItem(NSURL* loginItem, int toggleFlag)
|
|||
{
|
||||
//flag
|
||||
BOOL wasToggled = NO;
|
||||
|
||||
|
||||
//login item ref
|
||||
LSSharedFileListRef loginItemsRef = NULL;
|
||||
|
||||
|
@ -765,11 +769,14 @@ BOOL toggleLoginItem(NSURL* loginItem, int toggleFlag)
|
|||
else
|
||||
{
|
||||
//err msg
|
||||
logMsg(LOG_ERR, @"failed to added login item");
|
||||
logMsg(LOG_ERR, @"failed to add login item");
|
||||
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//happy
|
||||
wasToggled = YES;
|
||||
}
|
||||
//remove (uninstall)
|
||||
else
|
||||
|
@ -797,6 +804,9 @@ BOOL toggleLoginItem(NSURL* loginItem, int toggleFlag)
|
|||
{
|
||||
//remove
|
||||
LSSharedFileListItemRemove(loginItemsRef, (__bridge LSSharedFileListItemRef)item);
|
||||
|
||||
//happy
|
||||
wasToggled = YES;
|
||||
}
|
||||
|
||||
//release
|
||||
|
@ -813,9 +823,6 @@ BOOL toggleLoginItem(NSURL* loginItem, int toggleFlag)
|
|||
|
||||
}//remove/uninstall
|
||||
|
||||
//happy
|
||||
wasToggled = YES;
|
||||
|
||||
//bail
|
||||
bail:
|
||||
|
||||
|
@ -842,7 +849,114 @@ bail:
|
|||
return wasToggled;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//get logged in user
|
||||
NSString* loggedinUser()
|
||||
{
|
||||
//store
|
||||
SCDynamicStoreRef store = nil;
|
||||
|
||||
//user
|
||||
NSString* user = nil;
|
||||
|
||||
//create store
|
||||
store = SCDynamicStoreCreate(NULL, CFSTR("GetConsoleUser"), NULL, NULL);
|
||||
if(NULL == store)
|
||||
{
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//get user
|
||||
user = CFBridgingRelease(SCDynamicStoreCopyConsoleUser(store, NULL, NULL));
|
||||
|
||||
//bail
|
||||
bail:
|
||||
|
||||
//release store
|
||||
if(NULL != store)
|
||||
{
|
||||
//release
|
||||
CFRelease(store);
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
//find a process by name
|
||||
pid_t findProcess(NSString* processName)
|
||||
{
|
||||
//pid
|
||||
pid_t processID = 0;
|
||||
|
||||
//status
|
||||
int status = -1;
|
||||
|
||||
//# of procs
|
||||
int numberOfProcesses = 0;
|
||||
|
||||
//array of pids
|
||||
pid_t* pids = NULL;
|
||||
|
||||
//process path
|
||||
NSString* processPath = nil;
|
||||
|
||||
//get # of procs
|
||||
numberOfProcesses = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0);
|
||||
|
||||
//alloc buffer for pids
|
||||
pids = calloc(numberOfProcesses, sizeof(pid_t));
|
||||
|
||||
//get list of pids
|
||||
status = proc_listpids(PROC_ALL_PIDS, 0, pids, numberOfProcesses * sizeof(pid_t));
|
||||
if(status < 0)
|
||||
{
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//iterate over all pids
|
||||
// ->get name for each via helper function
|
||||
for(int i = 0; i < numberOfProcesses; ++i)
|
||||
{
|
||||
//skip blank pids
|
||||
if(0 == pids[i])
|
||||
{
|
||||
//skip
|
||||
continue;
|
||||
}
|
||||
|
||||
//get name
|
||||
processPath = getProcessPath(pids[i]);
|
||||
if( (nil == processPath) ||
|
||||
(0 == processPath.length) )
|
||||
{
|
||||
//skip
|
||||
continue;
|
||||
}
|
||||
|
||||
//match?
|
||||
if(YES == [processPath isEqualToString:processName])
|
||||
{
|
||||
//save
|
||||
processID = pids[i];
|
||||
|
||||
//pau
|
||||
break;
|
||||
}
|
||||
|
||||
}//all procs
|
||||
|
||||
//bail
|
||||
bail:
|
||||
|
||||
//free buffer
|
||||
if(NULL != pids)
|
||||
{
|
||||
//free
|
||||
free(pids);
|
||||
}
|
||||
|
||||
return processID;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue