]> git.sev.monster Git - dotfiles.git/commitdiff
in development
authorsev <git@sev.monster>
Sat, 19 Feb 2022 02:13:38 +0000 (20:13 -0600)
committersev <git@sev.monster>
Sat, 19 Feb 2022 02:13:38 +0000 (20:13 -0600)
base/.zlogin
base/.zlogout
base/.zprofile
base/.zsh/functions/Prompts/prompt_arrows_setup
base/.zshenv
base/.zshrc
bin/ykman-oath-reload [new file with mode: 0644]
gpg/gpg-agent.conf
gpg/gpg.conf

index 6fbf5749436d7a4665d75945f21588d8e2e6ab3e..40b4b8a4de66b8448f8f698de3a42738713d0128 100644 (file)
@@ -1,4 +1,4 @@
 ### load site-specific
 if [[ -f ~/.zlogin.local ]] { source ~/.zlogin.local }
 
-# vim: set et sts=4 sw=4 ts=8 tw=79 :
+# vim: et sts=4 sw=4 ts=8 tw=79
index 3b09ce51f1e967e453dc7a8bc7d6dba5499b89f6..1e506117626e1a30a0195859586ac23ca6f2c1d3 100644 (file)
@@ -17,10 +17,13 @@ if [[ $SHLVL == 1 && $GNUPGHOME =~ '.ssh_forward/\d+$' ]] {
     rm -f $_GNUPG_SOCK_DEST_BASE*(N=)
 }
 
+# remove xdg runtime
+rm -rf $XDG_RUNTIME_DIR 2>/dev/null
+
 [[ -o interactive ]] && echo logout
 clear
 
 ### load site-specific
 if [[ -f ~/.zlogout.local ]] { source ~/.zlogout.local }
 
-# vim: set et sts=4 sw=4 ts=8 tw=79 :
+# vim: et sts=4 sw=4 ts=8 tw=79
index 7a7fc107845a46a156892cc754039c35d9ed0038..a6a548fe4d69dc07f8647f478300b345c6317e80 100644 (file)
+# NOTE:
+# our .zprofile is expensive, so we keep track of what has been run already,
+# and only set up what is necessary. additionally, we want to ensure that our
+# environment is set up as early as possible, so we also source .zprofile in
+# .zshenv for new non-login shells.
+#
+# these issues are handled by using these methods:
+#   * the parent shell that starts the user's session after logging in to some
+#     graphical environments may not be a login shell—due to misconfiguration
+#     or otherwise—which means .zprofile is not ran and the environment is not
+#     properly configured for any child processes.
+#   * some desktop environments/graphical terminal emulators will start new
+#     terminal windows with login shells, which runs .zprofile every time and
+#     leads to noticably slow startup times.
+#   * switching users without wiping the environment will result in paths and
+#     variables intended for the old user being used for the new user. while
+#     this may be considered an edge-case that should not be supported, there
+#     are legitimate reasons to want to do this, and in any case the shell
+#     should not choke or cause unexpected problems should it happen anyway.
+
+### detect cygwin
+[[ $OSTYPE =~ (cygwin|msys)* ]] && is_cygwin=
+
 ### exports
