/usr/bin/jetring-review is in jetring 0.21.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | #!/usr/bin/perl
# Given a keyring and a changeset, shows what gpg would do if it
# applied the changeset to the keyring. The keyring is not modified.
use warnings;
use strict;
use File::Temp qw(tempdir);
use Cwd q{abs_path};
my @allowed_actions=qw(import edit-key delete-key);
my @gpgopts=qw(--command-fd 0 --no-auto-check-trustdb --options /dev/null
--no-default-keyring);
my $diff=0;
if (@ARGV && $ARGV[0] eq '-d') {
$diff=1;
shift;
}
my $keyring=shift || usage();
my $changeset=shift || usage();
# avoid gnupg touching ~/.gnupg
$ENV{GNUPGHOME}=tempdir("jetring.XXXXXXXXXX", TMPDIR => 1, CLEANUP => 1);
$keyring=abs_path($keyring); # gpg works better with an absolute path
my $testring=$keyring.".tmp.$$";
if (-e $testring) {
die "$testring exists";
}
system("cp", $keyring, $testring) == 0 || die "copy failed";
push @gpgopts, "--keyring", $testring;
my $secring="secret-dummy.$$";
sub END {
unlink $secring if defined $secring;
if (defined $testring) {
unlink $testring;
unlink $testring."~";# gpg backup file
unlink $testring.".cache"; # generated by jetring-diff
}
}
open (SECRET_DUMMY, ">$secring") || die "$secring: $!";
close SECRET_DUMMY;
push @gpgopts, "--secret-keyring", abs_path($secring);
my %fields;
my $field;
open(CHANGESET, "<", $changeset) || die "$changeset: $!";
while (<CHANGESET>) {
chomp;
if ($_ eq "-----BEGIN PGP SIGNED MESSAGE-----") {
<CHANGESET> for 1..2;
next;
}
elsif ($_ eq "-----BEGIN PGP SIGNATURE-----") {
last;
}
if (/^([^\s]+):(?:\s+(.*))?/) {
$field=lc $1;
if (defined $2) {
$fields{$field}=$2;
}
else {
$fields{$field}='';
}
}
elsif (/^\s+(.*)/ && defined $field) {
$fields{$field}.="\n" if length $fields{$field};
$fields{$field}.=$1;
}
elsif ($_ eq "") {
process() if defined $field;
%fields=();
$field=undef;
}
else {
die "parse error on line $. of $changeset";
}
}
close CHANGESET;
process() if defined $field;
if ($diff) {
system("jetring-diff", $keyring, $testring) == 0 ||
die "jetring-diff exited nonzero";
}
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";
}
print "gpg --$command @action\n";
my $pid = open(GPG, "|-");
$SIG{PIPE} = 'IGNORE';
if (! $pid) {
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";
sleep 1 if $command ne 'import'; # makes output clearer
}
close GPG || die "gpg exited nonzero";
print "gpg operation complete\n\n";
}
sub usage {
die "Usage: jetring-review [-d] keyring changeset\n";
}
|