Post

Replies

Boosts

Views

Activity

How to publish an XPC Service in a global daemon that employs EndpointSecurity framework?
I have a global daemon managed by launchd, whose .plist is installed in /Library/LaunchDaemons). To be correctly entitled and code-signed so it can communicate with EndpointSecurity framework, its executable resides in a normal Mac App bundle (main() will run as minimal UI when launched from UI, and as a daemon when launched by launchd). This means that the ProgramArguments.0 in its .plist looks something like /Library/PrivilegedHelperTools/MyDaemonApp.app/Contents/MacOS/MyDaemonApp Now I need this daemon to publish an XPC Service (with few control commands) so that other components of our system (UI app, a user-context launchd-daemon and another launchd global-daemon) will be able to connect to The XPC Service and control it via the published protocol. I read some answers here, and also found a working order sample code that does just this here - https://github.com/jdspoone/SampleOSXLaunchDaemon But when I apply its content to my global daemon, word for word - it doesn't work - meaning, clients cannot create a connection to The XPC Service. The daemon is up and running, and functional. its .plist is quite simple and looks like this: <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.mycompany.itm.service</string> <key>KeepAlive</key> <true/> <key>RunAtLoad</key> <true/> <key>MachServices</key> <dict> <key>com.mycompany.itm.service</key> <true/> </dict> <key>ProgramArguments</key> <array> <string>/Library/PrivilegedHelperTools/IMyDaemonApp.app/Contents/MacOS/MyDaemonApp</string> <string>-monitor</string> <string>-protectDeviceProtocol</string> <string>USB</string> </array> </dict> </plist> It creates and starts an XPC listener in MYXPCListener.h like thus: #import <Foundation/Foundation.h> #import "MYXPCProtocol.h" NS_ASSUME_NONNULL_BEGIN @interface OITPreventionXPCService : NSObject (instancetype) init; (void) start; /* Begin listening for incoming XPC connections */ (void) stop; /* Stop listening for incoming XPC connections */ @end NS_ASSUME_NONNULL_END and the implementation is: /* AppDelegate.m */ @interface MYXPCService () <NSXPCListenerDelegate, OITPreventionXPCProtocol> @property (nonatomic, strong, readwrite) NSXPCListener *listener; @property (nonatomic, readwrite) BOOL started; @end @implementation OITPreventionXPCService (instancetype) init {     if ((self = [super init]) != nil) {         _listener = [[NSXPCListener alloc] initWithMachServiceName:@"com.mycompany.itm.service"];         _listener.delegate = self;         if (_listener == nil) {             os_log_error(myLog, "XPCListener failed to initialize");         }         _started = NO;     }     return self; } (void) start {     assert(_started == NO);     [_listener resume];     os_log_info(myLog, "XPCListener resumed");     _started = YES; } (void) stop {     assert(_started == YES);     [_listener suspend];     os_log_info(myLog, "XPCListener suspended");     _started = NO; } /* NSXPCListenerDelegate implementation */ (BOOL) listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection {     os_log_info(myLog, "Prevention XPCListener is bequsted a new connection");     assert(listener == _listener);     assert(newConnection != nil);     newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(MYXPCProtocol)];     newConnection.exportedObject = self; &#9;&#9;[newConnection resume];     return YES; } /* Further down this implementation, I have implementations to all the methods in MYXPCProtocol. */ @end Now the client code (and I tried EVERY kind of client, signed unsigned, daemon, UI, root privileged, or user-scoped - whatever). For example, in the AppDelegate of a UI app: #import "AppDelegate.h" #import "MYXPCProtocol.h" @interface AppDelegate () @property (strong) IBOutlet NSWindow *window; @property (nonatomic, strong, readwrite) NSXPCConnection *connection; /* lazy initialized */ @end @implementation AppDelegate (NSXPCConnection *) connection {     if (_connection == nil) {         _connection = [[NSXPCConnection alloc] initWithMachServiceName:daemonLabel options:NSXPCConnectionPrivileged];         _connection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(MYXPCProtocol)];         _connection.invalidationHandler =  ^{             self->_connection = nil;             NSLog(@"connection has been invalidated");         };         [_connection resume];         /* New connections always start suspended */     }     return _connection; } (IBAction) getServiceStatus:(id)sender {     [self.connection.remoteObjectProxy getStatus:^(NSString * _Nonnull status) {         NSLog(@"MY XPC Service status is: %@", status);     }]; } @end but no matter what I do - I always get the "connection invalidated". The sample launchDaemon that works - is not code-signed at all!!! but mine, which is both signed and checking of which yields $ spctl --assess --verbose IMyDaemonApp.app IMyDaemonApp.app: accepted source=Notarized Developer ID   I'm at a loss - and would like to get any advice, or any helpful documentation (I've been reading TN2083, and man launchctl and man launchd.plist and many other pages - to no avail. There seems to be no real "programming guide" for XPC and no reasonable sample code on Apple developer site to fit my needs. Last - this is MacOS 10.15.7, and latest Xcode 12.3
7
0
2.5k
Jan ’21
Is there a good way to translate timespec into NSDate
My new EndpointSecurity client code receives event messages of type esmessaget. These contain 3 time values. struct timespec time; uint64_t mach_time; uint64_t deadline; To interpret the deadline I refer to the mach_time. However, when I wish to log/formet/otherwise-consider the "wall time" where the event was created - I need to translate the timespec into NSDate (hmm... NSTimeInterval?) and I fail to find any documentation or hint about the right way to do so. What I tried so far looks like this: NSDate * timestamp = [NSDate dateWithTimeIntervalSince1970:(double)(message-&gt;time.tv_sec) + (double)(message-&gt;time.tv_sec) / 1E9 ]; which at least mathematically seems reasonable, but I'm not sure this is the right answer, and I don't know anything about the behaviour of timespec, its origin and accuracy, and whether or not it is consistent. Can anyone shed a little light on the relation between these two time formats? Thanks!
2
0
2.1k
Dec ’20
How to setup AVFoundation based view to display CoreImage filtered Live video from Camera?
Hi. I watched the short "Optimize the Core Image pipeline for your video app" session several times, all excited, because it is at least 5 years that CI code-samples for MacOS are nonfunctional, and failed to make them work. My application (for Microscopy) needs to apply (mostly built-in) CI filters onto live video coming from an external IIDC/DCam camera. My current code is AVFoundation based, but I never managed to apply filters onto the video, and as I said Documentation and code-samples deteriorated to the point of no use. This beautiful session shows how to create an AVPlayerView and set it up for displaying CI-filtered video - but only for an "asset" (meaning - dead video from disk). How to do it for live "Preview" video? Also, is it too much to ask for a simple working order modern MacOS sample of CoreImage use? Thanks! (BTW I would be glad to move to MTKView instead- have I known how to tie the camera input to it. Again - Docs are unusable, and no reasonable sample exists for MacOS. Not even for the simplest of tasks.
3
0
1.8k
Jul ’20
Can my User-Agent know (be notified) of Configuration profile changes?
My agent/service relies on Accessibility APIs. Being installed by IT on all corporate Macs, it receives its permission to use these APIs via a configuration profile installed on the Mac, and not via the System-Preferences Security &amp; Privacy panel (Privacy tab, Accessibility item). Problem is - if that profile is removed, or changed to remove this permission - The agent currently has no way to know it, and will hang on the next call to some AX API. our code calls  @result Returns TRUE if the current process is a trusted accessibility client, FALSE if it is not.  */ extern Boolean AXIsProcessTrustedWithOptions (CFDictionaryRef __nullable options) CF_AVAILABLE_MAC(10_9); before using other AX APIs, but sadly - the method returns true even when accessibility has been denied by removing the profile. By contrast - if If user manually un-checks the Accessibility for this agent in the System-Preferences panel - the function returns false immediately. If after removing the profile, I kill my agent (launchd then relaunches it) - then calling AXIsProcessTrustedWithOptions returns false as expected. This seems to be a bug of some kind or incomplete behaviour, but I need a workaround as soon as possible. My first "wish" would be to be able to register for and receive some system-wide NSNotification about "configuration profile changes", at which time, I could decide to exit my agent, and relaunch with accessibility permissions synchronised. Or is there any AX internal notification I could register for? haven't found any. Any clue would be greatly appreciated.
1
0
1.1k
Jul ’20