diff options
-rwxr-xr-x | masterkey.pl | 59 |
1 files 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> GPG ID used to send the email + --from-address <email> Email of GPG ID to use --tokenfile <file> 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/^(?<name>.*?) (?:\((?<comment>.*?)\) )?\<(?<email>.*?@.*?)\>$/) { - 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/^(?<name>.*?) (?:\((?<comment>.*?)\) )?\<(?<email>.*?@.*?)\>$/) { + 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 = <STDIN>; + 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; |