Clarify mail message (for those who are unaware of how
[pgp-tools.git] / caff / caff
index d6aa2a90908b7164877fa911aa4709ba7233ff3e..026f3daa8e1bf86ea265a27615a42fc663ae080b 100755 (executable)
--- a/caff/caff
+++ b/caff/caff
@@ -40,7 +40,7 @@ caff -- CA - Fire and Forget
 
 =over
 
-=item B<caff> [-mMR] [-u I<yourkeyid>] I<keyid> [I<keyid> ..]
+=item B<caff> [-eEmMRS] [-u I<yourkeyid>] I<keyid> [I<keyid> ..]
 
 =back
 
@@ -56,6 +56,15 @@ sigs and sigs done by you.
 
 =over
 
+=item B<-e>, B<--export-old>
+
+Export old signatures. Default is to ask the user for each old signature.
+
+=item B<-E>, B<--no-export-old>
+
+Do not export old signatures. Default is to ask the user for each old
+signature.
+
 =item B<-m>, B<--mail>
 
 Send mail after signing. Default is to ask the user for each uid.
@@ -68,6 +77,10 @@ Do not send mail after signing. Default is to ask the user for each uid.
 
 Do not retrieve the key to be signed from a keyserver.
 
+=item B<-S>, B<--no-sign>
+
+Do not sign the keys.
+
 =item B<-u> I<yourkeyid>, B<--local-user> I<yourkeyid>
 
 Select the key that is used for signing, in case you have more than one key.
@@ -141,6 +154,10 @@ Path to your secret keyring.  Default: B<$HOME/.gnupg/secring.gpg>.
 
 An additional keyid to encrypt messages to. Default: none.
 
+=item B<gpg-sign-args> [string]
+
+Additional arguments to pass to gpg.  Default: none.
+
 =head2 Keyserver settings
 
 =item B<keyserver> [string]
@@ -268,9 +285,13 @@ please find attached the user id{(scalar @uids >= 2 ? 's' : '')}.
     $OUT .= "\t".$uid."\n";
 };} of your key {$key} signed by me.
 
-Note that I did not upload your key to any keyservers. If you want this
-new signature to be available to others, please upload it yourself.
-With GnuPG this can be done using
+Note that I did not upload your key to any keyservers.
+If you have multiple user ids, I sent the signature for each user id
+separately to that user id's associated email address. You can import
+the signatures by running each through `gpg --import`.
+
+If you want this new signature to be available to others, please upload
+it yourself. With GnuPG this can be done using
        gpg --keyserver subkeys.pgp.net --send-key {$key}
 
 If you have any questions, don't hesitate to ask.
@@ -410,8 +431,11 @@ sub readwrite_gpg($$$$$%) {
        return ($stdout, $stderr, $status);
 };
 
