Skip to content

Commit 37a997c

Browse files
committed
feat: validate the authorized_keys file when running the list subcommand
1 parent 388f152 commit 37a997c

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,23 @@ no-agent-forwarding,no-user-rc,no-X11-forwarding,no-port-forwarding
8282

8383
This can be useful for cases where the ssh server does not allow certain options or you
8484
wish to further constrain a user's environment. Please see `man sshd` for more information.
85+
86+
Existing keys can be listed via the `list` subcommand:
87+
88+
```shell
89+
# in text format
90+
sshcommand list cmd
91+
92+
# filter by a particular name
93+
sshcommand list cmd progrium
94+
95+
# in json format
96+
sshcommand list cmd "" json
97+
98+
# with name filtering
99+
sshcommand list cmd progrium json
100+
101+
# ignore validation errors (though they will be printed to stderr)
102+
export SSHCOMMAND_IGNORE_LIST_WARNINGS=true
103+
sshcommand list cmd
104+
```

sshcommand

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,49 @@ fn-adduser() {
8686
esac
8787
}
8888

89+
fn-verify-file() {
90+
declare desc="Test that public key is valid"
91+
declare file="$1"
92+
local has_errors=false
93+
94+
local key line=0
95+
local TMP_KEY_FILE
96+
TMP_KEY_FILE=$(mktemp "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")
97+
trap "rm -rf '$TMP_KEY_FILE' >/dev/null" RETURN INT TERM EXIT
98+
99+
SSHCOMMAND_IGNORE_LIST_WARNINGS="${SSHCOMMAND_IGNORE_LIST_WARNINGS:-false}"
100+
while read -r key; do
101+
line=$((line + 1))
102+
[[ -z "$key" ]] && continue
103+
[[ "$key" =~ ^#.*$ ]] && continue
104+
105+
echo "$key" >"$TMP_KEY_FILE"
106+
if ! ssh-keygen -lf "$TMP_KEY_FILE" &>/dev/null; then
107+
has_errors=true
108+
if [[ "$SSHCOMMAND_IGNORE_LIST_WARNINGS" == "false" ]]; then
109+
log-warn "${file} line $line failed ssh-keygen check."
110+
else
111+
log-warn "${file} line $line failed ssh-keygen check, ignoring."
112+
fi
113+
fi
114+
done <"${file}"
115+
116+
if [[ "$has_errors" == "true" ]]; then
117+
return 1
118+
fi
119+
}
120+
89121
log-fail() {
90122
declare desc="Log fail formatter"
91123
echo "$@" 1>&2
92124
exit 1
93125
}
94126

127+
log-warn() {
128+
declare desc="Log warn formatter"
129+
echo "$@" 1>&2
130+
}
131+
95132
log-verbose() {
96133
declare desc="Log verbose formatter"
97134
if [[ -n "$SSHCOMMAND_VERBOSE_OUTPUT" ]]; then
@@ -209,6 +246,11 @@ sshcommand-list() {
209246
[[ -e "$userhome/.ssh/authorized_keys" ]] || log-fail "authorized_keys not found for $USER"
210247
[[ -s "$userhome/.ssh/authorized_keys" ]] || log-fail "authorized_keys is empty for $USER"
211248

249+
SSHCOMMAND_IGNORE_LIST_WARNINGS="${SSHCOMMAND_IGNORE_LIST_WARNINGS:-false}"
250+
if ! fn-verify-file "$userhome/.ssh/authorized_keys" && [[ "$SSHCOMMAND_IGNORE_LIST_WARNINGS" == "false" ]]; then
251+
return 1
252+
fi
253+
212254
if [[ -n "$OUTPUT_TYPE" ]] && [[ "$OUTPUT_TYPE" == "json" ]]; then
213255
data=$(sed --silent --regexp-extended \
214256
's/^command="FINGERPRINT=(\S+) NAME=(\\"|)(.*)\2 `.*",(\S+).*/{ "fingerprint": "\1", "name": "\3", "SSHCOMMAND_ALLOWED_KEYS": "\4" }/p' \

0 commit comments

Comments
 (0)