From 219316fe8dcc6f5b599e2cf2ef3bcf0f72a02938 Mon Sep 17 00:00:00 2001 From: Florian Pritz Date: Thu, 6 Sep 2018 12:13:26 +0200 Subject: masterkey.pl: Select best email instead of using first one from gpg uid list Signed-off-by: Florian Pritz --- masterkey.pl | 59 ++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/masterkey.pl b/masterkey.pl index 861427a..a55579a 100755 --- a/masterkey.pl +++ b/masterkey.pl @@ -10,6 +10,7 @@ use Function::Parameters; use Getopt::Long; use GnuPG::Interface; use JSON; +use List::Util qw(first); use List::MoreUtils; use Mail::GPG; use MIME::Entity; @@ -32,12 +33,14 @@ Send verification mails to the owners of the listed GPG keys. --help, -h short help message --dry-run, -n do not perform any permanent actions --from, -f GPG ID used to send the email + --from-address Email of GPG ID to use --tokenfile Record tokens in this file --debug Output debugging information =cut sub main { + my $recipient_address_regex = qr/\@archlinux\.org/; my %templates = ( 'verification' => { 'subject' => 'Master Key Verification for {$recipient_name} ({$recipient_key})', @@ -75,7 +78,7 @@ on behalf of {$sender_name} ({$sender_key}) my %opts = (); Getopt::Long::Configure ("bundling"); - GetOptions(\%opts, "help|h", "dry-run|n", "from|f=s", "tokenfile=s", "debug") or pod2usage(2); + GetOptions(\%opts, "help|h", "dry-run|n", "from|f=s", "from-address=s", "tokenfile=s", "debug") or pod2usage(2); pod2usage(0) if $opts{help}; pod2usage(-verbose => 0) if (@ARGV== 0); @@ -95,7 +98,7 @@ on behalf of {$sender_name} ({$sender_key}) my $mail_body = $templates{$command}{'body'}; my $token = random_string('.' x 25); - my $msg = build_email($command, $opts{from}, $id, $mail_subject, $mail_body, $token); + my $msg = build_email($command, $opts{from}, quotemeta($opts{'from-address'}), $id, $recipient_address_regex, $mail_subject, $mail_body, $token); if ($command eq 'verification') { save_token($id, $token, $opts{tokenfile}) unless $opts{'dry-run'}; @@ -124,33 +127,51 @@ fun fill_template($template, $values) { fun gpg_get_users($key) { my $gpg = GnuPG::Interface->new(); - my @keys = $gpg->get_public_keys($key); + my @keys = $gpg->get_public_keys_with_sigs($key); die "No key found" if 0+@keys == 0; - my $user = Encode::decode('utf8', $keys[0]->user_ids_ref->[0]->as_string); + my @users; - unless ($user =~ m/^(?.*?) (?:\((?.*?)\) )?\<(?.*?@.*?)\>$/) { - die "Failed to parse GPG user information for key $key; got $user"; - } + for my $uid ($keys[0]->user_ids->@*) { + next if $uid->revocations->@* > 0; + + my $user = Encode::decode('utf8', $uid->as_string); + unless ($user =~ m/^(?.*?) (?:\((?.*?)\) )?\<(?.*?@.*?)\>$/) { + die "Failed to parse GPG user information for key $key; got $user"; + } - my $name = $+{name}; - my $email = $+{email}; + push @users, {%+}; + } - return ($name, $email); + return \@users; } -sub build_email { - my $command = shift; - my $sender_key = shift; - my $recipient_key = shift; - my $subject = shift; - my $body = shift; - my $token = shift; +fun gpg_get_user($key, $email_regex) { + my $users = gpg_get_users($key); + + return $users->[0] if $users->@* == 1; + + my $user = first {$_->{email} =~ m/$email_regex/} $users->@*; + + while (not defined $user) { + for my $item ($users->@*) { + printf "%s - %s\n", $item->@{qw(name email)}; + } + + print "Enter email address to use: "; + my $email = ; + chomp($email); + $user = first {$_->{email} eq $email} $users->@*; + } + + return $user; +} +fun build_email($command, $sender_key, $from_address_regex, $recipient_key, $recipient_address_regex, $subject, $body, $token) { # get from gpg keys - my ($sender_name, $sender_addr) = gpg_get_user($sender_key); - my ($recipient_name, $recipient_addr) = gpg_get_user($recipient_key); + my ($sender_name, $sender_addr) = gpg_get_user($sender_key, $from_address_regex)->@{qw(name email)}; + my ($recipient_name, $recipient_addr) = gpg_get_user($recipient_key, $recipient_address_regex)->@{qw(name email)}; my %values; $values{token} = $token; -- cgit v1.2.3-24-g4f1b