package target import ( "errors" "io/fs" "os" "path/filepath" "strings" "golang.org/x/sys/unix" "proxyctl/internal/profile" ) // ReadOnlyWriteAuthority observes whether the current process can write the // configured locations. It never creates a probe file or changes permissions. func ReadOnlyWriteAuthority(paths ...string) Check { check := Check{Name: "write authority", OK: true} var evidence []string for _, path := range paths { ok, detail := readOnlyWritablePath(path) check.OK = check.OK && ok evidence = append(evidence, detail) } check.Evidence = profile.RedactText(strings.Join(evidence, "; ")) return check } func readOnlyWritablePath(path string) (bool, string) { candidate := filepath.Clean(path) for { info, err := os.Stat(candidate) if err == nil { if !info.IsDir() { candidate = filepath.Dir(candidate) } if err := unix.Access(candidate, unix.W_OK); err != nil { return false, candidate + " is not writable: " + err.Error() } return true, candidate + " is writable" } if !errors.Is(err, fs.ErrNotExist) { return false, candidate + " cannot be inspected: " + err.Error() } parent := filepath.Dir(candidate) if parent == candidate { return false, path + " has no writable existing ancestor" } candidate = parent } }