diff --git a/commands/add-host-key/metadata b/commands/add-host-key/metadata index 74e3831..ba437df 100644 --- a/commands/add-host-key/metadata +++ b/commands/add-host-key/metadata @@ -3,4 +3,4 @@ # Sun Nov 18 08:46:36 PST 2012 NAME=add-host-key DESCRIPTION="Adds a public key to the specified known hosts file" -OPTIONS="hostname public-key type known-hosts-file" +OPTIONS="hostname type known-hosts-file host-key" diff --git a/commands/add-host-key/options.sh b/commands/add-host-key/options.sh index f46091c..ddbc01a 100644 --- a/commands/add-host-key/options.sh +++ b/commands/add-host-key/options.sh @@ -1,7 +1,7 @@ # Generated by stubbs:add-option. Do not edit, if using stubbs. -# Created: Sun Nov 18 09:05:34 PST 2012 +# Created: Mon Dec 3 15:36:32 PST 2012 # -#/ usage: ssh:add-host-key --hostname <> --public-key <> [ --type ] [ --known-hosts-file <$HOME/.ssh/known_hosts>] +#/ usage: ssh:add-host-key --hostname <> [ --type ] [ --known-hosts-file <$HOME/.ssh/known_hosts>] [ --host-key <>] # _rerun_options_parse_ - Parse the command arguments and set option variables. # @@ -23,9 +23,9 @@ rerun_options_parse() { OPT="$1" case "$OPT" in --hostname) rerun_option_check $# ; HOSTNAME=$2 ; shift ;; - --public-key) rerun_option_check $# ; PUBLIC_KEY=$2 ; shift ;; --type) rerun_option_check $# ; TYPE=$2 ; shift ;; --known-hosts-file) rerun_option_check $# ; KNOWN_HOSTS_FILE=$2 ; shift ;; + --host-key) rerun_option_check $# ; HOST_KEY=$2 ; shift ;; # help option -?) rerun_option_usage @@ -43,7 +43,6 @@ rerun_options_parse() { [ -z "$KNOWN_HOSTS_FILE" ] && KNOWN_HOSTS_FILE="$HOME/.ssh/known_hosts" # Check required options are set [ -z "$HOSTNAME" ] && { echo >&2 "missing required option: --hostname" ; return 2 ; } - [ -z "$PUBLIC_KEY" ] && { echo >&2 "missing required option: --public-key" ; return 2 ; } # If option variables are declared exportable, export them. # @@ -53,8 +52,8 @@ rerun_options_parse() { # Initialize the options variables to null. HOSTNAME= -PUBLIC_KEY= TYPE= KNOWN_HOSTS_FILE= +HOST_KEY= diff --git a/commands/add-host-key/script b/commands/add-host-key/script old mode 100755 new mode 100644 index 5e1fcf8..a75c4b5 --- a/commands/add-host-key/script +++ b/commands/add-host-key/script @@ -10,7 +10,7 @@ # and show its options. # #/ command: ssh:add-host-key: "Adds a public key to the specified known hosts file" -#/ usage: rerun ssh:add-host-key --hostname <> --public-key <> [ --type ] [ --known-hosts-file <$HOME/.ssh/known_hosts>] +#/ usage: rerun ssh:add-host-key --hostname <> [ --type ] [ --known-hosts-file <$HOME/.ssh/known_hosts>] [ --host-key <>] # Load common functions # --------------------- @@ -47,7 +47,7 @@ set -o nounset -o pipefail # declared by `rerun` or by the option parser function. #/ rerun-variables: RERUN, RERUN_VERSION, RERUN_MODULES, RERUN_MODULE_DIR -#/ option-variables: HOSTNAME PUBLIC_KEY TYPE KNOWN_HOSTS_FILE +#/ option-variables: HOSTNAME TYPE KNOWN_HOSTS_FILE HOST_KEY # The `rerun_options_parse` function processes the command line # arguments. Each accepted command line flag results in setting @@ -63,18 +63,24 @@ rerun_options_parse "$@" # Put the command implementation here. # - - - +# If the host key was not provided on the command line use ssh-keyscan(1) to acquire it. +if [[ -z $HOST_KEY ]] +then + HOST_KEY=$(ssh-keyscan -t ${TYPE} ${HOSTNAME} 2>/dev/null | cut -d' ' -f3) +fi + if [[ -r ${KNOWN_HOSTS_FILE} ]] then # Eliminate other entries for this key, if they are not identical to the one specified. - if grep -q "^${HOSTNAME} ssh-${TYPE} ${PUBLIC_KEY}$" ${KNOWN_HOSTS_FILE} + if grep -q "^${HOSTNAME} ssh-${TYPE} ${HOST_KEY}$" ${KNOWN_HOSTS_FILE} then echo "INFO: entry already exists, skipping" 1>&2 else TMP_KNOWN_HOSTS_FILE=$(mktemp) # Ignore the exit code since it's an indeterminate indication of success in this case. - if fgrep -v "${PUBLIC_KEY}" ${KNOWN_HOSTS_FILE} > ${TMP_KNOWN_HOSTS_FILE} + if fgrep -v "${HOST_KEY}" ${KNOWN_HOSTS_FILE} > ${TMP_KNOWN_HOSTS_FILE} then : fi @@ -88,7 +94,7 @@ then rm -f ${TMP_KNOWN_HOSTS_FILE} # Compose and append the entry to the specified known hosts file. - echo "${HOSTNAME} ssh-${TYPE} ${PUBLIC_KEY}" >> ${KNOWN_HOSTS_FILE} + echo "${HOSTNAME} ssh-${TYPE} ${HOST_KEY}" >> ${KNOWN_HOSTS_FILE} echo "INFO: replaced existing entrie(s)" 1>&2 fi @@ -97,7 +103,7 @@ else [[ -d $(dirname ${KNOWN_HOSTS_FILE}) ]] || mkdir $(dirname ${KNOWN_HOSTS_FILE}) && chmod 700 $(dirname ${KNOWN_HOSTS_FILE}) # Create the known hosts file with default permissions, if it doesn't already exist. - echo "${HOSTNAME} ssh-${TYPE} ${PUBLIC_KEY}" > ${KNOWN_HOSTS_FILE} + echo "${HOSTNAME} ssh-${TYPE} ${HOST_KEY}" > ${KNOWN_HOSTS_FILE} echo "INFO: added entry to new known hosts file" 1>&2 fi diff --git a/metadata b/metadata index c7c33cf..2882cc9 100644 --- a/metadata +++ b/metadata @@ -3,7 +3,7 @@ NAME=ssh DESCRIPTION="Rerun module for managing secure shell client and server usage" INTERPRETER="bash" -VERSION=1.0.1 +VERSION=1.1.1 REQUIRES= EXTERNALS= META_MODULE= diff --git a/options/host-key/metadata b/options/host-key/metadata new file mode 100644 index 0000000..9e1a1c1 --- /dev/null +++ b/options/host-key/metadata @@ -0,0 +1,12 @@ +# option metadata +# generated by stubbs:add-option +# Mon Dec 3 15:36:04 PST 2012 +NAME=host-key +DESCRIPTION="Public key of the specified host" +ARGUMENTS=true +REQUIRED=false +SHORT= +LONG=host-key +DEFAULT= +EXPORT=false + diff --git a/tests/add-host-key-1-test.sh b/tests/add-host-key-1-test.sh index 5204aa6..f72014a 100644 --- a/tests/add-host-key-1-test.sh +++ b/tests/add-host-key-1-test.sh @@ -14,7 +14,8 @@ describe "add-host-key" -it_works_with_a_new_key_and_a_duplicate() { +# Tests generating a DSA public host key and adding it to a temporary known hosts file. +it_works_with_a_new_and_duplicate_key() { # Generate a new key-pair into a temporary directory. TMPDIR=$(mktemp -d) rerun ssh:keygen --key-file ${TMPDIR}/id_dsa @@ -22,23 +23,48 @@ it_works_with_a_new_key_and_a_duplicate() { # Get the fields from the generated public key file. TYPE=$(cut -d' ' -f1 < ${TMPDIR}/id_dsa.pub | cut -d- -f2) PUBLIC_KEY=$(cut -d' ' -f2 < ${TMPDIR}/id_dsa.pub) - COMMENT=$(cut -d' ' -f3- < ${TMPDIR}/id_dsa.pub) # Add the key to a new empty known hosts file and make sure its the same as the original public key: - rerun ssh:add-host-key --public-key "${PUBLIC_KEY}" --known-hosts-file ${TMPDIR}/.ssh/known_hosts --type ${TYPE} --hostname localhost + rerun ssh:add-host-key --host-key "${PUBLIC_KEY}" --known-hosts-file ${TMPDIR}/.ssh/known_hosts --type ${TYPE} --hostname localhost echo "localhost ssh-${TYPE} ${PUBLIC_KEY}" > ${TMPDIR}/known_hosts.test diff ${TMPDIR}/known_hosts.test ${TMPDIR}/.ssh/known_hosts # Add the key a second time and make sure its the same as the original public key thus proving a duplicate entry was avoided: - rerun ssh:add-host-key --public-key "${PUBLIC_KEY}" --known-hosts-file ${TMPDIR}/.ssh/known_hosts --type ${TYPE} --hostname localhost + rerun ssh:add-host-key --host-key "${PUBLIC_KEY}" --known-hosts-file ${TMPDIR}/.ssh/known_hosts --type ${TYPE} --hostname localhost echo "localhost ssh-${TYPE} ${PUBLIC_KEY}" > ${TMPDIR}/known_hosts.test diff ${TMPDIR}/known_hosts.test ${TMPDIR}/.ssh/known_hosts # Add the key a third time with a different hostname proving the existing entry is replaced: - rerun ssh:add-host-key --public-key "${PUBLIC_KEY}" --known-hosts-file ${TMPDIR}/.ssh/known_hosts --type ${TYPE} --hostname $HOSTNAME + rerun ssh:add-host-key --host-key "${PUBLIC_KEY}" --known-hosts-file ${TMPDIR}/.ssh/known_hosts --type ${TYPE} --hostname $HOSTNAME echo "$HOSTNAME ssh-${TYPE} ${PUBLIC_KEY}" > ${TMPDIR}/known_hosts.test diff ${TMPDIR}/known_hosts.test ${TMPDIR}/.ssh/known_hosts rm -rf ${TMPDIR} } +# Tests using ssh-keyscan(1) to get the localhost's DSA public host key and add it to a temporary known hosts file +it_works_when_no_host_key_is_provided() { + # Generate a new key-pair into a temporary directory. + TMPDIR=$(mktemp -d) + + # Get the fields from the generated public key file. + TYPE=dsa + PUBLIC_KEY=$(ssh-keyscan -t dsa localhost 2>/dev/null | cut -d' ' -f3) + + # Add the key to a new empty known hosts file and make sure its the same as the original public key: + rerun ssh:add-host-key --known-hosts-file ${TMPDIR}/.ssh/known_hosts --type ${TYPE} --hostname localhost + echo "localhost ssh-${TYPE} ${PUBLIC_KEY}" > ${TMPDIR}/known_hosts.test + diff ${TMPDIR}/known_hosts.test ${TMPDIR}/.ssh/known_hosts + + # Add the key a second time and make sure its the same as the original public key thus proving a duplicate entry was avoided: + rerun ssh:add-host-key --known-hosts-file ${TMPDIR}/.ssh/known_hosts --type ${TYPE} --hostname localhost + echo "localhost ssh-${TYPE} ${PUBLIC_KEY}" > ${TMPDIR}/known_hosts.test + diff ${TMPDIR}/known_hosts.test ${TMPDIR}/.ssh/known_hosts + + # Add the key a third time with a different hostname proving the existing entry is replaced: + rerun ssh:add-host-key --known-hosts-file ${TMPDIR}/.ssh/known_hosts --type ${TYPE} --hostname $HOSTNAME + echo "$HOSTNAME ssh-${TYPE} ${PUBLIC_KEY}" > ${TMPDIR}/known_hosts.test + diff ${TMPDIR}/known_hosts.test ${TMPDIR}/.ssh/known_hosts + + rm -rf ${TMPDIR} +}