caff: brace-style fixes
[pgp-tools.git] / caff / caff
index 436e3343bd5fd3c06e9cf7855cfa324d8b68eed1..f32d5b5da615e71526f8c3cc2e32045f969490db 100755 (executable)
--- a/caff/caff
+++ b/caff/caff
@@ -82,7 +82,9 @@ 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.
-To sign with multiple keys at once, separate multiple keyids by comma.
+To sign with multiple keys at once, separate multiple keyids by comma. This
+option requires the key(s) to be defined through the keyid variable in the
+configuration file.
 
 =item B<--key-file> I<file>
 
@@ -187,7 +189,7 @@ Default: none.
 
 =item B<keyserver> [string]
 
-Keyserver to download keys from.  Default: B<subkeys.pgp.net>.
+Keyserver to download keys from.  Default: B<pool.sks-keyservers.net>.
 
 =item B<no-download> [boolean]
 
@@ -325,7 +327,21 @@ my $REVISION = '$Rev$';
 my ($REVISION_NUMER) = $REVISION =~ /(\d+)/;
 my $VERSION = "0.0.0.$REVISION_NUMER";
 
+# Global variables
+my @KEYIDS;
+my $params;
 
+##
+# Display an error message on STDERR and then exit.
+#
+# @param $exitcode exit code status to use to end the program
+# @param $line     error message to display on STDERR
+#
+sub myerror($$) {
+       my ($exitcode, $line) = @_;
+       print "[ERROR] $line\n";        
+       exit $exitcode;
+};
 
 sub mywarn($) {
        my ($line) = @_;
@@ -476,7 +492,7 @@ sub load_config() {
        };
        @{$CONFIG{'keyid'}} = map { uc } @{$CONFIG{'keyid'}};
        $CONFIG{'export-sig-age'}= 24*60*60 unless defined $CONFIG{'export-sig-age'};
-       $CONFIG{'keyserver'} = 'subkeys.pgp.net' unless defined $CONFIG{'keyserver'};
+       $CONFIG{'keyserver'} = 'pool.sks-keyservers.net' unless defined $CONFIG{'keyserver'};
        $CONFIG{'gpg'} = 'gpg' unless defined $CONFIG{'gpg'};
        $CONFIG{'gpg-sign'} = $CONFIG{'gpg'} unless defined $CONFIG{'gpg-sign'};
        $CONFIG{'gpg-delsig'} = $CONFIG{'gpg'} unless defined $CONFIG{'gpg-delsig'};
@@ -830,6 +846,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", '"'.Encode::encode('MIME-Q', $CONFIG{'owner'}).'" <'.$CONFIG{'email'}.'>');
+       $message_entity->head->add("Sender", '"'.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);
@@ -889,13 +906,161 @@ sub delete_signatures($$$$$$) {
        return $signed_by_me;
 };
 
+##
+# Check the local user keys.
+#
+# This function checks if the keyids defined through the --local-user
+# command line option or set in ~/.caffrc are valid and known to be one of the
+# keyids listed in ~/.caffrc.
+#
+# @return an array containing the local user keys\n
+#         (undef) if no valid key has been found
+#
+sub get_local_user_keys() {
+       my @local_user = ();
+       my @key_list;
+       
+       # No user-defined key id has been specified by the user, no need for
+       # further checks
+       if (!$CONFIG{'local-user'}) {
+               return (undef);
+       }       
+       
+       # Parse the list of keys
+       if (ref($CONFIG{'local-user'})) {
+               @key_list = @{$CONFIG{'local-user'}};
+       }
+       else {
+               @key_list = split /\s*,\s*/, $CONFIG{'local-user'};
+       }
+
+       # Check every key defined by the user...
+       for my $user_key (@key_list) {
+               
+               $user_key =~ s/^0x//i;
+               $user_key = uc($user_key);
+               
+               unless ($user_key =~ m/^([A-F0-9]{8}|[A-F0-9]{16}|[A-F0-9]{40})$/) {
+                       mywarn "Local-user $user_key is not a valid keyid.";
+                       next;
+               }
+               
+               unless (grep (/$user_key$/, @{$CONFIG{'keyid'}})) {
+                       mywarn "Local-user $user_key is not defined as one of your keyid in ~/.caffrc (it will not be used).";
+                       next;
+               }
+               
+               push (@local_user, $user_key);
+       }
+
+       # If no local-user key are valid, there is no need to go further
+       unless (defined $local_user[0]) {
+               myerror (1, "None of the local-user keys seem to be known as a keyid listed in ~/.caffrc.");
+       }
+
+       return @local_user;
+}
+
+##
+# Import a key from the user gnupghome into a specified gnupghome.
+#
+# @param asciikey      ascii format of the gpg key to import
+# @param dst_gnupghome gnupghome directory where to import the key
+#
+# @return 0 if successful\n
+#         1 if the key could not be exported.\n
+#         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;
+}
+
+##
+# Import a key file into a specified gnupghome.
+#
+# @param keyfile       file containing the keys to import
+# @param dst_gnupghome gnupghome directory where to import the key
+#
+# @return 0 if successful\n
+#         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;
+}
+
+##
+# Import keys to be signed into caff gnupghome directory.
+#
+# This function imports the keys the user wants to sign into the caff gnupghome
+# directory. We looks for the keys in the the user gnupghome directory first,
+# and in the key files specified by the user if not all of the keys have been
+# 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;
+}
 
 ###################
 # argument handling
 ###################
-my @KEYIDS;
-my $params;
-
 Getopt::Long::config('bundling');
 if (!GetOptions (
        '-h'              =>  \$params->{'help'},
@@ -965,37 +1130,14 @@ 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.");
-               my $key = export_key(undef, $keyid);
-               if (!defined $key || $key eq '') {
-                       warn ("Did not get key $keyid from your normal GnuPGHome\n");
-                       next;
-               };
-               my $result = import_key($GNUPGHOME, $key);
-               unless ($result) {
-                       warn ("Could not import $keyid into caff's gnupghome.\n");
-                       next;
-               };
-}
-
-########################
-# import keys from files
-########################
-foreach my $keyfile (@{$CONFIG{'key-files'}}) {
-    my $gpg = GnuPG::Interface->new();
-    $gpg->call( $CONFIG{'gpg'} );
-    $gpg->options->hash_init('homedir' => $GNUPGHOME);
-    $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 $keyfile");
-    waitpid $pid, 0;
-    if ($status !~ /^\[GNUPG:\] IMPORT_OK/m) {
-       warn $stderr;
+    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();
+
 #############################
 # receive keys from keyserver
 #############################
@@ -1073,24 +1215,7 @@ 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);
-       };
+       my @local_user = &get_local_user_keys();
 
        info("Sign the following keys according to your policy, then exit gpg with 'save' after signing each key");
        for my $keyid (@keyids_ok) {
@@ -1365,7 +1490,7 @@ 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}
+       gpg --keyserver pool.sks-keyservers.net --send-key {$key}
 
 If you have any questions, don't hesitate to ask.