diff options
author | Karl Berry <karl@freefriends.org> | 2016-04-13 22:30:20 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2016-04-13 22:30:20 +0000 |
commit | b9b0dce9293c9bd6d12ff53d088dfdb8fd33fef5 (patch) | |
tree | f968612769077b5f00a5d7bbc1bae35c7466d607 /Build/source/texk | |
parent | b9b417030377e161a8e9a259bb04cd5bc27773dd (diff) |
doc,regen,sync
git-svn-id: svn://tug.org/texlive/trunk@40492 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk')
-rw-r--r-- | Build/source/texk/tests/TeXLive/TLConfig.pm | 25 | ||||
-rw-r--r-- | Build/source/texk/tests/TeXLive/TLUtils.pm | 240 | ||||
-rwxr-xr-x | Build/source/texk/texlive/linked_scripts/texlive/fmtutil.pl | 20 | ||||
-rwxr-xr-x | Build/source/texk/texlive/linked_scripts/texlive/tlmgr.pl | 180 |
4 files changed, 381 insertions, 84 deletions
diff --git a/Build/source/texk/tests/TeXLive/TLConfig.pm b/Build/source/texk/tests/TeXLive/TLConfig.pm index 4d35866893d..972f708f893 100644 --- a/Build/source/texk/tests/TeXLive/TLConfig.pm +++ b/Build/source/texk/tests/TeXLive/TLConfig.pm @@ -5,7 +5,7 @@ package TeXLive::TLConfig; -my $svnrev = '$Revision: 40251 $'; +my $svnrev = '$Revision: 40475 $'; my $_modulerevision; if ($svnrev =~ m/: ([0-9]+) /) { $_modulerevision = $1; @@ -49,6 +49,9 @@ BEGIN { $NetworkTimeout $PartialEngineSupport $F_OK $F_WARNING $F_ERROR $F_NOPOSTACTION + $ChecksumLength + $ChecksumProgram + $ChecksumExtension ); @EXPORT = @EXPORT_OK; } @@ -57,9 +60,10 @@ BEGIN { # network packages, and in menu names, and other places. $ReleaseYear = 2016; -# users can upgrade from this year to the current year; maybe a spread -# of more than one year will be useful at some point, but not now. -$MinRelease = 2013; # upgrade from 2013 to 2015 should work, we'll see +# users can upgrade from this year to the current year; might be the +# same as the release year, or any number of releases earlier. +# Generally not tested. +$MinRelease = 2013; # users can NOT upgrade due to internal changes, force a full installation #$MinRelease = $ReleaseYear; @@ -193,7 +197,7 @@ our %TLPDBSettings = ( our $WindowsMainMenuName = "TeX Live $ReleaseYear"; # Comma-separated list of engines which do not exist on all platforms. -our $PartialEngineSupport = "luajittex"; +our $PartialEngineSupport = "luajittex,mfluajit"; # timeout for network connections (wget, LWP) in seconds our $NetworkTimeout = 30; @@ -211,6 +215,17 @@ our $F_ERROR = 2; # all fine, but no need to run post actions our $F_NOPOSTACTION = 4; +# The length of a checksum generated by tlchecksum and contained in +# texlive.tlpdb.checksum. Needs to be in agreement with the hash +# method used in TLUtils::tlchecksum and TLUtils::tldigest +$ChecksumLength = 128; + +# The program generating the checksum for the file given as first +# argument +$ChecksumProgram = "sha512sum"; + +# The extension of the checksum file +$ChecksumExtension = "sha512"; 1; diff --git a/Build/source/texk/tests/TeXLive/TLUtils.pm b/Build/source/texk/tests/TeXLive/TLUtils.pm index ac14adf3f3e..bc4ab402d9d 100644 --- a/Build/source/texk/tests/TeXLive/TLUtils.pm +++ b/Build/source/texk/tests/TeXLive/TLUtils.pm @@ -5,7 +5,7 @@ package TeXLive::TLUtils; -my $svnrev = '$Revision: 40251 $'; +my $svnrev = '$Revision: 40460 $'; my $_modulerevision; if ($svnrev =~ m/: ([0-9]+) /) { $_modulerevision = $1; @@ -98,6 +98,10 @@ C<TeXLive::TLUtils> -- utilities used in TeX Live infrastructure TeXLive::TLUtils::give_ctan_mirror(); TeXLive::TLUtils::give_ctan_mirror_base(); TeXLive::TLUtils::tlmd5($path); + TeXLive::TLUtils::tlchecksum($path); + TeXLive::TLUtils::setup_gpg(); + TeXLive::TLUtils::verify_checksum($file, $url); + TeXLive::TLUtils::verify_signature($file, $url); TeXLive::TLUtils::compare_tlpobjs($tlpA, $tlpB); TeXLive::TLUtils::compare_tlpdbs($tlpdbA, $tlpdbB); TeXLive::TLUtils::report_tlpdb_differences(\%ret); @@ -172,6 +176,10 @@ BEGIN { &create_mirror_list &extract_mirror_entry &tlmd5 + &tlchecksum + &setup_gpg + &verify_checksum + &verify_signature &wsystem &xsystem &run_cmd @@ -198,6 +206,7 @@ BEGIN { use Cwd; use Digest::MD5; +use Digest::SHA; use Getopt::Long; use File::Temp; @@ -1957,7 +1966,7 @@ not agree. Does nothing if neither of the check arguments is given. sub check_file { my ($xzfile, $checksum, $size) = @_; if ($checksum) { - if (tlmd5($xzfile) ne $checksum) { + if (tlchecksum($xzfile) ne $checksum) { tlwarn("TLUtils::check_file: found $xzfile, but hashsums differ, removing it.\n"); unlink($xzfile); return; @@ -2239,7 +2248,7 @@ sub setup_programs { # Return 0 if failure, 1 if success. # sub setup_unix_one { - my ($p, $def, $arg) = @_; + my ($p, $def, $arg, $donotwarn) = @_; our $tmp; my $test_fallback = 0; if (-r $def) { @@ -2313,9 +2322,13 @@ sub setup_unix_one { if ($ret == 0) { debug("Using system $p (tested).\n"); } else { - tlwarn("$0: Initialization failed (in setup_unix_one):\n"); - tlwarn("$0: could not find a usable $p.\n"); - tlwarn("$0: Please install $p and try again.\n"); + if ($donotwarn) { + debug("$0: initialization of $p failed but ignored!\n"); + } else { + tlwarn("$0: Initialization failed (in setup_unix_one):\n"); + tlwarn("$0: could not find a usable $p.\n"); + tlwarn("$0: Please install $p and try again.\n"); + } return 0; } } else { @@ -3578,6 +3591,221 @@ sub tlmd5 { } } +sub tldigest { + return (Digest::SHA::sha512_hex(shift)); +} +sub tl_short_digest { + return (Digest::MD5::md5_hex(shift)); +} + +sub tlchecksum { + my ($file) = @_; + if (-r $file) { + open(FILE, $file) || die "open($file) failed: $!"; + binmode(FILE); + my $cshash = Digest::SHA->new(512)->addfile(*FILE)->hexdigest; + close(FILE); + return $cshash; + } else { + tlwarn("tlchecksum: given file not readable: $file\n"); + return ""; + } +} + +sub tlchecksum_data { + my ($data) = @_; + my $cshash = Digest::SHA->new(512)->add($data)->hexdigest; + return $cshash; +} + + +=pod + +=item C<< setup_gpg() >> + +Tries to set up gpg command line C<$::gpg> used for +verification of downloads. + +Returns 1/0 on success/failure. + +=cut + +sub setup_gpg { + my $master = shift; + # first search for a gpg binary + return 0 if (!setup_unix_one( 'gpg' , '/no/such/path', '--version', 1)); + # ok, we found one + # Set up the gpg invocation: + $::gpg = "$::progs{'gpg'} "; + my $gpghome = ($ENV{'TL_GNUPGHOME'} ? $ENV{'TL_GNUPGHOME'} : + "$master/tlpkg/gpg" ); + $gpghome =~ s!/!\\!g if win32(); + my $gpghome_quote = "\"$gpghome\""; + # mind the final space for following args + $::gpg .= "--homedir $gpghome_quote "; + if ($ENV{'TL_GNUPGARGS'}) { + $::gpg .= $ENV{'TL_GNUPGARGS'}; + } else { + $::gpg .= "--no-secmem-warning --no-permission-warning "; + } + debug("gpg command line: $::gpg\n"); + return 1; +} + +=pod + +=item C<< slurp_file($file) >> + +Reads the whole file and returns the content in a scalar. + +=cut + +sub slurp_file { + my $file = shift; + my $file_data = do { + local $/ = undef; + open my $fh, "<", $file || die "open($file) failed: $!"; + <$fh>; + }; + return($file_data); +} + + +=pod + +=item C<< verify_checksum($file, $checksum_url) >> + +Verifies that C<$file> has checksum C<$checksum_url>. + +Returns 0 on success, -1 on connection error, 1 on checksum error. +In case of errors returns an informal message as second argument. + +=cut + +sub verify_checksum { + my ($file, $checksum_url) = @_; + my $checksum_file = download_to_temp_or_file($checksum_url); + # next step is verification of tlpdb checksum with checksum file + # existenc of checksum_file was checked above + if (!$checksum_file) { + return(-1, "download did not succeed: $checksum_url"); + } + # check the signature + my ($ret, $msg) = verify_signature($checksum_file, $checksum_url); + return ($ret, $msg) if ($ret != 0); + + # verify local data + open $cs_fh, "<$checksum_file" or die("cannot read file: $!"); + if (read ($cs_fh, $remote_digest, $ChecksumLength) != $ChecksumLength) { + close($cs_fh); + return(1, "incomplete read from $checksum_file"); + } else { + close($cs_fh); + ddebug("found remote digest: $remote_digest\n"); + } + $local_digest = tlchecksum($file); + ddebug("local_digest = $local_digest\n"); + if ($local_digest ne $remote_digest) { + return(1, "digest disagree"); + } + + # we are still here, so checksum also succeeded + debug("checksum of local copy identical with remote hash\n"); + + return(0); +} + +=pod + +=item C<< download_to_temp_or_file($url) >> + +If C<$url> tries to download the file into a temporary file. +In both cases returns the local file. + +Returns the local file name if succeeded, otherwise undef. + +=cut + +sub download_to_temp_or_file { + my $url = shift; + my ($url_fh, $url_file); + if ($url =~ m,^(http|ftp|file)://,) { + ($url_fh, $url_file) = File::Temp::tempfile(UNLINK => 1); + # now $url_fh filehandle is open, the file created + # TLUtils::download_file will just overwrite what is there + # on windows that doesn't work, so we close the fh immediately + # this creates a short loophole, but much better than before anyway + close($url_fh); + $ret = download_file($url, $url_file); + } else { + $url_file = $url; + $ret = 1; + } + if ($ret && (-r "$url_file")) { + return $url_file; + } + return; +} + +=pod + +=item C<< verify_signature($file, $url) >> + +Verifies a download of C<$url> into C<$file> by cheking the +gpg signature in C<$url.asc>. + +Returns 0 on success, -1 on connection error, 1 on checksum error. +In case of errors returns an informal message as second argument. + +=cut + +sub verify_signature { + my ($file, $url) = @_; + my $signature_url = "$url.asc"; + + # if we have $::gpg set, we try to verify cryptographic signatures + if ($::gpg) { + my $signature_file = download_to_temp_or_file($signature_url); + if ($signature_file) { + if (TeXLive::TLUtils::gpg_verify_signature($file, $signature_file)) { + info("cryptographic signature of $url verified\n"); + } else { + return(1, <<GPGERROR); +cryptograpic verification of + $file +against + $signature_url +failed. Please report to texlive\@tug.org +GPGERROR + } + } else { + debug("no access to cryptographic signature $signature_url\n"); + } + } else { + debug("gpg prog not defined, no checking of signatures\n"); + } + return (0); +} + +sub gpg_verify_signature { + my ($file, $sig) = @_; + my ($file_quote, $sig_quote); + if (win32()) { + $file =~ s!/!\\!g; + $sig =~ s!/!\\!g; + } + $file_quote = "\"$file\""; + $sig_quote = "\"$sig\""; + my ($out, $ret) = run_cmd("$::gpg --verify $sig_quote $file_quote 2>&1"); + if ($ret == 0) { + debug("verification succeeded, output:\n$out\n"); + return 1; + } else { + tlwarn("verification failed, output:\n$out\n"); + return 0; + } +} + # # compare_tlpobjs # returns a hash diff --git a/Build/source/texk/texlive/linked_scripts/texlive/fmtutil.pl b/Build/source/texk/texlive/linked_scripts/texlive/fmtutil.pl index 831b40b2e7e..05b9022488b 100755 --- a/Build/source/texk/texlive/linked_scripts/texlive/fmtutil.pl +++ b/Build/source/texk/texlive/linked_scripts/texlive/fmtutil.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# $Id: fmtutil.pl 39813 2016-02-22 05:25:37Z preining $ +# $Id: fmtutil.pl 40475 2016-04-12 20:56:58Z karl $ # fmtutil - utility to maintain format files. # (Maintained in TeX Live:Master/texmf-dist/scripts/texlive.) # @@ -24,11 +24,11 @@ BEGIN { TeX::Update->import(); } -my $svnid = '$Id: fmtutil.pl 39813 2016-02-22 05:25:37Z preining $'; -my $lastchdate = '$Date: 2016-02-22 06:25:37 +0100 (Mon, 22 Feb 2016) $'; +my $svnid = '$Id: fmtutil.pl 40475 2016-04-12 20:56:58Z karl $'; +my $lastchdate = '$Date: 2016-04-12 22:56:58 +0200 (Tue, 12 Apr 2016) $'; $lastchdate =~ s/^\$Date:\s*//; $lastchdate =~ s/ \(.*$//; -my $svnrev = '$Revision: 39813 $'; +my $svnrev = '$Revision: 40475 $'; $svnrev =~ s/^\$Revision:\s*//; $svnrev =~ s/\s*\$$//; my $version = "r$svnrev ($lastchdate)"; @@ -502,7 +502,7 @@ sub rebuild_one_format { my $addargs = $alldata->{'merged'}{$fmt}{$eng}{'args'}; # running parameters - my $texengine; + my $enginedir; my $jobswitch = "-jobname=$fmt"; my $prgswitch = "-progname=" ; my $recorderswitch = ($opts{'recorder'} ? "-recorder" : ""); @@ -533,15 +533,15 @@ sub rebuild_one_format { if ($eng eq "mpost") { $fmtfile .= ".mem" ; $kpsefmt = "mp" ; - $texengine = "metapost"; # the directory, not the executable - } elsif ($eng =~ m/^mf(w|-nowin)?$/) { + $enginedir = "metapost"; # the directory, not the executable + } elsif ($eng =~ m/^mf(lua(jit)?)?(w|-nowin)?$/) { $fmtfile .= ".base" ; $kpsefmt = "mf" ; - $texengine = "metafont"; + $enginedir = "metafont"; } else { $fmtfile .= ".fmt" ; $kpsefmt = "tex" ; - $texengine = $eng; + $enginedir = $eng; } # check for existence of ini file before doing anything else @@ -663,7 +663,7 @@ sub rebuild_one_format { if ($opts{'no-engine-subdir'}) { $fulldestdir = $opts{'fmtdir'}; } else { - $fulldestdir = "$opts{'fmtdir'}/$texengine"; + $fulldestdir = "$opts{'fmtdir'}/$enginedir"; } TeXLive::TLUtils::mkdirhier($fulldestdir); diff --git a/Build/source/texk/texlive/linked_scripts/texlive/tlmgr.pl b/Build/source/texk/texlive/linked_scripts/texlive/tlmgr.pl index 84adda21eca..4acb2998709 100755 --- a/Build/source/texk/texlive/linked_scripts/texlive/tlmgr.pl +++ b/Build/source/texk/texlive/linked_scripts/texlive/tlmgr.pl @@ -1,13 +1,13 @@ #!/usr/bin/env perl -# $Id: tlmgr.pl 40376 2016-04-10 00:31:57Z preining $ +# $Id: tlmgr.pl 40467 2016-04-12 06:14:51Z preining $ # # Copyright 2008-2016 Norbert Preining # This file is licensed under the GNU General Public License version 2 # or any later version. # -my $svnrev = '$Revision: 40376 $'; -my $datrev = '$Date: 2016-04-10 02:31:57 +0200 (Sun, 10 Apr 2016) $'; +my $svnrev = '$Revision: 40467 $'; +my $datrev = '$Date: 2016-04-12 08:14:51 +0200 (Tue, 12 Apr 2016) $'; my $tlmgrrevision; my $prg; if ($svnrev =~ m/: ([0-9]+) /) { @@ -74,9 +74,16 @@ BEGIN { # if not in bootstrapping mode => kpsewhich exists, so use it to get $Master chomp($Master = `kpsewhich -var-value=SELFAUTOPARENT`); } - $::installerdir = $Master; - # + # if we have no directory in which to find our modules, + # no point in going on. + if (! $Master) { + die ("Could not determine directory of tlmgr executable, " + . "maybe shared library woes?\nCheck for error messages above"); + } + + $::installerdir = $Master; # for config.guess et al., see TLUtils.pm + # make Perl find our packages first: unshift (@INC, "$Master/tlpkg"); unshift (@INC, "$Master/texmf-dist/scripts/texlive"); @@ -129,22 +136,6 @@ our $common_fmtutil_args = $::gui_mode = 0; $::machinereadable = 0; -my %globaloptions = ( - "gui" => 1, - "gui-lang" => "=s", - "debug-translation" => 1, - "location|repository|repo" => "=s", - "machine-readable" => 1, - "package-logfile" => "=s", - "persistent-downloads" => "!", - "no-execute-actions" => 1, - "pin-file" => "=s", - "pause" => 1, - "print-platform|print-arch" => 1, - "version" => 1, - "help" => 1, - "h|?" => 1); - my %action_specification = ( '_include_tlpobj' => { "run-post" => 0, @@ -347,6 +338,7 @@ sub main { "print-platform|print-arch" => 1, "usermode|user-mode" => 1, "usertree|user-tree" => "=s", + "verify-downloads" => "!", "version" => 1, ); @@ -630,6 +622,21 @@ for the full story.\n"; } } + # + # setup gpg if available + # first line: --(no-)verify-downloads was passed in (opts defined) + # second line: not passed in but in config + if ((defined($opts{"verify-downloads"}) && $opts{"verify-downloads"}) + || + (!defined($opts{"verify-downloads"}) && $config{"verify-downloads"})) { + if (TeXLive::TLUtils::setup_gpg($Master)) { + log("Trying to verify cryptographic signatures!\n") + } else { + tlwarn("Setting up gpg did not succeed!\n"); + } + } + + my $ret = execute_action($action, @ARGV); # F_ERROR stops processing immediately, and prevents postactions from @@ -2130,7 +2137,7 @@ sub write_w32_updater { push (@rst_info, "$pkg ^($oldrev^)"); next if ($opts{"dry-run"}); # create backup; make_container expects file name in a format: some-name.r[0-9]+ - my ($size, $md5, $fullname) = $localtlp->make_container("tar", $root, $temp, "__BACKUP_$pkg.r$oldrev"); + my ($size, $checksum, $fullname) = $localtlp->make_container("tar", $root, $temp, "__BACKUP_$pkg.r$oldrev"); if ($size <= 0) { tlwarn("$prg: Creation of backup container of $pkg failed.\n"); return 1; # backup failed? abort @@ -5499,11 +5506,16 @@ sub action_init_usertree { # sub action_conf { my $arg = shift @ARGV; + my $ret = $F_OK; + if (!defined($arg)) { texconfig_conf_mimic(); - return; - } - if ($arg eq "tlmgr" || $arg eq "texmf" || $arg eq "updmap") { + + } elsif ($arg !~ /^(tlmgr|texmf|updmap)$/) { + warn "$prg: unknown conf arg: $arg (try tlmgr or texmf or updmap)\n"; + $ret = $F_ERROR; + + } else { my ($fn,$cf); if ($opts{'conffile'}) { $fn = $opts{'conffile'} ; @@ -5531,6 +5543,7 @@ sub action_conf { } } else { info("$arg config file $fn not present\n"); + $ret = $F_WARNING; } } else { if (!defined($val)) { @@ -5540,6 +5553,7 @@ sub action_conf { $cf->delete_key($key); } else { info("$arg $key not defined, cannot remove ($fn)\n"); + $ret = $F_WARNING; } } else { if (defined($cf->value($key))) { @@ -5561,6 +5575,7 @@ sub action_conf { } else { if (defined($opts{'delete'})) { warning("$arg --delete and value for key $key given, don't know what to do!\n"); + $ret = $F_ERROR; } else { info("setting $arg $key to $val (in $fn)\n"); $cf->value($key, $val); @@ -5570,8 +5585,6 @@ sub action_conf { if ($cf->is_changed) { $cf->save; } - } else { - warn "$prg: unknown conf arg: $arg (try tlmgr or texmf or updmap)\n"; } } @@ -5839,7 +5852,7 @@ sub setup_one_remotetlpdb { my $local_copy_tlpdb_used = 0; if ($location =~ m;^(http|ftp)://;) { # first check that the saved tlpdb is present at all - my $loc_digest = Digest::MD5::md5_hex($location); + my $loc_digest = TeXLive::TLUtils::tl_short_digest($location); my $loc_copy_of_remote_tlpdb = "$Master/$InfraLocation/texlive.tlpdb.$loc_digest"; ddebug("loc_digest = $loc_digest\n"); @@ -5848,11 +5861,11 @@ sub setup_one_remotetlpdb { ddebug("loc copy found!\n"); # we found the tlpdb matching the current location # check for the remote hash - my $path = "$location/$InfraLocation/$DatabaseName.md5"; + my $path = "$location/$InfraLocation/$DatabaseName.$TeXLive::TLConfig::ChecksumExtension"; ddebug("remote path of digest = $path\n"); - my $fh = TeXLive::TLUtils::download_file($path, "|"); - my $rem_digest; - if (read ($fh, $rem_digest, 32) != 32) { + + my ($ret, $msg) = TeXLive::TLUtils::verify_checksum($loc_copy_of_remote_tlpdb, $path); + if ($ret < 0) { info(<<END_NO_INTERNET); No connection to the internet. Unable to download the checksum of the remote TeX Live database, @@ -5865,25 +5878,20 @@ http://tug.org/texlive/doc/install-tl.html END_NO_INTERNET # above text duplicated in install-tl - $remotetlpdb = TeXLive::TLPDB->new(root => $location, tlpdbfile => $loc_copy_of_remote_tlpdb); $local_copy_tlpdb_used = 1; + } elsif ($ret > 0) { + # no problem, checksum is wrong, we need to get new tlpdb } else { - ddebug("found remote digest: $rem_digest\n"); - my $rem_copy_digest = TeXLive::TLUtils::tlmd5($loc_copy_of_remote_tlpdb); - ddebug("rem_copy_digest = $rem_copy_digest\n"); - if ($rem_copy_digest eq $rem_digest) { - debug("md5 of local copy identical with remote hash\n"); - $remotetlpdb = TeXLive::TLPDB->new(root => $location, - tlpdbfile => $loc_copy_of_remote_tlpdb); - $local_copy_tlpdb_used = 1; - } + $remotetlpdb = TeXLive::TLPDB->new(root => $location, + tlpdbfile => $loc_copy_of_remote_tlpdb); + $local_copy_tlpdb_used = 1; } } } if (!$local_copy_tlpdb_used) { - $remotetlpdb = TeXLive::TLPDB->new(root => $location); + $remotetlpdb = TeXLive::TLPDB->new(root => $location, verify => 1); } if (!defined($remotetlpdb)) { return(undef, $loadmediasrcerror . $location); @@ -5959,9 +5967,9 @@ FROZEN # save remote database if it is a net location # make sure that the writeout of the tlpdb is done in UNIX mode - # since otherwise the sha256 will change. + # since otherwise the checksum will change. if (!$local_copy_tlpdb_used && $location =~ m;^(http|ftp)://;) { - my $loc_digest = Digest::MD5::md5_hex($location); + my $loc_digest = TeXLive::TLUtils::tl_short_digest($location); my $loc_copy_of_remote_tlpdb = "$Master/$InfraLocation/texlive.tlpdb.$loc_digest"; my $tlfh; @@ -6016,6 +6024,8 @@ sub load_config_file { # # by default we remove packages $config{"auto-remove"} = 1; + # + $config{"verify-downloads"} = 1; # loads system config file, this cannot be changes with tlmgr chomp (my $TEXMFSYSCONFIG = `kpsewhich -var-value=TEXMFSYSCONFIG`); @@ -6068,6 +6078,15 @@ sub load_options_from_config { tlwarn("$prg: $fn: Unknown value for auto-remove: $val\n"); } + } elsif ($key eq "verify-downloads") { + if ($val eq "0") { + $config{"verify-downloads"} = 0; + } elsif ($val eq "1") { + $config{"verify-downloads"} = 1; + } else { + tlwarn("$prg: $fn: Unknown value for verify-downloads: $val\n"); + } + } elsif ($sysmode) { # keys here are only allowed in sys mode if ($key eq "allowed-actions") { @@ -6430,6 +6449,15 @@ Activates user mode for this run of C<tlmgr>; see L<USER MODE> below. Uses I<dir> for the tree in user mode; see L<USER MODE> below. +=item B<--verify-downloads> + +=item B<--no-verify-downloads> + +Enables or disables cryptographic verification of downloaded database files. +A working GnuPG (C<gpg>) binary needs to be present in the path, otherwise +this option has no effect. See L<CRYPTOGRAPHIC VERIFICATION> below for details. + + =back The standard options for TeX Live programs are also accepted: @@ -6545,7 +6573,8 @@ Live Database are present. =item B<runfiles> -List those filenames that are occurring more than one time in the runfiles. +List those filenames that are occurring more than one time in the +runfiles sections. =back @@ -6569,12 +6598,13 @@ like the C<texconfig conf> call, but works on all supported platforms. With either C<conf texmf>, C<conf tlmgr>, or C<conf updmap> given in addition, shows all key/value pairs (i.e., all settings) as saved in -C<ROOT/texmf.cnf>, the tlmgr configuration file (see below), or the +C<ROOT/texmf.cnf>, the C<tlmgr> configuration file (see below), or the first found (via kpsewhich) C<updmap.cfg> file, respectively. If I<key> is given in addition, shows the value of only that I<key> in -the respective file. If option I<--delete> is also given, the -configuration file -- it is removed, not just commented out! +the respective file. If option I<--delete> is also given, the value in +the given configuration file is entirely removed (not just commented +out). If I<value> is given in addition, I<key> is set to I<value> in the respective file. I<No error checking is done!> @@ -6582,9 +6612,13 @@ respective file. I<No error checking is done!> In all cases the file used can be explicitly specified via the option C<--conffile I<file>>, in case one wants to operate on a different file. -Practical application: if the execution of (some or all) system commands -via C<\write18> was left enabled during installation, you can disable -it afterwards: +The PATH value shown is that used by C<tlmgr>. The directory in which +the C<tlmgr> executable is found is automatically prepended to the PATH +value inherited from the environment. + +Practical application of changing configuration values: if the execution +of (some or all) system commands via C<\write18> was left enabled during +installation, you can disable it afterwards: tlmgr conf texmf shell_escape 0 @@ -6726,7 +6760,7 @@ location in C<TEXMFLOCAL>). =item B<--rebuild-sys> -tells tlmgr to run necessary programs after config files have been +tells C<tlmgr> to run necessary programs after config files have been regenerated. These are: C<fmtutil-sys --all> after C<generate fmtutil>, C<fmtutil-sys --byhyphen .../language.dat> after C<generate language.dat>, @@ -6790,10 +6824,8 @@ dependencies in a similar way. =item B<--only-installed> -If this options is given, the installation source will -not be used; only locally installed packages, collections, or schemes -are listed. -(Does not work for listing of packages for now) +If this option is given, the installation source will not be used; only +locally installed packages, collections, or schemes are listed. =back @@ -6931,7 +6963,9 @@ is not likely to be of interest except perhaps to developers. The C<docfiles> and C<srcfiles> options control the installation of their respective files of a package. By default both are enabled (1). -This can be disabled (set to 0) if disk space is (very) limited. +Either or both can be disabled (set to 0) if disk space is limited or +for minimal testing installations, etc. When disabled, the respective +files are not downloaded at all. The options C<autobackup> and C<backupdir> determine the defaults for the actions C<update>, C<backup> and C<restore>. These three actions @@ -7212,7 +7246,7 @@ Otherwise, if neither I<pkg> nor I<rev> are given, list the available backup revisions for all packages. With I<pkg> given but no I<rev>, list all available backup revisions of I<pkg>. -When listing available packages tlmgr shows the revision, and in +When listing available packages, C<tlmgr> shows the revision, and in parenthesis the creation time if available (in format yyyy-mm-dd hh:mm). If (and only if) both I<pkg> and a valid revision number I<rev> are @@ -7484,6 +7518,25 @@ fallback information, but if you don't like them accumulating (e.g., on each run C<mirror.ctan.org> might resolve to a new host, resulting in a different hash), it's harmless to delete them. +=head1 CRYPTOGRAPHIC VERIFICATION + +If a working GnuPG binary (C<gpg>) is found, by default verification of +downloaded files is performed. This can be supressed by specifying +C<--no-verify-downloads> on the command line, or adding an entry +C<verify-downloads = 0> to a tlmgr config file. + +Verification is performed as follows: For each C<texlive.tlpdb> loaded +for a repository, the respective checksum C<texlive.tlpdb.sha512> is +always downloaded, too, and C<tlmgr> confirms whether the checksum +of the download tlpdb file agrees with the download data. This is done +in any case. + +If cryptographic verification is done, then a signature of the checksum +file is downloaded and the signature verified. The signature is done with +the TeX Live Distribution GPG key 0x06BAB6BC, which in turn is signed +by Karl Berry's key 0x9DEB46C0 and Norbert Preining's key 0x6CACA448. +All of these keys are obtainable from the standard key servers. + =head1 USER MODE C<tlmgr> provides a restricted way, called ``user mode'', to manage @@ -7585,12 +7638,13 @@ ignored. All other lines must look like where the allowed keys are C<gui-expertmode> (value 0 or 1), C<persistent-downloads> (value 0 or 1), C<auto-remove> (value 0 or 1), +C<verify-downloads> (value 0 or 1), and C<gui-lang> (value as with the command-line option). -C<persistent-downloads>, C<gui-lang>, and C<auto-remove> correspond to -the respective command line options of the same name. C<gui-expertmode> -switches between the full GUI and a simplified GUI with only the -important and mostly used settings. +C<persistent-downloads>, C<gui-lang>, C<auto-remove>, and C<verify-downloads> +correspond to the respective command line options of the same name. +C<gui-expertmode> switches between the full GUI and a simplified GUI +with only the important and mostly used settings. In addition, the system-wide config file can contain the key C<allowed-actions>. The value is a comma-separated list of actions that |