Merge commit 'jrollins/master'
[monkeysphere.git] / src / seckey2sshagent
1 #!/bin/bash
2
3 # seckey2sshagent: this is a hack of a script to cope with the fact
4 # that openpgp2ssh currently cannot support encrypted secret keys.
5
6 # the basic operating principal is: 
7
8 # export the secret key in encrypted format to a new keyring
9
10 # remove the passphrase in that keyring
11
12 # use that keyring with openpgp2ssh
13
14 # Authors: Daniel Kahn Gillmor <dkg@fifthhorseman.net>,
15 #          Jameson Rollins <jrollins@fifthhorseman.net>
16
17 explanation() {
18
19     cat <<EOF
20 Usage: $0 [GPGID [FILE]]
21
22 The basic strategy of seckey2sshagent is to dump your OpenPGP
23 authentication key(s) into your agent or a file.  With no arguments,
24 it will add all secret keys in your keyring to the agent.  With one
25 argument, it adds only the specified key to the agent.  With two
26 arguments, it dumps the specified key to FILE, with the pub key in
27 FILE.pub.
28
29 This script is a gross hack at the moment.  It is done by creating a
30 new, temporary private keyring, letting the user remove the
31 passphrases from the keys, and then exporting them.  The temporary
32 private keyring is purged from the system.
33
34 When you use this command, you'll find yourself dropped into a GPG
35 'edit-key' dialog relevant *only* to the temporary private keyring.
36
37 At that point, you should clear the password from your key, with:
38
39  passwd
40  <enter your current password>
41
42 followed by the empty string for the new password.  GPG will ask you
43 if you're really sure.  Answer yes, because this is only relevant to
44 the temporary keyring.  Then, do:
45
46  save
47
48 At this point, your key will be added to your running ssh-agent with
49 the alias 'monkeysphere-key' and seckey2sshagent should terminate.
50 You can check on it with:
51
52  ssh-add -l
53
54 EOF
55 }
56
57 cleanup() {
58     echo -n "removing temp gpg home... " 1>&2
59     rm -rf "$TMPPRIVATE"
60     echo "done." 1>&2
61 }
62
63 export_sec_key() {
64     gpg --export-secret-key "$GPGID" | GNUPGHOME="$TMPPRIVATE" gpg --import
65     
66     GNUPGHOME="$TMPPRIVATE" gpg --edit-key "$GPGID"
67
68     # idea to script the password stuff.  not working.
69     # read -s -p "enter gpg password: " PASSWD; echo
70     # cmd=$(cat <<EOF
71     # passwd
72     # $PASSWD
73     # \n
74     # \n
75     # \n
76     # yes
77     # save
78     # EOF
79     # )
80     # echo -e "$cmd" | GNUPGHOME="$TMPPRIVATE" gpg --command-fd 0 --edit-key $GPGID
81
82     # export secret key to file
83     GNUPGHOME="$TMPPRIVATE" gpg --export-secret-keys "$GPGID" | \
84         openpgp2ssh "$GPGID"
85 }
86
87 # if no hex string is supplied, just print an explanation.
88 # this covers seckey2sshagent --help, --usage, -h, etc...
89 if [  "$(echo "$1" | tr -d '0-9a-fA-F')" ]; then
90     explanation
91     exit
92 fi
93
94 # set the file creation umask
95 umask 077
96
97 GPGIDS="$1"
98 if [ "$2" -a ! -e "$2" ] ; then
99     FILE="$2"
100 fi
101
102 if [ -z "$GPGIDS" ]; then
103     # hack: we need to get the list of secret keys, because if you
104     # --list-secret-keys with no arguments, GPG fails to print the
105     # capability flags (i've just filed this as
106     # https://bugs.g10code.com/gnupg/issue945)
107     KEYIDS=$(gpg --with-colons --list-secret-keys | grep ^sec | cut -f5 -d:)
108     # default to using all fingerprints of authentication-enabled keys 
109     GPGIDS=$(gpg --with-colons --fingerprint --fingerprint --list-secret-keys $KEYIDS | egrep -A1 '^(ssb|sec):.*:[^:]*a[^:]*:$' | grep ^fpr: | cut -d: -f10)
110 fi
111
112 trap cleanup EXIT
113
114 for GPGID in $GPGIDS; do
115
116     TMPPRIVATE=$(mktemp -d)
117     
118     # if specified, write key to fail and passprotect
119     if [ "$FILE" ] ; then
120         # export secret key to file
121         export_sec_key > "$TMPPRIVATE/key"
122         # passprotect file
123         ssh-keygen -f "${TMPPRIVATE}/key" -p
124         # move into place
125         mv "${TMPPRIVATE}/key" "$FILE"
126         
127         # export public key
128         gpg --export "$GPGID" | openpgp2ssh "$GPGID" > "${FILE}.pub"
129
130     # otherwise add to agent
131     else
132         KEYNAME='MonkeySphere Key '$(echo "$GPGID" | tr -c -d '0-9a-fA-F')''
133
134         # creating this alias so the key is named "monkeysphere-key" in the
135         # comment stored by the agent, while never being written to disk in
136         # SSH form:
137         ln -s /dev/stdin "${TMPPRIVATE}/${KEYNAME}"
138
139         # export secret key to agent
140         export_sec_key | (cd "$TMPPRIVATE" && ssh-add -c "$KEYNAME")
141     fi
142
143 done