#!/usr/bin/perl
+use strict;
+use warnings;
-open(SSHFP_JS, ">", "include/sshfp.js") || die $!;
+use Digest::SHA qw(sha256_hex);
+use MIME::Base64;
-print SSHFP_JS qq|var SSHFP_RECORDS = [\n|;
+my %hosts;
if (-f "/etc/ssh/ssh_known_hosts")
{
- open(SSHFP, "-|","sshfp", "-k", "/etc/ssh/ssh_known_hosts") || die $!;
+ open(HOSTS, "<", "/etc/ssh/ssh_known_hosts") || die $!;
- while (my $line = <SSHFP>)
+ while (my $line = <HOSTS>)
{
- if ($line =~ /^(\S+) IN SSHFP (\d+) (\d+) ([0-9A-F]+)$/)
+ last if $line =~ /^# Manually maintained records$/;
+
+ if ($line =~ /^([^, ]+)\S* (\S+) (\S+)$/)
{
my $host = $1;
my $algorithm = $2;
- my $type = $3;
- my $value = $4;
+ my $value = uc(sha256_hex(decode_base64($3)));
+
+ $host =~ s/\.openstreetmap\.org$//;
- print SSHFP_JS qq| SSHFP("${host}", ${algorithm}, ${type}, "${value}");\n|;
+ if ($algorithm ne "2")
+ {
+ $hosts{$host} ||= {};
+
+ $hosts{$host}->{$algorithm} = $value;
+ }
}
- else
+ }
+
+ close(HOSTS);
+}
+
+open(SSHFP_JS, ">", "include/sshfp.js") || die $!;
+
+print SSHFP_JS qq|var SSHFP_RECORDS = [\n|;
+
+foreach my $host (sort keys %hosts)
+{
+ if ($hosts{$host}->{"ecdsa-sha2-nistp256"} || $hosts{$host}->{"ssh-ed25519"})
+ {
+ if ($hosts{$host}->{"ecdsa-sha2-nistp256"})
{
- warn $line;
+ print SSHFP_JS sshfp_record($host, "3", $hosts{$host}->{"ecdsa-sha2-nistp256"});
}
- }
- close(SSHFP);
+ if ($hosts{$host}->{"ssh-ed25519"})
+ {
+ print SSHFP_JS sshfp_record($host, "4", $hosts{$host}->{"ssh-ed25519"});
+ }
+ }
+ elsif ($hosts{$host}->{"ssh-rsa"})
+ {
+ print SSHFP_JS sshfp_record($host, "1", $hosts{$host}->{"ssh-rsa"});
+ }
}
print SSHFP_JS qq|];\n|;
close(SSHFP_JS);
exit 0;
+
+sub sshfp_record
+{
+ my $host = shift;
+ my $algorithm = shift;
+ my $value = shift;
+
+ return qq| SSHFP("${host}", ${algorithm}, 2, "${value}"),\n|;
+}