docs: prune history and orphans from party's comments
Rationale stays; what goes is narration of past revisions (git log has it), a 'Library mode' section heading with no code under it, a helper description left above cmd_role after the helper was folded in, a claim that cmd_close trusts the roster's SOCKET (it never reads it), and pointers to a README section that is named Security. The FS perms platform list gains DragonFly.
This commit is contained in:
parent
8661d2968e
commit
120fed8cb4
1 changed files with 21 additions and 42 deletions
63
party
63
party
|
|
@ -83,13 +83,6 @@ Info:
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
# Library mode
|
|
||||||
# ============
|
|
||||||
|
|
||||||
# Sourced from tests with __PARTY_LIB_ONLY=1 to expose helpers without
|
|
||||||
# triggering dispatch. The marker MUST be checked before the dispatch
|
|
||||||
# block at the bottom of the file.
|
|
||||||
|
|
||||||
# Helpers
|
# Helpers
|
||||||
# =======
|
# =======
|
||||||
|
|
||||||
|
|
@ -104,9 +97,7 @@ EOF
|
||||||
validate_party_name() {
|
validate_party_name() {
|
||||||
name="$1"
|
name="$1"
|
||||||
# Length cap: 63 keeps the full socket path comfortably below the
|
# Length cap: 63 keeps the full socket path comfortably below the
|
||||||
# 108-char sun_path limit for typical USERs. Runs before the empty/
|
# 108-char sun_path limit for typical USERs.
|
||||||
# shape checks below; an empty name has length 0, so it always
|
|
||||||
# passes this check and falls through to the '' case there.
|
|
||||||
if [ "${#name}" -gt 63 ]; then
|
if [ "${#name}" -gt 63 ]; then
|
||||||
echo "party: name '$name' too long (max 63 chars)" >&2
|
echo "party: name '$name' too long (max 63 chars)" >&2
|
||||||
return 2
|
return 2
|
||||||
|
|
@ -287,9 +278,6 @@ roster_read() {
|
||||||
# validate_party_name rejects them (dots are banned: tmux rewrites
|
# validate_party_name rejects them (dots are banned: tmux rewrites
|
||||||
# them in session names). Run the canonical validator so the
|
# them in session names). Run the canonical validator so the
|
||||||
# invariant cmd_host enforces on write is also checked on read.
|
# invariant cmd_host enforces on write is also checked on read.
|
||||||
# Side effect: pre-existing dotted-party dirs from older builds
|
|
||||||
# become undiscoverable, which is the pre-release migration policy
|
|
||||||
# (README §Status).
|
|
||||||
validate_party_name "$RR_PARTY_NAME" 2>/dev/null || return 1
|
validate_party_name "$RR_PARTY_NAME" 2>/dev/null || return 1
|
||||||
|
|
||||||
# Both the dir and its sock must be owned by the user named in the
|
# Both the dir and its sock must be owned by the user named in the
|
||||||
|
|
@ -324,9 +312,8 @@ roster_read() {
|
||||||
'' | \#*) ;;
|
'' | \#*) ;;
|
||||||
esac
|
esac
|
||||||
done < "$rec"
|
done < "$rec"
|
||||||
# A roster written before --group existed (or otherwise missing
|
# No GROUP= in the record: assume the default, so callers can use
|
||||||
# GROUP=) gates on the default group; callers can rely on RR_GROUP
|
# RR_GROUP unconditionally.
|
||||||
# always naming the party's actual perimeter.
|
|
||||||
[ -n "$RR_GROUP" ] || RR_GROUP=$TMUX_PARTY_GROUP
|
[ -n "$RR_GROUP" ] || RR_GROUP=$TMUX_PARTY_GROUP
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
@ -379,15 +366,11 @@ roster_list() {
|
||||||
# list-clients` exits 0 only against a real tmux server bound to that
|
# list-clients` exits 0 only against a real tmux server bound to that
|
||||||
# exact socket path, which rules out stale roster pointers, AF_UNIX
|
# exact socket path, which rules out stale roster pointers, AF_UNIX
|
||||||
# impostors (a same-group user planting a hand-rolled listener via
|
# impostors (a same-group user planting a hand-rolled listener via
|
||||||
# `nc -lU`), and PID-reuse leftovers in one shot. Earlier revisions had
|
# `nc -lU`), and PID-reuse leftovers in one shot. Do not add a
|
||||||
# a separate is_party_alive() that also format-checked the roster's
|
# `kill -0 $SERVER_PID` pre-filter: per POSIX, kill(2) signal 0 may
|
||||||
# SERVER_PID, a vestige of a `kill -0` pre-filter that broke cross-user
|
# return EPERM when the caller lacks send-permission, and illumos, the
|
||||||
# discovery on every non-Linux POSIX target: per POSIX, kill(2) signal
|
# BSDs, and macOS honor that, which breaks cross-user discovery
|
||||||
# 0 may return EPERM when the caller lacks send-permission, and
|
# everywhere but Linux (and LX zones). SERVER_PID is display-only.
|
||||||
# illumos, all the BSDs, and macOS honor that. Linux (and LX-branded
|
|
||||||
# zones) return 0 for "exists, even if not signalable", which is why
|
|
||||||
# the bug hid in the test matrix until a native illumos run surfaced
|
|
||||||
# it. SERVER_PID stays in the roster as display-only metadata.
|
|
||||||
party_conn_state() {
|
party_conn_state() {
|
||||||
_cs_err=$("$PARTY_TMUX" -S "$1" list-clients 2>&1 >/dev/null) \
|
_cs_err=$("$PARTY_TMUX" -S "$1" list-clients 2>&1 >/dev/null) \
|
||||||
&& _cs_rc=0 || _cs_rc=$?
|
&& _cs_rc=0 || _cs_rc=$?
|
||||||
|
|
@ -403,9 +386,7 @@ party_conn_state() {
|
||||||
# Guest sessions
|
# Guest sessions
|
||||||
# --------------
|
# --------------
|
||||||
|
|
||||||
# Print the caller's guest session name for a given user: the fixed
|
# Print the guest session name of user $1.
|
||||||
# session __party_guest_<user> that join/leave/status/role/kick/detach
|
|
||||||
# all target.
|
|
||||||
guest_session_name() {
|
guest_session_name() {
|
||||||
printf '__party_guest_%s\n' "$1"
|
printf '__party_guest_%s\n' "$1"
|
||||||
}
|
}
|
||||||
|
|
@ -419,7 +400,7 @@ guest_session_name() {
|
||||||
# __party_guest_$USER (and even group it to the party), so on a shared
|
# __party_guest_$USER (and even group it to the party), so on a shared
|
||||||
# server no session name is unforgeable. We trust invitees by design,
|
# server no session name is unforgeable. We trust invitees by design,
|
||||||
# that's the whole model. A read-only invitee (-r) can't create
|
# that's the whole model. A read-only invitee (-r) can't create
|
||||||
# sessions, so it's not exposed. See README §Trust model.
|
# sessions, so it's not exposed. See README §Security.
|
||||||
ensure_guest_session() {
|
ensure_guest_session() {
|
||||||
_eg_sock="$1" _eg_host_sess="$2"
|
_eg_sock="$1" _eg_host_sess="$2"
|
||||||
guest=$(guest_session_name "$USER")
|
guest=$(guest_session_name "$USER")
|
||||||
|
|
@ -441,7 +422,7 @@ caller_present_on() {
|
||||||
#
|
#
|
||||||
# The OS group is the perimeter, tmux's server-access allowlist is the
|
# The OS group is the perimeter, tmux's server-access allowlist is the
|
||||||
# per-user filter. Both are universal across the supported platforms
|
# per-user filter. Both are universal across the supported platforms
|
||||||
# (Linux, FreeBSD, NetBSD, OpenBSD, illumos, Solaris, macOS), so the
|
# (Linux, FreeBSD, DragonFly, NetBSD, OpenBSD, illumos, Solaris, macOS), so the
|
||||||
# mechanism is one liner: chgrp + chmod. No ACL syscalls invoked.
|
# mechanism is one liner: chgrp + chmod. No ACL syscalls invoked.
|
||||||
#
|
#
|
||||||
# ACL-shadowing on filesystems with NFSv4-style extended ACLs (macOS
|
# ACL-shadowing on filesystems with NFSv4-style extended ACLs (macOS
|
||||||
|
|
@ -470,7 +451,7 @@ caller_present_on() {
|
||||||
# ACLs that chmod 0750 can't override, document it in your deployment
|
# ACLs that chmod 0750 can't override, document it in your deployment
|
||||||
# notes, server-access still keeps strangers out, but advertised
|
# notes, server-access still keeps strangers out, but advertised
|
||||||
# group members may need ACL-level access to traverse PARTY_SOCKET_DIR.
|
# group members may need ACL-level access to traverse PARTY_SOCKET_DIR.
|
||||||
# See README §Trust model for the user-facing version of this caveat.
|
# See README §Security for the user-facing version of this caveat.
|
||||||
# WONTFIX, by design.
|
# WONTFIX, by design.
|
||||||
|
|
||||||
apply_party_perms_file() {
|
apply_party_perms_file() {
|
||||||
|
|
@ -923,9 +904,7 @@ EOF
|
||||||
trap - EXIT INT TERM HUP
|
trap - EXIT INT TERM HUP
|
||||||
|
|
||||||
# Roster: chgrp only. roster_write already left mode 0640 (g+r, no g+w).
|
# Roster: chgrp only. roster_write already left mode 0640 (g+r, no g+w).
|
||||||
# Guests read records to discover/join; only the host writes them. Keeping
|
# Guests read records to discover/join; only the host writes them.
|
||||||
# them non-group-writable means a tampered SOCKET=... can't redirect
|
|
||||||
# cmd_close's destructive cleanup at peer-supplied paths.
|
|
||||||
chgrp "$TMUX_PARTY_GROUP" "$rec"
|
chgrp "$TMUX_PARTY_GROUP" "$rec"
|
||||||
|
|
||||||
if [ -z "${TMUX:-}" ] && [ -t 1 ]; then
|
if [ -z "${TMUX:-}" ] && [ -t 1 ]; then
|
||||||
|
|
@ -1309,9 +1288,8 @@ EOF
|
||||||
echo "$PARTY_TMUX -S $RR_SOCKET $*"
|
echo "$PARTY_TMUX -S $RR_SOCKET $*"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
# exec with discrete, quoted args: the old flat-string + unquoted
|
# exec with discrete, quoted args: a flat command string would
|
||||||
# `exec $attach_cmd` word-split on any whitespace in PARTY_TMUX or
|
# word-split on whitespace in PARTY_TMUX or the socket path.
|
||||||
# the socket path.
|
|
||||||
exec "$PARTY_TMUX" -S "$RR_SOCKET" "$@"
|
exec "$PARTY_TMUX" -S "$RR_SOCKET" "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1586,9 +1564,9 @@ cmd_list() {
|
||||||
"$RR_HOST_USER" "$RR_PARTY_NAME" "$attendees" "$group_tag")
|
"$RR_HOST_USER" "$RR_PARTY_NAME" "$attendees" "$group_tag")
|
||||||
else
|
else
|
||||||
# Live server, connection refused: we can't count attendees
|
# Live server, connection refused: we can't count attendees
|
||||||
# (list-clients is behind the auth gate: its empty stdout
|
# (list-clients is behind the auth gate and would answer
|
||||||
# used to render here as a bogus "0 attendee(s)"), but the
|
# with empty stdout, a bogus "0 attendee(s)"), but the party
|
||||||
# party is real and the caller can ask for an invite.
|
# is real and the caller can ask for an invite.
|
||||||
line=$(printf '%-12s %-30s invite-only (ask %s)%s' \
|
line=$(printf '%-12s %-30s invite-only (ask %s)%s' \
|
||||||
"$RR_HOST_USER" "$RR_PARTY_NAME" "$RR_HOST_USER" "$group_tag")
|
"$RR_HOST_USER" "$RR_PARTY_NAME" "$RR_HOST_USER" "$group_tag")
|
||||||
fi
|
fi
|
||||||
|
|
@ -1704,8 +1682,6 @@ cmd_status() {
|
||||||
if [ -n "$joined" ]; then echo "joined: $joined"; fi
|
if [ -n "$joined" ]; then echo "joined: $joined"; fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Locate the party socket where the calling user has at least one
|
|
||||||
# attached client. Sets RR_* on success. Used by cmd_role.
|
|
||||||
cmd_role() {
|
cmd_role() {
|
||||||
sub="${1:-}"
|
sub="${1:-}"
|
||||||
case "$sub" in
|
case "$sub" in
|
||||||
|
|
@ -1818,6 +1794,9 @@ dispatch() {
|
||||||
# Entrypoint
|
# Entrypoint
|
||||||
# ==========
|
# ==========
|
||||||
|
|
||||||
|
# Tests source this file with __PARTY_LIB_ONLY=1 to reach the helpers
|
||||||
|
# without triggering dispatch.
|
||||||
|
|
||||||
if [ "${__PARTY_LIB_ONLY:-0}" != "1" ]; then
|
if [ "${__PARTY_LIB_ONLY:-0}" != "1" ]; then
|
||||||
dispatch "$@"
|
dispatch "$@"
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue