carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1//go:build linux
2
3package host
4
5import (
6 "crypto/sha256"
7 "encoding/hex"
8 "fmt"
9 "os"
10 "path/filepath"
11 "testing"
12
13 "github.com/carlosframework/platform/internal/hostbox"
14 "github.com/carlosframework/platform/internal/hostguard"
15 "github.com/carlosframework/platform/internal/provision"
16 "golang.org/x/sys/unix"
17)
18
19func TestServingParkSourceUsesRootInventory(t *testing.T) {
20 t.Parallel()
21 for _, attack := range []string{"none", "unmaterialized", "duplicate", "owner", "revision", "enrollment", "record", "stamp", "foreign", "missing", "flat", "symlink", "replacement"} {
22 t.Run(attack, func(t *testing.T) {
23 f, _, _, inputs := servingRetirementFixture(t)
24 o := servingAdmit(t, f, &inputs, "G")
25 h := o.Claim.Holder
26 actor := hostbox.Actor{Box: "box-1", Region: "ie", Enrollment: "enrollment", Revision: 7, Binding: "7"}
27 root := hostguard.RootInstallation{Host: o.Host, Incarnation: h.Incarnation, Stamp: h.Stamp, Migration: 1, InventoryRevision: 3, Account: h.Account, App: h.App, Record: h.Key, Box: actor.Box, Enrollment: actor.Enrollment}
28 d, err := os.Open(filepath.Dir(inputs.DBPath))
29 if err != nil {
30 t.Fatal(err)
31 }
32 id, err := servingParkDirID(d)
33 d.Close()
34 if err != nil {
35 t.Fatal(err)
36 }
37 owner := sha256.Sum256([]byte(fmt.Sprintf("%s\x00%s\x00%d\x00%s", o.Host, h.Incarnation, h.Stamp, actor.Box)))
38 in := hostbox.StopInventory{Complete: true, Host: o.Host, Incarnation: h.Incarnation, InstallationStamp: h.Stamp, Box: actor.Box, Enrollment: actor.Enrollment, DirectoryRevision: "7", Entries: []hostbox.StopInventoryEntry{{Kind: "path", ManagedRoot: "data", RelativePath: "instances/" + provision.InstanceID(o.Host), ArtifactID: "state", Ownership: hex.EncodeToString(owner[:]), Materialization: "materialized", Device: id.Device, Inode: id.Inode, Type: unix.S_IFDIR}}}
39 switch attack {
40 case "unmaterialized":
41 in.Entries[0].Materialization = "intended"
42 case "duplicate":
43 in.Entries = append(in.Entries, in.Entries[0])
44 case "owner":
45 in.Entries[0].Ownership = "forged"
46 case "revision":
47 root.InventoryRevision++
48 case "enrollment":
49 actor.Enrollment = "foreign"
50 case "record":
51 root.Record = "foreign"
52 case "stamp":
53 root.Stamp++
54 case "foreign":
55 in.Host = "other.example"
56 case "missing":
57 in.Entries = nil
58 case "flat":
59 in.Entries[0].RelativePath = "state"
60 case "symlink", "replacement":
61 dir := filepath.Dir(inputs.DBPath)
62 if err := os.Rename(dir, dir+".original"); err != nil {
63 t.Fatal(err)
64 }
65 if attack == "symlink" {
66 err = os.Symlink(dir+".original", dir)
67 } else {
68 err = os.Mkdir(dir, 0700)
69 }
70 if err != nil {
71 t.Fatal(err)
72 }
73 }
74 got, err := servingParkStateDirectory(f.guard.DataDir, o, root, in, 3, actor)
75 if attack == "none" {
76 if err != nil || got != id {
77 t.Fatalf("source: %+v %v", got, err)
78 }
79 } else if err == nil {
80 t.Fatal("unproved source accepted")
81 }
82 })
83 }
84}
85