Skip to content

Instantly share code, notes, and snippets.

@landonf
Last active June 22, 2020 17:08
Show Gist options
  • Save landonf/6413769 to your computer and use it in GitHub Desktop.
Save landonf/6413769 to your computer and use it in GitHub Desktop.
XPC-based privileged helper
- (BOOL)blessHelperWithLabel:(NSString *)label error:(NSError **)error {
BOOL result = NO;
AuthorizationItem authItem = { kSMRightBlessPrivilegedHelper, 0, NULL, 0 };
AuthorizationRights authRights = { 1, &authItem };
AuthorizationFlags flags = kAuthorizationFlagDefaults |
kAuthorizationFlagInteractionAllowed |
kAuthorizationFlagPreAuthorize |
kAuthorizationFlagExtendRights;
AuthorizationRef authRef = NULL;
/* Obtain the right to install privileged helper tools (kSMRightBlessPrivilegedHelper). */
OSStatus status = AuthorizationCreate(&authRights, kAuthorizationEmptyEnvironment, flags, &authRef);
if (status != errAuthorizationSuccess) {
*error = [NSError errorWithDomain: NSOSStatusErrorDomain code: status userInfo: nil];
NSLog(@"Failed to create AuthorizationRef, return code %i", status);
} else {
/* This does all the work of verifying the helper tool against the application
* and vice-versa. Once verification has passed, the embedded launchd.plist
* is extracted and placed in /Library/LaunchDaemons and then loaded. The
* executable is placed in /Library/PrivilegedHelperTools.
*/
CFErrorRef cferr;
result = SMJobBless(kSMDomainSystemLaunchd, (__bridge CFStringRef)label, authRef, &cferr);
if (error != NULL)
*error = CFBridgingRelease(cferr);
}
return result;
}
- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
{
AuthorizationItem authItem = { "coop.plausible.fuz", 0, NULL, 0 };
AuthorizationRights authRights = { 1, &authItem };
AuthorizationFlags flags = kAuthorizationFlagDefaults |
kAuthorizationFlagInteractionAllowed |
kAuthorizationFlagPreAuthorize |
kAuthorizationFlagExtendRights;
AuthorizationRef authRef = NULL;
/* Obtain the right to install privileged helper tools (kSMRightBlessPrivilegedHelper). */
OSStatus status = AuthorizationCreate(&authRights, kAuthorizationEmptyEnvironment, flags, &authRef);
if (status != errAuthorizationSuccess) {
NSLog(@"Failed to create AuthorizationRef, return code %i", status);
}
}
NSError *error = nil;
if (![self blessHelperWithLabel:@"coop.plausible.scuba.bpf-open" error:&error]) {
NSLog(@"Something went wrong! %@", error);
} else {
/* At this point, the job is available. However, this is a very
* simple sample, and there is no IPC infrastructure set up to
* make it launch-on-demand. You would normally achieve this by
* using a Sockets or MachServices dictionary in your launchd.plist.
*/
NSLog(@"Job is available!");
}
xpc_connection_t c = xpc_connection_create_mach_service("coop.plausible.scuba.bpf-open", dispatch_get_main_queue(), XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
xpc_connection_set_event_handler(c, ^(xpc_object_t object) {
NSLog(@"Got event: %s", xpc_copy_description(object));
});
xpc_connection_resume(c);
xpc_object_t hello = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_string(hello, "hello", "hello, world");
xpc_connection_send_message(c, hello);
xpc_release(hello);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment