coin: Extend TCC permissions to SSH server and bundled boostrap agent

We are experimenting with various ways of running and packaging the
bootstrap agent. To support this, let's add the required permissions
to both a standalone bootstrap-agent executable, as well as an app
bundled version of it, if found.

In addition, add the permissions to sshd-keygen-wrapper, which is
the responsible process for the SSH server, and any ssh login
sessions spawned by that. This serves two purposes. Firstly, this
matches the permissions between a coin run (by the bootstrap agent)
and what a developer will see when SSH'ing into the CI machine to
debug an issue. Secondly, we might use ssh as an entrypoint to
run the bootstrap-agent, in which case we need the permissions
on sshd-keygen-wrapper anyways, so that they are inherited by
the bootstrap-agent.

Pick-to: 6.8
Change-Id: I576349e93ca19d98384490c99102966e8ffe2833
Reviewed-by: Ville-Pekka Karhu <ville-pekka.karhu@qt.io>
This commit is contained in:
Tor Arne Vestbø
2024-08-23 15:20:34 +02:00
parent 29194b8803
commit 5368f47fe0

View File

@@ -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" <<EOF
DELETE from access WHERE client = '$client' AND service = '$service';
INSERT INTO access (service, client, client_type, auth_value, auth_reason, auth_version, csreq, flags) VALUES (
'$service', -- service
'$client', -- client
$client_type, -- client_type
2, -- auth_value (2 - allowed)
4, -- auth_reason (4 - "System Set")
1, -- auth_version
X'$req_hex', -- csreq
0 -- flags
);
EOF
}
# shellcheck disable=SC2043
for client in "${TCC_CLIENTS[@]}"; do
# shellcheck disable=SC2043
for service in "${SERVICES[@]}"; do
sqlite3 -echo "$TCC_DATABASE" <<EOF
DELETE from access WHERE client = '$BOOTSTRAP_AGENT' AND service = '$service';
INSERT INTO access (service, client, client_type, auth_value, auth_reason, auth_version, csreq, flags) VALUES (
'$service', -- service
'$BOOTSTRAP_AGENT', -- client
1, -- client_type (1 - absolute path)
2, -- auth_value (2 - allowed)
4, -- auth_reason (4 - "System Set")
1, -- auth_version
X'$REQ_HEX', -- csreq
0 -- flags
);
EOF
add_permission_for_client $client $service
done
else
echo "TCC database is not writable. Is SIP disabled?" >&2
exit 1
fi
done