package catalogue import ( "strings" "testing" ) // No placement and no access at the machine's own system or the mesh's state, however it is spelled (novox/hq // issue 339); a module's own place elsewhere is taken. func TestAPlacementOrAnAccessAtTheMachinesOwnIsRefused(t *testing.T) { m := Manifest{Module: "notes", Resources: []map[string]any{{"id": "data", "type": "directory"}}, Accesses: []Access{{ID: "media"}}} for _, path := range []string{"/", "/etc", "/etc/", "/etc/sudoers.d", "/usr/bin", "/root", "/var", "/var/lib", "/home", "/home/", "/run", "/run/user/1000", "/var/lib/mesh/x", "/var/lib/mesh-host", "/var/lib/mesh-host/identity", "/srv/../etc", "//etc", "/proc/1", "/sys", "/dev", "/boot/efi", "/bin", "/sbin", "/lib", "/lib64"} { layers := []Layer{{From: "laptop", Values: map[string]any{PlacesSetting: map[string]any{"data": path}}}} if _, err := Places(m, layers); err == nil || !strings.Contains(err.Error(), "issue 339") { t.Errorf("a place at %s: %v", path, err) } layers = []Layer{{From: "laptop", Values: map[string]any{AccessesSetting: map[string]any{"media": path}}}} if _, err := AccessPlaces(m, layers); err == nil || !strings.Contains(err.Error(), "issue 339") { t.Errorf("an access at %s: %v", path, err) } } for _, path := range []string{"/srv/notes", "/mnt/plex/data", "/storage/media", "/services/media/movies", "/var/lib/notes/data", "/home/restic/repo", "/var/lib/mesh-store"} { layers := []Layer{{From: "laptop", Values: map[string]any{PlacesSetting: map[string]any{"data": path}}}} if got, err := Places(m, layers); err != nil || got["data"].Path != path { t.Errorf("a place at %s: %v %v", path, got, err) } layers = []Layer{{From: "laptop", Values: map[string]any{AccessesSetting: map[string]any{"media": path}}}} if got, err := AccessPlaces(m, layers); err != nil || got["media"] != path { t.Errorf("an access at %s: %v %v", path, got, err) } } } // A line break, a carriage return or a NUL in any string of any setting is refused, at any depth, keys too — // where a layer is judged, which is both where it is kept and where it is composed (novox/hq issue 339). func TestASettingHoldsOneLine(t *testing.T) { m := Manifest{Module: "mailu"} for _, v := range []any{"a\nDEBUG=1", "a\rb", "a\x00b", []any{"ok", "x\ny"}, map[string]any{"k": []any{"ok", map[string]any{"deep": "x\ny"}}}, map[string]any{"k\nx": "v"}} { if err := JudgeSettings(m, []Layer{{From: "home", Values: map[string]any{"v": v}}}, false); err == nil || !strings.Contains(err.Error(), "line break") { t.Errorf("%q: %v", v, err) } } if err := JudgeSettings(m, []Layer{{From: "home", Values: map[string]any{"v\nPATH": "x"}}}, false); err == nil { t.Error("a line break in a key was taken") } if err := JudgeSettings(m, []Layer{{From: "home", Values: map[string]any{"v": "one line", "n": 3.0, "l": []any{"a", "b"}}}}, false); err != nil { t.Errorf("one line each: %v", err) } } // PEM blocks alone may hold lines: a provider serves its authority's root as a setting. Anything around them, or // a line in them that is not base64, is refused. func TestAPEMBlockIsTheOneSettingWithLines(t *testing.T) { m := Manifest{Module: "route-proxy"} full := strings.Repeat("MIIB", 16) pem := "-----BEGIN CERTIFICATE-----\n" + full + "\n" + full + "\nAbCd+/==\n-----END CERTIFICATE-----\n" for _, ok := range []string{pem, pem + pem, strings.TrimSuffix(pem, "\n"), "-----BEGIN CERTIFICATE-----\nMIIBeDCCAR2gAwIBAgIQfake000000000000000000000000\n-----END CERTIFICATE-----\n"} { if err := JudgeSettings(m, []Layer{{From: "anchor", Values: map[string]any{"root": ok}}}, false); err != nil { t.Errorf("a PEM block: %v", err) } } for _, bad := range []string{ pem + "PATH=/tmp\n", "PATH=\n" + pem, "-----BEGIN CERTIFICATE-----\n" + full + "\nPATH=\n-----END CERTIFICATE-----\n", "-----BEGIN CERTIFICATE-----\nshort\n" + full + "\n-----END CERTIFICATE-----\n", "-----BEGIN CERTIFICATE-----\n" + full + "\n-----END KEY-----\n", "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----\n", "-----BEGIN CERTIFICATE-----\r\n" + full + "\r\n-----END CERTIFICATE-----\r\n", } { if err := JudgeSettings(m, []Layer{{From: "anchor", Values: map[string]any{"root": bad}}}, false); err == nil { t.Errorf("taken: %q", bad) } } }