carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package host
2
3import (
4 "context"
5 "encoding/json"
6 "testing"
7 "time"
8
9 "github.com/carlosframework/platform/internal/hostclaim"
10 "github.com/carlosframework/platform/internal/hostguard"
11 "github.com/carlosframework/platform/internal/provision"
12 "github.com/carlosframework/platform/internal/registry"
13 "github.com/carlosframework/platform/internal/release"
14)
15
16func TestPlan14RootDispatchRejectsRegistryMutation(t *testing.T) {
17 t.Parallel()
18 t.Run("protected-passes", testPlan14RootProtectedDispatch)
19 for _, attack := range []string{"none", "account", "app", "unit", "backing", "delete", "record owner", "claim owner", "missing installation"} {
20 t.Run(attack, func(t *testing.T) {
21 store := release.NewDirStore(t.TempDir())
22 rec := provision.Record{Schema: 1, Host: "shop.example.com", Account: "bab", App: "shop", Channel: "stable", CreatedAt: time.Date(2026, 10, 1, 0, 0, 0, 0, time.UTC)}
23 plan14PutRecord(t, store, rec)
24 inc, err := hostclaim.Incarnation(rec.Account, rec.App, rec.Host, rec.CreatedAt)
25 if err != nil {
26 t.Fatal(err)
27 }
28 claim := &hostclaim.Claim{Host: rec.Host, Holder: &hostclaim.Holder{Key: provision.RecordKey(rec.Account, rec.App, rec.Host), Account: rec.Account, App: rec.App, Incarnation: inc, Stamp: 1, Session: 1, WriterBox: "box"}}
29 g := hostguard.Guard{DataDir: t.TempDir(), LockDir: t.TempDir(), Claims: rootViewClaimReader{obs: hostclaim.Observed{Host: rec.Host, ETag: "claim", Claim: claim}}, Root: hostguard.NewRootAuthority(&rollbackMemory{files: map[string][]byte{}})}
30 if attack != "missing installation" {
31 in := hostguard.RootInstallation{Host: rec.Host, Incarnation: inc, Account: rec.Account, App: rec.App, Stamp: 1, Migration: 1, Record: claim.Holder.Key, Box: "box", Enrollment: "enroll"}
32 if err := g.EstablishRoot(t.Context(), in, func(*hostclaim.Claim) error { return nil }); err != nil {
33 t.Fatal(err)
34 }
35 }
36 reg := restartTestRegistry(t)
37 row := registry.Route{Host: rec.Host, Account: rec.Account, App: rec.App}
38 switch attack {
39 case "account":
40 row.Account = "bap"
41 case "app":
42 row.App = "other"
43 case "unit":
44 row.Unit = "other.service"
45 case "backing":
46 row.Backing = registry.BackingUnit
47 case "record owner":
48 rec.App = "other"
49 plan14PutRecord(t, store, rec)
50 case "claim owner":
51 claim.Holder.App = "other"
52 }
53 if attack != "delete" {
54 if err := reg.Upsert(row); err != nil {
55 t.Fatal(err)
56 }
57 }
58 acct, app, err := rootInstallationHostApp(g, store)(rec.Host)
59 refused := attack == "record owner" || attack == "claim owner" || attack == "missing installation"
60 if refused {
61 if err == nil {
62 t.Fatal("unbound root dispatch")
63 }
64 return
65 }
66 if err != nil || acct != "bab" || app != "shop" {
67 t.Fatalf("root installation dispatch: %q %q %v", acct, app, err)
68 }
69 })
70 }
71}
72
73type rootViewClaimReader struct{ obs hostclaim.Observed }
74
75func (r rootViewClaimReader) Read(context.Context, string) (hostclaim.Observed, error) {
76 return r.obs, nil
77}
78
79func TestPlan14RootSidecarBinding(t *testing.T) {
80 for _, attack := range []string{"none", "account", "app", "host", "name", "key", "incarnation", "missing"} {
81 t.Run(attack, func(t *testing.T) {
82 store := release.NewDirStore(t.TempDir())
83 rec := provision.SidecarRecord{Schema: 1, Name: "worker", Host: provision.SidecarHost("worker", "shop", "bab"), Account: "bab", App: "shop", Channel: "stable", CreatedAt: time.Date(2026, 10, 1, 0, 0, 0, 0, time.UTC)}
84 key := provision.SidecarRecordKey(rec.Account, rec.App, rec.Name)
85 inc, err := hostclaim.Incarnation(rec.Account, rec.App, rec.Host, rec.CreatedAt)
86 if err != nil {
87 t.Fatal(err)
88 }
89 c := &hostclaim.Claim{Host: rec.Host, Holder: &hostclaim.Holder{Family: "sidecar", Key: key, Name: rec.Name, Account: rec.Account, App: rec.App, Incarnation: inc}}
90 switch attack {
91 case "account":
92 rec.Account = "other"
93 case "app":
94 rec.App = "other"
95 case "host":
96 rec.Host = "other.example"
97 case "name":
98 rec.Name = "other"
99 case "key":
100 c.Holder.Key = "apps/other/shop/sidecars/worker.json"
101 case "incarnation":
102 c.Holder.Incarnation = "other"
103 }
104 if attack != "missing" {
105 body, _ := json.Marshal(rec)
106 if _, err := store.Put(t.Context(), key, body, ""); err != nil {
107 t.Fatal(err)
108 }
109 }
110 row, etag, err := rootClaimRecord(t.Context(), store, c, t.TempDir())
111 if attack != "none" {
112 if err == nil {
113 t.Fatal("forged sidecar bound")
114 }
115 return
116 }
117 if err != nil || etag == "" || !row.IsSidecar() || row.Account != "bab" || row.App != "shop" || row.Socket != "" || row.Addr != "" {
118 t.Fatal(row, etag, err)
119 }
120 })
121 }
122}
123