ssh-add.zsh 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. # Standardize location of the ssh-agent authentication socket.
  2. # Perform automatic ssh-agent starting and key-loading as necessary.
  3. #
  4. # The `SSH_AUTH_SOCK` variable allows users interact with ssh-agent loaded
  5. # identities. Having this socket linked to a predictable place means a given
  6. # user can expect loaded identities to persist:
  7. # - in tmux, screen and similar multiplexers
  8. # - through `sudo su`/`su` to root (BUT NOT with '-' which clears envvars)
  9. # The script automatically loads identities based on the `ID_FILES` variable
  10. # below. This can be modified to suit a user's own array of keys. Users are,
  11. # however, encouraged to maintain as few keys as possible, even just One - and
  12. # for that, one of the standard names should do e.g. id_rsa.
  13. ID_FILES=(~/.ssh/id_rsa ~/.ssh/id_dsa ~/.ssh/id_ecdsa ~/.ssh/identity)
  14. function agent_setup() {
  15. # Try to reach an existing socket.
  16. linksocket
  17. # If that does not work, try to reach the socket of the sudo user.
  18. if ! agent_available; then
  19. linksocket_sudo
  20. fi
  21. # If nothing worked, a no valid socket is found. If there are any identities
  22. # available, create a new agent.
  23. if ! agent_available && ids_available; then
  24. start_sshagent
  25. linksocket
  26. fi
  27. # If the agent is empty, add identities with the default file names.
  28. if ! ids_loaded && ids_available; then
  29. ssh-add $ID_FILES 2> /dev/null
  30. fi
  31. # The End
  32. }
  33. # Start a new ssh-agent process.
  34. function start_sshagent() {
  35. echo "Starting a new SSH Agent."
  36. eval `ssh-agent` &> /dev/null
  37. }
  38. # Link up an existing socket to the expected location if it is not already.
  39. #
  40. # Also, if the socket in the environment is a symlink, try to get to the actual
  41. # socket itself.
  42. function linksocket() {
  43. local link="/tmp/ssh-agent-$USER-tmux"
  44. if [[ ! -z $SSH_AUTH_SOCK && $SSH_AUTH_SOCK != $link ]]; then
  45. local target=$SSH_AUTH_SOCK
  46. [[ -L $SSH_AUTH_SOCK ]] && target=`readlink $SSH_AUTH_SOCK`
  47. [[ -e $target ]] && ln -sf $target $link &> /dev/null
  48. fi
  49. export SSH_AUTH_SOCK=$link
  50. }
  51. # If we detect sudo, try to link the current user (usually root) to the sudo
  52. # user's socket directly
  53. #
  54. # A user cannot access another user's socket using a symlink, even if that user
  55. # has super privileges. They can, however reach that socket directly, so a
  56. # personal symlink is attempted.
  57. function linksocket_sudo() {
  58. local linksudo="/tmp/ssh-agent-$SUDO_USER-tmux"
  59. if [[ ! -z $SUDO_USER && -L $linksudo ]]; then
  60. local link="/tmp/ssh-agent-$USER-tmux"
  61. ln -sf `readlink $linksudo` $link &> /dev/null
  62. export SSH_AUTH_SOCK=$link
  63. fi
  64. }
  65. # Check if there is a usable ssh-agent.
  66. #
  67. # `ssh-add`'s return value `2` means it was unable to contact an agent.
  68. # Return values:
  69. # 0 = success, agent contacted.
  70. # 1 = failed to connect to an agent.
  71. function agent_available() {
  72. ssh-add -l &> /dev/null
  73. [[ $? -eq 2 ]] && return 1 || return 0
  74. }
  75. # Check if there are identities to load.
  76. #
  77. # Return values:
  78. # 0 = success, found a file.
  79. # 1 = failed to match any files.
  80. function ids_available() {
  81. for file in $ID_FILES; do
  82. [[ -f $file ]] && return 0
  83. done
  84. return 1
  85. }
  86. # Check if there are any identities already loaded
  87. #
  88. # Return values:
  89. # 0 = success, there are ids loaded into the current agent.
  90. # 1 = failed, there are none.
  91. function ids_loaded() {
  92. [[ `ssh-add -L 2> /dev/null | grep "^ssh-" | wc -l` -eq 0 ]] && return 1 || return 0
  93. }
  94. # Go!
  95. agent_setup
  96. # Clean up scripts which should not be used after setup. Leave `start_sshagent`.
  97. unset -f agent_setup
  98. unset -f linksocket
  99. unset -f linksocket_sudo
  100. unset -f agent_available
  101. unset -f ids_available
  102. unset -f ids_loaded