ssh-agent.plugin.zsh 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. lockdir=/tmp/oh-my-zsh-ssh-agent.lock
  2. while true; do
  3. if mkdir "$lockdir" 2>/dev/null
  4. then # directory did not exist, but was created successfully
  5. trap 'rm -rf "$lockdir"' 0 # remove directory when script finishes
  6. break # continue with script
  7. else
  8. sleep 0.1 # sleep for 0.2 and try again
  9. fi
  10. done
  11. typeset _ssh_env_cache
  12. function _start_agent() {
  13. local lifetime
  14. zstyle -s :omz:plugins:ssh-agent lifetime lifetime
  15. # start ssh-agent and setup environment
  16. echo Starting ssh-agent...
  17. ssh-agent -s ${lifetime:+-t} ${lifetime} | sed 's/^echo/#echo/' >! $_ssh_env_cache
  18. chmod 600 $_ssh_env_cache
  19. . $_ssh_env_cache > /dev/null
  20. }
  21. function _add_identities() {
  22. local id line sig lines
  23. local -a identities loaded_sigs loaded_ids not_loaded
  24. zstyle -a :omz:plugins:ssh-agent identities identities
  25. # check for .ssh folder presence
  26. if [[ ! -d $HOME/.ssh ]]; then
  27. return
  28. fi
  29. # add default keys if no identities were set up via zstyle
  30. # this is to mimic the call to ssh-add with no identities
  31. if [[ ${#identities} -eq 0 ]]; then
  32. # key list found on `ssh-add` man page's DESCRIPTION section
  33. for id in id_rsa id_dsa id_ecdsa id_ed25519 identity; do
  34. # check if file exists
  35. [[ -f "$HOME/.ssh/$id" ]] && identities+=$id
  36. done
  37. fi
  38. # get list of loaded identities' signatures and filenames
  39. if lines=$(ssh-add -l); then
  40. for line in ${(f)lines}; do
  41. loaded_sigs+=${${(z)line}[2]}
  42. loaded_ids+=${${(z)line}[3]}
  43. done
  44. fi
  45. # add identities if not already loaded
  46. for id in $identities; do
  47. # check for filename match, otherwise try for signature match
  48. if [[ ${loaded_ids[(I)$HOME/.ssh/$id]} -le 0 ]]; then
  49. sig="$(ssh-keygen -lf "$HOME/.ssh/$id" | awk '{print $2}')"
  50. [[ ${loaded_sigs[(I)$sig]} -le 0 ]] && not_loaded+="$HOME/.ssh/$id"
  51. fi
  52. done
  53. local args
  54. zstyle -a :omz:plugins:ssh-agent ssh-add-args args
  55. [[ -n "$not_loaded" ]] && ssh-add "${args[@]}" ${^not_loaded}
  56. }
  57. # Get the filename to store/lookup the environment from
  58. _ssh_env_cache="$HOME/.ssh/environment-$SHORT_HOST"
  59. if zstyle -t :omz:plugins:ssh-agent agent-forwarding && [[ -n "$SSH_AUTH_SOCK" ]]; then
  60. # Add a nifty symlink for screen/tmux if agent forwarding
  61. [[ -L $SSH_AUTH_SOCK ]] || ln -sf "$SSH_AUTH_SOCK" /tmp/ssh-agent-$USERNAME-screen
  62. elif [[ -f "$_ssh_env_cache" ]]; then
  63. # Source SSH settings, if applicable
  64. . $_ssh_env_cache > /dev/null
  65. if [[ $USERNAME == "root" ]]; then
  66. FILTER="ax"
  67. else
  68. FILTER="x"
  69. fi
  70. ps $FILTER | grep ssh-agent | grep -q $SSH_AGENT_PID || {
  71. _start_agent
  72. }
  73. elif [[ -d $HOME/.ssh ]]; then
  74. _start_agent
  75. fi
  76. if ! zstyle -t :omz:plugins:ssh-agent lazy; then
  77. _add_identities
  78. fi
  79. # tidy up after ourselves
  80. unset _ssh_env_cache
  81. unfunction _start_agent _add_identities
  82. rm -rf "$lockdir"