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 "os"
5 "sort"
6 "strings"
7
8 "github.com/carlosframework/platform/internal/hostbox"
9 "github.com/carlosframework/platform/internal/hostguard"
10 "github.com/carlosframework/platform/internal/registry"
11)
12
13func inventoryTimerNames(a hostguard.InstallationArtifacts) ([]string, error) {
14 if a.Schema != 1 || len(a.Timers) > 1<<20 {
15 return nil, os.ErrPermission
16 }
17 if a.Timers == "" {
18 return nil, nil
19 }
20 names := strings.Split(a.Timers, "\n")
21 if len(names) > 8192 {
22 return nil, os.ErrPermission
23 }
24 for i, name := range names {
25 if name == "" || name == "." || name == ".." || strings.ContainsAny(name, "/\\\r\x00") || (i > 0 && names[i-1] >= name) {
26 return nil, os.ErrPermission
27 }
28 }
29 return names, nil
30}
31
32func rootInventoryArtifacts(prior hostguard.RootInstallation, canonical registry.Route, in hostbox.StopInventory, revision uint64) (hostguard.InstallationArtifacts, error) {
33 a := prior.Artifacts
34 if a == (hostguard.InstallationArtifacts{}) {
35 // Only the independently checked first registration establishes absence.
36 // Older installations remain unknown; today's shape cannot reconstruct them.
37 if revision != 0 {
38 return a, nil
39 }
40 a.Schema = 1
41 }
42 names, err := inventoryTimerNames(a)
43 if err != nil {
44 return a, err
45 }
46 a.StateDirectory = a.StateDirectory || canonical.DBPath != ""
47 set := map[string]bool{}
48 for _, name := range names {
49 set[name] = true
50 }
51 for _, e := range in.Entries {
52 if e.Kind == "timer" {
53 set[strings.TrimPrefix(e.RelativePath, in.Host+"/")] = true
54 }
55 }
56 names = nil
57 for name := range set {
58 names = append(names, name)
59 }
60 sort.Strings(names)
61 a.Timers = strings.Join(names, "\n")
62 _, err = inventoryTimerNames(a)
63 return a, err
64}
65
66func (h ClaimRootHTTP) verifyInventoryTimers(in hostbox.StopInventory) error {
67 timers, err := h.Reconcile.Registry.TimersFor(in.Host)
68 if err != nil {
69 return err
70 }
71 if len(timers) > 8192 {
72 return hostbox.ErrTypedInventory
73 }
74 for _, timer := range timers {
75 found := false
76 for _, e := range in.Entries {
77 if e.Kind == "timer" && e.RelativePath == in.Host+"/"+timer.Name {
78 found = true
79 break
80 }
81 }
82 if !found {
83 return hostbox.ErrTypedInventory
84 }
85 }
86 return nil
87}
88
89func generationRetainedTimers(snapshot generationInventory) error {
90 for _, view := range snapshot.Installations {
91 names, err := inventoryTimerNames(view.Installation.Artifacts)
92 if err != nil {
93 return err
94 }
95 present := map[string]bool{}
96 for _, p := range snapshot.Payloads {
97 if p.Inventory.Host != view.Host {
98 continue
99 }
100 for _, e := range p.Inventory.Entries {
101 if e.Kind == "timer" {
102 present[strings.TrimPrefix(e.RelativePath, view.Host+"/")] = true
103 }
104 }
105 }
106 for _, name := range names {
107 if !present[name] {
108 return os.ErrPermission
109 }
110 }
111 }
112 return nil
113}
114