Skip to content

Instantly share code, notes, and snippets.

@chrispaynter
Last active February 17, 2021 19:45
Show Gist options
  • Save chrispaynter/efc605c0b0ae8f2859f440ddfd3e4b37 to your computer and use it in GitHub Desktop.
Save chrispaynter/efc605c0b0ae8f2859f440ddfd3e4b37 to your computer and use it in GitHub Desktop.
Medium - Daemons and Agents - main.swift
<?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>Label</key>
<string>IOServicesTestLaunchAgent</string>
<key>Disabled</key>
<false/>
<key>KeepAlive</key>
<dict>
<key>SuccessfulExit</key>
<false/>
</dict>
<key>Program</key>
<string>/Users/chris/Library/Developer/Xcode/DerivedData/IOServicesTest-fmrplonbcfeolhcpagogehzpkqzz/Build/Products/Debug/IOServicesTest</string>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
<?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>Label</key>
<string>IOServicesTestLaunchDaemon</string>
<key>Disabled</key>
<false/>
<key>KeepAlive</key>
<true />
<key>Program</key>
<string>/Users/chris/Library/Developer/Xcode/DerivedData/IOServicesTest-fmrplonbcfeolhcpagogehzpkqzz/Build/Products/Debug/IOServicesTest</string>
</dict>
</plist>
import Foundation
import IOKit.hid
import OSLog
func tryOpenHidDevice(options:Int) -> Bool{
let deviceMatch = IOServiceMatching(kIOHIDDeviceKey)
let match = IOServiceGetMatchingService(kIOMasterPortDefault, deviceMatch);
let deviceRef = IOHIDDeviceCreate(kCFAllocatorDefault, match);
let result = IOHIDDeviceOpen(deviceRef!, IOOptionBits(options));
if(result == kIOReturnSuccess) {
os_log("Device opened successfully")
IOHIDDeviceClose(deviceRef!, IOOptionBits(kIOHIDOptionsTypeNone))
return true;
} else {
os_log("Device opened failed")
return false;
}
}
if(getuid() == 0) {
os_log("Running as daemon");
// Open will fail if the agent hasn't prompted the
// user to give access to input monitoring.
if(tryOpenHidDevice(options: kIOHIDOptionsTypeSeizeDevice)) {
os_log("Daemon now has access to seize HID devices");
// You'd now let trigger the actual daemon code to run, now
// that it has the HID access it needs.
} else {
os_log("Daemon still waiting for HID open access");
// Not much we can do but try again soon.
// Quit the agent, let launchd start it again soon.
exit(1)
}
} else {
os_log("Running as agent");
// We run this to trigger the TCC prompt
if(tryOpenHidDevice(options: kIOHIDOptionsTypeNone)) {
// Try again soon - you'd use a timer of some sort here.
} else {
// It worked. Let the agent exit, no longer needed.
exit(0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment