/[pgp-tools]/trunk/caff/caff
ViewVC logotype

Diff of /trunk/caff/caff

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 7 by weasel, Tue Jun 29 12:32:29 2004 UTC revision 79 by myon-guest, Sun Jun 26 23:10:19 2005 UTC
# Line 1  Line 1 
1  #!/usr/bin/perl -w  #!/usr/bin/perl -w
2    
3  # caff  --  CA - fire and forget  # caff  --  CA - Fire and Forget
4  # $Id$  # $Id$
5  #  #
6  # Copyright (c) 2004 Peter Palfrader <peter@palfrader.org>  # Copyright (c) 2004, 2005 Peter Palfrader <peter@palfrader.org>
7  #  #
8  # All rights reserved.  # All rights reserved.
9  #  #
# Line 29  Line 29 
29  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31    
32    =pod
33    
34    =head1 NAME
35    
36    caff -- CA - Fire and Forget
37    
38    =head1 SYNOPSIS
39    
40    =over
41    
42    =item B<caff> [-mMR] [-u I<yourkeyid>] I<keyid> [I<keyid> ..]
43    
44    =back
45    
46    =head1 DESCRIPTION
47    
48    CA Fire and Forget is a script that helps you in keysigning.  It takes a list
49    of keyids on the command line, fetches them from a keyserver and calls GnuPG so
50    that you can sign it.  It then mails each key to all its email addresses - only
51    including the one UID that we send to in each mail, pruned from all but self
52    sigs and sigs done by you.
53    
54    =head1 OPTIONS
55    
56    =over
57    
58    =item B<-m> B<-M>
59    
60    Send/do not send mail after signing. Default is to ask the user for each uid.
61    
62    =item B<-R>
63    
64    Do not retrieve the key to be signed from a keyserver.
65    
66    =item B<-u> I<yourkeyid>
67    
68    Select the key that is used for signing, in case you have more than one key.
69    
70    =back
71    
72    =head1 FILES
73    
74    =over
75    
76    =item $HOME/.caffrc  -  configuration file
77    
78    =back
79    
80    =head1 CONFIGURATION FILE OPTIONS
81    
82    The configuration file is a perl script that sets values in the hash B<%CONFIG>.
83    
84    Example:
85    
86            $CONFIG{owner} = q{Peter Palfrader};
87            $CONFIG{email} = q{peter@palfrader.org};
88            $CONFIG{keyid} = [ qw{DE7AAF6E94C09C7F 62AF4031C82E0039} ];
89    
90    =head2 Valid keys
91    
92    =over
93    
94    =item B<caffhome> [string]
95    
96    Base directory for the files caff stores.  Default: B<$HOME/.caff/>.
97    
98    =item B<owner> [string]
99    
100    Your name.  B<REQUIRED>.
101    
102    =item B<email> [string]
103    
104    Your email address, used in From: lines.  B<REQUIRED>.
105    
106    =item B<keyid> [list of keyids]
107    
108    A list of your keys.  This is used to determine which signatures to keep
109    in the pruning step.  If you select a key using B<-u> it has to be in
110    this list.  B<REQUIRED>.
111    
112    =item B<export-sig-age> [seconds]
113    
114    Don't export UIDs by default, on which your latest signature is older
115    than this age.  Default: B<24*60*60> (i.e. one day).
116    
117    =item B<keyserver> [string]
118    
119    Keyserver to download keys from.  Default: B<subkeys.pgp.net>.
120    
121    =item B<gpg> [string]
122    
123    Path to the GnuPG binary.  Default: B<gpg>.
124    
125    =item B<gpg-sign> [string]
126    
127    Path to the GnuPG binary which is used to sign keys.  Default: what
128    B<gpg> is set to.
129    
130    =item B<gpg-delsig> [string]
131    
132    Path to the GnuPG binary which is used to split off signatures.  This was
133    needed while the upstream GnuPG was not fixed.  Default: what B<gpg>
134    is set to.
135    
136    =item B<secret-keyring> [string]
137    
138    Path to your secret keyring.  Default: B<$HOME/.gnupg/secring.gpg>.
139    
140    =item B<also-encrypt-to> [keyid]
141    
142    An additional keyid to encrypt messages to. Default: none.
143    
144    =item B<no-download> [boolean]
145    
146    If true, then skip the step of fetching keys from the keyserver.
147    Default: B<0>.
148    
149    =item B<no-sign> [boolean]
150    
151    If true, then skip the signing step. Default: B<0>.
152    
153    =back
154    
155    =head1 AUTHOR
156    
157    Peter Palfrader <peter@palfrader.org>
158    
159    =head1 WEBSITE
160    
161    http://pgp-tools.alioth.debian.org/
162    
163    =cut
164    
165  use strict;  use strict;
166  use IO::Handle;  use IO::Handle;
167  use English;  use English;
# Line 37  use File::Temp qw{tempdir}; Line 170  use File::Temp qw{tempdir};
170  use MIME::Entity;  use MIME::Entity;
171  use Fcntl;  use Fcntl;
172  use IO::Select;  use IO::Select;
173    use Getopt::Std;
174  use GnuPG::Interface;  use GnuPG::Interface;
175    
176  my %CONFIG;  my %CONFIG;
# Line 46  my $VERSION = "0.0.0.$REVISION_NUMER"; Line 180  my $VERSION = "0.0.0.$REVISION_NUMER";
180    
181  sub load_config() {  sub load_config() {
182          my $config = $ENV{'HOME'} . '/.caffrc';          my $config = $ENV{'HOME'} . '/.caffrc';
183          -f $config or die "No file $config present.  See caffrc(5).\n";          -f $config or die "No file $config present.  See caff(1).\n";
184          unless (scalar eval `cat $config`) {          unless (scalar eval `cat $config`) {
185                  die "Couldn't parse $config: $EVAL_ERROR\n" if $EVAL_ERROR;                  die "Couldn't parse $config: $EVAL_ERROR\n" if $EVAL_ERROR;
186          };          };
187    
188          die ("caffhome is not defined.\n") unless defined $CONFIG{'caffhome'};          $CONFIG{'caffhome'}=$ENV{'HOME'}.'/.caff' unless defined $CONFIG{'caffhome'};
189          die ("owner is not defined.\n") unless defined $CONFIG{'owner'};          die ("owner is not defined.\n") unless defined $CONFIG{'owner'};
190          die ("email is not defined.\n") unless defined $CONFIG{'email'};          die ("email is not defined.\n") unless defined $CONFIG{'email'};
191          die ("keyid is not defined.\n") unless defined $CONFIG{'keyid'};          die ("keyid is not defined.\n") unless defined $CONFIG{'keyid'};
# Line 66  sub load_config() { Line 200  sub load_config() {
200          $CONFIG{'gpg-sign'} = $CONFIG{'gpg'} unless defined $CONFIG{'gpg-sign'};          $CONFIG{'gpg-sign'} = $CONFIG{'gpg'} unless defined $CONFIG{'gpg-sign'};
201          $CONFIG{'gpg-delsig'} = $CONFIG{'gpg'} unless defined $CONFIG{'gpg-delsig'};          $CONFIG{'gpg-delsig'} = $CONFIG{'gpg'} unless defined $CONFIG{'gpg-delsig'};
202          $CONFIG{'secret-keyring'} = $ENV{'HOME'}.'/.gnupg/secring.gpg' unless defined $CONFIG{'secret-keyring'};          $CONFIG{'secret-keyring'} = $ENV{'HOME'}.'/.gnupg/secring.gpg' unless defined $CONFIG{'secret-keyring'};
203            $CONFIG{'no-download'} = 0 unless defined $CONFIG{'no-download'};
204            $CONFIG{'no-sign'} = 0 unless defined $CONFIG{'no-sign'};
205  };  };
206    
207  sub notice($) {  sub notice($) {
# Line 125  sub readwrite_gpg($$$$$%) { Line 261  sub readwrite_gpg($$$$$%) {
261    
262          my ($stdout, $stderr, $status) = ("", "", "");          my ($stdout, $stderr, $status) = ("", "", "");
263          my $exitwhenstatusmatches = $options{'exitwhenstatusmatches'};          my $exitwhenstatusmatches = $options{'exitwhenstatusmatches'};
264          trace("doign stuff until we find $exitwhenstatusmatches") if defined $exitwhenstatusmatches;          trace("doing stuff until we find $exitwhenstatusmatches") if defined $exitwhenstatusmatches;
265    
266            my $readwrote_stuff_this_time = 0;
267            my $do_not_wait_on_select = 0;
268          my ($readyr, $readyw, $written);          my ($readyr, $readyw, $written);
269          while ($sout->count() > 0 || (defined($sin) && ($sin->count() > 0))) {          while ($sout->count() > 0 || (defined($sin) && ($sin->count() > 0))) {
270                  if (defined $exitwhenstatusmatches) {                  if (defined $exitwhenstatusmatches) {
271                          if ($status =~ /$exitwhenstatusmatches/m) {                          if ($status =~ /$exitwhenstatusmatches/m) {
272                                  trace("readwrite_gpg found match on $exitwhenstatusmatches");                                  trace("readwrite_gpg found match on $exitwhenstatusmatches");
273                                  last;                                  if ($readwrote_stuff_this_time) {
274                                            trace("read/write some more\n");
275                                            $do_not_wait_on_select = 1;
276                                    } else {
277                                            trace("that's it in our while loop.\n");
278                                            last;
279                                    }
280                          };                          };
281                  };                  };
282    
283                    $readwrote_stuff_this_time = 0;
284                  trace("select waiting for ".($sout->count())." fds.");                  trace("select waiting for ".($sout->count())." fds.");
285                  ($readyr, $readyw, undef) = IO::Select::select($sout, $sin, undef, 1);                  ($readyr, $readyw, undef) = IO::Select::select($sout, $sin, undef, $do_not_wait_on_select ? 0 : 1);
286                  trace("ready: write: ".(defined $readyw ? scalar @$readyw : 0 )."; read: ".(defined $readyr ? scalar @$readyr : 0));                  trace("ready: write: ".(defined $readyw ? scalar @$readyw : 0 )."; read: ".(defined $readyr ? scalar @$readyr : 0));
287                  for my $wfd (@$readyw) {                  for my $wfd (@$readyw) {
288                            $readwrote_stuff_this_time = 1;
289                          if (length($in) != $offset) {                          if (length($in) != $offset) {
290                                  trace("writing to $wfd.");                                  trace("writing to $wfd.");
291                                  $written = $wfd->syswrite($in, length($in) - $offset, $offset);                                  $written = $wfd->syswrite($in, length($in) - $offset, $offset);
# Line 159  sub readwrite_gpg($$$$$%) { Line 305  sub readwrite_gpg($$$$$%) {
305                  next unless (defined(@$readyr)); # Wait some more.                  next unless (defined(@$readyr)); # Wait some more.
306    
307                  for my $rfd (@$readyr) {                  for my $rfd (@$readyr) {
308                            $readwrote_stuff_this_time = 1;
309                          if ($rfd->eof) {                          if ($rfd->eof) {
310                                  trace("reading from $rfd done.");                                  trace("reading from $rfd done.");
311                                  $sout->remove($rfd);                                  $sout->remove($rfd);
# Line 215  my $KEYEDIT_KEYEDIT_OR_DELSIG_PROMPT = ' Line 362  my $KEYEDIT_KEYEDIT_OR_DELSIG_PROMPT = '
362  my $KEYEDIT_DELSUBKEY_PROMPT = '^\[GNUPG:\] GET_BOOL keyedit.remove.subkey';  my $KEYEDIT_DELSUBKEY_PROMPT = '^\[GNUPG:\] GET_BOOL keyedit.remove.subkey';
363    
364  load_config;  load_config;
365  my $USER_AGENT = "caff $VERSION - (c) 2004 Peter Palfrader";  my $USER_AGENT = "caff $VERSION - (c) 2004, 2005 Peter Palfrader";
366    
367  my $KEYSBASE =  $CONFIG{'caffhome'}.'/keys';  my $KEYSBASE =  $CONFIG{'caffhome'}.'/keys';
368  my $GNUPGHOME = $CONFIG{'caffhome'}.'/gnupghome';  my $GNUPGHOME = $CONFIG{'caffhome'}.'/gnupghome';
# Line 229  my $DATE_STRING = sprintf("%04d-%02d-%02 Line 376  my $DATE_STRING = sprintf("%04d-%02d-%02
376    
377    
378  sub usage() {  sub usage() {
379          print STDERR "caff $VERSION - (c) 2004 Peter Palfrader\n";          print STDERR "caff $VERSION - (c) 2004, 2005 Peter Palfrader\n";
380          print STDERR "Usage: $PROGRAM_NAME [-u <yourkeyid] <keyid> [<keyid> ...]\n";          print STDERR "Usage: $PROGRAM_NAME [-mMR] [-u <yourkeyid>] <keyid> [<keyid> ...]\n";
381          exit 1;          exit 1;
382  };  };
383    
# Line 330  $CONFIG{'owner'} Line 477  $CONFIG{'owner'}
477    
478          $message_entity->head->add("Subject", "Your signed PGP key 0x$key_id");          $message_entity->head->add("Subject", "Your signed PGP key 0x$key_id");
479          $message_entity->head->add("To", $address);          $message_entity->head->add("To", $address);
480          $message_entity->head->add("From", $CONFIG{'owner'}.' <'.$CONFIG{'email'}.'>');          $message_entity->head->add("From", '"'.$CONFIG{'owner'}.'" <'.$CONFIG{'email'}.'>');
481          $message_entity->head->add("User-Agent", $USER_AGENT);          $message_entity->head->add("User-Agent", $USER_AGENT);
482          $message_entity->send();          $message_entity->send();
483          $message_entity->stringify();          $message_entity->stringify();
484  };  };
485    
486    sub sanitize_uid($) {
487            my ($uid) = @_;
488    
489            my $good_uid = $uid;
490            $good_uid =~ tr#/:\\#_#;
491            trace2("[sanitize_uid] changed UID from $uid to $good_uid.\n") if $good_uid ne $uid;
492            return $good_uid;
493    };
494    
495  my $USER;  my $USER;
496  my @KEYIDS;  my @KEYIDS;
497    my %opt;
498    
499    getopts('mMRu:', \%opt);
500    
501  usage() unless scalar @ARGV >= 1;  usage() unless scalar @ARGV >= 1;
502  if ($ARGV[0] eq '-u') {  if ($opt{u}) {
503          usage() unless scalar @ARGV >= 3;          $USER = $opt{u};
504          shift @ARGV;          $USER =~ s/^0x//i;
         $USER = shift @ARGV;  
505          unless ($USER =~ /^[A-Za-z0-9]{8,8}([A-Za-z0-9]{8})?$/) {          unless ($USER =~ /^[A-Za-z0-9]{8,8}([A-Za-z0-9]{8})?$/) {
506                  print STDERR "-u $USER is not a keyid.\n";                  print STDERR "-u $USER is not a keyid.\n";
507                  usage();                  usage();
# Line 351  if ($ARGV[0] eq '-u') { Line 509  if ($ARGV[0] eq '-u') {
509          $USER = uc($USER);          $USER = uc($USER);
510  };  };
511  for my $keyid (@ARGV) {  for my $keyid (@ARGV) {
512            $keyid =~ s/^0x//i;
513          unless ($keyid =~ /^[A-Za-z0-9]{8}([A-Za-z0-9]{8})?$/) {          unless ($keyid =~ /^[A-Za-z0-9]{8}([A-Za-z0-9]{8})?$/) {
514                  print STDERR "$keyid is not a keyid.\n";                  print STDERR "$keyid is not a keyid.\n";
515                  usage();                  usage();
# Line 359  for my $keyid (@ARGV) { Line 518  for my $keyid (@ARGV) {
518  };  };
519    
520    
521    
522    #################
523    # import own keys
524    #################
525            my $gpg = GnuPG::Interface->new();
526            $gpg->call( $CONFIG{'gpg'} );
527            $gpg->options->hash_init(
528                    'homedir' => $GNUPGHOME,
529                    'extra_args' => '--keyserver='.$CONFIG{'keyserver'} );
530            $gpg->options->meta_interactive( 0 );
531            my ($inputfd, $stdoutfd, $stderrfd, $statusfd, $handles) = make_gpg_fds();
532            $gpg->options->hash_init( 'extra_args' => [ '--with-colons', '--fixed-list-mode' ] );
533            my $pid = $gpg->list_public_keys(handles => $handles, command_args => $CONFIG{'keyid'});
534            my ($stdout, $stderr, $status) = readwrite_gpg('', $inputfd, $stdoutfd, $stderrfd, $statusfd);
535            waitpid $pid, 0;
536            if ($stdout eq '') {
537                    warn ("No data from gpg for list-key\n");
538                    next;
539            };
540            foreach my $keyid (@{$CONFIG{'keyid'}}) {
541                    unless ($stdout =~ /^pub:(?:[^:]*:){3,3}$keyid:/m) {
542                            info("Importing $keyid");
543                            system "gpg --export $keyid | gpg --import --homedir $GNUPGHOME";
544                    }
545            }
546    
547  #############################  #############################
548  # receive keys from keyserver  # receive keys from keyserver
549  #############################  #############################
 my $gpg = GnuPG::Interface->new();  
 $gpg->call( $CONFIG{'gpg'} );  
 $gpg->options->hash_init(  
         'homedir' => $GNUPGHOME,  
         'extra_args' => '--keyserver='.$CONFIG{'keyserver'} );  
 $gpg->options->meta_interactive( 0 );  
 my ($inputfd, $stdoutfd, $stderrfd, $statusfd, $handles) = make_gpg_fds();  
 my $pid = $gpg->recv_keys(handles => $handles, command_args => [ @KEYIDS ]);  
 my ($stdout, $stderr, $status) = readwrite_gpg('', $inputfd, $stdoutfd, $stderrfd, $statusfd);  
 waitpid $pid, 0;  
   
550  my @keyids_ok;  my @keyids_ok;
551  my @keyids_failed;  my @keyids_failed;
552    if ($CONFIG{'no-download'} or $opt{R}) {
553            @keyids_ok = @KEYIDS;
554    } else {
555            my $gpg = GnuPG::Interface->new();
556            $gpg->call( $CONFIG{'gpg'} );
557            $gpg->options->hash_init(
558                    'homedir' => $GNUPGHOME,
559                    'extra_args' => '--keyserver='.$CONFIG{'keyserver'} );
560            $gpg->options->meta_interactive( 0 );
561            my ($inputfd, $stdoutfd, $stderrfd, $statusfd, $handles) = make_gpg_fds();
562    
563            my @local_keyids = @KEYIDS;
564            for my $keyid (@local_keyids) {
565                    info ("fetching $keyid...");
566                    my $pid = $gpg->recv_keys(handles => $handles, command_args => [ $keyid ]);
567                    my ($stdout, $stderr, $status) = readwrite_gpg('', $inputfd, $stdoutfd, $stderrfd, $statusfd);
568                    waitpid $pid, 0;
569    
570  # [GNUPG:] IMPORT_OK 0 5B00C96D5D54AEE1206BAF84DE7AAF6E94C09C7F  # [GNUPG:] IMPORT_OK 0 5B00C96D5D54AEE1206BAF84DE7AAF6E94C09C7F
571  # [GNUPG:] NODATA 1  # [GNUPG:] NODATA 1
572  # [GNUPG:] NODATA 1  # [GNUPG:] NODATA 1
573  # [GNUPG:] IMPORT_OK 0 25FC1614B8F87B52FF2F99B962AF4031C82E0039  # [GNUPG:] IMPORT_OK 0 25FC1614B8F87B52FF2F99B962AF4031C82E0039
574  for my $line (split /\n/, $status) {                  my $handled = 0;
575          if ($line =~ /^\[GNUPG:\] IMPORT_OK/) {                  for my $line (split /\n/, $status) {
576                  push @keyids_ok, shift @KEYIDS;                          if ($line =~ /^\[GNUPG:\] IMPORT_OK/) {
577          } elsif ($line =~ /^\[GNUPG:\] NODATA/) {                                  push @keyids_ok, shift @KEYIDS;
578                  push @keyids_failed, shift @KEYIDS;                                  $handled = 1;
579          };                                  last;
580  }                          } elsif ($line =~ /^\[GNUPG:\] NODATA/) {
581  die ("Still keys in \@KEYIDS.  This should not happen.") if scalar @KEYIDS;                                  push @keyids_failed, shift @KEYIDS;
582  notice ("Import failed for: ". (join ' ', @keyids_failed).".") if scalar @keyids_failed;                                  $handled = 1;
583                                    last;
584                            };
585                    };
586                    unless ($handled) {
587                            notice ("Huh, what's up with $keyid?");
588                            push @keyids_failed, shift @KEYIDS;
589                    };
590            };
591            die ("Still keys in \@KEYIDS.  This should not happen.") if scalar @KEYIDS;
592            notice ("Import failed for: ". (join ' ', @keyids_failed).".") if scalar @keyids_failed;
593    };
594    
595  ###########  ###########
596  # sign keys  # sign keys
597  ###########  ###########
598  info("Sign the following keys according to your policy...");  unless ($CONFIG{'no-sign'}) {
599  for my $keyid (@keyids_ok) {          info("Sign the following keys according to your policy, then exit gpg with 'save' after signing each key");
600          my @command;          for my $keyid (@keyids_ok) {
601          push @command, $CONFIG{'gpg-sign'};                  my @command;
602          push @command, '--local-user', $USER if (defined $USER);                  push @command, $CONFIG{'gpg-sign'};
603          push @command, "--homedir=$GNUPGHOME";                  push @command, '--local-user', $USER if (defined $USER);
604          push @command, '--secret-keyring', $CONFIG{'secret-keyring'};                  push @command, "--homedir=$GNUPGHOME";
605          push @command, '--sign-key', $keyid;                  push @command, '--secret-keyring', $CONFIG{'secret-keyring'};
606          print join(' ', @command),"\n";                  push @command, '--edit', $keyid;
607          system (@command);                  push @command, 'sign';
608                    print join(' ', @command),"\n";
609                    system (@command);
610            };
611  };  };
612    
613  ##################  ##################
# Line 411  KEYS: Line 617  KEYS:
617  for my $keyid (@keyids_ok) {  for my $keyid (@keyids_ok) {
618          # get key listing          # get key listing
619          #################          #################
620          $gpg = GnuPG::Interface->new();          my $gpg = GnuPG::Interface->new();
621          $gpg->call( $CONFIG{'gpg'} );          $gpg->call( $CONFIG{'gpg'} );
622          $gpg->options->hash_init( 'homedir' => $GNUPGHOME );          $gpg->options->hash_init( 'homedir' => $GNUPGHOME );
623          $gpg->options->meta_interactive( 0 );          $gpg->options->meta_interactive( 0 );
624          ($inputfd, $stdoutfd, $stderrfd, $statusfd, $handles) = make_gpg_fds();          my ($inputfd, $stdoutfd, $stderrfd, $statusfd, $handles) = make_gpg_fds();
625          $gpg->options->hash_init( 'extra_args' => [ '--with-colons', '--fixed-list-mode' ] );          $gpg->options->hash_init( 'extra_args' => [ '--with-colons', '--fixed-list-mode' ] );
626          $pid = $gpg->list_public_keys(handles => $handles, command_args => [ $keyid ]);          my $pid = $gpg->list_public_keys(handles => $handles, command_args => [ $keyid ]);
627          ($stdout, $stderr, $status) = readwrite_gpg('', $inputfd, $stdoutfd, $stderrfd, $statusfd);          my ($stdout, $stderr, $status) = readwrite_gpg('', $inputfd, $stdoutfd, $stderrfd, $statusfd);
628          waitpid $pid, 0;          waitpid $pid, 0;
629          if ($stdout eq '') {          if ($stdout eq '') {
630                  warn ("No data from gpg for list-key $keyid\n");                  warn ("No data from gpg for list-key $keyid\n");
# Line 446  for my $keyid (@keyids_ok) { Line 652  for my $keyid (@keyids_ok) {
652          while (1) {          while (1) {
653                  my $this_uid_text = '';                  my $this_uid_text = '';
654                  $uid_number++;                  $uid_number++;
655                  info("Doing key $keyid, uid $uid_number");                  debug("Doing key $keyid, uid $uid_number");
656    
657                  # import into temporary gpghome                  # import into temporary gpghome
658                  ###############################                  ###############################
# Line 515  for my $keyid (@keyids_ok) { Line 721  for my $keyid (@keyids_ok) {
721                          next;                          next;
722                  };                  };
723                  unless ($have_one) {                  unless ($have_one) {
724                            debug("Uid ".($uid_number-1)." was the last, there is no $uid_number.");
725                          info("key $keyid done.");                          info("key $keyid done.");
726                          last;                          last;
727                  };                  };
# Line 544  for my $keyid (@keyids_ok) { Line 751  for my $keyid (@keyids_ok) {
751                  while($status =~ /$KEYEDIT_DELSIG_PROMPT/m) {                  while($status =~ /$KEYEDIT_DELSIG_PROMPT/m) {
752                          # sig:?::17:EA2199412477CAF8:1058095214:::::13x:                          # sig:?::17:EA2199412477CAF8:1058095214:::::13x:
753                          my @sigline = grep { /^sig/ } (split /\n/, $stdout);                          my @sigline = grep { /^sig/ } (split /\n/, $stdout);
754                            $stdout =~ s/\n/\\n/g;
755                            notice("[sigremoval] why are there ".(scalar @sigline)." siglines in that part of the dialog!? got: $stdout") if scalar @sigline >= 2; # XXX
756                          my $line = pop @sigline;                          my $line = pop @sigline;
757                          my $answer = "no";                          my $answer = "no";
758                          if (defined $line) { # only if we found a sig here - we never remove revocation packets for instance                          if (defined $line) { # only if we found a sig here - we never remove revocation packets for instance
759                                    debug("[sigremoval] doing line $line.");
760                                  my ($dummy1, $dummy2, $dummy3, $dummy4, $signer, $created, $dummy7, $dummy8, $dummy9) = split /:/, $line;                                  my ($dummy1, $dummy2, $dummy3, $dummy4, $signer, $created, $dummy7, $dummy8, $dummy9) = split /:/, $line;
761                                  if ($signer eq $longkeyid) {                                  if ($signer eq $longkeyid) {
762                                            debug("[sigremoval] selfsig ($signer).");
763                                          $answer = "no";                                          $answer = "no";
764                                  } elsif (grep { $signer eq $_ } @{$CONFIG{'keyid'}}) {                                  } elsif (grep { $signer eq $_ } @{$CONFIG{'keyid'}}) {
765                                            debug("[sigremoval] signed by us ($signer).");
766                                          $answer = "no";                                          $answer = "no";
767                                          $signed_by_me = $signed_by_me > $created ? $signed_by_me : $created;                                          $signed_by_me = $signed_by_me > $created ? $signed_by_me : $created;
768                                  } else {                                  } else {
769                                            debug("[sigremoval] not interested in that sig ($signer).");
770                                          $answer = "yes";                                          $answer = "yes";
771                                  };                                  };
772                            } else {
773                                    debug("[sigremoval] no sig line here, only got: ".$stdout);
774                          };                          };
775                          ($stdout, $stderr, $status) =                          ($stdout, $stderr, $status) =
776                                  readwrite_gpg($answer."\n", $inputfd, $stdoutfd, $stderrfd, $statusfd, exitwhenstatusmatches => $KEYEDIT_KEYEDIT_OR_DELSIG_PROMPT, nocloseinput => 1);                                  readwrite_gpg($answer."\n", $inputfd, $stdoutfd, $stderrfd, $statusfd, exitwhenstatusmatches => $KEYEDIT_KEYEDIT_OR_DELSIG_PROMPT, nocloseinput => 1);
# Line 577  for my $keyid (@keyids_ok) { Line 792  for my $keyid (@keyids_ok) {
792                          my $keydir = "$KEYSBASE/$DATE_STRING";                          my $keydir = "$KEYSBASE/$DATE_STRING";
793                          -d $keydir  || mkpath($keydir , 0, 0700) or die ("Cannot create $keydir $!\n");                          -d $keydir  || mkpath($keydir , 0, 0700) or die ("Cannot create $keydir $!\n");
794    
795                          my $keyfile = "$keydir/$longkeyid.key.$uid_number.$this_uid_text.asc";                          my $keyfile = "$keydir/$longkeyid.key.$uid_number.".sanitize_uid($this_uid_text).".asc";
796                          open (KEY, ">$keyfile") or die ("Cannot open $keyfile\n");                          open (KEY, ">$keyfile") or die ("Cannot open $keyfile\n");
797                          print KEY $asciikey;                          print KEY $asciikey;
798                          close KEY;                          close KEY;
# Line 593  for my $keyid (@keyids_ok) { Line 808  for my $keyid (@keyids_ok) {
808          if (scalar @UIDS == 0) {          if (scalar @UIDS == 0) {
809                  info("found no signed uids for $keyid");                  info("found no signed uids for $keyid");
810          } else {          } else {
811                  my @attached ;                  next if $opt{M}; # do not send mail
812    
813                    my @attached;
814                  for my $uid (@UIDS) {                  for my $uid (@UIDS) {
815                            trace("UID: $uid->{'text'}\n");
816                          unless ($uid->{'text'} =~ /@/) {                          unless ($uid->{'text'} =~ /@/) {
817                                  my $attach = ask("UID $uid->{'text'} is no email address, attach it to every email sent?", 1);                                  my $attach = ask("UID $uid->{'text'} is no email address, attach it to every email sent?", 1);
818                                  push @attached, $uid;                                  push @attached, $uid if $attach;
819                          };                          };
820                  };                  };
821    
# Line 606  for my $keyid (@keyids_ok) { Line 824  for my $keyid (@keyids_ok) {
824                          if ($uid->{'text'} =~ /@/) {                          if ($uid->{'text'} =~ /@/) {
825                                  my $address = $uid->{'text'};                                  my $address = $uid->{'text'};
826                                  $address =~ s/.*<(.*)>.*/$1/;                                  $address =~ s/.*<(.*)>.*/$1/;
827                                  my $send = ask("Send mail to '$address' for $uid->{'text'}?", 1);                                  if ($opt{m} or ask("Send mail to '$address' for $uid->{'text'}?", 1)) {
                                 if ($send) {  
828                                          my $mail = send_mail($address, $can_encrypt, $longkeyid, $uid, @attached);                                          my $mail = send_mail($address, $can_encrypt, $longkeyid, $uid, @attached);
829    
830                                          my $keydir = "$KEYSBASE/$DATE_STRING";                                          my $keydir = "$KEYSBASE/$DATE_STRING";
831                                          my $mailfile = "$keydir/$longkeyid.mail.".$uid->{'serial'}.".".$uid->{'text'};                                          my $mailfile = "$keydir/$longkeyid.mail.".$uid->{'serial'}.".".sanitize_uid($uid->{'text'});
832                                          open (KEY, ">$mailfile") or die ("Cannot open $mailfile\n");                                          open (KEY, ">$mailfile") or die ("Cannot open $mailfile\n");
833                                          print KEY $mail;                                          print KEY $mail;
834                                          close KEY;                                          close KEY;

Legend:
Removed from v.7  
changed lines
  Added in v.79

  ViewVC Help
Powered by ViewVC 1.1.5