caff: Create the mail files in ~/.caff/keys even if mail is not sent (closes: #590666)
[pgp-tools.git] / caff / caff
index 99710ced34221c131e99cf06ab6a27432db72440..f9bb72d90404f88805d17e13328ec408c3f892fa 100755 (executable)
--- a/caff/caff
+++ b/caff/caff
@@ -90,6 +90,10 @@ configuration file.
 
 Import keys from file. Can be supplied more than once.
 
+=item B<--keys-from-gnupg> I<file>
+
+Try to import keys from your standard GnuPG keyrings.
+
 =back
 
 =head1 FILES
@@ -752,13 +756,13 @@ sub import_key($$) {
 
 
 ######
-# Send an email to $address.  If $can_encrypt is true then the mail
+# Create an email to $address.  If $can_encrypt is true then the mail
 # will be PGP/MIME encrypted to $longkeyid.
 #
 # $longkeyid, $uid, and @attached will be used in the email and the template.
 ######
-#send_mail($address, $can_encrypt, $longkeyid, $uid, @attached);
-sub send_mail($$$@) {
+# create_mail($address, $can_encrypt, $longkeyid, $uid, @attached);
+sub create_mail($$$@) {
        my ($address, $can_encrypt, $key_id, @keys) = @_;
 
        my $template = Text::Template->new(TYPE => 'STRING', SOURCE => $CONFIG{'mail-template'})
@@ -851,9 +855,21 @@ sub send_mail($$$@) {
        $message_entity->head->add("Reply-To", $CONFIG{'reply-to'}) if defined $CONFIG{'reply-to'};
        $message_entity->head->add("Bcc", $CONFIG{'bcc'}) if defined $CONFIG{'bcc'};
        $message_entity->head->add("User-Agent", $USER_AGENT);
-       mywarn("You have set arguments to pass to Mail::Mailer.  Better fix your MTA.  (Also, Mail::Mailer's error reporting is non existant, so it won't tell you when it doesn't work.)") if (scalar @{$CONFIG{'mailer-send'}} > 0);
+       return $message_entity;
+};
+
+######
+# send a mail message (MIME::Entity)
+######
+my $warned_about_broken_mailer_send = 0;
+sub send_message($) {
+       my ($message_entity) = @_;
+
+       if ( (scalar @{$CONFIG{'mailer-send'}} > 0) && !$warned_about_broken_mailer_send) {
+               mywarn("You have set arguments to pass to Mail::Mailer.  Better fix your MTA.  (Also, Mail::Mailer's error reporting is non existant, so it won't tell you when it doesn't work.)");
+               $warned_about_broken_mailer_send = 1;
+       };
        $message_entity->send(@{$CONFIG{'mailer-send'}});
-       $message_entity->stringify();
 };
 
 ######
@@ -973,24 +989,24 @@ sub get_local_user_keys() {
 #         2 if the key could not be imported.
 #
 sub import_key_from_user_gnupghome($$) {
-    my $err;
-    my ($asciikey, $dst_gpghome) = @_;
-
-    trace("Exporting key $asciikey from your normal GnuPGHOME.");
-    my $key = export_key(undef, $asciikey);
-    if (defined $key && $key ne '') {
-        trace("Importing key $asciikey into $GNUPGHOME.");
-        if (import_key($GNUPGHOME, $key)) {
-            $err = 0;
-        } else {
-            warn("Could not import $asciikey into caff's gnupghome.");
-            $err = 2;
-        }
-    } else {
-        $err = 1;
-    }
-
-    return $err;
+       my $err;
+       my ($asciikey, $dst_gpghome) = @_;
+
+       trace("Exporting key $asciikey from your normal GnuPGHOME.");
+       my $key = export_key(undef, $asciikey);
+       if (defined $key && $key ne '') {
+               trace("Importing key $asciikey into $GNUPGHOME.");
+               if (import_key($GNUPGHOME, $key)) {
+                       $err = 0;
+               } else {
+                       warn("Could not import $asciikey into caff's gnupghome.");
+                       $err = 2;
+               }
+       } else {
+               $err = 1;
+       }
+
+       return $err;
 }
 
 ##
@@ -1003,29 +1019,29 @@ sub import_key_from_user_gnupghome($$) {
 #         1 if an error occured.
 #
 sub import_key_files($$) {
-    my $err;
-    my ($keyfile, $dst_gpghome) = @_;
-
-    my $gpg = GnuPG::Interface->new();
-    $gpg->call( $CONFIG{'gpg'} );
-    $gpg->options->hash_init(
-        'homedir' => $dst_gpghome,
-        'extra_args' => [ qw{ --no-auto-check-trustdb --trust-model=always } ] );
-    $gpg->options->meta_interactive( 0 );
-    my ($inputfd, $stdoutfd, $stderrfd, $statusfd, $handles) = make_gpg_fds();
-    my $pid = $gpg->import_keys(handles => $handles, command_args => $keyfile);
-    my ($stdout, $stderr, $status) = readwrite_gpg('', $inputfd, $stdoutfd, $stderrfd, $statusfd);
-    info("Importing keys from file $keyfile");
-    waitpid $pid, 0;
-
-    if ($status !~ /^\[GNUPG:\] IMPORT_OK/m) {
-        warn $stderr;
-        $err = 1;
-    } else {
-        $err = 0;
-    }
-
-    return $err;
+       my $err;
+       my ($keyfile, $dst_gpghome) = @_;
+
+       my $gpg = GnuPG::Interface->new();
+       $gpg->call( $CONFIG{'gpg'} );
+       $gpg->options->hash_init(
+               'homedir' => $dst_gpghome,
+               'extra_args' => [ qw{ --no-auto-check-trustdb --trust-model=always } ] );
+       $gpg->options->meta_interactive( 0 );
+       my ($inputfd, $stdoutfd, $stderrfd, $statusfd, $handles) = make_gpg_fds();
+       my $pid = $gpg->import_keys(handles => $handles, command_args => $keyfile);
+       my ($stdout, $stderr, $status) = readwrite_gpg('', $inputfd, $stdoutfd, $stderrfd, $statusfd);
+       info("Importing keys from file $keyfile");
+       waitpid $pid, 0;
+
+       if ($status !~ /^\[GNUPG:\] IMPORT_OK/m) {
+               warn $stderr;
+               $err = 1;
+       } else {
+               $err = 0;
+       }
+
+       return $err;
 }
 
 ##
@@ -1037,26 +1053,22 @@ sub import_key_files($$) {
 # found.
 #
 sub import_keys_to_sign() {
-    # Check if we can find the gpg key from our normal gnupghome, and then
-    # try to import it into our working gnupghome directory
-    my $imported_keys = 0;
-    foreach my $keyid (@KEYIDS) {
-        if (!import_key_from_user_gnupghome($keyid, $GNUPGHOME)) {
-            info("Key $keyid imported from your normal GnuPGHOME.");
-            $imported_keys++;
-        }
-    }
-
-    # If all of the keys have been successfully imported, there is no need to
-    # go further
-    return 1 if ($imported_keys == scalar (@KEYIDS));
-
-    # Import user specified key files
-    foreach my $keyfile (@{$CONFIG{'key-files'}}) {
-        import_key_files($keyfile, $GNUPGHOME);
-    }
-
-    return 0;
+       # Check if we can find the gpg key from our normal gnupghome, and then
+       # try to import it into our working gnupghome directory
+       if ($CONFIG{'keys-from-gnupg'}) {
+               foreach my $keyid (@KEYIDS) {
+                       if (!import_key_from_user_gnupghome($keyid, $GNUPGHOME)) {
+                               info("Key $keyid imported from your normal GnuPGHOME.");
+                       }
+               }
+       };
+
+       # Import user specified key files
+       foreach my $keyfile (@{$CONFIG{'key-files'}}) {
+               import_key_files($keyfile, $GNUPGHOME);
+       }
+
+       return 0;
 }
 
 ###################
@@ -1064,25 +1076,26 @@ sub import_keys_to_sign() {
 ###################
 Getopt::Long::config('bundling');
 if (!GetOptions (
-       '-h'              =>  \$params->{'help'},
-       '--help'          =>  \$params->{'help'},
-       '--version'       =>  \$params->{'version'},
-       '-V'              =>  \$params->{'version'},
-       '-u=s'            =>  \$params->{'local-user'},
-       '--local-user=s'  =>  \$params->{'local-user'},
-       '-e'              =>  \$params->{'export-old'},
-       '--export-old'    =>  \$params->{'export-old'},
-       '-E'              =>  \$params->{'no-export-old'},
-       '--no-export-old' =>  \$params->{'no-export-old'},
+       '-h'                =>  \$params->{'help'},
+       '--help'            =>  \$params->{'help'},
+       '--version'         =>  \$params->{'version'},
+       '-V'                =>  \$params->{'version'},
+       '-u=s'              =>  \$params->{'local-user'},
+       '--local-user=s'    =>  \$params->{'local-user'},
+       '-e'                =>  \$params->{'export-old'},
+       '--export-old'      =>  \$params->{'export-old'},
+       '-E'                =>  \$params->{'no-export-old'},
+       '--no-export-old'   =>  \$params->{'no-export-old'},
        '-m:s'              =>  \$params->{'mail'},
        '--mail:s'          =>  \$params->{'mail'},
-       '-M'              =>  \$params->{'no-mail'},
-       '--no-mail'       =>  \$params->{'no-mail'},
-       '-R'              =>  \$params->{'no-download'},
-       '--no-download'   =>  \$params->{'no-download'},
-       '-S'              =>  \$params->{'no-sign'},
-       '--no-sign'       =>  \$params->{'no-sign'},
-       '--key-file=s@'   =>  \$params->{'key-files'},
+       '-M'                =>  \$params->{'no-mail'},
+       '--no-mail'         =>  \$params->{'no-mail'},
+       '-R'                =>  \$params->{'no-download'},
+       '--no-download'     =>  \$params->{'no-download'},
+       '-S'                =>  \$params->{'no-sign'},
+       '--no-sign'         =>  \$params->{'no-sign'},
+       '--key-file=s@'     =>  \$params->{'key-files'},
+       '--keys-from-gnupg' =>  \$params->{'keys-from-gnupg'},
        )) {
        usage(\*STDERR, 1);
 };
@@ -1095,13 +1108,9 @@ if ($params->{'version'}) {
 };
 usage(\*STDERR, 1) unless scalar @ARGV >= 1;
 
-$CONFIG{'local-user'}  = $params->{'local-user'}  if defined $params->{'local-user'};
-$CONFIG{'no-download'} = $params->{'no-download'} if defined $params->{'no-download'};
-$CONFIG{'no-sign'}     = $params->{'no-sign'}     if defined $params->{'no-sign'};
-
-$CONFIG{'no-mail'}     = $params->{'no-mail'}     if defined $params->{'no-mail'};
-$CONFIG{'mail'}        = $params->{'mail'}        if defined $params->{'mail'};
-
+for my $hashkey (qw{local-user no-download no-sign no-mail mail keys-from-gnupg}) {
+       $CONFIG{$hashkey} = $params->{$hashkey}  if defined $params->{$hashkey};
+};
 # If old 'no-mail' parameter, or if the 'mail' parameter is set to 'no'
 if ( defined $CONFIG{'no-mail'} || 
      ( defined $CONFIG{'mail'} && $CONFIG{'mail'}  eq 'no' ) ) {
@@ -1131,10 +1140,10 @@ for my $keyid (map { split /\n/ } @ARGV) { # caff "`cat txt`" is a single argume
 # import own keys
 #################
 for my $keyid (@{$CONFIG{'keyid'}}) {
-    info("Importing key $keyid from your normal GnuPGHome.");
-    if (import_key_from_user_gnupghome($keyid, $GNUPGHOME)) {
-        mywarn("Key $keyid not found.");
-    }
+       info("Importing key $keyid from your normal GnuPGHome.");
+       if (import_key_from_user_gnupghome($keyid, $GNUPGHOME)) {
+               mywarn("Key $keyid not found.");
+       }
 }
 
 &import_keys_to_sign();
@@ -1454,17 +1463,18 @@ for my $keyid (@keyids_ok) {
                        if (!$uid->{'is_uat'} && ($uid->{'text'} =~ /@/)) {
                                my $address = $uid->{'text'};
                                $address =~ s/.*<(.*)>.*/$1/;
-                               if (ask("Mail signature for $uid->{'text'} to '$address'?", $CONFIG{'mail'} ne 'ask-no', $CONFIG{'mail'} eq 'yes')) {
-                                       my $mail = send_mail($address, $can_encrypt, $longkeyid, $uid, @attached);
-                                       if (defined $mail) {
-                                               my $keydir = "$KEYSBASE/$DATE_STRING";
-                                               my $mailfile = "$keydir/$longkeyid.mail.".$uid->{'serial'}.".".sanitize_uid($uid->{'text'});
-                                               open (KEY, ">$mailfile") or die ("Cannot open $mailfile: $!\n");
-                                               print KEY $mail;
-                                               close KEY;
-                                       } else {
-                                               warn "Generating mail failed.\n";
-                                       };
+                               my $mail = create_mail($address, $can_encrypt, $longkeyid, $uid, @attached);
+                               if (defined $mail) {
+                                       my $should_send_mail = ask("Mail signature for $uid->{'text'} to '$address'?", $CONFIG{'mail'} ne 'ask-no', $CONFIG{'mail'} eq 'yes');
+                                       send_message($mail) if $should_send_mail;
+
+                                       my $keydir = "$KEYSBASE/$DATE_STRING";
+                                       my $mailfile = "$keydir/$longkeyid.mail.".($should_send_mail ? '' : 'unsent.').$uid->{'serial'}.".".sanitize_uid($uid->{'text'});
+                                       open (MAILFILE, ">$mailfile") or die ("Cannot open $mailfile: $!\n");
+                                       print MAILFILE $mail->stringify();
+                                       close MAILFILE;
+                               } else {
+                                       warn "Generating mail failed.\n";
                                };
                        };
                };