Use constant for name of gpgv executable to enable testing with mock gpgv
authorJacob Bachmeyer <jcb@gnu.org>
Sat, 27 Feb 2021 22:28:56 +0000 (16:28 -0600)
committerJacob Bachmeyer <jcb@gnu.org>
Sat, 27 Feb 2021 22:28:56 +0000 (16:28 -0600)
upload-ftp-v1.2.pl

index e57f56f2b68681851853de4475980d015f8d226c..09dc0b21d77652942798457edb83d06efe21059e 100755 (executable)
@@ -102,6 +102,9 @@ use warnings;
 
 use constant ();       # load this now for use in later BEGIN blocks
 
+use FindBin;
+use File::Spec;
+
 use Net::SMTP;
 use Date::Manip;
 use Sys::Syslog qw(:DEFAULT setlogsock);
@@ -165,6 +168,16 @@ BEGIN {
            );
 
   constant->import(IN_TEST_MODE => $TestingMode);
+
+  if ($TestingMode) {
+    # We trust our test environment, but taint mode forces this issue.
+    $FindBin::Bin =~ m[^(/[[:graph:] ]+)$]
+      or die "strange base path for test environment";
+    my $gpgv_mock = File::Spec->catfile($1, qw(testsuite lib exec mockgpgv));
+    constant->import(GPGV_BIN => $gpgv_mock);
+  } else {
+    constant->import(GPGV_BIN => '/usr/bin/gpgv');
+  }
 }
 
 our $style;
@@ -220,18 +233,34 @@ my $email_always = 'ftp-upload-script@gnu.org';  # e.g., ftp-upload@gnu.org
 # syslog destination
 my $facility = "LOCAL5";
 
-if (IN_TEST_MODE) { # override the above for testing
+if (IN_TEST_MODE) {    # override the above for testing
   # override PATH
   # override file paths to our testcase environment
   # verify mock gpgv
+  {
+    open my $gpgv,'-|',GPGV_BIN, '--version'
+      or die "run gpgv --version: $!";
+    my $hline = <$gpgv>;       # get the first line
+    1 while defined <$gpgv>;   # read and discard the rest
+    $hline =~ m/gpgv \(Testing mock\)/
+      or die "test mode selected, but mock gpgv not found";
+    close $gpgv;
+  }
   # verify configuration for mock smtpd
   die "ftp-upload: test mode: TEST_SMTP_PORT not valid"
     unless $ENV{TEST_SMTP_PORT} && $ENV{TEST_SMTP_PORT} =~ m/^\d+$/;
   # verify configuration for mock syslog
   die "ftp-upload: test mode: TEST_SYSLOG_SOCKET not valid"
     unless $ENV{TEST_SYSLOG_SOCKET} && -S $ENV{TEST_SYSLOG_SOCKET} && -w _;
-} else {
-  # TODO: make sure the mock gpgv is NOT in our PATH
+} else {               # in production mode
+  # ensure we are using the real gpgv
+  open my $gpgv,'-|',GPGV_BIN, '--version'
+    or die "run gpgv --version: $!";
+  my $hline = <$gpgv>;         # get the first line
+  1 while defined <$gpgv>;     # read and discard the rest
+  $hline =~ m/gpgv \(GnuPG\)/
+    or die "production mode selected, but real gpgv not found";
+  close $gpgv;
 }
 
 my %info;   # package being processed; a global so fatal and mail can use it
@@ -1001,7 +1030,7 @@ sub verify_keyring {
     # We need what gpgv writes to STDERR to determine the timestamp
     # Hence the silly trick with storing the return code of gpgv in
     # the command output
-    my @verify_args = ("/usr/bin/gpgv", "--keyring", $_,
+    my @verify_args = (GPGV_BIN, "--keyring", $_,
                       $directive_file,"2>&1",";echo \$?");
 
     my $verify_str = join(' ',@verify_args);
@@ -1055,7 +1084,7 @@ sub check_files {
   my $valid = 0;
   foreach my $keyring (@keyrings) {
     # Verify that the file has been correctly signed with a valid signature.
-    my @verify_args = ("/usr/bin/gpgv", "--keyring", $keyring,
+    my @verify_args = (GPGV_BIN, "--keyring", $keyring,
           $sig_file, $upload_file);
     if (!system (@verify_args)) {
       $valid = 1;