]> git.sev.monster Git - dotfiles.git/commitdiff
code cleanup, add su support
authorsev <git@sev.monster>
Wed, 3 Mar 2021 07:14:34 +0000 (01:14 -0600)
committersev <git@sev.monster>
Wed, 3 Mar 2021 07:14:34 +0000 (01:14 -0600)
cleanup renames some internal vars, moves SSH/GPG setup back to .zshenv,
and upgrades SSH setup to give more information about what it is doing.

su support will allow you to switch to another user with a non-login
shell and, as long as they are using zsh with the same dotfiles, you
will get a proper environment set up as if it were a login shell; this
is a lot easier and more comfortable than making an alias to or manually
passing SSH_AUTH_AGENT and other vars via sudo... for now.

an attempt should be made to make super user switching more portable by
adding support for doas and bog-standard su in aliases and elsewhere.

base/.zprofile
base/.zshenv
base/.zshrc

index f02872800c6c44d36fb806f664cf9fdef6e1f75c..7a7fc107845a46a156892cc754039c35d9ed0038 100644 (file)
@@ -2,10 +2,10 @@
 ## reset PATH to prevent /etc/zprofile from changing it
 # some distros put non-interactive PATH in env and interactive PATH in profile;
 # we want to make sure to always use ours regardless
-if [[ -v _sev_backup_path ]] {
+if [[ -v _backup_path ]] {
     path=("${_backup_path[@]}" "${path[@]}")
     export PATH
-    unset _sev_backup_path
+    unset _backup_path
 }
 ## common
 export EDITOR=vim
@@ -22,46 +22,6 @@ export PYTHONSTARTUP=~/.pythonrc
 ## perl
 [[ -v commands[perl] ]] && eval $(perl -I $XDG_DATA_HOME/perl5/lib/perl5 -Mlocal::lib=$XDG_DATA_HOME/perl5 2>/dev/null)
 
-### ssh agents
-# NOTE: preferred order of agents to check: okcagent, gnupg, openssh
-#       first block takes care of okcagent and openssh, second handles gnupg
-if [[ ! -v SSH_AUTH_SOCK && ( -v commands[okc-ssh-agent] ||
-      ( -v commands[ssh-agent] && ! -v commands[gpg] ) ) ]] {
-    okc=${commands[okc-ssh-agent]:+okc-}
-    agentfile=~/tmp/${okc}ssh-agent-exports
-    typeset sock=
-    typeset -i pid=
-    if [[ -f "$agentfile" ]] {
-        IFS=$'\0' read -r sock pid <"$agentfile"
-    }
-    if [[ -S "$sock" && $pid > 0 ]] && kill -0 $pid; then
-        echo "Reusing agent pid $pid"
-        export SSH_AUTH_SOCK="$sock"
-        export SSH_AGENT_PID=$pid
-    else
-        # TODO: ensure ssh-agent path looks legit
-        #       to avoid unsafe eval?
-        eval `${okc}ssh-agent`
-        echo -n "$SSH_AUTH_SOCK"$'\0'$SSH_AGENT_PID >!$agentfile
-    fi
-    unset okc agentfile sock pid
-} elif [[ -v commands[gpg] && ! -S $_GNUPG_SOCK_DEST && \
-          ( ! -v SSH_AUTH_SOCK || -v DISPLAY ) ]] {
-    export GPG_TTY=$(tty)
-    export PINENTRY_USER_DATA=USE_TTY=$((!${+DISPLAY}))
-    gpg-connect-agent UPDATESTARTUPTTY /bye >/dev/null 2>&1
-    gpg-connect-agent /subst /serverpid \
-        '/echo GPG agent pid ${get serverpid}' /bye
-    [[ ! -v SSH_AUTH_SOCK ]] && \
-        export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
-}
-
-### gpg socket
-if [[ -v _GNUPG_SOCK_SRC && -v _GNUPG_SOCK_DEST && -S $_GNUPG_SOCK_DEST ]] {
-    unlink $_GNUPG_SOCK_SRC >/dev/null 2>&1
-    mv $_GNUPG_SOCK_DEST $_GNUPG_SOCK_SRC >/dev/null
-}
-
 ### load site-specific
 if [[ -f ~/.zprofile.local ]] { source ~/.zprofile.local }
 
index 819eb70e00260a893cca9baaaa95478d7a74d681..8add8171a4e0ec591f08f695309be4565d320f9b 100644 (file)
@@ -1,21 +1,33 @@
-### exports for new non-interactive shell
-if [[ $SHLVL == 1 ]] {
+### unset unwanted options that could be set in /etc/zshenv
+unsetopt SH_WORD_SPLIT KSH_ARRAYS
+
+### check if su
+if [[ -v _sev_olduser && $_sev_olduser != $USERNAME ]] _sev_reset_shell=
+export _sev_olduser=$USERNAME
+
+### exports for all new shells
+if [[ -v _sev_reset_shell || $SHLVL == 1 ]] {
     ## lang
     export CHARSET=UTF-8
-    export LANG="en_US.UTF-8"
-    export LC_CTYPE="$LANG"
+    export LANG=en_US.UTF-8
+    export LC_CTYPE=$LANG
 
     ## path
+    typeset -U path fpath
+    if [[ $SHLVL  == 1 ]] {
+        # take a backup before any customizations
+        export _sev_sys_PATH=$PATH
+        export _sev_sys_FPATH=$FPATH
+    }
     # /usr/{pkg,local,games} are unix/bsdisms
-    typeset -U PATH path
     path=({~/,/,/usr/}sbin {~/,/,/usr/}bin /usr/pkg/{s,}bin /usr/X11R{7,6}/bin
-          /usr/local/{s,}bin /usr/games "${path[@]}")
-    export PATH
-    typeset -U _sev_backup_path
-    _sev_backup_path=("${path[@]}")
-    typeset -U FPATH fpath
-    fpath=(${ZDOTDIR:-$HOME/.zsh}/functions/{*,Completions/*}(N) "${fpath[@]}")
-    export FPATH
+          /usr/local/{s,}bin /usr/games)
+    PATH=$PATH:$_sev_sys_PATH
+    fpath=(${ZDOTDIR:-$HOME/.zsh}/functions/{*,Completions/*}(N))
+    FPATH=$FPATH:$_sev_sys_FPATH
+    # take another backup, explained in .zprofile
+    typeset -U _backup_path
+    _backup_path=("${path[@]}")
 
     ## xdg
     export XDG_CONFIG_HOME=~/etc
@@ -25,33 +37,88 @@ if [[ $SHLVL == 1 ]] {
     export XDG_CACHE_HOME=~/tmp
     export XDG_RUNTIME_DIR=~/tmp
 
-    # create tmp link
-    t="${TMPDIR:-/tmp}/home-$LOGNAME"
-    h="$HOME/tmp"
-    if [[ ! -e "$t" ]] {
-        mkdir -m 700 "$t" > /dev/null 2>&1
+    ## create tmp link
+    t=${TMPDIR:-/tmp}/home-$LOGNAME
+    h=$HOME/tmp
+    if [[ ! -e $t ]] {
+        mkdir -m 700 $t > /dev/null 2>&1
         # TODO: check if dir exists after mkdir
     }
     # allow opaque entries to override link creation
-    if [[ ! -e "$h" ]] {
-        ln -sf "$t" "$h" > /dev/null 2>&1
+    if [[ ! -e $h ]] {
+        ln -sf $t $h > /dev/null 2>&1
     }
     unset t h
-}
 
-### gpg ssh forwarding
-# these env vars are used as arguments to RemoteForward in ~/.ssh/config
-if [[ -v commands[gpgconf] && ! ( -v _GNUPG_SOCK_SRC && -v _GNUPG_SOCK_DEST ) ]] {
-    # if already connected over SSH, reuse forwarded socket for future
-    # connections; else use extra socket
-    sock=${SSH_CLIENT:+agent-socket}
-    export _GNUPG_SOCK_SRC=$(gpgconf --list-dirs ${sock:-agent-extra-socket})
-    # XXX: chance of race condition
-    export _GNUPG_SOCK_DEST=/tmp/.gpg-agent-forward
-    unset sock
+    ## ssh agents
+    # NOTE: preferred order of agents to check: okcagent, gnupg, openssh
+    #       first block takes care of okcagent and openssh, second gnupg
+    print -nP "%F{blue}>>>%f SSH: %F{green}"
+    if [[ ! -v SSH_AUTH_SOCK && ( -v commands[okc-ssh-agent] ||
+          ( -v commands[ssh-agent] && ! -v commands[gpg] ) ) ]] {
+        okc=${commands[okc-ssh-agent]:+okc-}
+        agentfile=~/tmp/${okc}ssh-agent-exports
+        typeset sock=
+        typeset -i pid=
+        if [[ -f $agentfile ]] {
+            IFS=$'\0' read -r sock pid <$agentfile
+        }
+        if [[ -S $sock && $pid > 0 ]] && kill -0 $pid; then
+            echo "Reusing agent pid $pid"
+            export SSH_AUTH_SOCK=$sock
+            export SSH_AGENT_PID=$pid
+        else
+            # TODO: ensure ssh-agent path looks legit
+            #       to avoid unsafe eval?
+            eval `${okc}ssh-agent`
+            echo -n $SSH_AUTH_SOCK$'\0'$SSH_AGENT_PID >!$agentfile
+        fi
+        unset okc agentfile sock pid
+    } elif [[ -v commands[gpg] && ! -S $_GNUPG_SOCK_DEST && \
+              ( ! -v SSH_AUTH_SOCK || -v DISPLAY ) ]] {
+        export GPG_TTY=$(tty)
+        export PINENTRY_USER_DATA=USE_TTY=$((!${+DISPLAY}))
+        gpg-connect-agent UPDATESTARTUPTTY /bye >/dev/null 2>&1
+        gpg-connect-agent /subst /serverpid \
+            '/echo GPG agent pid ${get serverpid}' /bye
+        [[ ! -v SSH_AUTH_SOCK ]] && \
+            export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
+    } else {
+        echo "Pre-existing or remote agent"
+    }
+
+    ## gpg ssh forwarding
+    # ssh automatically tunnels SSH_AUTH_SOCK with the right config, but GPG
+    # doesn't—we use a RemoteForward rule in ~/.ssh/config that uses these env
+    # vars to push the gpg extra socket through when connecting via ssh
+    # HACK: this entire thing sucks but there is no other easy way that works
+    #       out of the box with other systems
+    if [[ -v commands[gpgconf] ]] {
+        # if already connected over SSH, reuse forwarded socket for future
+        # connections; else use extra socket
+        sock=${SSH_CLIENT:+agent-socket}
+        export _GNUPG_SOCK_SRC=$(gpgconf --list-dirs ${sock:-agent-extra-socket})
+        unset sock
+        # XXX: multiple SSH sessions to the same host will overwrite this
+        #      socket, no way to send unique paths without configuring explicit
+        #      SendEnv and AcceptEnv exclusions on client and host respectively
+        export _GNUPG_SOCK_DEST=/tmp/.gpg-agent-forward
+        # if socket exists already, we are on a RemoteForwarded client, so copy
+        # it over so that GPG sees it
+        # XXX: race condition if connecting multiple terminals at once
+        if [[ -S $_GNUPG_SOCK_DEST ]] {
+            unlink $_GNUPG_SOCK_SRC >/dev/null 2>&1
+            mv $_GNUPG_SOCK_DEST $_GNUPG_SOCK_SRC >/dev/null
+        }
+    }
 }
 
 ### load site-specific
 if [[ -f ~/.zshenv.local ]] { source ~/.zshenv.local }
 
+### source .zprofile
+# if we used su, without --login, let's run zprofile ourselves
+# XXX: system zprofile is not run
+if [[ -v _sev_reset_shell || $SHLVL == 1 ]] source ~/.zprofile
+
 # vim: set et sts=4 sw=4 ts=8 tw=79 :
index 090d7fa5c9714b003c4ba58c4474a7818b62ff8c..014b03943e9f690408a7ebf8f22cc2110fc035f8 100644 (file)
@@ -37,12 +37,13 @@ if (( $#terminfo == 0 )) {
     if [[ -n $keymap ]] {
         source $keymap
     } else {
-        echo "Failed to source file $keymap" >&2
+        echo "Failed to source keymap file $keymap" >&2
     }
     unfunction find_keymap; unset keymap
 } else {
     # activate application mode for zle so terminfo keys work
-    # don't do this for zkbd since application mode shouldn't have ben enabled
+    # NOTE: don't do this for zkbd since application mode shouldn't have been
+    #       enabled by zkbd when the keymap file was generated
     if [[ -v terminfo[smkx] && -v terminfo[rmkx] ]] {
         autoload -Uz add-zle-hook-widget
         function _enter-application-mode { echoti smkx }
This page took 0.067529 seconds and 4 git commands to generate.