From df882c1e7e63fc658d0296dbd272499923fc4c69 Mon Sep 17 00:00:00 2001 From: Jameson Rollins Date: Mon, 18 Oct 2010 09:55:53 -0400 Subject: Simplification/refactoring of key/file processing This is a fairly major overhaul to greatly reduce the number of redundant code paths. We here created a new process_keys_for_file function that processes key from a userid for a given key file. All the main top elevel functions now call this one function. The main top level monkeysphere functions for updating the user's authorized_keys and known_hosts files are now moved to their own sourced files, which greatly reduces the amount of code sourced with common. monkeysphere now updates authorized_keys and known_hosts in temporary files that are then atomically moved into place upon completion. Finally, removed the confusing return codes in the key/file processing functions that were based on number of valid/invalid keys processed. It was confusing in the presence of actual errors that stopped processing. --- src/share/m/keys_for_userid | 26 +++++++++++ src/share/m/ssh_proxycommand | 1 + src/share/m/update_authorized_keys | 51 +++++++++++++++++++++ src/share/m/update_known_hosts | 91 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 169 insertions(+) create mode 100644 src/share/m/keys_for_userid create mode 100644 src/share/m/update_authorized_keys create mode 100644 src/share/m/update_known_hosts (limited to 'src/share/m') diff --git a/src/share/m/keys_for_userid b/src/share/m/keys_for_userid new file mode 100644 index 0000000..a65356b --- /dev/null +++ b/src/share/m/keys_for_userid @@ -0,0 +1,26 @@ +# -*-shell-script-*- +# This should be sourced by bash (though we welcome changes to make it POSIX sh compliant) + +# Monkeysphere keys-for-userid subcommand +# +# The monkeysphere scripts are written by: +# Jameson Rollins +# Jamie McClelland +# Daniel Kahn Gillmor +# +# They are Copyright 2010, and are all released under the GPL, version +# 3 or later. + +keys_for_userid() { + local tmpFile=$(msmktempfile) + + trap "rm -f $tmpFile" EXIT + + FILE_TYPE='raw' process_keys_for_file "$tmpFile" "$@" + + cat "$tmpFile" + + rm -f "$tmpFile" + + trap - EXIT +} diff --git a/src/share/m/ssh_proxycommand b/src/share/m/ssh_proxycommand index 5fb2ce4..a4c01c6 100644 --- a/src/share/m/ssh_proxycommand +++ b/src/share/m/ssh_proxycommand @@ -272,6 +272,7 @@ CHECK_KEYSERVER=${MONKEYSPHERE_CHECK_KEYSERVER:=$CHECK_KEYSERVER} # update the known_hosts file for the host local returnCode=0 +source "${MSHAREDIR}/update_known_hosts" update_known_hosts "$HOSTP" || returnCode="$?" # output on depending on the return of the update-known_hosts diff --git a/src/share/m/update_authorized_keys b/src/share/m/update_authorized_keys new file mode 100644 index 0000000..f38bdab --- /dev/null +++ b/src/share/m/update_authorized_keys @@ -0,0 +1,51 @@ +# -*-shell-script-*- +# This should be sourced by bash (though we welcome changes to make it POSIX sh compliant) + +# Monkeysphere update_authorized_keys subcommand +# +# The monkeysphere scripts are written by: +# Jameson Rollins +# Jamie McClelland +# Daniel Kahn Gillmor +# +# They are Copyright 2010, and are all released under the GPL, version +# 3 or later. + +update_authorized_keys() { + local tmpFile + + log debug "updating authorized_keys file:" + log debug " $AUTHORIZED_KEYS" + + # check permissions on the authorized_{keys,user_ids} file paths + check_key_file_permissions $(whoami) "$AUTHORIZED_KEYS" || failure + check_key_file_permissions $(whoami) "$AUTHORIZED_USER_IDS" || failure + + # create a lockfile on authorized_keys + lock create "$AUTHORIZED_KEYS" + + # make temp file + #tmpFile="$(dirname "$keyFile")/.$(basename "$keyFile")." + tmpFile=$(mktemp "${AUTHORIZED_KEYS}.monkeysphere.XXXXXX") + + # FIXME: we're discarding any pre-existing EXIT trap; is this bad? + trap "lock remove $AUTHORIZED_KEYS; rm -f $tmpFile" EXIT + + # remove any monkeysphere lines from authorized_keys file + remove_monkeysphere_lines "$AUTHORIZED_KEYS" > "$tmpFile" + + process_authorized_user_ids "$tmpFile" \ + < "$AUTHORIZED_USER_IDS" + + # note if the authorized_keys file was updated + if [ "$(file_hash "$AUTHORIZED_KEYS")" != "$(file_hash "$tmpFile")" ] ; then + log debug "authorized_keys file updated." + fi + mv -f "$tmpFile" "$AUTHORIZED_KEYS" + + # remove the lockfile and the trap + lock remove "$AUTHORIZED_KEYS" + + # remove the trap + trap - EXIT +} diff --git a/src/share/m/update_known_hosts b/src/share/m/update_known_hosts new file mode 100644 index 0000000..58cf78a --- /dev/null +++ b/src/share/m/update_known_hosts @@ -0,0 +1,91 @@ +# -*-shell-script-*- +# This should be sourced by bash (though we welcome changes to make it POSIX sh compliant) + +# Monkeysphere update_known_hosts subcommand +# +# The monkeysphere scripts are written by: +# Jameson Rollins +# Jamie McClelland +# Daniel Kahn Gillmor +# +# They are Copyright 2010, and are all released under the GPL, version +# 3 or later. + +# update the known_hosts file for a set of hosts listed on command +# line +update_known_hosts() { + local returnCode=0 + local fileCheck + local host + local newUmask + + # touch the known_hosts file so that the file permission check + # below won't fail upon not finding the file + if [ ! -f "$KNOWN_HOSTS" ]; then + # make sure to create any files or directories with the appropriate write bits turned off: + newUmask=$(printf "%04o" $(( 0$(umask) | 0022 )) ) + [ -d $(dirname "$KNOWN_HOSTS") ] \ + || (umask "$newUmask" && mkdir -p -m 0700 $(dirname "$KNOWN_HOSTS") ) \ + || failure "Could not create path to known_hosts file '$KNOWN_HOSTS'" + # make sure to create this file with the appropriate bits turned off: + (umask "$newUmask" && touch "$KNOWN_HOSTS") \ + || failure "Unable to create known_hosts file '$KNOWN_HOSTS'" + fi + + # check permissions on the known_hosts file path + check_key_file_permissions $(whoami) "$KNOWN_HOSTS" \ + || failure "Bad permissions governing known_hosts file '$KNOWN_HOSTS'" + + # create a lockfile on known_hosts: + lock create "$KNOWN_HOSTS" + + # make temp file + tmpFile=$(mktemp "${KNOWN_HOSTS}.monkeysphere.XXXXXX") + + # FIXME: we're discarding any pre-existing EXIT trap; is this bad? + trap "lock remove $KNOWN_HOSTS; rm -f $tmpFile" EXIT + + for host ; do + FILE_TYPE='known_hosts' process_keys_for_file "$tmpFile" "ssh://${host}" + + # touch the lockfile, for good measure. + lock touch "$KNOWN_HOSTS" + done + + # note if the authorized_keys file was updated + if [ "$(file_hash "$KNOWN_HOSTS")" != "$(file_hash "$tmpFile")" ] ; then + log debug "known_hosts file updated." + fi + mv -f "$tmpFile" "$KNOWN_HOSTS" + + # remove the lockfile and the trap + lock remove "$KNOWN_HOSTS" + + # remove the trap + trap - EXIT +} + +# process hosts from a known_hosts file +process_known_hosts() { + local hosts + + # exit if the known_hosts file does not exist + if [ ! -e "$KNOWN_HOSTS" ] ; then + failure "known_hosts file '$KNOWN_HOSTS' does not exist." + fi + + log debug "processing known_hosts file:" + log debug " $KNOWN_HOSTS" + + hosts=$(meat "$KNOWN_HOSTS" | cut -d ' ' -f 1 | grep -v '^|.*$' | tr , ' ' | tr '\n' ' ') + + if [ -z "$hosts" ] ; then + log debug "no hosts to process." + return + fi + + # take all the hosts from the known_hosts file (first + # field), grep out all the hashed hosts (lines starting + # with '|')... + update_known_hosts $hosts +} -- cgit v1.2.3