Permalink
Browse files

fix RT #46339: sign files without eol filtering; verify with three eo…

…l varitions
  • Loading branch information...
andk committed Sep 19, 2010
1 parent c7f3d83 commit b9cd19788bca95579d43948d7e092b3c0be1a449
View
@@ -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
View
@@ -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
View
@@ -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;
@@ -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;
};
@@ -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) {
@@ -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)
@@ -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;
@@ -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);
}
@@ -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;
}
}
View
@@ -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;
+}
@@ -0,0 +1,3 @@
+MANIFEST
+README
+SIGNATURE
@@ -0,0 +1,4 @@
+Data in Unix format
+Regards,
+--
+author
@@ -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-----
@@ -0,0 +1,3 @@
+MANIFEST
+README
+SIGNATURE
@@ -0,0 +1,4 @@
+Data in Unix format
+Regards,
+--
+author
@@ -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,0 +1,3 @@
+MANIFEST
+README
+SIGNATURE
@@ -0,0 +1,4 @@
+Data in Unix format
+Regards,
+--
+author
@@ -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-----
@@ -0,0 +1,3 @@
+MANIFEST
+README
+SIGNATURE
@@ -0,0 +1,4 @@
+Data in Unix format
+Regards,
+--
+author
@@ -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.