X-Git-Url: https://git.sev.monster/~sev/dotfiles.git/blobdiff_plain/29b45f3cd04fe7f94aaebbd99c4bdbb3f23f98f3..bc7442960295bf9f0b7578aa6086fa349570fb22:/etc/zsh/.zprofile diff --git a/etc/zsh/.zprofile b/etc/zsh/.zprofile index 58ebfa1..3aedb8c 100644 --- a/etc/zsh/.zprofile +++ b/etc/zsh/.zprofile @@ -71,7 +71,7 @@ if [[ ! -v DBUS_SESSION_BUS_ADDRESS && -v commands[dbus-launch] ]] { # clunky (e.g. asking for password twice) to make it worth it. function _gpg_socketpath { # dirs are percent-encoded: https://stackoverflow.com/a/64312099 - echo ${1//(#b)%([[:xdigit:]](#c2))/${(#):-0x$match[1]}} + echo -E - ${1//(#b)%([[:xdigit:]](#c2))/${(#):-0x$match[1]}} } if [[ ! -v _sev_setup_gpg_forward && -v commands[gpg] ]] { # XXX: assuming /tmp exists and is writable on destination @@ -81,34 +81,38 @@ if [[ ! -v _sev_setup_gpg_forward && -v commands[gpg] ]] { export _sev_gpg_forward_dir=$XDG_RUNTIME_DIR/gnupg/.ssh_forward _sev_zcleanup gpg-forward - # find our forwarded socket - s=($_GNUPG_SOCK_DEST_BASE*(N=oc[1])) - if [[ -n $s && -v SSH_CLIENT ]] { - # create new forward dir - export _sev_setup_gpg_forward= - h=$_sev_gpg_forward_dir/$$ - mkdir -pm700 $h - for x (gpg{,-agent}.conf sshcontrol random_seed - pubring.kbx{,~} trustdb.gpg private-keys-v1.d crls.d) { - ln -s ${GNUPGHOME:-~/.gnupg}/$x $h - } - export GNUPGHOME=$h - unset h - for x in $(gpgconf --list-dirs | grep 'agent-.*-\?socket:'); do - x=$(_gpg_socketpath ${x/#agent-*socket:}) - if [[ ! -v primary ]] { - # move forwarded socket to first valid agent socket path - # XXX: if tmp is on different filesystem this may not work - mv $s $x - primary=$x - } else { - # make links to forwarded socket for any others - ln -s $primary $x + # check for a forwarded socket + if [[ -v SSH_CLIENT ]] { + # find newest socket owned by us + # XXX: race condition + s=($_GNUPG_SOCK_DEST_BASE*(N=u[$LOGNAME]oc[1])) + if [[ -n $s ]] { + # create new forward dir + export _sev_setup_gpg_forward= + h=$_sev_gpg_forward_dir/$$ + mkdir -pm700 $h + for x (gpg{,-agent}.conf sshcontrol random_seed + pubring.kbx{,~} trustdb.gpg private-keys-v1.d crls.d) { + ln -s ${GNUPGHOME:-~/.gnupg}/$x $h } - done - unset x primary + export GNUPGHOME=$h + unset h + for x ($(gpgconf --list-dirs | grep 'agent-.*-\?socket:')) { + x=$(_gpg_socketpath ${x/#agent-*socket:}) + if [[ ! -v primary ]] { + # move forwarded socket to first valid agent socket path + # XXX: if tmp is on different filesystem this may not work + mv $s $x + primary=$x + } else { + # make links to forwarded socket for any others + ln -s $primary $x + } + } + unset x primary + } + unset s } - unset s # what we will forward if we start a new ssh connection # NOTE: do this after setting up GNUPGHOME to pick up new socket path; @@ -143,11 +147,9 @@ if [[ -v commands[gpg-connect-agent] && export GPG_TTY=$(tty) if [[ ( -v DISPLAY || -v WAYLAND_DISPLAY ) && ${PINENTRY_USER_DATA/USE_TTY=0} == $PINENTRY_USER_DATA ]] - export PINENTRY_USER_DATA=USE_TTY=0 - # XXX: we are assuming this is our pinentry from .local/bin - sed -Ei 's^([[:space:]]*pinentry-program[[:space:]]).*$\1'$HOME'/.local/bin/pinentry' \ + export PINENTRY_USER_DATA=${${:-${PINENTRY_USER_DATA//USE_TTY=[01] #/} USE_TTY=0}/# ##/} + sed -Ei 's^([[:space:]]*pinentry-program[[:space:]]).*/\.local/bin/pinentry$\1'$HOME'/.local/bin/pinentry' \ ${GNUPGHOME:-~/.gnupg}/gpg-agent.conf 2>/dev/null - # XXX: could check for changes before doing this to save perf gpg-connect-agent RELOADAGENT UPDATESTARTUPTTY /bye >/dev/null 2>&1 if {$p} { gpg-connect-agent /subst /serverpid \ @@ -177,25 +179,31 @@ if [[ ! -v _sev_setup_ssh ]] { if [[ -f $e ]] { IFS=$'\0' read -r sock pid <$e } - if [[ -S $sock && $pid > 0 ]] && kill -0 $pid >/dev/null 2>&1; then + if ([[ -S $sock && $pid > 0 ]] && kill -0 $pid >/dev/null 2>&1) { [[ -o interactive ]] && print -P "Reusing agent PID $pid%f" export SSH_AUTH_SOCK=$sock export SSH_AGENT_PID=$pid - else + } else { + # remove stale socket and dir + if [[ -v $sock ]] { + [[ -e $sock ]] && rm $sock 2>/dev/null + [[ -d ${sock:h} ]] && rmdir ${sock:h} 2>/dev/null + } # TODO: ensure ssh-agent path looks legit to avoid unsafe eval? # XXX: doesn't appear to be any other way to handle redirection. - # because eval needs to write to current scope environment + # because eval needs to write to current environment, # subshells can't be used to capture output and print. c='TMPDIR=$_sev_tmp ${okc}ssh-agent' if [[ -o interactive ]] { + [[ -n $okc ]] && echo -n 'OKC-' eval $(eval $=c) print -nP '%f' } else { eval $(eval $=c) >/dev/null 2>&1 } - echo -n $SSH_AUTH_SOCK$'\0'$SSH_AGENT_PID >!$e + echo -En - $SSH_AUTH_SOCK$'\0'$SSH_AGENT_PID >!$e unset c - fi + } unset okc e sock pid } elif [[ ! -v SSH_AUTH_SOCK && -v commands[gpg] ]] { # since gpg should have been started above, just export and notify @@ -220,5 +228,8 @@ if [[ ! -v _sev_setup_ssh ]] { } unfunction _gpg_socketpath +### plugins +load-plugins zprofile + ### load site-specific load-site-dotfile zprofile