我可以使用守护进程打开 DriverKit 用户客户端吗?
Can I open a DriverKit user client with a daemon?
我正在 Driver Kit 中构建虚拟 HID 设备。
我想通过守护进程与虚拟设备驱动程序通信,因为守护进程对于生成从驱动程序发送的 HID 事件是必需的。
我通过守护进程匹配我的驱动程序服务,但是当我尝试打开该服务时,我得到 -536870174
, 表示 kIOReturnNotPermitted
.
据我了解,设备驱动程序用户客户端只能通过已获得 Apple com.apple.developer.driverkit.userclient-access
授权的应用程序打开。
那么,我的问题是:
用守护进程打开Driver Kit中设备驱动程序的用户客户端完全不可能吗?
我唯一的选择是拥有一个具有 com.apple.developer.driverkit.userclient-access
权利的中间应用程序,它可以充当守护进程和驱动程序之间的代理吗?
所以它会是这样的:
Daemon <---xpc connection--> Intermediate App <--- user client ---> 虚拟HID设备
编辑:
要添加以下关于 运行 应用程序作为守护程序的 Phil 的回答,有一些 Apple written guidance here.
简而言之:没有必要耗费太多精力。守护进程可以拥有权利。
official solution 是让你的守护进程成为一个应用程序,从 OS 的角度来看。本质上,将您的守护程序构建为应用程序包,只是不要将其称为 .app。您的 launchd plist 可以指向嵌入式可执行文件,它将继承周围包的权利。
非正式地,我也成功地将 Info.plist 直接嵌入到守护进程的二进制文件中,而没有周围的包目录。这通常用于与 SMJobBless()
and is described in a bunch of places including here 一起使用的特权帮助工具。本质上,在 Xcode 中启用“Create Info.plist Section in Binary”构建设置,或者在使用其他构建系统时将 -sectcreate __TEXT __info_plist path/to/Info.plist
添加到链接器标志。 但是,我最终没有发布这个(最终不需要它)所以我只在禁用 SIP 的情况下测试过它。所以我目前不能确定它在使用适当的配置文件签名时是否会起作用。
这两种方法都允许您通过在 Info.plist 中指定它来为二进制文件提供一个应用程序包 ID,这样您还可以在代码签名期间包含一个权利文件。由于 com.apple.developer.driverkit.userclient-access
不是来自 com.apple.security.*
命名空间的“开放”权利之一,您还需要一个包含它的配置文件,否则 OS 不会接受 SIP已启用。
如果您像上述apple resource那样采用运行一个应用程序作为守护进程的路径,则以下代码是objective-c的swift变体爱斯基摩人发帖了。
import Foundation
import Security
import OSLog;
var me:SecCode? = nil;
let kSecCSDefaultFlags:SecCSFlags = SecCSFlags(rawValue: SecCSFlags.RawValue(0))
var err = SecCodeCopySelf(kSecCSDefaultFlags, &me);
assert(err == errSecSuccess)
var infoCF:CFDictionary? = nil;
var staticMe:SecStaticCode? = nil;
err = SecCodeCopyStaticCode(me!, kSecCSDefaultFlags, &staticMe)
assert(err == errSecSuccess);
err = SecCodeCopySigningInformation(staticMe!, kSecCSDefaultFlags, &infoCF);
assert(err == errSecSuccess);
print(infoCF);
os_log("%{public}s", infoCF.debugDescription);
我正在 Driver Kit 中构建虚拟 HID 设备。
我想通过守护进程与虚拟设备驱动程序通信,因为守护进程对于生成从驱动程序发送的 HID 事件是必需的。
我通过守护进程匹配我的驱动程序服务,但是当我尝试打开该服务时,我得到 -536870174
,kIOReturnNotPermitted
.
据我了解,设备驱动程序用户客户端只能通过已获得 Apple com.apple.developer.driverkit.userclient-access
授权的应用程序打开。
那么,我的问题是:
用守护进程打开Driver Kit中设备驱动程序的用户客户端完全不可能吗?
我唯一的选择是拥有一个具有 com.apple.developer.driverkit.userclient-access
权利的中间应用程序,它可以充当守护进程和驱动程序之间的代理吗?
所以它会是这样的:
Daemon <---xpc connection--> Intermediate App <--- user client ---> 虚拟HID设备
编辑: 要添加以下关于 运行 应用程序作为守护程序的 Phil 的回答,有一些 Apple written guidance here.
简而言之:没有必要耗费太多精力。守护进程可以拥有权利。
official solution 是让你的守护进程成为一个应用程序,从 OS 的角度来看。本质上,将您的守护程序构建为应用程序包,只是不要将其称为 .app。您的 launchd plist 可以指向嵌入式可执行文件,它将继承周围包的权利。
非正式地,我也成功地将 Info.plist 直接嵌入到守护进程的二进制文件中,而没有周围的包目录。这通常用于与 SMJobBless()
and is described in a bunch of places including here 一起使用的特权帮助工具。本质上,在 Xcode 中启用“Create Info.plist Section in Binary”构建设置,或者在使用其他构建系统时将 -sectcreate __TEXT __info_plist path/to/Info.plist
添加到链接器标志。 但是,我最终没有发布这个(最终不需要它)所以我只在禁用 SIP 的情况下测试过它。所以我目前不能确定它在使用适当的配置文件签名时是否会起作用。
这两种方法都允许您通过在 Info.plist 中指定它来为二进制文件提供一个应用程序包 ID,这样您还可以在代码签名期间包含一个权利文件。由于 com.apple.developer.driverkit.userclient-access
不是来自 com.apple.security.*
命名空间的“开放”权利之一,您还需要一个包含它的配置文件,否则 OS 不会接受 SIP已启用。
如果您像上述apple resource那样采用运行一个应用程序作为守护进程的路径,则以下代码是objective-c的swift变体爱斯基摩人发帖了。
import Foundation
import Security
import OSLog;
var me:SecCode? = nil;
let kSecCSDefaultFlags:SecCSFlags = SecCSFlags(rawValue: SecCSFlags.RawValue(0))
var err = SecCodeCopySelf(kSecCSDefaultFlags, &me);
assert(err == errSecSuccess)
var infoCF:CFDictionary? = nil;
var staticMe:SecStaticCode? = nil;
err = SecCodeCopyStaticCode(me!, kSecCSDefaultFlags, &staticMe)
assert(err == errSecSuccess);
err = SecCodeCopySigningInformation(staticMe!, kSecCSDefaultFlags, &infoCF);
assert(err == errSecSuccess);
print(infoCF);
os_log("%{public}s", infoCF.debugDescription);