#!/bin/bash
set -uE -o pipefail
umask 077
print_usage() {
local rc="${1:-0}"; shift
local msg="${*:-}"
if [[ -n "$msg" ]] ; then
>&2 echo "$msg"
fi
>&2 echo "Syntax: ${0##*/} <path>"
exit $rc
}
abort() {
local msg="$*"
>&2 echo "$msg; aborting!"
exit 1
}
is_secure_permissions() {
local file="$1"
local perms="$(stat -c %A "$file")"
if [[ ! "${perms:4:6}" == "------" ]] ; then
return 1
else
return 0
fi
}
is_passphraseless() {
local src_key="$1"
local sock="$(mktemp -u -t "${0##*/}.XXXXXXXX")"
local dot_ssh="$(mktemp -d -t "${0##*/}.XXXXXXXX")"
local test_key="$(mktemp --tmpdir="$dot_ssh" -t "${0##*/}.XXXXXXXX")"
local rc=1
trap "rm -rf --one-file-system '$sock' '$dot_ssh'" EXIT INT TERM HUP USR1 USR2
cat "$src_key" > "$test_key"
export SSH_AUTH_SOCK="$sock" SSH_AGENT_PID=""
eval $(ssh-agent -a "$sock" -t 3) >/dev/null
if [[ -n "$SSH_AGENT_PID" ]] && \
[[ -n "$SSH_AUTH_SOCK" ]] && [[ -S "$SSH_AUTH_SOCK" ]] ; then
if echo | ssh-add "$test_key" >/dev/null 2>&1 ; then
printf "$src_key\t"
ssh-add -L
ssh-add -D >/dev/null 2>&1
if ! ssh-agent -k >/dev/null ; then
kill -9 $SSH_AGENT_PID
rm -f "$sock"
fi
rc=0
fi
else
rc=2
fi
rm -rf --one-file-system "$sock" "$dot_ssh" && \
trap - EXIT INT TERM HUP USR1 USR2
return $rc
}
main() {
if [[ ! $# == 1 ]] ; then
print_usage 64 "Missing mandatory path argument."
fi
local root="$1"
if [[ ! -e "$root" ]] ; then
abort "Path $root does not exist"
elif [[ ! -d "$root" ]] ; then
abort "Path $root is not a directory"
fi
find "$root" -maxdepth 3 -type f -path "*/.ssh/*" -or -name "id_" 2>&1 \
| grep -v ": Permission denied$" \
| while read file ; do
if [[ ! -r "$file" ]] ; then
>&2 echo "Cannot read $file; skipping."
continue
elif egrep -q '^-----BEGIN [A-Z0-9]+ PRIVATE KEY-----' "$file" ; then
if ! is_secure_permissions "$file" ; then
>&2 echo "$file $(stat -c %A "$file") permissions are not secure."
fi
if is_passphraseless "$file" ; then
>&2 echo "$file has no passphrase set."
elif [[ $? == 1 ]] ; then
>&2 echo "$file is secured."
else
>&2 echo "$file could not be tested."
fi
fi
done
}
main "$@"
exit