diff options
author | Ian Jackson <ijackson@chiark.greenend.org.uk> | 2015-05-31 12:15:45 +0100 |
---|---|---|
committer | Ian Jackson <ijackson@chiark.greenend.org.uk> | 2015-05-31 12:57:18 +0100 |
commit | fb73b55ade7687b65727b1146b860ea892425cc6 (patch) | |
tree | 2be08d284c4420767f60f28a0b594c7013e00b00 /infra | |
parent | f040d41cc7411e08709a5e0ba97aa985589b4790 (diff) |
New approach to replay prevention - WIP
Diffstat (limited to 'infra')
-rwxr-xr-x | infra/dgit-repos-server | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/infra/dgit-repos-server b/infra/dgit-repos-server index e794de2..ab83136 100755 --- a/infra/dgit-repos-server +++ b/infra/dgit-repos-server @@ -632,10 +632,10 @@ sub checksuite () { } sub checktagnoreplay () { - # We check that the signed tag mentions the name and value of + # We check that the signed tag mentions the name and tag object id of # (a) in the case of FRESHREPO all tags in the repo; # (b) in the case of just NOFFCHECK all tags referring to - # the current head for the suite (there must be at least one). + # the current head for the suite (there must be at least one). # This prevents a replay attack using an earlier signed tag. return unless $policy & (FRESHREPO|NOFFCHECK); @@ -677,14 +677,29 @@ sub checktagnoreplay () { my @problems; git_for_each_tag_referring($onlyreferring, sub { - my ($objid,$refobjid,$fullrefname,$tagname) = @_; - printdebug "checktagnoreplay - overwriting $fullrefname=$objid\n"; + my ($tagobjid,$refobjid,$fullrefname,$tagname) = @_; + printdebug "checktagnoreplay - overwriting". + " $fullrefname=$tagobjid->$refobjid\n"; my $supers = $supersedes{$fullrefname}; if (!defined $supers) { - push @problems, "does not supersede $fullrefname"; - } elsif ($supers ne $objid) { + printdebug "checktagnoreply - fallbacks\n"; + my $super_fallback = 0; + foreach my $didsuper (sort keys %supersedes) { + my $didsuper_tagobjid = $supersedes{$didsuper}; + my $didsuper_refobjid = git_rev_parse $didsuper_tagobjid; + printdebug "checktagnoreply - fallback". + " $didsuper=$didsuper_refobjid->$didsuper_tagobjid\n"; + last if + $refobjid ne $didsuper_refobjid + and is_fast_fwd($refobjid, $didsuper_refobjid); + printdebug "checktagnoreply - fallback $didsuper OK\n"; + $super_fallback = 1; + } + push @problems, "does not supersede $fullrefname" + unless $super_fallback; + } elsif ($supers ne $tagobjid) { push @problems, - "supersedes $fullrefname=$supers but previously $fullrefname=$objid"; + "supersedes $fullrefname=$supers but previously $fullrefname=$tagobjid"; } else { # ok; } |