summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Jackson <ijackson@chiark.greenend.org.uk>2022-12-27 01:17:39 +0000
committerIan Jackson <ijackson@chiark.greenend.org.uk>2022-12-28 12:07:44 +0000
commit23e23a4f14ffa1dbf8ba07f3d2136e2e16f2e1e1 (patch)
tree3c3b55fc6a4dd39680b5eb5a9a2293b4c5213c0c
parent270e9275117a9833a1dfd447d1940b8d100a6fca (diff)
policy-client-query: dgit: use tainted-objects query
Add the config for controlling policy-client-query calls. For now we default to "unknown" everywhere. If supported, check if tainted objects are reachable from $dgithead, and report them. Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
-rwxr-xr-xdgit77
-rw-r--r--dgit.112
2 files changed, 89 insertions, 0 deletions
diff --git a/dgit b/dgit
index 00ad811..f7bfc0f 100755
--- a/dgit
+++ b/dgit
@@ -105,6 +105,7 @@ our %forceopts = map { $_=>0 }
dsc-changes-mismatch changes-origs-exactly
uploading-binaries uploading-source-only
reusing-version
+ push-tainted
import-gitapply-absurd
import-gitapply-no-absurd
import-dsc-with-dgit-field);
@@ -749,6 +750,7 @@ our %defcfg = ('dgit.default.distro' => 'debian',
'dgit.default.sshpsql-dbname' => 'service=projectb',
'dgit.default.aptget-components' => 'main',
'dgit.default.source-only-uploads' => 'ok',
+ 'dgit.default.policy-query-supported-ssh' => 'unknown',
'dgit.dsc-url-proto-ok.http' => 'true',
'dgit.dsc-url-proto-ok.https' => 'true',
'dgit.dsc-url-proto-ok.git' => 'true',
@@ -4560,6 +4562,61 @@ sub sign_changes ($) {
}
}
+sub tainted_objects_precheck ($$) {
+ my ($json, $dgithead) = @_;
+ my %taints;
+ ROW: foreach my $row (@{ decode_json $json }) {
+ my $objid = $row->{gitobjid};
+ my ($gtype, $dummy) = git_cat_file $objid, undef;
+ next if $gtype eq 'missing';
+ if ($gtype ne $row->{gitobjtype}) {
+ print STDERR f_ <<'END', $objid, $gtype, $row->{gitobjtype};
+warning: server says object %s type %s is tainted, but here it has type %s
+END
+ }
+ foreach my $override (@{ $row->{overrides} }) {
+ next ROW if grep { $_ eq $override } @deliberatelies;
+ }
+ push @{ $taints{$objid} }, $row;
+ }
+
+ open GRL, "-|",
+ @git, qw(rev-list --objects --in-commit-order --pretty=format:),
+ $dgithead
+ or confess "$!";
+ my $trouble = 0;
+ my $found = sub {
+ my ($objid) = @_;
+ my $taints = $taints{$objid};
+ return unless $taints && @$taints;
+ print STDERR f_ "would want to push tainted object %s\n", $objid;
+ foreach my $row (@$taints) {
+ if (grep m{^--deliberately-}, @{ $row->{overrides} }) {
+ print STDERR f_ " overrideable (--deliberately): %s\n", $row->{comment};
+ } else {
+ print STDERR f_ " not overrideable: %s\n", $row->{comment};
+ }
+ $trouble = 1;
+ }
+ };
+ my $c_commit;
+ while (<GRL>) {
+ if (m{^commit (\w+)$}) {
+ $c_commit = $1;
+ $found->($1, __ 'commit');
+ } elsif (m{(^\w{20}\w*) } && defined $c_commit) {
+ $found->($1, f_ 'object within commit %s', $c_commit);
+ } else {
+ confess "$_ ?";
+ }
+ }
+ GRL->error and die $!;
+ close GRL or confess "$? $!";
+ forceable_fail [qw(push-tainted)],
+ __ "pushing tainted objects (which server would reject)"
+ if $trouble;
+}
+
sub dopush () {
printdebug "actually entering push\n";
@@ -4800,6 +4857,26 @@ ENDT
$sourceonlypolicy;
}
+ # Try to detect if we're about to be rejected due to tainted objects
+ my $pq_supported = access_cfg 'policy-query-supported-ssh';
+ if ($pq_supported !~ m/false/) {
+ my @cmd =
+ (access_cfg_ssh, access_gituserhost(),
+ access_runeinfo("policy-client-query $package tainted-objects ").
+ " true");
+ my $json = cmdoutput_errok @cmd;
+ if (!defined $json) {
+ # "unknown" means try the call, but don't mind if it
+ # fails. (This is OK, as a best effort, because then the
+ # server will enforce the check and this machinery is just
+ # to prevent late failures.)
+ failedcmd @cmd unless $pq_supported =~ m/unknown/;
+ } elsif (!length $json) {
+ } else {
+ tainted_objects_precheck $json, $dgithead;
+ }
+ }
+
# Perhaps adjust .dsc to contain right set of origs
changes_update_origs_from_dsc($dsc, $changes, $upstreamversion,
$changesfile)
diff --git a/dgit.1 b/dgit.1
index 5a0eb82..4bad5aa 100644
--- a/dgit.1
+++ b/dgit.1
@@ -1431,6 +1431,16 @@ when running gbp pq import
when importing a package from a .dsc.
See Debian bug #841867.
.TP
+.BR \-\-force-push-tainted
+Go ahead and try to push even tainted git objects
+hat the server says it is going to reject,
+but without declaring any --deliberately.
+This option is provided for testing or strange situations,
+and is not the way to override the taint check:
+using it will probably just fail later,
+burning the version number you are using.
+Use the appropriate --deliberately option instead.
+.TP
.BR \-\-for\-push
Override the dgit-distro.distro.readonly configuration setting,
to specify that we have read/write access
@@ -1580,6 +1590,8 @@ or when pushing and
.TP
.BI dgit-distro. distro .git-check-suffix
.TP
+.BI dgit-distro. distro .policy-query-supported-ssh " " false | unknown | true
+.TP
.BR dgit-distro. \fIdistro\fR .diverts.divert " " new-distro | / \fIdistro-suffix\fR
.TP
.BI dgit-distro. distro .git-create " " ssh-cmd | true