fix: classify unauthorized tmux connections; stop misreporting membership
tmux answers non-allowlisted users with 'access not allowed' on stderr and exit 0 for every command (verified 3.3a/3.5a, two users), so has-session reports any target as existing. party status claimed uninvited group members were joined, party leave silently 'succeeded', and party list printed bogus '0 attendee(s)' rows. New party_conn_state (ok/unauthorized/dead) classifies by message content; list now shows 'invite-only (ask <host>)'.
This commit is contained in:
parent
6cac86bb15
commit
f3209e39d1
3 changed files with 157 additions and 14 deletions
87
tests/96-unauthorized.bats
Normal file
87
tests/96-unauthorized.bats
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
#!/usr/bin/env bats
|
||||
#
|
||||
# Uninvited-guest semantics. tmux >= 3.3 answers a non-allowlisted
|
||||
# user's connection with "access not allowed" on stderr and EXIT 0
|
||||
# (verified live on 3.3a and 3.5a with two real users), for every
|
||||
# command — including has-session, which then reports any target as
|
||||
# existing. Exit-code-based checks therefore misclassified
|
||||
# "unauthorized" as "authorized": party status reported uninvited
|
||||
# members as joined, party leave silently "succeeded", and party list
|
||||
# printed bogus "0 attendee(s)" rows. These tests pin the corrected
|
||||
# classification.
|
||||
|
||||
load 'helpers'
|
||||
|
||||
setup() {
|
||||
setup_party_sandbox
|
||||
export TMUX_PARTY_GROUP="$(id -gn)"
|
||||
|
||||
# Stub tmux that answers every command the way a real server answers
|
||||
# a non-allowlisted user: message on stderr, exit 0.
|
||||
cat > "$PARTY_TMP/tmux-denied" <<'STUB'
|
||||
#!/bin/sh
|
||||
echo "access not allowed" >&2
|
||||
exit 0
|
||||
STUB
|
||||
chmod +x "$PARTY_TMP/tmux-denied"
|
||||
export PARTY_TMUX="$PARTY_TMP/tmux-denied"
|
||||
|
||||
# Plant a live-looking party dir + roster. Ownership is ours (bats
|
||||
# can't fake a foreign uid without root), so cmd_status will also see
|
||||
# this fixture as "hosting" — that's orthogonal to the joined/leave
|
||||
# misreporting under test.
|
||||
ensure_party_dir "$USER" fiesta
|
||||
d="$PARTY_SOCKET_DIR/party-$USER:fiesta.d"
|
||||
cat > "$d/roster" <<EOF
|
||||
HOST_USER=$USER
|
||||
PARTY_NAME=fiesta
|
||||
SOCKET=$d/sock
|
||||
SERVER_PID=12345
|
||||
GROUP=$TMUX_PARTY_GROUP
|
||||
CREATED=2026-07-03T00:00:00Z
|
||||
EOF
|
||||
chmod 0640 "$d/roster"
|
||||
}
|
||||
|
||||
teardown() { teardown_party_sandbox; }
|
||||
|
||||
@test "party list marks an unauthorized party invite-only, not 0 attendees" {
|
||||
run "$PARTY_BIN" list
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"fiesta"* ]]
|
||||
[[ "$output" == *"invite-only"* ]]
|
||||
[[ "$output" != *"0 attendee"* ]]
|
||||
}
|
||||
|
||||
@test "party join an invite-only party says whom to ask and exits 13" {
|
||||
# Regression lock: this already worked (the preflight greps stdout,
|
||||
# which is empty for unauthorized callers) and must keep working.
|
||||
run "$PARTY_BIN" join fiesta
|
||||
[ "$status" -eq 13 ]
|
||||
[[ "$output" == *"invite"* ]]
|
||||
}
|
||||
|
||||
@test "party status does not report unauthorized parties as joined" {
|
||||
run "$PARTY_BIN" status
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" != *"joined"* ]]
|
||||
}
|
||||
|
||||
@test "party leave on unauthorized parties says 'not joined', not success" {
|
||||
run "$PARTY_BIN" leave
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" == *"not joined"* ]]
|
||||
}
|
||||
|
||||
@test "a dead socket is still treated as dead" {
|
||||
cat > "$PARTY_TMP/tmux-dead" <<'STUB'
|
||||
#!/bin/sh
|
||||
echo "no server running" >&2
|
||||
exit 1
|
||||
STUB
|
||||
chmod +x "$PARTY_TMP/tmux-dead"
|
||||
export PARTY_TMUX="$PARTY_TMP/tmux-dead"
|
||||
run "$PARTY_BIN" list
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"no parties found"* ]]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue