From ca0b2937b9689a2bf66a15713d0d86bad0be5458 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 22 Apr 2019 16:34:06 -0400 Subject: [PATCH 1/6] refactor: fetch ssh key via argument before stdin This allows the ssh-keys:add command to work in environments where there is no stdin/tty available, such as via server automation. --- plugins/ssh-keys/subcommands/add | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/plugins/ssh-keys/subcommands/add b/plugins/ssh-keys/subcommands/add index ecd6c9746..0b6ec0d6d 100755 --- a/plugins/ssh-keys/subcommands/add +++ b/plugins/ssh-keys/subcommands/add @@ -7,22 +7,28 @@ source "$PLUGIN_AVAILABLE_PATH/ssh-keys/functions" add_keys() { declare desc="add a new key via sshcommand" local cmd="ssh-keys:add" - shift - local name="$1" key_file="$2" key_contents key_from_pipe - [[ -p /dev/stdin ]] && read -r key_from_pipe - if [[ -n "$key_from_pipe" ]]; then - ssh-keygen -lf /dev/stdin <<<"$key_from_pipe" &>/dev/null || dokku_log_fail "Key piped in is not a valid ssh public key" - key_contents="$key_from_pipe" - elif [[ -n "$key_file" ]]; then - key_contents="$(cat "$key_file")" - ssh-keygen -lf /dev/stdin <<<"$key_contents" &>/dev/null || dokku_log_fail "Key from file is not a valid ssh public key" + [[ "$1" == "$cmd" ]] && shift 1 + declare NAME="$1" KEY_FILE="$2" + local key_contents + + if [[ -n "$KEY_FILE" ]]; then + key_contents="$(cat "$KEY_FILE")" + elif [[ -p /dev/stdin ]]; then + read -r key_contents + else + dokku_log_fail "No key specified via file or pipe" fi - [[ -n "$name" && -n "$key_contents" ]] || dokku_log_fail "Two arguments are required if not piping, ie: dokku ssh-keys:add " + + if [[ -n "$key_contents" ]]; then + dokku_log_fail "No key specified via file or pipe" + fi + local count="$(wc -l <<<"$key_contents")" - [ "$count" -eq 1 ] || dokku_log_fail 'Too many keys provided, set one per invocation of dokku ssh-keys:add ' + [[ "$count" -eq 1 ]] || dokku_log_fail "Too many keys provided, set one per invocation of dokku ssh-keys:add " + ssh-keygen -lf /dev/stdin <<<"$key_contents" &>/dev/null || dokku_log_fail "Key specified in is not a valid ssh public key" create_ssh_key_file verify_ssh_key_exists - echo "$key_contents" | sshcommand acl-add dokku "$name" || dokku_log_fail "sshcommand returned an error: $?" + echo "$key_contents" | sshcommand acl-add dokku "$NAME" || dokku_log_fail "sshcommand returned an error: $?" verify_ssh_key_file } From 6a5bbd63a3741bc3fdd1c416089d1b40f8e9bf72 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 22 Apr 2019 16:49:50 -0400 Subject: [PATCH 2/6] refactor: always use a temp file for interacting with ssh keys Rather than have stdin open everywhere, try to coerce input into a temporary file for later use. --- plugins/ssh-keys/subcommands/add | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/plugins/ssh-keys/subcommands/add b/plugins/ssh-keys/subcommands/add index 0b6ec0d6d..6d05cf746 100755 --- a/plugins/ssh-keys/subcommands/add +++ b/plugins/ssh-keys/subcommands/add @@ -9,26 +9,31 @@ add_keys() { local cmd="ssh-keys:add" [[ "$1" == "$cmd" ]] && shift 1 declare NAME="$1" KEY_FILE="$2" - local key_contents + local TMP_KEY_FILE + TMP_KEY_FILE=$(mktemp "/tmp/${FUNCNAME[0]}.XXXX") + trap 'rm -rf "$TMP_KEY_FILE" >/dev/null' RETURN INT TERM EXIT if [[ -n "$KEY_FILE" ]]; then - key_contents="$(cat "$KEY_FILE")" + true elif [[ -p /dev/stdin ]]; then + local key_contents read -r key_contents + echo "$key_contents" > "$TMP_KEY_FILE" + KEY_FILE="$TMP_KEY_FILE" else dokku_log_fail "No key specified via file or pipe" fi - if [[ -n "$key_contents" ]]; then + if [[ -s "$KEY_FILE" ]]; then dokku_log_fail "No key specified via file or pipe" fi - local count="$(wc -l <<<"$key_contents")" + local count="$(wc -l "$KEY_FILE")" [[ "$count" -eq 1 ]] || dokku_log_fail "Too many keys provided, set one per invocation of dokku ssh-keys:add " - ssh-keygen -lf /dev/stdin <<<"$key_contents" &>/dev/null || dokku_log_fail "Key specified in is not a valid ssh public key" + ssh-keygen -lf "$KEY_FILE" &>/dev/null || dokku_log_fail "Key specified in is not a valid ssh public key" create_ssh_key_file verify_ssh_key_exists - echo "$key_contents" | sshcommand acl-add dokku "$NAME" || dokku_log_fail "sshcommand returned an error: $?" + sshcommand acl-add dokku "$NAME" "$KEY_FILE" || dokku_log_fail "sshcommand returned an error: $?" verify_ssh_key_file } From 8551dfb2973818e8b2d535017c7a3e838fbf78d3 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Mon, 22 Apr 2019 16:52:53 -0400 Subject: [PATCH 3/6] refactor: switch to temporary file for key verification --- plugins/ssh-keys/functions | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/ssh-keys/functions b/plugins/ssh-keys/functions index f18200830..8e4560fa7 100755 --- a/plugins/ssh-keys/functions +++ b/plugins/ssh-keys/functions @@ -14,9 +14,14 @@ verify_ssh_key_file() { declare desc="Test that public key is valid" [[ -s ${DOKKU_ROOT}/.ssh/authorized_keys ]] || dokku_log_fail "No public keys found." local key line=0 + local TMP_KEY_FILE + TMP_KEY_FILE=$(mktemp "/tmp/${FUNCNAME[0]}.XXXX") + trap 'rm -rf "$TMP_KEY_FILE" >/dev/null' RETURN INT TERM EXIT + while read -r key; do line=$((line + 1)) - ssh-keygen -l -f /dev/stdin <<<"$key" &>/dev/null || dokku_log_fail "${DOKKU_ROOT}/.ssh/authorized_keys line $line failed ssh-keygen check." + echo "$key" >"$TMP_KEY_FILE" + ssh-keygen -lf "$TMP_KEY_FILE" &>/dev/null || dokku_log_fail "${DOKKU_ROOT}/.ssh/authorized_keys line $line failed ssh-keygen check." done <"${DOKKU_ROOT}/.ssh/authorized_keys" } From a717cb99a362d116c6d26c4e09279f1b3797ae1e Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 23 Apr 2019 12:21:43 -0400 Subject: [PATCH 4/6] fix: correct shfmt and update error message --- plugins/ssh-keys/subcommands/add | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/ssh-keys/subcommands/add b/plugins/ssh-keys/subcommands/add index 6d05cf746..788a9d200 100755 --- a/plugins/ssh-keys/subcommands/add +++ b/plugins/ssh-keys/subcommands/add @@ -18,14 +18,14 @@ add_keys() { elif [[ -p /dev/stdin ]]; then local key_contents read -r key_contents - echo "$key_contents" > "$TMP_KEY_FILE" + echo "$key_contents" >"$TMP_KEY_FILE" KEY_FILE="$TMP_KEY_FILE" else dokku_log_fail "No key specified via file or pipe" fi if [[ -s "$KEY_FILE" ]]; then - dokku_log_fail "No key specified via file or pipe" + dokku_log_fail "Empty key was specified" fi local count="$(wc -l "$KEY_FILE")" From 6ca4813247eff69fa21b72d04d68060a21c1ee41 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 23 Apr 2019 14:21:40 -0400 Subject: [PATCH 5/6] fix: invert check --- plugins/ssh-keys/subcommands/add | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/ssh-keys/subcommands/add b/plugins/ssh-keys/subcommands/add index 788a9d200..395b17909 100755 --- a/plugins/ssh-keys/subcommands/add +++ b/plugins/ssh-keys/subcommands/add @@ -24,7 +24,7 @@ add_keys() { dokku_log_fail "No key specified via file or pipe" fi - if [[ -s "$KEY_FILE" ]]; then + if [[ ! -s "$KEY_FILE" ]]; then dokku_log_fail "Empty key was specified" fi From dee0144c7c719904d10ff9f6f0f6d69a8aa95a5c Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 12 May 2019 19:08:55 -0400 Subject: [PATCH 6/6] fix: add missing awk to get number of lines in key file --- plugins/ssh-keys/subcommands/add | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/ssh-keys/subcommands/add b/plugins/ssh-keys/subcommands/add index 395b17909..89242b8c3 100755 --- a/plugins/ssh-keys/subcommands/add +++ b/plugins/ssh-keys/subcommands/add @@ -28,7 +28,7 @@ add_keys() { dokku_log_fail "Empty key was specified" fi - local count="$(wc -l "$KEY_FILE")" + local count="$(wc -l "$KEY_FILE" | awk '{ print $1; }')" [[ "$count" -eq 1 ]] || dokku_log_fail "Too many keys provided, set one per invocation of dokku ssh-keys:add " ssh-keygen -lf "$KEY_FILE" &>/dev/null || dokku_log_fail "Key specified in is not a valid ssh public key" create_ssh_key_file