white-listing granularity is now down to the device level (mic/camera)

ui: stuff is resizable / fixed warnings
This commit is contained in:
Patrick Wardle 2017-04-07 21:37:23 -10:00
parent 5ba5b585ba
commit 5a1f704931
14 changed files with 257 additions and 139 deletions

View File

@ -56,9 +56,9 @@
#ifdef DEBUG
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"loading whitelist %@", path]);
#endif
//since file is created by priv'd XPC, it shouldn't be writeable
// ...unless somebody maliciously creates it, so we check if that here
// ...unless somebody maliciously creates it, so we check that here
if(YES == [[NSFileManager defaultManager] isWritableFileAtPath:path])
{
//err msg
@ -67,7 +67,7 @@
//bail
goto bail;
}
//load
self.whiteList = [NSMutableArray arrayWithContentsOfFile:path];
@ -834,7 +834,7 @@ bail:
//dbg msg
#ifdef DEBUG
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"audio procs from XPC: %@", audioProcesses]);
#endif
#endif
//generate notification for each process
for(NSNumber* processID in audioProcesses)
@ -1018,16 +1018,25 @@ bail:
//ignore whitelisted processes
// ->for activation events, can check process path
if( (YES == [DEVICE_ACTIVE isEqual:event[EVENT_DEVICE_STATUS]]) &&
(YES == [self.whiteList containsObject:processPath]) )
if(YES == [DEVICE_ACTIVE isEqual:event[EVENT_DEVICE_STATUS]])
{
//dbg msg
#ifdef DEBUG
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"activation alert for process %@ is whitelisted, so ignoring", processPath]);
#endif
//bail
goto bail;
//check each
// ->need match on path and device (camera || mic)
for(NSDictionary* item in self.whiteList)
{
//check path & device
if( (YES == [item[EVENT_PROCESS_PATH] isEqualToString:processPath]) &&
([item[EVENT_DEVICE] intValue] == deviceType.intValue) )
{
//dbg msg
#ifdef DEBUG
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"activation alert for process %@ is whitelisted, so ignoring", item]);
#endif
//bail
goto bail;
}
}
}
//ignore whitelisted processes
// ->for deactivation, ignore when no activation alert was shown (cuz process will have likely died, so no pid/path, etc)

View File

@ -21,6 +21,10 @@
// ->used for whitelisting
@property (nonatomic, retain)NSString* processPath;
//device
// ->used for whitelisting
@property (nonatomic, retain)NSNumber* device;
//instance of av monitor
@property (nonatomic, retain)AVMonitor* avMonitor;

View File

