[Pgp-tools-commit] r790 - in trunk: caff debian
Guilhem Moulin
guilhem-guest at moszumanska.debian.org
Fri Feb 20 19:37:15 UTC 2015
Author: guilhem-guest
Date: 2015-02-20 19:37:15 +0000 (Fri, 20 Feb 2015)
New Revision: 790
Modified:
trunk/caff/caff
trunk/debian/changelog
Log:
caff: Fix $CONFIG{'also-lsign-in-gnupghome'}
Local signatures are directly imported from caff's GNUPGHOME to our own;
in auto-lsign'ing mode, lsign UID for which we have an exportable
signature (preserving the signer and cert level).
Modified: trunk/caff/caff
===================================================================
--- trunk/caff/caff 2015-02-20 19:37:09 UTC (rev 789)
+++ trunk/caff/caff 2015-02-20 19:37:15 UTC (rev 790)
@@ -976,14 +976,19 @@
return $good_uid;
};
-sub delete_signatures($$$$) {
- my ($handles, $longkeyid, $uid, $keyids) = @_;
+# Delete all non self-sigs that are not made by one of the @$keyids, and
+# return the date of the most recent signature and a hash reference
+# {$signer => $level} of the keys in @$keyids that have an exportable
+# signature on that $uid. If $keep_lsigs_only, our exportable
+# signatures are removed as well.
+sub delete_signatures($$$$;$) {
+ my ($handles, $longkeyid, $uid, $keyids, $keep_lsigs_only) = @_;
readwrite_gpg($handles, command => "uid 0", status => $KEYEDIT_PROMPT); # unmark all uids from delsig
readwrite_gpg($handles, command => "uid $uid", status => $KEYEDIT_PROMPT); # mark $uid for delsig
my $last_signed_on = 0;
- my %signers;
+ my %xsigners;
my %output = readwrite_gpg($handles, command => "delsig", status => $KEYEDIT_DELSIG_PROMPT);
@@ -996,7 +1001,7 @@
}
else { # only if we found a sig here - we never remove revocation packets for instance
my $sig = pop @sigline;
- $sig =~ /^sig:(?:[^:]*:){3}([0-9A-F]{16}):(\d+):(?:[^:]*:){4}(1[0-3]|30)[lx](?::.*)?$/ or
+ $sig =~ /^sig:(?:[^:]*:){3}([0-9A-F]{16}):(\d+):(?:[^:]*:){4}(1[0-3]|30)([lx])(?::.*)?$/ or
mywarn("I hit a bug, please report: Couldn't parse sigline $sig");
debug("[sigremoval] doing sigline $sig");
if ($1 eq $longkeyid) {
@@ -1004,9 +1009,9 @@
$answer = "no";
} elsif (grep { $1 eq $_ } @$keyids and $3 != 30) {
debug("[sigremoval] signed by us ($1)");
- $answer = "no";
+ $answer = ($keep_lsigs_only and $4 eq 'x') ? "yes" : "no";
$last_signed_on = $2 if $last_signed_on < $2;
- $signers{$1} = $3-10;
+ $xsigners{$1} = $3-10 if $4 eq 'x';
} else {
debug("[sigremoval] not interested in that sig ($1)");
$answer = "yes";
@@ -1014,10 +1019,10 @@
mywarn("I hit a bug, please report: Found the following ".($#sigline+2)." siglines in that part of the dialog:\n".$output{stdout}) if @sigline;
}
%output = readwrite_gpg($handles, command => $answer, status => $KEYEDIT_KEYEDIT_OR_DELSIG_PROMPT);
- };
+ }
- return ($last_signed_on, \%signers);
-};
+ return ($last_signed_on, \%xsigners);
+}
##
# Check the local user keys.
@@ -1081,6 +1086,7 @@
my @extra_args;
push @import_options, 'import-local-sigs' if $CONFIG{'gpg-sign-type'} =~ /l/ and !grep /import-local-sigs$/, @import_options;
+ push @import_options, 'keep-ownertrust' unless defined $dst_gpghome or $GNUPG_VERSION >= 2.1; # don't modify our own trustdb
push @extra_args, '--min-cert-level=1' if grep { $_ eq 'import-clean' } @import_options;
push @extra_args, '--import-options', join (',', @import_options) if @import_options;
@@ -1598,7 +1604,7 @@
# delete signatures
###################
# this shouldn't delete anything as $longkeyid is already clean, but maybe we didn't sign that uid with all keys in @{$CONFIG{'keyid'}}
- my ($last_signed_on, $signers) = delete_signatures($handles, $longkeyid, $uid->{hash}, $CONFIG{'keyid'});
+ my ($last_signed_on, $xsigners) = delete_signatures($handles, $longkeyid, $uid->{hash}, $CONFIG{'keyid'});
delete_signatures($handles, $longkeyid, $first_uid->{hash}, [])
if $uid->{type} ne 'uid'; # delete all sigs on the first UID if $uid is an attribute
@@ -1620,88 +1626,98 @@
# it's a bit inefficient to store the $asciikey in memory,
# but it has been pruned so it's shouldn't be too big
$uid->{key} = $asciikey;
- $uid->{signers} = $signers;
+ $uid->{xsigners} = $xsigners;
$uid->{last_signed_on} = $last_signed_on;
};
};
+
+
+ unless ($CONFIG{'also-lsign-in-gnupghome'} eq 'no') {
+ # remove all exportable sigs, and import into our GnuPGHOME
+ ###########################################################
+ my $gpg = mkGnuPG( homedir => $keydir, extra_args => ['--with-colons'] );
+ my $handles = mkGnuPG_fds( command => undef, stdout => undef, status => undef );
+ my $pid = $gpg->wrap_call(
+ commands => [ '--edit-key' ],
+ command_args => [ $keyid ],
+ handles => $handles );
+
+ debug("Starting edit session on $keyid");
+ my %output = readwrite_gpg($handles, status => $KEYEDIT_PROMPT);
+ delete_signatures($handles, $longkeyid, $uids[$_]->{hash}, $CONFIG{'keyid'}, 1) foreach (0 .. $#uids);
+
+ readwrite_gpg($handles, command => "save");
+ done_gpg($pid, $handles);
+ debug("Done editing");
+
+ # import the pruned keys with our own local sigs only; this is
+ # required even if there are no lsigs, to ensure we've got all
+ # UIDs in our own GnuPGHOME
+ import_keys_from_gnupghome( [$keyid], $keydir, undef, 'import-local-sigs' );
+ }
undef $keydir; # delete dir
- if ($CONFIG{'also-lsign-in-gnupghome'} ne 'no') {
- ###############################
- # add non-exportable signatures
- ###############################
-
- import_keys_from_gnupghome( [ $keyid ], $GNUPGHOME, undef,
- # do not export our own exportable signatures, but ensure we've got the same UID list
- $CONFIG{'gpg-sign-type'} =~ /l/ ? () : 'export-minimal' );
- if ( $CONFIG{'gpg-sign-type'} =~ /l/ ) {
- # we've copied the (local) signature to our GnuPHOME and we're done
+ if ($CONFIG{'also-lsign-in-gnupghome'} eq 'ask') {
+ # manually lsign the key
+ ########################
+ foreach my $local_user (@LOCAL_USER) {
+ my @command = ($CONFIG{'gpg'});
+ push @command, '--local-user', $local_user;
+ push @command, '--secret-keyring', $CONFIG{'secret-keyring'};
+ push @command, qw/--no-auto-check-trustdb --trust-model=always/;
+ push @command, '--edit-key', $keyid;
+ push @command, 'showphoto' if $CONFIG{'show-photos'};
+ push @command, 'lsign';
+ push @command, split ' ', $CONFIG{'gpg-sign-args'} || "";
+ print join(' ', @command),"\n";
+ mysystem(@command);
}
- elsif ( $CONFIG{'also-lsign-in-gnupghome'} ne 'auto' ) {
- # manually lsign the key
- ########################
- foreach my $local_user (@LOCAL_USER) {
- my @command = ($CONFIG{'gpg'});
- push @command, '--local-user', $local_user;
- push @command, '--secret-keyring', $CONFIG{'secret-keyring'};
- push @command, qw/--no-auto-check-trustdb --trust-model=always/;
- push @command, '--edit-key', $keyid;
- push @command, 'showphoto' if $CONFIG{'show-photos'};
- push @command, 'lsign';
- push @command, split ' ', $CONFIG{'gpg-sign-args'} || "";
- print join(' ', @command),"\n";
- mysystem(@command);
- };
- }
- else {
- # auto lsign the relevant uids
- ##############################
- my @uids = grep {$_->{last_signed_on}} @{$KEYS{$keyid}->{uids}};
- my @signers = map {keys %{$_->{signers}}} @uids;
- if (@LOCAL_USER && defined $LOCAL_USER[0]) {
- # which of @LOCAL_USER has signed at least one UID in this key?
- @signers = grep { my $u = $_; grep { $u eq $_ } @signers } @LOCAL_USER;
- } else {
- # no @LOCAL_USER was defined; remove duplicates to avoid double signing
- @signers = keys %{{ map { $_ => 1 } @signers }}
- };
+ }
+ elsif ($CONFIG{'also-lsign-in-gnupghome'} eq 'auto') {
+ # auto lsign the uids we for which we have an exportable sig
+ ############################################################
+ my @uids = grep {exists $_->{xsigners}} @{$KEYS{$keyid}->{uids}};
+ my @signers = map {keys %{$_->{xsigners}}} @uids;
+ # which of @LOCAL_USER has signed at least one UID in this key?
+ @signers = grep { my $u = $_; grep { $u eq $_ } @signers } @LOCAL_USER;
+ @signers = keys %{{ map { $_ => 1 } @signers }}; # remove duplicates to avoid double signing
- foreach my $u (@signers) {
- my @signeduids; # uids signed by $u
- foreach my $uid (@uids) {
- # we use UIDs hashes to distinguish and select UIDs; it's the only reliable way to identify them accross keyrings
- push @signeduids, $uid if grep { $u eq $_ } (keys %{$uid->{signers}}) and
- !grep { $uid->{hash} eq $_->{hash} } @signeduids;
- }
+ foreach my $u (@signers) {
+ my @signeduids; # uids signed by $u
+ foreach my $uid (@uids) {
+ # we use UIDs hashes to distinguish and select UIDs; it's the only reliable way to identify them accross keyrings
+ push @signeduids, $uid if grep { $u eq $_ } (keys %{$uid->{xsigners}}) and
+ !grep { $uid->{hash} eq $_->{hash} } @signeduids;
+ }
- my $gpg = mkGnuPG( extra_args => ['--local-user' => $u, '--ask-cert-level'] );
- $gpg->options->push_extra_args('--secret-keyring', $CONFIG{'secret-keyring'}) if $GNUPG_VERSION < 2.1;
- $gpg->options->push_extra_args('--use-agent') if $GNUPG_VERSION < 2.0; # we know there is a working agent
- my $handles = mkGnuPG_fds( command => undef, stdout => undef, status => undef );
- my $pid = $gpg->wrap_call(
- commands => [ '--edit-key' ],
- command_args => [ $keyid ],
- handles => $handles );
+ my $gpg = mkGnuPG( extra_args => ['--local-user' => $u, '--ask-cert-level', '--with-colons', '--no-batch'] );
+ $gpg->options->push_extra_args('--secret-keyring', $CONFIG{'secret-keyring'}) if $GNUPG_VERSION < 2.1;
+ $gpg->options->push_extra_args('--use-agent') if $GNUPG_VERSION < 2.0; # we know there is a working agent
+ my $handles = mkGnuPG_fds( command => undef, stdout => undef, status => undef );
+ my $pid = $gpg->wrap_call(
+ commands => [ '--edit-key' ],
+ command_args => [ $keyid ],
+ handles => $handles );
- debug("Starting edit session on $keyid, signer $u");
- readwrite_gpg($handles, status => $KEYEDIT_PROMPT);
+ debug("Starting edit session on $keyid, signer $u");
+ readwrite_gpg($handles, status => $KEYEDIT_PROMPT);
- foreach my $level (0..3) {
- my @signeduids_with_level = grep {$_->{signers}->{$u} eq $level} @signeduids;
- next unless @signeduids_with_level;
+ foreach my $level (0..3) {
+ my @signeduids_with_level = grep {$_->{xsigners}->{$u} eq $level} @signeduids;
+ next unless @signeduids_with_level;
- notice("lsign-ing (by $u) with cert level $level uid(s) #".(join ',', sort (map {$_->{serial}} @signeduids_with_level))." of $longkeyid", 1);
- readwrite_gpg($handles, command => "uid 0", status => $KEYEDIT_PROMPT);
- readwrite_gpg($handles, command => "uid $_->{hash}", status => $KEYEDIT_PROMPT) for @signeduids_with_level;
- my %output = readwrite_gpg($handles, command => "lsign", statusmatches => qr/$KEYEDIT_SIGNUID_CLASS_PROMPT|$KEYEDIT_PROMPT/);
- next if $output{status} =~ /^\[GNUPG:\] $KEYEDIT_PROMPT/m; # already signed
- readwrite_gpg($handles, command => $level, status => $KEYEDIT_SIGNUID_PROMPT);
- readwrite_gpg($handles, command => "yes", status => $KEYEDIT_PROMPT);
- }
+ notice("Key $longkeyid UID(s) #".(join ',', sort (map {$_->{serial}} @signeduids_with_level)).": lsign'ing with $u, cert level $level", 1);
+ readwrite_gpg($handles, command => "uid 0", status => $KEYEDIT_PROMPT); # unselect UIDs
+ readwrite_gpg($handles, command => "uid $_->{hash}", status => $KEYEDIT_PROMPT) for @signeduids_with_level;
+ my %output = readwrite_gpg($handles, command => "lsign", status => qr/$KEYEDIT_SIGNUID_CLASS_PROMPT|$KEYEDIT_PROMPT/);
+ next if $output{status} =~ /^\[GNUPG:\] $KEYEDIT_PROMPT/m; # already signed
+ readwrite_gpg($handles, command => $level, status => $KEYEDIT_SIGNUID_PROMPT);
+ readwrite_gpg($handles, command => "yes", status => $KEYEDIT_PROMPT);
+ }
- readwrite_gpg($handles, command => "save");
- done_gpg($pid, $handles);
- }
+ readwrite_gpg($handles, command => "save");
+ done_gpg($pid, $handles);
+ debug("Done editing");
}
}
}
Modified: trunk/debian/changelog
===================================================================
--- trunk/debian/changelog 2015-02-20 19:37:09 UTC (rev 789)
+++ trunk/debian/changelog 2015-02-20 19:37:15 UTC (rev 790)
@@ -20,6 +20,10 @@
attribute, for instance.
+ Use Term::ANSIColor to produce colored output.
+ Prune keys with import-{clean,minimal} not export-{clean,minimal}.
+ + Fix $CONFIG{'also-lsign-in-gnupghome'}: local signatures are directly
+ imported from caff's GNUPGHOME to our own; in auto-lsign'ing mode, lsign
+ UID for which we have an exportable signature (preserving the signer and
+ cert level).
* gpgsigs:
+ Add a legend with the different signature types.
+ Mark local signatures as 'L' (formerly they were marked as 'S'), and
More information about the Pgp-tools-commit
mailing list