The following commit has been merged in the master branch:
commit 9945c52208fa7520bb307868d6c152ced8238969
Author: Guillem Jover <[email protected]>
Date: Sun Dec 16 00:33:25 2012 +0100
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 <[email protected]>
diff --git a/debian/changelog b/debian/changelog
index 0a2c7d5..c881d8b 100644
--- a/debian/changelog
+++ b/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).
diff --git a/scripts/Dpkg/Control/Hash.pm b/scripts/Dpkg/Control/Hash.pm
index fabcf68..623ca73 100644
--- a/scripts/Dpkg/Control/Hash.pm
+++ b/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"));
diff --git a/scripts/Dpkg/Source/Package.pm b/scripts/Dpkg/Source/Package.pm
index 47ea319..cbc35aa 100644
--- a/scripts/Dpkg/Source/Package.pm
+++ b/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);
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 3172097..13c9123 100644
--- a/scripts/Makefile.am
+++ b/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 \
diff --git a/scripts/t/700_Dpkg_Control.t b/scripts/t/700_Dpkg_Control.t
index fbdc997..dab90d5 100644
--- a/scripts/t/700_Dpkg_Control.t
+++ b/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');
diff --git a/scripts/t/700_Dpkg_Control/bogus-armor-double.dsc
b/scripts/t/700_Dpkg_Control/bogus-armor-double.dsc
new file mode 100644
index 0000000..1888a00
--- /dev/null
+++ b/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-----
diff --git a/scripts/t/700_Dpkg_Control/bogus-armor-nested.dsc
b/scripts/t/700_Dpkg_Control/bogus-armor-nested.dsc
new file mode 100644
index 0000000..ca99c35
--- /dev/null
+++ b/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-----
diff --git a/scripts/t/700_Dpkg_Control/bogus-armor-spaces.dsc
b/scripts/t/700_Dpkg_Control/bogus-armor-spaces.dsc
new file mode 100644
index 0000000..ab71ab5
--- /dev/null
+++ b/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
diff --git a/scripts/t/700_Dpkg_Control/bogus-armor-trail.dsc
b/scripts/t/700_Dpkg_Control/bogus-armor-trail.dsc
new file mode 100644
index 0000000..90b00f1
--- /dev/null
+++ b/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-----
diff --git a/scripts/t/700_Dpkg_Control/bogus-unsigned.dsc
b/scripts/t/700_Dpkg_Control/bogus-unsigned.dsc
new file mode 100644
index 0000000..7573eb3
--- /dev/null
+++ b/scripts/t/700_Dpkg_Control/bogus-unsigned.dsc
@@ -0,0 +1,5 @@
+-----BEGIN PGP MESSAGE-----
+
+Source: fail
+
+-----END PGP MESSAGE-----
--
dpkg's main repository
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]