# $Id$
#
# Copyright (c) 2004, 2005 Peter Palfrader <peter@palfrader.org>
+# Copyright (c) 2005 Christoph Berg <cb@df7cb.de>
#
# All rights reserved.
#
$CONFIG{email} = q{peter@palfrader.org};
$CONFIG{keyid} = [ qw{DE7AAF6E94C09C7F 62AF4031C82E0039} ];
-=head2 Valid keys
+=head2 Required basic settings
=over
-=item B<caffhome> [string]
-
-Base directory for the files caff stores. Default: B<$HOME/.caff/>.
-
=item B<owner> [string]
Your name. B<REQUIRED>.
in the pruning step. If you select a key using B<-u> it has to be in
this list. B<REQUIRED>.
-=item B<export-sig-age> [seconds]
+=head2 General settings
-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<caffhome> [string]
-=item B<keyserver> [string]
+Base directory for the files caff stores. Default: B<$HOME/.caff/>.
-Keyserver to download keys from. Default: B<subkeys.pgp.net>.
+=head2 GnuPG settings
=item B<gpg> [string]
An additional keyid to encrypt messages to. Default: none.
+=head2 Keyserver settings
+
+=item B<keyserver> [string]
+
+Keyserver to download keys from. Default: B<subkeys.pgp.net>.
+
=item B<no-download> [boolean]
If true, then skip the step of fetching keys from the keyserver.
Default: B<0>.
+=head2 Signing settings
+
=item B<no-sign> [boolean]
If true, then skip the signing step. Default: B<0>.
+=item B<export-sig-age> [seconds]
+
+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).
+
+=head2 Mail settings
+
+=item B<mail> [boolean]
+
+Do not prompt for sending mail, just do it. Default: B<0>.
+
+=item B<no-mail> [boolean]
+
+Do not prompt for sending mail. The messages are still written to
+$CONFIG{caffhome}/keys/. Default: B<0>.
+
=item B<mail-template> [string]
-Email template which is used as the body text for the email sent out.
+Email template which is used as the body text for the email sent out
instead of the default text if specified. The following perl variables
can be used in the template:
=back
+=item B<bcc> [string]
+
+Address to send blind carbon copies to when sending mail.
+Default: none.
+
=back
-=head1 AUTHOR
+=head1 AUTHORS
+
+=over
+
+=item Peter Palfrader <peter@palfrader.org>
+
+=item Christoph Berg <cb@df7cb.de>
-Peter Palfrader <peter@palfrader.org>
+=back
=head1 WEBSITE
my $KEYEDIT_DELSUBKEY_PROMPT = '^\[GNUPG:\] GET_BOOL keyedit.remove.subkey';
load_config;
-my $USER_AGENT = "caff $VERSION - (c) 2004, 2005 Peter Palfrader";
+my $USER_AGENT = "caff $VERSION - (c) 2004, 2005 Peter Palfrader et al.";
my $KEYSBASE = $CONFIG{'caffhome'}.'/keys';
my $GNUPGHOME = $CONFIG{'caffhome'}.'/gnupghome';
sub version($) {
my ($fd) = @_;
- print $fd "caff $VERSION - (c) 2004, 2005 Peter Palfrader\n";
+ print $fd "caff $VERSION - (c) 2004, 2005 Peter Palfrader et al.\n";
};
sub usage($$) {
$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("Bcc", $CONFIG{'bcc'}) if defined $CONFIG{'bcc'};
$message_entity->head->add("User-Agent", $USER_AGENT);
$message_entity->send();
$message_entity->stringify();
if ($params->{'local-user'}) {
$USER = $params->{'local-user'};
$USER =~ s/^0x//i;
- unless ($USER =~ /^[A-Za-z0-9]{8,8}([A-Za-z0-9]{8})?$/) {
+ unless ($USER =~ /^([A-Z0-9]{8}|[A-Z0-9]{16}|[A-Z0-9]{32}|[A-Z0-9]{40})$/i) {
print STDERR "-u $USER is not a keyid.\n";
usage(\*STDERR, 1);
};
for my $keyid (@ARGV) {
$keyid =~ s/^0x//i;
- unless ($keyid =~ /^[A-Za-z0-9]{8}([A-Za-z0-9]{8}|[A-Za-z0-9]{32})?$/) {
+ unless ($keyid =~ /^([A-Z0-9]{8}|[A-Z0-9]{16}|[A-Z0-9]{32}|[A-Z0-9]{40})$/i) {
print STDERR "$keyid is not a keyid.\n";
usage(\*STDERR, 1);
};
# receive keys from keyserver
#############################
my @keyids_ok;
-my @keyids_failed;
if ($CONFIG{'no-download'}) {
@keyids_ok = @KEYIDS;
} else {
$gpg->options->meta_interactive( 0 );
my ($inputfd, $stdoutfd, $stderrfd, $statusfd, $handles) = make_gpg_fds();
- my @local_keyids = @KEYIDS;
- for my $keyid (@local_keyids) {
- info ("fetching $keyid...");
- my $pid = $gpg->recv_keys(handles => $handles, command_args => [ $keyid ]);
- my ($stdout, $stderr, $status) = readwrite_gpg('', $inputfd, $stdoutfd, $stderrfd, $statusfd);
- waitpid $pid, 0;
+ 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;
# [GNUPG:] IMPORT_OK 0 5B00C96D5D54AEE1206BAF84DE7AAF6E94C09C7F
# [GNUPG:] NODATA 1
# [GNUPG:] NODATA 1
# [GNUPG:] IMPORT_OK 0 25FC1614B8F87B52FF2F99B962AF4031C82E0039
- my $handled = 0;
- for my $line (split /\n/, $status) {
- if ($line =~ /^\[GNUPG:\] IMPORT_OK \d+ ([0-9A-F]{40})/) {
- my $imported_key = $1;
- if ($keyid ne $imported_key &&
- $keyid ne substr($imported_key, -16) &&
- $keyid ne substr($imported_key, -8)) {
- warn("Imported unexpected key. expected: $keyid; got: $imported_key.\n");
- next;
- };
- push @keyids_ok, $keyid;
- shift @KEYIDS;
- $handled = 1;
- last;
- } elsif ($line =~ /^\[GNUPG:\] NODATA/) {
- push @keyids_failed, $keyid;
- shift @KEYIDS;
- $handled = 1;
- last;
+ 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");
+ next;
};
- };
- unless ($handled) {
- notice ("Huh, what's up with $keyid?");
- push @keyids_failed, $keyid;
- shift @KEYIDS;
- };
+ info ("Imported $imported_key");
+ delete $local_keyids{$imported_key};
+ unshift @keyids_ok, $imported_key;
+ }
};
- die ("Still keys in \@KEYIDS. This should not happen.") if scalar @KEYIDS;
- notice ("Import failed for: ". (join ' ', @keyids_failed).".") if scalar @keyids_failed;
+ notice ("Import failed for: ". (join ' ', keys %local_keyids).".") if scalar %local_keyids;
};
###########