package host import ( "os" "sort" "strings" "github.com/carlosframework/platform/internal/hostbox" "github.com/carlosframework/platform/internal/hostguard" "github.com/carlosframework/platform/internal/registry" ) func inventoryTimerNames(a hostguard.InstallationArtifacts) ([]string, error) { if a.Schema != 1 || len(a.Timers) > 1<<20 { return nil, os.ErrPermission } if a.Timers == "" { return nil, nil } names := strings.Split(a.Timers, "\n") if len(names) > 8192 { return nil, os.ErrPermission } for i, name := range names { if name == "" || name == "." || name == ".." || strings.ContainsAny(name, "/\\\r\x00") || (i > 0 && names[i-1] >= name) { return nil, os.ErrPermission } } return names, nil } func rootInventoryArtifacts(prior hostguard.RootInstallation, canonical registry.Route, in hostbox.StopInventory, revision uint64) (hostguard.InstallationArtifacts, error) { a := prior.Artifacts if a == (hostguard.InstallationArtifacts{}) { // Only the independently checked first registration establishes absence. // Older installations remain unknown; today's shape cannot reconstruct them. if revision != 0 { return a, nil } a.Schema = 1 } names, err := inventoryTimerNames(a) if err != nil { return a, err } a.StateDirectory = a.StateDirectory || canonical.DBPath != "" set := map[string]bool{} for _, name := range names { set[name] = true } for _, e := range in.Entries { if e.Kind == "timer" { set[strings.TrimPrefix(e.RelativePath, in.Host+"/")] = true } } names = nil for name := range set { names = append(names, name) } sort.Strings(names) a.Timers = strings.Join(names, "\n") _, err = inventoryTimerNames(a) return a, err } func (h ClaimRootHTTP) verifyInventoryTimers(in hostbox.StopInventory) error { timers, err := h.Reconcile.Registry.TimersFor(in.Host) if err != nil { return err } if len(timers) > 8192 { return hostbox.ErrTypedInventory } for _, timer := range timers { found := false for _, e := range in.Entries { if e.Kind == "timer" && e.RelativePath == in.Host+"/"+timer.Name { found = true break } } if !found { return hostbox.ErrTypedInventory } } return nil } func generationRetainedTimers(snapshot generationInventory) error { for _, view := range snapshot.Installations { names, err := inventoryTimerNames(view.Installation.Artifacts) if err != nil { return err } present := map[string]bool{} for _, p := range snapshot.Payloads { if p.Inventory.Host != view.Host { continue } for _, e := range p.Inventory.Entries { if e.Kind == "timer" { present[strings.TrimPrefix(e.RelativePath, view.Host+"/")] = true } } } for _, name := range names { if !present[name] { return os.ErrPermission } } } return nil }