我可以使用守护程序打开 DriverKit 用户客户端吗?

问题描述

我正在 Driver Kit 中构建虚拟 HID 设备。

我想从守护进程与虚拟设备驱动程序通信,因为守护进程是生成将从驱动程序发送的 HID 事件所必需的。

我通过守护程序匹配我的驱动程序服务很好,但是当我尝试打开服务时,我得到 -536870174,它来自 what I see here 的意思是 kIOReturnNotPermitted

据我了解,设备驱动程序用户客户端只能通过 Apple 授予 com.apple.developer.driverkit.userclient-access 权限的应用程序打开。

所以,我的问题是:

在 Driver Kit 中使用守护程序打开设备驱动程序的用户客户端是完全不可能的吗?

我唯一的选择是拥有一个具有 com.apple.developer.driverkit.userclient-access 权利的中间应用程序,它可以充当守护程序和驱动程序之间的代理吗?

所以它会是这样的:

Daemon 中间应用 虚拟 HID 设备

编辑: 要添加 Phil 在下面关于将应用程序作为守护程序运行的回答,还有一些 Apple written guidance here

解决方法

简而言之:没有必要走这么远。守护进程可以拥有权利。

从操作系统的角度来看,official solution 是使您的守护程序成为应用程序。本质上,将您的守护程序构建为应用程序包,只是不要将其称为 .app。您的 launchd plist 可以指向嵌入的可执行文件,它将继承周围包的权利。

非正式地,我还成功地将 Info.plist 直接嵌入到守护程序的二进制文件中,而没有周围的包目录。这通常用于与 SMJobBless() 一起使用的特权帮助器工具,并在许多地方 including here 中进行了描述。本质上,在 Xcode 中启用“Create Info.plist Section in Binary”构建设置,或者在使用其他构建系统时将 -sectcreate __TEXT __info_plist path/to/Info.plist 添加到您的链接器标志。 但是,我最终没有发货(最终不需要它),所以我只在禁用 SIP 的情况下对其进行了测试。所以我目前不能确定它在使用适当的配置文件签名后是否会起作用。

这两种方法都允许您通过在 Info.plist 中指定应用程序包 ID 来为二进制文件提供应用程序包 ID,然后您还可以在代码签名期间包含权利文件。由于 com.apple.developer.driverkit.userclient-access 不是 com.apple.security.* 命名空间中的“开放”权利之一,您还需要一个包含它的配置文件,否则操作系统将不会在启用 SIP 的情况下接受它。>

,

如果您采用上述 apple resource 中将应用程序作为守护程序运行的路径,以下代码是 Eskimo 发布的 Objective-c 的快速变体。

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!,&infoCF);
assert(err == errSecSuccess);

print(infoCF);
os_log("%{public}s",infoCF.debugDescription);