Interrogate the GnuPG::Interface object to get $GPGHOME, when guessing
authorDavid Bremner <bremner@unb.ca>
Thu, 10 Mar 2011 16:08:07 +0000 (12:08 -0400)
committerDavid Bremner <bremner@unb.ca>
Thu, 10 Mar 2011 16:59:51 +0000 (12:59 -0400)
a keyserver.

We fall back on the environment, as before. This required splitting
untaint out into its own module.

Crypt/Monkeysphere/Keyserver.pm
Crypt/Monkeysphere/MSVA.pm
Crypt/Monkeysphere/Util.pm [new file with mode: 0644]
unit-tests/10.keyserver/10.gnupghome.t [new file with mode: 0644]

index ff436eb9f46d4a22c669f5a960d037b6806a73dd..97998687492dad574c24be40f0af5f15edbc0b91 100644 (file)
@@ -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");
index f3fe0d797ea5654e29f976fe8986fa981214110b..9436671da33f6c4353202da247059ac200e15b80 100755 (executable)
@@ -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;
     }
   }
 
-  # 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 (file)
index 0000000..d4694d5
--- /dev/null
@@ -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 (file)
index 0000000..c8ec61b
--- /dev/null
@@ -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);