Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

74 lines (58 sloc) 2.33 KB
name 'verify_checksums';
description 'Verify CHECKSUMS before unpacking the archive';
author 'Tatsuhiko Miyagawa';
api_version 0.1;
hook verify_archive => sub {
my $args = shift;
# Just require and throw errors -- cpanminus will catch them and display it in the build.log
require Module::Signature;
require Digest::SHA;
# TODO move this logic to cpanminus and set 'source' parameter
my $base = $args->{uri};
$base =~ s!(authors/id/[A-Z]/[A-Z]{2}/([A-Z]+))/[^/]+\.(?:tar\.gz|tgz|zip)$!$1!
or return;
my $pause_id = $2; # TODO this can be in the context
my $chk_uri = "$base/CHECKSUMS";
$args->{app}->chat("Fetching $chk_uri ...\n");
my $chk_file = "$pause_id.CHECKSUMS";
$args->{app}->mirror($chk_uri, $chk_file);
if (-e $chk_file) {
$args->{app}->chat("Verifying the signature of CHECKSUMS itself...\n");
my $rv = eval {
my $v = Module::Signature::_verify($chk_file);
$v == Module::Signature::SIGNATURE_OK();
if ($rv) {
$args->{app}->chat("Verified OK!\n");
} else {
$args->{app}->diag("Verifying CHECKSUMS signature failed: $rv\n");
return $args->{fail}++;
$args->{app}->chat("Verifying the SHA1 for $args->{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') {
$args->{app}->diag("! Checksum file downloaded from $chk_file is broken.\n");
return $args->{fail}++;
if (my $sha = $chksum->{$args->{file}}{sha256}) {
open my $fh, "<$args->{file}" or die "$args->{file}: $!";
my $dg = Digest::SHA->new(256);
while (read($fh, $data, 4096)) {
my $hex = $dg->hexdigest;
if ($hex eq $sha) {
$args->{app}->chat("Checksum for $args->{file}: Verified!\n");
} else {
$args->{app}->diag("Checksum mismatch for $args->{file}\n");
} else {
$args->{app}->chat("Checksum for $args->{file} not found in CHECKSUMS.\n");
Jump to Line
Something went wrong with that request. Please try again.