Page MenuHomeFreeBSD
Paste P498

gpg-hook
ActivePublic

Authored by mat on Apr 22 2021, 2:40 PM.
#!/usr/local/bin/perl
# vim:sts=4 sw=4 et
# perltidy -bext=/ -se -i=4 -it=2 -ci=2 -xci -l=132 -pt=2 -ce -cti=1 -cab=4 -cb -cbo=0 -wbb="% + - * / x != == >= <= =~ !~ < > | &" -enc=utf8 -wn -sot -sct -asc -tqw -sbq=0 -csc -csct=30 -ssc
use 5.024;
use strict;
use warnings;
use experimental 'switch';
use File::Temp qw(tempdir);
use Text::Wrap qw(wrap);
use Git;
################################################################
# Helper functions
################################################################
my $git = Git->repository;
{ # sub context to avoid leaking @push_options
my @push_options;
for (my $i = 0 ; $i < $ENV{GIT_PUSH_OPTION_COUNT} ; ++$i) {
push @push_options, $ENV{"GIT_PUSH_OPTION_${i}"};
}
sub has_option {
my ($opt) = @_;
for (@push_options) {
return 1 if $opt eq $_;
}
return 0;
} ## end sub has_option
}
sub do_say {
local $Text::Wrap::columns = 65;
say "\n================================================================\n"
. wrap(q{}, q{}, @_)
. "\n================================================================\n";
} ## end sub do_say
sub do_die {
local $Text::Wrap::columns = 65;
die "\n================================================================\n"
. wrap(q{}, q{}, @_)
. "\n================================================================\n\n";
}
local $ENV{'GNUPGHOME'} = tempdir(
'gpg-home-XXXXXXXX',
'CLEANUP' => 1,
'TMPDIR' => 1,
);
my $id = $ENV{'GL_USER'};
system('gpg', '--import', '--quiet', '--no-permission-warning', "/some/where/with/the/doc/documentation/static/pgpkeys/${id}.key")
== 0
or do {
do_say #
"Import of key file for user ${id} failed:\n", #
"$!\n", #
"Verify that the key can be imported with current GnuPG.\n", #
'Ignoring the error for now as signatures are not mandatory.';
exit 0; ## TODO: Switch to do_die when we make this mandatory.
};
################################################################
# Main loop, magic happens here.
for (<STDIN>) {
chomp;
my ($old, $new, $ref) = split / /;
for my $line ($git->command('log', "--format=%H\t%G?\t%GK", $new, '--not', '--all')) {
my ($rev, $status, $key) = split /\t/, $line, 3;
given ($status) {
when ('G') { ## good (valid) signature
## This should not happen as we do not have
## a trustdb to validate the signature.
}
when ('B') { ## bad signature
do_say "Commit $rev has a bad signature";
}
when ('U') { ## good signature with unknown validity
## This is the final expected status, as we don't have a
## trustdb to check the validity.
}
when ('X') { ## good signature that has expired
## Git does not set an expiration on signatues
## so this should not happen.
}
when ('Y') { ## good signature made by an expired key
do_say #
"Commit $rev was signed but the key expired, make sure ", #
'you update the key in the doc repository to match the ', #
'current expiration of your key.';
} ## end when ('Y')
when ('R') { ## good signature made by a revoked key
do_say #
"Commit $rev was signed but the key in the doc repo is, ", #
'but the key expired, make sure you update the key ', #
'in the doc repository to match the current expiration ', #
'of your key.';
} ## end when ('R')
when ('E') { ## signature cannot be checked (e.g. missing key)
do_say #
"Commit $rev was signed with key/subkey \"0x$key\" which ", #
"does not match they key \"$id\" has in the doc repository.";
}
when ('N') { ## no signature
do_say "Commit $rev was not signed.";
}
} ## end given
} ## end for my $line ($git->command('log'...))
} ## end for (<STDIN>)
exit 0;

Event Timeline

mat created this object in space S1 Global.
mat edited the content of this paste. (Show Details)