-## 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 _backup_path ]] {
-    path=("${_backup_path[@]}" "${path[@]}")
-    export PATH
-    unset _backup_path
+## lang
+export CHARSET=UTF-8
+export LANG=en_US.UTF-8
+export LC_CTYPE=$LANG
+
+## msys2
+if [[ -v MSYSTEM && ! -v _sev_setup_msys2 ]] {
+    # path mangling exclusions for gpg-connect-agent
+    # https://www.gnupg.org/documentation/manuals/gnupg/Controlling-gpg_002dconnect_002dagent.html
+    export MSYS2_ARG_CONV_EXCL="${MSYS2_ARG_CONV_EXCL:+$MSYS2_ARG_CONV_EXCL;}\
+/echo;/let ;/definq;/datafile ;/showdef;/cleardev;/sendfd ;/recvfd;/open ;\
+/close ;/showopen;/serverpid;/sleep;/hex;/nohex;/decode;/nodecode;/subst;\
+/nosubst;/while ;/if ;/end;/run ;/bye;/help"
+    # ssh called from mingw64-git attempts to convert path to Windows, and
+    # causes it to choke. paths are converted to *nix before exporting and
+    # will work if cygwin ssh is installed (default).
+    export MSYS2_ENV_CONV_EXCL=_GNUPG_SOCK_
+    export _sev_setup_msys2=
+}
+
+
+## path
+# NOTE: we utilize the fact that unique arrays keep the first occurrence and
+#       remove any further occurences to capture elements from the old PATH
+#       that we did not anticipate and shift them to the front, since they are
+#       probably important to the system
+if [[ ! -v _sev_setup_path || -o login ]] {
+    typeset -a winpath
+    if [[ -v is_cygwin ]] {
+        windir=$(cygpath -uW)
+        sysdir=$(cygpath -uS)
+        winpath=($sysdir $windir $sysdir/Wbem
+                 $sysdir/WindowsPowerShell/v1.0
+                 $sysdir/../SysWOW64 $sysdir/../SysWOW64/Wbem
+                 $sysdir/../SysWOW64/WindowsPowerShell/v1.0)
+        for (( i = 1; i <= $#winpath; i++ )) {
+            winpath[$i]=${winpath[$i]:a}
+        }
+        unset windir sysdir
+    }
+    typeset -U path fpath
+    # add as many generic paths as possible to keep the order we want
+    # NOTE: /usr/{local,pkg,games} are unix/bsdisms
+    syspath=("$path[@]")
+    path=({~/,/,/usr/}sbin /opt/{s,}bin /usr/local/{s,}bin /usr/pkg/{s,}bin
+          /usr/X11R{7,6}/bin /usr/games {~/,/,/usr/}bin)
+    ((ulen=$#path))
+    [[ -v is_cygwin ]] && path=("$path[@]" "$winpath[@]")
+    ((wlen=$#path))
+    path=("$path[@]" "$syspath[@]")
+    # remove nonexistent and duplicate paths
+    for (( i = 1; i <= $#path; i++ )) {
+        if [[ ! -e $path[$i] ]] {
+            path[$i]=()
+            ((i <= ulen)) && ((ulen--))
+            ((i <= wlen)) && ((wlen--))
+            ((i--))
+            continue
+        }
+        if [[ ! -v is_cygwin ]] || (( i <= ulen )) { continue }
+        # Windows only: remove cygwin-ified duplicates case-insensitively
+        c=$(cygpath -u -- ${(L)path[$i]})
+        for (( j = i + 1; j <= $#path; j++ )) {
+            if [[ $c == $(cygpath -u -- ${(L)path[$j]}) ]] {
+                path[$j]=()
+                # NOTE: likelihood of our defined windows path being duplicate
+                #       is low, but just in case
+                ((j <= wlen)) && ((wlen--))
+                ((j--))
+            }
+        }
+        unset c
+    }
+    (( wlen > 0 )) && path=("${(@)path[wlen + 1, -1]}" "${(@)path[1, wlen]}")
+    unset winpath syspath ulen wlen i j
+    # include our zsh dir in fpath. unlike above, we always prefer our paths
+    fpath=(${ZDOTDIR:-~/.zsh}/functions/{*,Completions/*}(N) "$fpath[@]")
+    # FPATH is not exported by default
+    export FPATH
+    typeset +U path fpath
+    export _sev_setup_path=
+}
+
+## xdg
+if [[ ! -v _sev_setup_xdg ]] {
+    # merge with any existing dirs and remove duplicates using unique arrays
+    # NOTE: include and then remove .config and .local/share to ensure it is
+    #       not present in the array if it was added before we got to it
+    typeset -UT XDG_CONFIG_DIRS xdg_config_dirs
+    typeset -UT XDG_DATA_DIRS xdg_data_dirs
+    export XDG_CONFIG_HOME=$HOME/etc
+    xdg_config_dirs=($XDG_CONFIG_HOME $HOME/.config
+      {/opt,/usr/local,/usr/pkg,}/etc/xdg
+      "${XDG_CONFIG_DIRS:+${xdg_config_dirs[@]}}")
+    export XDG_CONFIG_DIRS=${XDG_CONFIG_DIRS#$XDG_CONFIG_HOME}
+    export XDG_DATA_HOME=$HOME/share
+    xdg_data_dirs=($XDG_DATA_HOME $HOME/.local/share
+      /{opt,usr/local,usr/pkg,usr}/share
+      "${XDG_DATA_DIRS:+${xdg_data_dirs[@]}}")
+    export XDG_DATA_DIRS=${XDG_DATA_DIRS#$XDG_DATA_HOME}
+    # use our custom tmp for cache and runtime
+    export XDG_CACHE_HOME=~/tmp
+    # NOTE: it's intentional to keep the same runtime dir for the whole session
+    #       and not create a new one if a new login shell is spawned, since the
+    #       spec calls for the same dir to be utilized for each "session".
+    export XDG_RUNTIME_DIR=~/tmp/xdg.$$
+}
+
+## temp
+if [[ ! -v _sev_setup_tmp ]] {
+    t=${TMPDIR:-${TEMP:-${TMP:-/tmp}}}/.home-$LOGNAME
+    if [[ ! -e $t ]] {
+        mkdir -m700 $t 2>/dev/null
+        if [[ ! -d $t ]] {
+            [[ -o interactive ]] &&
+              print -P "%F{red}!!! Can't create temp folder $t%f"
+            # fallback bare directories
+            [[ -h $XDG_CACHE_HOME ]] && unlink $XDG_CACHE_HOME 2>/dev/null
+            [[ ! -e $XDG_CACHE_HOME ]] && mkdir -m700 $XDG_CACHE_HOME 2>/dev/null
+        }
+    }
+    if [[ -e $t ]] {
+        export TMPDIR=$t TEMP=$t TMP=$t
+        # [re-]create link to our tmp if safe
+        [[ -h $XDG_CACHE_HOME || ! -e $XDG_CACHE_HOME ]] &&
+          ln -sf $t $XDG_CACHE_HOME 2>/dev/null
+    } else {
+        # ensure proper tmp vars, e.g. msys2 does not set TMPDIR
+        : ${TMPDIR:=${TEMP:-${TMP:-/tmp}}}
+        : ${TEMP:=$TMPDIR}
+        : ${TMP:=$TMPDIR}
+    }
+    unset t
+    export _sev_setup_tmp=
+}
+
+## xdg
+if [[ ! -v _sev_setup_xdg ]] {
+    # create xdg runtime dir
+    # NOTE: spec says the dir should only exist for the lifetime of the
+    #       session, so if there is already something there it is likely stale
+    #       or something is very broken—assume the former.
+    [[ -e $XDG_RUNTIME_DIR ]] && rm -rf $XDG_RUNTIME_DIR 2>/dev/null &&
+      mkdir -m700 $XDG_RUNTIME_DIR 2>/dev/null
+    # source user dirs after other vars
+    [[ -e $XDG_CONFIG_HOME/user-dirs.dirs ]] &&
+      emulate sh -c "source $XDG_CONFIG_HOME/user-dirs.dirs"
+    export _sev_setup_xdg=
 }
-## common
-export EDITOR=vim
-export PAGER=less
-## grep
-# XXX: deprecated in GNU
-export GREP_OPTIONS=--color=auto
-## histfile
-export HISTFILE=~/.histfile
-export HISTSIZE=1000
-export SAVEHIST=1000
-## python
-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)
-
-### load site-specific
+
+## gpg forwarding
+# NOTE: while ssh manages its auth sock in its protocol when ForwardSsh is
+#       enabled, GPG must be forwarded manually over Unix socket. to support
+#       this, we forward the restricted gpg-agent extra socket to the remote
+#       host with a RemoteForward rule in ~/.ssh/config that uses the
+#       _GNUPG_SOCK_* env vars. to avoid conflicts with other ssh sessions
+#       where the same user is connecting to the same host from different
+#       machines, gpg in each environment should utilize its own forwarded
+#       socket, rather than replace the sockets in GNUPGHOME which will be
+#       overridden on the next connection. previously, you could provide a path
+#       to the agent socket in GPG_AGENT_INFO, but that was deprecated in GPG
+#       v2.1. instead, we must clone GNUPGHOME and replace the agent sockets
+#       there with the forwarded one.
+# NOTE: since Unix sockets are not supported under Windows, this will not work
+#       under msys, cygwin, mingw, etc.
+# HACK: without SendEnv, which is disabled by default in most sshd configs,
+#       there is no foolproof way to prevent race conditions via filename
+#       collisions or to pass the desired forward path to the remote host
+#       environment. we just have to guess the path we choose is good on the
+#       desination, and assume the newest matching socket is the correct one
+#       after connecting. in theory, we could occlude the ssh binary on PATH
+#       with an alias or script that would allow us to communicate with the
+#       remote host before opening a shell, so that we can have the host
+#       communicate back to the client where it wants a socket created or ask
+#       the host if the path the client wants to use is writable. however, this
+#       would open up too many edge cases where it wouldn't work or be clunky
+#       (e.g. asking for password twice) to make it worth it.
+if [[ ! -v _sev_setup_gpg ]] {
+    # helper function for decoding gpgconf socket paths
+    function _socketpath {
+        # dirs are percent-encoded
+        # https://stackoverflow.com/a/64312099
+        local x=${1//(#b)%([[:xdigit:]](#c2))/${(#):-0x$match[1]}}
+        # remove \r from Windows paths
+        if [[ -v commands[cygpath] ]] {
+            x=$(cygpath -u -- ${x/%$'\r'} 2>/dev/null)
+        }
+        echo $x
+    }
+
+    if [[ ! -v _sev_gpg_forwarded && -v commands[gpg] ]] {
+        export _GNUPG_SOCK_DEST_BASE=/tmp/.gpg-agent-forward
+        export _GNUPG_SOCK_DEST_EXT=$(date +%s).$RANDOM
+        export _GNUPG_SOCK_DEST=$_GNUPG_SOCK_DEST_BASE.$_GNUPG_SOCK_DEST_EXT
+        export _sev_gpg_forward_dir=${GNUPGHOME:-~/.gnupg}/.ssh_forward
+        # clean up forwards if its session is dead or we ask for it
+        if [[ -d $_sev_gpg_forward_dir ]] {
+            find $_sev_gpg_forward_dir -type d -mindepth 1 -maxdepth 1 |
+              while read -r x; do
+                # NOTE: the only way we can get here is if we have not been
+                #       forwarded before. if our own pid already has a dir, it
+                #       is most likely stale, or something is very broken—
+                #       assume the former.
+                p=$(basename $x)
+                if [[ -v _sev_gpg_forward_clean || $$ == $p ]] ||
+                      ! kill -0 $p 2>/dev/null; then
+                    find $x -mindepth 1 -maxdepth 1 | while read -r y; do
+                        unlink $y
+                    done
+                    rmdir $x
+                fi
+            done
+            unset x p y
+        }
+
+        # find our forwarded socket
+        s=($_GNUPG_SOCK_DEST_BASE*(N=oc[1]))
+        if [[ -n $s && -v SSH_CLIENT ]] {
+            # create new forward dir
+            export _sev_gpg_forwarded=
+            mkdir -pm700 $_sev_gpg_forward_dir
+            h=$_sev_gpg_forward_dir/$$
+            mkdir -pm700 $h
+            # XXX: is it safe to link scdaemon socket? can its name be changed?
+            for x in S.scdaemon gpg.conf gpg-agent.conf sshcontrol \
+                     pubring.kbx trustdb.gpg private-keys-v1.d crls.d; do
+                ln -s ${GNUPGHOME:-~/.gnupg}/$x $h
+            done
+            export GNUPGHOME=$h
+            unset h
+            for x in $(gpgconf --list-dirs | grep 'agent-.*-\?socket:'); do
+                x=$(_socketpath ${x/#agent-*socket:})
+                if [[ ! -v orig ]] {
+                    mv $s $x
+                    orig=$x
+                } else {
+                    ln -s $orig $x
+                }
+            done
+            unset x orig
+        }
+        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;
+        #       if already connected over SSH, extra should be the remote one
+        export _GNUPG_SOCK_SRC=$(_socketpath \
+          $(gpgconf --list-dirs agent-extra-socket))
+    } else {
+        # required for RemoteForward to not error out if the vars are unset
+        [[ ! -v _GNUPG_SOCK_SRC ]] && export _GNUPG_SOCK_SRC=/nonexistent
+        [[ ! -v _GNUPG_SOCK_DEST ]] && export _GNUPG_SOCK_DEST=/nonexistent
+    }
+
+    ## gpg agent
+    if [[ -v commands[gpg-connect-agent] ]] {
+        [[ -o interactive ]] && print -nP '%F{blue}>>>%f GPG agent: %F{green}'
+        gpg-connect-agent /bye >/dev/null 2>&1
+        if [[ $? -ne 0 ]] {
+            [[ -o interactive ]] &&
+              print -P '%F{red}Error communicating with GPG agent%f'
+        } elif [[ ! -v _sev_gpg_forward && ! -v GPG_TTY &&
+                  ( -o interactive || -v DISPLAY ) ]] {
+            # if we aren't forwarded, set up tty if it isn't and we're
+            # in an interactive session
+            export GPG_TTY=$(tty)
+            export PINENTRY_USER_DATA=USE_TTY=$((!${+DISPLAY}))
+            gpg-connect-agent UPDATESTARTUPTTY /bye >/dev/null 2>&1
+            [[ -o interactive ]] &&
+              print -P "Updated TTY%f"
+        } else {
+            [[ -o interactive ]] &&
+              print -P 'Ready%f'
+        }
+    }
+
+    ## ssh agent
+    # NOTE: preferred order of agents to check: okcagent, gnupg, openssh
+    #       first block takes care of okcagent and openssh, second gnupg
+    [[ -o interactive ]] && 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
+            [[ -o interactive ]] && print -P "Reusing agent PID $pid%f"
+            export SSH_AUTH_SOCK=$sock
+            export SSH_AGENT_PID=$pid
+        else
+            e=${okc}ssh-agent
+            # 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
+            #      subshells can't be used to capture output and print.
+            if [[ -o interactive ]] {
+                eval `$e`
+                print -nP '%f'
+            } else {
+                eval `$e` >/dev/null 2>&1
+            }
+            echo -n $SSH_AUTH_SOCK$'\0'$SSH_AGENT_PID >!$agentfile
+        fi
+        unset okc agentfile sock pid
+    } elif [[ ! -v SSH_AUTH_SOCK && -v commands[gpg] ]] {
+        # since gpg agent was started above, we just have to export and notify
+        if [[ -o interactive ]] {
+            if [[ -v _sev_gpg_forwarded ]] {
+                echo 'Remote GPG agent'
+            } else {
+                gpg-connect-agent /subst /serverpid \
+                  '/echo GPG agent PID ${get serverpid}' /bye
+            }
+            print -nP '%f'
+        }
+        export SSH_AUTH_SOCK=$(_socketpath \
+          $(gpgconf --list-dirs agent-ssh-socket))
+    } elif [[ -v SSH_AUTH_SOCK ]] {
+        [[ -o interactive ]] && print -P 'Preconfigured agent%f'
+    } else {
+        [[ -o interactive ]] && print -P '%F{red}No agent available%f'
+    }
+
+    ## cleanup
+    # unset gpg helper
+    unfunction _socketpath
+
+    ## perl local lib
+    [[ -v commands[perl] && -d $XDG_DATA_HOME/perl5/lib/perl5 ]] &&
+      eval $(perl -I$XDG_DATA_HOME/perl5/lib/perl5
+                  -Mlocal::lib=$XDG_DATA_HOME/perl5 2>/dev/null)
+}
+
+unset is_cygwin
+
+# load site-specific
 if [[ -f ~/.zprofile.local ]] { source ~/.zprofile.local }
 
-# vim: set et sts=4 sw=4 ts=8 tw=79 :
+# vim: et sts=4 sw=4 ts=8 tw=79
index 08f364689082832902ed93eedd0a4e8b7c8bea3d..8719a121b9f49d24c04b15fbfaf785a0cd01fe97 100644 (file)
@@ -22,33 +22,36 @@ EOF
 local prompt_arrows_vimode=
 
 function prompt_arrows_setup() {
+    prompt_opts=( cr sp percent subst )
+
+
     # TODO: check for color terminal. never will use B&W term but still a XXX
-    local n p _p s r c d u
+    local m n p s r c d u
     #TODO remove n?
-    m="${1:-2line}"         # Mode
-    n="${2:-white}"         # Normal
-    p="${3:-green}"         # Prompt
-    s="${4:-random}"        # Ssh prompt
-    r="${5:-red}"           # uRgent
-    c="${6:-blue}"          # Comment
-    d="${7:-yellow}"        # Dir
-    u="${8:-darkyellow}"    # Unwritable
+    m=${1:-2line}      # Mode
+    n=${2:-white}      # Normal
+    p=${3:-green}      # Prompt
+    s=${4:-random}     # Ssh prompt
+    r=${5:-red}        # uRgent
+    c=${6:-blue}       # Comment
+    d=${7:-yellow}     # Dir
+    u=${8:-darkyellow} # Unwritable
 
     # [AC]CURSED COMMAND
     # concatenate the numerical values of each letter of the hostname,
     # moduloing by the number of possible colors.
-    generated=$(uname -n | od -An -td1 | awk -F' ' \
-      "{for (i=1; i<=NF; i++) {sum+=1; sum*=\$i; sum%=`echotc Co`} print sum}")
-    [[ "$p" = 'random' ]] && p=$generated
-    [[ "$s" = 'random' ]] && s=$generated
+    local generated=$(uname -n | od -An -td1 | awk -F' ' \
+      "{for (i=1; i<=NF; i++) {sum+=1; sum*=\$i; sum%=$(echotc Co)} print sum}")
+    [[ $p = random ]] && p=$generated
+    [[ $s = random ]] && s=$generated
 
     # use ssh color if connected
-    p="${${SSH_CLIENT+$s}:-$p}"
+    [[ -v SSH_CLIENT ]] && p=$s
 
     local clock="%F{$n}%T%f" dirvcs="%F{$d}"'${vcs_info_msg_0_:-%~}'"%f"
     # XXX: linux only
     local battery=/sys/class/power_supply/BAT0/capacity
-    [[ -e "$battery" ]] && clock+=" `cat $battery`%%"
+    [[ -e "$battery" ]] && clock+=' $(cat $battery)%%'
     local vicol='%F{${${prompt_arrows_vimode:+'"$r"'}:-'"$c"'}}'
     local hist="%F{$n}%h"
     case "$m" {
@@ -66,7 +69,7 @@ function prompt_arrows_setup() {
             ;;
     }
     PROMPT="$PROMPT%(1j,%F{$c}%j,)$vicol%#%F{$p}%n%F{$n}@%F{$p}%2m%(?..%F{$n}/%F{$r}\$?)%F{$n}: "
-    POSTEDIT="`print -P "%F{$n}%f"`"
+    POSTEDIT="$(print -P "%F{$n}%f")"
     autoload -Uz vcs_info
     zstyle ':vcs_info:git*' formats "%c%u%%F{$p}%r/%b%%F{$n}/%%F{$d}%S%%f"
     zstyle ':vcs_info:git*' actionformats "%%F{$r}(%a)%f %c%u%%F{$p}%r/%b%f/%%F{$d}%S%f"
@@ -95,5 +98,17 @@ function prompt_arrows_preexec {
     print -Pn "%F{red}<<<%f "
 }
 
+function prompt_arrows_preview {
+  if (( ! $#* )); then
+    prompt_preview_theme arrows 2line
+    print '\n'
+    prompt_preview_theme arrows right
+    print
+  else
+    prompt_preview_theme arrows "$@"
+    print
+  fi
+}
+
 prompt_arrows_setup "$@"
 # vim: set et fenc=utf-8 ft=zsh sts=4 sw=4 ts=8 tw=0 :
index 11cded74897d2df05e3a1329a9c398ca0d02d795..7787a934df3697fd6120c99051a40ed0e73714c4 100644 (file)
-# WARN: not used in this repo, but gpgconf --list-dirs does not read
-#       gpg-agent.conf to get socket path, see dev.gnupg.org/T3108
-
-### 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
-
-    ## path
-    # path and fpath should already be linked to PATH and FPATH
-    # we don't want duplicates so turn on unique mode if it isn't already
-    typeset -U path fpath
-    # do not run more than once per session, even if resetting shell
-    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
-    path=({~/,/,/usr/}sbin {~/,/,/usr/}bin /usr/pkg/{s,}bin /usr/X11R{7,6}/bin
-          /usr/local/{s,}bin /usr/games)
-    PATH=$PATH:$_sev_sys_PATH
-    fpath=(${ZDOTDIR:-$HOME/.zsh}/functions/{*,Completions/*}(N))
-    # fpath is not exported by default
-    export FPATH=$FPATH:$_sev_sys_FPATH
-    # take another backup, explained in .zprofile
-    typeset -U _backup_path
-    _backup_path=("${path[@]}")
-
-    ## xdg
-    # TODO: check for and merge existing XDG env vars
-    export XDG_CONFIG_HOME=~/etc
-    export XDG_CONFIG_DIRS=~/.config:/usr/pkg/etc/xdg:/usr/local/etc/xdg:/etc/xdg
-    export XDG_DATA_HOME=~/share
-    export XDG_DATA_DIRS=~/.local/share:/usr/pkg/share:/usr/local/share:/usr/share
-    export XDG_CACHE_HOME=~/tmp
-    export XDG_RUNTIME_DIR=~/tmp
-    if [[ -e $XDG_CONFIG_HOME/user-dirs.dirs ]] {
-        source $XDG_CONFIG_HOME/user-dirs.dirs
-    }
-
-    ## create tmp link
-    t=${TMPDIR:-/tmp}/.home-$LOGNAME
-    if [[ ! -e $t ]] {
-        mkdir -m 700 $t 2>/dev/null
-        if [[ ! -d $t ]] {
-            [[ -o interactive ]] &&
-              print -P "%F{red}!!! Can't create temp folder $t%f"
-            [[ -h $XDG_RUNTIME_DIR ]] && unlink $XDG_RUNTIME_DIR 2>/dev/null
-            [[ ! -e $XDG_RUNTIME_DIR ]] && mkdir $XDG_RUNTIME_DIR 2>/dev/null
-        }
-    }
-    # allow opaque entries to override link creation
-    [[ ! -e $XDG_RUNTIME_DIR ]] && ln -sf $t $XDG_RUNTIME_DIR 2>/dev/null
-    unset t
-
-    ## gpg forwarding
-    # NOTE: while ssh automatically sets SSH_AUTH_SOCK with the ForwardSsh
-    #       directive, GPG must be forwarded manually. to support this, we
-    #       forward the restricted gpg-agent extra socket to the remote host
-    #       with a RemoteForward rule in ~/.ssh/config that uses the
-    #       _GNUPG_SOCK_* env vars.
-    #       to avoid conflicts with other ssh sessions where the same user is
-    #       connecting to the same host from different machines, gpg in each
-    #       environment should utilize its own forwarded socket, rather than
-    #       replace the sockets in GNUPGHOME which will be overridden on the
-    #       next connection. previously, you could provide a path to the agent
-    #       socket in GPG_AGENT_INFO, but that was deprecated in GPG v2.1.
-    #       instead, we must clone GNUPGHOME and replace the agent sockets
-    #       there with the forwarded one.
-    # HACK: without SendEnv, which is disabled by default in most sshd configs,
-    #       there is no foolproof way to prevent race conditions or filename
-    #       collisions, pass the forward path to the remote host environment,
-    #       or even know if the forward path exists and is writable. we just
-    #       have to guess this path is good on the desination host, and assume
-    #       the newest matching socket is the correct one after connecting. in
-    #       theory we could occlude the ssh binary on PATH with an alias or
-    #       script that communicates with the remote host before opening a
-    #       shell, but that would open up too many edge cases where it wouldn't
-    #       work to make it worth the effort and extra overhead.
-    # do not run more than once per session, even if resetting shell
-    if [[ $SHLVL == 1 && -v commands[gpg] ]] {
-        export _GNUPG_SOCK_DEST_BASE=/tmp/.gpg-agent-forward
-        export _GNUPG_SOCK_DEST_EXT=$(date +%s).$RANDOM
-        export _GNUPG_SOCK_DEST=$_GNUPG_SOCK_DEST_BASE.$_GNUPG_SOCK_DEST_EXT
-        _sev_gpg_forward_dir=${GNUPGHOME:-~/.gnupg}/.ssh_forward
-        s=($_GNUPG_SOCK_DEST_BASE*(N=oc[1]))
-        # clean up forwards if its session is dead or we ask for it
-        if [[ -d $_sev_gpg_forward_dir ]] {
-            find $_sev_gpg_forward_dir -type d -mindepth 1 -maxdepth 1 |
-              while read -r x; do
-                # NOTE: the only way we can get here is if we are SHLVL 1. if
-                #       our own pid already has a dir, it is most likely stale,
-                #       or something is very broken—assume the former.
-                p=$(basename $x)
-                if [[ -v _sev_gpg_forward_clean || $$ == $p ]] ||
-                      ! kill -0 $p 2>/dev/null; then
-                    find $x -mindepth 1 -maxdepth 1 | while read -r y; do
-                        unlink $y
-                    done
-                    rmdir $x
-                fi
-            done
-            unset x p y
-        }
-        # create new forward dir
-        if [[ -n $s && -v SSH_CLIENT ]] {
-            export _sev_gpg_forwarded=
-            mkdir -pm700 $_sev_gpg_forward_dir
-            h=$_sev_gpg_forward_dir/$$
-            mkdir -pm700 $h
-            # XXX: is it safe to link scdaemon socket? can its name be changed?
-            for x in S.scdaemon gpg.conf gpg-agent.conf sshcontrol \
-                     pubring.kbx trustdb.gpg private-keys-v1.d crls.d; do
-                ln -s ${GNUPGHOME:-~/.gnupg}/$x $h
-            done
-            export GNUPGHOME=$h
-            unset h
-            for x in $(gpgconf --list-dirs | grep 'agent-.*-\?socket:'); do
-                # dirs are prefixed and percent-encoded—strip and decode
-                # https://stackoverflow.com/a/64312099
-                x=${${x/#agent-*socket:/}//(#b)%([[:xdigit:]](#c2))/${(#):-0x$match[1]}}
-                if [[ ! -v orig ]] {
-                    mv $s $x
-                    orig=$x
-                } else {
-                    ln -s $orig $x
-                }
-            done
-            unset x orig
-        }
-        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;
-        #       if already connected over SSH, extra should be the remote one
-        export _GNUPG_SOCK_SRC=$(gpgconf --list-dirs agent-extra-socket)
-    } else {
-        # required for RemoteForward to not error out if the vars are unset
-        export _GNUPG_SOCK_SRC=/nonexistent
-        export _GNUPG_SOCK_DEST=/nonexistent
-    }
-
-    ## gpg agent
-    # always try to start agent during setup
-    if [[ SHLVL == 1 ]] {
-        gpg-connect-agent /bye >/dev/null 2>&1
-        [[ $? -ne 0 && -o interactive ]] &&
-          print -P "%F{red}!!! Can't communicate with GPG agent%f"
-    }
-    # set up tty if it isn't, and we're interactive or in xorg & not forwarded
-    # do not run more than once per session, even if resetting shell
-    if [[ -v commands[gpg-connect-agent] &&
-          ! -v _sev_gpg_forward && ! -v GPG_TTY &&
-          ( -o interactive || -v DISPLAY ) ]] {
-        export GPG_TTY=$(tty)
-        export PINENTRY_USER_DATA=USE_TTY=$((!${+DISPLAY}))
-        gpg-connect-agent UPDATESTARTUPTTY /bye >/dev/null 2>&1
-    }
-
-    ## ssh agents
-    # NOTE: preferred order of agents to check: okcagent, gnupg, openssh
-    #       first block takes care of okcagent and openssh, second gnupg
-    [[ -o interactive ]] && 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
-            [[ -o interactive ]] && 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?
-            # NOTE: no way around doing redirection like this I think
-            e=${okc}ssh-agent
-            if [[ -o interactive ]] {
-                eval `$e`
-            } else {
-                eval `$e` >/dev/null 2>&1
-            }
-            echo -n $SSH_AUTH_SOCK$'\0'$SSH_AGENT_PID >!$agentfile
-        fi
-        unset okc agentfile sock pid
-    } elif [[ ! -v SSH_AUTH_SOCK && -v commands[gpg] ]] {
-        # since gpg agent was started above, we just have to export and notify
-        if [[ -o interactive ]] {
-            if [[ -v _sev_gpg_forwarded ]] {
-                echo 'Remote GPG agent'
-            } else {
-                gpg-connect-agent /subst /serverpid \
-                  '/echo GPG agent PID ${get serverpid}' /bye
-            }
-        }
-        export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
-    } elif [[ -v SSH_AUTH_SOCK ]] {
-        [[ -o interactive ]] && echo "Preconfigured agent"
-    } else {
-        [[ -o interactive ]] && print -P "%F{red}No agent available"
+# load site-specific
+[[ -f ~/.zshenv.local ]] && source ~/.zshenv.local
+
+# manually source .zprofile if we're not a login shell and it's a good idea
+# see comments in .zprofile for rationale
+if [[ ! -o login ]] {
+    if [[ -v _sev_olduser && $_sev_olduser != $USERNAME ]] {
+        # set up some user-dependent stuff since we switched users
+        _sev_switched_users= source ${ZDOTDIR:-~}/.zprofile
+    } elif [[ $SHLVL == 1 ]] {
+        # ensure profile is loaded for toplevel shells; should hopefully be 1
+        # under Xorg or cron, which is where this would be most useful
+        source ${ZDOTDIR:-~}/.zprofile
     }
 }
+export _sev_olduser=$USERNAME
 
-
-### 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 :
+# vim: et sts=4 sw=4 ts=8 tw=79
index 7890dad50a8c7deb67f479731babfd4e590a362a..488abbd206fa220168ba89e6bd74b8680cd62996 100644 (file)
@@ -4,24 +4,39 @@ setopt NO_BEEP NO_CLOBBER
 setopt AUTO_CD CDABLE_VARS
 ## completion
 setopt GLOB_COMPLETE
-## line
+## globbing
 setopt EXTENDED_GLOB GLOB_DOTS MARK_DIRS NOMATCH NUMERIC_GLOB_SORT
-## prompt
-setopt PROMPT_SUBST
 ## jobs
-setopt AUTO_CONTINUE
+setopt AUTO_CONTINUE LONG_LIST_JOBS
 ## history
 setopt NO_HIST_SAVE_BY_COPY HIST_IGNORE_DUPS SHARE_HISTORY HIST_REDUCE_BLANKS
 
+### imports
+autoload -Uz zmv
+autoload -Uz zmathfunc && zmathfunc
+
+### exports
+## common
+export EDITOR=vim
+export PAGER=less
+## grep
+# XXX: deprecated in GNU
+export GREP_OPTIONS=--color=auto
+## histfile
+export HISTFILE=~/.histfile
+export HISTSIZE=1000
+export SAVEHIST=1000
+## python
+export PYTHONSTARTUP=~/.pythonrc
+
 ### keys
-# TODO: investigate "^[[200~" bracketed-paste
 bindkey -v
 KEYTIMEOUT=10
 ## populate key array
 if (( $#terminfo == 0 )) {
     # terminfo is not set or empty
     function find_keymap {
-        for f in ${ZDOTDIR:-$HOME}/.zkbd/${TERM}{-${DISPLAY:-${VENDOR}-${OSTYPE}},}
+        for f in ${ZDOTDIR:-$HOME}/.zkbd/$TERM{-${DISPLAY:-$VENDOR-$OSTYPE},}
             [[ -f $f ]] && keymap=$f && break
     }
     find_keymap
@@ -122,8 +137,8 @@ if [[ "$OSTYPE" =~ '^(free|net)bsd' ]] {
 } else {
     alias ll='ls -lAFh'
 }
-alias p="${PAGER:-more}" # TODO: make sure more is there or use alternate
-alias e="${EDITOR:-vi}"  # TODO: make sure vi is there or use alternate
+alias p=${PAGER:-more} # TODO: make sure more is there or use alternate
+alias e=${EDITOR:-vi}  # TODO: make sure vi is there or use alternate
 alias se=sudoedit
 # be paranoid
 alias cp='cp -ip'
@@ -136,11 +151,11 @@ if [[ "$OSTYPE" =~ '^freebsd' ]] {
     alias rm='rm -i'
 }
 ## py venv
-alias va="source bin/activate"
-alias vd="deactivate"
+alias va='source bin/activate'
+alias vd=deactivate
 ## ps
 source ~/bin/.check-busybox
-if which pstree >/dev/null 2>&1 && ! check-busybox pstree; then
+if [[ -v commands[pstree] ]] && ! check-busybox pstree; then
     # use pstree, but NOT busybox pstree because it kinda sucks
     ps="pstree -wg3"
 elif [[ "$OSTYPE" =~ '^freebsd' ]]; then
@@ -163,7 +178,7 @@ if [[ "$(basename "$PAGER")" = "less" ]] {
 } else {
     ps="$ps | \"${PAGER:-more}\""
 }
-alias pa="$ps"
+alias pa=$ps
 alias spa="sudo $ps"
 unset ps
 
@@ -172,6 +187,7 @@ unset ps
 function up {
     cd $(printf '../%.0s' {1..${1:-1}})
 }
+alias u=up
 ## zoxide
 [[ -v commands[zoxide] ]] && eval "$(zoxide init zsh)"
 
@@ -208,7 +224,7 @@ function sev_chpwd {
 add-zsh-hook chpwd sev_chpwd
 
 ### system-specific configs and aliases
-case "$OSTYPE"; in
+case $OSTYPE; in
     freebsd*)
         # colors
         export CLICOLOR=
@@ -291,4 +307,4 @@ prompt arrows
 ### load site-specific
 if [[ -f ~/.zshrc.local ]] { source ~/.zshrc.local }
 
-# vim: set et sts=4 sw=4 ts=8 tw=79 :
+# vim: et sts=4 sw=4 ts=8 tw=79
diff --git a/bin/ykman-oath-reload b/bin/ykman-oath-reload
new file mode 100644 (file)
index 0000000..0d6d709
--- /dev/null
@@ -0,0 +1,17 @@
+#!/bin/zsh
+read -s 'p?Password:'$'\n'
+typeset -a oath
+echo OATH URIs:
+while read -r x; do
+    [[ -z $x ]] && break
+    oath+=($x)
+done
+for x in $(ykman list --serials); do
+    ykman -d $x oath accounts list -Hp $p | while read -r y; do
+        ykman -d $x oath accounts delete -fp $p ${y/%$'\r'}
+    done
+    for y in "$oath[@]"; do
+        ykman -d $x oath accounts uri -fp $p $y
+    done
+done
+# vim: sts=4 sw=4 et
index 95a2898ca57e45a7f8e066cf4b35ad5e9e3580e8..52034d517a4f4a0d2881f30ba2f795ba51d60456 100644 (file)
@@ -1,2 +1,2 @@
 enable-ssh-support
-pinentry-program /home/sev/bin/pinentry
+enable-putty-support
\ No newline at end of file
index a883cf586f597cfd6cfc5f9a4fccfd62e7b6271d..ab337e476e67aaba8786f95526ba15576e6d4701 100644 (file)
@@ -11,7 +11,7 @@ s2k-cipher-algo AES256
 
 # general
 expert
-charset utf-8
+display-charset utf-8
 use-agent
 default-key 0x747327ED5BA43ED5
 trusted-key 0x747327ED5BA43ED5
This page took 0.072328 seconds and 4 git commands to generate.