17 Commits
Author SHA1 Message Date
Patrick Wardle 237b19800f version 1.3.0 checkin 2018-09-26 14:40:10 +08:00
Patrick Wardle 0a7b73554a version # fix 2018-09-22 13:37:47 +08:00
Patrick Wardle 5201b4d2b7 XPC fixes, UI improvements 2018-09-22 13:37:35 +08:00
Patrick Wardle ffbd6139e0 project cleanup, ui tweaks 2018-09-09 12:23:44 -10:00
Patrick Wardle 4588cd5aee Friends of Objective-See 2018-09-03 19:07:01 -10:00
Patrick Wardle 651b61fef2 ui improvements (dark mode) 2018-09-02 17:16:13 -10:00
Patrick Wardle ff21b9867d mojave updates
-camera
 -permissions check/request
 -capture via login item

-birectional XPC

-project cleanup
2018-09-02 16:31:13 -10:00
Patrick Wardle 292699e5f5 v.1.2.2
updated project to be buildable as an archive
minor UI fixes
2018-06-15 11:32:36 -10:00
Patrick Wardle 681f836fbb always unset 'undelivered' alert after timeout
if alert was not delivered after multiple attempts (i.e. network offline), it wouldn't be cleared, preventing new alerts from being delivered
2018-06-15 08:24:08 -10:00
Patrick Wardle 641e1a9640 v.1.2.1
bumped version strings
2018-06-10 12:59:28 -10:00
Patrick Wardle 8c7c44432f carthage update 2018-05-29 10:43:33 -10:00
Patrick Wardle 4101c011fe cmdline install/uninstall
-see: https://github.com/objective-see/DoNotDisturb/issues/9
2018-05-29 10:18:10 -10:00
Patrick Wardle 76b6271a0c v 1.2.0 (RC)
-linked with updated DND framework (iOS notifications)
-bumped version #
-compiled with update version of Xcode
-minor UI improvements
2018-05-28 10:30:32 -10:00
Patrick Wardle 4927324f85 improved network alert queuing 2018-05-05 11:37:54 -10:00
Patrick Wardle eead935265 alerting queing, UI improvements, etc
-alert(s) now queued if network connectivity isn't immediately present on lid event
-installer now shows 'upgrade' if app is already installed
-certain preference access is now synchronized
2018-05-03 15:40:10 -10:00
Patrick Wardle e5323156a8 improved unistaller, improved (multi)camera selection
-uninstall cleans up empty directory
-uninstall keeps going if it can't login item
-linked w/ new framework which improves camera selection
  --first, looks for apple built in camera
  --otherwise, falls back to default
2018-04-27 10:18:05 -10:00
Patrick Wardle 2510865c24 improved uninstall logic
on uninstall, if no other Objective-See tools are installed remove the '/Library/Objective-See/' directory as well...
2018-04-26 12:11:41 -10:00
77 changed files with 1738 additions and 1605 deletions
+2 -2
View File
@@ -1,2 +1,2 @@
github "DigitaSecurity/dnd" "master"
github "getsentry/sentry-cocoa" "3.12.0"
github "DigitaSecurity/dnd" "cameraUpdates"
github "getsentry/sentry-cocoa" "4.1.0"
+8 -8
View File
@@ -1,14 +1,14 @@
github "Alamofire/Alamofire" "4.7.2"
github "Alamofire/AlamofireImage" "3.3.1"
github "DigitaSecurity/CocoaMQTT" "0c56a9397d5d3fcea4472671e24014a5f31f9b15"
github "DigitaSecurity/dnd" "35e24a1a4397c7b2c08b3bdc0df4a160ad340064"
github "Alamofire/Alamofire" "4.7.3"
github "Alamofire/AlamofireImage" "75fadf98aab78c0829923dd496f369950aa32d6f"
github "DigitaSecurity/CocoaAsyncSocket" "79a11b7036d0a77ca95de42cc1c92b5a4c50f0c9"
github "DigitaSecurity/dnd" "d9a93e985b83d537942e561f028e39b978cb56a5"
github "SnapKit/SnapKit" "4.0.0"
github "SwiftyJSON/SwiftyJSON" "4.1.0"
github "emaloney/CleanroomLogger" "5.1.0"
github "getsentry/sentry-cocoa" "3.12.0"
github "ninjaprox/NVActivityIndicatorView" "4.2.0"
github "emqtt/CocoaMQTT" "b851bdabc01dd98dda9781765ad510d818773819"
github "getsentry/sentry-cocoa" "4.1.0"
github "ninjaprox/NVActivityIndicatorView" "4.3.0"
github "radex/SwiftyTimer" "2.0.0"
github "realm/realm-cocoa" "v3.3.2"
github "robbiehanson/CocoaAsyncSocket" "7.6.3"
github "realm/realm-cocoa" "11dd806fcaacd680d12d616b3a5e93d85bf942f9"
github "saoudrizwan/Disk" "0.3.3"
github "soffes/CommonCrypto" "v1.1.0"
+8 -3
View File
@@ -32,9 +32,14 @@
//super
[super windowDidLoad];
//make white
[self.window setBackgroundColor: NSColor.whiteColor];
//not in mojave dark mode?
// make window color white
if(YES != isDarkMode())
{
//make white
self.window.backgroundColor = NSColor.whiteColor;
}
//set version sting
self.versionLabel.stringValue = [NSString stringWithFormat:@"Version: %@", getAppVersion()];
+2 -9
View File
@@ -12,7 +12,6 @@
#import "Configure.h"
#import "HelperComms.h"
#import "AboutWindowController.h"
#import "ErrorWindowController.h"
#import "ConfigureWindowController.h"
//block for install/uninstall
@@ -30,10 +29,10 @@ typedef void (^block)(NSNumber*);
@property(nonatomic) BOOL gotHelp;
//daemom comms object
@property(nonatomic, retain) HelperComms* xpcComms;
@property(nonatomic, retain)HelperComms* xpcComms;
//status msg
@property (nonatomic, weak) IBOutlet NSTextField *statusMsg;
@property (nonatomic, weak)IBOutlet NSTextField *statusMsg;
//about window controller
@property(nonatomic, retain)AboutWindowController* aboutWindowController;
@@ -41,16 +40,10 @@ typedef void (^block)(NSNumber*);
//configure window controller
@property(nonatomic, retain)ConfigureWindowController* configureWindowController;
//error window controller
@property(nonatomic, retain)ErrorWindowController* errorWindowController;
/* METHODS */
//display configuration window w/ 'install' || 'uninstall' button
-(void)displayConfigureWindow:(BOOL)isInstalled;
//display error window
-(void)displayErrorWindow:(NSDictionary*)errorInfo;
@end
-54
View File
@@ -27,7 +27,6 @@
@synthesize configureObj;
@synthesize aboutWindowController;
@synthesize errorWindowController;
@synthesize configureWindowController;
//main app interface
@@ -143,59 +142,6 @@ bail:
return;
}
//display error window
-(void)displayErrorWindow:(NSDictionary*)errorInfo
{
//alloc error window
errorWindowController = [[ErrorWindowController alloc] initWithWindowNibName:@"ErrorWindowController"];
//main thread
// just show UI alert, unless its fatal (then load URL)
if(YES == [NSThread isMainThread])
{
//non-fatal errors
// show error error popup
if(YES != [errorInfo[KEY_ERROR_URL] isEqualToString:FATAL_ERROR_URL])
{
//display it
// call this first to so that outlets are connected
[self.errorWindowController display];
//configure it
[self.errorWindowController configure:errorInfo];
}
//fatal error
// launch browser to go to fatal error page, then exit
else
{
//launch browser
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:errorInfo[KEY_ERROR_URL]]];
//then exit
[NSApp terminate:self];
}
}
//background thread
// have to show error window on main thread
else
{
//show alert
// in main UI thread
dispatch_sync(dispatch_get_main_queue(), ^{
//display it
// call this first to so that outlets are connected
[self.errorWindowController display];
//configure it
[self.errorWindowController configure:errorInfo];
});
}
return;
}
//menu handler for 'about'
-(IBAction)displayAboutWindow:(id)sender
{
+18 -27
View File
@@ -301,17 +301,12 @@ bail:
//define block
void (^block)(NSNumber *) = ^(NSNumber *result)
{
//callback from XPC will be a bg thread
// so since we're updating UI, invoke on main thread
dispatch_async(dispatch_get_main_queue(), ^{
//signal sema
dispatch_semaphore_signal(semaphore);
//signal sema
dispatch_semaphore_signal(semaphore);
//save result
wasInstalled = (BOOL)(result.intValue == 0);
});
//save result
wasInstalled = (BOOL)(result.intValue == 0);
};
//install
@@ -377,17 +372,11 @@ bail:
//define block
void (^block)(NSNumber *) = ^(NSNumber *result)
{
//callback from XPC will be a bg thread
// so since we're updating UI, invoke on main thread
dispatch_async(dispatch_get_main_queue(), ^{
//signal sema
dispatch_semaphore_signal(semaphore);
//signal sema
dispatch_semaphore_signal(semaphore);
//save result
wasUninstalled = (BOOL)(result.intValue == 0);
});
//save result
wasUninstalled = (BOOL)(result.intValue == 0);
};
//init path to login item
@@ -400,22 +389,24 @@ bail:
//err msg
logMsg(LOG_ERR, @"failed to uninstall login item");
//bail
goto bail;
//keep going though...
}
//dbg msg
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"uninstalled login item (%@)", loginItem]);
#ifdef DEBUG
else
{
//dbg msg
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"uninstalled login item (%@)", loginItem]);
}
#endif
//uninstall
// also sets return var/flag
// also sets return var/flag in block
[xpcComms uninstall:full reply:block];
//wait for install to be completed by XPC
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
bail:
return wasUninstalled;
}
@end
@@ -15,12 +15,27 @@
}
/* PROPERTIES */
@property (weak, nonatomic) IBOutlet NSTextField *statusMsg;
@property (weak, nonatomic) IBOutlet NSButton *installButton;
@property (weak, nonatomic) IBOutlet NSButton *moreInfoButton;
@property (weak, nonatomic) IBOutlet NSButton *uninstallButton;
@property (weak, nonatomic) IBOutlet NSProgressIndicator *activityIndicator;
//config (main) view
@property (weak) IBOutlet NSView *configView;
//"friends of objective-see"
@property (strong, nonatomic) IBOutlet NSView *friendsView;
//status msg
@property (weak, nonatomic) IBOutlet NSTextField *statusMsg;
//install button
@property (weak, nonatomic) IBOutlet NSButton *installButton;
//more info button
@property (weak, nonatomic) IBOutlet NSButton *moreInfoButton;
//uninstall button
@property (weak, nonatomic) IBOutlet NSButton *uninstallButton;
//activity indicator (spinner)
@property (weak, nonatomic) IBOutlet NSProgressIndicator *activityIndicator;
/* METHODS */
+114 -47
View File
@@ -18,6 +18,7 @@
@synthesize statusMsg;
@synthesize moreInfoButton;
@synthesize friendsView;
//automatically called when nib is loaded
// just center window
@@ -50,14 +51,22 @@
// also brings window to front
-(void)configure:(BOOL)isInstalled
{
//init status msg
[self.statusMsg setStringValue:@"evil maids: stay out! 🙅‍♀️🚪"];
//set title
self.window.title = [NSString stringWithFormat:@"Do Not Disturb (v. %@)", getAppVersion()];
//enable 'uninstall' button when app is installed already
//init status msg
self.statusMsg.stringValue = @"evil maids: stay out! 🙅‍♀️🚪";
//app already installed?
// enable 'uninstall' button
// change install button to say 'upgrade'
if(YES == isInstalled)
{
//enable
//enable 'uninstall'
self.uninstallButton.enabled = YES;
//set to 'upgrade'
self.installButton.title = ACTION_UPGRADE;
}
//otherwise disable
else
@@ -87,9 +96,14 @@
//make window front
[NSApp activateIgnoringOtherApps:YES];
//make white
[self.window setBackgroundColor: NSColor.whiteColor];
//not in mojave dark mode?
// make window color white
if(YES != isDarkMode())
{
//make white
self.window.backgroundColor = NSColor.whiteColor;
}
return;
}
@@ -97,42 +111,101 @@
//button handler for uninstall/install
-(IBAction)buttonHandler:(id)sender
{
//frame
NSRect frame = {0};
//action
NSInteger action = 0;
//dbg msg
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"handling action click: %@", ((NSButton*)sender).title]);
//grab tag
//grab action
action = ((NSButton*)sender).tag;
//close?
// close window to trigger exit logic
if(action == ACTION_CLOSE_FLAG)
//dbg msg
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"handling action click: %@ (tag: %ld)", ((NSButton*)sender).title, (long)action]);
//handle various actions
switch(action)
{
//close
[self.window close];
}
//disable 'x' button
// don't want user killing app during install/upgrade
[[self.window standardWindowButton:NSWindowCloseButton] setEnabled:NO];
//clear status msg
[self.statusMsg setStringValue:@""];
//force redraw of status msg
// sometime doesn't refresh (e.g. slow VM)
[self.statusMsg setNeedsDisplay:YES];
//invoke logic to install/uninstall
// do in background so UI doesn't block
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^{
case ACTION_CLOSE_FLAG:
[self.window close];
break;
//install/uninstall
[self lifeCycleEvent:action];
});
case ACTION_INSTALL_FLAG:
case ACTION_UNINSTALL_FLAG:
{
//disable 'x' button
// don't want user killing app during install/upgrade
[[self.window standardWindowButton:NSWindowCloseButton] setEnabled:NO];
//clear status msg
[self.statusMsg setStringValue:@""];
//force redraw of status msg
// sometime doesn't refresh (e.g. slow VM)
[self.statusMsg setNeedsDisplay:YES];
//invoke logic to install/uninstall
// do in background so UI doesn't block
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^{
//install/uninstall
[self lifeCycleEvent:action];
});
break;
}
//next
// show 'friends' view
case ACTION_NEXT_FLAG:
{
//unset window title
self.window.title = @"";
//get main window's frame
frame = self.window.contentView.frame;
//set origin to 0/0
frame.origin = CGPointZero;
//increase y offset
frame.origin.y += 5;
//reduce height
frame.size.height -= 5;
//pre-req
[self.friendsView setWantsLayer:YES];
//update overlay to take up entire window
self.friendsView.frame = frame;
//not in mojave dark mode?
// make window color white
if(YES != isDarkMode())
{
//set white
self.friendsView.layer.backgroundColor = [NSColor whiteColor].CGColor;
}
//update config view
self.window.contentView = self.friendsView;
//show
self.friendsView.hidden = NO;
//draw
self.friendsView.needsDisplay = YES;
}
default:
break;
}
return;
}
@@ -285,18 +358,13 @@
{
//set result msg
resultMsg = [NSMutableString stringWithFormat:@"Do Not Disturb %@ed!", action];
//set font to black
resultMsgColor = [NSColor blackColor];
}
//failure
else
{
//set result msg
resultMsg = [NSMutableString stringWithFormat:@"error: %@ failed", action];
//set font to red
resultMsgColor = [NSColor redColor];
resultMsg = [NSMutableString stringWithFormat:@"Error: %@ failed", action];
//show 'get more info' button
self.moreInfoButton.hidden = NO;
@@ -326,12 +394,11 @@
//set status msg
[self.statusMsg setStringValue:resultMsg];
//set button to close
self.installButton.title = ACTION_CLOSE;
//set button to 'next'
self.installButton.title = ACTION_NEXT;
//update it's tag
// will allow button handler method to detect the close
self.installButton.tag = -1;
//set tag to next
self.installButton.tag = ACTION_NEXT_FLAG;
//enable
self.installButton.enabled = YES;
+46 -42
View File
@@ -1,14 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14313.18"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="ConfigureWindowController">
<connections>
<outlet property="activityIndicator" destination="b1w-5W-ayX" id="P5e-PO-Ozi"/>
<outlet property="configView" destination="se5-gp-TjO" id="F8t-Xo-OlH"/>
<outlet property="friendsView" destination="PmP-2C-4wF" id="INT-Fp-t78"/>
<outlet property="installButton" destination="553-2y-kvm" id="nxf-wO-EI3"/>
<outlet property="moreInfoButton" destination="QWu-qZ-Za2" id="8kC-Ga-5oJ"/>
<outlet property="statusMsg" destination="SpB-Xc-WlB" id="jlm-ke-XfM"/>
@@ -18,11 +20,11 @@
</customObject>
<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" visibleAtLaunch="NO" animationBehavior="default" id="F0z-JX-Cv5">
<window allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES" texturedBackground="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="460" height="176"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1028"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="460" height="176"/>
<autoresizingMask key="autoresizingMask"/>
@@ -67,11 +69,6 @@
<action selector="buttonHandler:" target="-2" id="1wC-Ls-D2F"/>
</connections>
</button>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="K52-9g-sjn">
<rect key="frame" x="138" y="109" width="243" height="67"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="dndText" id="WRg-I2-vkK"/>
</imageView>
<button hidden="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="QWu-qZ-Za2">
<rect key="frame" x="414" y="33" width="25" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
@@ -83,6 +80,11 @@
<action selector="info:" target="-2" id="tg3-SV-AH9"/>
</connections>
</button>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hGI-P1-hcr">
<rect key="frame" x="140" y="113" width="302" height="46"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="dndText" id="ZKa-1w-mi3"/>
</imageView>
</subviews>
</view>
<connections>
@@ -90,44 +92,45 @@
</connections>
<point key="canvasLocation" x="185" y="-256"/>
</window>
<customView id="PmP-2C-4wF" userLabel="Support">
<customView id="PmP-2C-4wF" userLabel="Friends">
<rect key="frame" x="0.0" y="0.0" width="460" height="176"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="f0f-aN-ikB">
<rect key="frame" x="0.0" y="73" width="460" height="95"/>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="MGz-6K-qG8">
<rect key="frame" x="18" y="142" width="424" height="19"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Mahalo to the &quot;Friends of Objective-See&quot;" id="7Bp-jO-RQc">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tSv-y3-y5e">
<rect key="frame" x="80" y="27" width="138" height="19"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Digita Security" id="Jb9-oJ-xk4">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="eld-oV-6lG">
<rect key="frame" x="117" y="54" width="64" height="64"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="objectiveSee" id="8Lr-Ox-eyh"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="digita" id="wJq-yW-MBL"/>
</imageView>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Euc-W6-dQ1" userLabel="No">
<rect key="frame" x="216" y="13" width="115" height="32"/>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="MBu-V2-MAX">
<rect key="frame" x="286" y="54" width="64" height="64"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="No" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="8ir-Qw-y4G">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="malwarebytes" id="DiU-Xn-tkq"/>
</imageView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SDE-Qu-lcq">
<rect key="frame" x="249" y="27" width="138" height="19"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Malwarebytes" id="p1n-KZ-bj5">
<font key="font" size="13" name="Menlo-Regular"/>
</buttonCell>
<connections>
<action selector="buttonHandler:" target="-2" id="uik-ZX-MTQ"/>
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9Sm-sm-Qzm" userLabel="Yes">
<rect key="frame" x="331" y="13" width="115" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Yes!" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="ezp-te-R3O">
<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="Yea-Bv-dgb"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xaj-ED-vIC">
<rect key="frame" x="144" y="60" width="306" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="support our free tools?" id="KSy-eB-CzB">
<font key="font" size="17" name="Menlo-Bold"/>
<color key="textColor" white="0.25" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
@@ -135,8 +138,9 @@
</customView>
</objects>
<resources>
<image name="digita" width="334" height="338"/>
<image name="dndIcon" width="256" height="256"/>
<image name="dndText" width="266.605712890625" height="34.354286193847656"/>
<image name="objectiveSee" width="943" height="236"/>
<image name="dndText" width="164.57142639160156" height="21.188571929931641"/>
<image name="malwarebytes" width="300" height="267"/>
</resources>
</document>
@@ -1,43 +0,0 @@
//
// file: ErrorWindowController.h
// project: DND (config)
// description: error window (header)
//
// created by Patrick Wardle
// copyright (c) 2018 Objective-See. All rights reserved.
//
@import Cocoa;
@interface ErrorWindowController : NSWindowController <NSWindowDelegate>
{
}
//main msg in window
@property (weak, atomic) IBOutlet NSTextField *errMsg;
//sub msg in window
@property (weak, atomic) IBOutlet NSTextField *errSubMsg;
//info/help/fix button
@property (weak, atomic) IBOutlet NSButton *infoButton;
//close button
@property (weak, atomic) IBOutlet NSButton *closeButton;
//(optional) url for 'Info' button
@property(nonatomic, retain) NSURL* errorURL;
//flag indicating close button should exit app
@property(atomic) BOOL shouldExit;
/* METHODS */
//configure the object/window
-(void)configure:(NSDictionary*)errorInfo;
//display (show) window
-(void)display;
@end
-156
View File
@@ -1,156 +0,0 @@
//
// file: ErrorWindowController.m
// project: DND (config)
// description: error window
//
// created by Patrick Wardle
// copyright (c) 2018 Objective-See. All rights reserved.
//
#import "Consts.h"
#import "ErrorWindowController.h"
@interface ErrorWindowController ()
@end
@implementation ErrorWindowController
@synthesize errorURL;
@synthesize shouldExit;
@synthesize closeButton;
//automatically called when nib is loaded
// center window
-(void)awakeFromNib
{
//center
[self.window center];
return;
}
//configure the object/window
-(void)configure:(NSDictionary*)errorInfo
{
//set error msg
self.errMsg.stringValue = errorInfo[KEY_ERROR_MSG];
//set error sub msg
self.errSubMsg.stringValue = errorInfo[KEY_ERROR_SUB_MSG];
//save exit
self.shouldExit = [errorInfo[KEY_ERROR_SHOULD_EXIT] boolValue];
//grab optional error url
if(nil != errorInfo[KEY_ERROR_URL])
{
//extract/convert
self.errorURL = [NSURL URLWithString:errorInfo[KEY_ERROR_URL]];
}
//when exiting
// change 'close' to 'exit'
if(YES == self.shouldExit)
{
//change title
self.closeButton.title = @"Exit";
}
//for fatal errors
// change 'Info' to 'help fix'
if(YES == [[self.errorURL absoluteString] isEqualToString:FATAL_ERROR_URL])
{
//change title
self.infoButton.title = @"Help Fix";
}
//set delegate
[self.window setDelegate:self];
return;
}
//display (show) window
-(void)display
{
//show (now configured), alert
[self showWindow:self];
//make it key window
[self.window makeKeyAndOrderFront:self];
//make window front
[NSApp activateIgnoringOtherApps:YES];
//make 'close' have focus
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 100 * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{
//make close button active
[self.window makeFirstResponder:closeButton];
});
//make white
[self.window setBackgroundColor: NSColor.whiteColor];
return;
}
//invoked when user clicks '?' (help button)
// open url with more info about the error(s)
-(IBAction)help:(id)sender
{
#pragma unused(sender)
//if a url was specified
// use that one
if(nil != self.errorURL)
{
//open URL
// invokes user's default browser
[[NSWorkspace sharedWorkspace] openURL:self.errorURL];
}
//use default URL
else
{
//open URL
// invokes user's default browser
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:FATAL_ERROR_URL]];
}
return;
}
//invoked when user clicks 'close'
// just close window
-(IBAction)close:(id)sender
{
#pragma unused(sender)
//close
[self.window close];
return;
}
//automatically invoked when window is closing
// exit the app if specified...
-(void)windowWillClose:(NSNotification *)notification
{
#pragma unused(notification)
//check if should exit process
// e.g. an error during install, etc
if(YES == self.shouldExit)
{
//dbg msg
//logMsg(LOG_DEBUG, @"exiting application");
//exit
[NSApp terminate:self];
}
return;
}
@end
@@ -1,85 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="ErrorWindowController">
<connections>
<outlet property="closeButton" destination="zbs-ul-WTJ" id="1fu-zv-brA"/>
<outlet property="errMsg" destination="Act-U9-8G9" id="PMa-6M-gwu"/>
<outlet property="errSubMsg" destination="tQ0-f2-G4C" id="4hz-9M-Gub"/>
<outlet property="infoButton" destination="sNV-Jw-9dZ" id="qdf-xQ-ubf"/>
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Do Not Disturb Error" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES" texturedBackground="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="744" y="427" width="380" height="137"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="380" height="137"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zbs-ul-WTJ">
<rect key="frame" x="284" y="13" width="82" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Close" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Pjp-Se-SfK">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="close:" target="-2" id="sez-MW-4AE"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="tQ0-f2-G4C">
<rect key="frame" x="114" y="49" width="248" height="36"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" alignment="left" title="Label" id="sk0-EF-ZfG">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" preferredMaxLayoutWidth="0.0" translatesAutoresizingMaskIntoConstraints="NO" id="Act-U9-8G9">
<rect key="frame" x="114" y="88" width="248" height="20"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="ERROR msg" id="VCu-zh-Vcs">
<font key="font" size="13" name="Menlo-Bold"/>
<color key="textColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="sNV-Jw-9dZ">
<rect key="frame" x="202" y="13" width="82" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Info" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="L1w-RB-EC4">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="help:" target="-2" id="gCm-No-dHq"/>
</connections>
</button>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="sRj-I0-15e">
<rect key="frame" x="12" y="35" width="92" height="92"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="dndIcon" id="9iG-ot-b7i"/>
</imageView>
</subviews>
</view>
<connections>
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
</connections>
<point key="canvasLocation" x="257" y="269.5"/>
</window>
</objects>
<resources>
<image name="dndIcon" width="256" height="256"/>
</resources>
</document>
Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

