[Pkg-privacy-commits] [parcimonie] 10/25: Add support for GnuPG 2.1+.

Intrigeri intrigeri at moszumanska.debian.org
Sun May 29 11:33:09 UTC 2016


This is an automated email from the git hooks/post-receive script.

intrigeri pushed a commit to branch master
in repository parcimonie.

commit df605af24d6227e0f290d4ca5d614147c7f2bcba
Author: intrigeri <intrigeri at boum.org>
Date:   Sun May 29 10:30:55 2016 +0000

    Add support for GnuPG 2.1+.
    
    By default, we auto-detect whether the gpg binary found in $PATH
    is GnuPG 2.1+, and if it is we configure dirmng to use Tor.
    
    One can explicitly choose to use the gpg2 binary by passing the --gnupg2
    option to parcimonie.
---
 dist.ini                              |  2 ++
 lib/App/Parcimonie.pm                 | 66 ++++++++++++++++++++++++-----------
 lib/App/Parcimonie/Daemon.pm          | 16 ++++++++-
 lib/App/Parcimonie/GnuPG/Interface.pm | 27 +++++++++++---
 4 files changed, 86 insertions(+), 25 deletions(-)

diff --git a/dist.ini b/dist.ini
index ab80f8a..9d3ec6f 100644
--- a/dist.ini
+++ b/dist.ini
@@ -30,6 +30,7 @@ mb_class = My::Builder
 
 [Prereqs]
 namespace::clean = 0.25
+version = 0.9909
 Carp = 1.11
 Clone = 0.31
 Config::General = 2.48
@@ -41,6 +42,7 @@ Glib = 1.223
 GnuPG::Interface = 0.42
 Gtk3 = 0.011
 I18N::Langinfo = 0
+IPC::System::Simple = 0
 JSON::PP = 0
 List::MoreUtils = 0.25
 List::Util = 1.33
diff --git a/lib/App/Parcimonie.pm b/lib/App/Parcimonie.pm
index 32f80b3..ca8239e 100644
--- a/lib/App/Parcimonie.pm
+++ b/lib/App/Parcimonie.pm
@@ -10,10 +10,12 @@ use Config::General qw/ParseConfig/;
 use Encode;
 use English qw/-no_match_vars/;
 use File::HomeDir;
+use IPC::System::Simple qw/capturex/;
 use List::MoreUtils qw/uniq/;
 use List::Util qw/shuffle/;
 use Path::Tiny;
 use Try::Tiny;
+use version 0.77;
 
 use Exporter;
 our @ISA = qw(Exporter);
@@ -33,7 +35,7 @@ See bin/parcimonie :)
 
 =cut
 
-our @EXPORT = qw/pickRandomItems gpgPublicKeys gpgRecvKeys
+our @EXPORT = qw/pickRandomItems gpgPublicKeys gpgRecvKeys gpg_is_v21
                  checkGpgHasDefinedKeyserver averageLapseTime/;
 
 my $codeset;
@@ -68,6 +70,17 @@ sub pickRandomItems {
     return @randomized_pool[0..$n - 1];
 }
 
+=head2 gpg_is_v21()
+
+Detects the version of the gpg binary in the $PATH.
+Returns true iff. it is 2.1 or newer.
+
+=cut
+sub gpg_is_v21 {
+    version->parse(App::Parcimonie::GnuPG::Interface->new()->version())
+        >= version->parse('2.1.0');
+}
+
 =head2 gpgPublicKeys()
 
 Returns the list of key fingerprints found in the public keyring.
