package host import ( "context" "testing" "github.com/carlosframework/platform/internal/hostguard" "github.com/carlosframework/platform/internal/instancectl" ) type plan14NamedLaunchUnits struct { *launchUnits host, unit string } func (u plan14NamedLaunchUnits) Placement(host string) (string, string, error) { if host != u.host { return "", "", instancectl.ErrClaimUnit } return u.unit, instancectl.BoundClaimUnitControlGroup(host, u.unit), nil } func TestPlan14NamedLaunchBindingGate(t *testing.T) { for _, attack := range []string{"none", "missing", "canonical before", "canonical at exec", "owner", "retiring", "wrong group"} { t.Run(attack, func(t *testing.T) { f, _, _ := generationLaunchFixture(t) unit := "plan14-bound.service" f.units.started.Unit = unit f.units.started.ControlGroup = instancectl.BoundClaimUnitControlGroup(f.target.Host, unit) f.req.Reservation.Group.RelativePath = f.units.started.ControlGroup f.root.Units = plan14NamedLaunchUnits{f.units, f.target.Host, unit} b, _, _ := plan14UnitBindingFixture(t, unit, "", "") in, err := f.root.Guard.Root.Installation(t.Context(), f.target.Host, hostguard.Captured{Incarnation: f.target.Incarnation, Stamp: f.target.Stamp}) if err != nil { t.Fatal(err) } shape := claimUnitShape{Host: in.Host, Account: in.Account, App: in.App, Kind: "instance", Unit: unit, Addr: "127.0.0.1:8090"} b.installation = func(context.Context, string) (hostguard.RootInstallation, error) { return in, nil } b.canonical = func(context.Context, string) (claimUnitShape, error) { return shape, nil } saved, err := b.establish(t.Context(), in.Host) if err != nil { t.Fatal(err) } f.root.unitBindings = b switch attack { case "missing": f.root.unitBindings = nil case "canonical before": shape.Unit = "replacement.service" case "canonical at exec": f.units.beforeCheck = func() { shape.Unit = "replacement.service" } case "owner": in.Stamp++ case "retiring": saved.Retiring = true if err := b.write(saved); err != nil { t.Fatal(err) } case "wrong group": f.req.Reservation.Group.RelativePath = instancectl.ClaimUnitControlGroup(f.target.Host) } _, err = f.root.Serve(t.Context(), f.peer, f.req) started, _ := f.units.counts() if attack == "none" { if err != nil || started != 1 { t.Fatal("bound launch", err, started) } } else if err == nil || started != 0 { t.Fatal("authority attack executed", err, started) } }) } }