Factor timestamp ratchet out of read_directive_file
authorJacob Bachmeyer <jcb@gnu.org>
Thu, 20 Oct 2022 04:24:16 +0000 (23:24 -0500)
committerJacob Bachmeyer <jcb@gnu.org>
Thu, 20 Oct 2022 04:24:16 +0000 (23:24 -0500)
gatekeeper.pl

index 6e6348ab89b0f7e0c487dbe70200e5cd60afc80b..d1969c9fcb63648fca85642054b413336a9b3d48 100755 (executable)
@@ -1460,6 +1460,70 @@ sub interpret_directive {
   return \@ops;
 }
 
+=item $epoch = advance_timestamp_ratchet ( $full_filename, $epoch,  )
+
+Locate the stored timestamp for FULL_FILENAME, which is relative to the
+root of the managed tree, verify that the given EPOCH is newer, and update
+the stored timestamp to EPOCH.  Return the previous stored timestamp.
+
+An exception is thrown if the given EPOCH timestamp is not newer than the
+stored value.  An undefined value is returned if FULL_FILENAME did not have
+a stored timestamp.
+
+=cut
+
+sub advance_timestamp_ratchet {
+  my $full_filename = shift;
+  my $new_epoch = shift;
+
+  # Now we need to flock the our 'serials' file;
+  # verify the epoch value there/update it, etc.
+  my %serials = ();
+  my @serials = ();
+
+  if (!-e $serials_path) {
+    open(SERIALS,">$serials_path");
+    flock(SERIALS,2);          # Take exclusive lock
+  } else {
+    open(SERIALS,"+<$serials_path");
+    flock(SERIALS,2);          # Take exclusive lock
+    @serials = <SERIALS>;
+    foreach (@serials) {
+      my ($tmp1,$tmp2) = /(.*?):(.*?)\n/;
+      $tmp1 =~ s/\s+//g;
+      $tmp2 =~ s/\s+//g;
+      $serials{$tmp1} = $tmp2;
+    }
+  }
+  seek(SERIALS,0,0);
+
+  my $old_epoch = $serials{$full_filename};
+
+  # Verify that this is really a new version of the file!
+  if (exists($serials{$full_filename})
+      && ($serials{$full_filename} >= $new_epoch)) {
+    flock(SERIALS,4);          # Release lock
+    fatal("Gpg signed upload older than/same timestamp as existing version "
+         ."- not allowed. In other words, the filenames for the triplet "
+         ."you have uploaded are an exact match for a triplet that has "
+         ."been uploaded in the past, and the directive file that you "
+         ."just uploaded has been signed before or at the same time as "
+         ."the directive file for the triplet that was uploaded earlier. "
+         ."Most likely, you are re-uploading an old triplet.",1);
+  }
+
+  $serials{$full_filename} = $new_epoch;
+
+  foreach my $key (keys %serials) {
+    print SERIALS "$key:$serials{$key}\n";
+  }
+
+  flock(SERIALS,4);            # Release lock
+  close(SERIALS);
+
+  return $old_epoch;
+}
+
 sub read_directive_file {
   my $directive_file = shift;
   my $uploaded_file = shift;
@@ -1621,50 +1685,10 @@ sub read_directive_file {
            ."change the filename for your triplet.",1);
     }
 
-    # Now we need to flock the our 'serials' file;
-    # verify the epoch value there/update it, etc.
-    my %serials = ();
-    my @serials = ();
-
-    if (!-e $serials_path) {
-      open(SERIALS,">$serials_path");
-      flock(SERIALS,2); # Take exclusive lock
-    } else {
-      open(SERIALS,"+<$serials_path");
-      flock(SERIALS,2); # Take exclusive lock
-      @serials = <SERIALS>;
-      foreach (@serials) {
-       my ($tmp1,$tmp2) = /(.*?):(.*?)\n/;
-       $tmp1 =~ s/\s+//g;
-       $tmp2 =~ s/\s+//g;
-       $serials{$tmp1} = $tmp2;
-      }
-    }
-    seek(SERIALS,0,0);
     my $full_filename = $info{"directory"} . '/' . $uploaded_file;
     $full_filename =~ s/\/\//\//g; # Just in case...
 
-    # Verify that this is really a new version of the file!
-    if (exists($serials{$full_filename})
-       && ($serials{$full_filename} >= $epoch)) {
-      flock(SERIALS,4); # Release lock
-      fatal("Gpg signed upload older than/same timestamp as existing version "
-           ."- not allowed. In other words, the filenames for the triplet "
-           ."you have uploaded are an exact match for a triplet that has "
-           ."been uploaded in the past, and the directive file that you "
-           ."just uploaded has been signed before or at the same time as "
-           ."the directive file for the triplet that was uploaded earlier. "
-           ."Most likely, you are re-uploading an old triplet.",1);
-    }
-
-    $serials{$full_filename} = $epoch;
-
-    foreach my $key (keys %serials) {
-      print SERIALS "$key:$serials{$key}\n";
-    }
-
-    flock(SERIALS,4); # Release lock
-    close(SERIALS);
+    advance_timestamp_ratchet($full_filename, $epoch);
   } elsif ($filename_required) {
     fatal("gpg verification problem: could not extract timestamp",1);
   }