summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJameson Graef Rollins <jrollins@finestructure.net>2009-02-19 15:19:02 -0500
committerJameson Graef Rollins <jrollins@finestructure.net>2009-02-19 15:19:02 -0500
commitbd64869a3b68ff8a020c381371a8ab1e24a5a0e4 (patch)
treeb790ed7dc580224304386ac1d2c98d07248eaf3c /src
parentc073811aa573d0e3486c39ed9514c46e0a7a077f (diff)
The monkeysphere {import,gen}_subkey functions were not up-to-date.
did a lot of work to bring them up-to-date, and better handle argument checking. also updated man page, changelog, and tests/basic.
Diffstat (limited to 'src')
-rwxr-xr-xsrc/monkeysphere82
-rw-r--r--src/share/m/gen_subkey83
-rw-r--r--src/share/m/import_subkey62
-rw-r--r--src/share/mh/import_key9
4 files changed, 132 insertions, 104 deletions
diff --git a/src/monkeysphere b/src/monkeysphere
index 992ca06..4169f2a 100755
--- a/src/monkeysphere
+++ b/src/monkeysphere
@@ -45,12 +45,9 @@ Monkeysphere client tool.
subcommands:
update-known_hosts (k) [HOST]... update known_hosts file
update-authorized_keys (a) update authorized_keys file
- import-subkey (i) import existing ssh key as gpg subkey
- --keyfile (-f) FILE key file to import
- --expire (-e) EXPIRE date to expire
+ import-subkey (i) FILE [KEYID] import existing ssh key as gpg subkey
gen-subkey (g) [KEYID] generate an authentication subkey
--length (-l) BITS key length in bits (2048)
- --expire (-e) EXPIRE date to expire
ssh-proxycommand monkeysphere ssh ProxyCommand
subkey-to-ssh-agent (s) store authentication subkey in ssh-agent
version (v) show version number
@@ -59,6 +56,83 @@ subcommands:
EOF
}
+# take a secret key ID and check that only zero or one ID is provided,
+# and that it corresponds to only a single secret key ID
+check_gpg_sec_key_id() {
+ local gpgSecOut
+
+ case "$#" in
+ 0)
+ gpgSecOut=$(gpg --quiet --fixed-list-mode --list-secret-keys --with-colons 2>/dev/null | egrep '^sec:')
+ ;;
+ 1)
+ gpgSecOut=$(gpg --quiet --fixed-list-mode --list-secret-keys --with-colons "$keyID" | egrep '^sec:') || failure
+ ;;
+ *)
+ failure "You must specify only a single primary key ID."
+ ;;
+ esac
+
+ # check that only a single secret key was found
+ case $(echo "$gpgSecOut" | grep -c '^sec:') in
+ 0)
+ failure "No secret keys found. Create an OpenPGP key with the following command:
+ gpg --gen-key"
+ ;;
+ 1)
+ echo "$gpgSecOut" | cut -d: -f5
+ ;;
+ *)
+ echo "Multiple primary secret keys found:" | log error
+ echo "$gpgSecOut" | cut -d: -f5 | log error
+ echo "Please specify which primary key to use." | log error
+ failure
+ ;;
+ esac
+}
+
+# check that a valid authentication subkey does not already exist
+check_gpg_authentication_subkey() {
+ local keyID
+ local IFS
+ local line
+ local type
+ local validity
+ local usage
+
+ keyID="$1"
+
+ # check that a valid authentication key does not already exist
+ IFS=$'\n'
+ for line in $(gpg --quiet --fixed-list-mode --list-keys --with-colons "$keyID") ; do
+ type=$(echo "$line" | cut -d: -f1)
+ validity=$(echo "$line" | cut -d: -f2)
+ usage=$(echo "$line" | cut -d: -f12)
+
+ # look at keys only
+ if [ "$type" != 'pub' -a "$type" != 'sub' ] ; then
+ continue
+ fi
+ # check for authentication capability
+ if ! check_capability "$usage" 'a' ; then
+ continue
+ fi
+ # if authentication key is valid, prompt to continue
+ if [ "$validity" = 'u' ] ; then
+ log error "A valid authentication key already exists for primary key '$keyID'."
+ if [ "$PROMPT" = "true" ] ; then
+ read -p "Are you sure you would like to generate another one? (y/N) " OK; OK=${OK:N}
+ if [ "${OK/y/Y}" != 'Y' ] ; then
+ failure "aborting."
+ fi
+ break
+ else
+ failure "aborting."
+ fi
+ fi
+ done
+}
+
########################################################################
# MAIN
########################################################################
diff --git a/src/share/m/gen_subkey b/src/share/m/gen_subkey
index d926ad5..7c3ebb7 100644
--- a/src/share/m/gen_subkey
+++ b/src/share/m/gen_subkey
@@ -15,10 +15,10 @@
gen_subkey(){
local keyLength
- local keyExpire
+ local gpgSecOut
local keyID
- local gpgOut
- local userID
+ local editCommands
+ local fifoDir
# get options
while true ; do
@@ -27,10 +27,6 @@ gen_subkey(){
keyLength="$2"
shift 2
;;
- -e|--expire)
- keyExpire="$2"
- shift 2
- ;;
*)
if [ "$(echo "$1" | cut -c 1)" = '-' ] ; then
failure "Unknown option '$1'.
@@ -41,67 +37,11 @@ Type '$PGRM help' for usage."
esac
done
- case "$#" in
- 0)
- gpgSecOut=$(gpg --quiet --fixed-list-mode --list-secret-keys --with-colons 2>/dev/null | egrep '^sec:')
- ;;
- 1)
- gpgSecOut=$(gpg --quiet --fixed-list-mode --list-secret-keys --with-colons "$1" | egrep '^sec:') || failure
- ;;
- *)
- failure "You must specify only a single primary key ID."
- ;;
- esac
-
- # check that only a single secret key was found
- case $(echo "$gpgSecOut" | grep -c '^sec:') in
- 0)
- failure "No secret keys found. Create an OpenPGP key with the following command:
- gpg --gen-key"
- ;;
- 1)
- keyID=$(echo "$gpgSecOut" | cut -d: -f5)
- ;;
- *)
- echo "Multiple primary secret keys found:"
- echo "$gpgSecOut" | cut -d: -f5
- failure "Please specify which primary key to use."
- ;;
- esac
+ # check that the keyID is unique
+ keyID=$(check_gpg_sec_key_id "$@")
- # check that a valid authentication key does not already exist
- IFS=$'\n'
- for line in $(gpg --quiet --fixed-list-mode --list-keys --with-colons "$keyID") ; do
- type=$(echo "$line" | cut -d: -f1)
- validity=$(echo "$line" | cut -d: -f2)
- usage=$(echo "$line" | cut -d: -f12)
-
- # look at keys only
- if [ "$type" != 'pub' -a "$type" != 'sub' ] ; then
- continue
- fi
- # check for authentication capability
- if ! check_capability "$usage" 'a' ; then
- continue
- fi
- # if authentication key is valid, prompt to continue
- if [ "$validity" = 'u' ] ; then
- log error "A valid authentication key already exists for primary key '$keyID'."
- if [ "$PROMPT" = "true" ] ; then
- read -p "Are you sure you would like to generate another one? (y/N) " OK; OK=${OK:N}
- if [ "${OK/y/Y}" != 'Y' ] ; then
- failure "aborting."
- fi
- break
- else
- failure "aborting."
- fi
- fi
- done
-
- # set subkey defaults
- # prompt about key expiration if not specified
- keyExpire=$(get_gpg_expiration "$keyExpire")
+ # check that an authentication subkey does not already exist
+ check_gpg_authentication_subkey "$keyID"
# generate the list of commands that will be passed to edit-key
editCommands=$(cat <<EOF
@@ -112,19 +52,24 @@ E
A
Q
$keyLength
-$keyExpire
+0
save
EOF
)
- log verbose "generating subkey..."
+ # setup the temp fifo dir for retrieving the key password
+ log debug "creating password fifo..."
fifoDir=$(msmktempdir)
+ trap "rm -rf $fifoDir" EXIT
(umask 077 && mkfifo "$fifoDir/pass")
+
+ log verbose "generating subkey..."
echo "$editCommands" | gpg --passphrase-fd 3 3< "$fifoDir/pass" --expert --command-fd 0 --edit-key "$keyID" &
# FIXME: this needs to fail more gracefully if the passphrase is incorrect
passphrase_prompt "Please enter your passphrase for $keyID: " "$fifoDir/pass"
+ trap - EXIT
rm -rf "$fifoDir"
wait
log verbose "done."
diff --git a/src/share/m/import_subkey b/src/share/m/import_subkey
index 8b04456..d71c258 100644
--- a/src/share/m/import_subkey
+++ b/src/share/m/import_subkey
@@ -14,40 +14,46 @@
# import an existing ssh key as a gpg subkey
import_subkey() {
- local keyFile="~/.ssh/id_rsa"
- local keyExpire
+ local sshKeyFile
local keyID
- local gpgOut
- local userID
-
- # get options
- while true ; do
- case "$1" in
- -f|--keyfile)
- keyFile="$2"
- shift 2
- ;;
- -e|--expire)
- keyExpire="$2"
- shift 2
- ;;
- *)
- if [ "$(echo "$1" | cut -c 1)" = '-' ] ; then
- failure "Unknown option '$1'.
-Type '$PGRM help' for usage."
- fi
- break
- ;;
- esac
- done
-
- log verbose "importing ssh key..."
+ local gpgSecOut
+ local fifoDir
+
+ sshKeyFile="$1"
+ shift
+
+ # check that key file specified
+ if [ -z "$sshKeyFile" ] ; then
+ failure "Must specify ssh key file to import, or specify '-' for stdin."
+ fi
+
+ # check that the keyID is unique
+ keyID=$(check_gpg_sec_key_id "$@")
+
+ # check that an authentication subkey does not already exist
+ check_gpg_authentication_subkey "$keyID"
+
+ # setup the temp fifo dir for retrieving the key password
+ log debug "creating password fifo..."
fifoDir=$(msmktempdir)
+ trap "rm -rf $fifoDir" EXIT
(umask 077 && mkfifo "$fifoDir/pass")
- ssh2openpgp | gpg --passphrase-fd 3 3< "$fifoDir/pass" --expert --command-fd 0 --import &
+ # import ssh key to as authentication subkey
+ if [ "$sshKeyFile" = '-' ] ; then
+ log verbose "importing ssh key from stdin..."
+ ssh2openpgp \
+ | gpg --passphrase-fd 3 3< "$fifoDir/pass" --expert --command-fd 0 --import &
+ else
+ log verbose "importing ssh key from file '$sshKeyFile'..."
+ ssh2openpgp <"$sshKeyFile" \
+ | gpg --passphrase-fd 3 3< "$fifoDir/pass" --expert --command-fd 0 --import &
+ fi
+
+ # get the password if needed
passphrase_prompt "Please enter your passphrase for $keyID: " "$fifoDir/pass"
+ trap - EXIT
rm -rf "$fifoDir"
wait
log verbose "done."
diff --git a/src/share/mh/import_key b/src/share/mh/import_key
index 6394ad7..040b41c 100644
--- a/src/share/mh/import_key
+++ b/src/share/mh/import_key
@@ -21,6 +21,11 @@ local userID
sshKeyFile="$1"
hostName="$2"
+# check that key file specified
+if [ -z "$sshKeyFile" ] ; then
+ failure "Must specify ssh key file to import, or specify '-' for stdin."
+fi
+
# use the default hostname if not specified
if [ -z "$hostName" ] ; then
hostName=$(hostname -f) || failure "Could not determine hostname."
@@ -45,9 +50,7 @@ mkdir -p "${GNUPGHOME_HOST}"
chmod 700 "${GNUPGHOME_HOST}"
# import ssh key to a private key
-if [ -z "$sshKeyFile" ] ; then
- failure "Must specify ssh key file to import, or specify '-' for stdin."
-elif [ "$sshKeyFile" = '-' ] ; then
+if [ "$sshKeyFile" = '-' ] ; then
log verbose "importing ssh key from stdin..."
PEM2OPENPGP_USAGE_FLAGS=authenticate pem2openpgp "$userID" \
| gpg_host --import