my %options = ( replace => undef );
my %header = ( version => undef, options => \%options,
- package => undef, directory => undef );
+ package => undef, directory => undef, filename => undef );
my @ops = ([header => \%header]);
- my $have_install = 0; # can only install one file per directive
- my $filename;
+ my $install = undef; # can only install one file per directive
+ # The 'install' op carries the name of the file to install, while the
+ # 'filename' element binds the directive signature to its intended
+ # upload. These are assumed to be the same in protocol 1.2 and earlier.
my $cnt = 0; # TODO: remove this
{ # Extract version first, since directive elements may be in any order.
# Only let them specify one filename directive.
fatal("Only one filename directive is allowed per directive file. "
."Error at filename directive: $val.",1,$directive_file_contents)
- if exists $info{"filename"};
+ if defined $header{filename};
- $filename = $val;
+ $header{filename} = $val;
$info{"filename"} = {"value" => $val, "order" => $cnt++}; # ok.
} elsif ($tainted_cmd eq 'version') {
# already handled above
1,$directive_file_contents);
}
- if (!$have_install && $filename && defined $header{directory})
- { push @ops, [install => $filename]; $have_install = 1 }
+ if (!defined($install)
+ && defined $header{filename} && defined $header{directory})
+ { push @ops, ($install = [install => $header{filename}]) }
}
return \@ops;
}
}
- # The above check that the directive contains at least one command
- # ensures that we either have a filename or do not need one before we
- # reach this point. This is temporarily kept as scaffolding.
- my $filename_required = exists($info{filename});
-
- if ($filename_required) {
+ # Check if this directive carries a file/validate stem if needed
+ if (defined $op_header->{filename}) {
# Ben Pfaff <blp@cs.stanford.edu> wrote:
# First, "gpg -b" doesn't verify that the filename of the signed
# data is correct. This means that I can rename gcc-1.2.3.tar.gz
# correctly. This opens up the possibility for confusion, but in
# itself it's not a huge deal.
#
- # To fix this, we require a 'filename:' line in the directive file
- # that needs to match the name of the uploaded file.
-
- # Filename has to match the name of the uploaded file
+ # To fix this, we require a 'filename:' line in the directive file that
+ # needs to match the name of the uploaded file and serves to bind the
+ # directive signature and the uploaded packet. We already know that
+ # the name of the uploaded file must match the stem of the directive
+ # file name; this is how it was recognized as part of the packet.
fatal("The filename directive does not match name of the uploaded file."
- ."\n\n Filename directive: $info{filename}{value}"
- ."\n Uploaded file: $uploaded_file\n",1)
- if ($uploaded_file ne $info{filename}{value});
-
- # Filename has to match the name of this directive file (a bit
- # paranoid, but hey...)
- fatal("filename $info{filename}{value} does not match name of directive "
- ."file $directive_file",1)
- if ($directive_file ne "$info{filename}{value}.directive.asc");
+ ."\n\n Filename directive: $op_header->{filename}"
+ ."\n Uploaded file: $stem\n",1)
+ unless $stem eq $op_header->{filename};
}
my $retval = verify_keyring($directive_file,$directive_file_contents,
# 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 (($retval =~ /Signature made (.*)/) && ($filename_required)) {
+ if (($retval =~ /Signature made (.*)/) && (exists($info{filename}))) {
my $timestr = $1;
ftp_syslog('debug', "DEBUG: Signature made $1") if DEBUG;
$full_filename =~ s/\/\//\//g; # Just in case...
advance_timestamp_ratchet($full_filename, $epoch);
- } elsif ($filename_required) {
+ } elsif (exists($info{filename})) {
fatal("gpg verification problem: could not extract timestamp",1);
}