From: Jacob Bachmeyer Date: Wed, 26 Oct 2022 04:26:57 +0000 (-0500) Subject: Use epoch timestamp from GPG instead of parsing the display timestamp X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=ccf3c558f60a62b0e1259ec105cab48da7797242;p=gatekeeper.git Use epoch timestamp from GPG instead of parsing the display timestamp The --status-fd option reports timestamps in epoch time directly, although the documentation indicates that ISO 8601 format is also possible. This change eliminates several manipulations and removes the dependency on the external Date::Manip module. --- diff --git a/gatekeeper.pl b/gatekeeper.pl index 31622b5..89a95c8 100755 --- a/gatekeeper.pl +++ b/gatekeeper.pl @@ -176,7 +176,6 @@ use File::Spec; use Pod::Usage; use Net::SMTP; -use Date::Manip; use Sys::Syslog qw(:DEFAULT setlogsock); use Getopt::Long; use Text::Wrap; @@ -1351,7 +1350,14 @@ The 64-bit long key ID of the key that signed TEXT, if available. The fingerprint of the PGP key that signed TEXT, if available. -=item ... +=item sig_creation + +Epoch timestamp of signature. + +=item sig_expiration + +Epoch timestamp at which the signature expires, if the signature expires. +This key is only present if the signature has an expiration date. =back @@ -1556,9 +1562,13 @@ sub verify_clearsigned_message { if 0 == $ret{exitcode}; } elsif ($1 eq 'ERR') { # an ERRSIG line $verdict_status++; - if (m/\G(\d+)\s(\d+)\s([[:xdigit:]]{2})\s([-:T[:digit:]]+)\s(\d+)/gc) { + if (m/\G(\d+)\s(\d+)\s([[:xdigit:]]{2})\s([-:T[:digit:]Z+]+)\s(\d+) + /gcx) { # $1 -- pubkey algorithm $2 -- digest algorithm # $3 -- timestamp $4 -- result code + ftp_abort('gpgv returned an ISO8601 timestamp; implementation needed') + if $3 =~ m/T/; + $ret{sig_creation} = $3; } else { push @{$ret{TILT}}, 'gpgv ERRSIG line failed parsing' } @@ -1568,7 +1578,7 @@ sub verify_clearsigned_message { $check_status++; } } elsif (m/\G(VALID)SIG\s([[:xdigit:]]+)\s(\d{4}-\d{2}-\d{2})\s - ([-:T[:digit:]]+)\s([-:T[:digit:]]+)\s(\d+)\s(\S+)\s + ([-:T[:digit:]Z+]+)\s([-:T[:digit:]Z+]+)\s(\d+)\s(\S+)\s (\d+)\s(\d+)\s([[:xdigit:]]{2})\s([[:xdigit:]]+) /gcx) { $verdict_status++; @@ -1580,6 +1590,11 @@ sub verify_clearsigned_message { # $11 -- primary key fingerprint $ret{key_fingerprint} = $2; $ret{key_longid} = substr $2,-16; + ftp_abort('gpgv returned an ISO8601 timestamp; implementation needed') + if $4 =~ m/T/ || $5 =~ m/T/; + $ret{sig_creation} = $4; + # GPG reports 0 if the signature does not expire + $ret{sig_expiration} = $5 if $5 > 0; } } close $status or ftp_abort('close in-memory file for gpgv status'); @@ -1917,33 +1932,16 @@ sub read_directive_file { # than the one for the last file that was uploaded # This is only relevant when a 'filename' directive is present, hence the # test of the $filename_required variable. - if (($result->{raw_log} =~ /Signature made (.*)/) + if (defined $result->{sig_creation} && (exists($info{filename}))) { - my $timestr = $1; - - ftp_syslog('debug', "DEBUG: Signature made $1") if DEBUG; - - # Some versions of GPG also mention the key used to make the signature - # on this line, while others do not. The testing mock does. - $timestr =~ s/ using .*//; # trim to only timestamp - - # If the time/date string starts with a weekday - # (e.g. "Wed Apr 28 16:40:03 2004 EDT"), chop off the weekday - - # Date::Manip doesn't like it - $timestr =~ s/^[a-z]+? ([a-z]+)/$1/i; - - # We need to convert time/date strings like "Apr 28 16:40:03 2004 EDT" into - # "Apr 28 16:40:03 2004 EDT" for Date::Manip to understand them... - $timestr =~ - s/^([a-z]+? +\d{1,2}) (\d{2}:\d{2}:\d{2}) (\d{4}) (.*)$/$1 $3 $2 $4/i; - my $date = ParseDate($timestr); - my $epoch = UnixDate($date,"%s"); + ftp_syslog('debug', "DEBUG: Signature made " + .strftime('%a %b %d %H:%M:%S %Y %Z', + localtime $result->{sig_creation})) if DEBUG; # Verify that this timestamp is not too far in the future. We allow a # discrepancy of 1 day so we don't have to worry about timezones - my $now = time(); - if ($epoch > ($now + 24*3600)) { + if ($result->{sig_creation} > (time() + 24*3600)) { fatal("GPG signed upload from the future - not allowed. " ."Please make sure your clock is set correctly, " ."resign the directive file, and upload again. " @@ -1954,7 +1952,7 @@ sub read_directive_file { my $full_filename = $info{"directory"} . '/' . $uploaded_file; $full_filename =~ s/\/\//\//g; # Just in case... - advance_timestamp_ratchet($full_filename, $epoch); + advance_timestamp_ratchet($full_filename, $result->{sig_creation}); } elsif (exists($info{filename})) { fatal("gpg verification problem: could not extract timestamp",1); }