+2 -2
View File
@@ -13,11 +13,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.1.0</string>
<string>1.3.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.1.0</string>
<string>1.3.0</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright (c) 2018 Objective-See</string>
<key>NSMainNibFile</key>
+8
View File
@@ -75,6 +75,14 @@ elif [ "${1}" == "-uninstall" ]; then
if [[ "${2}" -eq "1" ]]; then
rm -rf $INSTALL_DIRECTORY
#no other objective-see tools?
# then delete that directory too
baseDir=$(dirname $INSTALL_DIRECTORY)
if [ ! "$(ls -A $baseDir)" ]; then
rm -rf $baseDir
fi
#partial
# just delete daemon, leaving prefs, etc
else
+116 -1
View File
@@ -9,7 +9,122 @@
@import Cocoa;
#import "Consts.h"
#import "Logging.h"
#import "utilities.h"
#import "Configure.h"
//cmdline interface
// install or uninstall
BOOL cmdlineInterface(int action);
//main interface
int main(int argc, char *argv[])
{
return NSApplicationMain(argc, (const char **) argv);
//status
int status = -1;
//cmdline install?
if(YES == [[[NSProcessInfo processInfo] arguments] containsObject:CMDLINE_FLAG_INSTALL])
{
//dbg msg
logMsg(LOG_DEBUG, @"performing commandline install");
//install
if(YES != cmdlineInterface(ACTION_INSTALL_FLAG))
{
//err msg
printf("\nDND ERROR: install failed\n\n");
//bail
goto bail;
}
//dbg msg
printf("DND: install ok!\n");
//happy
status = 0;
}
//cmdline uninstall?
else if(YES == [[[NSProcessInfo processInfo] arguments] containsObject:CMDLINE_FLAG_UNINSTALL])
{
//dbg msg
logMsg(LOG_DEBUG, @"performing commandline uninstall");
//install
if(YES != cmdlineInterface(ACTION_UNINSTALL_FLAG))
{
//err msg
printf("\nDND ERROR: uninstall failed\n\n");
//bail
goto bail;
}
//dbg msg
printf("DND: uninstall ok!\n");
//happy
status = 0;
}
//default run mode
// just kick off main app logic
else
{
//app main
status = NSApplicationMain(argc, (const char **) argv);
}
bail:
return status;
}
//cmdline interface
// install or uninstall
BOOL cmdlineInterface(int action)
{
//flag
BOOL wasConfigured = NO;
//configure obj
Configure* configure = nil;
//alloc/init
configure = [[Configure alloc] init];
//first check root
if(0 != geteuid())
{
//err msg
printf("\nDND ERROR: cmdline interface actions require root!\n\n");
//bail
goto bail;
}
//configure
wasConfigured = [configure configure:action];
if(YES != wasConfigured)
{
//bail
goto bail;
}
//happy
wasConfigured = YES;
bail:
//cleanup
if(nil != configure)
{
//cleanup
[configure removeHelper];
}
return wasConfigured;
}
+2 -2
View File
@@ -37,7 +37,7 @@ dispatch_source_t dispatchSource = nil;
//configure
// pass in 'install' flag
result = [NSNumber numberWithInt:[self configure:app arguements:@[@"-install"]]];
result = [NSNumber numberWithInt:[self configure:app arguements:@[CMDLINE_FLAG_INSTALL]]];
//reply to client
reply(result);
@@ -57,7 +57,7 @@ dispatch_source_t dispatchSource = nil;
//configure
// pass in 'uninstall' flag, and partial/full
result = [NSNumber numberWithInt:[self configure:app arguements:@[@"-uninstall", [NSNumber numberWithBool:full].stringValue]]];
result = [NSNumber numberWithInt:[self configure:app arguements:@[CMDLINE_FLAG_UNINSTALL, [NSNumber numberWithBool:full].stringValue]]];
//reply to client
reply(result);
+1 -1
View File
@@ -9,7 +9,7 @@
<key>CFBundleName</key>
<string>helper</string>
<key>CFBundleVersion</key>
<string>1.1.0</string>
<string>1.3.0</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright (c) 2018 Objective-See</string>
<key>SMAuthorizedClients</key>
+49 -24
View File
@@ -11,22 +11,20 @@
4BE4906110445E13006BE471 /* Helper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4905510445DDD006BE471 /* Helper.m */; };
4BE4906410445F2F006BE471 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BE4906310445F2F006BE471 /* Security.framework */; };
4BE4906810445F36006BE471 /* ServiceManagement.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BE4906710445F36006BE471 /* ServiceManagement.framework */; };
4BE49092104463A0006BE471 /* com.objective-see.dnd.installer.helper in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4BE4905D10445E0A006BE471 /* com.objective-see.dnd.installer.helper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
4BE49092104463A0006BE471 /* com.objective-see.dnd.installer.helper in Copy Helper */ = {isa = PBXBuildFile; fileRef = 4BE4905D10445E0A006BE471 /* com.objective-see.dnd.installer.helper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
BF04235611C0531400431286 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = BF04235511C0531400431286 /* AppDelegate.m */; };
BF65C19111B985C0007C20AB /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = BF65C19011B985C0007C20AB /* MainMenu.xib */; };
CD17D53B20104DD700F798D7 /* Logging.m in Sources */ = {isa = PBXBuildFile; fileRef = CD17D53820104DD700F798D7 /* Logging.m */; };
CD17D54D20104EE700F798D7 /* ErrorWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = CD17D54320104EE600F798D7 /* ErrorWindowController.xib */; };
CD17D54E20104EE700F798D7 /* AboutWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CD17D54420104EE700F798D7 /* AboutWindow.xib */; };
CD17D54F20104EE700F798D7 /* Configure.m in Sources */ = {isa = PBXBuildFile; fileRef = CD17D54720104EE700F798D7 /* Configure.m */; };
CD17D55020104EE700F798D7 /* ConfigureWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = CD17D54820104EE700F798D7 /* ConfigureWindowController.m */; };
CD17D55120104EE700F798D7 /* ConfigureWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = CD17D54920104EE700F798D7 /* ConfigureWindowController.xib */; };
CD17D55220104EE700F798D7 /* ErrorWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = CD17D54A20104EE700F798D7 /* ErrorWindowController.m */; };
CD17D55320104EE700F798D7 /* AboutWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = CD17D54B20104EE700F798D7 /* AboutWindowController.m */; };
CD17D55E201148F900F798D7 /* configure.sh in Resources */ = {isa = PBXBuildFile; fileRef = CD17D55D201148F900F798D7 /* configure.sh */; };
CD17D56320116C3800F798D7 /* com.objective-see.dnd.plist in Resources */ = {isa = PBXBuildFile; fileRef = CD17D56220116C3800F798D7 /* com.objective-see.dnd.plist */; };
CD20A0D02057992F0044BCC5 /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD20A0CF2057992F0044BCC5 /* Sentry.framework */; };
CD20A0D320579A380044BCC5 /* Sentry.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CD20A0CF2057992F0044BCC5 /* Sentry.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
CD20A0D320579A380044BCC5 /* Sentry.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = CD20A0CF2057992F0044BCC5 /* Sentry.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
CD2F4082204B462E0066673E /* dndText.png in Resources */ = {isa = PBXBuildFile; fileRef = CDAAC24A20226DFB0032F2E6 /* dndText.png */; };
CD3307AE203567D500F10D71 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CD3307AD203567D400F10D71 /* Assets.xcassets */; };
CD73DA912004629D001FFC84 /* HelperInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = CD73DA902004629D001FFC84 /* HelperInterface.m */; };
@@ -40,6 +38,8 @@
CDAAC24B20226DFB0032F2E6 /* objectiveSee.png in Resources */ = {isa = PBXBuildFile; fileRef = CDAAC24720226DFB0032F2E6 /* objectiveSee.png */; };
CDAAC24C20226DFB0032F2E6 /* logo.png in Resources */ = {isa = PBXBuildFile; fileRef = CDAAC24820226DFB0032F2E6 /* logo.png */; };
CDAAC24D20226DFB0032F2E6 /* dndIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = CDAAC24920226DFB0032F2E6 /* dndIcon.png */; };
CDFA08CF213E3C280089758C /* malwarebytes.png in Resources */ = {isa = PBXBuildFile; fileRef = CDFA08CD213E3C280089758C /* malwarebytes.png */; };
CDFA08D1213E3DD50089758C /* digita.png in Resources */ = {isa = PBXBuildFile; fileRef = CDFA08D0213E3DD50089758C /* digita.png */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -53,24 +53,36 @@
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
4BE49098104463C5006BE471 /* CopyFiles */ = {
4BE49098104463C5006BE471 /* Copy Helper */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = Contents/Library/LaunchServices;
dstSubfolderSpec = 1;
files = (
4BE49092104463A0006BE471 /* com.objective-see.dnd.installer.helper in CopyFiles */,
4BE49092104463A0006BE471 /* com.objective-see.dnd.installer.helper in Copy Helper */,
);
name = "Copy Helper";
runOnlyForDeploymentPostprocessing = 0;
};
CD20A0D220579A1B0044BCC5 /* CopyFiles */ = {
CD20A0D220579A1B0044BCC5 /* Copy Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
CD20A0D320579A380044BCC5 /* Sentry.framework in CopyFiles */,
CD20A0D320579A380044BCC5 /* Sentry.framework in Copy Frameworks */,
);
name = "Copy Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
CDD3ADF42135285B004F805F /* Copy Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Copy Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
@@ -93,16 +105,13 @@
CD17D53A20104DD700F798D7 /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../shared/Logging.h; sourceTree = "<group>"; };
CD17D53E20104E5A00F798D7 /* Consts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Consts.h; path = ../../shared/Consts.h; sourceTree = "<group>"; };
CD17D54220104EE600F798D7 /* AboutWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AboutWindowController.h; sourceTree = "<group>"; };
CD17D54320104EE600F798D7 /* ErrorWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ErrorWindowController.xib; sourceTree = "<group>"; };
CD17D54420104EE700F798D7 /* AboutWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AboutWindow.xib; sourceTree = "<group>"; };
CD17D54520104EE700F798D7 /* Configure.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Configure.h; sourceTree = "<group>"; };
CD17D54620104EE700F798D7 /* ConfigureWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConfigureWindowController.h; sourceTree = "<group>"; };
CD17D54720104EE700F798D7 /* Configure.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Configure.m; sourceTree = "<group>"; };
CD17D54820104EE700F798D7 /* ConfigureWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConfigureWindowController.m; sourceTree = "<group>"; };
CD17D54920104EE700F798D7 /* ConfigureWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ConfigureWindowController.xib; sourceTree = "<group>"; };
CD17D54A20104EE700F798D7 /* ErrorWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ErrorWindowController.m; sourceTree = "<group>"; };
CD17D54B20104EE700F798D7 /* AboutWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AboutWindowController.m; sourceTree = "<group>"; };
CD17D54C20104EE700F798D7 /* ErrorWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ErrorWindowController.h; sourceTree = "<group>"; };
CD17D55D201148F900F798D7 /* configure.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure.sh; sourceTree = "<group>"; };
CD17D56220116C3800F798D7 /* com.objective-see.dnd.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "com.objective-see.dnd.plist"; path = "../launchDaemon/launchDaemon/com.objective-see.dnd.plist"; sourceTree = "<group>"; };
CD18D64C200DA301005609F9 /* XPCProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XPCProtocol.h; path = Shared/XPCProtocol.h; sourceTree = SOURCE_ROOT; };
@@ -120,6 +129,8 @@
CDAAC24820226DFB0032F2E6 /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = logo.png; path = ../../shared/images/logo.png; sourceTree = "<group>"; };
CDAAC24920226DFB0032F2E6 /* dndIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dndIcon.png; path = ../../shared/images/dndIcon.png; sourceTree = "<group>"; };
CDAAC24A20226DFB0032F2E6 /* dndText.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dndText.png; path = ../../shared/images/dndText.png; sourceTree = "<group>"; };
CDFA08CD213E3C280089758C /* malwarebytes.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = malwarebytes.png; path = Images/malwarebytes.png; sourceTree = "<group>"; };
CDFA08D0213E3DD50089758C /* digita.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = digita.png; path = Images/digita.png; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -181,6 +192,7 @@
4BE4904710445D49006BE471 /* Configure */ = {
isa = PBXGroup;
children = (
CDFA08CB213E3C170089758C /* Images */,
CD3307AD203567D400F10D71 /* Assets.xcassets */,
CD17D54420104EE700F798D7 /* AboutWindow.xib */,
CD17D54220104EE600F798D7 /* AboutWindowController.h */,
@@ -190,9 +202,6 @@
CD17D54620104EE700F798D7 /* ConfigureWindowController.h */,
CD17D54820104EE700F798D7 /* ConfigureWindowController.m */,
CD17D54920104EE700F798D7 /* ConfigureWindowController.xib */,
CD17D54C20104EE700F798D7 /* ErrorWindowController.h */,
CD17D54A20104EE700F798D7 /* ErrorWindowController.m */,
CD17D54320104EE600F798D7 /* ErrorWindowController.xib */,
CD73DA98200490B4001FFC84 /* HelperComms.h */,
CD73DA97200490B4001FFC84 /* HelperComms.m */,
4BE4904C10445D49006BE471 /* Info.plist */,
@@ -260,6 +269,15 @@
name = Images;
sourceTree = "<group>";
};
CDFA08CB213E3C170089758C /* Images */ = {
isa = PBXGroup;
children = (
CDFA08D0213E3DD50089758C /* digita.png */,
CDFA08CD213E3C280089758C /* malwarebytes.png */,
);
name = Images;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -269,6 +287,7 @@
buildPhases = (
4BE4905A10445E0A006BE471 /* Sources */,
4BE4905B10445E0A006BE471 /* Frameworks */,
CDD3ADF42135285B004F805F /* Copy Frameworks */,
);
buildRules = (
);
@@ -286,9 +305,9 @@
8D1107290486CEB800E47090 /* Resources */,
8D11072C0486CEB800E47090 /* Sources */,
8D11072E0486CEB800E47090 /* Frameworks */,
4BE49098104463C5006BE471 /* CopyFiles */,
4BE49098104463C5006BE471 /* Copy Helper */,
CD17D55F20115E5E00F798D7 /* ShellScript */,
CD20A0D220579A1B0044BCC5 /* CopyFiles */,
CD20A0D220579A1B0044BCC5 /* Copy Frameworks */,
);
buildRules = (
);
@@ -307,7 +326,7 @@
29B97313FDCFA39411CA2CEA /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0920;
LastUpgradeCheck = 1000;
TargetAttributes = {
4BE4905C10445E0A006BE471 = {
DevelopmentTeam = VBG97UB4TA;
@@ -342,7 +361,6 @@
buildActionMask = 2147483647;
files = (
CD2F4082204B462E0066673E /* dndText.png in Resources */,
CD17D54D20104EE700F798D7 /* ErrorWindowController.xib in Resources */,
CDAAC24C20226DFB0032F2E6 /* logo.png in Resources */,
CD17D56320116C3800F798D7 /* com.objective-see.dnd.plist in Resources */,
CDAAC24B20226DFB0032F2E6 /* objectiveSee.png in Resources */,
@@ -352,6 +370,8 @@
CD17D54E20104EE700F798D7 /* AboutWindow.xib in Resources */,
CD3307AE203567D500F10D71 /* Assets.xcassets in Resources */,
CD17D55120104EE700F798D7 /* ConfigureWindowController.xib in Resources */,
CDFA08CF213E3C280089758C /* malwarebytes.png in Resources */,
CDFA08D1213E3DD50089758C /* digita.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -369,7 +389,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "cp -R -f \"$BUILT_PRODUCTS_DIR/Do Not Disturb.app\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Resources\"\n\nrm -rf \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Resources/Do Not Disturb.bundle\"\ncp -R -f \"$BUILT_PRODUCTS_DIR/Do Not Disturb.bundle\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Resources\"";
shellScript = "#archiving\nif [[ $BUILT_PRODUCTS_DIR = *\"ArchiveIntermediates\"* ]]; then\n\ncp -R -f \"$PROJECT_TEMP_ROOT/UninstalledProducts/macosx/Do Not Disturb.app\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Resources\"\ncp -R -f \"$PROJECT_TEMP_ROOT/UninstalledProducts/macosx/Do Not Disturb.bundle\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Resources\"\n\n#normal build\nelse\n\ncp -R -f \"$BUILT_PRODUCTS_DIR/Do Not Disturb.app\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Resources\"\nrm -rf \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Resources/Do Not Disturb.bundle\"\ncp -R -f \"$BUILT_PRODUCTS_DIR/Do Not Disturb.bundle\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Resources\"\n\nfi\n";
};
/* End PBXShellScriptBuildPhase section */
@@ -390,7 +410,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CD17D55220104EE700F798D7 /* ErrorWindowController.m in Sources */,
4BE4905110445D49006BE471 /* main.m in Sources */,
CD73DA942004633A001FFC84 /* HelperListener.m in Sources */,
CD17D55320104EE700F798D7 /* AboutWindowController.m in Sources */,
@@ -420,9 +439,10 @@
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_IDENTITY = "Developer ID Application";
CODE_SIGN_IDENTITY = "Mac Developer";
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_TEAM = VBG97UB4TA;
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../Carthage/Build/Mac";
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = NO;
INFOPLIST_FILE = Helper/Info.plist;
OTHER_LDFLAGS = (
@@ -448,9 +468,10 @@
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_IDENTITY = "Developer ID Application";
CODE_SIGN_IDENTITY = "Mac Developer";
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_TEAM = VBG97UB4TA;
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../Carthage/Build/Mac";
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = NO;
INFOPLIST_FILE = Helper/Info.plist;
OTHER_LDFLAGS = (
@@ -489,6 +510,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.objective-see.dnd.installer";
PRODUCT_NAME = "Do Not Disturb Installer";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = NO;
VALID_ARCHS = x86_64;
};
name = Debug;
@@ -511,6 +533,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.objective-see.dnd.installer";
PRODUCT_NAME = "Do Not Disturb Installer";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = NO;
VALID_ARCHS = x86_64;
};
name = Release;
@@ -529,13 +552,14 @@
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "Developer ID Application: Objective-See, LLC (VBG97UB4TA)";
CODE_SIGN_IDENTITY = "Mac Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_STRICT_OBJC_MSGSEND = YES;
@@ -580,13 +604,14 @@
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "Developer ID Application: Objective-See, LLC (VBG97UB4TA)";
CODE_SIGN_IDENTITY = "Mac Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_STRICT_OBJC_MSGSEND = YES;
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0920"
LastUpgradeVersion = "1000"
version = "1.3">
<BuildAction
parallelizeBuildables = "NO"
@@ -68,7 +68,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
@@ -85,10 +84,9 @@
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
+2 -2
View File
@@ -15,9 +15,9 @@
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.1.0</string>
<string>1.3.0</string>
<key>CFBundleVersion</key>
<string>1.1.0</string>
<string>1.3.0</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2018 Objective-See. All rights reserved.</string>
<key>NSPrincipalClass</key>
@@ -7,7 +7,6 @@
objects = {
/* Begin PBXBuildFile section */
209E459F203DF5D500900B89 /* Do Not Disturb in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7D7755D01F02DF9500D0017D /* Do Not Disturb */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
209E45B0203DF64E00900B89 /* Realm.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 209E45A2203DF64E00900B89 /* Realm.framework */; };
209E45B1203DF64E00900B89 /* AlamofireImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 209E45A3203DF64E00900B89 /* AlamofireImage.framework */; };
209E45B2203DF64E00900B89 /* CleanroomLogger.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 209E45A4203DF64E00900B89 /* CleanroomLogger.framework */; };
@@ -19,33 +18,31 @@
209E45B9203DF64E00900B89 /* CocoaMQTT.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 209E45AB203DF64E00900B89 /* CocoaMQTT.framework */; };
209E45BB203DF64E00900B89 /* RealmSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 209E45AD203DF64E00900B89 /* RealmSwift.framework */; };
209E45BC203DF64E00900B89 /* dnd.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 209E45AE203DF64E00900B89 /* dnd.framework */; };
20C87249204609A900F1275D /* Alamofire.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 209E45A7203DF64E00900B89 /* Alamofire.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C8724A204609A900F1275D /* AlamofireImage.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 209E45A3203DF64E00900B89 /* AlamofireImage.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C8724C204609A900F1275D /* CleanroomLogger.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 209E45A4203DF64E00900B89 /* CleanroomLogger.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C8724D204609A900F1275D /* CocoaAsyncSocket.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 209E45A5203DF64E00900B89 /* CocoaAsyncSocket.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C8724E204609A900F1275D /* CocoaMQTT.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 209E45AB203DF64E00900B89 /* CocoaMQTT.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C8724F204609A900F1275D /* CommonCrypto.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 209E45A6203DF64E00900B89 /* CommonCrypto.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C87250204609A900F1275D /* dnd.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 209E45AE203DF64E00900B89 /* dnd.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C87252204609A900F1275D /* Realm.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 209E45A2203DF64E00900B89 /* Realm.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C87253204609A900F1275D /* RealmSwift.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 209E45AD203DF64E00900B89 /* RealmSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C87255204609A900F1275D /* SwiftyJSON.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 209E45AA203DF64E00900B89 /* SwiftyJSON.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C87256204609A900F1275D /* SwiftyTimer.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 209E45A8203DF64E00900B89 /* SwiftyTimer.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C8725B20460A7E00F1275D /* deviceCSRRequest.p12 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 20C8725820460A7D00F1275D /* deviceCSRRequest.p12 */; };
20C8725C20460A7E00F1275D /* rootCA.pem in CopyFiles */ = {isa = PBXBuildFile; fileRef = 20C8725920460A7E00F1275D /* rootCA.pem */; };
20C8725D20460A7E00F1275D /* awsRootCA.pem in CopyFiles */ = {isa = PBXBuildFile; fileRef = 20C8725A20460A7E00F1275D /* awsRootCA.pem */; };
7D46FEFF1F5E41F000FEB0F8 /* UserCommsListener.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D46FEFD1F5E41F000FEB0F8 /* UserCommsListener.m */; };
20C87249204609A900F1275D /* Alamofire.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 209E45A7203DF64E00900B89 /* Alamofire.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C8724A204609A900F1275D /* AlamofireImage.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 209E45A3203DF64E00900B89 /* AlamofireImage.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C8724C204609A900F1275D /* CleanroomLogger.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 209E45A4203DF64E00900B89 /* CleanroomLogger.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C8724D204609A900F1275D /* CocoaAsyncSocket.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 209E45A5203DF64E00900B89 /* CocoaAsyncSocket.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C8724E204609A900F1275D /* CocoaMQTT.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 209E45AB203DF64E00900B89 /* CocoaMQTT.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C8724F204609A900F1275D /* CommonCrypto.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 209E45A6203DF64E00900B89 /* CommonCrypto.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C87250204609A900F1275D /* dnd.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 209E45AE203DF64E00900B89 /* dnd.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C87252204609A900F1275D /* Realm.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 209E45A2203DF64E00900B89 /* Realm.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C87253204609A900F1275D /* RealmSwift.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 209E45AD203DF64E00900B89 /* RealmSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C87255204609A900F1275D /* SwiftyJSON.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 209E45AA203DF64E00900B89 /* SwiftyJSON.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C87256204609A900F1275D /* SwiftyTimer.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 209E45A8203DF64E00900B89 /* SwiftyTimer.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20C8725B20460A7E00F1275D /* deviceCSRRequest.p12 in Copy Certs */ = {isa = PBXBuildFile; fileRef = 20C8725820460A7D00F1275D /* deviceCSRRequest.p12 */; };
20C8725C20460A7E00F1275D /* rootCA.pem in Copy Certs */ = {isa = PBXBuildFile; fileRef = 20C8725920460A7E00F1275D /* rootCA.pem */; };
20C8725D20460A7E00F1275D /* awsRootCA.pem in Copy Certs */ = {isa = PBXBuildFile; fileRef = 20C8725A20460A7E00F1275D /* awsRootCA.pem */; };
7D46FEFF1F5E41F000FEB0F8 /* XPCListener.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D46FEFD1F5E41F000FEB0F8 /* XPCListener.m */; };
7D4FF8C41F0E1402001A4A68 /* libbsm.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 7D4FF8C31F0E1402001A4A68 /* libbsm.tbd */; };
7D4FF8CD1F0EF2F9001A4A68 /* UserComms.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D4FF8CC1F0EF2F9001A4A68 /* UserComms.m */; };
7D4FF8CD1F0EF2F9001A4A68 /* XPCDaemon.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D4FF8CC1F0EF2F9001A4A68 /* XPCDaemon.m */; };
7D6E87701F3AE6FA00D6BD7C /* libprocInfo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7D6E876F1F3AE6FA00D6BD7C /* libprocInfo.a */; };
7D7755D41F02DF9500D0017D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D7755D31F02DF9500D0017D /* main.m */; };
7D7755FC1F02EBBE00D0017D /* Logging.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D7755FA1F02EBBE00D0017D /* Logging.m */; };
7DD2BF681F1DC42700B33214 /* Utilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DD2BF671F1DC42700B33214 /* Utilities.m */; };
7DD2BF761F1E9CE700B33214 /* NSMutableArray+QueueAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DD2BF731F1E9CE700B33214 /* NSMutableArray+QueueAdditions.m */; };
7DD2BF771F1E9CE700B33214 /* Queue.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DD2BF751F1E9CE700B33214 /* Queue.m */; };
CD20869B208E8F0200BA1D0A /* VolumeMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = CD208698208E8B1200BA1D0A /* VolumeMonitor.m */; };
CD20A0CA205793040044BCC5 /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD20A0C9205793040044BCC5 /* Sentry.framework */; };
CD20A0CB205793100044BCC5 /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD20A0C9205793040044BCC5 /* Sentry.framework */; };
CD20A0CC205793680044BCC5 /* Sentry.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CD20A0C9205793040044BCC5 /* Sentry.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
CD20A0CC205793680044BCC5 /* Sentry.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = CD20A0C9205793040044BCC5 /* Sentry.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
CD22786620463F0700C72C76 /* dnd.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD22786420463EB000C72C76 /* dnd.framework */; };
CD22786C20464A6E00C72C76 /* Preferences.m in Sources */ = {isa = PBXBuildFile; fileRef = CD22786A204648E000C72C76 /* Preferences.m */; };
CD256E022050DE9B00768457 /* ProcListener.m in Sources */ = {isa = PBXBuildFile; fileRef = CD256E002050DE6600768457 /* ProcListener.m */; };
@@ -56,6 +53,7 @@
CD256E072050DE9B00768457 /* USBMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = CD256DF52050DE4C00768457 /* USBMonitor.m */; };
CD256E082050DE9B00768457 /* UserAuthMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = CD256DED2050DE4B00768457 /* UserAuthMonitor.m */; };
CDA993A62048905D00C1E9CD /* FrameworkInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = CDA993A42048905D00C1E9CD /* FrameworkInterface.m */; };
CDD3ADF3213527F1004F805F /* Do Not Disturb in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7D7755D01F02DF9500D0017D /* Do Not Disturb */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
CE60F9C91FC9BBE500EFFDDA /* Lid.m in Sources */ = {isa = PBXBuildFile; fileRef = CE60F9C81FC9BBE500EFFDDA /* Lid.m */; };
/* End PBXBuildFile section */
@@ -70,57 +68,50 @@
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
209E459E203DF5B200900B89 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 6;
files = (
209E459F203DF5D500900B89 /* Do Not Disturb in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
20C8722C2046079F00F1275D /* CopyFiles */ = {
20C8722C2046079F00F1275D /* Copy Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
CD20A0CC205793680044BCC5 /* Sentry.framework in CopyFiles */,
20C87249204609A900F1275D /* Alamofire.framework in CopyFiles */,
20C8724A204609A900F1275D /* AlamofireImage.framework in CopyFiles */,
20C8724C204609A900F1275D /* CleanroomLogger.framework in CopyFiles */,
20C8724D204609A900F1275D /* CocoaAsyncSocket.framework in CopyFiles */,
20C8724E204609A900F1275D /* CocoaMQTT.framework in CopyFiles */,
20C8724F204609A900F1275D /* CommonCrypto.framework in CopyFiles */,
20C87250204609A900F1275D /* dnd.framework in CopyFiles */,
20C87252204609A900F1275D /* Realm.framework in CopyFiles */,
20C87253204609A900F1275D /* RealmSwift.framework in CopyFiles */,
20C87255204609A900F1275D /* SwiftyJSON.framework in CopyFiles */,
20C87256204609A900F1275D /* SwiftyTimer.framework in CopyFiles */,
CD20A0CC205793680044BCC5 /* Sentry.framework in Copy Frameworks */,
20C87249204609A900F1275D /* Alamofire.framework in Copy Frameworks */,
20C8724A204609A900F1275D /* AlamofireImage.framework in Copy Frameworks */,
20C8724C204609A900F1275D /* CleanroomLogger.framework in Copy Frameworks */,
20C8724D204609A900F1275D /* CocoaAsyncSocket.framework in Copy Frameworks */,
20C8724E204609A900F1275D /* CocoaMQTT.framework in Copy Frameworks */,
20C8724F204609A900F1275D /* CommonCrypto.framework in Copy Frameworks */,
20C87250204609A900F1275D /* dnd.framework in Copy Frameworks */,
20C87252204609A900F1275D /* Realm.framework in Copy Frameworks */,
20C87253204609A900F1275D /* RealmSwift.framework in Copy Frameworks */,
20C87255204609A900F1275D /* SwiftyJSON.framework in Copy Frameworks */,
20C87256204609A900F1275D /* SwiftyTimer.framework in Copy Frameworks */,
);
name = "Copy Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
20C8725720460A2300F1275D /* CopyFiles */ = {
20C8725720460A2300F1275D /* Copy Certs */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 7;
files = (
20C8725B20460A7E00F1275D /* deviceCSRRequest.p12 in CopyFiles */,
20C8725C20460A7E00F1275D /* rootCA.pem in CopyFiles */,
20C8725D20460A7E00F1275D /* awsRootCA.pem in CopyFiles */,
20C8725B20460A7E00F1275D /* deviceCSRRequest.p12 in Copy Certs */,
20C8725C20460A7E00F1275D /* rootCA.pem in Copy Certs */,
20C8725D20460A7E00F1275D /* awsRootCA.pem in Copy Certs */,
);
name = "Copy Certs";
runOnlyForDeploymentPostprocessing = 0;
};
7D7755CE1F02DF9500D0017D /* CopyFiles */ = {
CDD3ADF2213527E0004F805F /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 8;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 6;
files = (
CDD3ADF3213527F1004F805F /* Do Not Disturb in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 1;
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
@@ -141,12 +132,11 @@
20C8725920460A7E00F1275D /* rootCA.pem */ = {isa = PBXFileReference; lastKnownFileType = text; path = rootCA.pem; sourceTree = "<group>"; };
20C8725A20460A7E00F1275D /* awsRootCA.pem */ = {isa = PBXFileReference; lastKnownFileType = text; path = awsRootCA.pem; sourceTree = "<group>"; };
7D2582591F1A872400D28B95 /* com.objective-see.dnd.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "com.objective-see.dnd.plist"; path = "launchDaemon/com.objective-see.dnd.plist"; sourceTree = "<group>"; };
7D46FEFD1F5E41F000FEB0F8 /* UserCommsListener.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserCommsListener.m; sourceTree = "<group>"; };
7D46FEFE1F5E41F000FEB0F8 /* UserCommsListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserCommsListener.h; sourceTree = "<group>"; };
7D46FEFD1F5E41F000FEB0F8 /* XPCListener.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XPCListener.m; sourceTree = "<group>"; };
7D46FEFE1F5E41F000FEB0F8 /* XPCListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XPCListener.h; sourceTree = "<group>"; };
7D4FF8C31F0E1402001A4A68 /* libbsm.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libbsm.tbd; path = usr/lib/libbsm.tbd; sourceTree = SDKROOT; };
7D4FF8CB1F0EF2F9001A4A68 /* UserComms.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserComms.h; sourceTree = "<group>"; };
7D4FF8CC1F0EF2F9001A4A68 /* UserComms.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserComms.m; sourceTree = "<group>"; };
7D4FF8CE1F0EF360001A4A68 /* UserCommsInterface.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = UserCommsInterface.h; path = ../../shared/UserCommsInterface.h; sourceTree = "<group>"; };
7D4FF8CB1F0EF2F9001A4A68 /* XPCDaemon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XPCDaemon.h; sourceTree = "<group>"; };
7D4FF8CC1F0EF2F9001A4A68 /* XPCDaemon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XPCDaemon.m; sourceTree = "<group>"; };
7D6E876F1F3AE6FA00D6BD7C /* libprocInfo.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libprocInfo.a; path = launchDaemon/libs/libprocInfo.a; sourceTree = "<group>"; };
7D7755D01F02DF9500D0017D /* Do Not Disturb */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "Do Not Disturb"; sourceTree = BUILT_PRODUCTS_DIR; };
7D7755D31F02DF9500D0017D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
@@ -156,8 +146,6 @@
7DD2BF671F1DC42700B33214 /* Utilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Utilities.m; path = ../../shared/Utilities.m; sourceTree = "<group>"; };
7DD2BF721F1E9CE700B33214 /* NSMutableArray+QueueAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableArray+QueueAdditions.h"; sourceTree = "<group>"; };
7DD2BF731F1E9CE700B33214 /* NSMutableArray+QueueAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableArray+QueueAdditions.m"; sourceTree = "<group>"; };
7DD2BF741F1E9CE700B33214 /* Queue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Queue.h; sourceTree = "<group>"; };
7DD2BF751F1E9CE700B33214 /* Queue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Queue.m; sourceTree = "<group>"; };
CD208698208E8B1200BA1D0A /* VolumeMonitor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VolumeMonitor.m; sourceTree = "<group>"; };
CD208699208E8B1200BA1D0A /* VolumeMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VolumeMonitor.h; sourceTree = "<group>"; };
CD20A0C9205793040044BCC5 /* Sentry.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sentry.framework; path = ../Carthage/Build/Mac/Sentry.framework; sourceTree = "<group>"; };
@@ -184,6 +172,8 @@
CDA993A32048905D00C1E9CD /* FrameworkInterface.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FrameworkInterface.h; sourceTree = "<group>"; };
CDA993A42048905D00C1E9CD /* FrameworkInterface.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FrameworkInterface.m; sourceTree = "<group>"; };
CDAAC245202259B50032F2E6 /* Consts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Consts.h; path = ../../shared/Consts.h; sourceTree = "<group>"; };
CDFA088421367FB00089758C /* XPCUserProto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XPCUserProto.h; path = ../../shared/XPCUserProto.h; sourceTree = "<group>"; };
CDFA088521367FB00089758C /* XPCDaemonProto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XPCDaemonProto.h; path = ../../shared/XPCDaemonProto.h; sourceTree = "<group>"; };
CE60F9C71FC9BBE500EFFDDA /* Lid.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Lid.h; sourceTree = "<group>"; };
CE60F9C81FC9BBE500EFFDDA /* Lid.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Lid.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -204,7 +194,6 @@
209E45B9203DF64E00900B89 /* CocoaMQTT.framework in Frameworks */,
209E45BB203DF64E00900B89 /* RealmSwift.framework in Frameworks */,
209E45BC203DF64E00900B89 /* dnd.framework in Frameworks */,
CD20A0CB205793100044BCC5 /* Sentry.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -287,14 +276,12 @@
CDA993A42048905D00C1E9CD /* FrameworkInterface.m */,
CD227869204648E000C72C76 /* Preferences.h */,
CD22786A204648E000C72C76 /* Preferences.m */,
7DD2BF741F1E9CE700B33214 /* Queue.h */,
7DD2BF751F1E9CE700B33214 /* Queue.m */,
CD3307C82036518400F10D71 /* main.h */,
7D7755D31F02DF9500D0017D /* main.m */,
7D4FF8CB1F0EF2F9001A4A68 /* UserComms.h */,
7D4FF8CC1F0EF2F9001A4A68 /* UserComms.m */,
7D46FEFE1F5E41F000FEB0F8 /* UserCommsListener.h */,
7D46FEFD1F5E41F000FEB0F8 /* UserCommsListener.m */,
7D4FF8CB1F0EF2F9001A4A68 /* XPCDaemon.h */,
7D4FF8CC1F0EF2F9001A4A68 /* XPCDaemon.m */,
7D46FEFE1F5E41F000FEB0F8 /* XPCListener.h */,
7D46FEFD1F5E41F000FEB0F8 /* XPCListener.m */,
);
name = src;
path = launchDaemon;
@@ -308,7 +295,8 @@
7DD2BF671F1DC42700B33214 /* Utilities.m */,
7D7755FA1F02EBBE00D0017D /* Logging.m */,
7D7755FB1F02EBBE00D0017D /* Logging.h */,
7D4FF8CE1F0EF360001A4A68 /* UserCommsInterface.h */,
CDFA088421367FB00089758C /* XPCUserProto.h */,
CDFA088521367FB00089758C /* XPCDaemonProto.h */,
);
name = shared;
sourceTree = "<group>";
@@ -353,12 +341,10 @@
isa = PBXNativeTarget;
buildConfigurationList = 2063725E203DC70A006D4C38 /* Build configuration list for PBXNativeTarget "launchDaemonBundle" */;
buildPhases = (
20637257203DC70A006D4C38 /* Sources */,
20637258203DC70A006D4C38 /* Frameworks */,
20637259203DC70A006D4C38 /* Resources */,
209E459E203DF5B200900B89 /* CopyFiles */,
20C8722C2046079F00F1275D /* CopyFiles */,
20C8725720460A2300F1275D /* CopyFiles */,
20C8722C2046079F00F1275D /* Copy Frameworks */,
20C8725720460A2300F1275D /* Copy Certs */,
CDD3ADF2213527E0004F805F /* CopyFiles */,
);
buildRules = (
);
@@ -376,7 +362,6 @@
buildPhases = (
7D7755CC1F02DF9500D0017D /* Sources */,
7D7755CD1F02DF9500D0017D /* Frameworks */,
7D7755CE1F02DF9500D0017D /* CopyFiles */,
);
buildRules = (
);
@@ -393,7 +378,7 @@
7D7755C81F02DF9400D0017D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0900;
LastUpgradeCheck = 1000;
ORGANIZATIONNAME = "Objective-See";
TargetAttributes = {
2063725A203DC70A006D4C38 = {
@@ -424,24 +409,7 @@
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
20637259203DC70A006D4C38 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
20637257203DC70A006D4C38 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
7D7755CC1F02DF9500D0017D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -456,13 +424,12 @@
CD256E082050DE9B00768457 /* UserAuthMonitor.m in Sources */,
CD22786C20464A6E00C72C76 /* Preferences.m in Sources */,
CDA993A62048905D00C1E9CD /* FrameworkInterface.m in Sources */,
7D46FEFF1F5E41F000FEB0F8 /* UserCommsListener.m in Sources */,
7D46FEFF1F5E41F000FEB0F8 /* XPCListener.m in Sources */,
CE60F9C91FC9BBE500EFFDDA /* Lid.m in Sources */,
7DD2BF761F1E9CE700B33214 /* NSMutableArray+QueueAdditions.m in Sources */,
7DD2BF681F1DC42700B33214 /* Utilities.m in Sources */,
7DD2BF771F1E9CE700B33214 /* Queue.m in Sources */,
7D7755D41F02DF9500D0017D /* main.m in Sources */,
7D4FF8CD1F0EF2F9001A4A68 /* UserComms.m in Sources */,
7D4FF8CD1F0EF2F9001A4A68 /* XPCDaemon.m in Sources */,
7D7755FC1F02EBBE00D0017D /* Logging.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -537,6 +504,7 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
@@ -544,6 +512,7 @@
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -590,6 +559,7 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
@@ -597,6 +567,7 @@
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -642,6 +613,7 @@
OTHER_CODE_SIGN_FLAGS = "";
PRODUCT_NAME = "Do Not Disturb";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
};
name = Debug;
};
@@ -665,6 +637,7 @@
OTHER_LDFLAGS = "";
PRODUCT_NAME = "Do Not Disturb";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
};
name = Release;
};
+19 -2
View File
@@ -24,7 +24,7 @@ BOOL authViaTouchID(void);
/* CLASS INTERFACE */
@interface Lid : NSObject <DNDClientMacDelegate>
@interface Lid : NSObject <DNDClientMacDelegate, DNDClientMacTaskingDelegate>
{
//lid state
LidState lidState;
@@ -37,6 +37,7 @@ BOOL authViaTouchID(void);
//notification object
io_object_t notification;
}
/* PROPERTIES */
@@ -53,6 +54,18 @@ BOOL authViaTouchID(void);
//dispatch blocks
@property(nonatomic, retain)NSMutableArray* dispatchBlocks;
//latest undelivered alert
@property(nonatomic, retain)NSDate* undeliveredAlert;
//observer for dismiss alerts
@property(nonatomic, retain)id dismissObserver;
//observer for new client/user (login item)
@property(nonatomic, retain)id userObserver;
//undelivered alerts
@property(nonatomic, retain)NSMutableArray* undeliveredAlerts;
/* METHODS */
//check if client should be init'd
@@ -71,7 +84,11 @@ BOOL authViaTouchID(void);
-(void)unregister4Notifications;
//proces lid open event
-(void)processEvent:(NSDate*)timestamp;
-(void)processEvent:(NSDate*)timestamp user:(NSString*)user;
//wait for dismiss
// note: handles multiple client via dispatch group
-(void)wait4Dismiss;
//execute action
-(int)executeAction:(NSString*)path user:(NSString*)user;
+255 -45
View File
@@ -11,15 +11,18 @@
#import "Lid.h"
#import "Consts.h"
#import "Queue.h"
#import "Logging.h"
#import "Monitor.h"
#import "AuthEvent.h"
#import "Utilities.h"
#import "XPCListener.h"
#import "Preferences.h"
#import "UserAuthMonitor.h"
#import "FrameworkInterface.h"
#import "XPCUserProto.h"
/* GLOBALS */
//last state
@@ -29,9 +32,6 @@ LidState lastLidState;
//lid obj
extern Lid* lid;
//queue object
extern Queue* eventQueue;
//user auth event listener
extern UserAuthMonitor* userAuthMonitor;
@@ -41,6 +41,9 @@ extern Preferences* preferences;
//DND framework interface obj
extern FrameworkInterface* framework;
//XPC listener
extern XPCListener* xpcListener;
//callback for power/lid events
static void pmDomainChange(void *refcon, io_service_t service, uint32_t messageType, void *messageArgument)
{
@@ -138,7 +141,7 @@ static void pmDomainChange(void *refcon, io_service_t service, uint32_t messageT
//process event
// report to user, execute actions, etc
[lid processEvent:timestamp];
[lid processEvent:timestamp user:getConsoleUser()];
}
//(new) close?
@@ -245,8 +248,12 @@ BOOL authViaTouchID()
@implementation Lid
@synthesize client;
@synthesize userObserver;
@synthesize dispatchGroup;
@synthesize dispatchBlocks;
@synthesize dismissObserver;
@synthesize undeliveredAlert;
@synthesize undeliveredAlerts;
@synthesize dispatchGroupEmpty;
//init
@@ -265,6 +272,9 @@ BOOL authViaTouchID()
//init
notification = 0;
//alloc array for alerts
undeliveredAlerts = [NSMutableArray array];
//init to current state
lastLidState = getLidState();
@@ -280,6 +290,52 @@ BOOL authViaTouchID()
//init array for blocks
dispatchBlocks = [NSMutableArray array];
//register listener for dismiss alerts
// when it fires, invoke (user) XPC method to dismiss alert
self.dismissObserver = [[NSNotificationCenter defaultCenter] addObserverForName:DISMISS_NOTIFICATION object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
{
//connected login item?
if(nil != xpcListener.loginItem)
{
//dbg msg
logMsg(LOG_DEBUG, @"'DISMISS_NOTIFICATION' triggered, will send XPC msg to user (login item) to dismiss any alerts");
//send XPC msg to dismiss
[[xpcListener.loginItem remoteObjectProxy] alertDismiss];
}
else
{
//dbg msg
logMsg(LOG_DEBUG, @"no client (login item) is connected, so nothing to dismiss...");
}
}];
//register listener for new client/user (login item)
// when it fires, invoke (user) XPC method to deliver any alerts that occured when user wasn't logged in
self.userObserver = [[NSNotificationCenter defaultCenter] addObserverForName:USER_NOTIFICATION object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
{
//dbg msg
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"'USER_NOTIFICATION' triggered, will send XPC msg to user (login item) to display %lu undelivered alerts", self.undeliveredAlerts.count]);
//sync to access
@synchronized(self.undeliveredAlerts)
{
//send each alert to user
for(NSDictionary* alert in self.undeliveredAlerts)
{
//send XPC msg to user, to display alert
[[xpcListener.loginItem remoteObjectProxy] alertShow:alert];
//dbg msg
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"(re)delivered alert: %@", alert]);
}
//remove all
[self.undeliveredAlerts removeAllObjects];
}
}];
//should init client?
if(YES == [self shouldInitClient])
{
@@ -334,7 +390,7 @@ BOOL authViaTouchID()
self.client.delegate = self;
//indicate we want tasking
[self.client handleTasksWithFramework:[[preferences get:nil][PREF_NO_REMOTE_TASKING] boolValue]];
[self.client handleTasksWithFramework:[[preferences get:nil][PREF_NO_REMOTE_TASKING] boolValue] imageDelegate:self];
//happy
initialized = YES;
@@ -481,27 +537,55 @@ bail:
//proces lid open event
// report to user, execute cmd, send alert to server, etc
-(void)processEvent:(NSDate*)timestamp
-(void)processEvent:(NSDate*)timestamp user:(NSString*)user
{
//monitor obj
Monitor* monitor = nil;
//console user
NSString* consoleUser = nil;
//current prefs
NSDictionary* currentPrefs = nil;
//alert
NSDictionary* alert;
//init alert
alert = @{ALERT_TIMESTAMP:timestamp};
//get current prefs
currentPrefs = [preferences get:nil];
//only add events to queue
// when client is not running in passive mode
if(YES != [currentPrefs[PREF_PASSIVE_MODE] boolValue])
{
//add to global queue
// this will trigger processing of alert to user
[eventQueue enqueue:@{ALERT_TIMESTAMP:timestamp}];
//connected client? (login item)
// deliver alert via XPC, to user
if(nil != xpcListener.loginItem)
{
//send to client
// this will fail (but we'll handle) if no clients are connected
[[xpcListener.loginItem remoteObjectProxyWithErrorHandler:^(NSError * proxyError)
{
//err msg
logMsg(LOG_ERR, [NSString stringWithFormat:@"failed to invoke USER XPC method: 'alertShow' (error: %@)", proxyError]);
//save undelivered alert
@synchronized(self.undeliveredAlerts)
{
//save
[self.undeliveredAlerts addObject:alert];
}
//dbg msg
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"saved %@, will deliver when user (login item) connects", alert]);
}] alertShow:alert];
}
else
{
//dbg msg
logMsg(LOG_DEBUG, @"no client (login item) is connected, so won't locally deliver alert");
}
}
//passive mode
// just log a msg about this fact
@@ -534,7 +618,6 @@ bail:
if( (YES == [currentPrefs[PREF_EXECUTE_ACTION] boolValue]) &&
(0 != [currentPrefs[PREF_EXECUTE_PATH] length] ) )
{
//dbg msg
logMsg(LOG_DEBUG|LOG_TO_FILE, [NSString stringWithFormat:@"executing: %@ as %@", currentPrefs[PREF_EXECUTE_PATH], currentPrefs[PREF_EXECUTE_USER]]);
@@ -565,41 +648,43 @@ bail:
logMsg(LOG_DEBUG, @"(re)initialized DND client for framework");
}
//send to server
// and wait for dismiss
//registered device?
// send to alert to server
if(nil != self.client)
{
//get user
consoleUser = getConsoleUser();
if(0 == consoleUser.length)
//dbg msg
logMsg(LOG_DEBUG, @"found registerd device/client, will try send alert to server");
//no undelivered alert?
// spawn off dispatch to deliver
if(nil == self.undeliveredAlert)
{
//defult
consoleUser = @"unknown";
//dbg msg
logMsg(LOG_DEBUG, @"no (prev) alerts undelivered");
//save timestamp
self.undeliveredAlert = timestamp;
//send to server
// will wait up to x minutes if there's no network connectivity
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//wait
[self send2Server:user];
});
}
//dbg msg
// and log to file
logMsg(LOG_DEBUG|LOG_TO_FILE, [NSString stringWithFormat:@"sending alert to server (user: %@)", consoleUser]);
//send
[self.client sendAlertWithUuid:[NSUUID UUID] userName:consoleUser date:timestamp completion:^(NSNumber* response)
//already send(ing) alert
// just update, so if network comes online, will use this one (as latest)
else
{
//log
logMsg(LOG_DEBUG|LOG_TO_FILE, [NSString stringWithFormat:@"response from server: %@", response]);
//dbg msg
logMsg(LOG_DEBUG, @"previously alert undelivered, just updating that...");
//after getting server response
// update list of registered devices...
[preferences updateRegisteredDevices];
}];
//wait for dismiss
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//wait
[self wait4Dismiss];
});
//save timestamp
self.undeliveredAlert = timestamp;
}
}
//didn't send
@@ -615,6 +700,94 @@ bail:
return;
}
//send alert to server
// contains extra logic to check/wait for network connectivty
-(void)send2Server:(NSString*)user
{
//flag
BOOL sent = NO;
//response
__block NSNumber* response = nil;
//no user?
// set to default, but will try again
if(0 == user.length)
{
//default
user = USER_UNKNOWN;
}
//try send up to 10 times
// basically gives time for network to reconnect if lid-shut disconnected wifi, etc...
for(NSUInteger i=0; i<10; i++)
{
//unknown user?
// try get user again
if(YES == [user isEqualToString:USER_UNKNOWN])
{
//get user
user = getConsoleUser();
if(0 == user.length)
{
//default
user = USER_UNKNOWN;
}
}
//dbg msg
// and log to file
logMsg(LOG_DEBUG|LOG_TO_FILE, [NSString stringWithFormat:@"sending alert to server (user: %@)", user]);
//send
response = [self.client sendAlertSyncWithUuid:[NSUUID UUID] userName:user date:self.undeliveredAlert photo:NO];
if(nil != response)
{
//log
logMsg(LOG_DEBUG|LOG_TO_FILE, [NSString stringWithFormat:@"response from server: %@", response]);
//after getting server response
// update list of registered devices
[preferences updateRegisteredDevices];
//set flag
sent = YES;
//wait for dismiss
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//wait
[self wait4Dismiss];
});
//done
break;
}
//dbg msg
logMsg(LOG_DEBUG, @"could not reach endpoint - network offline?");
//not online
//... so take a nap
[NSThread sleepForTimeInterval:i*1.5];
}
//check
// log err
if(YES != sent)
{
//log
logMsg(LOG_DEBUG|LOG_TO_FILE, @"unable to deliver alert (network offline?)");
}
//unset
// even if we failed to send
self.undeliveredAlert = nil;
return;
}
//wait for dismiss
// note: handles multiple client via dispatch group
-(void)wait4Dismiss
@@ -754,7 +927,7 @@ bail:
int result = -1;
//exec script
// su man -c <user> <path>
// su -c <user> <path>
results = execTask(@"/usr/bin/su", @[user, @"-c", path], YES);
//dbg msg
@@ -772,4 +945,41 @@ bail:
return result;
}
//framework delegate method
// send XPC message to user (login item) to take picture
-(void)captureImageWithCompletion:(void (^ _Nonnull)(NSData * _Nullable))completion
{
//connected client? (login item)
// request image capture of camera, via XPC
if(nil != xpcListener.loginItem)
{
//request to user (login item) to take a picture
[[xpcListener.loginItem remoteObjectProxyWithErrorHandler:^(NSError * proxyError)
{
//err msg
logMsg(LOG_ERR, [NSString stringWithFormat:@"failed to invoke USER XPC method: 'capture picture' (error: %@)", proxyError]);
//error
completion(nil);
}] captureImage:^(NSData* image)
{
//pass back to framework
completion(image);
}];
}
else
{
//dbg msg
logMsg(LOG_DEBUG, @"no client (login item) is connected, so can't capture image");
//still, invoke callback
completion(nil);
}
return;
}
@end
+17 -9
View File
@@ -205,6 +205,10 @@ bail:
}
}
//sync prefs
@synchronized(self.preferences)
{
//updating list of registered devices?
// it's a dictionary so requires an extra merge
if( (nil != updates[PREF_REGISTERED_DEVICES]) &&
@@ -221,6 +225,8 @@ bail:
//merge
[self.preferences addEntriesFromDictionary:updates];
}
}//sync
//save
if(YES != [self save])
@@ -244,9 +250,6 @@ bail:
// then update preferences with this list...
-(void)updateRegisteredDevices
{
//current devices
NSDictionary* currentDevices = nil;
//client
DNDClientMac *client;
@@ -262,10 +265,9 @@ bail:
//alloc dictionary
devices = [NSMutableDictionary dictionary];
//get current devices
// aren't any, just bail
currentDevices = self.preferences[PREF_REGISTERED_DEVICES];
if(0 == currentDevices.count)
//aren't any registered devices?
// just bail
if(0 == [self.preferences[PREF_REGISTERED_DEVICES] count])
{
//bail
goto bail;
@@ -305,20 +307,26 @@ bail:
goto bail;
}
//sync prefs
@synchronized(self.preferences)
{
//get list of registered devices from server
// build (updated) list of devices id : device name mappings
for(NSString* deviceID in macShadow.state.reported.endpoints)
{
//sanity check
if(nil == currentDevices[deviceID])
if(nil == self.preferences[PREF_REGISTERED_DEVICES][deviceID])
{
//skip
continue;
}
//add current device name
devices[deviceID] = currentDevices[deviceID];
devices[deviceID] = self.preferences[PREF_REGISTERED_DEVICES][deviceID];
}
}//sync
//no registered devices?
// remove key from preferences
-40
View File
@@ -1,40 +0,0 @@
//
// file: Queue.h
// project: DND (launch daemon)
// description: a queue implementation (header)
//
// created by Patrick Wardle
// copyright (c) 2018 Objective-See. All rights reserved.
//
@import Foundation;
#import "NSMutableArray+QueueAdditions.h"
@interface Queue : NSObject
{
}
/* PROPERTIES */
//event queue
@property(retain, atomic)NSMutableArray* eventQueue;
//queue condition
@property (nonatomic, retain)NSCondition* queueCondition;
/* METHODS */
//add an object to the queue
-(void)enqueue:(id)anObject;
//wait until queue has item
// then pull if off, and return it
-(id)dequeue;
//wait until queue has item
// and return it, w/o removing it
-(id)peek;
@end
-106
View File
@@ -1,106 +0,0 @@
//
// file: Queue.m
// project: DND (launch daemon)
// description: a queue implementation
//
// created by Patrick Wardle
// copyright (c) 2018 Objective-See. All rights reserved.
//
#import "Queue.h"
#import "Consts.h"
#import "Logging.h"
@implementation Queue
@synthesize eventQueue;
@synthesize queueCondition;
//init
-(id)init
{
//init super
self = [super init];
if(nil != self)
{
//init queue
eventQueue = [NSMutableArray array];
//init empty condition
queueCondition = [[NSCondition alloc] init];
}
return self;
}
//add an object to the queue
-(void)enqueue:(id)anObject
{
//lock
[self.queueCondition lock];
//add to queue
[self.eventQueue enqueue:anObject];
//signal
[self.queueCondition signal];
//unlock
[self.queueCondition unlock];
return;
}
//wait until queue has item
// then pull if off, and return it
-(id)dequeue
{
//queue item
id item = nil;
//lock
[self.queueCondition lock];
//wait while queue is empty
while(YES == [self.eventQueue isEmpty])
{
//wait
[self.queueCondition wait];
}
//get item off queue
item = [self.eventQueue dequeue];
//unlock
[self.queueCondition unlock];
return item;
}
//wait until queue has item
// and return it, w/o removing it
-(id)peek
{
//queue item
id item = nil;
//lock
[self.queueCondition lock];
//wait while queue is empty
while(YES == [self.eventQueue isEmpty])
{
//wait
[self.queueCondition wait];
}
//get item off queue
item = [self.eventQueue peek];
//unlock
[self.queueCondition unlock];
return item;
}
@end
@@ -1,29 +1,25 @@
//
// file: UserComms.h
// file: XPCDaemon.h
// project: DND (launch daemon)
// description: interface for user componets (header)
// description: interface for user XPC methods (header)
//
// created by Patrick Wardle
// copyright (c) 2018 Objective-See. All rights reserved.
//
@import Foundation;
#import "UserCommsInterface.h"
#import <dnd/dnd-Swift.h>
@interface UserComms : NSObject <UserProtocol, DNDClientMacDelegate>
#import "XPCDaemonProto.h"
@interface XPCDaemon : NSObject <XPCDaemonProtocol, DNDClientMacDelegate>
{
}
/* PROPERTIES */
//client status
@property NSInteger currentStatus;
//last alert
@property(nonatomic,retain)NSDictionary* dequeuedAlert;
//registration info from server
@property(nonatomic,retain)NSDictionary *registrationInfo;
@@ -1,38 +1,31 @@
//
// file: UserComms.m
// file: XPCDaemon.m
// project: DND (launch daemon)
// description: interface for user componets
// description: interface for user XPC methods
//
// created by Patrick Wardle
// copyright (c) 2018 Objective-See. All rights reserved.
//
#import "Consts.h"
#import "Queue.h"
#import "Logging.h"
#import "UserComms.h"
#import "XPCDaemon.h"
#import "Preferences.h"
#import "FrameworkInterface.h"
#import "UserCommsInterface.h"
#import <dnd/dnd-swift.h>
//signing auth
#define SIGNING_AUTH @"Developer ID Application: Objective-See, LLC (VBG97UB4TA)"
//global queue object
extern Queue* eventQueue;
//global prefs obj
extern Preferences* preferences;
//framework interface obc
extern FrameworkInterface* framework;
@implementation UserComms
@implementation XPCDaemon
@synthesize currentStatus;
@synthesize dequeuedAlert;
@synthesize registrationInfo;
@synthesize registrationSema;
@@ -44,8 +37,7 @@ extern FrameworkInterface* framework;
self = [super init];
if(nil != self)
{
//set status
self.currentStatus = STATUS_CLIENT_UNKNOWN;
}
return self;
@@ -200,48 +192,7 @@ bail:
return;
}
//process alert request from client
// blocks for queue item, then sends to client
-(void)alertRequest:(void (^)(NSDictionary* alert))reply
{
//dbg msg
logMsg(LOG_DEBUG, @"XPC request: alert request");
//reset
self.dequeuedAlert = nil;
//read off queue
// will block until alert is ready
self.dequeuedAlert = [eventQueue peek];
//dbg msg
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"found alert on queue: %@", self.dequeuedAlert]);
//log to file
logMsg(LOG_DEBUG|LOG_TO_FILE, [NSString stringWithFormat:@"sending alert to login item to display to user: %@", self.dequeuedAlert]);
//return alert
reply(self.dequeuedAlert);
return;
}
//invoke when alert has been displayed
// for now, just remove it from the queue
-(void)alertResponse
{
//dbg msg
logMsg(LOG_DEBUG, @"XPC request: alert response");
//remove
[eventQueue dequeue];
//unset
self.dequeuedAlert = nil;
//dbg msg
logMsg(LOG_DEBUG, @"removed alert, as it's been consumed by the user");
}
//process alert dismiss request from client
// blocks until framework tell us it was dismissed via the phone || login item said 'disable'
@@ -1,16 +1,15 @@
//
// file: UserCommsListener.h
// file: XPCListener.h
// project: DND (launch daemon)
// description: XPC listener for connections for user components (header)
// description: XPC listener for connections from user components (header)
//
// created by Patrick Wardle
// copyright (c) 2018 Objective-See. All rights reserved.
//
@import Foundation;
#import "UserCommsInterface.h"
@interface UserCommsListener : NSObject <NSXPCListenerDelegate>
@interface XPCListener : NSObject <NSXPCListenerDelegate>
{
}
@@ -20,6 +19,12 @@
//XPC listener
@property(nonatomic, retain)NSXPCListener* listener;
//XPC connection for login item
@property(weak)NSXPCConnection* loginItem;
//XPC connection for main app
@property(weak)NSXPCConnection* mainApp;
/* METHODS */
//setup XPC listener
@@ -30,9 +35,4 @@
// note: we only allow binaries signed by Objective-See to talk to this!
-(BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection;
//connection invalidated
// if there is an 'undelivered' alert, (re)enqueue it
-(void)connectionInvalidated:(NSXPCConnection *)connection;
@end
@@ -1,7 +1,7 @@
//
// file: UserCommsListener.m
// file: XPCListener.h
// project: DND (launch daemon)
// description: XPC listener for connections for user components
// description: XPC listener for connections from user components
//
// created by Patrick Wardle
// copyright (c) 2018 Objective-See. All rights reserved.
@@ -9,18 +9,15 @@
#import "Consts.h"
#import "Logging.h"
#import "Queue.h"
#import "UserComms.h"
#import "UserCommsListener.h"
#import "UserCommsInterface.h"
#import "Utilities.h"
#import "XPCDaemon.h"
#import "XPCListener.h"
#import "XPCUSERProto.h"
#import "XPCDaemonProto.h"
//signing auth
#define SIGNING_AUTH @"Developer ID Application: Objective-See, LLC (VBG97UB4TA)"
//global queue object
extern Queue* eventQueue;
//interface for 'extension' to NSXPCConnection
// allows us to access the 'private' auditToken iVar
@interface ExtendedNSXPCConnection : NSXPCConnection
@@ -42,14 +39,10 @@ extern Queue* eventQueue;
@end
//function
OSStatus SecTaskValidateForRequirement(SecTaskRef task, CFStringRef requirement);
//global queue object
extern Queue* eventQueue;
@implementation UserCommsListener
@implementation XPCListener
@synthesize listener;
@@ -65,11 +58,10 @@ extern Queue* eventQueue;
if(YES != [self initListener])
{
//unset
self = nil;
self = nil;
//bail
goto bail;
}
}
@@ -112,7 +104,6 @@ bail:
return result;
}
#pragma mark -
#pragma mark NSXPCConnection method overrides
@@ -128,29 +119,14 @@ bail:
SecTaskRef taskRef = 0;
//signing req string
NSString *requirementString = nil;
NSString* requirementString = nil;
//make weak ref
// see: https://stackoverflow.com/a/23628986/3854841
__weak typeof(NSXPCConnection*) weakConnection = newConnection;
//path of connecting app
NSString* path = nil;
//dbg msg
logMsg(LOG_DEBUG, @"received request to connect to XPC interface");
//set interrupt & invalidation handler
newConnection.interruptionHandler = newConnection.invalidationHandler = ^{
//make strong ref
// see: https://stackoverflow.com/a/23628986/3854841
__strong typeof(NSXPCConnection*)strongConnection = weakConnection;
//dbg msg
logMsg(LOG_DEBUG, @"connection interrupted/invalidated");
//handle invalidation
[self connectionInvalidated:strongConnection];
};
//init signing req string
requirementString = [NSString stringWithFormat:@"anchor trusted and certificate leaf [subject.CN] = \"%@\"", SIGNING_AUTH];
@@ -170,18 +146,47 @@ bail:
//bail
goto bail;
}
//set the interface that the exported object implements
newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(UserProtocol)];
newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(XPCDaemonProtocol)];
//set object exported by connection
newConnection.exportedObject = [[UserComms alloc] init];
newConnection.exportedObject = [[XPCDaemon alloc] init];
//set type of remote object
// user (login item/main app) will set this object
newConnection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol: @protocol(XPCUserProtocol)];
//get path
path = getProcessPath(newConnection.processIdentifier);
//login item
// save connection and notify that new client has connected
if(YES == [path hasSuffix:LOGIN_ITEM_NAME])
{
//save
self.loginItem = newConnection;
//in background
// notify that a new client connected
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^{
//notify
[[NSNotificationCenter defaultCenter] postNotificationName:USER_NOTIFICATION object:nil userInfo:nil];
});
}
//main app
else
{
//save
self.mainApp = newConnection;
}
//resume
[newConnection resume];
//dbg msg
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"allowed XPC connection: %@", newConnection.exportedObject]);
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"allowed XPC connection from %@", path]);
//happy
shouldAccept = YES;
@@ -201,50 +206,4 @@ bail:
return shouldAccept;
}
//connection invalidated
// if there is an 'undelivered' alert, (re)enqueue it
-(void)connectionInvalidated:(NSXPCConnection *)connection
{
//user comms obj
UserComms* userComms = nil;
//dbg msg
logMsg(LOG_DEBUG, @"XPC connection interrupted/invalidated");
//sanity check
if(nil == connection)
{
//bail
goto bail;
}
//grab user comms object
userComms = connection.exportedObject;
//no undelivered (dequeued) alert?
if(nil == userComms.dequeuedAlert)
{
//bail
goto bail;
}
//dbg msg
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"found undelivered alert, will (re)enqueue"]);
//have alert
// requeue it up
[eventQueue enqueue:userComms.dequeuedAlert];
bail:
//unset export obj
connection.exportedObject = nil;
//unset connection
connection = nil;
return;
}
@end
+10 -24
View File
@@ -10,12 +10,11 @@
#import "Lid.h"
#import "main.h"
#import "Consts.h"
#import "Queue.h"
#import "Logging.h"
#import "Utilities.h"
#import "Preferences.h"
#import "XPCListener.h"
#import "UserAuthMonitor.h"
#import "UserCommsListener.h"
#import "FrameworkInterface.h"
@import Sentry;
@@ -29,10 +28,6 @@ Preferences* preferences = nil;
// registers for notifications, gets state, etc
Lid* lid = nil;
//queue object
// contains watch items that should be processed
Queue* eventQueue = nil;
//user auth event listener
UserAuthMonitor* userAuthMonitor = nil;
@@ -42,6 +37,9 @@ FrameworkInterface* framework = nil;
//dispatch source for SIGTERM
dispatch_source_t dispatchSource = nil;
//XPC listener
XPCListener* xpcListener = nil;
//main
// init & kickoff stuffz
int main(int argc, const char * argv[])
@@ -51,20 +49,14 @@ int main(int argc, const char * argv[])
@autoreleasepool
{
//user comms listener (XPC) obj
UserCommsListener* userCommsListener = nil;
//current preferences
NSDictionary* currentPrefs = nil;
//dbg msg
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"STARTED: launch daemon (args: %@)", [[NSProcessInfo processInfo] arguments]]);
//init crash reporting client
SentryClient.sharedClient = [[SentryClient alloc] initWithDsn:CRASH_REPORTING_URL didFailWithError:nil];
//start crash handler
[SentryClient.sharedClient startCrashHandlerWithError:nil];
//init crash reporting
initCrashReporting();
//alloc/init/load prefs
// to here (early) as other logic (below) uses prefs
@@ -165,18 +157,12 @@ int main(int argc, const char * argv[])
logMsg(LOG_DEBUG, @"currently disabled, so did not register for lid change notifications");
}
//init global queue
eventQueue = [[Queue alloc] init];
//dbg msg
logMsg(LOG_DEBUG, @"initialized global queue");
//alloc/init user comms XPC obj
userCommsListener = [[UserCommsListener alloc] init];
if(nil == userCommsListener)
//alloc/init XPC listener
xpcListener = [[XPCListener alloc] init];
if(nil == xpcListener)
{
//err msg
logMsg(LOG_ERR, [NSString stringWithFormat:@"failed to initialize user comms XPC listener"]);
logMsg(LOG_ERR, [NSString stringWithFormat:@"failed to initialize XPC listener"]);
//bail
goto bail;
@@ -18,23 +18,23 @@
// note: will only detect files downloaded from apps such as browsers (that have 'kMDItemWhereFroms' key set)
-(void)start
{
//has to be run on the main thread!
dispatch_async(dispatch_get_main_queue(), ^{
//alloc/init query
query = [[NSMetadataQuery alloc] init];
//add observer
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDownloadEvent:) name:NSMetadataQueryDidUpdateNotification object:query];
//has to be run on the main thread!
dispatch_async(dispatch_get_main_queue(), ^{
//add observer
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDownloadEvent:) name:NSMetadataQueryDidUpdateNotification object:self.query];
//set delegate
self.query.delegate = self;
//set delegate
self.query.delegate = self;
//set predicate
self.query.predicate = [NSPredicate predicateWithFormat:@"%K like '*'", @"kMDItemWhereFroms"];
//set predicate
self.query.predicate = [NSPredicate predicateWithFormat:@"%K like '*'", @"kMDItemWhereFroms"];
//start
[query startQuery];
//start
[self.query startQuery];
});
+58 -37
View File
@@ -11,7 +11,6 @@
7D16D6951F64E43300DB3161 /* UpdateWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7D16D6911F64E43300DB3161 /* UpdateWindow.xib */; };
7D16D6961F64E43300DB3161 /* UpdateWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D16D6931F64E43300DB3161 /* UpdateWindowController.m */; };
7D3B75141F13354900568828 /* StatusBarMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D3B74FD1F13354900568828 /* StatusBarMenu.m */; };
7D3B75151F13354900568828 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7D3B75011F13354900568828 /* MainMenu.xib */; };
7D3B75251F13357D00568828 /* Logging.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D3B75231F13357D00568828 /* Logging.m */; };
7D5C5F521F200B9200C0E94A /* Utilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D5C5F511F200B9200C0E94A /* Utilities.m */; };
7D7755E81F02E05B00D0017D /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D7755E71F02E05B00D0017D /* AppDelegate.m */; };
@@ -19,9 +18,7 @@
7D7755F01F02E05B00D0017D /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7D7755EE1F02E05B00D0017D /* MainMenu.xib */; };
7DD25FF01F23B73C00277EC4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7DD25FEF1F23B73C00277EC4 /* Assets.xcassets */; };
7DD260131F25307B00277EC4 /* HyperlinkTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DD260121F25307B00277EC4 /* HyperlinkTextField.m */; };
7DD2BF6E1F1DDF1F00B33214 /* AlertMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DD2BF6D1F1DDF1F00B33214 /* AlertMonitor.m */; };
7DD2BF7A1F1EAC9C00B33214 /* DaemonComms.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DD2BF791F1EAC9C00B33214 /* DaemonComms.m */; };
CD20A0D720579AFD0044BCC5 /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD20A0D620579AFD0044BCC5 /* Sentry.framework */; };
7DD2BF7A1F1EAC9C00B33214 /* XPCDaemonClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DD2BF791F1EAC9C00B33214 /* XPCDaemonClient.m */; };
CD3307E020375ED000F10D71 /* StatusBarPopoverController.m in Sources */ = {isa = PBXBuildFile; fileRef = CD3307DF20375ED000F10D71 /* StatusBarPopoverController.m */; };
CD3307E22037648B00F10D71 /* StatusBarPopover.xib in Resources */ = {isa = PBXBuildFile; fileRef = CD3307E12037648B00F10D71 /* StatusBarPopover.xib */; };
CD3307E420376B8300F10D71 /* popoverCloseAlt.png in Resources */ = {isa = PBXBuildFile; fileRef = CD3307E320376B8300F10D71 /* popoverCloseAlt.png */; };
@@ -29,6 +26,9 @@
CD3307E820376CCB00F10D71 /* dndIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = CD3307E720376CCB00F10D71 /* dndIcon.png */; };
CD981A8D2069049B001B875B /* statusIconDisabled.png in Resources */ = {isa = PBXBuildFile; fileRef = CD981A8B2069049A001B875B /* statusIconDisabled.png */; };
CD981A8E2069049B001B875B /* statusIconDisabled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CD981A8C2069049A001B875B /* statusIconDisabled@2x.png */; };
CDD8075D2134E0930046594E /* Sentry.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = CDD8075C2134E0930046594E /* Sentry.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
CDFA0888213685370089758C /* XPCUser.m in Sources */ = {isa = PBXBuildFile; fileRef = CDFA0887213685370089758C /* XPCUser.m */; };
CDFA08AA213B3ECA0089758C /* Camera.m in Sources */ = {isa = PBXBuildFile; fileRef = CDFA08A9213B3ECA0089758C /* Camera.m */; };
CDFB7888206E2F3400ABDD04 /* statusIconWhite.png in Resources */ = {isa = PBXBuildFile; fileRef = CDFB7884206E2F3400ABDD04 /* statusIconWhite.png */; };
CDFB7889206E2F3400ABDD04 /* statusIconDisabledWhite.png in Resources */ = {isa = PBXBuildFile; fileRef = CDFB7885206E2F3400ABDD04 /* statusIconDisabledWhite.png */; };
CDFB788A206E2F3400ABDD04 /* statusIconDisabledWhite@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CDFB7886206E2F3400ABDD04 /* statusIconDisabledWhite@2x.png */; };
@@ -37,6 +37,20 @@
CE968A9D1FCC590200AD6B78 /* statusIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CE968A9B1FCC590200AD6B78 /* statusIcon@2x.png */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
CDD8075B2134E0670046594E /* Copy Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
CDD8075D2134E0930046594E /* Sentry.framework in Copy Frameworks */,
);
name = "Copy Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
7D16D68F1F64E43300DB3161 /* Update.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Update.h; path = ../shared/Update.h; sourceTree = "<group>"; };
7D16D6901F64E43300DB3161 /* Update.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Update.m; path = ../shared/Update.m; sourceTree = "<group>"; };
@@ -46,7 +60,6 @@
7D3B74FD1F13354900568828 /* StatusBarMenu.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StatusBarMenu.m; sourceTree = "<group>"; };
7D3B74FF1F13354900568828 /* StatusBarMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StatusBarMenu.h; sourceTree = "<group>"; };
7D3B75021F13354900568828 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = MainMenu.xib; sourceTree = "<group>"; };
7D3B75211F13357D00568828 /* UserCommsInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UserCommsInterface.h; path = ../shared/UserCommsInterface.h; sourceTree = "<group>"; };
7D3B75221F13357D00568828 /* Consts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Consts.h; path = ../shared/Consts.h; sourceTree = "<group>"; };
7D3B75231F13357D00568828 /* Logging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Logging.m; path = ../shared/Logging.m; sourceTree = "<group>"; };
7D3B75241F13357D00568828 /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../shared/Logging.h; sourceTree = "<group>"; };
@@ -61,11 +74,8 @@
7DD25FEF1F23B73C00277EC4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
7DD260111F25307B00277EC4 /* HyperlinkTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HyperlinkTextField.h; path = loginItem/3rdParty/HyperlinkTextField.h; sourceTree = "<group>"; };
7DD260121F25307B00277EC4 /* HyperlinkTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HyperlinkTextField.m; path = loginItem/3rdParty/HyperlinkTextField.m; sourceTree = "<group>"; };
7DD2BF6C1F1DDF1F00B33214 /* AlertMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlertMonitor.h; sourceTree = "<group>"; };
7DD2BF6D1F1DDF1F00B33214 /* AlertMonitor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AlertMonitor.m; sourceTree = "<group>"; };
7DD2BF781F1EAC9C00B33214 /* DaemonComms.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DaemonComms.h; path = ../shared/DaemonComms.h; sourceTree = "<group>"; };
7DD2BF791F1EAC9C00B33214 /* DaemonComms.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DaemonComms.m; path = ../shared/DaemonComms.m; sourceTree = "<group>"; };
CD20A0D620579AFD0044BCC5 /* Sentry.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sentry.framework; path = ../Carthage/Build/Mac/Sentry.framework; sourceTree = "<group>"; };
7DD2BF781F1EAC9C00B33214 /* XPCDaemonClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XPCDaemonClient.h; path = ../shared/XPCDaemonClient.h; sourceTree = "<group>"; };
7DD2BF791F1EAC9C00B33214 /* XPCDaemonClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XPCDaemonClient.m; path = ../shared/XPCDaemonClient.m; sourceTree = "<group>"; };
CD3307DE20375ECF00F10D71 /* StatusBarPopoverController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StatusBarPopoverController.h; sourceTree = "<group>"; };
CD3307DF20375ED000F10D71 /* StatusBarPopoverController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StatusBarPopoverController.m; sourceTree = "<group>"; };
CD3307E12037648B00F10D71 /* StatusBarPopover.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = StatusBarPopover.xib; sourceTree = "<group>"; };
@@ -74,6 +84,14 @@
CD3307E720376CCB00F10D71 /* dndIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dndIcon.png; path = ../shared/images/dndIcon.png; sourceTree = "<group>"; };
CD981A8B2069049A001B875B /* statusIconDisabled.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = statusIconDisabled.png; sourceTree = "<group>"; };
CD981A8C2069049A001B875B /* statusIconDisabled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "statusIconDisabled@2x.png"; sourceTree = "<group>"; };
CDD8075C2134E0930046594E /* Sentry.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sentry.framework; path = ../Carthage/Build/Mac/Sentry.framework; sourceTree = "<group>"; };
CDFA088121367C690089758C /* XPC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = XPC.h; path = ../shared/XPC.h; sourceTree = "<group>"; };
CDFA088221367F980089758C /* XPCUserProto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XPCUserProto.h; path = ../shared/XPCUserProto.h; sourceTree = "<group>"; };
CDFA088321367F980089758C /* XPCDaemonProto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XPCDaemonProto.h; path = ../shared/XPCDaemonProto.h; sourceTree = "<group>"; };
CDFA0886213685370089758C /* XPCUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XPCUser.h; sourceTree = "<group>"; };
CDFA0887213685370089758C /* XPCUser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XPCUser.m; sourceTree = "<group>"; };
CDFA08A8213B3ECA0089758C /* Camera.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Camera.h; sourceTree = "<group>"; };
CDFA08A9213B3ECA0089758C /* Camera.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Camera.m; sourceTree = "<group>"; };
CDFB7884206E2F3400ABDD04 /* statusIconWhite.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = statusIconWhite.png; sourceTree = "<group>"; };
CDFB7885206E2F3400ABDD04 /* statusIconDisabledWhite.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = statusIconDisabledWhite.png; sourceTree = "<group>"; };
CDFB7886206E2F3400ABDD04 /* statusIconDisabledWhite@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "statusIconDisabledWhite@2x.png"; sourceTree = "<group>"; };
@@ -82,17 +100,6 @@
CE968A9B1FCC590200AD6B78 /* statusIcon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "statusIcon@2x.png"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
7D7755E01F02E05B00D0017D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
CD20A0D720579AFD0044BCC5 /* Sentry.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
7D3B75001F13354900568828 /* Base.lproj */ = {
isa = PBXGroup;
@@ -122,7 +129,10 @@
7D3B75201F13356900568828 /* shared */ = {
isa = PBXGroup;
children = (
CDFA088321367F980089758C /* XPCDaemonProto.h */,
CDFA088221367F980089758C /* XPCUserProto.h */,
CD3307E720376CCB00F10D71 /* dndIcon.png */,
CDFA088121367C690089758C /* XPC.h */,
7D16D68F1F64E43300DB3161 /* Update.h */,
7D16D6901F64E43300DB3161 /* Update.m */,
7D16D6911F64E43300DB3161 /* UpdateWindow.xib */,
@@ -130,9 +140,8 @@
7D16D6931F64E43300DB3161 /* UpdateWindowController.m */,
7D5C5F501F200B9200C0E94A /* Utilities.h */,
7D5C5F511F200B9200C0E94A /* Utilities.m */,
7DD2BF781F1EAC9C00B33214 /* DaemonComms.h */,
7DD2BF791F1EAC9C00B33214 /* DaemonComms.m */,
7D3B75211F13357D00568828 /* UserCommsInterface.h */,
7DD2BF781F1EAC9C00B33214 /* XPCDaemonClient.h */,
7DD2BF791F1EAC9C00B33214 /* XPCDaemonClient.m */,
7D3B75221F13357D00568828 /* Consts.h */,
7D3B75231F13357D00568828 /* Logging.m */,
7D3B75241F13357D00568828 /* Logging.h */,
@@ -162,8 +171,8 @@
7D7755E51F02E05B00D0017D /* src */ = {
isa = PBXGroup;
children = (
7DD2BF6C1F1DDF1F00B33214 /* AlertMonitor.h */,
7DD2BF6D1F1DDF1F00B33214 /* AlertMonitor.m */,
CDFA0886213685370089758C /* XPCUser.h */,
CDFA0887213685370089758C /* XPCUser.m */,
7D7755E61F02E05B00D0017D /* AppDelegate.h */,
7D7755E71F02E05B00D0017D /* AppDelegate.m */,
7D3B74FF1F13354900568828 /* StatusBarMenu.h */,
@@ -177,6 +186,8 @@
7D7755EE1F02E05B00D0017D /* MainMenu.xib */,
7D7755F11F02E05B00D0017D /* Info.plist */,
7D7755E91F02E05B00D0017D /* Supporting Files */,
CDFA08A8213B3ECA0089758C /* Camera.h */,
CDFA08A9213B3ECA0089758C /* Camera.m */,
);
name = src;
path = loginItem;
@@ -202,7 +213,7 @@
CD20A0D520579AE50044BCC5 /* Frameworks */ = {
isa = PBXGroup;
children = (
CD20A0D620579AFD0044BCC5 /* Sentry.framework */,
CDD8075C2134E0930046594E /* Sentry.framework */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -215,8 +226,8 @@
buildConfigurationList = 7D7755F41F02E05B00D0017D /* Build configuration list for PBXNativeTarget "loginItem" */;
buildPhases = (
7D7755DF1F02E05B00D0017D /* Sources */,
7D7755E01F02E05B00D0017D /* Frameworks */,
7D7755E11F02E05B00D0017D /* Resources */,
CDD8075B2134E0670046594E /* Copy Frameworks */,
);
buildRules = (
);
@@ -233,7 +244,7 @@
7D7755DB1F02E05B00D0017D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0900;
LastUpgradeCheck = 1000;
ORGANIZATIONNAME = "Objective-See";
TargetAttributes = {
7D7755E21F02E05B00D0017D = {
@@ -241,7 +252,7 @@
ProvisioningStyle = Manual;
SystemCapabilities = {
com.apple.ApplicationGroups.Mac = {
enabled = 1;
enabled = 0;
};
};
};
@@ -280,7 +291,6 @@
CDFB788B206E2F3400ABDD04 /* statusIconWhite@2x.png in Resources */,
CDFB7889206E2F3400ABDD04 /* statusIconDisabledWhite.png in Resources */,
CDFB788A206E2F3400ABDD04 /* statusIconDisabledWhite@2x.png in Resources */,
7D3B75151F13354900568828 /* MainMenu.xib in Resources */,
CD3307E22037648B00F10D71 /* StatusBarPopover.xib in Resources */,
CD981A8D2069049B001B875B /* statusIconDisabled.png in Resources */,
CD981A8E2069049B001B875B /* statusIconDisabled@2x.png in Resources */,
@@ -300,12 +310,13 @@
7D3B75141F13354900568828 /* StatusBarMenu.m in Sources */,
7D7755EB1F02E05B00D0017D /* main.m in Sources */,
7DD260131F25307B00277EC4 /* HyperlinkTextField.m in Sources */,
CDFA08AA213B3ECA0089758C /* Camera.m in Sources */,
7D3B75251F13357D00568828 /* Logging.m in Sources */,
7D5C5F521F200B9200C0E94A /* Utilities.m in Sources */,
CD3307E020375ED000F10D71 /* StatusBarPopoverController.m in Sources */,
7D7755E81F02E05B00D0017D /* AppDelegate.m in Sources */,
7DD2BF6E1F1DDF1F00B33214 /* AlertMonitor.m in Sources */,
7DD2BF7A1F1EAC9C00B33214 /* DaemonComms.m in Sources */,
7DD2BF7A1F1EAC9C00B33214 /* XPCDaemonClient.m in Sources */,
CDFA0888213685370089758C /* XPCUser.m in Sources */,
7D16D6941F64E43300DB3161 /* Update.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -345,6 +356,7 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
@@ -352,6 +364,7 @@
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -359,7 +372,7 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "Developer ID Application: Objective-See, LLC (VBG97UB4TA)";
CODE_SIGN_IDENTITY = "Mac Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
@@ -398,6 +411,7 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
@@ -405,6 +419,7 @@
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -412,7 +427,7 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "Developer ID Application: Objective-See, LLC (VBG97UB4TA)";
CODE_SIGN_IDENTITY = "Mac Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
@@ -435,6 +450,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "";
CODE_SIGN_IDENTITY = "Developer ID Application";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
@@ -443,10 +459,12 @@
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
INFOPLIST_FILE = loginItem/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../../../../../Frameworks";
OTHER_CODE_SIGN_FLAGS = "";
OTHER_CFLAGS = "-DXPC_USER=1";
OTHER_CODE_SIGN_FLAGS = "-o hard,kill,library";
PRODUCT_BUNDLE_IDENTIFIER = "com.objective-see.dnd.helper";
PRODUCT_NAME = "Do Not Disturb Helper";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
};
name = Debug;
};
@@ -454,6 +472,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "";
CODE_SIGN_IDENTITY = "Developer ID Application";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
@@ -462,11 +481,13 @@
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
INFOPLIST_FILE = loginItem/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../../../../../Frameworks";
OTHER_CODE_SIGN_FLAGS = "-o hard,kill";
OTHER_CFLAGS = "-DXPC_USER=1";
OTHER_CODE_SIGN_FLAGS = "-o hard,kill,library";
OTHER_LDFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = "com.objective-see.dnd.helper";
PRODUCT_NAME = "Do Not Disturb Helper";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
};
name = Release;
};
-28
View File
@@ -1,28 +0,0 @@
//
// file: AlertMonitor.h
// project: DND (login item)
// description: monitor for alerts from daemon (header)
//
// created by Patrick Wardle
// copyright (c) 2018 Objective-See. All rights reserved.
//
@import Foundation;
@interface AlertMonitor : NSObject <NSUserNotificationCenterDelegate>
/* PROPERTIES */
@property(nonatomic, retain)NSDate* lastAlert;
/* METHODS */
//forever,
// wait for & display alerts
-(void)monitor;
//forever
// wait for dismiss XPC msg from dameon
// note: currently, will dismiss all alerts...
-(void)dismissAlerts;
@end
-210
View File
@@ -1,210 +0,0 @@
//
// file: AlertMonitor.m
// project: DND (login item)
// description: monitor for alerts from daemom
//
// created by Patrick Wardle
// copyright (c) 2018 Objective-See. All rights reserved.
//
#import "Consts.h"
#import "Logging.h"
#import "AppDelegate.h"
#import "DaemonComms.h"
#import "AlertMonitor.h"
@implementation AlertMonitor
@synthesize lastAlert;
//forever,
// receive & display alerts
-(void)monitor
{
//daemon comms object
DaemonComms* daemonComms = nil;
//wait semaphore
dispatch_semaphore_t semaphore = 0;
//init daemon
// use local var here, as we need to block
daemonComms = [[DaemonComms alloc] init];
//init sema
semaphore = dispatch_semaphore_create(0);
//process alerts
// call daemon and block, then display, and repeat!
while(YES)
{
//pool
@autoreleasepool
{
//dbg msg
logMsg(LOG_DEBUG, @"requesting alert(s) from daemon, will block");
//wait for alert from daemon via XPC
[daemonComms alertRequest:^(NSDictionary* alert)
{
//dbg msg
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"got alert from daemon: %@", alert]);
//tell daemon we got it
// allows it to be discarded from queue
[daemonComms alertResponse];
//signal alert
// indicates it was processed
dispatch_semaphore_signal(semaphore);
//ignore if it's same/same
// sometimes lid open/awake cause weird stuff with XPC resume, so multiple deliveries
if(YES == [self.lastAlert isEqualToDate:alert[ALERT_TIMESTAMP]])
{
//ignore
// will just exit block
return;
}
//update
self.lastAlert = alert[ALERT_TIMESTAMP];
//show alert on main thread
dispatch_async(dispatch_get_main_queue(), ^{
//show notification
[self showNotification:alert];
});
}];
//wait for alert to be received
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}//pool
}//forevers
return;
}
//forever
// wait for alert dismiss XPC msg from dameon
// note: currently, will dismiss all alerts shown...
-(void)dismissAlerts
{
//daemon comms object
DaemonComms* daemonComms = nil;
//wait semaphore
dispatch_semaphore_t semaphore = 0;
//init daemon
// use local var here, as we need to block
daemonComms = [[DaemonComms alloc] init];
//init sema
semaphore = dispatch_semaphore_create(0);
//dimisss alerts
// call daemon and block, then dismiss/repeat
while(YES)
{
//pool
@autoreleasepool
{
//dbg msg
logMsg(LOG_DEBUG, @"requesting alert dismiss message(s) from daemon, will block");
//wait for alert dismiss from daemon via XPC
// for now, will just dimiss all (shown) alerts
[daemonComms alertDismiss:^(NSDictionary* alert)
{
//dbg msg
logMsg(LOG_DEBUG, @"got 'alert dismiss' message from daemon");
//dismiss alerts on main thread
dispatch_async(dispatch_get_main_queue(), ^{
//show notification
[[NSUserNotificationCenter defaultUserNotificationCenter] removeAllDeliveredNotifications];
//set app delegate's touch bar to nil
// will hide/unset the touch bar alert....
((AppDelegate*)[[NSApplication sharedApplication] delegate]).touchBar = nil;
});
//signal alert
// indicates it was processed
dispatch_semaphore_signal(semaphore);
}];
//wait for alert dismiss msg to be received
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}//pool
}//forevers
return;
}
//format, then show notification
// both on screen and on touch bar
-(void)showNotification:(NSDictionary*)alert
{
//notification
NSUserNotification* notification = nil;
//formatter
NSDateFormatter* dateFormat = nil;
//dbg msg
logMsg(LOG_DEBUG, @"displaying alert to user...");
//alloc notification
notification = [[NSUserNotification alloc] init];
//alloc formatter
dateFormat = [[NSDateFormatter alloc] init];
//set date format
[dateFormat setDateFormat:@"MM/dd/yyyy HH:mm:ss"];
//set other button title
notification.otherButtonTitle = @"Dismiss";
//remove action button
notification.hasActionButton = NO;
//set title
notification.title = @"⚠️ Do Not Disturb Alert";
//set subtitle
notification.subtitle = [NSString stringWithFormat:@"Lid Opened: %@", [dateFormat stringFromDate:alert[ALERT_TIMESTAMP]]];
//set delegate to self
[[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
//deliver notification
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
//init/show touch bar
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) initTouchBar];
return;
}
//delegate method
// always should alert to user
-(BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification
{
return YES;
}
@end
+3 -2
View File
@@ -8,9 +8,10 @@
//
@import Cocoa;
@import AVFoundation;
#import "DaemonComms.h"
#import "StatusBarMenu.h"
#import "XPCDaemonClient.h"
#import "UpdateWindowController.h"
@interface AppDelegate : NSObject <NSApplicationDelegate, NSTouchBarProvider, NSTouchBarDelegate>
@@ -30,7 +31,7 @@
@property(nonatomic, retain)UpdateWindowController* updateWindowController;
//daemon comms
@property(nonatomic, retain)DaemonComms* daemonComms;
@property(nonatomic, retain)XPCDaemonClient* daemonComms;
//observer
@property(nonatomic, retain)NSObject* appObserver;
+29 -54
View File
@@ -12,7 +12,7 @@
#import "Logging.h"
#import "Utilities.h"
#import "AppDelegate.h"
#import "AlertMonitor.h"
#import "XPCDaemonClient.h"
@interface AppDelegate ()
@@ -38,14 +38,14 @@
//dbg msg
logMsg(LOG_DEBUG, @"starting DND login item");
//init deamon comms
daemonComms = [[DaemonComms alloc] init];
//init deamon client
daemonComms = [[XPCDaemonClient alloc] init];
//get preferences
// sends XPC message to daemon
preferences = [self.daemonComms getPreferences:nil];
//no preferences yet? ... first run
//no preferences yet? ... first run on full (re)install
// a) set some defaults for login item (passive mode, etc)
// b) wait for main app to exit before checking in with daemon
if(0 == preferences.count)
@@ -70,39 +70,44 @@
// wait until it's exited to complete initializations
self.appObserver = [[[NSWorkspace sharedWorkspace] notificationCenter] addObserverForName:NSWorkspaceDidTerminateApplicationNotification object:nil queue:nil usingBlock:^(NSNotification *notification)
{
//ignore others
if(YES != [MAIN_APP_ID isEqualToString:[((NSRunningApplication*)notification.userInfo[NSWorkspaceApplicationKey]) bundleIdentifier]])
{
//ignore
return;
}
//ignore others
if(YES != [MAIN_APP_ID isEqualToString:[((NSRunningApplication*)notification.userInfo[NSWorkspaceApplicationKey]) bundleIdentifier]])
{
//ignore
return;
}
//dbg msg
logMsg(LOG_DEBUG, @"main application completed");
//dbg msg
logMsg(LOG_DEBUG, @"main application completed");
//remove observer
[[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self.appObserver];
//unset
self.appObserver = nil;
//remove observer
[[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self.appObserver];
//unset
self.appObserver = nil;
//(re)load prefs
// main app should have set em all now
preferences = [self.daemonComms getPreferences:nil];
//complete initializations
[self completeInitialization:preferences firstTime:YES];
}];
//complete initializations
// will show popover, etc
[self completeInitialization:preferences firstTime:YES];
}]; //main app (welcome screen) exited
}
//found prefs
// main app already ran, so just complete init's
else
{
//might be an upgrade so ask for camera permissions
requestCameraAccess();
//complete initializations
[self completeInitialization:preferences firstTime:NO];
}
bail:
return;
@@ -112,9 +117,6 @@ bail:
// based on prefs, show status bar, check for updates, etc...
-(void)completeInitialization:(NSDictionary*)preferences firstTime:(BOOL)firstTime
{
//alert monitor obj
__block AlertMonitor* alertMonitor = nil;
//run with status bar icon?
if(YES != [preferences[PREF_NO_ICON_MODE] boolValue])
{
@@ -147,33 +149,6 @@ bail:
});
}
//wait to checkin
// first time, need a bit to show the popover
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, firstTime * 5 * NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
{
//init alert monitor
alertMonitor = [[AlertMonitor alloc] init];
//in background
// monitor / process alerts from daemon
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//monitor
[alertMonitor monitor];
});
//in background
// wait for alert dimiss msgs from daemon
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//monitor
[alertMonitor dismissAlerts];
});
});
return;
}
@@ -238,7 +213,7 @@ bail:
touchBarItem = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
//icon
if(YES == [identifier isEqualToString: @".icon" ])
if(YES == [identifier isEqualToString:@".icon"])
{
//init icon view
iconView = [[NSImageView alloc] initWithFrame:NSMakeRect(0, 0, 30.0, 30.0)];
+27
View File
@@ -0,0 +1,27 @@
//
// Camera.h
// loginItem
//
// Created by Patrick Wardle on 9/1/18.
// Copyright © 2018 Objective-See. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
@interface Camera : NSObject
/* PROPERTIES */
//av session
@property(nonatomic, retain)AVCaptureSession* session;
/* METHODS */
//capture an image from the webcam
-(NSData*)captureImage;
@end
+184
View File
@@ -0,0 +1,184 @@
//
// Camera.m
// loginItem
//
// Created by Patrick Wardle on 9/1/18.
// Copyright © 2018 Objective-See. All rights reserved.
//
#import "Camera.h"
#import "Logging.h"
@implementation Camera
@synthesize session;
//configure
-(BOOL)configure
{
//flag
BOOL configured = NO;
//device
AVCaptureDevice* device = nil;
//input
AVCaptureInput* input = nil;
//output
AVCaptureStillImageOutput* output = nil;
//find default camera
device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if(nil == device)
{
//err msg
logMsg(LOG_ERR, @"failed to find camera for capture");
//bail
goto bail;
}
//init input from camera
input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
if(nil == input)
{
//err msg
logMsg(LOG_ERR, @"failed to find input from camera");
//bail
goto bail;
}
//init session
self.session = [[AVCaptureSession alloc] init];
//check if input can be added to session
if(YES != [self.session canAddInput:input])
{
//err msg
logMsg(LOG_ERR, @"cannot add input to session");
//bail
goto bail;
}
//add input
[self.session addInput:input];
//init output
output = [[AVCaptureStillImageOutput alloc] init];
//set output settings (jpeg)
output.outputSettings = @{AVVideoCodecKey:AVVideoCodecJPEG};
//check if output can be added to session
if(YES != [self.session canAddOutput:output])
{
//err msg
logMsg(LOG_ERR, @"cannot add output to session");
//bail
goto bail;
}
//add output
[self.session addOutput:output];
//happy
configured = YES;
bail:
return configured;
}
//capture an image from the webcam
-(NSData*)captureImage
{
//image
__block NSData* image = nil;
//output
__block AVCaptureStillImageOutput* output = nil;
//wait semaphore
dispatch_semaphore_t semaphore = 0;
//init sema
semaphore = dispatch_semaphore_create(0);
//configure/init session
if(YES == [self configure])
{
//dbg msg
logMsg(LOG_DEBUG, @"configured camera for capture");
//start
[self.session startRunning];
//give session some time to start
// could use KVO, etc, but this seems like a pain
// see: https://stackoverflow.com/questions/27260697/avcapturedevice-adjustingexposure-is-false-but-captured-image-is-dark
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
//grab output
output = self.session.outputs.firstObject;
//capture image
[output captureStillImageAsynchronouslyFromConnection:[output connectionWithMediaType:AVMediaTypeVideo] completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error)
{
//covert image
if( (nil == error) &&
(NULL != imageDataSampleBuffer))
{
//dbg msg
logMsg(LOG_DEBUG, @"captured image");
//covert
image = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
}
//error
else
{
//err msg
logMsg(LOG_ERR, [NSString stringWithFormat:@"failed to capture image (%@)", error]);
}
//(always) signal sema
dispatch_semaphore_signal(semaphore);
}];
});
//wait for install to be completed by XPC
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
//stop session
if(YES == self.session.isRunning)
{
//stop
[self.session stopRunning];
}
}
//failed to init session
else
{
//err msg
logMsg(LOG_ERR, @"failed to initialize/configure camera capture session");
//bail
goto bail;
}
bail:
return image;
}
@end
+2 -2
View File
@@ -17,11 +17,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.1.0</string>
<string>1.3.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.1.0</string>
<string>1.3.0</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>LSUIElement</key>
+2 -2
View File
@@ -9,7 +9,7 @@
@import Cocoa;
#import "DaemonComms.h"
#import "XPCDaemonClient.h"
@interface StatusBarMenu : NSObject <NSPopoverDelegate>
{
@@ -23,7 +23,7 @@
@property (retain, nonatomic)NSPopover *popover;
//daemom comms object
@property (nonatomic, retain)DaemonComms* daemonComms;
@property (nonatomic, retain)XPCDaemonClient* daemonComms;
//disabled flag
@property BOOL isDisabled;
+2 -3
View File
@@ -11,9 +11,8 @@
#import "Logging.h"
#import "Utilities.h"
#import "AppDelegate.h"
#import "DaemonComms.h"
#import "StatusBarMenu.h"
#import "UserCommsInterface.h"
#import "XPCDaemonClient.h"
#import "StatusBarPopoverController.h"
//menu items
@@ -44,7 +43,7 @@ enum menuItems
if(self != nil)
{
//init daemon comms
daemonComms = [[DaemonComms alloc] init];
daemonComms = [[XPCDaemonClient alloc] init];
//init status item
statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
+20
View File
@@ -0,0 +1,20 @@
//
// file: XPCUser.h
// project: DND (login item)
// description: user XPC methods (header)
//
// created by Patrick Wardle
// copyright (c) 2018 Objective-See. All rights reserved.
//
@import Foundation;
#import <dnd/dnd-Swift.h>
#import "XPCUserProto.h"
@interface XPCUser : NSObject <XPCUserProtocol, NSUserNotificationCenterDelegate>
{
}
@end
+121
View File
@@ -0,0 +1,121 @@
//
// file: XPCUser.m
// project: DND (login item)
// description: user XPC methods
//
// created by Patrick Wardle
// copyright (c) 2018 Objective-See. All rights reserved.
//
#import "Camera.h"
#import "Consts.h"
#import "Logging.h"
#import "XPCUser.h"
#import "AppDelegate.h"
@implementation XPCUser
//show an alert
-(void)alertShow:(NSDictionary*)alert
{
//notification
NSUserNotification* notification = nil;
//formatter
NSDateFormatter* dateFormat = nil;
//dbg msg
logMsg(LOG_DEBUG, @"XPC request from daemon: alert show");
//alloc notification
notification = [[NSUserNotification alloc] init];
//alloc formatter
dateFormat = [[NSDateFormatter alloc] init];
//set date format
[dateFormat setDateFormat:@"MM/dd/yyyy HH:mm:ss"];
//set other button title
notification.otherButtonTitle = @"Dismiss";
//remove action button
notification.hasActionButton = NO;
//set title
notification.title = @"⚠️ Do Not Disturb Alert";
//set subtitle
notification.subtitle = [NSString stringWithFormat:@"Lid Opened: %@", [dateFormat stringFromDate:alert[ALERT_TIMESTAMP]]];
//set delegate to self
[[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
//show alert on main thread
dispatch_async(dispatch_get_main_queue(), ^{
//deliver notification
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
//init/show touch bar
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) initTouchBar];
});
return;
}
//dismiss alert(s)
-(void)alertDismiss
{
//dbg msg
logMsg(LOG_DEBUG, @"XPC request from daemon: alert dismiss");
//dismiss alerts on main thread
dispatch_async(dispatch_get_main_queue(), ^{
//clear (all) notification(s)
[[NSUserNotificationCenter defaultUserNotificationCenter] removeAllDeliveredNotifications];
//set app delegate's touch bar to nil
// will hide/unset the touch bar alert....
((AppDelegate*)[[NSApplication sharedApplication] delegate]).touchBar = nil;
});
return;
}
//XPC method
// capture an image from the webcam
-(void)captureImage:(void (^)(NSData *))reply
{
//image data
NSData* image = nil;
//camera obj
Camera* camera = nil;
//dbg msg
logMsg(LOG_DEBUG, @"XPC request from daemon: capture picture");
//init camera
camera = [[Camera alloc] init];
//grab image
image = [camera captureImage];
//get current prefs
reply(image);
return;
}
//'NSUserNotificationCenterDelegate' delegate method
// tell system to always present (show) the alert to user
-(BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification
{
return YES;
}
@end
+2 -5
View File
@@ -24,11 +24,8 @@ int main(int argc, const char * argv[])
//dbg msg
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"STARTED: login item (args: %@)", [[NSProcessInfo processInfo] arguments]]);
//init crash reporting client
SentryClient.sharedClient = [[SentryClient alloc] initWithDsn:CRASH_REPORTING_URL didFailWithError:nil];
//start crash handler
[SentryClient.sharedClient startCrashHandlerWithError:nil];
//init crash reporting
initCrashReporting();
//already running?
if(YES == isAppRunning([[NSBundle mainBundle] bundleIdentifier]))
+24 -31
View File
@@ -8,14 +8,13 @@
/* Begin PBXBuildFile section */
7D16D69A1F65EF9900DB3161 /* Update.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D16D6991F65EF9900DB3161 /* Update.m */; };
7D2582571F19FAD700D28B95 /* DaemonComms.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D2582561F19FAD700D28B95 /* DaemonComms.m */; };
7D2582571F19FAD700D28B95 /* XPCDaemonClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D2582561F19FAD700D28B95 /* XPCDaemonClient.m */; };
7D46FF041F5F496800FEB0F8 /* patrons.txt in Resources */ = {isa = PBXBuildFile; fileRef = 7D46FF031F5F496800FEB0F8 /* patrons.txt */; };
7D564DAE1F18434F00B8AAD6 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D564DAD1F18434F00B8AAD6 /* AppDelegate.m */; };
7D564DB11F18434F00B8AAD6 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D564DB01F18434F00B8AAD6 /* main.m */; };
7D564DB61F18434F00B8AAD6 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7D564DB41F18434F00B8AAD6 /* MainMenu.xib */; };
7D564DD61F18441500B8AAD6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7D564DBF1F18441500B8AAD6 /* Assets.xcassets */; };
7D564DDA1F18441500B8AAD6 /* AboutWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D564DC31F18441500B8AAD6 /* AboutWindowController.m */; };
7D564DDB1F18441500B8AAD6 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7D564DC51F18441500B8AAD6 /* MainMenu.xib */; };
7D564DDC1F18441500B8AAD6 /* AboutWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7D564DC71F18441500B8AAD6 /* AboutWindow.xib */; };
7D564DDF1F18441500B8AAD6 /* HyperlinkTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D564DCE1F18441500B8AAD6 /* HyperlinkTextField.m */; };
7D564DE61F18446200B8AAD6 /* Logging.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D564DE41F18446200B8AAD6 /* Logging.m */; };
@@ -38,8 +37,7 @@
CD17D58C201A7F8500F798D7 /* Welcome.xib in Resources */ = {isa = PBXBuildFile; fileRef = CD17D58A201A7F8500F798D7 /* Welcome.xib */; };
CD17D58F201A827A00F798D7 /* QuickResponseCode.m in Sources */ = {isa = PBXBuildFile; fileRef = CD17D58E201A827A00F798D7 /* QuickResponseCode.m */; };
CD1FD56B2089224F00151D1C /* appStore.pdf in Resources */ = {isa = PBXBuildFile; fileRef = CD1FD56A2089224E00151D1C /* appStore.pdf */; };
CD20A0CE205797030044BCC5 /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD20A0CD205797030044BCC5 /* Sentry.framework */; };
CD20A0DA20579B290044BCC5 /* Sentry.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CD20A0CD205797030044BCC5 /* Sentry.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
CD20A0DA20579B290044BCC5 /* Sentry.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = CD20A0CD205797030044BCC5 /* Sentry.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
CD2F407F204B417E0066673E /* alert.png in Resources */ = {isa = PBXBuildFile; fileRef = CD2F407E204B417E0066673E /* alert.png */; };
CD2F4081204B41C90066673E /* hacker.png in Resources */ = {isa = PBXBuildFile; fileRef = CD2F4080204B41C90066673E /* hacker.png */; };
CD325425204DEAEA0059951B /* dndText@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CD325424204DEAEA0059951B /* dndText@2x.png */; };
@@ -59,23 +57,15 @@
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
7DD25FEE1F23B5AE00277EC4 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = Contents/Library/LoginItems;
dstSubfolderSpec = 1;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
CD20A0D920579B170044BCC5 /* CopyFiles */ = {
CD20A0D920579B170044BCC5 /* Copy Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
CD20A0DA20579B290044BCC5 /* Sentry.framework in CopyFiles */,
CD20A0DA20579B290044BCC5 /* Sentry.framework in Copy Frameworks */,
);
name = "Copy Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
@@ -83,9 +73,9 @@
/* Begin PBXFileReference section */
7D16D6981F65EF9900DB3161 /* Update.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Update.h; path = ../shared/Update.h; sourceTree = "<group>"; };
7D16D6991F65EF9900DB3161 /* Update.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Update.m; path = ../shared/Update.m; sourceTree = "<group>"; };
7D2582551F19FAD700D28B95 /* DaemonComms.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DaemonComms.h; path = ../shared/DaemonComms.h; sourceTree = "<group>"; };
7D2582561F19FAD700D28B95 /* DaemonComms.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DaemonComms.m; path = ../shared/DaemonComms.m; sourceTree = "<group>"; };
7D2582581F19FB6000D28B95 /* UserCommsInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UserCommsInterface.h; path = ../shared/UserCommsInterface.h; sourceTree = "<group>"; };
7D2582551F19FAD700D28B95 /* XPCDaemonClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XPCDaemonClient.h; path = ../shared/XPCDaemonClient.h; sourceTree = "<group>"; };
7D2582561F19FAD700D28B95 /* XPCDaemonClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XPCDaemonClient.m; path = ../shared/XPCDaemonClient.m; sourceTree = "<group>"; };
7D2582581F19FB6000D28B95 /* XPCDaemonProto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XPCDaemonProto.h; path = ../shared/XPCDaemonProto.h; sourceTree = "<group>"; };
7D46FF031F5F496800FEB0F8 /* patrons.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = patrons.txt; sourceTree = "<group>"; };
7D564DA91F18434F00B8AAD6 /* Do Not Disturb.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Do Not Disturb.app"; sourceTree = BUILT_PRODUCTS_DIR; };
7D564DAC1F18434F00B8AAD6 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
@@ -152,7 +142,6 @@
buildActionMask = 2147483647;
files = (
CDAAC238201FD4660032F2E6 /* LocalAuthentication.framework in Frameworks */,
CD20A0CE205797030044BCC5 /* Sentry.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -276,11 +265,11 @@
children = (
CD1FD56A2089224E00151D1C /* appStore.pdf */,
7D564DE31F18446200B8AAD6 /* Consts.h */,
7D2582551F19FAD700D28B95 /* DaemonComms.h */,
7D2582561F19FAD700D28B95 /* DaemonComms.m */,
7D2582551F19FAD700D28B95 /* XPCDaemonClient.h */,
7D2582561F19FAD700D28B95 /* XPCDaemonClient.m */,
7D564DE51F18446200B8AAD6 /* Logging.h */,
7D564DE41F18446200B8AAD6 /* Logging.m */,
7D2582581F19FB6000D28B95 /* UserCommsInterface.h */,
7D2582581F19FB6000D28B95 /* XPCDaemonProto.h */,
7D16D6981F65EF9900DB3161 /* Update.h */,
7D16D6991F65EF9900DB3161 /* Update.m */,
7D564DE91F1855E900B8AAD6 /* UpdateWindowController.h */,
@@ -311,9 +300,8 @@
7D564DA51F18434F00B8AAD6 /* Sources */,
7D564DA61F18434F00B8AAD6 /* Frameworks */,
7D564DA71F18434F00B8AAD6 /* Resources */,
7DD25FEE1F23B5AE00277EC4 /* CopyFiles */,
7D16D6971F650FF400DB3161 /* ShellScript */,
CD20A0D920579B170044BCC5 /* CopyFiles */,
CD20A0D920579B170044BCC5 /* Copy Frameworks */,
);
buildRules = (
);
@@ -330,7 +318,7 @@
7D564DA11F18434F00B8AAD6 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0900;
LastUpgradeCheck = 1000;
ORGANIZATIONNAME = "Objective-See";
TargetAttributes = {
7D564DA81F18434F00B8AAD6 = {
@@ -338,7 +326,7 @@
ProvisioningStyle = Manual;
SystemCapabilities = {
com.apple.ApplicationGroups.Mac = {
enabled = 1;
enabled = 0;
};
};
};
@@ -396,7 +384,6 @@
CDAAC21D201D77390032F2E6 /* unconnected.png in Resources */,
CD2F4081204B41C90066673E /* hacker.png in Resources */,
CE968A9F1FCC66A300AD6B78 /* prefsAction.png in Resources */,
7D564DDB1F18441500B8AAD6 /* MainMenu.xib in Resources */,
CDAAC217201D54C30032F2E6 /* prefsLink.png in Resources */,
CE133C5F1FD756CC00A29D67 /* dndIcon.png in Resources */,
7D564DEB1F1855E900B8AAD6 /* UpdateWindow.xib in Resources */,
@@ -418,7 +405,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "#for normal builds\n# ->just copy into app\nmkdir -p \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Library/LoginItems\"\ncp -R -f \"$BUILT_PRODUCTS_DIR/Do Not Disturb Helper.app\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Library/LoginItems\"";
shellScript = "rm -rf \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Library/LoginItems\"\nmkdir -p \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Library/LoginItems\"\n\n#archiving\nif [[ $BUILT_PRODUCTS_DIR = *\"ArchiveIntermediates\"* ]]; then\n cp -R -f \"$PROJECT_TEMP_ROOT/UninstalledProducts/macosx/Do Not Disturb Helper.app\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Library/LoginItems\"\n\n#normal build\nelse\n cp -R -f \"$BUILT_PRODUCTS_DIR/Do Not Disturb Helper.app\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Library/LoginItems\"\nfi\n";
};
/* End PBXShellScriptBuildPhase section */
@@ -429,7 +416,7 @@
files = (
7D564DEA1F1855E900B8AAD6 /* UpdateWindowController.m in Sources */,
CD17D58F201A827A00F798D7 /* QuickResponseCode.m in Sources */,
7D2582571F19FAD700D28B95 /* DaemonComms.m in Sources */,
7D2582571F19FAD700D28B95 /* XPCDaemonClient.m in Sources */,
7D564DE61F18446200B8AAD6 /* Logging.m in Sources */,
7D16D69A1F65EF9900DB3161 /* Update.m in Sources */,
7D564DB11F18434F00B8AAD6 /* main.m in Sources */,
@@ -477,6 +464,7 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
@@ -484,6 +472,7 @@
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -530,6 +519,7 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
@@ -537,6 +527,7 @@
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -576,10 +567,11 @@
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
INFOPLIST_FILE = mainApp/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
OTHER_CODE_SIGN_FLAGS = "";
OTHER_CODE_SIGN_FLAGS = "-o hard,kill,library";
PRODUCT_BUNDLE_IDENTIFIER = "com.objective-see.dnd";
PRODUCT_NAME = "Do Not Disturb";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
};
name = Debug;
};
@@ -596,11 +588,12 @@
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
INFOPLIST_FILE = mainApp/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
OTHER_CODE_SIGN_FLAGS = "-o hard,kill";
OTHER_CODE_SIGN_FLAGS = "-o hard,kill,library";
OTHER_LDFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = "com.objective-see.dnd";
PRODUCT_NAME = "Do Not Disturb";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
};
name = Release;
};
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0920"
LastUpgradeVersion = "1000"
version = "1.3">
<BuildAction
parallelizeBuildables = "NO"
@@ -40,7 +40,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
@@ -57,10 +56,9 @@
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
language = ""
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
+2 -2
View File
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14113" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14113"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
+9 -2
View File
@@ -22,6 +22,8 @@
{
//center
[self.window center];
return;
}
//automatically invoked when window is loaded
@@ -34,8 +36,13 @@
//super
[super windowDidLoad];
//make white
[self.window setBackgroundColor: NSColor.whiteColor];
//not in mojave dark mode?
// make window color white
if(YES != isDarkMode())
{
//make white
self.window.backgroundColor = NSColor.whiteColor;
}
//grab app version
version = getAppVersion();
+1 -1
View File
@@ -9,7 +9,7 @@
@import Cocoa;
#import "DaemonComms.h"
#import "XPCDaemonClient.h"
#import "AboutWindowController.h"
#import "PrefsWindowController.h"
#import "UpdateWindowController.h"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 993 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 B

