summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/monkeysphere18
-rwxr-xr-xsrc/monkeysphere-host13
-rw-r--r--src/share/common17
-rw-r--r--src/share/m/ssh_proxycommand10
-rw-r--r--src/share/m/subkey_to_ssh_agent12
-rw-r--r--src/share/ma/add_certifier16
-rw-r--r--src/share/ma/diagnostics2
-rw-r--r--src/share/ma/remove_certifier2
-rw-r--r--src/share/ma/update_users5
-rw-r--r--src/share/mh/add_hostname6
-rw-r--r--src/share/mh/add_revoker16
-rw-r--r--src/share/mh/import_key15
-rw-r--r--src/share/mh/revoke_hostname6
-rw-r--r--src/share/mh/revoke_key70
14 files changed, 136 insertions, 72 deletions
diff --git a/src/monkeysphere b/src/monkeysphere
index a65cef6..371983f 100755
--- a/src/monkeysphere
+++ b/src/monkeysphere
@@ -12,6 +12,8 @@
# or later.
########################################################################
+set -e
+
PGRM=$(basename $0)
SYSSHAREDIR=${MONKEYSPHERE_SYSSHAREDIR:-"/usr/share/monkeysphere"}
@@ -27,9 +29,6 @@ DATE=$(date -u '+%FT%T')
# unset some environment variables that could screw things up
unset GREP_OPTIONS
-# default return code
-RETURN=0
-
# set the file creation mask to be only owner rw
umask 077
@@ -87,9 +86,9 @@ check_gpg_sec_key_id() {
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
+ echo "Multiple primary secret keys found:"
+ echo "$gpgSecOut" | cut -d: -f5
+ echo "Please specify which primary key to use."
failure
;;
esac
@@ -123,7 +122,7 @@ check_gpg_authentication_subkey() {
fi
# if authentication key is valid, prompt to continue
if [ "$validity" = 'u' ] ; then
- echo "A valid authentication key already exists for primary key '$keyID'."
+ echo "A valid authentication key already exists for primary key '$keyID'." 1>&2
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
@@ -203,13 +202,11 @@ case $COMMAND in
# those hosts
if [ "$1" ] ; then
update_known_hosts "$@"
- RETURN="$?"
# otherwise, if no hosts are specified, process every host
# in the user's known_hosts file
else
process_known_hosts
- RETURN="$?"
fi
;;
@@ -219,7 +216,6 @@ case $COMMAND in
# process authorized_user_ids file
process_authorized_user_ids "$AUTHORIZED_USER_IDS"
- RETURN="$?"
;;
'import-subkey'|'i')
@@ -255,5 +251,3 @@ case $COMMAND in
Type '$PGRM help' for usage."
;;
esac
-
-exit "$RETURN"
diff --git a/src/monkeysphere-host b/src/monkeysphere-host
index 4c7df88..540a8ab 100755
--- a/src/monkeysphere-host
+++ b/src/monkeysphere-host
@@ -54,14 +54,15 @@ usage: $PGRM <subcommand> [options] [args]
Monkeysphere host admin tool.
subcommands:
- import-key (i) FILE [NAME[:PORT]] import existing ssh key to gpg
+ import-key (i) FILE NAME[:PORT] import existing ssh key to gpg
show-key (s) output all host key information
+ publish-key (p) publish host key to keyserver
set-expire (e) [EXPIRE] set host key expiration
add-hostname (n+) NAME[:PORT] add hostname user ID to host key
revoke-hostname (n-) NAME[:PORT] revoke hostname user ID
- add-revoker (o) [KEYID|FILE] add a revoker to the host key
- revoke-key (r) revoke host key
- publish-key (p) publish host key to keyserver
+ add-revoker (r+) [KEYID|FILE] add a revoker to the host key
+ revoke-key generate and/or publish revocation
+ certificate for host key
version (v) show version number
help (h,?) this help
@@ -268,14 +269,14 @@ case $COMMAND in
revoke_hostname "$@"
;;
- 'add-revoker'|'o')
+ 'add-revoker'|'r+')
check_host_no_key
load_fingerprint
source "${MHSHAREDIR}/add_revoker"
add_revoker "$@"
;;
- 'revoke-key'|'r')
+ 'revoke-key')
check_host_no_key
load_fingerprint
source "${MHSHAREDIR}/revoke_key"
diff --git a/src/share/common b/src/share/common
index 653d58b..5e0cb6a 100644
--- a/src/share/common
+++ b/src/share/common
@@ -586,8 +586,8 @@ gpg2authorized_keys() {
# FIXME: need to figure out how to retrieve all matching keys
# (not just first N (5 in this case))
gpg_fetch_userid() {
+ local returnCode=0
local userID
- local returnCode
if [ "$CHECK_KEYSERVER" != 'true' ] ; then
return 0
@@ -626,6 +626,7 @@ gpg_fetch_userid() {
#
# expects global variable: "MODE"
process_user_id() {
+ local returnCode=0
local userID
local requiredCapability
local requiredPubCapability
@@ -657,10 +658,10 @@ process_user_id() {
# output gpg info for (exact) userid and store
gpgOut=$(gpg --list-key --fixed-list-mode --with-colon \
--with-fingerprint --with-fingerprint \
- ="$userID" 2>/dev/null)
+ ="$userID" 2>/dev/null) || returnCode="$?"
# if the gpg query return code is not 0, return 1
- if [ "$?" -ne 0 ] ; then
+ if [ "$returnCode" -ne 0 ] ; then
log verbose " no primary keys found."
return 1
fi
@@ -890,6 +891,7 @@ process_host_known_hosts() {
# update the known_hosts file for a set of hosts listed on command
# line
update_known_hosts() {
+ local returnCode=0
local nHosts
local nHostsOK
local nHostsBAD
@@ -919,9 +921,9 @@ update_known_hosts() {
for host ; do
# process the host
- process_host_known_hosts "$host"
+ process_host_known_hosts "$host" || returnCode="$?"
# note the result
- case "$?" in
+ case "$returnCode" in
0)
nHostsOK=$((nHostsOK+1))
;;
@@ -1043,6 +1045,7 @@ process_uid_authorized_keys() {
# update the authorized_keys files from a list of user IDs on command
# line
update_authorized_keys() {
+ local returnCode=0
local userID
local nIDs
local nIDsOK
@@ -1072,10 +1075,10 @@ update_authorized_keys() {
for userID ; do
# process the user ID, change return code if key not found for
# user ID
- process_uid_authorized_keys "$userID"
+ process_uid_authorized_keys "$userID" || returnCode="$?"
# note the result
- case "$?" in
+ case "$returnCode" in
0)
nIDsOK=$((nIDsOK+1))
;;
diff --git a/src/share/m/ssh_proxycommand b/src/share/m/ssh_proxycommand
index bd09588..abe068d 100644
--- a/src/share/m/ssh_proxycommand
+++ b/src/share/m/ssh_proxycommand
@@ -18,6 +18,7 @@
# "marginal case" ouput in the case that there is not a full
# validation path to the host
output_no_valid_key() {
+ local returnCode=0
local sshKeyOffered
local userID
local type
@@ -112,11 +113,11 @@ EOF
fi
;;
esac
- done
+ done || returnCode="$?"
# if no key match was made (and the "while read" subshell returned
# 1) output how many keys were found
- if (($? != 1)) ; then
+ if (( returnCode != 1 )) ; then
cat <<EOF | log info
None of the found keys matched the key offered by the host.
Run the following command for more info about the found keys:
@@ -200,12 +201,13 @@ fi
CHECK_KEYSERVER=${MONKEYSPHERE_CHECK_KEYSERVER:=$CHECK_KEYSERVER}
# update the known_hosts file for the host
-update_known_hosts "$HOSTP"
+local returnCode=0
+update_known_hosts "$HOSTP" || returnCode="$?"
# output on depending on the return of the update-known_hosts
# subcommand, which is (ultimately) the return code of the
# update_known_hosts function in common
-case $? in
+case "$returnCode" in
0)
# acceptable host key found so continue to ssh
true
diff --git a/src/share/m/subkey_to_ssh_agent b/src/share/m/subkey_to_ssh_agent
index 818f4f7..7fb2fdb 100644
--- a/src/share/m/subkey_to_ssh_agent
+++ b/src/share/m/subkey_to_ssh_agent
@@ -14,11 +14,11 @@
# try to add all authentication subkeys to the agent
subkey_to_ssh_agent() {
- local sshaddresponse
+ local sshaddresponse=0
local secretkeys
local authsubkeys
local workingdir
- local keysuccess
+ local keysuccess=0
local subkey
local publine
local kname
@@ -38,8 +38,7 @@ For more details, see:
# and if it looks like it's running, but we can't actually talk to
# it, bail out:
- ssh-add -l >/dev/null
- sshaddresponse="$?"
+ ssh-add -l >/dev/null || sshaddresponse="$?"
if [ "$sshaddresponse" = "2" ]; then
failure "Could not connect to ssh-agent"
fi
@@ -100,8 +99,7 @@ You might want to 'monkeysphere gen-subkey'"
passphrase_prompt "Enter passphrase for key $kname: " "$workingdir/passphrase"
wait %2
- fi
- keysuccess="$?"
+ fi || keysuccess="$?"
rm -f "$workingdir/$kname"
done
@@ -112,5 +110,5 @@ You might want to 'monkeysphere gen-subkey'"
# FIXME: sort out the return values: we're just returning the
# success or failure of the final authentication subkey in this
# case. What if earlier ones failed?
- exit "$keysuccess"
+ return "$keysuccess"
}
diff --git a/src/share/ma/add_certifier b/src/share/ma/add_certifier
index f2cadf2..6f85ecf 100644
--- a/src/share/ma/add_certifier
+++ b/src/share/ma/add_certifier
@@ -120,14 +120,24 @@ else
# get the full fingerprint of new certifier key
log debug "getting fingerprint of certifier key..."
fingerprint=$(gpg_sphere "--list-key --with-colons --with-fingerprint 0x${keyID}!" \
- | grep '^fpr:' | grep "$keyID" | cut -d: -f10)
+ | grep '^fpr:' | cut -d: -f10)
+
+ # test that there is only a single fingerprint
+ if (( $(echo "$fingerprint" | wc -l) != 1 )) ; then
+ cat <<EOF
+More than one fingerprint found:
+$fingerprint
+Please use a more specific key ID.
+EOF
+ failure
+ fi
log info "key found:"
gpg_sphere "--fingerprint 0x${fingerprint}!"
if [ "$PROMPT" = "true" ] ; then
- echo "Are you sure you want to add the above key as a"
- read -p "certifier of users on this system? (Y/n) " OK; OK=${OK:-Y}
+ echo "Are you sure you want to add the above key as a certifier"
+ read -p "of users on this system? (Y/n) " OK; OK=${OK:-Y}
if [ "${OK/y/Y}" != 'Y' ] ; then
failure "Identity certifier not added."
fi
diff --git a/src/share/ma/diagnostics b/src/share/ma/diagnostics
index ce463b2..8fc4b31 100644
--- a/src/share/ma/diagnostics
+++ b/src/share/ma/diagnostics
@@ -105,7 +105,7 @@ echo
echo "Checking for Identity Certifiers..."
if ! monkeysphere-authentication list-identity-certifiers | egrep -q '^[A-F0-9]{40}:' then
echo "! No Identity Certifiers found!"
- echo " - Recommendation: once you know who should be able to certify identities for
+ echo " - Recommendation: once you know who should be able to certify the identities of
connecting users, you should add their key, with:
monkeysphere-authentication add-identity-certifier"
problemsfound=$(($problemsfound+1))
diff --git a/src/share/ma/remove_certifier b/src/share/ma/remove_certifier
index a9a1451..6c90358 100644
--- a/src/share/ma/remove_certifier
+++ b/src/share/ma/remove_certifier
@@ -27,7 +27,7 @@ fi
gpg_core --list-key --fingerprint "0x${keyID}!" || failure
if [ "$PROMPT" = "true" ] ; then
- read -p "Really remove the identity certifier above? (Y/n) " OK; OK=${OK:-Y}
+ read -p "Really remove the above listed identity certifier? (Y/n) " OK; OK=${OK:-Y}
if [ "${OK/y/Y}" != 'Y' ] ; then
failure "Identity certifier not removed."
fi
diff --git a/src/share/ma/update_users b/src/share/ma/update_users
index 092d108..bfefc31 100644
--- a/src/share/ma/update_users
+++ b/src/share/ma/update_users
@@ -93,8 +93,8 @@ for uname in $unames ; do
# process authorized_user_ids file, as monkeysphere user
su_monkeysphere_user \
- ". ${SYSSHAREDIR}/common; process_authorized_user_ids $TMP_AUTHORIZED_USER_IDS"
- RETURN="$?"
+ ". ${SYSSHAREDIR}/common; process_authorized_user_ids $TMP_AUTHORIZED_USER_IDS" \
+ || RETURN="$?"
else
log debug "not processing authorized_user_ids."
fi
@@ -154,4 +154,5 @@ for uname in $unames ; do
rm -rf "$TMPLOC"
done
+return $RETURN
}
diff --git a/src/share/mh/add_hostname b/src/share/mh/add_hostname
index 0da6a06..b08d688 100644
--- a/src/share/mh/add_hostname
+++ b/src/share/mh/add_hostname
@@ -32,9 +32,9 @@ find_host_userid > /dev/null && \
failure "Host userID '$userID' already exists."
if [ "$PROMPT" = "true" ] ; then
- echo "The following user ID will be added to the host key:"
- echo " $userID"
- read -p "Are you sure you would like to add this user ID? (Y/n) " OK; OK=${OK:=Y}
+ read -p "The following user ID will be added to the host key:
+ $userID
+Are you sure you would like to add this user ID? (Y/n) " OK; OK=${OK:=Y}
if [ "${OK/y/Y}" != 'Y' ] ; then
failure "User ID not added."
fi
diff --git a/src/share/mh/add_revoker b/src/share/mh/add_revoker
index 428b958..03ae56f 100644
--- a/src/share/mh/add_revoker
+++ b/src/share/mh/add_revoker
@@ -74,14 +74,24 @@ else
# get the full fingerprint of new revoker key
log debug "getting fingerprint of revoker key..."
fingerprint=$(su_monkeysphere_user "GNUPGHOME=$tmpDir gpg --list-key --with-colons --with-fingerprint 0x${keyID}!" \
- | grep '^fpr:' | grep "$keyID" | cut -d: -f10)
+ | grep '^fpr:' | cut -d: -f10)
+
+ # test that there is only a single fingerprint
+ if (( $(echo "$fingerprint" | wc -l) != 1 )) ; then
+ cat <<EOF
+More than one fingerprint found:
+$fingerprint
+Please use a more specific key ID.
+EOF
+ failure
+ fi
log info "key found:"
su_monkeysphere_user "GNUPGHOME=$tmpDir gpg --fingerprint 0x${fingerprint}!"
if [ "$PROMPT" = "true" ] ; then
- echo "Are you sure you want to add the above key as a"
- read -p "revoker of the host key? (Y/n) " OK; OK=${OK:-Y}
+ read -p "Are you sure you want to add the above key as a revoker
+of the host key? (Y/n) " OK; OK=${OK:-Y}
if [ "${OK/y/Y}" != 'Y' ] ; then
failure "revoker not added."
fi
diff --git a/src/share/mh/import_key b/src/share/mh/import_key
index 040b41c..f7c69c3 100644
--- a/src/share/mh/import_key
+++ b/src/share/mh/import_key
@@ -26,20 +26,9 @@ if [ -z "$sshKeyFile" ] ; then
failure "Must specify ssh key file to import, or specify '-' for stdin."
fi
-# use the default hostname if not specified
+# fail if hostname not specified
if [ -z "$hostName" ] ; then
- hostName=$(hostname -f) || failure "Could not determine hostname."
- # test that the domain is not obviously illegitimate
- domain=${foo##*.}
- case $domain in
- 'local'|'localdomain')
- failure "Host domain '$domain' is not legitimate. Aborting key import."
- ;;
- esac
- # test that there are at least two parts
- if (( $(echo "$hostName" | tr . ' ' | wc -w) < 2 )) ; then
- failure "Host name '$hostName' is not legitimate. Aborting key import."
- fi
+ failure "You must specify a fully-qualified domain name for use in the host certificate user ID."
fi
userID="ssh://${hostName}"
diff --git a/src/share/mh/revoke_hostname b/src/share/mh/revoke_hostname
index 71b56ed..2142af7 100644
--- a/src/share/mh/revoke_hostname
+++ b/src/share/mh/revoke_hostname
@@ -43,9 +43,9 @@ uidIndex=$(find_host_userid) || \
failure "No non-revoked user ID found matching '$userID'."
if [ "$PROMPT" = "true" ] ; then
- echo "The following host key user ID will be revoked:"
- echo " $userID"
- read -p "Are you sure you would like to revoke this user ID? (N/y) " OK; OK=${OK:=Y}
+ read -p "The following host key user ID will be revoked:
+ $userID
+Are you sure you would like to revoke this user ID? (Y/n) " OK; OK=${OK:=Y}
if [ "${OK/y/Y}" != 'Y' ] ; then
failure "User ID not revoked."
fi
diff --git a/src/share/mh/revoke_key b/src/share/mh/revoke_key
index 380236b..ad68d5f 100644
--- a/src/share/mh/revoke_key
+++ b/src/share/mh/revoke_key
@@ -18,6 +18,28 @@ revoke_key() {
# Coming in here, we expect $HOST_FINGERPRINT to be set, and we
# believe that there is in fact a key.
+ if [ "$PROMPT" = "false" ] ; then
+ publish=N
+ else
+ cat <<EOF >&2
+This will generate a revocation certificate for your host key
+(fingerprint: $HOST_FINGERPRINT) and
+dump the certificate to standard output.
+
+It can also directly publish the new revocation certificate
+to the public keyservers via $KEYSERVER if you want it to.
+
+Publishing this certificate will IMMEDIATELY and PERMANENTLY revoke
+your host key!
+
+EOF
+ read -p "Publish the certificate after generation? (y/n/Q) " publish
+
+ if ! [ "${publish/y/Y}" = 'Y' -o "${publish/n/N}" = 'N' ] ; then
+ failure "aborting at user request"
+ fi
+ fi
+
# our current implementation is very simple: we just want to
# generate the revocation certificate on stdout. This provides
# for the two most likely (but hopefully not common) scenarios:
@@ -28,18 +50,52 @@ revoke_key() {
# transcribe from the terminal.
# Alternately, an admin might want to publish the revocation
- # certificate immediately. here's a quick way to do this:
+ # certificate immediately, which we can help them do as well.
+
+ if [ "$PROMPT" = 'false' ] ; then
+ # FIXME: allow the end user to choose something other than
+ # "key was compromised" (1) and to supply their own revocation
+ # string.
+ local revoke_commands="y
+1
+Monkeysphere host key revocation (automated) $(date '+%F_%T%z')
- # tmp=$(mktemp -d)
- # export GNUPGHOME="$tmp"
- # gpg --import < /var/lib/monkeysphere/ssh_host_rsa_key.pub.gpg
- # monkeysphere-host revoke-key | gpg --import
- # gpg --keyserver pool.sks-keyservers.net --send $(hostname -f)
+y
+"
+ revcert=$(GNUPGHOME="$GNUPGHOME_HOST" gpg_host --command-fd 0 --armor --gen-revoke "0x${HOST_FINGERPRINT}!" <<<"$revoke_commands" ) \
+ || failure "Failed to generate revocation certificate!"
+
+ else
# note: we're not using the gpg_host function because we actually
# want to use gpg's UI in this case, so we want to omit --no-tty
+ revcert=$(GNUPGHOME="$GNUPGHOME_HOST" gpg --no-greeting --quiet --armor --gen-revoke "0x${HOST_FINGERPRINT}!") \
+ || failure "Failed to generate revocation certificate!"
+ fi
+
+ # if you run gpg --gen-revoke but cancel it or quit in the middle,
+ # it returns success, but emits no revocation certificate:
+ if ! [ "$revcert" ] ; then
+ failure "Revocation canceled."
+ fi
+
+ ## ok, now we have the revocation certificate. Print it, and
+ ## offer to publish if originally requested:
+ printf "%s\n" "$revcert"
- GNUPGHOME="$GNUPGHOME_HOST" gpg --no-greeting --quiet --armor --gen-revoke "0x${HOST_FINGERPRINT}!"
+ if [ "${publish/y/Y}" = 'Y' ] ; then
+ printf "\n" >&2
+ read -p "Really publish this cert to $KEYSERVER ? (Y/n) " really
+ if [ "${really/n/N}" = 'N' ] ; then
+ printf "Not publishing.\n" >&2
+ else
+ local newhome=$(mkmstempdir)
+ GNUPGHOME="$newhome" gpg --no-tty --quiet --import < "$HOST_KEY_FILE"
+ GNUPGHOME="$newhome" gpg --no-tty --quiet --import <<< "$revcert"
+ GNUPGHOME="$newhome" gpg --keyserver "$KEYSERVER" --send "0x${HOST_FINGERPRINT}!"
+ rm -rf "$newhome"
+ fi
+ fi
}