Toby Inkster avatar Toby Inkster committed 4364184

update to newer version of cpanminus

Comments (0)

Files changed (4)

 
 1.501901	2012-01-07
 	- check availability of LWP::Protocol::https (RT#82505)
+
+1.502100	2012-01-31
+	- based on cpanminus 1.5021

lib/App/cpanminus/script.pm

 use constant WIN32 => $^O eq 'MSWin32';
 use constant SUNOS => $^O eq 'solaris';
 
-our $VERSION = "1.5019";
+our $VERSION = "1.5021";
 
 my $quote = WIN32 ? q/"/ : q/'/;
 
         format   => 'tree',
         save_dists => undef,
         skip_configure => 0,
+        verify => 0,
         @_,
     }, $class;
 }
         'test-only' => sub { $self->{notest} = 0; $self->{skip_installed} = 0; $self->{test_only} = 1 },
         'S|sudo!'   => \$self->{sudo},
         'v|verbose' => sub { $self->{verbose} = $self->{interactive} = 1 },
+        'verify!'   => \$self->{verify},
         'q|quiet!'  => \$self->{quiet},
         'h|help'    => sub { $self->{action} = 'show_help' },
         'V|version' => sub { $self->{action} = 'show_version' },
     }
 }
 
+sub setup_verify {
+    my $self = shift;
+
+    my $has_modules = eval { require Module::Signature; require Digest::SHA; 1 };
+    $self->{cpansign} = $self->which('cpansign');
+
+    unless ($has_modules && $self->{cpansign}) {
+        warn "WARNING: Module::Signature and Digest::SHA is required for distribution verifications.\n";
+        $self->{verify} = 0;
+    }
+}
+
 sub doit {
     my $self = shift;
 
     $self->setup_home;
     $self->init_tools;
+    $self->setup_verify if $self->{verify};
 
     if (my $action = $self->{action}) {
         $self->$action() and return 1;
     if ($self->{scandeps}) {
         $self->dump_scandeps();
     }
+    # Workaround for older File::Temp's
+    # where creating a tempdir with an implicit $PWD
+    # causes tempdir non-cleanup if $PWD changes
+    # as paths are stored internally without being resolved
+    # absolutely.
+    # https://rt.cpan.org/Public/Bug/Display.html?id=44924
+    $self->chdir($cwd);
 
     return !@fail;
 }
 
     if ($found) {
         if (!$version or
-            version->new($found->{version} || 0) >= version->new($version)) {
+            version->new($found->{module_version} || 0) >= version->new($version)) {
             return $found;
         } else {
-            $self->chat("Found $module version $found->{version} < $version.\n");
+            $self->chat("Found $module version $found->{module_version} < $version.\n");
         }
     }
 
         $self->diag_ok;
         $dist->{local_path} = File::Spec->rel2abs($name);
 
-        my $dir = $self->unpack($file);
+        my $dir = $self->unpack($file, $uri, $dist);
         next unless $dir; # unpack failed
 
         if (my $save = $self->{save_dists}) {
 }
 
 sub unpack {
-    my($self, $file) = @_;
+    my($self, $file, $uri, $dist) = @_;
+
+    if ($self->{verify}) {
+        $self->verify_archive($file, $uri, $dist) or return;
+    }
+
     $self->chat("Unpacking $file\n");
     my $dir = $file =~ /\.zip/i ? $self->unzip($file) : $self->untar($file);
     unless ($dir) {
     return $dir;
 }
 
+sub verify_checksums_signature {
+    my($self, $chk_file) = @_;
+
+    require Module::Signature;
+
+    $self->chat("Verifying the signature of CHECKSUMS\n");
+
+    my $rv = eval {
+        local $SIG{__WARN__} = sub {}; # suppress warnings
+        my $v = Module::Signature::_verify($chk_file);
+        $v == Module::Signature::SIGNATURE_OK();
+    };
+    if ($rv) {
+        $self->chat("Verified OK!\n");
+    } else {
+        $self->diag_fail("Verifying CHECKSUMS signature failed: $rv\n");
+        return;
+    }
+
+    return 1;
+}
+
+sub verify_archive {
+    my($self, $file, $uri, $dist) = @_;
+
+    unless ($dist->{cpanid}) {
+        $self->chat("Archive '$file' does not seem to be from PAUSE. Skip verification.\n");
+    }
+
+    (my $mirror = $uri) =~ s!/authors/id.*$!!;
+
+    (my $chksum_uri = $uri) =~ s!/[^/]*$!/CHECKSUMS!;
+    my $chk_file = $self->source_for($mirror) . "/$dist->{cpanid}.CHECKSUMS";
+    $self->diag_progress("Fetching $chksum_uri");
+    $self->mirror($chksum_uri, $chk_file);
+
+    unless (-e $chk_file) {
+        $self->diag_fail("Fetching $chksum_uri failed.\n");
+        return;
+    }
+
+    $self->diag_ok;
+    $self->verify_checksums_signature($chk_file) or return;
+    $self->verify_checksum($file, $chk_file);
+}
+
+sub verify_checksum {
+    my($self, $file, $chk_file) = @_;
+
+    $self->chat("Verifying the SHA1 for $file\n");
+
+    open my $fh, "<$chk_file" or die "$chk_file: $!";
+    my $data = join '', <$fh>;
+    $data =~ s/\015?\012/\n/g;
+
+    require Safe;
+    my $chksum = Safe->new->reval($data);
+
+    if (!ref $chksum or ref $chksum ne 'HASH') {
+        $self->diag_fail("! Checksum file downloaded from $chk_file is broken.\n");
+        return;
+    }
+
+    if (my $sha = $chksum->{$file}{sha256}) {
+        my $hex = $self->sha1_for($file);
+        if ($hex eq $sha) {
+            $self->chat("Checksum for $file: Verified!\n");
+        } else {
+            $self->diag_fail("Checksum mismatch for $file\n");
+            return;
+        }
+    } else {
+        $self->chat("Checksum for $file not found in CHECKSUMS.\n");
+        return;
+    }
+}
+
+sub sha1_for {
+    my($self, $file) = @_;
+
+    require Digest::SHA;
+
+    open my $fh, "<", $file or die "$file: $!";
+    my $dg = Digest::SHA->new(256);
+    my($data);
+    while (read($fh, $data, 4096)) {
+        $dg->add($data);
+    }
+
+    return $dg->hexdigest;
+}
+
+sub verify_signature {
+    my($self, $dist) = @_;
+
+    $self->diag_progress("Verifying the SIGNATURE file");
+    my $out = `$self->{cpansign} -v --skip 2>&1`;
+    $self->log($out);
+
+    if ($out =~ /Signature verified OK/) {
+        $self->diag_ok("Verified OK");
+        return 1;
+    } else {
+        $self->diag_fail("SIGNATURE verificaion for $dist->{filename} failed\n");
+        return;
+    }
+}
+
 sub resolve_name {
     my($self, $module, $version) = @_;
 
 sub build_stuff {
     my($self, $stuff, $dist, $depth) = @_;
 
+    if ($self->{verify} && -e 'SIGNATURE') {
+        $self->verify_signature($dist) or return;
+    }
+
     my @config_deps;
     if (!%{$dist->{meta} || {}} && -e 'META.yml') {
         $self->chat("Checking configure dependencies from META.yml\n");

lib/App/cpantimes.pm

 package App::cpantimes;
-our $VERSION = "1.501901";
+our $VERSION = "1.502100";
 
 =encoding utf8
 

lib/App/cpantimes/script.pm

 package App::cpantimes::script;
 
-our $VERSION = "1.501901";
+our $VERSION = "1.502100";
 
 use 5.008;
 use strict;
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.