Parent directory

ssh-agent.plugin.zsh

3619 bytes
  1# Get the filename to store/lookup the environment from
  2ssh_env_cache="$HOME/.ssh/environment-$SHORT_HOST"
  3
  4function _start_agent() {
  5  # Check if ssh-agent is already running
  6  if [[ -f "$ssh_env_cache" ]]; then
  7    . "$ssh_env_cache" > /dev/null
  8
  9    # Test if $SSH_AUTH_SOCK is visible
 10    zmodload zsh/net/socket
 11    if [[ -S "$SSH_AUTH_SOCK" ]] && zsocket "$SSH_AUTH_SOCK" 2>/dev/null; then
 12      return 0
 13    fi
 14  fi
 15
 16  if [[ ! -d "$HOME/.ssh" ]]; then
 17    echo "[oh-my-zsh] ssh-agent plugin requires ~/.ssh directory"
 18    return 1
 19  fi
 20
 21  # Set a maximum lifetime for identities added to ssh-agent
 22  local lifetime
 23  zstyle -s :omz:plugins:ssh-agent lifetime lifetime
 24
 25  # start ssh-agent and setup environment
 26  zstyle -t :omz:plugins:ssh-agent quiet || echo >&2 "Starting ssh-agent ..."
 27  ssh-agent -s ${lifetime:+-t} ${lifetime} | sed '/^echo/d' >! "$ssh_env_cache"
 28  chmod 600 "$ssh_env_cache"
 29  . "$ssh_env_cache" > /dev/null
 30}
 31
 32function _add_identities() {
 33  local id file line sig lines
 34  local -a identities loaded_sigs loaded_ids not_loaded
 35  zstyle -a :omz:plugins:ssh-agent identities identities
 36
 37  # check for .ssh folder presence
 38  if [[ ! -d "$HOME/.ssh" ]]; then
 39    return
 40  fi
 41
 42  # add default keys if no identities were set up via zstyle
 43  # this is to mimic the call to ssh-add with no identities
 44  if [[ ${#identities} -eq 0 ]]; then
 45    # key list found on `ssh-add` man page's DESCRIPTION section
 46    for id in id_rsa id_dsa id_ecdsa id_ed25519 id_ed25519_sk identity; do
 47      # check if file exists
 48      [[ -f "$HOME/.ssh/$id" ]] && identities+=($id)
 49    done
 50  fi
 51
 52  # get list of loaded identities' signatures and filenames
 53  if lines=$(ssh-add -l); then
 54    for line in ${(f)lines}; do
 55      loaded_sigs+=${${(z)line}[2]}
 56      loaded_ids+=${${(z)line}[3]}
 57    done
 58  fi
 59
 60  # add identities if not already loaded
 61  for id in $identities; do
 62    # if id is an absolute path, make file equal to id
 63    [[ "$id" = /* ]] && file="$id" || file="$HOME/.ssh/$id"
 64    # check for filename match, otherwise try for signature match
 65    if [[ -f $file && ${loaded_ids[(I)$file]} -le 0 ]]; then
 66      sig="$(ssh-keygen -lf "$file" | awk '{print $2}')"
 67      [[ ${loaded_sigs[(I)$sig]} -le 0 ]] && not_loaded+=("$file")
 68    fi
 69  done
 70
 71  # abort if no identities need to be loaded
 72  if [[ ${#not_loaded} -eq 0 ]]; then
 73    return
 74  fi
 75
 76  # pass extra arguments to ssh-add
 77  local args
 78  zstyle -a :omz:plugins:ssh-agent ssh-add-args args
 79
 80  # if ssh-agent quiet mode, pass -q to ssh-add
 81  zstyle -t :omz:plugins:ssh-agent quiet && args=(-q $args)
 82
 83  # use user specified helper to ask for password (ksshaskpass, etc)
 84  local helper
 85  zstyle -s :omz:plugins:ssh-agent helper helper
 86
 87  if [[ -n "$helper" ]]; then
 88    if [[ -z "${commands[$helper]}" ]]; then
 89      echo >&2 "ssh-agent: the helper '$helper' has not been found."
 90    else
 91      SSH_ASKPASS="$helper" ssh-add "${args[@]}" ${^not_loaded} < /dev/null
 92      return $?
 93    fi
 94  fi
 95
 96  ssh-add "${args[@]}" ${^not_loaded}
 97}
 98
 99# Add a nifty symlink for screen/tmux if agent forwarding is enabled
100if zstyle -t :omz:plugins:ssh-agent agent-forwarding \
101   && [[ -n "$SSH_AUTH_SOCK" ]]; then
102  if [[ ! -L "$SSH_AUTH_SOCK" ]]; then
103    if [[ -n "$TERMUX_VERSION" ]]; then
104      ln -sf "$SSH_AUTH_SOCK" "$PREFIX"/tmp/ssh-agent-$USERNAME-screen
105    else
106      ln -sf "$SSH_AUTH_SOCK" /tmp/ssh-agent-$USERNAME-screen
107    fi
108  fi
109else
110  _start_agent
111fi
112
113# Don't add identities if lazy-loading is enabled
114if ! zstyle -t :omz:plugins:ssh-agent lazy; then
115  _add_identities
116fi
117
118unset agent_forwarding ssh_env_cache
119unfunction _start_agent _add_identities