package sandbox import ( "fmt" "os" "sort" ) // pathEntry holds a path with its permission type type pathEntry struct { path string flag string // --ro, --rox, --rw, --rwx } // isAvailableFn is overridable for testing. var ( isAvailableFn = isAvailable ) // ErrNotAvailable is returned when landrun is not found on the system. var ErrNotAvailable = fmt.Errorf("SANDBOX FAILURE: landrun is not installed or not in PATH — shell CANNOT run without it") // WrapCommand wraps a command with landrun based on the configuration. // Returns an error if landrun is not available. func WrapCommand(cfg *Config, originalCmd []string, cwd string, getenv EnvFunc) ([]string, error) { if !isAvailableFn() { return nil, ErrNotAvailable } args := []string{"landrun"} if cfg.General.LogLevel != "" { args = append(args, "--log-level", cfg.General.LogLevel) } if cfg.General.BestEffort { args = append(args, "--best-effort") } if cfg.Advanced.LDD { args = append(args, "--ldd") } if cfg.Advanced.AddExec { args = append(args, "--add-exec") } var entries []pathEntry addPaths := func(paths []string, flag string) { for _, path := range paths { p := expandPath(path, cwd, getenv) if p != "" && pathExists(p) { entries = append(entries, pathEntry{p, flag}) } } } addPaths(cfg.Filesystem.RO, "--ro") addPaths(cfg.Filesystem.ROX, "--rox") addPaths(cfg.Filesystem.RW, "--rw") addPaths(cfg.Filesystem.RWX, "--rwx") // Sort so parents come before children sort.Slice(entries, func(i, j int) bool { if len(entries[i].path) != len(entries[j].path) { return len(entries[i].path) < len(entries[j].path) } return entries[i].path < entries[j].path }) for _, e := range entries { args = append(args, e.flag, e.path) } if cfg.Network.Unrestricted { args = append(args, "--unrestricted-network") } else if cfg.Network.Enabled { for _, port := range cfg.Network.BindTCP { args = append(args, "--bind-tcp", port) } for _, port := range cfg.Network.ConnectTCP { args = append(args, "--connect-tcp", port) } } for _, name := range cfg.Env { args = append(args, "--env", name) } args = append(args, "--") args = append(args, originalCmd...) return args, nil } // pathExists checks if a file or directory exists func pathExists(path string) bool { _, err := os.Stat(path) return err == nil }