Sfoglia il codice sorgente

Dpkg: Fix OpenPGP armored signature parsing

Change parsing code to honour RFC4880. Handle whitespaces at EOL, and
correctly expect five trailing dashes on the Armor Header Lines.

Closes: #695919

Reported-by: Ansgar Burchardt <ansgar@debian.org>
Guillem Jover 13 anni fa
parent
commit
9945c52208

+ 2 - 0
debian/changelog

@@ -6,6 +6,8 @@ dpkg (1.16.10) UNRELEASED; urgency=low
   * Add missing @LIBLZMA_LIBS@ to Libs.Private in libdpkg.pc.in.
   * Do not use an undefined va_list variable in dpkg_put_errno().
   * Abort installation if we cannot set the security context for a file.
+  * Fix OpenPGP armored signature parsing, to be resilient against doctored
+    input, including source package control files. Closes: #695919
 
   [ Updated programs translations ]
   * Esperanto (Felipe Castro).

+ 7 - 6
scripts/Dpkg/Control/Hash.pm

@@ -193,31 +193,32 @@ sub parse {
 		$line = substr $line, 1;
 	    }
 	    $self->{$cf} .= "\n$line";
-	} elsif (m/^-----BEGIN PGP SIGNED MESSAGE/) {
+	} elsif (m/^-----BEGIN PGP SIGNED MESSAGE-----$/) {
 	    $expect_pgp_sig = 1;
 	    if ($$self->{'allow_pgp'}) {
 		# Skip PGP headers
 		while (<$fh>) {
-		    last if m/^$/;
+		    last if m/^\s*$/;
 		}
 	    } else {
 		syntaxerr($desc, _g("PGP signature not allowed here"));
 	    }
-	} elsif (m/^$/ || ($expect_pgp_sig && m/^-----BEGIN PGP SIGNATURE/)) {
+	} elsif (m/^$/ || ($expect_pgp_sig && m/^-----BEGIN PGP SIGNATURE-----$/)) {
 	    if ($expect_pgp_sig) {
 		# Skip empty lines
 		$_ = <$fh> while defined($_) && $_ =~ /^\s*$/;
 		length($_) ||
                     syntaxerr($desc, _g("expected PGP signature, found EOF " .
                                         "after blank line"));
-		s/\n$//;
-		unless (m/^-----BEGIN PGP SIGNATURE/) {
+		s/\s*\n$//;
+		unless (m/^-----BEGIN PGP SIGNATURE-----$/) {
 		    syntaxerr($desc, sprintf(_g("expected PGP signature, " .
                                                 "found something else \`%s'"), $_));
                 }
 		# Skip PGP signature
 		while (<$fh>) {
-		    last if m/^-----END PGP SIGNATURE/;
+		    s/\s*\n$//;
+		    last if m/^-----END PGP SIGNATURE-----$/;
 		}
 		unless (defined($_)) {
                     syntaxerr($desc, _g("unfinished PGP signature"));

+ 1 - 1
scripts/Dpkg/Source/Package.pm

@@ -194,7 +194,7 @@ sub initialize {
     $self->{'is_signed'} = 0;
     while (<DSC>) {
         next if /^\s*$/o;
-        $self->{'is_signed'} = 1 if /^-----BEGIN PGP SIGNED MESSAGE-----$/o;
+        $self->{'is_signed'} = 1 if /^-----BEGIN PGP SIGNED MESSAGE-----\s*$/o;
         last;
     }
     close(DSC);

+ 5 - 0
scripts/Makefile.am

@@ -229,6 +229,11 @@ test_data = \
 	t/600_Dpkg_Changelog/regressions \
 	t/600_Dpkg_Changelog/shadow \
 	t/700_Dpkg_Control/control-1 \
+	t/700_Dpkg_Control/bogus-unsigned.dsc \
+	t/700_Dpkg_Control/bogus-armor-double.dsc \
+	t/700_Dpkg_Control/bogus-armor-trail.dsc \
+	t/700_Dpkg_Control/bogus-armor-nested.dsc \
+	t/700_Dpkg_Control/bogus-armor-spaces.dsc \
 	t/750_Dpkg_Substvars/substvars1 \
 	t/910_merge_changelogs/ch-old \
 	t/910_merge_changelogs/ch-a \

+ 39 - 2
scripts/t/700_Dpkg_Control.t

@@ -13,17 +13,32 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-use Test::More tests => 11;
+use Test::More tests => 20;
 
 use strict;
 use warnings;
 use IO::String;
 
-use_ok('Dpkg::Control::Info');
+BEGIN {
+    use_ok('Dpkg::Control');
+    use_ok('Dpkg::Control::Info');
+}
 
 my $srcdir = $ENV{srcdir} || '.';
 my $datadir = $srcdir . '/t/700_Dpkg_Control';
 
+sub parse_dsc {
+    my ($path) = @_;
+
+    my $dsc = Dpkg::Control->new(type => CTRL_PKG_SRC);
+    eval {
+        $dsc->load($path);
+        1;
+    } or return;
+
+    return $dsc;
+}
+
 my $c = Dpkg::Control::Info->new("$datadir/control-1");
 
 my $io = IO::String->new();
@@ -86,3 +101,25 @@ is(${$io->string_ref()},
 Architecture: all
 Depends: hello
 ', "Dump of second binary package of $datadir/control-1");
+
+# Check OpenPGP armored signatures in source control files
+
+my $dsc;
+
+$dsc = parse_dsc("$datadir/bogus-unsigned.dsc");
+is($dsc, undef, 'Unsigned .dsc w/ OpenPGP armor');
+
+$dsc = parse_dsc("$datadir/bogus-armor-trail.dsc");
+is($dsc, undef, 'Signed .dsc w/ bogus OpenPGP armor trailer');
+
+$dsc = parse_dsc("$datadir/bogus-armor-double.dsc");
+ok(defined $dsc, 'Signed .dsc w/ two OpenPGP armor signatures');
+is($dsc->{Source}, 'pass', 'Signed spaced .dsc package name');
+
+$dsc = parse_dsc("$datadir/bogus-armor-spaces.dsc");
+ok(defined $dsc, 'Signed .dsc w/ spaced OpenPGP armor');
+is($dsc->{Source}, 'pass', 'Signed spaced .dsc package name');
+
+$dsc = parse_dsc("$datadir/bogus-armor-nested.dsc");
+ok(defined $dsc, 'Signed .dsc w/ nested OpenPGP armor');
+is($dsc->{Source}, 'pass', 'Signed nested .dsc package name');

+ 13 - 0
scripts/t/700_Dpkg_Control/bogus-armor-double.dsc

@@ -0,0 +1,13 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+Source: pass
+
+-----BEGIN PGP SIGNATURE-----
+
+Valid signature here.
+-----END PGP SIGNATURE-----
+-----BEGIN PGP SIGNATURE-----
+
+Fake signature here.
+-----END PGP SIGNATURE-----

+ 15 - 0
scripts/t/700_Dpkg_Control/bogus-armor-nested.dsc

@@ -0,0 +1,15 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+ 	 
+Source: pass
+  
+-----BEGIN PGP SIGNATURE-----
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+Source: fail
+
+-----BEGIN PGP SIGNATURE-----
+
+Valid signature here.
+-----END PGP SIGNATURE-----

+ 18 - 0
scripts/t/700_Dpkg_Control/bogus-armor-spaces.dsc

@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNED MESSAGE-----    	
+Hash: SHA1
+ 	 
+Source: pass
+  
+-----BEGIN PGP SIGNATURE-----		  
+Version: GnuPG v1.4.12 (GNU/Linux)
+  
+Valid signature here.
+-----END PGP SIGNATURE-----
+
+Source: fail
+
+-----BEGIN PGP SIGNATURE
+Version: vim v7.3.547 (GNU/Linux)
+
+Fake signature here.
+-----END PGP SIGNATURE

+ 14 - 0
scripts/t/700_Dpkg_Control/bogus-armor-trail.dsc

@@ -0,0 +1,14 @@
+-----BEGIN PGP SIGNED MESSAGE
+
+Source: fail
+
+-----BEGIN PGP SIGNATURE
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA256
+
+Source: pass
+
+-----BEGIN PGP SIGNATURE-----   
+
+Valid signature here.
+-----END PGP SIGNATURE-----

+ 5 - 0
scripts/t/700_Dpkg_Control/bogus-unsigned.dsc

@@ -0,0 +1,5 @@
+-----BEGIN PGP MESSAGE-----
+
+Source: fail
+
+-----END PGP MESSAGE-----