| 1 | package host |
| 2 | |
| 3 | import ( |
| 4 | "strings" |
| 5 | "testing" |
| 6 | |
| 7 | "github.com/carlosframework/platform/internal/instancectl" |
| 8 | "github.com/carlosframework/platform/internal/provision" |
| 9 | ) |
| 10 | |
| 11 | func TestPlan14BoundUnitDefinition(t *testing.T) { |
| 12 | _, _, shape := plan14UnitBindingFixture(t, "console.service", "", "") |
| 13 | shape.Program = strings.Repeat("a", 64) |
| 14 | for _, tcp := range []bool{true, false} { |
| 15 | if !tcp { |
| 16 | shape.Addr, shape.Socket = "", provision.NestedSocket(shape.Host) |
| 17 | } |
| 18 | raw, err := claimBoundUnitDefinition(shape) |
| 19 | if err != nil { |
| 20 | t.Fatal(err) |
| 21 | } |
| 22 | body := string(raw) |
| 23 | if !strings.Contains(body, "ExecStart=/usr/bin/false\n") || strings.Contains(body, "ExecStart=/opt/carlos/carlos instance-exec") || !strings.Contains(body, "Restart=no\n") || !strings.Contains(body, "Slice="+instancectl.SliceName(shape.Host)+"\n") || strings.Contains(body, "%I") || strings.Contains(body, "%i") { |
| 24 | t.Fatal("definition permits unreserved execution or foreign placement") |
| 25 | } |
| 26 | if strings.Contains(body, "IPAddressAllow=localhost") { |
| 27 | t.Fatal("broad loopback allowance") |
| 28 | } |
| 29 | if tcp && (!strings.Contains(body, "SocketBindDeny=any\n") || !strings.Contains(body, "SocketBindAllow=ipv4:tcp:8090\n")) { |
| 30 | t.Fatal("missing exact listener bind restriction") |
| 31 | } |
| 32 | if strings.Contains(body, "BindsTo=carlos-edge.service") { |
| 33 | t.Fatal("edge restart stops bound operator unit") |
| 34 | } |
| 35 | for _, setting := range []string{"ProtectControlGroups=yes", "PrivatePIDs=yes", "NoNewPrivileges=yes", "CapabilityBoundingSet=", "TemporaryFileSystem=/opt/carlos:ro"} { |
| 36 | if !strings.Contains(body, setting+"\n") { |
| 37 | t.Fatal("missing containment", setting) |
| 38 | } |
| 39 | } |
| 40 | } |
| 41 | shape.Host = "woodstar-media.example" |
| 42 | shape.Socket = provision.NestedSocket(shape.Host) |
| 43 | raw, err := claimBoundUnitDefinition(shape) |
| 44 | if err != nil { |
| 45 | t.Fatal(err) |
| 46 | } |
| 47 | if !strings.Contains(string(raw), "Slice="+instancectl.SliceName(shape.Host)+"\n") { |
| 48 | t.Fatal("named unit used unescaped slice") |
| 49 | } |
| 50 | } |
| 51 | |
| 52 | func TestPlan14FlatBoundSocketDefinition(t *testing.T) { |
| 53 | _, _, shape := plan14UnitBindingFixture(t, "woodstar-media.service", "", "/run/carlos/woodstar-media.sock") |
| 54 | shape.Program = strings.Repeat("a", 64) |
| 55 | raw, err := claimBoundUnitDefinition(shape) |
| 56 | if err != nil { |
| 57 | t.Fatal(err) |
| 58 | } |
| 59 | own := provision.InstanceRunDir(shape.Host) |
| 60 | if !strings.Contains(string(raw), "BindPaths="+own+":/run/carlos\n") || !strings.Contains(string(raw), "ReadWritePaths=/run/carlos\n") { |
| 61 | t.Fatal("flat path has no private run view") |
| 62 | } |
| 63 | if strings.Contains(string(raw), "BindPaths=/run/carlos:/run/carlos") || strings.Contains(string(raw), "TemporaryFileSystem=/run/carlos:ro") { |
| 64 | t.Fatal("flat socket exposes siblings") |
| 65 | } |
| 66 | for _, socket := range []string{"/run/carlos/../other.sock", "/run/carlos/other/path.sock", "/run/carlos/space name.sock", "/run/carlos/percent%name.sock", "/elsewhere/app.sock"} { |
| 67 | shape.Socket = socket |
| 68 | if _, err := claimBoundUnitDefinition(shape); err == nil { |
| 69 | t.Fatal("unsafe socket", socket) |
| 70 | } |
| 71 | } |
| 72 | } |
| 73 | |
| 74 | func TestPlan14BoundTemplateNotBootstrapped(t *testing.T) { |
| 75 | names, err := unitNames() |
| 76 | if err != nil { |
| 77 | t.Fatal(err) |
| 78 | } |
| 79 | for _, name := range names { |
| 80 | if name == "carlos-claim-bound.service" { |
| 81 | t.Fatal("claim template changes no-census bootstrap") |
| 82 | } |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | func TestPlan14MappedLoopbackDefinition(t *testing.T) { |
| 87 | _, _, s := plan14UnitBindingFixture(t, "console.service", "", "") |
| 88 | s.Program = strings.Repeat("a", 64) |
| 89 | s.Addr = "[::ffff:127.0.0.1]:8090" |
| 90 | raw, err := claimBoundUnitDefinition(s) |
| 91 | if err != nil { |
| 92 | t.Fatal(err) |
| 93 | } |
| 94 | if !strings.Contains(string(raw), "IPAddressAllow=127.0.0.1/32\n") || strings.Contains(string(raw), "IPAddressAllow=::ffff") { |
| 95 | t.Fatal("mapped address broadened IPv6 allowance") |
| 96 | } |
| 97 | } |
| 98 | |