143 lines
3.3 KiB
Objective-C
143 lines
3.3 KiB
Objective-C
//
|
|
// main.m
|
|
// OverSightXPC
|
|
//
|
|
// Created by Patrick Wardle on 8/16/16.
|
|
// Copyright (c) 2016 Objective-See. All rights reserved.
|
|
//
|
|
|
|
#import "main.h"
|
|
#import "Logging.h"
|
|
|
|
/* GLOBALS */
|
|
|
|
//client/requestor pid
|
|
pid_t clientPID = 0;
|
|
|
|
//implementation for 'extension' to NSXPCConnection
|
|
// ->allows us to access the 'private' auditToken iVar
|
|
@implementation ExtendedNSXPCConnection
|
|
|
|
//private iVar
|
|
@synthesize auditToken;
|
|
|
|
@end
|
|
|
|
@implementation ServiceDelegate
|
|
|
|
//automatically invoked
|
|
// allows NSXPCListener to configure/accept/resume a new incoming NSXPCConnection
|
|
// note: we only allow binaries signed by Objective-See to connect & talk to this!
|
|
-(BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection
|
|
{
|
|
//flag
|
|
BOOL shouldAccept = NO;
|
|
|
|
//task ref
|
|
SecTaskRef taskRef = 0;
|
|
|
|
//signing req string
|
|
NSString *requirementString = nil;
|
|
|
|
//dbg msg
|
|
#ifdef DEBUG
|
|
logMsg(LOG_DEBUG, @"new client connection");
|
|
#endif
|
|
|
|
//init signing req string
|
|
requirementString = [NSString stringWithFormat:@"anchor trusted and certificate leaf [subject.CN] = \"%@\"", SIGNING_AUTH];
|
|
|
|
//step 1: create task ref
|
|
// ->uses NSXPCConnection's (private) 'auditToken' iVar
|
|
taskRef = SecTaskCreateWithAuditToken(NULL, ((ExtendedNSXPCConnection*)newConnection).auditToken);
|
|
if(NULL == taskRef)
|
|
{
|
|
//bail
|
|
goto bail;
|
|
}
|
|
|
|
//step 2: validate
|
|
// ->check that client is signed with Objective-See's dev cert
|
|
if(0 != SecTaskValidateForRequirement(taskRef, (__bridge CFStringRef)(requirementString)))
|
|
{
|
|
//bail
|
|
goto bail;
|
|
}
|
|
|
|
//set the interface that the exported object implements
|
|
newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(XPCProtocol)];
|
|
|
|
//set object exported by connection
|
|
newConnection.exportedObject = [[OverSightXPC alloc] init];
|
|
|
|
//resume
|
|
[newConnection resume];
|
|
|
|
//grab client/requestor's pid
|
|
clientPID = audit_token_to_pid(((ExtendedNSXPCConnection*)newConnection).auditToken);
|
|
|
|
//happy
|
|
shouldAccept = YES;
|
|
|
|
//dbg msg
|
|
#ifdef DEBUG
|
|
logMsg(LOG_DEBUG, [NSString stringWithFormat:@"accepted new client connection (pid: %d)", clientPID]);
|
|
#endif
|
|
|
|
//bail
|
|
bail:
|
|
|
|
//release task ref object
|
|
if(NULL != taskRef)
|
|
{
|
|
//release
|
|
CFRelease(taskRef);
|
|
|
|
//unset
|
|
taskRef = NULL;
|
|
}
|
|
|
|
return shouldAccept;
|
|
}
|
|
|
|
@end
|
|
|
|
//main entrypoint
|
|
// ->install exception handlers & setup/kickoff listener
|
|
int main(int argc, const char *argv[])
|
|
{
|
|
//ret var
|
|
int status = -1;
|
|
|
|
//service delegate
|
|
ServiceDelegate* delegate = nil;
|
|
|
|
//listener
|
|
NSXPCListener* listener = nil;
|
|
|
|
//first thing...
|
|
// ->install exception handlers!
|
|
installExceptionHandlers();
|
|
|
|
//create the delegate for the service.
|
|
delegate = [[ServiceDelegate alloc] init];
|
|
|
|
//set up the one NSXPCListener for this service
|
|
// ->handles incoming connections
|
|
listener = [NSXPCListener serviceListener];
|
|
|
|
//set delegate
|
|
listener.delegate = delegate;
|
|
|
|
//resuming the listener starts this service
|
|
// ->method does not return
|
|
[listener resume];
|
|
|
|
//happy
|
|
status = 0;
|
|
|
|
bail:
|
|
|
|
return status;
|
|
}
|