From 9bfdbea37230c6402a3a6f9f286f6e886a7d46e4 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Tue, 26 Apr 2016 21:42:20 +0000 Subject: tlmgr/tlcrypto: allow for different sha512 computation methods git-svn-id: svn://tug.org/texlive/trunk@40770 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/scripts/texlive/tlmgr.pl | 26 +++++- Master/tlpkg/TeXLive/TLCrypto.pm | 141 +++++++++++++++++++---------- 2 files changed, 116 insertions(+), 51 deletions(-) (limited to 'Master') diff --git a/Master/texmf-dist/scripts/texlive/tlmgr.pl b/Master/texmf-dist/scripts/texlive/tlmgr.pl index dd3fe7d4de6..ef190a6d7d3 100755 --- a/Master/texmf-dist/scripts/texlive/tlmgr.pl +++ b/Master/texmf-dist/scripts/texlive/tlmgr.pl @@ -5773,8 +5773,21 @@ sub init_tlmedia { $localtlpdb->save; %repos = repository_to_array($location); } - # do the gpg stuff only when loading the remote tlpdb - handle_gpg_config_settings(); + + # checksums and gpg stuff + if (TeXLive::TLCrypto::setup_checksum_method()) { + # it is only possible to do gpg verification if we can + # find a checksum method + # do the gpg stuff only when loading the remote tlpdb + handle_gpg_config_settings(); + } else { + if (!$config{'no-checksums'}) { + tlwarn("Cannot determine a checksum method!\n"); + tlwarn("Please install either Digest::SHA, openssl, or sha512sum.\n"); + tlwarn("To silence this warning, set 'no-checksums' to 1 in the\n"); + tlwarn("tlmgr configuration file.\n"); + } + } # check if we are only one tag/repo if ($#tags == 0) { @@ -6153,6 +6166,15 @@ sub load_options_from_config { tlwarn("$prg: $fn: Unknown value for verify-downloads: $val\n"); } + } elsif ($key eq "no-checksums") { + if ($val eq "1") { + $config{"no-checksums"} = 1; + } elsif ($val eq "0") { + $config{"no-checksums"} = 0; + } else { + tlwarn("$prg: $fn: Unknown value for no-checksums: $val\n"); + } + } elsif ($sysmode) { # keys here are only allowed in sys mode if ($key eq "allowed-actions") { diff --git a/Master/tlpkg/TeXLive/TLCrypto.pm b/Master/tlpkg/TeXLive/TLCrypto.pm index a0fab47aa7d..8a09f94a9ac 100644 --- a/Master/tlpkg/TeXLive/TLCrypto.pm +++ b/Master/tlpkg/TeXLive/TLCrypto.pm @@ -9,20 +9,8 @@ package TeXLive::TLCrypto; use Digest::MD5; use TeXLive::TLConfig; -use TeXLive::TLUtils qw(debug ddebug win32 which platform conv_to_w32_path); - -# try to load Digest::SHA, and if that fails, use our own slow modules -my $dig; -eval { - require Digest::SHA; - Digest::SHA->import('sha512_hex'); - $dig = Digest::SHA->new(512); -}; -if ($@) { - require TeXLive::SHA; - TeXLive::SHA->import('sha512_hex'); - $dig = TeXLive::SHA->new(512); -} +use TeXLive::TLUtils qw(debug ddebug win32 which platform conv_to_w32_path tlwarn); + my $svnrev = '$Revision: 40650 $'; my $_modulerevision = ($svnrev =~ m/: ([0-9]+) /) ? $1 : "unknown"; @@ -38,10 +26,13 @@ C -- checksums and cryptographic signatures use TeXLive::TLCrypto; # requires Digest::MD5 and Digest::SHA +=head2 Setup + + TeXLive::TLCrypto::setup_checksum_method(); + =head2 Checksums TeXLive::TLCrypto::tlchecksum($path); - TeXLive::TLCrypto::tlmd5($path); TeXLive::TLCrypto::verify_checksum($file, $url); =head2 Signatures @@ -59,10 +50,7 @@ BEGIN { @ISA = qw(Exporter); @EXPORT_OK = qw( &tlchecksum - &tlmd5 - &tldigest &tl_short_digest - &tlmd5 &verify_checksum &setup_gpg &verify_signature @@ -71,65 +59,116 @@ BEGIN { =pod -=item C<< tlchecksum($file) >> +=item C<< setup_checksum_method() >> -Return checksum of C<$file>. +Tries to find a checksum method: First check for usability of C<>, +then for either the C or the C programs. +Returns the checksum method or undef if none found. =cut -sub tlchecksum { - my ($file) = @_; - if (-r $file) { - open(FILE, $file) || die "open($file) failed: $!"; - binmode(FILE); - my $cshash = $dig->new(512)->addfile(*FILE)->hexdigest; - close(FILE); - return $cshash; - } else { - tlwarn("tlchecksum: given file not readable: $file\n"); - return ""; +sub setup_checksum_method { + # for debugging + # $::checksum_method = "sha512sum"; + # return($::checksum_method); + # try to load Digest::SHA, and if that fails, use our own slow modules + eval { + require Digest::SHA; + Digest::SHA->import('sha512_hex'); + $::checksum_method = "digest::sha"; + }; + if ($@) { + # ok, Digest::SHA is not available, try to find either the openssl + # or sha512sum programs + if (TeXLive::TLUtils::which("openssl")) { + $::checksum_method = "openssl"; + } elsif (TeXLive::TLUtils::which("sha512sum")) { + $::checksum_method = "sha512sum"; + } else { + debug("Cannot find usable checksum method!\n"); + } } + return($::checksum_method); } -sub tlchecksum_data { - my ($data) = @_; - my $cshash = $dig->new(512)->add($data)->hexdigest; - return $cshash; -} =pod -=item C<< tlmd5($file) >> +=item C<< tlchecksum($file) >> -Return md5, specifically, of C<$file>. +Return checksum of C<$file>. =cut -sub tlmd5 { +sub tlchecksum { my ($file) = @_; + if (!$::checksum_method) { + setup_checksum_method(); + } if (-r $file) { - open(FILE, $file) || die "open($file) failed: $!"; - binmode(FILE); - my $md5hash = Digest::MD5->new->addfile(*FILE)->hexdigest; - close(FILE); - return $md5hash; + my ($out, $ret); + if ($::checksum_method eq "openssl") { + ($out, $ret) = TeXLive::TLUtils::run_cmd("openssl dgst -sha512 $file"); + chomp($out); + } elsif ($::checksum_method eq "sha512sum") { + ($out, $ret) = TeXLive::TLUtils::run_cmd("sha512sum $file"); + chomp($out); + } elsif ($::checksum_method eq "digest::sha") { + open(FILE, $file) || die "open($file) failed: $!"; + binmode(FILE); + $out = Digest::SHA->new(512)->addfile(*FILE)->hexdigest; + close(FILE); + $ret = 0; + } else { + tldie("unknown checksum program: $::checksum_method\n"); + } + if ($ret != 0) { + tlwarn("tlchecksum: cannot compute checksum: $file\n"); + return ""; + } + ddebug("tlchecksum: out = $out\n"); + my $cs; + if ($::checksum_method eq "openssl") { + (undef,$cs) = split(/= /,$out); + } elsif ($::checksum_method eq "sha512sum") { + ($cs,undef) = split(' ',$out); + } elsif ($::checksum_method eq "digest::sha") { + $cs = $out; + } + ddebug("tlchecksum: cs ===$cs===\n"); + if (length($cs) != 128) { + tlwarn("unexpected output from $::checksum_method: $out\n"); + return ""; + } + return $cs; } else { - tlwarn("tlmd5, given file not readable: $file\n"); + tlwarn("tlchecksum: given file not readable: $file\n"); return ""; } } -=pod +# sub tlchecksum { +# my ($file) = @_; +# if (-r $file) { +# open(FILE, $file) || die "open($file) failed: $!"; +# binmode(FILE); +# my $cshash = $dig->new(512)->addfile(*FILE)->hexdigest; +# close(FILE); +# return $cshash; +# } else { +# tlwarn("tlchecksum: given file not readable: $file\n"); +# return ""; +# } +# } -=item C<< tldigest($str) >> +=pod =item C<< tl_short_digest($str) >> -Return full and short digests of C<$str>, respectively. +Return short digest (MD5) of C<$str>. =cut -sub tldigest { return (sha512_hex(shift)); } sub tl_short_digest { return (Digest::MD5::md5_hex(shift)); } # emacs-page @@ -149,6 +188,9 @@ In case of errors returns an informal message as second argument. sub verify_checksum { my ($file, $checksum_url) = @_; + # don't do anything if we cannot determine a checksum method + # return -2 which is as much as missing signature + return(-2) if (!$::checksum_method); my $checksum_file = TeXLive::TLUtils::download_to_temp_or_file($checksum_url); @@ -361,6 +403,7 @@ sub gpg_verify_signature { =back =cut + 1; __END__ -- cgit v1.2.3