Skip to content

Commit

Permalink
fix RT #46339: sign files without eol filtering; verify with three eo…
Browse files Browse the repository at this point in the history
…l varitions
  • Loading branch information
andk committed Sep 19, 2010
1 parent c7f3d83 commit b9cd197
Show file tree
Hide file tree
Showing 16 changed files with 230 additions and 19 deletions.
13 changes: 13 additions & 0 deletions MANIFEST
Expand Up @@ -23,3 +23,16 @@ SIGNATURE
t/0-signature.t
t/1-basic.t
t/2-cygwin.t
t/3-verify.t
t/test-datcrlf-sigcrlf/MANIFEST
t/test-datcrlf-sigcrlf/README
t/test-datcrlf-sigcrlf/SIGNATURE
t/test-datcrlf-siglf/MANIFEST
t/test-datcrlf-siglf/README
t/test-datcrlf-siglf/SIGNATURE
t/test-datlf-sigcrlf/MANIFEST
t/test-datlf-sigcrlf/README
t/test-datlf-sigcrlf/SIGNATURE
t/test-datlf-siglf/MANIFEST
t/test-datlf-siglf/README
t/test-datlf-siglf/SIGNATURE
2 changes: 1 addition & 1 deletion Makefile.PL
Expand Up @@ -8,7 +8,7 @@ all_from 'lib/Module/Signature.pm';
readme_from 'lib/Module/Signature.pm';
repository 'http://github.com/audreyt/module-signature';
install_script 'script/cpansign';
build_requires 'Test::More';
build_requires 'Test::More', 'IPC::Run:';

# On Win32 (excluding cygwin) we know that IO::Socket::INET,
# which is needed for keyserver stuff, doesn't work. In fact
Expand Down
88 changes: 70 additions & 18 deletions lib/Module/Signature.pm
Expand Up @@ -51,6 +51,18 @@ not run its Makefile.PL or Build.PL.
$AutoKeyRetrieve = 1;
$CanKeyRetrieve = undef;

sub _cipher_map {
my($sigtext) = @_;
my @lines = split /\015?\012/, $sigtext;
my %map;
for my $line (@lines) {
my($cipher,$digest,$file) = split " ", $line, 3;
return unless defined $file;
$map{$file} = [$cipher, $digest];
}
return \%map;
}