After

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 475 B

After

Width:  |  Height:  |  Size: 868 B

+4 -2
View File
@@ -17,9 +17,9 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.1.0</string>
<string>1.3.0</string>
<key>CFBundleVersion</key>
<string>1.1.0</string>
<string>1.3.0</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key>
@@ -28,5 +28,7 @@
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>AppDelegate</string>
<key>NSCameraUsageDescription</key>
<string>When a lid open event occurs, this will allow the application to take a picture!</string>
</dict>
</plist>
+20 -21
View File
@@ -1,9 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14313.13.2" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
<capability name="box content view" minToolsVersion="7.0"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14313.13.2"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -33,18 +32,18 @@
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
<rect key="contentRect" x="196" y="240" width="600" height="383"/>
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<view key="contentView" wantsLayer="YES" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="600" height="383"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="X2d-3b-ceM">
<rect key="frame" x="0.0" y="0.0" width="600" height="62"/>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="TfC-c7-kXd">
<rect key="frame" x="154" y="0.0" width="293" height="46"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" image="dndText" id="W8J-sT-YoM"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="dndText" id="EOL-U2-Wgh"/>
</imageView>
</subviews>
</view>
@@ -307,7 +306,7 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="path" drawsBackground="YES" id="kLf-zy-hmt">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
@@ -395,7 +394,7 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" fixedFrame="YES" tag="7" translatesAutoresizingMaskIntoConstraints="NO" id="Mtn-pi-zIl">
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Mtn-pi-zIl">
<rect key="frame" x="233" y="132" width="134" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Check Now" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="2qr-2x-A3U">
@@ -443,20 +442,20 @@
</textField>
<scrollView horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="RDW-1i-H7T">
<rect key="frame" x="322" y="115" width="258" height="153"/>
<clipView key="contentView" id="FSf-NQ-BdZ">
<clipView key="contentView" drawsBackground="NO" id="FSf-NQ-BdZ">
<rect key="frame" x="1" y="1" width="256" height="151"/>
<autoresizingMask key="autoresizingMask"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView editable="NO" selectable="NO" importsGraphics="NO" verticallyResizable="YES" usesFontPanel="YES" findStyle="panel" continuousSpellChecking="YES" usesRuler="YES" allowsNonContiguousLayout="YES" quoteSubstitution="YES" dashSubstitution="YES" spellingCorrection="YES" smartInsertDelete="YES" id="9cB-rx-0JH">
<rect key="frame" x="0.0" y="0.0" width="256" height="151"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
<size key="minSize" width="256" height="151"/>
<size key="maxSize" width="463" height="10000000"/>
<color key="insertionPointColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
<color key="insertionPointColor" name="textColor" catalog="System" colorSpace="catalog"/>
</textView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</clipView>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="YES" id="efX-ju-LJj">
<rect key="frame" x="-100" y="-100" width="87" height="18"/>
@@ -519,11 +518,11 @@
</constraints>
<point key="canvasLocation" x="218" y="1428.5"/>
</customView>
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" hidesOnDeactivate="YES" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="vdL-RT-p6a" userLabel="QRC Panel" customClass="NSPanel">
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" hidesOnDeactivate="YES" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="vdL-RT-p6a" userLabel="QRC Panel" customClass="NSPanel">
<windowStyleMask key="styleMask" utility="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="2832" y="172" width="594" height="440"/>
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<view key="contentView" id="jEo-ef-0kG">
<rect key="frame" x="0.0" y="0.0" width="594" height="440"/>
<autoresizingMask key="autoresizingMask"/>
@@ -5125,9 +5124,9 @@ IGsABCB5AAQgfQAEIIQABCCJAAQglgAEIJkABCCmAAQgqwAEILMABCC2AAQguwAEIMMABCDGAAQg2AAE
INsABCDgAAAAAAAABAEAAAAAAAAAVgAAAAAAAAAAAAAAAAAEIOI
</mutableData>
</image>
<image name="prefsAction" width="32" height="32"/>
<image name="prefsGeneral" width="32" height="32"/>
<image name="prefsLink" width="32" height="32"/>
<image name="prefsUpdate" width="32" height="32"/>
<image name="prefsAction" width="64" height="64"/>
<image name="prefsGeneral" width="64" height="64"/>
<image name="prefsLink" width="64" height="64"/>
<image name="prefsUpdate" width="64" height="64"/>
</resources>
</document>
+2 -1
View File
@@ -9,6 +9,7 @@
@import Cocoa;
#import "XPCDaemonClient.h"
#import "UpdateWindowController.h"
/* CONSTS */
@@ -57,7 +58,7 @@
/* PROPERTIES */
//daemon comms object
@property (retain, nonatomic)DaemonComms* daemonComms;
@property (retain, nonatomic)XPCDaemonClient* daemonComms;
//preferences
@property(nonatomic, retain)NSDictionary* preferences;
+18 -10
View File
@@ -12,7 +12,7 @@
#import "Logging.h"
#import "Utilities.h"
#import "AppDelegate.h"
#import "DaemonComms.h"
#import "XPCDaemonClient.h"
#import "QuickResponseCode.h"
#import "PrefsWindowController.h"
#import "UpdateWindowController.h"
@@ -40,7 +40,7 @@
self.window.title = [NSString stringWithFormat:@"Do Not Disturb (v. %@)", getAppVersion()];
//init daemon comms
daemonComms = [[DaemonComms alloc] init];
daemonComms = [[XPCDaemonClient alloc] init];
//make 'general' selected
[self.toolbar setSelectedItemIdentifier:TOOLBAR_GENERAL_ID];
@@ -111,9 +111,12 @@
//set 'touch id' button state
((NSButton*)[view viewWithTag:BUTTON_TOUCHID_MODE]).state = [self.preferences[PREF_TOUCHID_MODE] boolValue];
//set 'no remote tasking' button state
((NSButton*)[view viewWithTag:BUTTON_NO_REMOTE_TASKING]).state = [self.preferences[PREF_NO_REMOTE_TASKING] boolValue];
//set 'start mode' button state
((NSButton*)[view viewWithTag:BUTTON_START_MODE]).state = [self.preferences[PREF_START_MODE] boolValue];
break;
}
@@ -139,9 +142,6 @@
//set 'monitor' button state
((NSButton*)[view viewWithTag:BUTTON_MONITOR_ACTION]).state = [self.preferences[PREF_MONITOR_ACTION] boolValue];
//set 'no remote tasking' button state
((NSButton*)[view viewWithTag:BUTTON_NO_REMOTE_TASKING]).state = [self.preferences[PREF_NO_REMOTE_TASKING] boolValue];
break;
}
@@ -242,13 +242,22 @@
self.hostName.stringValue = [[NSHost currentHost] localizedName];
//set font
self.deviceNames.font = [NSFont fontWithName:@"Avenir Next Condensed Regular" size:20];
self.deviceNames.font = [NSFont fontWithName:@"Avenir Next Condensed Regular" size:18];
//set inset
self.deviceNames.textContainerInset = NSMakeSize(5.0, 10.0);
//reset
self.deviceNames.string = @"";
//not in mojave dark mode?
// make window color white
if( (YES != [[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){10, 14, 0}]) &&
(YES != [[[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"] isEqualToString:@"Dark"]) )
{
//light gray
self.deviceNames.backgroundColor = [NSColor lightGrayColor];
}
//populate text view w/ registered devices
for(NSString* deviceToken in registeredDevices[PREF_REGISTERED_DEVICES])
@@ -419,7 +428,7 @@
QuickResponseCode* qrcObj = nil;
//daemon comms obj
__block DaemonComms* daemonComms = nil;
__block XPCDaemonClient* daemonComms = nil;
//size
CGSize qrcSize = {0};
@@ -499,7 +508,7 @@
//init daemon comms
// will connect, etc.
daemonComms = [[DaemonComms alloc] init];
daemonComms = [[XPCDaemonClient alloc] init];
//call into daemon/framework
// this will block until phone linking/registration is complete
@@ -518,7 +527,6 @@
[self toolbarButtonHandler:self.linkToolbarItem];
});
}];
}];
+2 -2
View File
@@ -10,14 +10,14 @@
@import Cocoa;
@import Foundation;
#import "DaemonComms.h"
#import "XPCDaemonClient.h"
@interface QuickResponseCode : NSObject
/* PROPERTIES */
//daemon comms obj
@property(nonatomic, retain)DaemonComms* daemonComms;
@property(nonatomic, retain)XPCDaemonClient* daemonComms;
/* METHODS */
+2 -2
View File
@@ -8,7 +8,7 @@
//
#import "Logging.h"
#import "DaemonComms.h"
#import "XPCDaemonClient.h"
#import "QuickResponseCode.h"
#import <CoreImage/CoreImage.h>
@@ -27,7 +27,7 @@
{
//init daemon comms
// will connect, etc.
daemonComms = [[DaemonComms alloc] init];
daemonComms = [[XPCDaemonClient alloc] init];
}
return self;
+4 -5
View File
@@ -1,9 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14313.13.2" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
<capability name="box content view" minToolsVersion="7.0"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14313.13.2"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -23,7 +22,7 @@
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Do Not Disturb" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
<window title="Do Not Disturb" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="800" height="500"/>
@@ -177,7 +176,7 @@
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="laptop" id="tNr-00-iNk"/>
</imageView>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9FN-FI-sj3">
<rect key="frame" x="345" y="100" width="110" height="49"/>
<rect key="frame" x="337" y="94" width="127" height="55"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="bevel" bezelStyle="rounded" image="appStore" imagePosition="overlaps" alignment="center" imageScaling="proportionallyDown" inset="2" id="cPG-lr-39E">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@@ -8,6 +8,7 @@
//
@import Cocoa;
#import <objc/message.h>
@interface WelcomeWindowController : NSWindowController
+28 -9
View File
@@ -10,7 +10,7 @@
#import "Consts.h"
#import "Logging.h"
#import "Utilities.h"
#import "DaemonComms.h"
#import "XPCDaemonClient.h"
#import "QuickResponseCode.h"
#import "WelcomeWindowController.h"
@@ -34,8 +34,13 @@
//center
[self.window center];
//make white
[self.window setBackgroundColor: NSColor.whiteColor];
//not in mojave dark mode?
// make window color white
if(YES != isDarkMode())
{
//make white
self.window.backgroundColor = NSColor.whiteColor;
}
//when supported
// indicate title bar is transparent (too)
@@ -54,6 +59,7 @@
return;
}
//button handler for all views
// show next view, sometimes, with view specific logic
-(IBAction)buttonHandler:(id)sender
@@ -100,8 +106,8 @@
//skip
case SKIP_LINKING:
{
//bye
[NSApp terminate:self];
//bye!
[self terminate];
break;
}
@@ -124,8 +130,8 @@
//linked view
case VIEW_LINKED:
{
//exit
[NSApp terminate:nil];
//bye!
[self terminate];
break;
}
@@ -133,6 +139,19 @@
return;
}
//exit app
// performing any actions
-(void)terminate
{
//before exiting
// ask for camera
requestCameraAccess();
//exit
[NSApp terminate:nil];
}
//generate a QRC
// calls into daemon and then displays
-(void)generateQRC
@@ -141,7 +160,7 @@
QuickResponseCode* qrcObj = nil;
//daemon comms obj
__block DaemonComms* daemonComms = nil;
__block XPCDaemonClient* daemonComms = nil;
//size
CGSize qrcSize = {0};
@@ -193,7 +212,7 @@
//init daemon comms
// will connect, etc.
daemonComms = [[DaemonComms alloc] init];
daemonComms = [[XPCDaemonClient alloc] init];
//call into daemon/framework
// this will block until phone linking/registration is complete
+2 -5
View File
@@ -24,11 +24,8 @@ int main(int argc, const char * argv[])
//dbg msg
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"STARTED: config/prefs app (args: %@)", [[NSProcessInfo processInfo] arguments]]);
//init crash reporting client
SentryClient.sharedClient = [[SentryClient alloc] initWithDsn:CRASH_REPORTING_URL didFailWithError:nil];
//start crash handler
[SentryClient.sharedClient startCrashHandlerWithError:nil];
//init crash reporting
initCrashReporting();
//already running?
if(YES == isAppRunning([[NSBundle mainBundle] bundleIdentifier]))
+5 -1
View File
@@ -1 +1,5 @@
Lance Gaines, Ash Morgan, Jeff Golden, Nando Mendonca, Khalil Sehnaoui, Gamer_Bot
Patrons:
Halo Privacy, Ash Morgan, Jesse Daguanno, Beau Galbraith, Nando Mendonca, Khalil Sehnaoui, Jeff Golden, Geoffrey Weber, Randy Wong, Gamer_Bot
Friends of Objective-See:
Digita Security, Malwarebytes, Don MacAskill
+16 -25
View File
@@ -43,30 +43,15 @@
//iOS companion app URL
#define IOS_APP_URL @"https://itunes.apple.com/us/app/do-not-disturb-companion/id1345055731?mt=8"
//action to install
// also button title
#define ACTION_INSTALL @"Install"
//button title: upgrade
#define ACTION_UPGRADE @"Upgrade"
//action to uninstall
// also button title
#define ACTION_UNINSTALL @"Uninstall"
//button title
// close
//button title: close
#define ACTION_CLOSE @"Close"
//button title
// next
//button title: next
#define ACTION_NEXT @"Next »"
//button title
// no
#define ACTION_NO @"No"
//button title
// yes
#define ACTION_YES @"Yes!"
//frame shift
// for status msg to avoid activity indicator
#define FRAME_SHIFT 45
@@ -80,6 +65,9 @@
//flag to install
#define ACTION_INSTALL_FLAG 1
//next
#define ACTION_NEXT_FLAG 2
//flag for partial uninstall
// leave preferences file, etc.
#define UNINSTALL_PARTIAL 0
@@ -123,6 +111,9 @@
//daemon mach name
#define DAEMON_MACH_SERVICE @"com.objective-see.dndDaemon"
//user (login item) mach name
#define USER_MACH_SERVICE @"com.objective-see.dndUser"
//product url
#define PRODUCT_URL @"https://objective-see.com/products/dnd.html"
@@ -144,12 +135,6 @@
//product version url
#define PRODUCT_VERSIONS_URL @"https://objective-see.com/products.json"
//flag to uninstall
#define ACTION_UNINSTALL_FLAG 0
//flag to install
#define ACTION_INSTALL_FLAG 1
//login item name
#define LOGIN_ITEM_NAME @"Do Not Disturb Helper"
@@ -291,8 +276,14 @@
//dismiss event notification
#define DISMISS_NOTIFICATION @"com.objective-see.dnd.dismissNotification"
//new user/client notification
#define USER_NOTIFICATION @"com.objective-see.dnd.userNotification"
//monitoring timeout
#define MONITORING_TIMEOUT 60*3
//unknown user
#define USER_UNKNOWN @"unknown"
#endif
+7 -2
View File
@@ -41,8 +41,13 @@
//super
[super windowDidLoad];
//make white
[self.window setBackgroundColor: NSColor.whiteColor];
//not in mojave dark mode?
// make window color white
if(YES != isDarkMode())
{
//make white
self.window.backgroundColor = NSColor.whiteColor;
}
//when supported
// indicate title bar is transparent (too)
+19 -5
View File
@@ -10,6 +10,9 @@
#ifndef Utilities_h
#define Utilities_h
@import Sentry;
@import AVFoundation;
#import <AppKit/AppKit.h>
#import <IOKit/IOKitLib.h>
#import <IOKit/pwr_mgt/IOPM.h>
@@ -17,7 +20,8 @@
#import <SystemConfiguration/SystemConfiguration.h>
//enum of lid states
typedef NS_ENUM(int, LidState) {
typedef NS_ENUM(int, LidState)
{
stateUnavailable = -1,
stateOpen = 0,
stateClosed = 1
@@ -25,14 +29,17 @@ typedef NS_ENUM(int, LidState) {
/* FUNCTIONS */
//init crash reporting
void initCrashReporting(void);
//loads a framework
// note: assumes it is in 'Framework' dir
NSBundle* loadFramework(NSString* name);
//get app's version
// extracted from Info.plist
NSString* getAppVersion(void);
//get OS version
// note: this uses macOS 10.10+ methods
NSOperatingSystemVersion getOSVersion(void);
//get path to (main) app
// login item is in app bundle, so parse up to get main app
NSString* getMainAppPath(void);
@@ -84,4 +91,11 @@ BOOL hasTouchID(void);
//get current console user
NSString* currentConsoleUser(SCDynamicStoreRef store);
//macOS Mojave+
// gotta request camera access
void requestCameraAccess(void);
//check if (true) dark mode
BOOL isDarkMode(void);
#endif
+158 -8
View File
@@ -23,6 +23,101 @@
#import <LocalAuthentication/LocalAuthentication.h>
#import <SystemConfiguration/SystemConfiguration.h>
//init crash reporting
void initCrashReporting()
{
//sentry
NSBundle *sentry = nil;
//error
NSError* error = nil;
//class
Class SentryClient = nil;
//load senty
sentry = loadFramework(@"Sentry.framework");
if(nil == sentry)
{
//err msg
logMsg(LOG_ERR, @"failed to load 'Sentry' framework");
//bail
goto bail;
}
//get client class
SentryClient = NSClassFromString(@"SentryClient");
if(nil == SentryClient)
{
//bail
goto bail;
}
//set shared client
[SentryClient setSharedClient:[[SentryClient alloc] initWithDsn:CRASH_REPORTING_URL didFailWithError:&error]];
if(nil != error)
{
//log error
logMsg(LOG_ERR, [NSString stringWithFormat:@"initializing 'Sentry' failed with %@", error]);
//bail
goto bail;
}
//start crash handler
[[SentryClient sharedClient] startCrashHandlerWithError:&error];
if(nil != error)
{
//log error
logMsg(LOG_ERR, [NSString stringWithFormat:@"starting 'Sentry' crash handler failed with %@", error]);
//bail
goto bail;
}
bail:
return;
}
//loads a framework
// note: assumes it is in 'Framework' dir
NSBundle* loadFramework(NSString* name)
{
//handle
NSBundle* framework = nil;
//framework path
NSString* path = nil;
//init path
path = [NSString stringWithFormat:@"%@/../Frameworks/%@", [NSProcessInfo.processInfo.arguments[0] stringByDeletingLastPathComponent], name];
//standardize path
path = [path stringByStandardizingPath];
//init framework (bundle)
framework = [NSBundle bundleWithPath:path];
if(NULL == framework)
{
//bail
goto bail;
}
//load framework
if(YES != [framework loadAndReturnError:nil])
{
//bail
goto bail;
}
bail:
return framework;
}
//get app's version
// extracted from Info.plist
NSString* getAppVersion()
@@ -31,13 +126,6 @@ NSString* getAppVersion()
return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
}
//get OS version
// note: this uses macOS 10.10+ methods
NSOperatingSystemVersion getOSVersion()
{
return [[NSProcessInfo processInfo] operatingSystemVersion];
}
//get path to (main) app
// login item is in app bundle, so parse up to get main app
NSString* getMainAppPath()
@@ -929,9 +1017,71 @@ NSString* currentConsoleUser(SCDynamicStoreRef store)
goto bail;
}
bail:
return consoleUser;
}
//macOS Mojave+ gotta request camera access
// note, we check first, to see if request was already made
void requestCameraAccess()
{
//on macOS 10.14+
// trigger request for camera access
if(@available(macOS 10.14, *))
{
//auth status
AVAuthorizationStatus authStatus = AVAuthorizationStatusNotDetermined;
//get current status
authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
//already requested?
if(authStatus != AVAuthorizationStatusNotDetermined)
{
//bail
goto bail;
}
//request
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted)
{
//dbg msg
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"user response for camera access: %d", granted]);
}];
}
bail:
return;
}
//check if (true) dark mode
BOOL isDarkMode()
{
//flag
BOOL darkMode = NO;
//not mojave?
// bail, since not true dark mode
if(YES != [[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){10, 14, 0}])
{
//bail
goto bail;
}
//not dark mode?
if(YES != [[[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"] isEqualToString:@"Dark"])
{
//bail
goto bail;
}
//ok, mojave dark mode it is!
darkMode = YES;
bail:
return darkMode;
}
+47
View File
@@ -0,0 +1,47 @@
//
// file: XPC.h
// project: DND (shared)
// description: xpc protocols, ivars, etc,
//
// created by Patrick Wardle
// copyright (c) 2018 Objective-See. All rights reserved.
//
#ifndef XPC_h
#define XPC_h
//protocol
// methods that deamon exports
@protocol XPC_DAEMON
@end
//protocol
// methods that user exports
@protocol XPC_USER
- (void) updateProgress: (double) currentProgress;
- (void) finished;
@end
@interface XPCListener : NSObject<NSXPCListenerDelegate>
/* PROPERTIES */
//XPC listener
@property(retain, nonatomic)NSXPCListener* listener;
/* METHODS */
//setup XPC listener
-(BOOL)initListener;
//automatically invoked when new client (attempts) to connect
-(BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection;
@end
#endif /* XPC_h */
@@ -1,7 +1,7 @@
//
// file: DaemonComms.h
// file: XPCDaemonClient
// project: DND (shared)
// description: interface to talk to daemon (header)
// description: talk to the daemon, via XPC (header)
//
// created by Patrick Wardle
// copyright (c) 2018 Objective-See. All rights reserved.
@@ -9,16 +9,20 @@
@import Foundation;
#import "UserCommsInterface.h"
#import "XPCDaemonProto.h"
@interface DaemonComms : NSObject
@interface XPCDaemonClient : NSObject
{
}
//remote deamon proxy object
@property(nonatomic, retain) id <UserProtocol> daemon;
/* PROPERTIES */
//xpc connection
@property (atomic, strong, readwrite) NSXPCConnection* xpcServiceConnection;
/* METHODS */
//ask daemon for QRC info
// name, uuid, key, key size, etc...
-(void)qrcRequest:(void (^)(NSData* qrcInfo))reply;
@@ -34,17 +38,4 @@
//update (save) preferences
-(void)updatePreferences:(NSDictionary*)preferences;
//ask for alert
-(void)alertRequest:(void (^)(NSDictionary* alert))reply;
//send alert response back to the daemon
// for now, it's just an 'ack' that it was recieved/shown
-(void)alertResponse;
//ask (and then block) for an alert dismiss
-(void)alertDismiss:(void (^)(NSDictionary* alert))reply;
//close/cleanup connection
-(void)close;
@end
@@ -1,7 +1,7 @@
//
// file: DaemonComms.m
// file: XPCDaemonClient.m
// project: DND (shared)
// description: interface to talk to daemon
// description: talk to the daemon, via XPC (header)
//
// created by Patrick Wardle
// copyright (c) 2018 Objective-See. All rights reserved.
@@ -9,11 +9,15 @@
#import "Consts.h"
#import "Logging.h"
#import "DaemonComms.h"
#import "XPCUserProto.h"
#import "XPCDaemonClient.h"
@implementation DaemonComms
#ifdef XPC_USER
#import "XPCUser.h"
#endif
@implementation XPCDaemonClient
@synthesize daemon;
@synthesize xpcServiceConnection;
//init
@@ -28,7 +32,18 @@
xpcServiceConnection = [[NSXPCConnection alloc] initWithMachServiceName:DAEMON_MACH_SERVICE options:0];
//set remote object interface
self.xpcServiceConnection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(UserProtocol)];
self.xpcServiceConnection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(XPCDaemonProtocol)];
#ifdef XPC_USER
//set exported object interface (protocol)
self.xpcServiceConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(XPCUserProtocol)];
//set exported object
// this will allow daemon to invoke user methods!
self.xpcServiceConnection.exportedObject = [[XPCUser alloc] init];
#endif
//resume
[self.xpcServiceConnection resume];
@@ -144,76 +159,4 @@
return;
}
//ask (and then block) for an alert
-(void)alertRequest:(void (^)(NSDictionary* alert))reply
{
//dbg msg
logMsg(LOG_DEBUG, @"sending request, via XPC, for alert");
//request alert
[[self.xpcServiceConnection remoteObjectProxyWithErrorHandler:^(NSError * proxyError)
{
//err msg
logMsg(LOG_ERR, [NSString stringWithFormat:@"failed to execute 'alertRequest' method on launch daemon (error: %@)", proxyError]);
}] alertRequest:^(NSDictionary* alert)
{
//respond with alert
reply(alert);
}];
return;
}
//send alert response back to the daemon
// for now, it's just an 'ack' that it was recieved/shown
-(void)alertResponse
{
//dbg msg
logMsg(LOG_DEBUG, @"sending request, via XPC, for alert response");
//respond to alert
[[self.xpcServiceConnection remoteObjectProxyWithErrorHandler:^(NSError * proxyError)
{
//err msg
logMsg(LOG_ERR, [NSString stringWithFormat:@"failed to execute 'alertResponse' method on launch daemon (error: %@)", proxyError]);
}] alertResponse];
return;
}
//ask (and then block) for an alert dismiss
-(void)alertDismiss:(void (^)(NSDictionary* alert))reply
{
//dbg msg
logMsg(LOG_DEBUG, @"sending request, via XPC, for alert dismiss events");
//request alert
[[self.xpcServiceConnection remoteObjectProxyWithErrorHandler:^(NSError * proxyError)
{
//err msg
logMsg(LOG_ERR, [NSString stringWithFormat:@"failed to execute 'alertDismiss' method on launch daemon (error: %@)", proxyError]);
}] alertDismiss:^(NSDictionary* alert)
{
//respond with alert
reply(alert);
}];
return;
}
//close/cleanup connection
-(void)close
{
//invalidate
[self.xpcServiceConnection invalidate];
//unset
self.xpcServiceConnection = nil;
return;
}
@end
@@ -1,18 +1,15 @@
//
// file: UserCommsInterface.h
// file: XPCDaemonProtocol.h
// project: DND (shared)
// description: protocol for talking to the daemon
// description: methods exported by the daemon
//
// created by Patrick Wardle
// copyright (c) 2018 Objective-See. All rights reserved.
//
#ifndef UserCommsInterface_h
#define UserCommsInterface_h
@import Foundation;
@protocol UserProtocol
@protocol XPCDaemonProtocol
//process qrc request from client
-(void)qrcRequest:(void (^)(NSData *))reply;
@@ -27,15 +24,5 @@
//update preferences
-(void)updatePreferences:(NSDictionary*)preferences;
//ask (and block) alert request from daemon
-(void)alertRequest:(void (^)(NSDictionary* alert))reply;
//process alert response from client
-(void)alertResponse;
//ask (and block) for alert dismiss msg from daemon
-(void)alertDismiss:(void (^)(NSDictionary* alert))reply;
@end
#endif
+25
View File
@@ -0,0 +1,25 @@
//
// file: XPCUserProtocol
// project: DND (shared)
// description: protocol for talking to the user (header)
//
// created by Patrick Wardle
// copyright (c) 2018 Objective-See. All rights reserved.
//
@import Foundation;
@protocol XPCUserProtocol
//show an alert
// returns with rep
-(void)alertShow:(NSDictionary*)alert;
//dismiss alert(s)
-(void)alertDismiss;
//take a picture
-(void)captureImage:(void (^)(NSData *))reply;
@end