@ -16,6 +16,7 @@
@implementation RememberWindowController
@synthesize device;
@synthesize avMonitor;
@synthesize processPath;
@ -45,18 +46,6 @@
return;
}
/*
//automatically invoked when window is closing
// ->make ourselves unmodal
-(void)windowWillClose:(NSNotification *)notification
{
//make un-modal
[[NSApplication sharedApplication] stopModal];
return;
}
*/
//save stuff into iVars
// ->configure window w/ dynamic text
-(void)configure:(NSUserNotification*)notification avMonitor:(AVMonitor*)monitor;
@ -83,14 +72,18 @@
// ->saved into iVar for whitelisting
self.processPath = notification.userInfo[EVENT_PROCESS_PATH];
//grab device
// ->saved into iVar for whitelisting
self.device = notification.userInfo[EVENT_DEVICE];
//set device type for audio
if(SOURCE_AUDIO.intValue == [notification.userInfo[EVENT_DEVICE] intValue])
if(SOURCE_AUDIO.intValue == [self.device intValue])
{
//set
deviceType = @"mic";
}
//set device type for mic
else if(SOURCE_VIDEO.intValue == [notification.userInfo[EVENT_DEVICE] intValue])
else if(SOURCE_VIDEO.intValue == [self.device intValue])
{
//set
deviceType = @"camera";
@ -131,7 +124,7 @@
#endif
//invoke XPC method 'whitelistProcess' to add process to white list
[[xpcConnection remoteObjectProxy] whitelistProcess:self.processPath reply:^(BOOL wasWhitelisted)
[[xpcConnection remoteObjectProxy] whitelistProcess:self.processPath device:self.device reply:^(BOOL wasWhitelisted)
{
//dbg msg
#ifdef DEBUG

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="16E195" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11762"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@ -14,47 +14,45 @@
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES" texturedBackground="YES" unifiedTitleAndToolbar="YES"/>
<windowStyleMask key="styleMask" titled="YES" closable="YES" resizable="YES" texturedBackground="YES" unifiedTitleAndToolbar="YES"/>
<rect key="contentRect" x="196" y="240" width="422" height="123"/>
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1058"/>
<value key="minSize" type="size" width="422" height="123"/>
<value key="maxSize" type="size" width="800" height="123"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="422" height="123"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lEv-Wj-6S5">
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="lEv-Wj-6S5">
<rect key="frame" x="10" y="36" width="104" height="82"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<constraints>
<constraint firstAttribute="height" constant="82" id="hbh-Sm-Zhs"/>
<constraint firstAttribute="width" constant="104" id="wAG-N8-wcA"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="icon" id="xKf-GK-m0k"/>
</imageView>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Eaf-yA-bbe">
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Eaf-yA-bbe">
<rect key="frame" x="20" y="6" width="94" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<constraints>
<constraint firstAttribute="width" constant="94" id="PdH-hs-jAq"/>
<constraint firstAttribute="height" constant="22" id="hIM-Jw-VTR"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="overSight" id="Ws8-bD-j2R"/>
</imageView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="OSm-xS-Dmd">
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="OSm-xS-Dmd">
<rect key="frame" x="120" y="47" width="290" height="56"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<constraints>
<constraint firstAttribute="height" constant="56" id="W2y-ds-fJG"/>
</constraints>
<textFieldCell key="cell" truncatesLastVisibleLine="YES" sendsActionOnEndEditing="YES" id="bBK-v0-ypq">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" fixedFrame="YES" tag="100" translatesAutoresizingMaskIntoConstraints="NO" id="RKg-ba-EQ4">
<rect key="frame" x="177" y="11" width="127" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="yes, always" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="0OU-M1-ErX">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="13" name="Menlo-Regular"/>
</buttonCell>
<connections>
<action selector="buttonHandler:" target="-2" id="LNd-1i-TBg"/>
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" tag="101" translatesAutoresizingMaskIntoConstraints="NO" id="HZZ-Es-mpy">
<rect key="frame" x="310" y="11" width="98" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="just once" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="J9x-sM-h9S">
<button verticalHuggingPriority="750" tag="101" translatesAutoresizingMaskIntoConstraints="NO" id="HZZ-Es-mpy">
<rect key="frame" x="303" y="11" width="111" height="32"/>
<buttonCell key="cell" type="push" title="Just Once" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="J9x-sM-h9S">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="13" name="Menlo-Regular"/>
</buttonCell>
@ -62,7 +60,30 @@
<action selector="buttonHandler:" target="-2" id="yBL-R5-DDG"/>
</connections>
</button>
<button verticalHuggingPriority="750" tag="100" translatesAutoresizingMaskIntoConstraints="NO" id="RKg-ba-EQ4">
<rect key="frame" x="161" y="11" width="127" height="32"/>
<buttonCell key="cell" type="push" title="Yes, Always" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="0OU-M1-ErX">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="13" name="Menlo-Regular"/>
</buttonCell>
<connections>
<action selector="buttonHandler:" target="-2" id="LNd-1i-TBg"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstAttribute="bottom" secondItem="HZZ-Es-mpy" secondAttribute="bottom" constant="18" id="Dl1-Xj-w6N"/>
<constraint firstAttribute="bottom" secondItem="OSm-xS-Dmd" secondAttribute="bottom" constant="47" id="Igd-JW-wvo"/>
<constraint firstAttribute="bottom" secondItem="RKg-ba-EQ4" secondAttribute="bottom" constant="18" id="KUJ-j6-Bjl"/>
<constraint firstAttribute="trailing" secondItem="RKg-ba-EQ4" secondAttribute="trailing" constant="140" id="Klc-7g-EQu"/>
<constraint firstAttribute="trailing" secondItem="OSm-xS-Dmd" secondAttribute="trailing" constant="14" id="QcB-Yv-9vm"/>
<constraint firstItem="OSm-xS-Dmd" firstAttribute="leading" secondItem="lEv-Wj-6S5" secondAttribute="trailing" constant="8" id="So9-MA-q9b"/>
<constraint firstItem="lEv-Wj-6S5" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="10" id="WhZ-G2-Urs"/>
<constraint firstItem="Eaf-yA-bbe" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="20" id="iJQ-GM-l7f"/>
<constraint firstItem="lEv-Wj-6S5" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="5" id="pnZ-ff-hBv"/>
<constraint firstAttribute="bottom" secondItem="Eaf-yA-bbe" secondAttribute="bottom" constant="6" id="tae-Ir-cHI"/>
<constraint firstAttribute="trailing" secondItem="HZZ-Es-mpy" secondAttribute="trailing" constant="14" id="yfU-kv-QZb"/>
</constraints>
</view>
<connections>
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>

View File

@ -16,6 +16,6 @@
/* FUNCTION DEFINITIONS */
//send XPC message to remove process from whitelist file
void unWhiteList(NSString* process);
void unWhiteList(NSString* process, NSNumber* deviceType);
#endif /* main_h */

View File

@ -86,21 +86,21 @@ int main(int argc, const char * argv[])
//bail
goto bail;
}
}
//unwhitelist path/device
else if(3 == argc)
{
//dbg msg
#ifdef DEBUG
logMsg(LOG_DEBUG, @"running 'un-whitelist me' logic");
#endif
//remove from whitelist file
unWhiteList([NSString stringWithUTF8String:argv[1]], [NSNumber numberWithInt:atoi(argv[2])]);
//assume its a path to a process to remove from whitelist
else
{
//dbg msg
#ifdef DEBUG
logMsg(LOG_DEBUG, @"running 'un-whitelist me' logic");
#endif
//remove from whitelist file
unWhiteList([NSString stringWithUTF8String:argv[1]]);
//don't bail
// ->let it start (as it was killed)
}
//don't bail
// ->let it start (as it was killed)
}
//launch app normally
@ -113,7 +113,7 @@ bail:
}
//send XPC message to remove process from whitelist file
void unWhiteList(NSString* process)
void unWhiteList(NSString* process, NSNumber* device)
{
//xpc connection
__block NSXPCConnection* xpcConnection = nil;
@ -129,11 +129,11 @@ void unWhiteList(NSString* process)
//dbg msg
#ifdef DEBUG
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"sending XPC message to remove %@ from whitelist file", process]);
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"sending XPC message to remove %@/%@ from whitelist file", process, device]);
#endif
//invoke XPC method 'whitelistProcess' to add process to white list
[[xpcConnection remoteObjectProxy] unWhitelistProcess:process reply:^(BOOL wasRemoved)
[[xpcConnection remoteObjectProxy] unWhitelistProcess:process device:device reply:^(BOOL wasRemoved)
{
//dbg msg
#ifdef DEBUG

View File

@ -455,6 +455,11 @@ bail:
configuration = @{NSWorkspaceLaunchConfigurationArguments:args};
}
//dbg msg
#ifdef DEBUG
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"starting login item with: %@/%@", configuration, args]);
#endif
//launch it
[[NSWorkspace sharedWorkspace] launchApplicationAtURL:[NSURL fileURLWithPath:loginItem] options:NSWorkspaceLaunchWithoutActivation configuration:configuration error:&error];

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="16E195" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11762"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@ -14,11 +14,12 @@
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="White Listed Applications" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
<windowStyleMask key="styleMask" titled="YES" closable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="611" height="270"/>
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1058"/>
<value key="minSize" type="size" width="500" height="100"/>
<value key="maxSize" type="size" width="1500" height="500"/>
<view key="contentView" wantsLayer="YES" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="611" height="270"/>
<autoresizingMask key="autoresizingMask"/>
@ -36,7 +37,7 @@
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="608" minWidth="40" maxWidth="1000" id="ocl-vV-SZu">
<tableColumn width="608" minWidth="40" maxWidth="1500" id="ocl-vV-SZu">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
@ -55,10 +56,14 @@
<subviews>
<imageView translatesAutoresizingMaskIntoConstraints="NO" id="JiF-Nx-dl5">
<rect key="frame" x="3" y="7" width="40" height="40"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="Ek4-aX-zze"/>
<constraint firstAttribute="width" constant="40" id="LIx-0S-38a"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSColorPanel" id="v3A-16-OyI"/>
</imageView>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" tag="100" translatesAutoresizingMaskIntoConstraints="NO" id="JMN-i9-vxR">
<rect key="frame" x="54" y="21" width="523" height="26"/>
<rect key="frame" x="54" y="21" width="525" height="26"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Item Category" id="2GD-5k-sEf">
<font key="font" size="17" name="Menlo-Bold"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@ -66,10 +71,7 @@
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" tag="101" translatesAutoresizingMaskIntoConstraints="NO" id="w9P-yZ-pho">
<rect key="frame" x="54" y="8" width="523" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="519" id="kmq-rD-zZS"/>
</constraints>
<rect key="frame" x="54" y="8" width="525" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Item Category Description" id="EZN-NC-GXx">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
@ -77,7 +79,11 @@
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aWW-9r-3lC">
<rect key="frame" x="583" y="19" width="14" height="15"/>
<rect key="frame" x="585" y="19" width="20" height="15"/>
<constraints>
<constraint firstAttribute="width" constant="20" id="6gy-ZI-MZN"/>
<constraint firstAttribute="height" constant="15" id="iy3-ST-MU7"/>
</constraints>
<buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="NSStopProgressFreestandingTemplate" imagePosition="overlaps" alignment="center" imageScaling="proportionallyDown" inset="2" id="wdw-rZ-IR3">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@ -88,19 +94,20 @@
</button>
</subviews>
<constraints>
<constraint firstItem="JiF-Nx-dl5" firstAttribute="top" secondItem="moN-VP-hzI" secondAttribute="top" constant="7" id="0og-eM-P5A"/>
<constraint firstItem="aWW-9r-3lC" firstAttribute="top" secondItem="moN-VP-hzI" secondAttribute="top" constant="20" id="2Hq-gF-RRx"/>
<constraint firstAttribute="bottom" secondItem="JMN-i9-vxR" secondAttribute="bottom" constant="21" id="2lm-V9-MgG"/>
<constraint firstItem="w9P-yZ-pho" firstAttribute="trailing" secondItem="JMN-i9-vxR" secondAttribute="trailing" id="3zL-0B-Yt0"/>
<constraint firstItem="JMN-i9-vxR" firstAttribute="top" secondItem="JiF-Nx-dl5" secondAttribute="top" id="4ZQ-hO-YeB"/>
<constraint firstAttribute="bottom" secondItem="aWW-9r-3lC" secondAttribute="bottom" constant="19" id="JXs-JW-Xg3"/>
<constraint firstItem="w9P-yZ-pho" firstAttribute="top" secondItem="moN-VP-hzI" secondAttribute="top" constant="29" id="Rbh-tU-0B0"/>
<constraint firstItem="JiF-Nx-dl5" firstAttribute="leading" secondItem="moN-VP-hzI" secondAttribute="leading" constant="3" id="UxO-Jr-Zzk"/>
<constraint firstItem="w9P-yZ-pho" firstAttribute="leading" secondItem="JMN-i9-vxR" secondAttribute="leading" id="d1t-pb-hcW"/>
<constraint firstItem="w9P-yZ-pho" firstAttribute="leading" secondItem="JiF-Nx-dl5" secondAttribute="trailing" constant="13" id="dD6-u5-DZw"/>
<constraint firstItem="w9P-yZ-pho" firstAttribute="leading" secondItem="moN-VP-hzI" secondAttribute="leading" constant="56" id="mQY-GF-Ndc"/>
<constraint firstAttribute="trailing" secondItem="aWW-9r-3lC" secondAttribute="trailing" constant="11" id="n4e-65-kcp"/>
<constraint firstAttribute="bottom" secondItem="JiF-Nx-dl5" secondAttribute="bottom" constant="7" id="na5-b4-JAs"/>
<constraint firstAttribute="bottom" secondItem="w9P-yZ-pho" secondAttribute="bottom" constant="8" id="8ET-Mt-gF3"/>
<constraint firstAttribute="bottom" secondItem="aWW-9r-3lC" secondAttribute="bottom" constant="19" id="8wP-dc-ILG"/>
<constraint firstAttribute="trailing" secondItem="aWW-9r-3lC" secondAttribute="trailing" constant="3" id="Lhf-xZ-vWk"/>
<constraint firstItem="JMN-i9-vxR" firstAttribute="top" secondItem="moN-VP-hzI" secondAttribute="top" constant="7" id="O8w-Nb-paE"/>
<constraint firstItem="aWW-9r-3lC" firstAttribute="top" secondItem="moN-VP-hzI" secondAttribute="top" constant="20" id="QgG-WW-zbV"/>
<constraint firstAttribute="bottom" secondItem="JiF-Nx-dl5" secondAttribute="bottom" constant="7" id="SIi-FU-8f2"/>
<constraint firstItem="aWW-9r-3lC" firstAttribute="leading" secondItem="w9P-yZ-pho" secondAttribute="trailing" constant="8" id="dQs-ek-ECt"/>
<constraint firstItem="w9P-yZ-pho" firstAttribute="leading" secondItem="JiF-Nx-dl5" secondAttribute="trailing" constant="13" id="fQn-oM-uvI"/>
<constraint firstItem="aWW-9r-3lC" firstAttribute="leading" secondItem="JMN-i9-vxR" secondAttribute="trailing" constant="8" id="kgo-T3-47B"/>
<constraint firstItem="JiF-Nx-dl5" firstAttribute="leading" secondItem="moN-VP-hzI" secondAttribute="leading" constant="3" id="lYV-gy-fqI"/>
<constraint firstItem="w9P-yZ-pho" firstAttribute="top" secondItem="moN-VP-hzI" secondAttribute="top" constant="29" id="moi-p4-d9X"/>
<constraint firstItem="JMN-i9-vxR" firstAttribute="leading" secondItem="JiF-Nx-dl5" secondAttribute="trailing" constant="13" id="p3K-7u-mdM"/>
<constraint firstAttribute="bottom" secondItem="JMN-i9-vxR" secondAttribute="bottom" constant="21" id="sYy-ZF-GpO"/>
<constraint firstItem="JiF-Nx-dl5" firstAttribute="top" secondItem="moN-VP-hzI" secondAttribute="top" constant="7" id="wcd-hM-fV6"/>
</constraints>
<connections>
<outlet property="imageView" destination="JiF-Nx-dl5" id="pVf-M3-mAH"/>

