feat: complete session preferences and PAM fixture gates
This commit is contained in:
@@ -1,9 +1,5 @@
|
||||
#!/bin/sh
|
||||
# Exercise the non-interactive CLI contract without authenticating a user.
|
||||
#
|
||||
# This suite intentionally uses --preview. It validates TOML parsing, command
|
||||
# line validation, build metadata, and the preflight path without requiring a
|
||||
# PAM secret, a controlling VT, or a running display server.
|
||||
# Use --preview so this test does not need PAM, a VT, or a display server.
|
||||
set -eu
|
||||
|
||||
binary=${1:-target/debug/latchd}
|
||||
|
||||
93
scripts/test-pam-fixture.sh
Executable file
93
scripts/test-pam-fixture.sh
Executable file
@@ -0,0 +1,93 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "pam-fixture: SKIP (root is required to install a temporary PAM policy)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
service="latchd-fixture-$$"
|
||||
session_service="latchd-session-fixture-$$"
|
||||
policy="/etc/pam.d/$service"
|
||||
session_policy="/etc/pam.d/$session_service"
|
||||
checker="/tmp/latchd-pam-session-check-$$"
|
||||
module_source="/tmp/latchd-pam-session-env-$$.c"
|
||||
module="/tmp/latchd-pam-session-env-$$.so"
|
||||
cleanup() {
|
||||
rm -f "$policy" "$session_policy" "$checker" "$module_source" "$module"
|
||||
}
|
||||
trap cleanup EXIT HUP INT TERM
|
||||
|
||||
umask 077
|
||||
cat >"$policy" <<'PAM'
|
||||
auth required pam_deny.so
|
||||
account required pam_permit.so
|
||||
password required pam_deny.so
|
||||
session required pam_permit.so
|
||||
PAM
|
||||
|
||||
cat >"$checker" <<'SH'
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
[ "${PAM_TTY:-}" = "tty2" ]
|
||||
[ "${XDG_SESSION_CLASS:-}" = "user" ]
|
||||
[ "${XDG_SESSION_TYPE:-}" = "wayland" ]
|
||||
[ "${XDG_SESSION_DESKTOP:-}" = "niri" ]
|
||||
[ "${XDG_SEAT:-}" = "seat0" ]
|
||||
[ "${XDG_VTNR:-}" = "2" ]
|
||||
SH
|
||||
chmod 700 "$checker"
|
||||
|
||||
cat >"$module_source" <<'C'
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_modules.h>
|
||||
|
||||
PAM_EXTERN int pam_sm_open_session(
|
||||
pam_handle_t *pamh,
|
||||
int flags,
|
||||
int argc,
|
||||
const char **argv
|
||||
) {
|
||||
int result;
|
||||
(void)flags;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
result = pam_putenv(pamh, "XDG_SESSION_ID=fixture-session");
|
||||
if (result != PAM_SUCCESS) return result;
|
||||
result = pam_putenv(pamh, "XDG_RUNTIME_DIR=/tmp/latchd-runtime-fixture");
|
||||
if (result != PAM_SUCCESS) return result;
|
||||
return pam_putenv(
|
||||
pamh,
|
||||
"DBUS_SESSION_BUS_ADDRESS=unix:path=/tmp/latchd-runtime-fixture/bus"
|
||||
);
|
||||
}
|
||||
|
||||
PAM_EXTERN int pam_sm_close_session(
|
||||
pam_handle_t *pamh,
|
||||
int flags,
|
||||
int argc,
|
||||
const char **argv
|
||||
) {
|
||||
(void)pamh;
|
||||
(void)flags;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
C
|
||||
${CC:-cc} -shared -fPIC "$module_source" -o "$module" -lpam
|
||||
chmod 700 "$module"
|
||||
|
||||
cat >"$session_policy" <<PAM
|
||||
auth required pam_permit.so
|
||||
account required pam_permit.so
|
||||
password required pam_deny.so
|
||||
session required $module
|
||||
session required pam_exec.so $checker
|
||||
PAM
|
||||
|
||||
LATCHD_PAM_FIXTURE_SERVICE="$service" \
|
||||
LATCHD_PAM_SESSION_FIXTURE_SERVICE="$session_service" \
|
||||
cargo test --locked -p latchd-auth --test pam_fixture -- --ignored
|
||||
@@ -1,9 +1,5 @@
|
||||
#!/bin/sh
|
||||
# Probe host capabilities needed for a real login-manager deployment.
|
||||
#
|
||||
# This script never reports an unavailable capability as a pass. On an
|
||||
# ordinary container it prints SKIP and exits successfully; --strict turns
|
||||
# every SKIP into a failure for a prepared VM or privileged runner.
|
||||
# Report unavailable capabilities as SKIP. In strict mode, each SKIP is an error.
|
||||
set -u
|
||||
|
||||
binary=${1:-}
|
||||
@@ -47,8 +43,7 @@ else
|
||||
skip "latchd binary not supplied; capability-only probe"
|
||||
fi
|
||||
|
||||
# This is deliberately a runtime capability check, not an authentication
|
||||
# claim. Authentication needs a disposable VM user and a test PAM policy.
|
||||
# This checks the PAM runtime only. Authentication requires a test account and policy.
|
||||
if need_command ldconfig && ldconfig -p 2>/dev/null | grep -q 'libpam\.so'; then
|
||||
pass "PAM runtime library is available"
|
||||
else
|
||||
@@ -70,16 +65,14 @@ else
|
||||
skip "faillock helper is unavailable"
|
||||
fi
|
||||
|
||||
# A real VT is a character device and must be allocated by the host/VM. A
|
||||
# pseudo-terminal from CI is not equivalent and is intentionally not accepted.
|
||||
# A pseudo-terminal does not test VT allocation by the host or VM.
|
||||
if [ -c /dev/tty0 ] && [ -d /sys/class/tty/tty0 ]; then
|
||||
pass "Linux virtual terminal device is available"
|
||||
else
|
||||
skip "Linux virtual terminal is unavailable (container or non-console host)"
|
||||
fi
|
||||
|
||||
# Xvfb is a genuine X server and is safe to exercise without host display
|
||||
# access. If it is absent, this is a skip rather than a synthetic success.
|
||||
# Xvfb tests X11 without access to the host display.
|
||||
if need_command Xvfb; then
|
||||
display_number=$((100 + ($$ % 500)))
|
||||
display=":$display_number"
|
||||
@@ -113,8 +106,7 @@ else
|
||||
skip "Xvfb is unavailable"
|
||||
fi
|
||||
|
||||
# A Wayland socket is meaningful only when a compositor owns it. Do not claim
|
||||
# Wayland support merely because a client library or executable is installed.
|
||||
# A compositor must own the Wayland socket. Installed client libraries are not sufficient.
|
||||
wayland_socket=
|
||||
if [ -n "${WAYLAND_DISPLAY:-}" ] && [ -n "${XDG_RUNTIME_DIR:-}" ]; then
|
||||
case "$WAYLAND_DISPLAY" in
|
||||
@@ -128,8 +120,7 @@ else
|
||||
skip "Wayland compositor socket is unavailable (requires a compositor-backed VM/session)"
|
||||
fi
|
||||
|
||||
# systemd-logind is not normally PID 1 in a Docker container. loginctl output
|
||||
# is checked only when the manager and seat are actually reachable.
|
||||
# Check loginctl only when systemd-logind is available.
|
||||
if need_command loginctl && [ -d /run/systemd/system ]; then
|
||||
if loginctl --no-pager show-seat seat0 >/dev/null 2>&1; then
|
||||
pass "systemd-logind seat0 is reachable"
|
||||
|
||||
Reference in New Issue
Block a user