diff options
Diffstat (limited to 'get-host-keys')
-rwxr-xr-x | get-host-keys | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/get-host-keys b/get-host-keys new file mode 100755 index 0000000..f55b6cd --- /dev/null +++ b/get-host-keys | |||
@@ -0,0 +1,89 @@ | |||
1 | #!/bin/sh | ||
2 | die() | ||
3 | { | ||
4 | printf "Error: %s\n" "$*" >&2 | ||
5 | exit 1 | ||
6 | } | ||
7 | |||
8 | b16_to_b32() | ||
9 | { | ||
10 | printf %s "$1" | basez -x -d | basez -j -l | tr -d = | ||
11 | } | ||
12 | |||
13 | to_domain_suffix() | ||
14 | { | ||
15 | local hashtype=2 | ||
16 | local keystring keytype sshfp_b16 sshfp_b32 | ||
17 | [ -f "$1" ] || return | ||
18 | [ -s "$1" ] || return | ||
19 | sshfp_raw=$(ssh-keygen -r . -f "$1" | grep -E -e "^. IN SSHFP [0-9]+ $hashtype ") | ||
20 | case "$sshfp_raw" in | ||
21 | '. IN SSHFP 1 '*) keytype=1; keystring=rsa ;; | ||
22 | '. IN SSHFP 4 '*) keytype=4; keystring=ed25519 ;; | ||
23 | *) return 1 ;; | ||
24 | esac | ||
25 | sshfp_b16=$(printf '%s' "$sshfp_raw" | sed -ne "s/^. IN SSHFP $keytype $hashtype //p") && | ||
26 | [ "$sshfp_b16" ] || die "could not determine ssh client fingerprint" | ||
27 | sshfp_b32=$(b16_to_b32 "$sshfp_b16") | ||
28 | |||
29 | printf %s.%s.%s "$sshfp_b32" "$keystring" cryptonomic.net | tail -c64 | ||
30 | } | ||
31 | |||
32 | crypto_validate_hostname() | ||
33 | { | ||
34 | local host="$1" t r | ||
35 | t=$(mktemp) | ||
36 | case "$host" in | ||
37 | *.ed25519.cryptonomic.net) | ||
38 | ssh-keyscan -t ed25519 "$host" 2>/dev/null | while read h keytype keydata comment | ||
39 | do | ||
40 | case "$h $keytype" in | ||
41 | "$host ssh-ed25519") | ||
42 | echo "$keytype $keydata" >> "$t" | ||
43 | break | ||
44 | ;; | ||
45 | esac | ||
46 | done ;; | ||
47 | *) die "unsupported hostname: $host" ;; | ||
48 | esac | ||
49 | if validated=$(to_domain_suffix "$t") | ||
50 | then | ||
51 | case "$host" in | ||
52 | "$validated" | *."$validated" ) | ||
53 | read line < "$t" | ||
54 | echo "$host $line" | ||
55 | rm -f "$t" | ||
56 | return 0 | ||
57 | ;; | ||
58 | esac | ||
59 | fi | ||
60 | rm -f "$t" | ||
61 | false | ||
62 | } | ||
63 | |||
64 | set -e | ||
65 | _TEMP_DIR_=$(mktemp -d) | ||
66 | cd "$_TEMP_DIR_" | ||
67 | trap 'rm -rf "$_TEMP_DIR_"' EXIT | ||
68 | host=${1:-borges} | ||
69 | |||
70 | # ssh-keygen -F "${host#*@}" | grep -v '^#' > ssh_known_hosts 2>/dev/null | ||
71 | # touch ssh_known_hosts.stamp -r ssh_known_hosts | ||
72 | |||
73 | line=$(crypto_validate_hostname "$host") || die "could not validate hostname cryptographically" | ||
74 | |||
75 | echo "$line" > ssh_known_hosts | ||
76 | cp ssh_known_hosts ssh_known_hosts~ | ||
77 | |||
78 | ssh \ | ||
79 | -F /dev/null \ | ||
80 | -o GlobalKnownHostsFile=$PWD/ssh_known_hosts \ | ||
81 | -o UserKnownHostsFile=$PWD/ssh_known_hosts \ | ||
82 | -o UpdateHostKeys=yes \ | ||
83 | -o PasswordAuthentication=no \ | ||
84 | -o StrictHostKeyChecking=yes \ | ||
85 | -n -T \ | ||
86 | "$host" >/dev/null 2>&1 | ||
87 | |||
88 | cat ssh_known_hosts | ||
89 | |||