From 4aab67657407734e9a5da1df06e0f84e07096064 Mon Sep 17 00:00:00 2001 From: Alex Hope-O'Connor Date: Thu, 17 Sep 2026 14:51:55 +1000 Subject: [PATCH] test: detect headless NetworkManager sessions --- tools/lib/portal-hardware-session.sh | 6 ++++-- tools/tests/test-portal-hardware-cli.sh | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/tools/lib/portal-hardware-session.sh b/tools/lib/portal-hardware-session.sh index 71dda92..0203e75 100755 --- a/tools/lib/portal-hardware-session.sh +++ b/tools/lib/portal-hardware-session.sh @@ -54,7 +54,9 @@ wm_prepare_networkmanager_authorization() { auto) if [[ "$direct" == yes ]]; then WM_NMCLI_MODE=direct - elif [[ -z "${DISPLAY:-}" && -z "${WAYLAND_DISPLAY:-}" && -z "${DBUS_SESSION_BUS_ADDRESS:-}" ]]; then + # A session D-Bus socket is common over SSH but does not itself + # provide a graphical Polkit agent, so require an actual display. + elif [[ -z "${DISPLAY:-}" && -z "${WAYLAND_DISPLAY:-}" ]]; then WM_NMCLI_MODE=sudo else # Give a graphical Polkit agent the chance to authorize the @@ -91,7 +93,7 @@ wm_report_networkmanager_authorization() { done if [[ "$direct" == yes ]]; then echo 'NetworkManager portal authorization: direct.' - elif [[ -z "${DISPLAY:-}" && -z "${WAYLAND_DISPLAY:-}" && -z "${DBUS_SESSION_BUS_ADDRESS:-}" ]]; then + elif [[ -z "${DISPLAY:-}" && -z "${WAYLAND_DISPLAY:-}" ]]; then echo 'NetworkManager portal authorization: scoped sudo will be requested before a portal command flashes the board.' else echo 'NetworkManager portal authorization: graphical Polkit may authorize actions; set WM_NMCLI_AUTH=sudo to use scoped sudo instead.' diff --git a/tools/tests/test-portal-hardware-cli.sh b/tools/tests/test-portal-hardware-cli.sh index 0fe2f72..105a6e2 100755 --- a/tools/tests/test-portal-hardware-cli.sh +++ b/tools/tests/test-portal-hardware-cli.sh @@ -21,6 +21,7 @@ printf '%s\n' '#!/usr/bin/env bash' \ 'echo "192.168.4.1 dev wlan-client src 192.168.4.2"' >"$stub_bin/ip" printf '%s\n' '#!/usr/bin/env bash' \ 'printf "%s\\n" "$*" >>"$CALL_LOG"' \ +'if [[ "${NMCLI_PERMISSION_MODE:-}" == "auth" && "$1" == "-t" && "$2" == "-f" && "$3" == "PERMISSION,VALUE" ]]; then printf "%s\\n" "org.freedesktop.NetworkManager.wifi.scan:auth" "org.freedesktop.NetworkManager.network-control:auth" "org.freedesktop.NetworkManager.settings.modify.system:auth"; exit 0; fi' \ 'if [[ "${NMCLI_REQUIRE_SUDO:-}" == "yes" && "${RUN_AS_SUDO:-}" != "yes" ]]; then echo "Error: Insufficient privileges" >&2; exit 7; fi' \ 'if [[ "${NMCLI_FAIL_SCAN:-}" == "yes" && "$1" == "device" && "$2" == "wifi" && "$3" == "rescan" ]]; then echo "fixture scan failure" >&2; exit 7; fi' \ 'if [[ "${NMCLI_FAIL_ADD:-}" == "yes" && "$1" == "connection" && "$2" == "add" ]]; then exit 7; fi' \ @@ -176,6 +177,22 @@ unset SUDO_FAIL export WM_NMCLI_AUTH=direct unset WM_NMCLI_AUTH_READY WM_NMCLI_MODE WM_NMCLI_PERMISSIONS +# A session D-Bus socket alone is not a graphical Polkit agent. This models +# the SSH environment that exposes DBUS_SESSION_BUS_ADDRESS but no display. +: >"$CALL_LOG" +if ! ROOT="$root" PATH="$stub_bin:$PATH" WM_NMCLI_AUTH=auto \ + NMCLI_PERMISSION_MODE=auth NMCLI_REQUIRE_SUDO=yes \ + DBUS_SESSION_BUS_ADDRESS='unix:path=/run/user/1000/bus' DISPLAY='' WAYLAND_DISPLAY='' \ + bash -c ' + source "$ROOT/tools/lib/portal-hardware-session.sh" + wm_prepare_networkmanager_authorization + [[ "$WM_NMCLI_MODE" == sudo ]] + '; then + echo 'headless session D-Bus path did not select scoped sudo' >&2 + exit 1 +fi +grep -Fq 'sudo -v' "$CALL_LOG" + # A portal scan failure must stop before `connection add` and clear the # pre-add pending record, even though this helper is invoked in an `if`. wm_wait_for_portal_ssid() { return 1; }