Make keylookup use gpg --search instead of querying the keyserver directly.
authorweasel <weasel@b513b33f-fedd-0310-b452-c3deb5f4c849>
Tue, 16 Aug 2005 14:18:56 +0000 (14:18 +0000)
committerweasel <weasel@b513b33f-fedd-0310-b452-c3deb5f4c849>
Tue, 16 Aug 2005 14:18:56 +0000 (14:18 +0000)
git-svn-id: svn://svn.debian.org/pgp-tools/trunk@177 b513b33f-fedd-0310-b452-c3deb5f4c849

keylookup/NEWS
keylookup/keylookup

index 7e9eeed46cd57eb910f0095525725b03487780e1..c979e574a4841d8ecc91de90c4b8b209626bde85 100644 (file)
@@ -1,5 +1,9 @@
 $Id$
 
+Release notes for keylookup 2005-08-16
+ * Make keylookup use gpg --search instead of querying the
+   keyserver directly.
+
 Release notes for keylookup 2.2 (2002-09-24)
  * Some keyservers have started putting the key type (DSA or RSA)
    in their replies to searches. Keylookup now handles that.
index 5b02836d160c9c16575a29ba76da78d75e5abb49..1a60f24241ec0ecf9841bdf4d76125e851f96a64 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -Tw
+#!/usr/bin/perl -w
 
 # (c) 2000, 2002 Christian Kurz <shorty@debian.org>,
 #                Peter Palfrader <peter@palfrader.org>
@@ -33,17 +33,7 @@ use Getopt::Long;
 
 my $version = '2.1 ($Id$)';
 
-# The port to use for keyservers unless given otherwise.
-my $PORT=11371;
-# The default proxy port which is used unless the port is explicitly given
-# in the http_proxy environment variable.
-my $PROXY_PORT=3128;
-
-# Name of the GnuPG binary. The executeable must the in the PATH. This may
-# be overriden using the --gnupg= switch.
-my $GnuPG='gpg';
 # Where to find GnuPG's options file.
-my $GNUPGOPTIONS=(defined $ENV{GNUPGHOME} ? $ENV{GNUPGHOME} : $ENV{'HOME'}.'/.gnupg' ) . '/options';
 # Full path to the dialog and whiptail executeable.
 my $Dialog = '/usr/bin/dialog';
 my $Whiptail = '/usr/bin/whiptail';
@@ -69,59 +59,15 @@ my @WHIPTAILSIZE;
 my $keyserverWasSetOnCmdLine = 0;
 
 
-# Queries a remote keyserver (using a proxy if requested) and returns
-# the keyservers anser. No module is used deliberatly to make this
-# script run on as many systems as possible.
-
-sub fetchIt($$$$) {
-       my $server = shift;
-       my $port = shift;
-       my $requestURL = shift;
-       my $honorproxy = shift;
-       
-       my $result;
-       my $remote;
-
-       if ($honorproxy && defined $ENV{'http_proxy'}) {
-               my $proxyserver;
-               my $proxyport;
-
-               if ( $ENV{'http_proxy'} =~ m#^http://(\S+):(\d+)/?$# ) {
-                       $proxyserver = $1;
-                       $proxyport   = $2;
-               } elsif ( $ENV{'http_proxy'} =~ m#^http://(\S+)/?$# ) {
-                       $proxyserver = $1;
-                       $proxyport   = $PROXY_PORT;
-               } else {
-                       die ("Unkown http_proxy format");
-               };
-
-               $remote = IO::Socket::INET->new(
-                       Proto           => 'tcp',
-                       PeerAddr        => $proxyserver,
-                       PeerPort        => $proxyport
-               ) || die ("Cannot connect to prox: $!");
-
-               my $URL=sprintf("http://%s:%s%s/", $server, $port, $requestURL);
-               printf $remote "GET %s HTTP/1.1\n\n", $URL;
-       } else {
-               $remote = IO::Socket::INET->new(
-                       Proto           => 'tcp',
-                       PeerAddr        => $server,
-                       PeerPort        => $port
-               ) || die ("Cannot connect to keysever: $!");
-
-               printf $remote "GET %s HTTP/1.1\nHost: %s\n\n\n", $requestURL, $server;
-       };
-
-
-       {
-               local $/;
-               $/=undef;
-               $result = <$remote>;
-       };
-       return $result;
-};
+# Maps algorithm numbers to algorithm types as defined in RFC 2400.
+my %ALGOS = (
+                1 => 'R',         # RSA
+                2 => 'r',         # RSA encrypt only  (deprecated)
+                3 => 's',         # RSA sign only (deprecated)
+                16 => 'g',        # ElGamal encrypt only
+                20 => 'g',        # ElGamal sign and encrypt (all OpenPGP implementations cryptographically broken, do not use.  no longer part of OpenPGP)
+                17 => 'D'         # DSA
+            );
 
 
 # getHits receives all options as a parameter, calls fetchIT to