@@ -152,29 +165,42 @@ Throws an exception if no keyserver is defined in GnuPG configuration.
 =cut
 
 sub checkGpgHasDefinedKeyserver {
-    my $arg_ref = shift;
-    my $gnupg_homedir = $arg_ref->{homedir};
-
-    my $gpgconf;
-    if (defined $gnupg_homedir) {
-        $gpgconf = path($gnupg_homedir, 'gpg.conf');
+    my $gnupg_options = shift;
+    my $arg_ref       = shift;
+    my $gnupg_homedir = $gnupg_options->{homedir};
+    my $gnupg2        = $arg_ref->{gnupg2};
+
+    if ($gnupg2) {
+        my @output = capturex(qw{gpg-connect-agent --dirmngr keyserver /bye});
+        my $res = pop @output;
+        $res eq "OK\n" || croak "Agent replied: $res";
+        @output        || croak "No keyserver is configured.";
+        my $last_keyserver = pop @output;
+        $last_keyserver =~ m{\A [S] \s+ KEYSERVER \s+}xms
+            || croak "No keyserver is configured."
     }
     else {
-        $gpgconf = path(File::HomeDir->my_home, '.gnupg', 'gpg.conf');
+        my $gpgconf;
+        if (defined $gnupg_homedir) {
+            $gpgconf = path($gnupg_homedir, 'gpg.conf');
+        }
+        else {
+            $gpgconf = path(File::HomeDir->my_home, '.gnupg', 'gpg.conf');
+        }
+
+        -f $gpgconf
+            or croak "No GnuPG configuration file was found in '$gpgconf'";
+        -r $gpgconf
+            or croak "The GnuPG configuration file ($gpgconf) is not readable";
+
+        my %gpgconf = ParseConfig($gpgconf);
+
+        defined $gpgconf{keyserver} && length $gpgconf{keyserver}
+            or croak
+                "No keyserver is defined in GnuPG configuration ($gpgconf).\n" .
+                "See 'man parcimonie' to learn how to correct that.";
     }
 
-    -f $gpgconf
-        or croak "No GnuPG configuration file was found in '$gpgconf'";
-    -r $gpgconf
-        or croak "The GnuPG configuration file ($gpgconf) is not readable";
-
-    my %gpgconf = ParseConfig($gpgconf);
-
-    defined $gpgconf{keyserver} && length $gpgconf{keyserver}
-        or croak
-            "No keyserver is defined in GnuPG configuration ($gpgconf).\n" .
-            "See 'man parcimonie' to learn how to correct that.";
-
     return;
 }
 
diff --git a/lib/App/Parcimonie/Daemon.pm b/lib/App/Parcimonie/Daemon.pm
index 0ff8e7a..7acdfad 100644
--- a/lib/App/Parcimonie/Daemon.pm
+++ b/lib/App/Parcimonie/Daemon.pm
@@ -119,6 +119,14 @@ option 'gnupg_already_torified' => (
     default   => sub { 0; },
 );
 
+option 'gnupg2' => (
+    documentation => q{Use GnuPG 2.1+ (default: autodetect gpg's version).},
+    isa      => 'Bool',
+    is       => 'ro',
+    required => 0,
+    default  => sub { gpg_is_v21(); },
+);
+
 has 'memory_usage' => (
     isa       => 'Memory::Usage',
     is        => 'ro',
@@ -141,7 +149,11 @@ sub BUILD {
     $self->record_memory_usage("[BUILD]: entering");
 
     $self->keyserver_defined_on_command_line
-        or checkGpgHasDefinedKeyserver($self->gnupg_options);
+        or checkGpgHasDefinedKeyserver(
+            $self->gnupg_options,
+            {
+                gnupg2 => $self->gnupg2,
+            });
 
     if ($self->with_dbus) {
         $self->record_memory_usage("[BUILD]: starting to load D-Bus dependencies");
@@ -339,6 +351,7 @@ sub tryRecvKey {
             [ $keyid ],
             $self->gnupg_options,
             already_torified => $self->gnupg_already_torified,
+            gnupg2           => $self->gnupg2,
         );
     } catch {
         $gpg_error = $_;
@@ -401,6 +414,7 @@ sub iterate {
     my @public_keys = gpgPublicKeys(
         $self->gnupg_options,
         already_torified => $self->gnupg_already_torified,
+        gnupg2           => $self->gnupg2,
     );
     unless (@public_keys) {
         warn "No public key was found.";
diff --git a/lib/App/Parcimonie/GnuPG/Interface.pm b/lib/App/Parcimonie/GnuPG/Interface.pm
index 0252c27..13bb6dc 100644
--- a/lib/App/Parcimonie/GnuPG/Interface.pm
+++ b/lib/App/Parcimonie/GnuPG/Interface.pm
@@ -14,6 +14,7 @@ use Moo;
 use MooX::late;
 use Carp;
 use File::Which qw{which};
+use IPC::System::Simple qw{system systemx};
 
 use namespace::clean;
 
@@ -26,13 +27,31 @@ has 'already_torified' => (
     default  => sub { 0; },
 );
 
+has 'gnupg2' => (
+    isa      => 'Bool',
+    is       => 'rw',
+    required => 0,
+    default  => sub { 0; },
+);
+
 after 'BUILD' => sub {
     my $self = shift;
-    unless ($self->already_torified) {
-        foreach my $prog (qw{torsocks parcimonie-torified-gpg}) {
-            defined which($prog) or croak "$prog not found in \$PATH";
+    if ($self->gnupg2) {
+        unless ($self->already_torified) {
+            system(q{echo 'use-tor:0:1' | gpgconf --change-options dirmngr});
+            # Passing --runtime to the previous command does not work,
+            # so we have to:
+            systemx(qw{gpgconf --reload dirmngr});
+        }
+        $self->call('gpg2');
+    }
+    else {
+        unless ($self->already_torified) {
+            foreach my $prog (qw{torsocks parcimonie-torified-gpg}) {
+                defined which($prog) or croak "$prog not found in \$PATH";
+            }
+            $self->call('parcimonie-torified-gpg');
         }
-        $self->call('parcimonie-torified-gpg');
     }
 };
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/parcimonie.git



More information about the Pkg-privacy-commits mailing list