我正在开发一个大型 Mac 应用程序,该应用程序在许多不同进程中的许多组件中拆分。其中一个组件是 Safari Extension Companion[1],它是一种“应用程序扩展”,允许基于 JavaScript 的扩展与本机代码对话(这是我们组件之间安全 IPC 所必需的)。IPC 通道是用户~/Library/Application Support/<APPNAME>/
目录中的一个 Unix 域套接字。由于遗留原因,Unix 套接字服务器使用 HTTP 并且客户端库使用自定义URLProtocol
的,以防万一。
这适用于我们所有其他组件,但它们都没有在沙箱中运行[2]。但是,扩展伴侣的 Xcode 模板创建了一个沙箱,如果沙箱加载了伴侣,它似乎需要沙箱。我尝试在权利文件中设置com.apple.security.app-sandbox
,false
或删除权利文件(以及对它的所有引用),两者似乎都阻止了 Safari 加载伴侣(如果直接调用它仍然作为自己的二进制文件运行,但 Safari 显然不会不要碰它)。
我在沙箱中添加了例外,以允许它直接访问相关目录,以及直接访问 IPC 套接字;但这似乎还不够。尝试打开套接字时遇到的错误是EPERM
(不允许操作),这并不能真正解释问题。在将例外添加到权利并修复路径之后,日志文件(也在 "real" 下~/Library/
)之类的内容现在按预期写入。
这个错误发生在对connect
套接字的调用上(它返回-1,表示一个错误,并且errno
是1(EPERM
)),所以实际上从来没有尝试写入或读取套接字。这对我来说似乎很奇怪,因为 - 根据Apple Sandbox Design Guide -
UNIX 域套接字很简单;它们就像任何其他文件一样工作
关于沙盒异常。
权利文件(使用此处的答案从自动生成的模板修改:
<?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>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.temporary-exception.files.home-relative-path.read-write</key>
<array>
<string>/Library/Application Support/{APPNAME}/</string>
<string>/Library/Application Support/{APPNAME}/ipc_socket</string>
<string>/Library/Logs/{APPNAME}/</string>
</array>
</dict>
</plist>
有没有办法让 Safari Extension Companion 完全不用沙箱工作?如果没有,我如何允许同伴使用 IPC 套接字?
或者,有没有办法在扩展伴侣中使用 UNIX 套接字(如果问题不在于沙箱本身)?
*编辑:此问题已被编辑为先前的问题 -ENOENT
调用时(未找到文件)connect
- 在得到任何评论或答案之前已解决。这是由于sockaddr_un
完整的域套接字路径太短,并且通过使用套接字的真实路径而不是通过沙盒版本的(非常长的)路径Library/Application Support
和在那里种植的符号链接来解决。但是,新问题似乎在同一个地方,也可能是由于沙盒。
编辑 2:更新了权利以包括网络客户端(和服务器,为了很好的衡量标准)。虽然 Unix 套接字不是网络套接字,但它是一个失败的网络 API,所以我认为它可能会有所帮助。不过没有区别;还是继续EPERM
打电话吧connect
。
[1] 使用 Extension Companion 而不是原生代码 Safari App Extension,因为背景/全局逻辑相当复杂,但目前在所有主要浏览器中基本相同;用本机代码重写它将是一项重大的一次性任务,也是一项持续的维护负担。我也怀疑这对我遇到的问题没有帮助。
[2] 两个主要的不能被沙盒化,因为它们需要访问整个文件系统。该应用程序不是通过 App Store 分发的,因此缺少沙盒不会带来合规性问题。为了安全起见,我想启用沙盒,但这不切实际。