#!/bin/bash # @file tmux-member.sh # @description Server mode, one Linux user per account (S3): installed as # /opt/agenthub/libexec/tmux-member, the one tmux the host may run AS a # member (sudoers). Called as `tmux-member -S `, it runs # the args with the binary of the tmux server already listening on that # socket (`/proc//exe`, which still runs after an upgrade replaced the # file), else with TMUX_BIN from /etc/agenthub/server.conf (no server yet: # this call starts one, on the installed version). A client must match its # server: a tmux 3.8 client asking a 3.6 server kept it at 100% CPU. # # It runs as the member and execs only a process THEY own (under hidepid they # see no other), so it can run nothing they could not run themselves. # @author Nguyễn Ngọc Trí Vĩ set -u bin=$(sed -n 's/^TMUX_BIN=//p' /etc/agenthub/server.conf 2>/dev/null | head -n 1) [[ "$bin" == /* ]] || { echo "tmux-member: no TMUX_BIN in /etc/agenthub/server.conf" >&2; exit 2; } if [ "${1:-}" = -S ] && [ -n "${2:-}" ]; then # /proc/net/unix: Num RefCount Protocol Flags Type St Inode Path; 00010000 = listening. inode=$(awk -v s="$2" '$4 == "00010000" && $8 == s { print $7; exit }' /proc/net/unix 2>/dev/null) if [ -n "$inode" ]; then for d in /proc/[0-9]*; do [ -O "$d" ] || continue read -r comm <"$d/comm" 2>/dev/null || continue [[ "$comm" == tmux* ]] || continue for fd in "$d"/fd/*; do if [ "$(readlink "$fd" 2>/dev/null)" = "socket:[$inode]" ] && [ -x "$d/exe" ]; then exec "$d/exe" "$@" fi done done fi fi exec "$bin" "$@"