X-Git-Url: https://git.sthu.org/?a=blobdiff_plain;f=caff%2Fcaff;h=ae922cd96d2f2e7020ba7f1bfe69f0740a8d0d0c;hb=ffeb72b98d41f9928a59792366e88146e4d8541a;hp=2fc095df8e093460da63584fc4a7bbccdd6179f1;hpb=88e91c7dab59944a9463696712fbfee3602bf7fa;p=pgp-tools.git diff --git a/caff/caff b/caff/caff index 2fc095d..ae922cd 100755 --- a/caff/caff +++ b/caff/caff @@ -3,7 +3,7 @@ # caff -- CA - Fire and Forget # $Id$ # -# Copyright (c) 2004, 2005 Peter Palfrader +# Copyright (c) 2004, 2005, 2006 Peter Palfrader # Copyright (c) 2005, 2006 Christoph Berg # # All rights reserved. @@ -85,6 +85,7 @@ Do not sign the keys. =item B<-u> I, B<--local-user> I Select the key that is used for signing, in case you have more than one key. +To sign with multiple keys at once, separate multiple keyids by comma. =item B<--key-file> I @@ -104,7 +105,7 @@ Import keys from file. Can be supplied more than once. =item $HOME/.caff/gnupghome/gpg.conf - gpg configuration -useful options include use-agent, default-cert-level, etc. +useful options include use-agent, keyserver-options, default-cert-level, etc. =back @@ -115,9 +116,9 @@ The file is generated when it does not exist. Example: - $CONFIG{owner} = q{Peter Palfrader}; - $CONFIG{email} = q{peter@palfrader.org}; - $CONFIG{keyid} = [ qw{DE7AAF6E94C09C7F 62AF4031C82E0039} ]; + $CONFIG{'owner'} = q{Peter Palfrader}; + $CONFIG{'email'} = q{peter@palfrader.org}; + $CONFIG{'keyid'} = [ qw{DE7AAF6E94C09C7F 62AF4031C82E0039} ]; =head2 Required basic settings @@ -164,13 +165,14 @@ is set to. Path to your secret keyring. Default: B<$HOME/.gnupg/secring.gpg>. -=item B [keyid] +=item B [keyid, or list of keyids] -An additional keyid to encrypt messages to. Default: none. +Additional keyids to encrypt messages to. Default: none. =item B [string] -Additional arguments to pass to gpg. Default: none. +Additional commands to pass to gpg after the "sign" command. +Default: none. =head2 Keyserver settings @@ -203,9 +205,10 @@ This is useful for offline signing. Default: B<0>. Don't export UIDs by default, on which your latest signature is older than this age. Default: B<24*60*60> (i.e. one day). -=item B [string] +=item B [keyid, or list of keyids] Select the key that is used for signing, in case you have more than one key. +With multiple keyids, sign with each key in turn. =head2 Mail settings @@ -216,7 +219,7 @@ Do not prompt for sending mail, just do it. Default: B<0>. =item B [boolean] Do not prompt for sending mail. The messages are still written to -$CONFIG{caffhome}/keys/. Default: B<0>. +$CONFIG{'caffhome'}/keys/. Default: B<0>. =item B [string] @@ -254,11 +257,11 @@ Default: none. Parameters to pass to Mail::Mailer. This could for example be - $CONFIG{mailer-send} = [ 'smtp', Server => 'mail.server', Auth => ['user', 'pass'] ] + $CONFIG{'mailer-send'} = [ 'smtp', Server => 'mail.server', Auth => ['user', 'pass'] ]; to use the perl SMTP client or - $CONFIG{mailer-send} = [ 'sendmail', '-o8' ] + $CONFIG{'mailer-send'} = [ 'sendmail', '-o8' ]; to pass arguments to the sendmail program. For more information run C<< perldoc Mail::Mailer >>. @@ -295,6 +298,7 @@ use File::Path; use File::Temp qw{tempdir}; use Text::Template; use MIME::Entity; +use Encode; use Fcntl; use IO::Select; use Getopt::Long; @@ -380,26 +384,39 @@ sub generate_config() { ($Cgecos,$Cemail,$Ckeys) = ('#','#','#'); }; - return < # -# if you have a v4 key, it will simply be the last 16 digits of +# If you have a v4 key, it will simply be the last 16 digits of # your fingerprint. # # Example: -# \$CONFIG{'keyid'} = [ qw{FEDCBA9876543210} ]; +# \$CONFIG{'keyid'} = [ qw{FEDCBA9876543210} ]; # or, if you have more than one key: -# \$CONFIG{'keyid'} = [ qw{0123456789ABCDEF 89ABCDEF76543210} ]; +# \$CONFIG{'keyid'} = [ qw{0123456789ABCDEF 89ABCDEF76543210} ]; +$Ckeys\$CONFIG{'keyid'} = [ qw{@keys} ]; + +# Select this/these keys to sign with +#\$CONFIG{'local-user'} = [ qw{@keys} ]; -$Ckeys\$CONFIG{'keyid'} = [ qw{@keys} ]; +# Additionally encrypt messages for these keyids +#\$CONFIG{'also-encrypt-to'} = [ qw{@keys} ]; + +# Mail template to use for the encrypted part +#\$CONFIG{'mail-template'} = << 'EOM'; EOT + + $template .= "#$_" foreach ; + $template .= "#EOM\n"; + return $template; }; sub check_executable($$) { @@ -450,34 +467,16 @@ sub load_config() { check_executable("gpg", $CONFIG{'gpg'}); check_executable("gpg-sign", $CONFIG{'gpg-sign'}); check_executable("gpg-delsig", $CONFIG{'gpg-delsig'}); - $CONFIG{'secret-keyring'} = $ENV{'HOME'}.'/.gnupg/secring.gpg' unless defined $CONFIG{'secret-keyring'}; + $CONFIG{'secret-keyring'} = ($ENV{'GNUPGHOME'} || "$ENV{'HOME'}/.gnupg") . '/secring.gpg' + unless defined $CONFIG{'secret-keyring'}; $CONFIG{'no-download'} = 0 unless defined $CONFIG{'no-download'}; $CONFIG{'no-sign'} = 0 unless defined $CONFIG{'no-sign'}; $CONFIG{'key-files'} = () unless defined $CONFIG{'key-files'}; $CONFIG{'mailer-send'} = [] unless defined $CONFIG{'mailer-send'}; die ("$PROGRAM_NAME: mailer-send is not an array ref in $config.\n") unless (ref $CONFIG{'mailer-send'} eq 'ARRAY'); - $CONFIG{'mail-template'} = <<'EOM' unless defined $CONFIG{'mail-template'}; -Hi, - -please find attached the user id{(scalar @uids >= 2 ? 's' : '')}. -{foreach $uid (@uids) { - $OUT .= "\t".$uid."\n"; -};} of your key {$key} signed by me. - -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. - -Regards, -{$owner} -EOM + unless (defined $CONFIG{'mail-template'}) { + $CONFIG{'mail-template'} .= $_ foreach ; + } }; sub make_gpg_fds() { @@ -766,7 +765,14 @@ sub send_mail($$$@) { $gpg->options->meta_interactive( 0 ); my ($inputfd, $stdoutfd, $stderrfd, $statusfd, $handles) = make_gpg_fds(); $gpg->options->push_recipients( $key_id ); - $gpg->options->push_recipients( $CONFIG{'also-encrypt-to'} ) if defined $CONFIG{'also-encrypt-to'}; + if (defined $CONFIG{'also-encrypt-to'}) { + if (ref($CONFIG{'also-encrypt-to'})) { + $gpg->options->push_recipients($_) + foreach @{$CONFIG{'also-encrypt-to'}}; + } else { + $gpg->options->push_recipients($CONFIG{'also-encrypt-to'}); + } + } my $pid = $gpg->encrypt(handles => $handles); my ($stdout, $stderr, $status) = readwrite_gpg($message, $inputfd, $stdoutfd, $stderrfd, $statusfd); waitpid $pid, 0; @@ -796,7 +802,7 @@ sub send_mail($$$@) { $message_entity->head->add("Subject", "Your signed PGP key 0x$key_id"); $message_entity->head->add("To", $address); - $message_entity->head->add("From", '"'.$CONFIG{'owner'}.'" <'.$CONFIG{'email'}.'>'); + $message_entity->head->add("From", '"'.Encode::encode('MIME-Q', $CONFIG{'owner'}).'" <'.$CONFIG{'email'}.'>'); $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); @@ -857,8 +863,9 @@ sub delete_signatures($$$$$$) { }; - -my $USER; +################### +# argument handling +################### my @KEYIDS; my $params; @@ -902,23 +909,14 @@ $CONFIG{'mail'} = $params->{'mail'} if defined $params->{'mail'}; $CONFIG{'no-sign'} = $params->{'no-sign'} if defined $params->{'no-sign'}; push @{$CONFIG{'key-files'}}, @{$params->{'key-files'}} if defined $params->{'key-files'}; -if ($CONFIG{'local-user'}) { - $USER = $CONFIG{'local-user'}; - $USER =~ s/^0x//i; - unless ($USER =~ /^([A-F0-9]{8}|[A-F0-9]{16}|[A-F0-9]{40})$/i) { - print STDERR "Local-user $USER is not a keyid.\n"; - usage(\*STDERR, 1); - }; - $USER = uc($USER); -}; - -for my $keyid (@ARGV) { +for my $keyid (map { split /\n/ } @ARGV) { # caff "`cat txt`" is a single argument $keyid =~ s/^0x//i; - unless ($keyid =~ /^([A-F0-9]{8}|[A-F0-9]{16}||[A-F0-9]{40})$/i) { - if ($keyid =~ /^[A-F0-9]{32}$/) { - info("Ignoring v3 fingerprint $keyid. v3 keys are obsolete."); - next; - }; + $keyid =~ s/ //g; # gpg --fingerprint includes spaces + if ($keyid =~ /^[A-F0-9]{32}$/i) { + info("Ignoring v3 fingerprint $keyid. v3 keys are obsolete."); + next; + }; + if ($keyid !~ /^([A-F0-9]{8}|[A-F0-9]{16}|[A-F0-9]{40})$/i) { print STDERR "$keyid is not a keyid.\n"; usage(\*STDERR, 1); }; @@ -1031,7 +1029,7 @@ if ($CONFIG{'no-download'}) { if (scalar %local_keyids) { notice ("Import failed for: ". (join ' ', keys %local_keyids)."." . ($had_v3_keys ? " (Or maybe it's one of those ugly v3 keys?)" : "")); exit 1 unless ask ("Some keys could not be imported - continue anyway?", 0); - if (scalar %local_keyids == 1) { + if (scalar keys %local_keyids == 1) { mywarn("Assuming ". (join ' ', keys %local_keyids)." is a fine keyid."); } else { mywarn("Assuming ". (join ' ', keys %local_keyids)." are fine keyids."); @@ -1053,20 +1051,41 @@ if ($CONFIG{'ask-sign'} && ! $CONFIG{'no-sign'}) { } unless ($CONFIG{'no-sign'}) { + my @local_user; + if ($CONFIG{'local-user'}) { + if (ref($CONFIG{'local-user'})) { + @local_user = @{$CONFIG{'local-user'}}; + } else { + @local_user = split /\s*,\s*/, $CONFIG{'local-user'}; + }; + foreach (@local_user) { + s/^0x//i; + unless (/^([A-F0-9]{8}|[A-F0-9]{16}|[A-F0-9]{40})$/i) { + print STDERR "Local-user $_ is not a keyid.\n"; + usage(\*STDERR, 1); + }; + $_ = uc($_); + }; + } else { + @local_user = (undef); + }; + info("Sign the following keys according to your policy, then exit gpg with 'save' after signing each key"); for my $keyid (@keyids_ok) { - my @command; - push @command, $CONFIG{'gpg-sign'}; - push @command, '--local-user', $USER if (defined $USER); - push @command, "--homedir=$GNUPGHOME"; - push @command, '--secret-keyring', $CONFIG{'secret-keyring'}; - push @command, '--no-auto-check-trustdb'; - push @command, '--trust-model=always'; - push @command, '--edit', $keyid; - push @command, 'sign'; - push @command, split ' ', $CONFIG{'gpg-sign-args'} || ""; - print join(' ', @command),"\n"; - system (@command); + foreach my $local_user (@local_user) { + my @command; + push @command, $CONFIG{'gpg-sign'}; + push @command, '--local-user', $local_user if (defined $local_user); + push @command, "--homedir=$GNUPGHOME"; + push @command, '--secret-keyring', $CONFIG{'secret-keyring'}; + push @command, '--no-auto-check-trustdb'; + push @command, '--trust-model=always'; + push @command, '--edit', $keyid; + push @command, 'sign'; + push @command, split ' ', $CONFIG{'gpg-sign-args'} || ""; + print join(' ', @command),"\n"; + system (@command); + }; }; }; @@ -1301,3 +1320,29 @@ for my $keyid (@keyids_ok) { }; }; + +########################### +# the default mail template +########################### + +__DATA__ +Hi, + +please find attached the user id{(scalar @uids >= 2 ? 's' : '')} +{foreach $uid (@uids) { + $OUT .= "\t".$uid."\n"; +};}of your key {$key} signed by me. + +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`. + +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 + gpg --keyserver subkeys.pgp.net --send-key {$key} + +If you have any questions, don't hesitate to ask. + +Regards, +{$owner}