portsnap broken?
Matthew D. Fuller
fullermd at over-yonder.net
Sun Jul 7 02:31:57 UTC 2019
On Wed, Jul 03, 2019 at 10:11:41AM +0200 I heard the voice of
Kurt Jaeger, and lo! it spake thus:
>
> > With a little script to pull the snapdates:
> > [...]
>
> Nice! Can you put that script somewhere for others to use ?
It's pretty small and straightforward. Attached. It _is_ based on a
bit of reverse-engineering of /usr/sbin/portsnap, so there may well be
a better way already extant of getting the info (and there probably
should be, if there isn't), but it Works For Me...
-------------- next part --------------
#!/usr/bin/env perl
use strict;
use warnings;
# Find the server list
my @servers;
{
use Net::DNS;
my $res = Net::DNS::Resolver->new;
my $srv = $res->search('_http._tcp.portsnap.freebsd.org', 'SRV');
die "Nothing from SRV request: @{[$res->errorstring]}\n" unless $srv;
foreach my $rr (grep { $_->type eq 'SRV' } $srv->answer)
{
my $si = {
'priority' => $rr->priority,
'host' => $rr->target,
};
push @servers, $si;
}
@servers = sort {
my $r;
return $r if($r = ($a->{priority} <=> $b->{priority}));
return $r if($r = ($a->{host} cmp $b->{host}));
return 0;
} @servers;
}
# We need to store temp files to go through openssl...
my $tmpdir;
{
use File::Temp qw/tempdir/;
$tmpdir = tempdir(CLEANUP => 1);
die "Failed making tempdir" unless -d $tmpdir;
}
# Load snapshot info and check timestamp from each
for my $s (@servers)
{
my $host = $s->{host};
my $key = "http://$host/pub.ssl";
my $snap = "http://$host/latest.ssl";
my $keyout = "$tmpdir/$host.key";
my $snapout = "$tmpdir/$host.snap";
use LWP::UserAgent;
my $web = LWP::UserAgent->new(timeout => 5);
my $res = $web->get($key, ':content_file' => $keyout);
if(!$res->is_success)
{
$s->{failed} = 1;
print STDERR "$host key fetch failed: @{[$res->status_line]}\n";
next;
}
$res = $web->get($snap, ':content_file' => $snapout);
if(!$res->is_success)
{
$s->{failed} = 1;
print STDERR "$host snap fetch failed: @{[$res->status_line]}\n";
next;
}
# Now we use openssl to dissect
my @cmd = ( qw(openssl rsautl -pubin -inkey), $keyout, '-verify' );
use IPC::Run3;
my ($out, $err);
run3(\@cmd, $snapout, \$out, \$err);
my $rc = $? >> 8;
if($rc != 0)
{
$s->{failed} = 1;
print STDERR "$host: openssl returned $rc\n$err\n";
next;
}
# Second field of $out is the timestamp
chomp $out;
my $ts = (split/\|/, $out)[1];
$s->{timestamp} = $ts;
}
# And show the results
my $now = time;
for my $s (@servers)
{
my $host = $s->{host};
(my $sh = $host) =~ s/\.portsnap\.freebsd\.org$//;
if($s->{failed})
{
print "$sh: failed\n";
next;
}
my $pri = $s->{priority};
my $ts = $s->{timestamp};
# How old?
my $old = $now - $ts;
my $age;
if($old > 86400)
{
my $days = int($old / 86400);
$age .= "$days days, ";
$old -= ($days * 86400);
}
{
my $hours = int($old / 3600);
$old -= ($hours * 3600);
my $mins = int($old / 60);
$old -= ($mins * 60);
$age .= sprintf("%02d:%02d:%02d", $hours, $mins, $old);
}
use Date::Format;
chomp(my $ftime = ctime($ts));
printf "%20s: $ftime ($age ago)\n", $sh;
}
More information about the freebsd-ports
mailing list