summaryrefslogtreecommitdiff
path: root/src/share/mh
diff options
context:
space:
mode:
authorMatt Goins <mjgoins@openflows.com>2009-02-20 11:42:10 -0500
committerMatt Goins <mjgoins@openflows.com>2009-02-20 11:42:10 -0500
commitd41fe28eb49e42d7773a223a43fd108913410c99 (patch)
treea109a88b02089a3f328730a9aa394e3155fda916 /src/share/mh
parent3b48f2e80fac8d0fc62537ed07b3d1f1946648cd (diff)
parent9b47ae89c3840eb2af9a57a885e19ccbe36957d5 (diff)
Merge commit 'jrollins/master'
Diffstat (limited to 'src/share/mh')
-rw-r--r--src/share/mh/add_hostname4
-rw-r--r--src/share/mh/add_revoker132
-rw-r--r--src/share/mh/diagnostics37
-rw-r--r--src/share/mh/import_key27
-rw-r--r--src/share/mh/publish_key8
-rw-r--r--src/share/mh/revoke_hostname6
-rw-r--r--src/share/mh/revoke_key28
-rw-r--r--src/share/mh/set_expire2
8 files changed, 134 insertions, 110 deletions
diff --git a/src/share/mh/add_hostname b/src/share/mh/add_hostname
index 70bbec3..0da6a06 100644
--- a/src/share/mh/add_hostname
+++ b/src/share/mh/add_hostname
@@ -34,8 +34,8 @@ find_host_userid > /dev/null && \
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:=N}
- if [ ${OK/y/Y} != 'Y' ] ; then
+ read -p "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
else
diff --git a/src/share/mh/add_revoker b/src/share/mh/add_revoker
index b4113df..428b958 100644
--- a/src/share/mh/add_revoker
+++ b/src/share/mh/add_revoker
@@ -15,91 +15,99 @@
add_revoker() {
-local domain=
-local trust=full
-local depth=1
local keyID
-local importinfo
+local tmpDir
local fingerprint
-local ltsignCommand
-local trustval
+local addrevokerCommand
keyID="$1"
+
+# check that key ID or file is specified
if [ -z "$keyID" ] ; then
failure "You must specify the key ID of a revoker key, or specify a file to read the key from."
fi
-if [ -f "$keyID" ] ; then
- log info "Reading key from file '$keyID':"
- importinfo=$(gpg_host --import < "$keyID" 2>&1) || failure "could not read key from '$keyID'"
- # FIXME: if this is tried when the key database is not
- # up-to-date, i got these errors (using set -x):
-
- # ++ su -m monkeysphere -c '\''gpg --import'\''
- # Warning: using insecure memory!
- # gpg: key D21739E9: public key "Daniel Kahn Gillmor <dkg@fifthhorseman.net>" imported
- # gpg: Total number processed: 1
- # gpg: imported: 1 (RSA: 1)
- # gpg: can'\''t create `/var/monkeysphere/gnupg-host/pubring.gpg.tmp'\'': Permission denied
- # gpg: failed to rebuild keyring cache: Permission denied
- # gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
- # gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
- # gpg: next trustdb check due at 2009-01-10'
- # + failure 'could not read key from '\''/root/dkg.gpg'\'''
- # + echo 'could not read key from '\''/root/dkg.gpg'\'''
-
- keyID=$(echo "$importinfo" | grep '^gpg: key ' | cut -f2 -d: | cut -f3 -d\ )
- if [ -z "$keyID" ] || [ $(echo "$keyID" | wc -l) -ne 1 ] ; then
+
+# make a temporary directory for storing keys during import, and set
+# the trap to delete it on exit
+tmpDir=$(msmktempdir)
+trap "rm -rf $tmpDir" EXIT
+
+# if file is specified
+if [ -f "$keyID" -o "$keyID" = '-' ] ; then
+ # load the key from stdin
+ if [ "$keyID" = '-' ] ; then
+ # make a temporary file to hold the key from stdin
+ keyID="$tmpDir"/importkey
+ log verbose "reading key from stdin..."
+ cat > "$keyID"
+
+ # load the key from the file
+ elif [ -f "$keyID" ] ; then
+ log verbose "reading key from file '$keyID'..."
+ fi
+
+ # check the key is ok as monkeysphere user before loading
+ log debug "checking keys in file..."
+ fingerprint=$(su_monkeysphere_user \
+ ". ${SYSSHAREDIR}/common; list_primary_fingerprints" < "$keyID")
+
+ if [ $(printf "%s" "$fingerprint" | egrep -c '^[A-F0-9]{40}$') -ne 1 ] ; then
failure "There was not exactly one gpg key in the file."
fi
+
+ # load the key
+ gpg_host --import <"$keyID" \
+ || failure "could not read key from '$keyID'"
+
+# else, get the key from the keyserver
else
- # create a temporary directory for storing the downloaded key
- TMPLOC=$(mktemp -d "${MHTMPDIR}"/tmp.XXXXXXXXXX) || failure "Could not create temporary directory!"
+ # fix permissions and ownership on temporary directory which will
+ # be used by monkeysphere user for storing the downloaded key
+ chmod 0700 "$tmpDir"
+ chown "$MONKEYSPHERE_USER":"$MONKEYSPHERE_USER" "$tmpDir"
# download the key from the keyserver as the monkeysphere user
- su_monkeysphere_user \
- "GNUPGHOME=$TMPLOC gpg --keyserver $KEYSERVER --recv-key 0x${keyID}!"
+ log verbose "searching keyserver $KEYSERVER for keyID $keyID..."
+ su_monkeysphere_user "GNUPGHOME=$tmpDir gpg --quiet --keyserver $KEYSERVER --recv-key 0x${keyID}!" \
+ || failure "Could not receive a key with this ID from the '$KEYSERVER' keyserver."
+
+ # 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)
+
+ 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}
+ if [ "${OK/y/Y}" != 'Y' ] ; then
+ failure "revoker not added."
+ fi
+ else
+ log debug "adding revoker without prompting."
+ fi
# export the new key to the host keyring
- su_monkeysphere_user "GNUPGHOME=$TMPLOC gpg --export 0x${keyID}!" \
+ log debug "loading key into host keyring..."
+ su_monkeysphere_user "GNUPGHOME=$tmpDir gpg --quiet --export 0x${fingerprint}!" \
| gpg_host --import
fi
-export keyID
-
-# get the full fingerprint of the revoker key ID
-fingerprint=$(gpg_host --list-key --with-colons --with-fingerprint "0x${keyID}!" \
- | grep '^fpr:' | grep "$keyID" | cut -d: -f10)
-
-if [ -z "$fingerprint" ] ; then
- failure "Key '$keyID' not found."
-fi
-
-log info "key found:"
-gpg_host --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:-N}
- if [ "${OK/y/Y}" != 'Y' ] ; then
- failure "revoker not added."
- fi
-else
- log debug "adding revoker without prompting."
-fi
-
# edit-key script to add revoker
addrevokerCommand=$(cat <<EOF
addrevoker
+$fingerprint
+y
+save
EOF
)
-# FIXME: implement!
-failure "not implemented yet!"
-
# core ltsigns the newly imported revoker key
-if echo "$addrevokerCommand" | \
- gpg_core_edit ; then
+log debug "executing add revoker script..."
+if echo "$addrevokerCommand" | gpg_host_edit ; then
update_gpg_pub_file
@@ -108,4 +116,8 @@ else
failure "Problem adding revoker."
fi
+# remove the temporary directory
+trap - EXIT
+rm -rf "$tmpDir"
+
}
diff --git a/src/share/mh/diagnostics b/src/share/mh/diagnostics
index d774723..2f65f89 100644
--- a/src/share/mh/diagnostics
+++ b/src/share/mh/diagnostics
@@ -25,11 +25,10 @@ local expire
local uid
local fingerprint
local badhostkeys
-local sshd_config
local problemsfound=0
-# FIXME: what's the correct, cross-platform answer?
-sshd_config=/etc/ssh/sshd_config
+report_cruft
+
seckey=$(gpg_host --list-secret-keys --fingerprint --with-colons --fixed-list-mode)
keysfound=$(echo "$seckey" | grep -c ^sec:)
curdate=$(date +%s)
@@ -50,7 +49,7 @@ fi
echo "Checking host GPG key..."
if (( "$keysfound" < 1 )); then
echo "! No host key found."
- echo " - Recommendation: run 'monkeysphere-host gen-key' or 'monkeysphere-host import-key'"
+ echo " - Recommendation: run 'monkeysphere-host import-key'"
problemsfound=$(($problemsfound+1))
elif (( "$keysfound" > 1 )); then
echo "! More than one host key found?"
@@ -114,35 +113,9 @@ else
# FIXME: propose adding a revoker to the host key if none exist (do we
# have a way to do that after key generation?)
- # Ensure that the ssh_host_rsa_key file is present and non-empty:
- echo
- echo "Checking host SSH key..."
- if [ ! -s "${SYSDATADIR}/ssh_host_rsa_key" ] ; then
- echo "! The host key as prepared for SSH (${SYSDATADIR}/ssh_host_rsa_key) is missing or empty."
- problemsfound=$(($problemsfound+1))
- else
- if [ $(ls -l "${SYSDATADIR}/ssh_host_rsa_key" | cut -f1 -d\ ) != '-rw-------' ] ; then
- echo "! Permissions seem wrong for ${SYSDATADIR}/ssh_host_rsa_key -- should be 0600."
- problemsfound=$(($problemsfound+1))
- fi
+# FIXME: test (with ssh-keyscan?) that the running ssh
+# daemon is actually offering the monkeysphere host key.
- # propose changes needed for sshd_config (if any)
- if ! grep -q "^HostKey[[:space:]]\+${SYSDATADIR}/ssh_host_rsa_key$" "$sshd_config"; then
- echo "! $sshd_config does not point to the monkeysphere host key (${SYSDATADIR}/ssh_host_rsa_key)."
- echo " - Recommendation: add a line to $sshd_config: 'HostKey ${SYSDATADIR}/ssh_host_rsa_key'"
- problemsfound=$(($problemsfound+1))
- fi
- if badhostkeys=$(grep -i '^HostKey' "$sshd_config" | grep -v "^HostKey[[:space:]]\+${SYSDATADIR}/ssh_host_rsa_key$") ; then
- echo "! $sshd_config refers to some non-monkeysphere host keys:"
- echo "$badhostkeys"
- echo " - Recommendation: remove the above HostKey lines from $sshd_config"
- problemsfound=$(($problemsfound+1))
- fi
-
- # FIXME: test (with ssh-keyscan?) that the running ssh
- # daemon is actually offering the monkeysphere host key.
-
- fi
fi
# FIXME: look at the ownership/privileges of the various keyrings,
diff --git a/src/share/mh/import_key b/src/share/mh/import_key
index 557bb7f..040b41c 100644
--- a/src/share/mh/import_key
+++ b/src/share/mh/import_key
@@ -13,15 +13,22 @@
import_key() {
+local sshKeyFile
local hostName
local domain
local userID
-hostName="$1"
+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)
+ hostName=$(hostname -f) || failure "Could not determine hostname."
# test that the domain is not obviously illegitimate
domain=${foo##*.}
case $domain in
@@ -39,14 +46,20 @@ userID="ssh://${hostName}"
# create host home
mkdir -p "${MHDATADIR}"
-mkdir -p "${MHTMPDIR}"
mkdir -p "${GNUPGHOME_HOST}"
chmod 700 "${GNUPGHOME_HOST}"
-log verbose "importing ssh key..."
-# translate ssh key to a private key
-PEM2OPENPGP_USAGE_FLAGS=authenticate pem2openpgp "$userID" \
- | gpg_host --import 2>&1 | log debug
+# import ssh key to a private key
+if [ "$sshKeyFile" = '-' ] ; then
+ log verbose "importing ssh key from stdin..."
+ PEM2OPENPGP_USAGE_FLAGS=authenticate pem2openpgp "$userID" \
+ | gpg_host --import
+else
+ log verbose "importing ssh key from file '$sshKeyFile'..."
+ PEM2OPENPGP_USAGE_FLAGS=authenticate pem2openpgp "$userID" \
+ <"$sshKeyFile" \
+ | gpg_host --import
+fi
# load the new host fpr into the fpr variable. this is so we can
# create the gpg pub key file. we have to do this from the secret key
diff --git a/src/share/mh/publish_key b/src/share/mh/publish_key
index b433ad7..b0ffd93 100644
--- a/src/share/mh/publish_key
+++ b/src/share/mh/publish_key
@@ -18,8 +18,8 @@ publish_key() {
local GNUPGHOME
if [ "$PROMPT" = "true" ] ; then
- read -p "Really publish host key to $KEYSERVER? (y/N) " OK; OK=${OK:=N}
- if [ ${OK/y/Y} != 'Y' ] ; then
+ read -p "Really publish host key to $KEYSERVER? (Y/n) " OK; OK=${OK:=Y}
+ if [ "${OK/y/Y}" != 'Y' ] ; then
failure "key not published."
fi
else
@@ -27,7 +27,9 @@ else
fi
# create a temporary gnupg directory from which to publish the key
-export GNUPGHOME=$(mktemp -d)
+export GNUPGHOME=$(msmktempdir)
+chmod 0700 "$GNUPGHOME"
+chown "$MONKEYSPHERE_USER":"$MONKEYSPHERE_USER" "$GNUPGHOME"
# trap to remove tmp dir if break
trap "rm -rf $GNUPGHOME" EXIT
diff --git a/src/share/mh/revoke_hostname b/src/share/mh/revoke_hostname
index 77f1f0d..71b56ed 100644
--- a/src/share/mh/revoke_hostname
+++ b/src/share/mh/revoke_hostname
@@ -28,7 +28,7 @@ if [ -z "$1" ] ; then
fi
echo "WARNING: There is a known bug in this function."
-echo "This function has been known to occasionally revoke the wrong user ID."
+echo "This function has been known to occasionally revoke the wrong hostname."
echo "Please see the following bug report for more information:"
echo "https://labs.riseup.net/code/issues/show/422"
read -p "Are you sure you would like to proceed? (y/N) " OK; OK=${OK:=N}
@@ -45,8 +45,8 @@ uidIndex=$(find_host_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? (y/N) " OK; OK=${OK:=N}
- if [ ${OK/y/Y} != 'Y' ] ; then
+ read -p "Are you sure you would like to revoke this user ID? (N/y) " OK; OK=${OK:=Y}
+ if [ "${OK/y/Y}" != 'Y' ] ; then
failure "User ID not revoked."
fi
else
diff --git a/src/share/mh/revoke_key b/src/share/mh/revoke_key
index cccdc22..380236b 100644
--- a/src/share/mh/revoke_key
+++ b/src/share/mh/revoke_key
@@ -15,7 +15,31 @@
revoke_key() {
-# FIXME: implement!
-failure "not implemented yet!"
+# Coming in here, we expect $HOST_FINGERPRINT to be set, and we
+# believe that there is in fact a key.
+ # 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:
+
+ # an admin wants a revocation certificate for the host which they
+ # can store securely offline. In this case, the admin can
+ # redirect stdout to a file, or can simply copy/paste or
+ # transcribe from the terminal.
+
+ # Alternately, an admin might want to publish the revocation
+ # certificate immediately. here's a quick way to do this:
+
+
+ # 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)
+
+
+ # 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
+
+ GNUPGHOME="$GNUPGHOME_HOST" gpg --no-greeting --quiet --armor --gen-revoke "0x${HOST_FINGERPRINT}!"
}
diff --git a/src/share/mh/set_expire b/src/share/mh/set_expire
index ae7c13a..63e5c55 100644
--- a/src/share/mh/set_expire
+++ b/src/share/mh/set_expire
@@ -22,7 +22,7 @@ local extendTo
extendTo=$(get_gpg_expiration "$1")
if [ "$PROMPT" = "true" ] ; then
- read -p "Are you sure you want to change the expiration on the host key to '$extendTo'? (y/N) " OK; OK=${OK:-N}
+ read -p "Are you sure you want to change the expiration on the host key to '$extendTo'? (Y/n) " OK; OK=${OK:-Y}
if [ "${OK/y/Y}" != 'Y' ] ; then
failure "expiration not set."
fi