From 626e59e0e1d665f2e81b29b53671008ec2dcd5a6 Mon Sep 17 00:00:00 2001 From: David Bremner Date: Thu, 10 Mar 2011 12:08:07 -0400 Subject: [PATCH] Interrogate the GnuPG::Interface object to get $GPGHOME, when guessing a keyserver. We fall back on the environment, as before. This required splitting untaint out into its own module. --- Crypt/Monkeysphere/Keyserver.pm | 38 +++++++++++++++++++------ Crypt/Monkeysphere/MSVA.pm | 10 +------ Crypt/Monkeysphere/Util.pm | 19 +++++++++++++ unit-tests/10.keyserver/10.gnupghome.t | 39 ++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 17 deletions(-) create mode 100644 Crypt/Monkeysphere/Util.pm create mode 100644 unit-tests/10.keyserver/10.gnupghome.t diff --git a/Crypt/Monkeysphere/Keyserver.pm b/Crypt/Monkeysphere/Keyserver.pm index ff436eb..9799868 100644 --- a/Crypt/Monkeysphere/Keyserver.pm +++ b/Crypt/Monkeysphere/Keyserver.pm @@ -10,6 +10,7 @@ use POSIX; use strict; use warnings; use parent qw(Crypt::Monkeysphere::Logger); +use Crypt::Monkeysphere::Util qw(untaint); our $default_keyserver='hkp://pool.sks-keyservers.net'; @@ -19,8 +20,12 @@ sub new { my $self=$class->SUPER::new($opts{loglevel} || 'info'); - $self->{keyserver} = $opts{keyserver} || $self->_get_keyserver(); + # gnupg should be initialized first, before figuring out + # what keyserver to use. + $self->{gnupg} = $opts{gnupg} || new GnuPG::Interface(); + + $self->{keyserver} = $opts{keyserver} || $self->_get_keyserver(); return $self; } @@ -28,13 +33,31 @@ sub _get_keyserver{ my $self=shift; - my $gpghome; + my $gpghome=$self->{gnupg}->options->homedir; + + if (!defined($gpghome)) { + if (exists $ENV{GNUPGHOME} and $ENV{GNUPGHOME} ne '') { + $gpghome = untaint($ENV{GNUPGHOME}); + } else { + my $userhome=File::HomeDir->my_home; + if (defined($userhome)) { + $gpghome = File::Spec->catfile($userhome, '.gnupg'); + } + } + } - if (exists $ENV{GNUPGHOME} and $ENV{GNUPGHOME} ne '') { - $gpghome = untaint($ENV{GNUPGHOME}); + if (defined $gpghome) { + return $self->_read_keyserver_from_gpg_conf($gpghome) || $default_keyserver; } else { - $gpghome = File::Spec->catfile(File::HomeDir->my_home, '.gnupg'); + return $default_keyserver; } + +} + +sub _read_keyserver_from_gpg_conf() { + my $self=shift; + my $gpghome=shift; + my $gpgconf = File::Spec->catfile($gpghome, 'gpg.conf'); if (-f $gpgconf) { if (-r $gpgconf) { @@ -51,12 +74,11 @@ sub _get_keyserver{ } else { $self->log('info', "Did not find GnuPG configuration file while looking for keyserver '%s'\n", $gpgconf); } - - return $default_keyserver; + return undef; + } - sub fetch_uid { my $self= shift; my $uid = shift || croak("uid argument mandatory"); diff --git a/Crypt/Monkeysphere/MSVA.pm b/Crypt/Monkeysphere/MSVA.pm index f3fe0d7..9436671 100755 --- a/Crypt/Monkeysphere/MSVA.pm +++ b/Crypt/Monkeysphere/MSVA.pm @@ -37,6 +37,7 @@ use Config::General; use Crypt::Monkeysphere::MSVA::MarginalUI; use Crypt::Monkeysphere::Logger; + use Crypt::Monkeysphere::Util qw(untaint); use Crypt::Monkeysphere::MSVA::Monitor; use JSON; @@ -749,15 +750,6 @@ } } - # use sparingly! We want to keep taint mode around for the data we - # get over the network. this is only here because we want to treat - # the command line arguments differently for the subprocess. - sub untaint { - my $x = shift; - $x =~ /^(.*)$/ ; - return $1; - } - sub post_bind_hook { my $self = shift; my $server = shift; diff --git a/Crypt/Monkeysphere/Util.pm b/Crypt/Monkeysphere/Util.pm new file mode 100644 index 0000000..d4694d5 --- /dev/null +++ b/Crypt/Monkeysphere/Util.pm @@ -0,0 +1,19 @@ +package Crypt::Monkeysphere::Util; + +use strict; +use warnings; + +use Exporter qw(import); +our @EXPORT_OK=qw(untaint); + + +# use sparingly! We want to keep taint mode around for the data we +# get over the network. this is only here because we want to treat +# the command line arguments differently for the subprocess. +sub untaint { + my $x = shift; + $x =~ /^(.*)$/ ; + return $1; +} + +1; diff --git a/unit-tests/10.keyserver/10.gnupghome.t b/unit-tests/10.keyserver/10.gnupghome.t new file mode 100644 index 0000000..c8ec61b --- /dev/null +++ b/unit-tests/10.keyserver/10.gnupghome.t @@ -0,0 +1,39 @@ +# -*- perl -*- +use Test::More; + +use Crypt::Monkeysphere::Keyserver; +use GnuPG::Interface; +use File::Temp qw(tempdir); +use strict; +use warnings; + +my $fpr='762B57BB784206AD'; +plan tests =>5; + +{ + + $ENV{HOME}='/nonexistant'; + my $ks = new Crypt::Monkeysphere::Keyserver(); + + isa_ok($ks,'Crypt::Monkeysphere::Keyserver'); + is($ks->{keyserver},$Crypt::Monkeysphere::Keyserver::default_keyserver); + +} + +my $tempdir = tempdir("/tmp/unitXXXXX", CLEANUP=> 1); +my $gnupg = new GnuPG::Interface(); +my $testks = 'hkp://keys.gnupg.net'; +$gnupg->options->hash_init(homedir=>$tempdir); + +is($gnupg->options->homedir,$tempdir); + +open GPGCONF, '>', "$tempdir/gpg.conf"; +print GPGCONF "keyserver $testks\n"; +close GPGCONF; + +my $ks=new Crypt::Monkeysphere::Keyserver(gnupg=>$gnupg, + loglevel=>'debug'); + +isa_ok($ks,'Crypt::Monkeysphere::Keyserver'); + +is($ks->{keyserver},$testks); -- 2.26.2