summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xmasterkey.pl48
1 files changed, 41 insertions, 7 deletions
diff --git a/masterkey.pl b/masterkey.pl
index a43dba3..4d26194 100755
--- a/masterkey.pl
+++ b/masterkey.pl
@@ -9,6 +9,7 @@ use Email::MessageID;
use Getopt::Long;
use GnuPG::Interface;
use JSON;
+use List::MoreUtils;
use Mail::GPG;
use MIME::Entity;
use Pod::Usage;
@@ -36,8 +37,10 @@ Send verification mails to the owners of the listed GPG keys.
=cut
sub main {
-my $mail_subject = 'Master Key Verification for {$recipient_name} ({$recipient_key})';
-my $mail_template = 'Hi,
+ my %templates = (
+ 'verification' => {
+ 'subject' => 'Master Key Verification for {$recipient_name} ({$recipient_key})',
+ 'body' => 'Hi,
This mail is about having your GPG key signed by an Arch Linux master key.
Please reply with an email that is signed with your key ({$recipient_key})
@@ -48,7 +51,21 @@ Your token: {$token}
Best Regards,
SAMKIVS (Simple Automated Master Key Identity Verification System)
on behalf of {$sender_name} ({$sender_key})
-';
+',
+ },
+ 'confirmation' => {
+ 'subject' => 'Master Key Signature Confirmation for {$recipient_name} ({$recipient_key})',
+ 'body' => 'Hi,
+
+Your GPG key ({$recipient_key})
+has been successfully signed by an Arch Linux master key.
+
+Best Regards,
+SAMKIVS (Simple Automated Master Key Identity Verification System)
+on behalf of {$sender_name} ({$sender_key})
+',
+ },
+ );
my %opts = ();
@@ -57,18 +74,28 @@ on behalf of {$sender_name} ({$sender_key})
pod2usage(0) if $opts{help};
pod2usage(-verbose => 0) if (@ARGV== 0);
+ my $command = shift @ARGV;
+
# TODO: print all errors at once
die "Error: --from option is required but not set\n" if not $opts{from};
die "Error: --tokenfile option is required but not set\n" if not $opts{tokenfile};
+ die "Error: no or invalid command\n" unless $templates{$command};
for my $id (@ARGV) {
say STDERR "Processing $id";
try {
+ die "key ID has length != 40\n" unless length($id) == 40;
+
+ my $mail_subject = $templates{$command}{'subject'};
+ my $mail_body = $templates{$command}{'body'};
my $token = random_string('.' x 25);
- my $msg = build_email($opts{from}, $id, $mail_subject, $mail_template, $token);
+ my $msg = build_email($command, $opts{from}, $id, $mail_subject, $mail_body, $token);
+
+ if ($command eq 'verification') {
+ save_token($id, $token, $opts{tokenfile}) unless $opts{'dry-run'};
+ }
- save_token($id, $token, $opts{tokenfile}) unless $opts{'dry-run'};
send_email($msg) unless $opts{'dry-run'};
say $msg->as_string if $opts{debug};
} catch {
@@ -108,7 +135,7 @@ sub gpg_get_user {
my $user = $keys[0]->user_ids_ref->[0]->as_string;
unless ($user =~ m/^(?<name>.*?) (?:\((?<comment>.*?)\) )?\<(?<email>.*?@.*?)\>$/) {
- die "Failed to parse GPG user information for key $key";
+ die "Failed to parse GPG user information for key $key; got $user";
}
my $name = $+{name};
@@ -118,6 +145,7 @@ sub gpg_get_user {
}
sub build_email {
+ my $command = shift;
my $sender_key = shift;
my $recipient_key = shift;
my $subject = shift;
@@ -160,7 +188,13 @@ sub build_email {
$msg->add("Message-ID", Email::MessageID->new->in_brackets);
$msg->replace("Return-Path", "<$sender_addr>");
- return $mgpg->mime_sign_encrypt(
+ if ($command eq 'verification') {
+ return $mgpg->mime_sign_encrypt(
+ entity => $msg,
+ recipients => [$sender_key, $recipient_key],
+ );
+ }
+ return $mgpg->mime_sign(
entity => $msg,
recipients => [$sender_key, $recipient_key],
);