View File

@ -34,20 +34,6 @@
}
/*
-(void)windowDidLoad
{
//super
[super windowDidLoad];
//load whitelisted items
self.items = [NSMutableArray arrayWithContentsOfFile:[[APP_SUPPORT_DIRECTORY stringByExpandingTildeInPath] stringByAppendingPathComponent:FILE_WHITELIST]];
return;
}
*/
//table delegate
// ->return number of rows
-(NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
@ -75,6 +61,9 @@
//app bundle
NSBundle* appBundle = nil;
//device type
NSString* device = nil;
//sanity check
if(row >= self.items.count)
{
@ -83,7 +72,7 @@
}
//grab process path
processPath = [self.items objectAtIndex:row];
processPath = [[self.items objectAtIndex:row] objectForKey:EVENT_PROCESS_PATH];
//try find an app bundle
appBundle = findAppBundle(processPath);
@ -104,6 +93,19 @@
//grab icon
processIcon = getIconForProcess(processPath);
//set device type for audio
if(SOURCE_AUDIO.intValue == [[[self.items objectAtIndex:row] objectForKey:EVENT_DEVICE] intValue])
{
//set
device = @"mic";
}
//set device type for mic
else if(SOURCE_VIDEO.intValue == [[[self.items objectAtIndex:row] objectForKey:EVENT_DEVICE] intValue])
{
//set
device = @"camera";
}
//init table cell
tableCell = [tableView makeViewWithIdentifier:@"itemCell" owner:self];
if(nil == tableCell)
@ -116,7 +118,8 @@
tableCell.imageView.image = processIcon;
//set (main) text
tableCell.textField.stringValue = processName;
// process name (device)
tableCell.textField.stringValue = [NSString stringWithFormat:@"%@ (access: %@)", processName, device];
//set sub text
[[tableCell viewWithTag:TABLE_ROW_SUB_TEXT_TAG] setStringValue:processPath];
@ -166,27 +169,39 @@ bail:
//index of selected row
NSInteger selectedRow = 0;
//item
NSDictionary* item = nil;
//rule
NSString* processPath = nil;
//device
NSNumber* device = nil;
//grab selected row
selectedRow = [self.tableView rowForView:sender];
//extract selected item
processPath = self.items[selectedRow];
//grab item
item = self.items[selectedRow];
//extract path
processPath = item[EVENT_PROCESS_PATH];
//extract device
device = item[EVENT_DEVICE];
//remove from items
[self.items removeObject:processPath];
[self.items removeObject:item];
//reload table
[self.tableView reloadData];
//restart login item in background
// ->pass in process name so it can un-whitelist via XPC
// ->pass in process path/device so it can un-whitelist via XPC
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^{
//restart
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) startLoginItem:YES args:@[processPath]];
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) startLoginItem:YES args:@[processPath, [device stringValue]]];
});
return;

