package store import ( "crypto/ed25519" "encoding/json" "errors" "os" "path/filepath" "strings" "testing" ) func signedBy(t *testing.T, body string) (ed25519.PublicKey, Declared) { t.Helper() public, private, err := ed25519.GenerateKey(nil) if err != nil { t.Fatal(err) } return public, Declared{ Declaration: []byte(body), Signature: ed25519.Sign(private, []byte(body)), } } func TestNothingDeclaredIsNotAFault(t *testing.T) { // A node that has enrolled and not yet been assigned anything has nothing to hold its machine // to, and that is an ordinary state — different from having lost what it was told. public, _ := signedBy(t, "{}") _, err := LoadDeclared(DeclaredPath(filepath.Join(t.TempDir(), "state.json")), public) if !errors.Is(err, ErrNothingDeclared) { t.Fatalf("a node that was never told anything gave %v", err) } } func TestWhatWasKeptIsWhatComesBack(t *testing.T) { path := DeclaredPath(filepath.Join(t.TempDir(), "state.json")) public, d := signedBy(t, `{"declaration":1,"resources":[]}`) if err := SaveDeclared(path, d); err != nil { t.Fatal(err) } back, err := LoadDeclared(path, public) if err != nil { t.Fatal(err) } if string(back) != string(d.Declaration) { t.Errorf("kept %q and read back %q", d.Declaration, back) } } func TestWhatWasKeptIsVerifiedAgainOnLoad(t *testing.T) { // This file is on a machine, and a node reading it back unverified would apply whatever is in // it. Anyone able to write it already has root — but the check costs nothing, and it means // the file is trusted for the same reason the message was rather than for being local. path := DeclaredPath(filepath.Join(t.TempDir(), "state.json")) public, d := signedBy(t, `{"declaration":1,"resources":[]}`) if err := SaveDeclared(path, d); err != nil { t.Fatal(err) } // Somebody edits it, keeping the signature. tampered, err := json.Marshal(Declared{ Declaration: []byte(`{"declaration":1,"resources":["something else"]}`), Signature: d.Signature, }) if err != nil { t.Fatal(err) } if err := os.WriteFile(path, tampered, 0o600); err != nil { t.Fatal(err) } if _, err := LoadDeclared(path, public); err == nil { t.Fatal("an edited declaration was read back and would have been applied") } } func TestAnotherMeshsDeclarationIsRefused(t *testing.T) { // The same check answers a second question: this node now believes a different signing key, // so what it kept is not this mesh's. Applying it would be applying something nobody in this // mesh said. path := DeclaredPath(filepath.Join(t.TempDir(), "state.json")) _, d := signedBy(t, `{"declaration":1}`) if err := SaveDeclared(path, d); err != nil { t.Fatal(err) } other, _ := signedBy(t, "unrelated") _, err := LoadDeclared(path, other) if err == nil { t.Fatal("a declaration signed by another mesh was accepted") } if !strings.Contains(err.Error(), "not signed by the mesh it joined") { t.Errorf("the refusal does not say what is wrong: %v", err) } } func TestWhatWasKeptIsNotWorldReadable(t *testing.T) { path := DeclaredPath(filepath.Join(t.TempDir(), "state.json")) _, d := signedBy(t, `{"declaration":1}`) if err := SaveDeclared(path, d); err != nil { t.Fatal(err) } info, err := os.Stat(path) if err != nil { t.Fatal(err) } if info.Mode().Perm()&0o077 != 0 { t.Errorf("what this node was told is mode %04o", info.Mode().Perm()) } } func TestKeepingLeavesNoHalfWrittenFile(t *testing.T) { dir := t.TempDir() path := DeclaredPath(filepath.Join(dir, "state.json")) _, d := signedBy(t, `{"declaration":1}`) for i := 0; i < 3; i++ { if err := SaveDeclared(path, d); err != nil { t.Fatal(err) } } entries, err := os.ReadDir(dir) if err != nil { t.Fatal(err) } for _, e := range entries { if strings.HasPrefix(e.Name(), ".declared-") { t.Errorf("a temporary file survived: %s", e.Name()) } } } func TestAnEmptyDeclarationIsNotKept(t *testing.T) { // It would read back as an instruction to own nothing, and a node that acted on it would // remove everything the mesh had given it. path := DeclaredPath(filepath.Join(t.TempDir(), "state.json")) if err := SaveDeclared(path, Declared{}); err == nil { t.Fatal("an empty declaration was kept") } }