mrrl-logincaps

MRRL version of logincaps
git clone https://ccx.te2000.cz/git/mrrl-logincaps
Log | Files | Refs

commit b14f9dec7919b95c5a1b8192ee6189a6e5b7cd15
parent d3def3fd568cf6b41fa32396191fdf443a03405b
Author: Jan Pobrislo <ccx@webprojekty.cz>
Date:   Tue, 15 Dec 2020 01:19:14 +0100

Plumber interface over FIFO for the X11 container; enable boot/poweroff caps; add chvt capability
Diffstat:
Mbin/zshaskpass_lock | 52+++++++++++++++++++++++++++++++++++++++++++++++++---
Msbin/logincaps | 29++++++++++++++++++++---------
2 files changed, 69 insertions(+), 12 deletions(-)

diff --git a/bin/zshaskpass_lock b/bin/zshaskpass_lock @@ -12,7 +12,7 @@ fi setopt no_unset warn_create_global zmodload zsh/zselect -typeset -g COPROC_OUT fd newfd prompt_end keep_running X die_color +typeset -g COPROC_OUT fd newfd prompt_end keep_running X die_color plumb_r plumb_w typeset -a coproc_args typeset -gA fds @@ -43,6 +43,8 @@ coproc_args=( ) if [[ -n $X ]]; then coproc_args+=( tail -F /run/containers/xsession.$X.ccx/run/uncaught-logs/current ) + typeset -g plumber_fifo + plumber_fifo=/run/containers/xsession.$X.ccx/run/plumber_fifo else coproc_args+=( tail -F /run/user/ccx.logs/current ) fi @@ -69,10 +71,28 @@ lock() { ssh-add -D || die "Error removing identities" s6-svc -o -wu -T 3000 /run/containers/xsession.$X.ccx/run/service/screen-locker/ || "Failed to bring up screen locker" s6-svstat /run/containers/xsession.$X.ccx/run/service/screen-locker/ - s6-svlisten1 -d /run/containers/xsession.$X.ccx/run/service/screen-locker/ zsh -c "read -sk 1 $'?Session locked, press enter to unlock.\n' || exit 98; until ssh-add -c; do sleep 2; read -sk 1 $'?\nUnlock failed, press enter to try again.\n' || exit 98; done; if ssh-add -l >/dev/null; then printf '%s\n' 'Success, stopping screen locker'; s6-svc -d '/run/containers/xsession.$X.ccx/run/service/screen-locker/'; fi" + s6-svlisten1 -d /run/containers/xsession.$X.ccx/run/service/screen-locker/ zsh -c "read -sk 1 $'?Session locked, press enter to unlock.\n' || exit 98; until ssh-add -c; do sleep 2; read -sk 1 $'?\nUnlock failed, press enter to try again.\n' || exit 98; done; if ssh-add -l >/dev/null; then printf '%s\n' 'Success, stopping screen locker'; s6-svc -d '/run/containers/xsession.$X.ccx/run/service/screen-locker/'; fi" ssh-add -l >/dev/null || die "Failed to load SSH agent identities (screen locker died?), exiting." } +setup-plumber-listener() { + local temp_r # keep plumb_r in temp variable and set it at the end to indicate success + [[ -n $plumb_r ]] && return 0 + + if [[ ! -p $plumber_fifo ]]; then + mkfifo $plumber_fifo || return $? + fi + + true >$plumber_fifo &! # background disowned task to keep the fifo's writing side open until it's opened below + sysopen -o cloexec -u temp_r -r $plumber_fifo || return $? + if ! sysopen -o cloexec -f plumber_w -w $plumber_fifo; then + exec {temp_r}>&- # close fd + return 1 + fi + plumb_r=$temp_r + fds+=( $plumb_r ) +} + cmd() { case $1 in ('') ;; @@ -86,6 +106,7 @@ cmd() { logincap X\ $X s6-svc -wu -o /run/service/container.xsession.$X.ccx s6-svstat /run/service/container.xsession.$X.ccx + setup-plumber-listener ;; (off|poweroff) logincap o;; @@ -104,9 +125,32 @@ cmd() { esac } +read-plumber-message() { + local plumb_dst plumb_wdir plumb_type plumb_attr plumb_ndata plumb_data + + IFS= read -ru $plumb_r plumb_src || return $? + IFS= read -ru $plumb_r plumb_dst || return $? + IFS= read -ru $plumb_r plumb_wdir || return $? + IFS= read -ru $plumb_r plumb_type || return $? + IFS= read -ru $plumb_r plumb_attr || return $? + IFS= read -ru $plumb_r plumb_ndata || return $? + [[ $plumb_ndata =~ [0-9]+ ]] || return $? + IFS= read -ru $plumb_r -k $plumb_ndata plumb_data || return $? + printf >&2 '%s=%s\n' src ${(qqq)plumb_src} dst ${(qqq)plumb_dst} wdir ${(qqq)plumb_wdir} type ${(qqq)plumb_type} attr ${(qqq)plumb_attr} data ${(qqq)plumb_data} + case $plumb_data in + (poweroff) logincap o;; + (reboot) logincap b;; + (lock) + logincap chvt tty + lock + logincap chvt X + ;; + esac +} + # typeset -f -t cmd -coproc "$coproc_args[@]" | s6-tai64nlocal +coproc "$coproc_args[@]" | s6-tai64nlocal trap 'kill %1' EXIT trap 'kill %1; ssh-add -D; exit' INT HUP TERM QUIT trap 'printf "\nALRM!\n"' ALRM @@ -154,6 +198,8 @@ while (($keep_running)) && zselect -A fds -r 0 $select_fds; do printf '> %s\n' $REPLY # fi fi + elif [[ $fd == $plumb_r ]]; then + read-plumber-message else # stdin if IFS= read -u $fd -s; then diff --git a/sbin/logincaps b/sbin/logincaps @@ -64,17 +64,23 @@ run_x() { } typeset -f -t run_x +cap_cmd() { + if "$@"; then + printf 'OK\n' + else + printf 'EX%d\n' $? + fi +} + main() { local line term_cmd REPLY while read line; do case $line in (o) printf >&2 "%s\n" "Would power-off." - pretendrun s6-poweroff - printf 'OK\n' + cap_cmd s6-poweroff ;; (b) printf >&2 "%s\n" "Would reboot." - pretendrun s6-reboot - printf 'OK\n' + cap_cmd s6-reboot ;; (terminal *) term_cmd=( "${(Q@)${(z)${line#terminal }}}" ) @@ -85,13 +91,18 @@ main() { printf 'OK\n' ;; + (chvt tty) + cap_cmd chvt ${LOGIN_TTY#/dev/tty} + ;; + + (chvt [Xx]) + cap_cmd chvt $X + ;; + (X [5678]*) - if run_x "${(Q@)${(z)${line#X }}}"; then - printf 'OK\n' - else - printf 'EX%d\n' $? - fi + cap_cmd run_x "${(Q@)${(z)${line#X }}}" ;; + (*) printf 'ECMD\n';; esac done