diff --git a/coin/provisioning/common/macos/set_tcc_permissions.sh b/coin/provisioning/common/macos/set_tcc_permissions.sh index 274b01ff..116263fa 100755 --- a/coin/provisioning/common/macos/set_tcc_permissions.sh +++ b/coin/provisioning/common/macos/set_tcc_permissions.sh @@ -2,38 +2,91 @@ #Copyright (C) 2024 The Qt Company Ltd #SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only -TCC_DATABASE="$HOME/Library/Application Support/com.apple.TCC/TCC.db" -if touch "$TCC_DATABASE"; then - # We can write to the TCC database - BOOTSTRAP_AGENT="$HOME/bootstrap-agent" - REQ_STR=$(codesign -d -r- "$BOOTSTRAP_AGENT" 2>&1 | awk -F ' => ' '/designated/{print $2}') - REQ_HEX=$(echo "$REQ_STR" | csreq -r- -b >(xxd -p | tr -d '\n')) +set -e - SERVICES=() +# ------ Clients ------ - # Qt Multimedia tests need microphone access - SERVICES+=('kTCCServiceMicrophone') +TCC_CLIENTS=() - # Qt Connectivity tests need Bluetooth access - SERVICES+=('kTCCServiceBluetoothAlways') +# The original path to bootstrap-agent +if [[ -x "$HOME/bootstrap-agent" ]]; then + TCC_CLIENTS+=("$HOME/bootstrap-agent") +fi +# The app-bundle version of the agent, in case we install it like that +if [[ -d "$HOME/bootstrap-agent.app" ]]; then + TCC_CLIENTS+=("$HOME/bootstrap-agent.app") +fi + +# The responsible process for the SSH server. By giving this +# process the permissions we ensure that developers SSH'ing +# into a CI machine will have the same permissions when running +# tests as bootstrap-agent has. This also opens the door to +# running the boostrap agent via SSH, giving the exact same +# environment for interactive developer sessions as coin. +TCC_CLIENTS+=("/usr/libexec/sshd-keygen-wrapper") + +# ------ Services (permissions) ------ + +SERVICES=() + +# Qt Multimedia tests need microphone access +SERVICES+=("kTCCServiceMicrophone|$HOME") + +# Qt Connectivity tests need Bluetooth access +SERVICES+=("kTCCServiceBluetoothAlways|$HOME") + +# ------ Implementation ------ + +function add_permission_for_client() { + local client="$1" + local service="$2" + + local path="${service#*|}" + local service="${service%|*}" + + tcc_database="${path%/}/Library/Application Support/com.apple.TCC/TCC.db" + if ! sudo touch "$tcc_database"; then + echo "TCC database is not writable. Is SIP disabled?" >&2 + exit 1 + fi + + if [[ -d "$client" && "${client%/}" == *.app ]]; then + info_plist="$client/Contents/Info.plist" + executable=$(defaults read $info_plist CFBundleExecutable) + executable="$client/Contents/MacOS/$executable" + client=$(defaults read $info_plist CFBundleIdentifier) + client_type="0" # Bundle ID + elif [[ -x "$client" ]]; then + executable=$client + client_type="1" # Absolute path + else + echo "Unknown or missing TCC client type '$client'!" >&2 + exit 1 + fi + + local req_str=$(codesign -d -r- "$executable" 2>&1 | awk -F ' => ' '/designated/{print $2}') + local req_hex=$(echo "$req_str" | csreq -r- -b >(xxd -p | tr -d '\n')) + + sudo sqlite3 -echo "$tcc_database" <&2 - exit 1 -fi +done