summaryrefslogtreecommitdiff
path: root/src/share/m/subkey_to_ssh_agent
blob: 818f4f70c3ae65a86ed58c169a02c31b89884d5e (plain)
  1. # -*-shell-script-*-
  2. # This should be sourced by bash (though we welcome changes to make it POSIX sh compliant)
  3. # Monkeysphere subkey-to-ssh-agent subcommand
  4. #
  5. # The monkeysphere scripts are written by:
  6. # Jameson Rollins <jrollins@finestructure.net>
  7. # Jamie McClelland <jm@mayfirst.org>
  8. # Daniel Kahn Gillmor <dkg@fifthhorseman.net>
  9. #
  10. # They are Copyright 2008-2009, and are all released under the GPL,
  11. # version 3 or later.
  12. # try to add all authentication subkeys to the agent
  13. subkey_to_ssh_agent() {
  14. local sshaddresponse
  15. local secretkeys
  16. local authsubkeys
  17. local workingdir
  18. local keysuccess
  19. local subkey
  20. local publine
  21. local kname
  22. if ! test_gnu_dummy_s2k_extension ; then
  23. failure "Your version of GnuTLS does not seem capable of using with gpg's exported subkeys.
  24. You may want to consider patching or upgrading to GnuTLS 2.6 or later.
  25. For more details, see:
  26. http://lists.gnu.org/archive/html/gnutls-devel/2008-08/msg00005.html"
  27. fi
  28. # if there's no agent running, don't bother:
  29. if [ -z "$SSH_AUTH_SOCK" ] || ! which ssh-add >/dev/null ; then
  30. failure "No ssh-agent available."
  31. fi
  32. # and if it looks like it's running, but we can't actually talk to
  33. # it, bail out:
  34. ssh-add -l >/dev/null
  35. sshaddresponse="$?"
  36. if [ "$sshaddresponse" = "2" ]; then
  37. failure "Could not connect to ssh-agent"
  38. fi
  39. # get list of secret keys (to work around bug
  40. # https://bugs.g10code.com/gnupg/issue945):
  41. secretkeys=$(gpg_user --list-secret-keys --with-colons --fixed-list-mode \
  42. --fingerprint | \
  43. grep '^fpr:' | cut -f10 -d: | awk '{ print "0x" $1 "!" }')
  44. if [ -z "$secretkeys" ]; then
  45. failure "You have no secret keys in your keyring!
  46. You might want to run 'gpg --gen-key'."
  47. fi
  48. authsubkeys=$(gpg_user --list-secret-keys --with-colons --fixed-list-mode \
  49. --fingerprint --fingerprint $secretkeys | \
  50. cut -f1,5,10,12 -d: | grep -A1 '^ssb:[^:]*::[^:]*a[^:]*$' | \
  51. grep '^fpr::' | cut -f3 -d: | sort -u)
  52. if [ -z "$authsubkeys" ]; then
  53. failure "no authentication-capable subkeys available.
  54. You might want to 'monkeysphere gen-subkey'"
  55. fi
  56. workingdir=$(msmktempdir)
  57. trap "rm -rf $workingdir" EXIT
  58. umask 077
  59. mkfifo "$workingdir/passphrase"
  60. keysuccess=1
  61. # FIXME: we're currently allowing any other options to get passed
  62. # through to ssh-add. should we limit it to known ones? For
  63. # example: -d or -c and/or -t <lifetime>
  64. for subkey in $authsubkeys; do
  65. # choose a label by which this key will be known in the agent:
  66. # we are labelling the key by User ID instead of by
  67. # fingerprint, but filtering out all / characters to make sure
  68. # the filename is legit.
  69. primaryuid=$(gpg_user --with-colons --list-key "0x${subkey}!" | grep '^pub:' | cut -f10 -d: | tr -d /)
  70. #kname="[monkeysphere] $primaryuid"
  71. kname="$primaryuid"
  72. if [ "$1" = '-d' ]; then
  73. # we're removing the subkey:
  74. gpg_user --export "0x${subkey}!" | openpgp2ssh "$subkey" > "$workingdir/$kname"
  75. (cd "$workingdir" && ssh-add -d "$kname")
  76. else
  77. # we're adding the subkey:
  78. mkfifo "$workingdir/$kname"
  79. gpg_user --passphrase-fd 3 3<"$workingdir/passphrase" \
  80. --export-options export-reset-subkey-passwd,export-minimal,no-export-attributes \
  81. --export-secret-subkeys "0x${subkey}!" | openpgp2ssh "$subkey" > "$workingdir/$kname" &
  82. (cd "$workingdir" && DISPLAY=nosuchdisplay SSH_ASKPASS=/bin/false ssh-add "$@" "$kname" </dev/null )&
  83. passphrase_prompt "Enter passphrase for key $kname: " "$workingdir/passphrase"
  84. wait %2
  85. fi
  86. keysuccess="$?"
  87. rm -f "$workingdir/$kname"
  88. done
  89. trap - EXIT
  90. rm -rf "$workingdir"
  91. # FIXME: sort out the return values: we're just returning the
  92. # success or failure of the final authentication subkey in this
  93. # case. What if earlier ones failed?
  94. exit "$keysuccess"
  95. }