diff options
author | Ian Jackson <ijackson@chiark.greenend.org.uk> | 2017-07-08 17:22:53 +0100 |
---|---|---|
committer | Ian Jackson <ijackson@chiark.greenend.org.uk> | 2017-07-08 17:23:02 +0100 |
commit | fa5bd1281c3c7500104a7ca15795e6448819f391 (patch) | |
tree | 72a1e7847b132a50954454322bf38f11eac41b4d | |
parent | 2046b269f987d70a6b89cbcd8926ef4931586706 (diff) |
dgit: fix rpush+buildinfo: Transfer buildinfos for signing.
buildinfos are supposed to be signed. And, indeed, if they are
present, debsign wants to sign them. That means they need to be
transferred to the signing end, and back again.
We check that the filename is not totally unreasonable, but do not
attempt to verify it completely. If there are situations where
unwanted or confusing buildinfos are generated, this is the fault of
the build process. dgit rpush should, in this respect, do the same as
debsign+dput - ie faithfully sign and upload what the build has
provided.
We do check that the buildinfo doesn't look too much like a .changes,
and mentions the same files as the .changes (insofar as they mention
files in common). This is a rather nugatory defence against some
kinds of bait and switch attacks.
This is in some sense an incompatible protocol change: if the build
host has a new dgit, and sends buildinfos, an old dgit on the
initiator will declare a protocol violation. However, the new
protocol elements occur only when needed. in this situation, the only
way to get things to work at all with the old dgit at either end would
be to strip out the buildinfos, which is obviously undesirable.
Closes:#867693.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
-rw-r--r-- | debian/changelog | 3 | ||||
-rwxr-xr-x | dgit | 44 |
2 files changed, 44 insertions, 3 deletions
diff --git a/debian/changelog b/debian/changelog index 73a0035..942c77b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,7 @@ dgit (3.11~) unstable; urgency=medium - * + * dgit: fix rpush+buildinfo: Transfer buildinfos for signing. + Closes:#867693. -- @@ -316,6 +316,9 @@ sub gbp_pq { # > param tagformat old|new # > param maint-view MAINT-VIEW-HEAD # +# > param buildinfo-filename P_V_X.buildinfo # zero or more times +# > file buildinfo # for buildinfos to sign +# # > previously REFNAME=OBJNAME # if --deliberately-not-fast-forward # # goes into tag, for replay prevention # @@ -332,6 +335,9 @@ sub gbp_pq { # [etc] # < data-block NBYTES [transfer of signed changes] # [etc] +# < data-block NBYTES [transfer of each signed buildinfo +# [etc] same number and order as "file buildinfo"] +# ... # < files-end # # > complete @@ -4296,6 +4302,14 @@ END responder_send_command("param maint-view $maintviewhead"); } + # Perhaps send buildinfo(s) for signing + my $changes_files = getfield $changes, 'Files'; + my @buildinfos = ($changes_files =~ m/ .* (\S+\.buildinfo)$/mg); + foreach my $bi (@buildinfos) { + responder_send_command("param buildinfo-filename $bi"); + responder_send_file('buildinfo', "$buildproductsdir/$bi"); + } + if (deliberately_not_fast_forward) { git_for_each_ref(lrfetchrefs, sub { my ($objid,$objtype,$lrfetchrefname,$reftail) = @_; @@ -4367,6 +4381,7 @@ END if ($we_are_responder) { my $dryrunsuffix = act_local() ? "" : ".tmp"; my @rfiles = ($dscpath, $changesfile); + push @rfiles, map { "$buildproductsdir/$_" } @buildinfos; responder_receive_files('signed-dsc-changes', map { "$_$dryrunsuffix" } @rfiles); } else { @@ -4719,7 +4734,7 @@ sub i_resp_want ($) { print RI "files-end\n" or die $!; } -our ($i_clogp, $i_version, $i_dscfn, $i_changesfn); +our ($i_clogp, $i_version, $i_dscfn, $i_changesfn, @i_buildinfos); sub i_localname_parsed_changelog { return "remote-changelog.822"; @@ -4736,6 +4751,31 @@ sub i_localname_dsc { } sub i_file_dsc { } +sub i_localname_buildinfo ($) { + my $bi = $i_param{'buildinfo-filename'}; + defined $bi or badproto \*RO, "buildinfo before filename"; + defined $i_changesfn or badproto \*RO, "buildinfo before changes"; + $bi =~ m{^\Q$package\E_[!-.0-~]*\.buildinfo$}s + or badproto \*RO, "improper buildinfo filename"; + return $&; +} +sub i_file_buildinfo { + my $bi = $i_param{'buildinfo-filename'}; + my $bd = parsecontrol "$i_tmp/$bi", $bi; + my $ch = parsecontrol "$i_tmp/$i_changesfn", 'changes'; + if (!forceing [qw(buildinfo-changes-mismatch)]) { + files_compare_inputs($bd, $ch); + (getfield $bd, $_) eq (getfield $ch, $_) or + fail "buildinfo mismatch $_" + foreach qw(Source Version); + !defined $bd->{$_} or + fail "buildinfo contains $_" + foreach qw(Changes Changed-by Distribution); + } + push @i_buildinfos, $bi; + delete $i_param{'buildinfo-filename'}; +} + sub i_localname_changes { defined $i_dscfn or badproto \*RO, "dsc (before parsed-changelog)"; $i_changesfn = $i_dscfn; @@ -4777,7 +4817,7 @@ sub i_want_signed_tag { sub i_want_signed_dsc_changes { rename "$i_dscfn.tmp","$i_dscfn" or die "$i_dscfn $!"; sign_changes $i_changesfn; - return ($i_dscfn, $i_changesfn); + return ($i_dscfn, $i_changesfn, @i_buildinfos); } #---------- building etc. ---------- |