ssh-add.sh 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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 `ID_FILES` variable contains the standard identity files that ssh-add
  10. # tries to load. The value can be overridden by simply declaring an alternate
  11. # array before this script is run i.e. near the top of bashrc/zshrc.
  12. ID_FILES=(${ID_FILES[@]:-~/.ssh/id_rsa ~/.ssh/id_dsa ~/.ssh/id_ecdsa ~/.ssh/identity})
  13. function agent_setup() {
  14. # Try to reach an existing socket.
  15. linksocket
  16. # If that does not work, try to reach the socket of the sudo user.
  17. if ! agent_available; then
  18. linksocket_sudo
  19. fi
  20. # If nothing worked, a no valid socket is found. If there are any identities
  21. # available, create a new agent.
  22. if ! agent_available && ids_available; then
  23. start_sshagent
  24. linksocket
  25. fi
  26. # If the agent is empty, add identities with the default file names.
  27. if ! ids_loaded && ids_available; then
  28. ssh-add $ID_FILES 2> /dev/null
  29. fi
  30. # The End
  31. }
  32. # Start a new ssh-agent process.
  33. function start_sshagent() {
  34. echo "Starting a new SSH Agent."
  35. eval `ssh-agent` &> /dev/null
  36. }
  37. # Link up an existing socket to the expected location if it is not already.
  38. #
  39. # Also, if the socket in the environment is a symlink, try to get to the actual
  40. # socket itself.
  41. function linksocket() {
  42. local link="/tmp/ssh-agent-$USER-tmux"
  43. if [[ ! -z $SSH_AUTH_SOCK && $SSH_AUTH_SOCK != $link ]]; then
  44. local target=$SSH_AUTH_SOCK
  45. [[ -L $SSH_AUTH_SOCK ]] && target=`readlink $SSH_AUTH_SOCK`
  46. [[ -e $target ]] && ln -sf $target $link &> /dev/null
  47. fi
  48. export SSH_AUTH_SOCK=$link
  49. }
  50. # If we detect sudo, try to link the current user (usually root) to the sudo
  51. # user's socket directly
  52. #
  53. # A user cannot access another user's socket using a symlink, even if that user
  54. # has super privileges. They can, however reach that socket directly, so a
  55. # personal symlink is attempted.
  56. function linksocket_sudo() {
  57. local linksudo="/tmp/ssh-agent-$SUDO_USER-tmux"
  58. if [[ ! -z $SUDO_USER && -L $linksudo ]]; then
  59. local link="/tmp/ssh-agent-$USER-tmux"
  60. ln -sf `readlink $linksudo` $link &> /dev/null
  61. export SSH_AUTH_SOCK=$link
  62. fi
  63. }
  64. # Check if there is a usable ssh-agent.
  65. #
  66. # `ssh-add`'s return value `2` means it was unable to contact an agent.
  67. # Return values:
  68. # 0 = success, agent contacted.
  69. # 1 = failed to connect to an agent.
  70. function agent_available() {
  71. ssh-add -l &> /dev/null
  72. [[ $? -eq 2 ]] && return 1 || return 0
  73. }
  74. # Check if there are identities to load.
  75. #
  76. # Return values:
  77. # 0 = success, found a file.
  78. # 1 = failed to match any files.
  79. function ids_available() {
  80. for file in $ID_FILES; do
  81. [[ -f $file ]] && return 0
  82. done
  83. return 1
  84. }
  85. # Check if there are any identities already loaded
  86. #
  87. # Return values:
  88. # 0 = success, there are ids loaded into the current agent.
  89. # 1 = failed, there are none.
  90. function ids_loaded() {
  91. [[ `ssh-add -L 2> /dev/null | grep "^ssh-" | wc -l` -eq 0 ]] && return 1 || return 0
  92. }
  93. # Go!
  94. agent_setup
  95. # Clean up scripts which should not be used after setup. Leave `start_sshagent`.
  96. unset -f agent_setup
  97. unset -f linksocket
  98. unset -f linksocket_sudo
  99. unset -f agent_available
  100. unset -f ids_available
  101. unset -f ids_loaded