Files
BlockBlock/Shared/XPCDaemonClient.m
Patrick Wardle 397699c1d0 switched to universal logging
remove old log file #74
switch to os_log_* APIs
2024-03-19 20:12:11 -10:00

235 lines
6.5 KiB
Objective-C

//
// file: XPCDaemonClient.m
// project: BlockBlock (shared)
// description: talk to daemon via XPC (header)
//
// created by Patrick Wardle
// copyright (c) 2017 Objective-See. All rights reserved.
//
#import "consts.h"
#import "XPCUser.h"
#import "utilities.h"
#import "AppDelegate.h"
#import "XPCUserProto.h"
#import "XPCDaemonClient.h"
/* GLOBALS */
//log handle
extern os_log_t logHandle;
//alert (windows)
extern NSMutableDictionary* alerts;
@implementation XPCDaemonClient
@synthesize daemon;
//init
// create XPC connection & set remote obj interface
-(id)init
{
//super
self = [super init];
if(nil != self)
{
//alloc/init
daemon = [[NSXPCConnection alloc] initWithMachServiceName:DAEMON_MACH_SERVICE options:0];
//set remote object interface
self.daemon.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(XPCDaemonProtocol)];
//set exported object interface (protocol)
self.daemon.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(XPCUserProtocol)];
//set exported object
// this will allow daemon to invoke user methods!
self.daemon.exportedObject = [[XPCUser alloc] init];
//resume
[self.daemon resume];
}
return self;
}
//get preferences
// note: synchronous, will block until daemon responds
-(NSDictionary*)getPreferences
{
//preferences
__block NSDictionary* preferences = nil;
//dbg msg
os_log_debug(logHandle, "invoking daemon XPC method, '%s'", __PRETTY_FUNCTION__);
//request preferences
[[self.daemon synchronousRemoteObjectProxyWithErrorHandler:^(NSError * proxyError)
{
//err msg
os_log_error(logHandle, "ERROR: failed to execute daemon XPC method '%s' (error: %{public}@)", __PRETTY_FUNCTION__, proxyError);
}] getPreferences:^(NSDictionary* preferencesFromDaemon)
{
//dbg msg
os_log_debug(logHandle, "got preferences: %{public}@", preferencesFromDaemon);
//save
preferences = preferencesFromDaemon;
}];
return preferences;
}
//update (save) preferences
-(void)updatePreferences:(NSDictionary*)preferences
{
//dbg msg
os_log_debug(logHandle, "invoking daemon XPC method, '%s'", __PRETTY_FUNCTION__);
//update prefs
[[self.daemon remoteObjectProxyWithErrorHandler:^(NSError * proxyError)
{
//err msg
os_log_error(logHandle, "ERROR: failed to execute daemon XPC method '%s' (error: %{public}@)", __PRETTY_FUNCTION__, proxyError);
}] updatePreferences:preferences];
return;
}
//get rules
// note: synchronous, will block until daemon responds
-(NSArray*)getRules
{
//unarchived rules
__block NSDictionary* unarchivedRules = nil;
//rules
__block NSMutableArray* rules = nil;
//error
__block NSError* error = nil;
//dbg msg
os_log_debug(logHandle, "invoking daemon XPC method, '%s'", __PRETTY_FUNCTION__);
//make XPC request to get rules
[[self.daemon synchronousRemoteObjectProxyWithErrorHandler:^(NSError * proxyError)
{
//err msg
os_log_error(logHandle, "ERROR: failed to execute daemon XPC method '%s' (error: %{public}@)", __PRETTY_FUNCTION__, proxyError);
}] getRules:^(NSData* archivedRules)
{
//unarchive
unarchivedRules = [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet setWithArray: @[[NSMutableDictionary class], [NSMutableArray class], [NSString class], [NSNumber class], [Rule class]]]
fromData:archivedRules error:&error];
if(nil != error)
{
//err msg
os_log_error(logHandle, "ERROR: failed to unarchive rules: %{public}@", error);
}
//init
rules = [NSMutableArray array];
//convert into array (for UI)
for(NSString* key in unarchivedRules)
{
//add (each) processes rules
[rules addObjectsFromArray:unarchivedRules[key][KEY_RULES]];
}
}];
return rules;
}
//delete rule
-(NSArray*)deleteRule:(Rule*)rule
{
//unarchived rules
__block NSDictionary* unarchivedRules = nil;
//rules
__block NSMutableArray* rules = nil;
//error
__block NSError* error = nil;
//dbg msg
os_log_debug(logHandle, "invoking daemon XPC method, '%s'", __PRETTY_FUNCTION__);
//delete rule
[[self.daemon synchronousRemoteObjectProxyWithErrorHandler:^(NSError * proxyError)
{
//err msg
os_log_error(logHandle, "ERROR: failed to execute daemon XPC method '%s' (error: %{public}@)", __PRETTY_FUNCTION__, proxyError);
}] deleteRule:rule reply:^(NSData* archivedRules)
{
//unarchive
unarchivedRules = [NSKeyedUnarchiver unarchivedObjectOfClasses:[NSSet setWithArray: @[[NSMutableDictionary class], [NSMutableArray class], [NSString class], [NSNumber class], [Rule class]]]
fromData:archivedRules error:&error];
if(nil != error)
{
//err msg
os_log_error(logHandle, "ERROR: failed to unarchive rules: %{public}@", error);
}
//init
rules = [NSMutableArray array];
//convert into array (for UI)
for(NSString* key in unarchivedRules)
{
//add (each) processes rules
[rules addObjectsFromArray:unarchivedRules[key][KEY_RULES]];
}
//dbg msg
os_log_debug(logHandle, "received updated rules %{public}@", rules);
}];
return rules;
}
//send alert response back to the deamon
-(void)alertReply:(NSDictionary*)alert
{
//pool
@autoreleasepool {
//dbg msg
os_log_debug(logHandle, "invoking daemon XPC method, '%s'", __PRETTY_FUNCTION__);
//respond to alert
[[self.daemon remoteObjectProxyWithErrorHandler:^(NSError * proxyError)
{
//err msg
os_log_error(logHandle, "ERROR: failed to execute daemon XPC method '%s' (error: %{public}@)", __PRETTY_FUNCTION__, proxyError);
}] alertReply:alert];
//sync to remove alert (window)
@synchronized(alerts)
{
//remove
alerts[alert[ALERT_UUID]] = nil;
}
//set app's background/foreground state
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) setActivationPolicy];
} //pool
return;
}
@end