View File

@ -27,6 +27,9 @@
//sample binary
#define SAMPLE @"/usr/bin/sample"
//path to siri
#define SIRI @"/System/Library/PrivateFrameworks/AssistantServices.framework/assistantd"
/* PROPERTIES */

View File

@ -388,13 +388,50 @@ bail:
//assign
candidateAudioProcs = [[intersection allObjects] mutableCopy];
//if there aren't any new i/o registy clients and only one new mach sender
// ->use that! (e.g. Siri, reactivated)
if( (0 == candidateAudioProcs.count) &&
(1 == newSenders.count) )
//if there aren't any new i/o registy clients might just be siri
if(0 == candidateAudioProcs.count)
{
//assign as candidate
[candidateAudioProcs addObject:newSenders.firstObject];
//dbg msg
#ifdef DEBUG
logMsg(LOG_DEBUG, @"no new user clients");
#endif
//1 new mach msg sender
// just use that as candidate
if(1 == newSenders.count)
{
//dbg msg
#ifdef DEBUG
logMsg(LOG_DEBUG, @"but only found one new mach sender, so using that!");
#endif
//assign as candidate
[candidateAudioProcs addObject:newSenders.firstObject];
}
//more than
// ->check if any are siri ('assisantd')?
else
{
//check each new ones
for(NSNumber* newSender in newSenders)
{
//check each
if(YES == [SIRI isEqualToString:getProcessPath([newSender intValue])])
{
//dbg msg
#ifdef DEBUG
logMsg(LOG_DEBUG, @"found a mach sender that's 'siri' so using that!");
#endif
//assign as candidate
[candidateAudioProcs addObject:newSenders.firstObject];
//all set
break;
}
}
}
}
//dbg msg
@ -413,6 +450,7 @@ bail:
goto bail;
}
//got more than one candidate
// ->invoke 'sample' to determine which candidate is using CMIO/video inputs
// note: will skip FaceTime.app on macOS Sierra, as it doesn't do CMIO stuff directly
audioProcs = [self sampleCandidates:candidateAudioProcs];