-sub ask($$) {
-       my ($question, $default) = @_;
+sub ask($$;$$) {
+       my ($question, $default, $forceyes, $forceno) = @_;
+       return $default if $forceyes and $forceno;
+       return 1 if $forceyes;
+       return 0 if $forceno;
        my $answer;
        while (1) {
                print $question,' ',($default ? '[Y/n]' : '[y/N]'), ' ';
@@ -459,7 +483,7 @@ sub version($) {
 sub usage($$) {
        my ($fd, $exitcode) = @_;
        version($fd);
-       print $fd "Usage: $PROGRAM_NAME [-mMR] [-u <yourkeyid>] <keyid> [<keyid> ...]\n";
+       print $fd "Usage: $PROGRAM_NAME [-eEmMRS] [-u <yourkeyid>] <keyid> [<keyid> ...]\n";
        print $fd "Consult the manual page for more information.\n";
        exit $exitcode;
 };
@@ -657,12 +681,18 @@ if (!GetOptions (
        '-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'              =>  \$params->{'mail'},
        '--mail'          =>  \$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'},
        )) {
        usage(\*STDERR, 1);
 };
@@ -680,7 +710,7 @@ usage(\*STDERR, 1) unless scalar @ARGV >= 1;
 if ($params->{'local-user'}) {
        $USER = $params->{'local-user'};
        $USER =~ s/^0x//i;
-       unless ($USER =~ /^([A-Z0-9]{8}|[A-Z0-9]{16}|[A-Z0-9]{32}|[A-Z0-9]{40})$/i) {
+       unless ($USER =~ /^([A-Z0-9]{8}|[A-Z0-9]{16}|[A-Z0-9]{40})$/i) {
                print STDERR "-u $USER is not a keyid.\n";
                usage(\*STDERR, 1);
        };
@@ -689,7 +719,7 @@ if ($params->{'local-user'}) {
 
 for my $keyid (@ARGV) {
        $keyid =~ s/^0x//i;
-       unless ($keyid =~ /^([A-Z0-9]{8}|[A-Z0-9]{16}|[A-Z0-9]{32}|[A-Z0-9]{40})$/i) {
+       unless ($keyid =~ /^([A-Z0-9]{8}|[A-Z0-9]{16}||[A-Z0-9]{40})$/i) {
                print STDERR "$keyid is not a keyid.\n";
                usage(\*STDERR, 1);
        };
@@ -699,6 +729,7 @@ for my $keyid (@ARGV) {
 $CONFIG{'no-download'} = $params->{'no-download'} if defined $params->{'no-download'};
 $CONFIG{'no-mail'}     = $params->{'no-mail'}     if defined $params->{'no-mail'};
 $CONFIG{'mail'}        = $params->{'mail'}        if defined $params->{'mail'};
+$CONFIG{'no-sign'}     = $params->{'no-sign'}     if defined $params->{'no-sign'};
 
 
 #################
@@ -733,6 +764,8 @@ my @keyids_ok;
 if ($CONFIG{'no-download'}) {
        @keyids_ok = @KEYIDS;
 } else {
+       info ("fetching keys, this will take a while...");
+
        my $gpg = GnuPG::Interface->new();
        $gpg->call( $CONFIG{'gpg'} );
        $gpg->options->hash_init(
@@ -740,9 +773,6 @@ if ($CONFIG{'no-download'}) {
                'extra_args' => '--keyserver='.$CONFIG{'keyserver'} );
        $gpg->options->meta_interactive( 0 );
        my ($inputfd, $stdoutfd, $stderrfd, $statusfd, $handles) = make_gpg_fds();
-       
-       my %local_keyids = map { $_ => 1 } @KEYIDS;
-       info ("fetching keys, this will take a while...");
        my $pid = $gpg->recv_keys(handles => $handles, command_args => [ @KEYIDS ]);
        my ($stdout, $stderr, $status) = readwrite_gpg('', $inputfd, $stdoutfd, $stderrfd, $statusfd);
        waitpid $pid, 0;
@@ -751,21 +781,40 @@ if ($CONFIG{'no-download'}) {
 # [GNUPG:] NODATA 1
 # [GNUPG:] NODATA 1
 # [GNUPG:] IMPORT_OK 0 25FC1614B8F87B52FF2F99B962AF4031C82E0039
+       my %local_keyids = map { $_ => 1 } @KEYIDS;
        for my $line (split /\n/, $status) {
                if ($line =~ /^\[GNUPG:\] IMPORT_OK \d+ ([0-9A-F]{40})/) {
                        my $imported_key = $1;
-                       if (not exists $local_keyids{$imported_key}) {
-                           warn("Imported unexpected key; got: $imported_key.\n");
+                       my $whole_fpr = $imported_key;
+                       my $long_keyid = substr($imported_key, -16);
+                       my $short_keyid = substr($imported_key, -8);
+                       my $speced_key;
+                       for my $spec (($whole_fpr, $long_keyid, $short_keyid)) {
+                               $speced_key = $spec if $local_keyids{$spec};
+                       };
+                       unless ($speced_key) {
+                           notice ("Imported unexpected key; got: $imported_key\n");
                            next;
                        };
-                       info ("Imported $imported_key");
-                       delete $local_keyids{$imported_key};
+                       debug ("Imported $imported_key for $speced_key");
+                       delete $local_keyids{$speced_key};
                        unshift @keyids_ok, $imported_key;
+               } elsif ($line =~ /^\[GNUPG:\] (NODATA|IMPORT_RES|IMPORTED) /) {
+               } else {
+                       notice ("got unknown reply from gpg: $line");
                }
        };
-       notice ("Import failed for: ". (join ' ', keys %local_keyids).".") if scalar %local_keyids;
+       if (scalar %local_keyids) {
+               notice ("Import failed for: ". (join ' ', keys %local_keyids).".");
+               exit 1 unless ask ("Some keys could not be imported - continue anyway?", 0);
+       }
 };
 
+unless (@keyids_ok) {
+       notice ("No keys to sign found");
+       exit 0;
+}
+
 ###########
 # sign keys
 ###########
@@ -779,6 +828,7 @@ unless ($CONFIG{'no-sign'}) {
                push @command, '--secret-keyring', $CONFIG{'secret-keyring'};
                push @command, '--edit', $keyid;
                push @command, 'sign';
+               push @command, split ' ', $CONFIG{'gpg-sign-args'} || "";
                print join(' ', @command),"\n";
                system (@command);
        };
@@ -959,7 +1009,7 @@ for my $keyid (@keyids_ok) {
 
                if ($signed_by_me) {
                        if ($NOW - $signed_by_me > $CONFIG{'export-sig-age'} ) {
-                               my $write = ask("Signature on $this_uid_text is old.  Export?", 0);
+                               my $write = ask("Signature on $this_uid_text is old.  Export?", 0, $params->{'export-old'}, $params->{'no-export-old'});
                                next unless $write;
                        };
                        my $keydir = "$KEYSBASE/$DATE_STRING";
@@ -1000,7 +1050,7 @@ for my $keyid (@keyids_ok) {
                        if (!$uid->{'is_uat'} && ($uid->{'text'} =~ /@/)) {
                                my $address = $uid->{'text'};
                                $address =~ s/.*<(.*)>.*/$1/;
-                               if ($CONFIG{'mail'} or ask("Send mail to '$address' for $uid->{'text'}?", 1)) {
+                               if (ask("Send mail to '$address' for $uid->{'text'}?", 1, $CONFIG{'mail'})) {
                                        my $mail = send_mail($address, $can_encrypt, $longkeyid, $uid, @attached);
 
                                        my $keydir = "$KEYSBASE/$DATE_STRING";