Anthony Towns wrote: > On Fri, Feb 23, 2007 at 11:15:00PM -0500, Joey Hess wrote: > > Changed-By: Joey Hess <joeyh@debian.org> > > Comment: Removing an old email address. > > I'm not sure that's plausible -- afaik the keyring gets synced to the > real keyservers for new signatures and uids, so removing addresses > doesn't work; though iirc you can do a revocation of a uid these days. Sure, I just wanted to show it can be used for anything you'd do via --edit-keys. I'm not sure what classes of changes keyring-maint typically makes so it seemed best to cover all of them. > There should be some way of getting back to the original conversation > in case something goes wrong. I guess a field containing a URL to an rt > entry or similar would work? Could be an url or even the whole message included, sure. I also left out a Date field, which should be included. > > Note that this is a relative changeset: its action depends on the > > keyring it's run on, since it deletes uid 3 of 788A3F4C. > > That means you can't reorder changesets easily. I wonder if it'd be > better say "del uid joeyh@master.debian.org" and have the tool work out > which uid (if any) that is. I don't feel that reordering changesets is a good thing in general, since it can lead to other problems (for example, reordering a key deletion to come before a key addition), and it loses history that can be useful for reviewing why and when a given change was made. > > joey@kodama:~>cmp input.gpg TESTRING.gpg > > joey@kodama:~> > > Didn't you delete a uid as well as add and remove a key? Why aren't > there differences? Because it's a review tool, so it's not intended to actually change the input keyring. For that something like the attached would be used. -- see shy jo
#!/usr/bin/perl
# Applies a changeset to a keyring.
use warnings;
use strict;
use File::Temp;
my @allowed_actions=qw(import edit-key delete-key);
my @gpgopts=qw(--command-fd 0 --no-auto-check-trustdb --no-default-keyring);
my $keyring=shift || usage();
my $changeset=shift || usage();
push @gpgopts, "--keyring", $keyring;
my %fields;
my $field;
open(CHANGESET, "<", $changeset) || die "$changeset: $!";
while (<CHANGESET>) {
chomp;
if (/^([^\s]+):(?:\s+(.*))?/) {
$field=lc $1;
if (defined $2) {
$fields{$field}=$2;
}
else {
$fields{$field}='';
}
}
elsif (/^\s+\.$/ && defined $field) {
$fields{$field}.="\n";
}
elsif (/^\s+(.*)/ && defined $field) {
$fields{$field}.="\n" if length $fields{$field};
$fields{$field}.=$1;
}
elsif ($_ eq "") {
process() if defined $field;
%fields=();
}
else {
die "parse error on line $. of $changeset";
}
}
close CHANGESET;
process() if defined $field;
sub process {
if (! exists $fields{action}) {
die "$changeset missing action field";
}
my @action=split(' ', $fields{action});
my $command=shift @action;
if (! grep { $_ eq $command } @allowed_actions) {
die "$changeset contains disallowed action \"$command\"";
}
if (! exists $fields{data}) {
die "$changeset missing data field";
}
my $pid = open(GPG, "|-");
$SIG{PIPE} = sub { die "whoops, pipe broke" };
if (! $pid) {
print "gpg --$command @action\n";
exec("gpg", @gpgopts, "--$command", @action) ||
die("failed to run gpg");
}
$|=1;
GPG->autoflush(1);
foreach my $line (split("\n", $fields{data})) {
print ">> $line\n" if $command ne 'import';
print GPG "$line\n" || die "failed talking to gpg";
}
close GPG || die "gpg exited nonzero";
print "gpg operation complete\n\n";
}
sub usage {
die "Usage: changeset-apply keyring changeset\n";
}
Attachment:
signature.asc
Description: Digital signature