@@ -130,60 +76,56 @@ sub fetchIt($$$$) {
 sub getHits($) {
        my $options = shift;
 
-       die ("$0: No keyserver given!\n") unless (defined $options->{'keyserver'});
-
-       my $result = fetchIt(
-               $options->{'keyserver'}, 
-               $options->{'port'}, 
-               sprintf("/pks/lookup?op=index&search=%s", $options->{'search'}),
-               $options->{'honor-http-proxy'}
-       );
-
-       $result =~ s/<.*?>//g;
-       $result =~ s/&gt;/>/g;
-       $result =~ s/&lt;/</g;
-       $result =~ s/&quot;/"/g;
-       $result =~ s/&amp;/&/g;
-
-       my @lines = split (/\r?\n/, $result);
-
-       shift @lines;
-       shift @lines;
-       shift @lines;
-       shift @lines;
+       my $pid = open(KID, '-|');
+       defined ($pid) or die ("Cannot fork: $!\n");
+       unless ($pid) {
+               close (STDIN);
+               open (STDIN, "/dev/null") || die ("Cannot open /dev/null as stdin: $!\n");
 
+               # child
+               my @ops = ('gpg');
+               if ($options->{'keyserver'}) {
+                       push @ops, '--keyserver='.$options->{'keyserver'};
+               };
+               push @ops, '--command-fd=0';
+               push @ops, '--batch';
+               push @ops, '--no-tty';
+               push @ops, '--with-colons';
+               push @ops, '--fixed-list-mode';
+               push @ops, '--search';
+               push @ops, $options->{'search'};
+               exec(@ops);
+               die ("Cannot exec GnuPG: $!\n");
+       };
        my %keys;
        my $currentKey;
 
-       for (@lines) {
-               if (/^pub /) {
-                       m, ^pub                 # pub at the start of the line
-                          \s+                  # whitespace
-                          (\d+)                # bits                  1024
-                          ([A-Za-z]*)          # optional type (R or D usually) D
-                          /                    # a slash
-                          ([0-9A-Za-z]+)       # keyid                 94C09C7F
-                          \s+                  # whitespace
-                          (\d+)/(\d+)/(\d+)    # date                  1999/11/10
-                          \s+                  # whitespace
-                          (.*)                 # primary user id       Peter Palfrader
-                          ,x or
-                               warn ("Unexpected format: $_\n"), next;
-
-                       $currentKey = { 'bits' => $1,
-                                       'type' => $2,
-                                       'keyid' => $3,
-                                       'year' => $4,
-                                       'month' => $5,
-                                       'day' => $6,
-                                       'uid' => [ $7 ]
+       while (<KID>) {
+               chomp;
+               my ($type, undef) = split /:/;
+               if ($type eq 'pub') {
+                       my ($type, $keyid, $algo, $bits, $created, undef, $revoked) = split /:/;
+                       my (undef,undef,undef,$mday,$mon,$year,undef,undef,undef) = localtime ($created);
+                       $currentKey = { 'bits' => $bits,
+                                       'type' => (defined $ALGOS{$algo} ? $ALGOS{$algo} : '#'.$algo),
+                                       'keyid' => $keyid,
+                                       'year' => $year+1900,
+                                       'month' => $mon+1,
+                                       'day' => $mday,
+                                       'revoked' => $revoked,
+                                       'uid' => []
                                      };
-                       $keys{ $3 } = $currentKey;
-               } elsif (defined $currentKey) {
-                       s/^\s+//;
-                       push @{ $currentKey->{'uid'} }, $_;
+                       $keys{ $keyid } = $currentKey;
+               } elsif (defined $currentKey && $type eq 'uid') {
+                       my ($type, $name) = split /:/;
+                       if ($currentKey->{'revoked'} eq 'r') {
+                               $name .= ' [REVOKED]';
+                       };
+                       push @{ $currentKey->{'uid'} }, $name;
                };
        };
+       close KID;
+       waitpid $pid, 0;
 
        return \%keys;
 };
@@ -351,10 +293,11 @@ sub importKeys {
        my $keyids = shift;
        my $options = shift;
 
-       my @args = ( $options->{'gnupg'},
-                 '--keyserver',
-                 $options->{'keyserver'},
-                 '--recv-keys');
+       my @args = ('gpg');
+       if ($options->{'keyserver'}) {
+               push @args, '--keyserver='.$options->{'keyserver'};
+       };
+       push @args,  '--recv-keys';
        for my $keyid (@$keyids) {
                # untaint keyids
                my ($cleanid) = $keyid =~ /^([a-zA-Z0-9]{8})$/;
@@ -362,7 +305,7 @@ sub importKeys {
                        unless defined $cleanid;
                push @args, $cleanid;
        }
-                 
+
        print "Calling GnuPG...\n";
        exec (@args) || die "can't exec gnupg: $!\n"; # won't return
 };
@@ -375,11 +318,8 @@ Syntax: keylookup [options] <searchstring>
 
 Options:
        --keyserver=<keyserver> Select keyserver
-       --port=<port>           Use a non standard port
        --frontend=<frontend>   One of whiptail, dialog or plain
        --importall             Import all matched keys
-       --gnupg=<gnupg>         use this gnupg binary
-       --honor-http-proxy      honor the http_proxy environment varibale
        --help                  print this message
 
 EOF
@@ -395,40 +335,14 @@ sub version {
        my %options;
        GetOptions( \%options,
                'keyserver=s',
-               'port=i',
                'frontend=s',
                'importall',
-               'gnupg=s',
-               'honor-http-proxy',
                'version',
                'help') or
                &usage(1);
        &version(0) if ($options{'version'});
        &usage(0) if ($options{'help'} || ( scalar(@ARGV) == 0));
 
-       ## If the keyserver was not given on the command line, lurk into
-       ## GnuPG's config file, it might be defined there.
-       $keyserverWasSetOnCmdLine = defined $options{'keyserver'};
-       unless (defined $options{'keyserver'} &&
-               defined $options{'honor-http-proxy'} ) {
-               if ( open(GNUPGOPTIONS, $GNUPGOPTIONS) ) {
-                       my $keyserver = $options{'keyserver'};
-                       while (<GNUPGOPTIONS>) {
-                               $options{'keyserver'} = $1 if (/^\s*keyserver\s+(\S+?)[#\s]/i && ! defined $keyserver);
-                               $options{'honor-http-proxy'} = 1 if /^\s*(keyserver-options\s+)honor-http-proxy\s/i;
-                       };
-                       close(GNUPGOPTIONS) || warn("Cannot close $GNUPGOPTIONS: $!\n");
-               } else {
-                       warn ("Cannot open $GNUPGOPTIONS: $!\n");
-               };
-       };
-       $options{'port'}  = $PORT unless (defined $options{'port'});
-       $options{'gnupg'} = $GnuPG unless (defined $options{'gnupg'});
-
-       # Untaint it
-       $options{'keyserver'} =~ /(.*)/;
-       $options{'keyserver'} = $1;
-
        ## Take all additional arguments to the program as a search target,
        ## escape the string for use in URLs.
        $options{'search'} = join ' ', @ARGV;