我正在维护一个 github 项目,该项目旨在自动化干净的 macOS 安装、macOS 自定义(完整的系统首选项和更多设置)以及应用程序和系统的更新。
https://github.com/tiiecherle/osx_install_config
脚本之一在系统首选项 - 安全 - 隐私下设置首选项。
每个 macOS 应用程序都有一个 csreq,它似乎是每个应用程序的指纹/校验和。在 macOS Mojave 之前,不需要显式设置值,它正在努力用“?”替换 csreq。例如,允许访问终端:
DATABASE_SYSTEM="/Library/Application Support/com.apple.TCC/TCC.db"
INPUT_SERVICE=kTCCServiceAccessibility
APP_ID=com.apple.Terminal
PERMISSION_GRANTED=1
APP_CSREQ=X'FADE0C000000003000000001000000060000000200000012636F6D2E6170706C652E5465726D696E616C000000000003'
### working, but no csreq
sudo sqlite3 "$DATABASE_SYSTEM" "REPLACE INTO access VALUES('"$INPUT_SERVICE"','"$APP_ID"',0,$PERMISSION_GRANTED,1,NULL,NULL,NULL,?,NULL,0,?);"
### working with csreq
sqlite3 "$DATABASE_USER" "REPLACE INTO access VALUES('"$INPUT_SERVICE"','"$APP_ID"',0,$PERMISSION_GRANTED,1,$APP_CSREQ,NULL,NULL,?,NULL,NULL,?);"
Run Code Online (Sandbox Code Playgroud)
这仍然有效,但 macOS Mojave 引入了更多安全设置,并且为了通过命令行正确设置自动化,需要两个应用程序、自动化和自动化应用程序的 csreqs,例如允许终端自动化系统设置:
DATABASE_USER="/Users/"$USER"/Library/Application Support/com.apple.TCC/TCC.db"
SOURCE_APP_ID=com.apple.Terminal
SOURCE_APP_CSREQ=X'FADE0C000000003000000001000000060000000200000012636F6D2E6170706C652E5465726D696E616C000000000003'
PERMISSION_GRANTED=1
AUTOMATED_APP_ID=com.apple.systemevents
AUTOMATED_APP_CSREQ=X'FADE0C000000003400000001000000060000000200000016636F6D2E6170706C652E73797374656D6576656E7473000000000003'
sqlite3 "$DATABASE_USER" "REPLACE INTO access VALUES('kTCCServiceAppleEvents','"$SOURCE_APP_ID"',0,$PERMISSION_GRANTED,1,$SOURCE_APP_CSREQ,NULL,0,'"$AUTOMATED_APP_ID"',$AUTOMATED_APP_CSREQ,NULL,?);"
Run Code Online (Sandbox Code Playgroud)
如果 csreq 替换为问号“?”,则该条目有效,但根本不会出现在系统首选项的 GUI 中。
系统会在请求权限时单击允许时生成 csreq,然后可以从数据库中读取。为了通过命令行进行正确的输入,我想从命令行上的应用程序读取/生成正确的 csreq,而不是从 tcc.db 读取它,因为它似乎随着应用程序的每个版本而变化。
感谢您提前提供任何帮助
编辑
非常感谢 Keith Johnson 非常好的解释和解决了大部分问题。按照他的回答,我能够在我的脚本的新配置文件中实现 csreq。
https://github.com/tiiiecherle/osx_install_config/blob/master/_config_file/shellscriptsrc.sh
在函数env_set_apps_security_permissions
和env_set_apps_automation_permissions
.
我还无法解决的是获取使用脚本编辑器或自动程序创建的未签名小程序或小程序的 csreq。
PATH_TO_APP="/Applications/brew_casks_update.app"
codesign --detached "$PATH_TO_APP".sig -s - "$PATH_TO_APP"
SOURCE_APP_CSREQ_STRING=$(codesign -d -r- --detached "$PATH_TO_APP".sig "$PATH_TO_APP")
echo "$SOURCE_APP_CSREQ_STRING" | csreq -r- -b /tmp/csreq.bin
Executable=/Applications/brew_casks_update.app/Contents/MacOS/applet error: invalid or corrupted code requirement(s) Requirement syntax error(s): line 2:1: unexpected end of file
Run Code Online (Sandbox Code Playgroud)
如果我手动添加它并从数据库中读取字符串,则它具有有效的 csreq。如果这个问题也能弄清楚,这个问题就完全解决了。那真是太好了。
谢谢
csreq blob 本身的格式看起来并不太复杂,如果你想花哨的话,Security.Framework 中的源代码可以帮助解码其含义。 [1] 它基本上是一个魔术头(0xFADE0C00),后跟一个 32 位长度(blob 的大小),然后是一些不同的“操作”。
值得庆幸的是,我们已经可以使用实用程序来操作 csreq blob,因此我们无需深入研究。
让我以你上面的例子为例Terminal.app
。Apple 发布了一个名为的工具csreq
,可用于将需求从其二进制表示转换为文本表示(然后再返回)。
# Convert the hex string into a binary blob
$ BLOB="FADE0C000000003000000001000000060000000200000012636F6D2E6170706C652E5465726D696E616C000000000003"
$ echo "$BLOB" | xxd -r -p > terminal-csreq.bin
# Ask csreq to tell us what it means
$ csreq -r- -t < terminal-csreq.bin
identifier "com.apple.Terminal" and anchor apple
Run Code Online (Sandbox Code Playgroud)
所以 csreq blob 只是说它想将应用程序与标识符“com.apple.Terminal”和锚点苹果匹配。我们可以检查 Terminal.app 并找到相同的需求字符串(在“指定”下)
$ codesign -d -r- /Applications/Utilities/Terminal.app
Executable=/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal
designated => identifier "com.apple.Terminal" and anchor apple
Run Code Online (Sandbox Code Playgroud)
让我们看另一个例子,这次是来自你的存储库 [2] 的 virtualbox:
# Convert the hex string into a binary blob
BLOB="FADE0C00000000AC0000000100000006000000020000001D6F72672E7669727475616C626F782E6170702E5669727475616C426F78000000000000060000000F000000060000000E000000010000000A2A864886F76364060206000000000000000000060000000E000000000000000A2A864886F7636406010D0000000000000000000B000000000000000A7375626A6563742E4F550000000000010000000A564235453254563936330000"
$ echo "$BLOB" | xxd -r -p > vbox-csreq.bin
# Ask csreq to tell us what it means
$ csreq -r- -t < vbox-csreq.bin
identifier "org.virtualbox.app.VirtualBox" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = VB5E2TV963
# ask codesign what the requirement text from the application itself is
$ codesign -d -r- /Applications/VirtualBox.app
Executable=/Applications/VirtualBox.app/Contents/MacOS/VirtualBox
designated => identifier "org.virtualbox.app.VirtualBox" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = VB5E2TV963
Run Code Online (Sandbox Code Playgroud)
我们再次可以看到designated
codesign 返回的字段与 csreq blob 包含的内容相同。
如果您对需求字符串的实际含义感到好奇,Apple 有一些关于此的文档[3]。
现在我们知道 csreq blob 包含什么以及在哪里可以找到等效信息,我们需要将其转换为 tcc 数据库所需的二进制格式。csreq
我们上面用于解码二进制 blob的工具也能够将文本表示转换为二进制。
# Get the requirement string from codesign
$ REQ_STR=$(codesign -d -r- /Applications/Utilities/Terminal.app/ 2>&1 | awk -F ' => ' '/designated/{print $2}')
# Convert the requirements string into it's binary representation(sadly it seems csreq requires the output to be a file; so we just throw it in /tmp)
$ echo "$REQ_STR" | csreq -r- -b /tmp/csreq.bin
# Convert the binary form to hex, and print it nicely for use in sqlite
$ REQ_HEX=$(xxd -p /tmp/csreq.bin | tr -d '\n')
$ echo "X'$REQ_HEX'"
X'fade0c000000003000000001000000060000000200000012636f6d2e6170706c652e5465726d696e616c000000000003'
Run Code Online (Sandbox Code Playgroud)
这个十六进制字符串与你上面从 tcc 数据库中得到的相同。
如果您想信任未签名的脚本/二进制文件并尝试使用上述方法,您会遇到一些问题:
$ codesign -d -r- ./hello.sh
./hello.sh: code object is not signed at all
Run Code Online (Sandbox Code Playgroud)
阅读有关代码签名要求语言 [3] 的文档,在Code Directory Hash
(强调我的)下有一个小注释
因为每当程序以一种非平凡的方式更改时,代码目录就会更改,所以此测试可用于明确识别程序的一个特定版本。当操作系统签署其他未签名的程序时(例如,以便钥匙串或家长控制可以识别该程序),它使用此要求。
因此,对于未签名的程序,会生成一个临时签名并用于识别诸如 TCC(等等)之类的东西。
该codesign
工具可用于创建临时签名,我们可以从中获取需求字符串。
# Get the requirement string from codesign
$ REQ_STR=$(codesign -d -r- /Applications/Utilities/Terminal.app/ 2>&1 | awk -F ' => ' '/designated/{print $2}')
# Convert the requirements string into it's binary representation(sadly it seems csreq requires the output to be a file; so we just throw it in /tmp)
$ echo "$REQ_STR" | csreq -r- -b /tmp/csreq.bin
# Convert the binary form to hex, and print it nicely for use in sqlite
$ REQ_HEX=$(xxd -p /tmp/csreq.bin | tr -d '\n')
$ echo "X'$REQ_HEX'"
X'fade0c000000003000000001000000060000000200000012636f6d2e6170706c652e5465726d696e616c000000000003'
Run Code Online (Sandbox Code Playgroud)
从这里我们可以继续上面给出的相同过程。
归档时间: |
|
查看次数: |
1077 次 |
最近记录: |