sub verify {
my %args = ( skip => 1, @_ );
my $rv;
Expand All @@ -65,12 +77,12 @@ sub verify {
return SIGNATURE_MALFORMED;
};

(my ($cipher) = ($sigtext =~ /^(\w+) /)) or do {
(my ($cipher_map) = _cipher_map($sigtext)) or do {
warn "==> MALFORMED Signature file! <==\n";
return SIGNATURE_MALFORMED;
};

(defined(my $plaintext = _mkdigest($cipher))) or do {
(defined(my $plaintext = _mkdigest($cipher_map))) or do {
warn "==> UNKNOWN Cipher format! <==\n";
return CIPHER_UNKNOWN;
};
Expand Down Expand Up @@ -489,7 +501,7 @@ EOF
}

sub _mkdigest {
my $digest = _mkdigest_files(undef, @_) or return;
my $digest = _mkdigest_files(@_) or return;
my $plaintext = '';

foreach my $file (sort keys %$digest) {
Expand All @@ -500,13 +512,8 @@ sub _mkdigest {
return $plaintext;
}

sub _mkdigest_files {
my $p = shift;
my $algorithm = shift || $Cipher;
my $dosnames = (defined(&Dos::UseLFN) && Dos::UseLFN()==0);
my $read = ExtUtils::Manifest::maniread() || {};
my $found = ExtUtils::Manifest::manifind($p);
my(%digest) = ();
sub _digest_object {
my($algorithm) = @_;
my $obj = eval { Digest->new($algorithm) } || eval {
my ($base, $variant) = ($algorithm =~ /^(\w+?)(\d+)$/g) or die;
require "Digest/$base.pm"; "Digest::$base"->new($variant)
Expand All @@ -523,8 +530,35 @@ sub _mkdigest_files {
} and return } or do {
warn "Unknown cipher: $algorithm, please install Digest::$algorithm\n"; return;
};
$obj;
}

foreach my $file (sort keys %$read){
sub _mkdigest_files {
my $verify_map = shift;
my $dosnames = (defined(&Dos::UseLFN) && Dos::UseLFN()==0);
my $read = ExtUtils::Manifest::maniread() || {};
my $found = ExtUtils::Manifest::manifind();
my(%digest) = ();
my($default_obj) = _digest_object($Cipher);
FILE: foreach my $file (sort keys %$read){
next FILE if $file eq $SIGNATURE;
my($obj,$this_cipher,$this_hexdigest,$verify_digest);
if ($verify_map) {
if (my $vmf = $verify_map->{$file}) {
($this_cipher,$verify_digest) = @$vmf;
if ($this_cipher eq $Cipher) {
$obj = $default_obj;
} else {
$obj = _digest_object($this_cipher);
}
} else {
$this_cipher = $Cipher;
$obj = $default_obj;
}
} else {
$this_cipher = $Cipher;
$obj = $default_obj;
}
warn "Debug: collecting digest from $file\n" if $Debug;
if ($dosnames){
$file = lc $file;
Expand All @@ -541,10 +575,6 @@ sub _mkdigest_files {
binmode(F);
$obj->addfile(*F);
}
elsif ($] >= 5.006) {
binmode(F, ':crlf');
$obj->addfile(*F);
}
elsif ($^O eq 'MSWin32') {
$obj->addfile(*F);
}
Expand All @@ -553,10 +583,32 @@ sub _mkdigest_files {
local $/;
binmode(F);
my $input = <F>;
$input =~ s/\015?\012/\n/g;
$obj->add($input);
VERIFYLOOP: for my $eol ("","\015\012","\012") {
my $lax_input = $input;
if (! length $eol) {
# first try is binary
} else {
my @lines = split /$eol/, $input, -1;
if (grep /[\015\012]/, @lines) {
# oops, apparently not a text file, treat as binary, forget @lines
} else {
my $other_eol = $eol eq "\012" ? "\015\012" : "\012";
$lax_input = join $other_eol, @lines;
}
}
$obj->add($lax_input);
$this_hexdigest = $obj->hexdigest;
if ($verify_digest) {
if ($this_hexdigest eq $verify_digest) {
last VERIFYLOOP;
}
$obj->reset;
} else {
last VERIFYLOOP;
}
}
}
$digest{$file} = [$algorithm, $obj->hexdigest];
$digest{$file} = [$this_cipher, $this_hexdigest];
$obj->reset;
}
}
Expand Down
18 changes: 18 additions & 0 deletions t/3-verify.t
@@ -0,0 +1,18 @@
#!perl

use strict;
use Test::More;
use IPC::Run qw(run);
plan tests => 4;

$|=1;
for my $tdir (glob("t/test-dat*")) {
chdir $tdir or die;
my @system = ($^X, "-I../../lib/", "../../script/cpansign", "-v");
my($in,$out,$err);
run \@system, \$in, \$out, \$err;
close $out;
my $diff = join "\n", grep /^.SHA1/, split /\n/, $out;
ok(0==$?) or diag "dir[$tdir]system[@system]diff[$diff]";
chdir "../../" or die;
}
3 changes: 3 additions & 0 deletions t/test-datcrlf-sigcrlf/MANIFEST
@@ -0,0 +1,3 @@
MANIFEST
README
SIGNATURE
4 changes: 4 additions & 0 deletions t/test-datcrlf-sigcrlf/README
@@ -0,0 +1,4 @@
Data in Unix format
Regards,
--
author
25 changes: 25 additions & 0 deletions t/test-datcrlf-sigcrlf/SIGNATURE
@@ -0,0 +1,25 @@
This file contains message digests of all files listed in MANIFEST,
signed via the Module::Signature module, version 0.660001.

To verify the content in this distribution, first make sure you have
Module::Signature installed, then type:

% cpansign -v

It will check each file's integrity, as well as the signature's
validity. If "==> Signature verified OK! <==" is not displayed,
the distribution may already have been compromised, and you should
not run its Makefile.PL or Build.PL.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

SHA1 e943619dfc12d2bab253597ab1d6eff80f00dbde MANIFEST
SHA1 47e6d6416876be98bcab097507c31eb5dc217b35 README
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)

iEYEARECAAYFAkyV6HsACgkQ7IA58KMXwV0BHACcDL2NSFNHnKxpGyGNgV6susvT
jrQAoK2FFvqrxc7dgxCs61YivlKUUMx/
=NRNf
-----END PGP SIGNATURE-----
3 changes: 3 additions & 0 deletions t/test-datcrlf-siglf/MANIFEST
@@ -0,0 +1,3 @@
MANIFEST
README
SIGNATURE
4 changes: 4 additions & 0 deletions t/test-datcrlf-siglf/README
@@ -0,0 +1,4 @@
Data in Unix format
Regards,
--
author
25 changes: 25 additions & 0 deletions t/test-datcrlf-siglf/SIGNATURE
@@ -0,0 +1,25 @@
This file contains message digests of all files listed in MANIFEST,
signed via the Module::Signature module, version 0.63.

To verify the content in this distribution, first make sure you have
Module::Signature installed, then type:

% cpansign -v

It will check each file's integrity, as well as the signature's
validity. If "==> Signature verified OK! <==" is not displayed,
the distribution may already have been compromised, and you should
not run its Makefile.PL or Build.PL.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

SHA1 e943619dfc12d2bab253597ab1d6eff80f00dbde MANIFEST
SHA1 f7a80112f7597a7312d6e0d499aa4cf5f6e8ef08 README
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)

iEYEARECAAYFAkyV6GUACgkQ7IA58KMXwV3MkACeJgzW5pSEFDr/kxflJW3tVfsk
wKsAn0LQPjqcUSDMdd/1gd8SC7x0TAI4
=MAQR
-----END PGP SIGNATURE-----
3 changes: 3 additions & 0 deletions t/test-datlf-sigcrlf/MANIFEST
@@ -0,0 +1,3 @@
MANIFEST
README
SIGNATURE
4 changes: 4 additions & 0 deletions t/test-datlf-sigcrlf/README
@@ -0,0 +1,4 @@
Data in Unix format
Regards,
--
author
25 changes: 25 additions & 0 deletions t/test-datlf-sigcrlf/SIGNATURE
@@ -0,0 +1,25 @@
This file contains message digests of all files listed in MANIFEST,
signed via the Module::Signature module, version 0.660001.

To verify the content in this distribution, first make sure you have
Module::Signature installed, then type:

% cpansign -v

It will check each file's integrity, as well as the signature's
validity. If "==> Signature verified OK! <==" is not displayed,
the distribution may already have been compromised, and you should
not run its Makefile.PL or Build.PL.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

SHA1 e943619dfc12d2bab253597ab1d6eff80f00dbde MANIFEST
SHA1 47e6d6416876be98bcab097507c31eb5dc217b35 README
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)

iEYEARECAAYFAkyV6HsACgkQ7IA58KMXwV0BHACcDL2NSFNHnKxpGyGNgV6susvT
jrQAoK2FFvqrxc7dgxCs61YivlKUUMx/
=NRNf
-----END PGP SIGNATURE-----
3 changes: 3 additions & 0 deletions t/test-datlf-siglf/MANIFEST
@@ -0,0 +1,3 @@
MANIFEST
README
SIGNATURE
4 changes: 4 additions & 0 deletions t/test-datlf-siglf/README
@@ -0,0 +1,4 @@
Data in Unix format
Regards,
--
author
25 changes: 25 additions & 0 deletions t/test-datlf-siglf/SIGNATURE
@@ -0,0 +1,25 @@
This file contains message digests of all files listed in MANIFEST,
signed via the Module::Signature module, version 0.63.

To verify the content in this distribution, first make sure you have
Module::Signature installed, then type:

% cpansign -v

It will check each file's integrity, as well as the signature's
validity. If "==> Signature verified OK! <==" is not displayed,
the distribution may already have been compromised, and you should
not run its Makefile.PL or Build.PL.

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

SHA1 e943619dfc12d2bab253597ab1d6eff80f00dbde MANIFEST
SHA1 f7a80112f7597a7312d6e0d499aa4cf5f6e8ef08 README
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)

iEYEARECAAYFAkyV6GUACgkQ7IA58KMXwV3MkACeJgzW5pSEFDr/kxflJW3tVfsk
wKsAn0LQPjqcUSDMdd/1gd8SC7x0TAI4
=MAQR
-----END PGP SIGNATURE-----

0 comments on commit b9cd197

Please sign in to comment.