#!/usr/bin/perl use strict; use warnings; my ($keyserver, $getEmails); BEGIN { $keyserver = shift || 'subkeys.pgp.net:11371'; # the keyserver to + use $getEmails = undef; # wether to get em +ails or not } $, = $\ = $/; # ;-) use LWP::Simple; use URI::Find; use if $getEmails => 'Email::Find'; use if $getEmails => 'PGP::FindKey'; # mainly compile time death BEGIN { unless (eval { require Crypt::OpenPGP::KeyServer }){ # getting ugl +y ## the following emulates Crypt::OpenPGP::Keyserver, in a not +so pretty way. *Crypt::OpenPGP::KeyServer::new = sub { # create a new object my $pkg = shift; my %conf = @_; bless \$conf{Server}, $pkg; # fill it only with the keyser +ver setting }; *Crypt::OpenPGP::KeyServer::find_keyblock_by_uid = sub { # fet +ch a key via uid - wraps around PGP::FindKey - not much fun. my $self = shift; my $str = shift; my $id = PGP::FindKey->new( keyserver => $keyserver, address => $str, )->result; $self->find_keyblock_by_keyid(pack("H*",$id)); # "find" th +ey key ID. PGP::FindKey only gives back one key }; *Crypt::OpenPGP::KeyServer::find_keyblock_by_keyid = sub { # f +etch a key via it's id - constructs a simple URL my $self = shift; my $id = unpack("H*", shift); my $url = "http://" . $$self . '/pks/lookup?op=get&search= +0x' . $id; # the URL we'll be fetching filter_key_blocks(LWP::Simple::get($url)); # give back an +array or string of key blocks, made from the return value of the HTTP + get }; } } my $kbs = Crypt::OpenPGP::KeyServer->new( Server => $keyserver, ); my @finders = ( # the general interface is the same, so we've grouped +them URI::Find->new(sub { # to find URLS print filter_key_blocks(get(shift)); # get the URL using LWP:: +Simple, and filter key blocks out of it return shift; }), ($getEmails ? Email::Find->new(sub { # to find emails, if at all my $emails = shift; foreach my $email (@$emails){ print $kbs->find_keyblock_by_uid +($email) || '' }; # run the list of emails through the key server obj +ect, and print the results out return shift; }) : () ), ); sub get_id { # a shortcut to print a key by it's ID print $kbs->find_keyblock_by_keyid(pack 'H*', shift) || ''; } sub filter_key_blocks { my $str = shift; my @blocks = $str =~ /(-----BEGIN PGP PUBLIC KEY BLOCK-----.*?---- +-END PGP PUBLIC KEY BLOCK-----)/sg; # get all the blocks, nothing mor +e return wantarray ? @blocks : join($/, @blocks); # join if scalar c +ontext } while (<>){ #study; foreach my $uid (/\b(?:0x)((?:[a-fA-F0-9]{8}){1,2})\b/g){ get_id($ +uid) }; # matches ID foreach my $finder (@finders) { $finder->find(\$_) }; # run the ca +nned matches on the input }
In reply to GPG Key prefetcher by nothingmuch
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |