The following commit has been merged in the master branch:
commit 0e804cc658e3a00e07873a4be880f3d2769c913f
Author: James McCoy <[email protected]>
Date:   Wed Dec 19 22:25:01 2012 -0500

    dscverify: Use "gpg --status-fd" to get more details about validity
    
    Simply running "gpg < file" doesn't ensure the content is properly
    signed.  Even when it does, we may not be using the signed content.
    
    Using "gpg --status-fd 1 < file" solves both of these issues.  Even
    though it still won't error out with an unsigned file, we'll be able to
    detect that the content wasn't signed by the lack of a VALIDSIG status.
    Also, the command will emit the signed content between PLAINTEXT status
    and any subsequent status lines.
    
    Closes: #695914
    Signed-off-by: James McCoy <[email protected]>

diff --git a/debian/changelog b/debian/changelog
index ea99072..a587d22 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -18,6 +18,8 @@ devscripts (2.12.6+exp1) UNRELEASED; urgency=low
     + Handle an incomplete line of output.  (Closes: #695609)
     + Don't treat backslashes in the command's output as an escape.  (Closes:
       #695613)
+  * dscverify: Use "gpg --status-fd" to determine if a valid signature is
+    found and only use the signed content.  (Closes: #695914)
 
   [ Dmitry Smirnov ]
   * licensecheck: Remove any regular comments pattern. (Closes: #526698)
diff --git a/scripts/dscverify.pl b/scripts/dscverify.pl
index d13ded0..c313055 100755
--- a/scripts/dscverify.pl
+++ b/scripts/dscverify.pl
@@ -110,11 +110,11 @@ sub get_rings {
     xdie "can't find any system keyrings\n";
 }
 
-sub check_signature {
-    my ($file, @rings) = @_;
+sub check_signature($\@;\$) {
+    my ($file, $rings, $outref) = @_;
 
-    my @cmd = qw(gpg --batch --no-options --no-default-keyring --always-trust);
-    foreach (@rings) { push @cmd, '--keyring'; push @cmd, $_; }
+    my @cmd = qw(gpg --status-fd 1 --batch --no-options --no-default-keyring 
--always-trust);
+    foreach (@$rings) { push @cmd, '--keyring'; push @cmd, $_; }
 
     my ($out, $err) = ('', '');
     eval {
@@ -129,6 +129,17 @@ sub check_signature {
        print $out if ($verbose);
        return $err || $@;
     }
+    if ($out !~ m/^\[GNUPG:\] VALIDSIG/m) {
+       $out = join("\n", grep /^(?!\[GNUPG:\] )/, split(/\n/, $out))."\n";
+       return $out;
+    }
+
+    if (defined $outref) {
+       my @lines = split(/\n/, $out);
+       while ($lines[0] =~ m/^\[GNUPG:\] PLAINTEXT/) { shift @lines; }
+       while ($lines[0] !~ m/^\[GNUPG:\]/) { $$outref .= "$lines[0]\n"; shift 
@lines; }
+    }
+
     return '';
 }
 
@@ -152,14 +163,26 @@ sub process_file {
        $filebase = $file;
     }
 
-    if (!open SIGNED, '<', $filebase) {
-       xwarn "can't open $file:";
-       return;
+    my $out;
+    if ($verify_sigs) {
+       $sigcheck = check_signature $filebase, @rings, $out;
+       if ($sigcheck) {
+           xwarn "$file failed signature check:\n$sigcheck";
+           return;
+       } else {
+           print "      Good signature found\n";
+       }
     }
-    my $out = do { local $/; <SIGNED> };
-    if (!close SIGNED) {
-       xwarn "problem reading $file:";
-       return;
+    else {
+       if (!open SIGNED, '<', $filebase) {
+           xwarn "can't open $file:";
+           return;
+       }
+       $out = do { local $/; <SIGNED> };
+       if (!close SIGNED) {
+           xwarn "problem reading $file:";
+           return;
+       }
     }
 
     if ($file =~ /\.changes$/ and $out =~ /^Format:\s*(.*)$/mi) {
@@ -177,16 +200,6 @@ sub process_file {
        }
     }
 
-    if ($verify_sigs == 1) {
-       $sigcheck = check_signature $filebase, @rings;
-       if ($sigcheck) {
-           xwarn "$file failed signature check:\n$sigcheck";
-           return;
-       } else {
-           print "      Good signature found\n";
-       }
-    }
-
     my @spec = map { split /\n/ } $out =~ /^Files:\s*\n((?:[ \t]+.*\n)+)/mgi;
     unless (@spec) {
        xwarn "no file spec lines in $file\n";
@@ -316,7 +329,7 @@ sub process_file {
 
        close FILE;
 
-       if ($filename =~ /\.dsc$/ && $verify_sigs == 1) {
+       if ($filename =~ /\.dsc$/ && $verify_sigs) {
            $sigcheck = check_signature $filename, @rings;
            if ($sigcheck) {
                xwarn "$filename failed signature check:\n$sigcheck";

-- 
Git repository for devscripts

_______________________________________________
devscripts-devel mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/devscripts-devel

Reply via email to