View File

@ -77,7 +77,7 @@
}
//whitelist a process
-(void)whitelistProcess:(NSString*)processPath reply:(void (^)(BOOL))reply
-(void)whitelistProcess:(NSString*)processPath device:(NSNumber*)device reply:(void (^)(BOOL))reply
{
//flag
BOOL wasAdded = NO;
@ -106,7 +106,7 @@
}
//add
[whiteList addObject:processPath];
[whiteList addObject:@{EVENT_PROCESS_PATH:processPath, EVENT_DEVICE:device}];
//check if intermediate dirs exist
// ->create them if they aren't there yet
@ -151,7 +151,7 @@ bail:
}
//remove a process from the whitelist file
-(void)unWhitelistProcess:(NSString*)processPath reply:(void (^)(BOOL))reply
-(void)unWhitelistProcess:(NSString*)processPath device:(NSNumber*)device reply:(void (^)(BOOL))reply
{
//flag
BOOL wasRemoved = NO;
@ -162,6 +162,11 @@ bail:
//whitelist
NSMutableArray* whiteList = nil;
//dbg msg
#ifdef DEBUG
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"got request to unwhitelist %@/%@", processPath, device]);
#endif
//init path to whitelist
path = [[APP_SUPPORT_DIRECTORY stringByExpandingTildeInPath] stringByAppendingPathComponent:FILE_WHITELIST];
@ -176,22 +181,40 @@ bail:
goto bail;
}
//remove item
[whiteList removeObject:processPath];
//save to disk
if(YES != [whiteList writeToFile:path atomically:YES])
//find/remove item from whitelist
for(NSDictionary* item in whiteList)
{
//err msg
logMsg(LOG_ERR, [NSString stringWithFormat:@"XPC: failed to save updated whitelist to %@", path]);
//bail
goto bail;
//match path and device?
if( (YES == [item[EVENT_PROCESS_PATH] isEqualToString:processPath]) &&
([item[EVENT_DEVICE] intValue] == device.intValue) )
{
//dbg msg
#ifdef DEBUG
logMsg(LOG_DEBUG, @"found match in whitelist, will remove!");
#endif
//remove
// ->ok, since we aren't going to iterate any more
[whiteList removeObject:item];
//save to disk
if(YES != [whiteList writeToFile:path atomically:YES])
{
//err msg
logMsg(LOG_ERR, [NSString stringWithFormat:@"XPC: failed to save updated whitelist to %@", path]);
//bail
goto bail;
}
//happy
wasRemoved = YES;
//done
goto bail;
}
}
//happy
wasRemoved = YES;
//bail
bail:

View File

@ -43,7 +43,7 @@
<button verticalHuggingPriority="750" fixedFrame="YES" tag="101" translatesAutoresizingMaskIntoConstraints="NO" id="HZZ-Es-mpy">
<rect key="frame" x="280" y="11" width="128" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="more info" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="J9x-sM-h9S">
<buttonCell key="cell" type="push" title="More Info" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="J9x-sM-h9S">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="13" name="Menlo-Regular"/>
</buttonCell>
@ -54,7 +54,7 @@
<button verticalHuggingPriority="750" fixedFrame="YES" tag="100" translatesAutoresizingMaskIntoConstraints="NO" id="xnd-Gw-0o8">
<rect key="frame" x="137" y="11" width="128" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="support us!" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="6g3-Pg-x3P">
<buttonCell key="cell" type="push" title="Support Us!" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="6g3-Pg-x3P">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="13" name="Menlo-Regular"/>
</buttonCell>

View File

@ -29,10 +29,10 @@
-(void)updateAudioStatus:(unsigned int)status reply:(void (^)(void))reply;
//whitelist a process
-(void)whitelistProcess:(NSString*)processPath reply:(void (^)(BOOL))reply;
-(void)whitelistProcess:(NSString*)processPath device:(NSNumber*)device reply:(void (^)(BOOL))reply;
//remove a process from the whitelist file
-(void)unWhitelistProcess:(NSString*)processPath reply:(void (^)(BOOL))reply;
-(void)unWhitelistProcess:(NSString*)processPath device:(NSNumber*)device reply:(void (^)(BOOL))reply;
//kill a process
-(void)killProcess:(NSNumber*)processID reply:(void (^)(BOOL))reply;