diff options
Diffstat (limited to 'internal/sys')
| -rw-r--r-- | internal/sys/hsu.go | 88 | ||||
| -rw-r--r-- | internal/sys/interface.go | 76 | ||||
| -rw-r--r-- | internal/sys/std.go | 44 |
3 files changed, 0 insertions, 208 deletions
diff --git a/internal/sys/hsu.go b/internal/sys/hsu.go deleted file mode 100644 index 5ae12046..00000000 --- a/internal/sys/hsu.go +++ /dev/null @@ -1,88 +0,0 @@ -package sys - -import ( - "errors" - "fmt" - "log" - "os" - "os/exec" - "strconv" - "sync" - - "hakurei.app/container" - "hakurei.app/hst" - "hakurei.app/internal" - "hakurei.app/internal/hlog" -) - -// Hsu caches responses from cmd/hsu. -type Hsu struct { - idOnce sync.Once - idErr error - id int -} - -var ErrHsuAccess = errors.New("current user is not in the hsurc file") - -// ID returns the current user hsurc identifier. ErrHsuAccess is returned if the current user is not in hsurc. -func (h *Hsu) ID() (int, error) { - h.idOnce.Do(func() { - h.id = -1 - hsuPath := internal.MustHsuPath() - - cmd := exec.Command(hsuPath) - cmd.Path = hsuPath - cmd.Stderr = os.Stderr // pass through fatal messages - cmd.Env = make([]string, 0) - cmd.Dir = container.FHSRoot - var ( - p []byte - exitError *exec.ExitError - ) - - const step = "obtain uid from hsu" - if p, h.idErr = cmd.Output(); h.idErr == nil { - h.id, h.idErr = strconv.Atoi(string(p)) - if h.idErr != nil { - h.idErr = &hst.AppError{Step: step, Err: h.idErr, Msg: "invalid uid string from hsu"} - } - } else if errors.As(h.idErr, &exitError) && exitError != nil && exitError.ExitCode() == 1 { - // hsu prints an error message in this case - h.idErr = &hst.AppError{Step: step, Err: ErrHsuAccess} - } else if os.IsNotExist(h.idErr) { - h.idErr = &hst.AppError{Step: step, Err: os.ErrNotExist, - Msg: fmt.Sprintf("the setuid helper is missing: %s", hsuPath)} - } - }) - - return h.id, h.idErr -} - -func (h *Hsu) Uid(identity int) (int, error) { - id, err := h.ID() - if err == nil { - return 1000000 + id*10000 + identity, nil - } - return id, err -} - -// MustUid calls [State.Uid] and terminates on error. -func MustUid(s State, identity int) int { - uid, err := s.Uid(identity) - if err == nil { - return uid - } - - const fallback = "cannot obtain uid from setuid wrapper:" - if errors.Is(err, ErrHsuAccess) { - hlog.Verbose("*"+fallback, err) - os.Exit(1) - return -0xdeadbeef - } else if m, ok := container.GetErrorMessage(err); ok { - log.Fatal(m) - return -0xdeadbeef - } else { - log.Fatalln(fallback, err) - return -0xdeadbeef - } -} diff --git a/internal/sys/interface.go b/internal/sys/interface.go deleted file mode 100644 index f2465e62..00000000 --- a/internal/sys/interface.go +++ /dev/null @@ -1,76 +0,0 @@ -// Package sys wraps OS interaction library functions. -package sys - -import ( - "io/fs" - "log" - "os/user" - "strconv" - - "hakurei.app/container" - "hakurei.app/hst" - "hakurei.app/internal/hlog" -) - -// State provides safe interaction with operating system state. -type State interface { - // Getuid provides [os.Getuid]. - Getuid() int - // Getgid provides [os.Getgid]. - Getgid() int - // LookupEnv provides [os.LookupEnv]. - LookupEnv(key string) (string, bool) - // TempDir provides [os.TempDir]. - TempDir() string - // LookPath provides exec.LookPath. - LookPath(file string) (string, error) - // MustExecutable provides [container.MustExecutable]. - MustExecutable() string - // LookupGroup provides [user.LookupGroup]. - LookupGroup(name string) (*user.Group, error) - // ReadDir provides [os.ReadDir]. - ReadDir(name string) ([]fs.DirEntry, error) - // Stat provides [os.Stat]. - Stat(name string) (fs.FileInfo, error) - // Open provides [os.Open]. - Open(name string) (fs.File, error) - // EvalSymlinks provides filepath.EvalSymlinks. - EvalSymlinks(path string) (string, error) - // Exit provides [os.Exit]. - Exit(code int) - - Println(v ...any) - Printf(format string, v ...any) - - // Paths returns a populated [hst.Paths] struct. - Paths() hst.Paths - // Uid invokes hsu and returns target uid. - // Any errors returned by Uid is already wrapped [hlog.BaseError]. - Uid(identity int) (int, error) -} - -// MustGetUserID obtains user id from hsu by querying uid of identity 0. -func MustGetUserID(os State) int { return (MustUid(os, 0) / 10000) - 100 } - -// CopyPaths is a generic implementation of [hst.Paths]. -func CopyPaths(os State, v *hst.Paths, userid int) { - if tempDir, err := container.NewAbs(os.TempDir()); err != nil { - log.Fatalf("invalid TMPDIR: %v", err) - } else { - v.TempDir = tempDir - } - - v.SharePath = v.TempDir.Append("hakurei." + strconv.Itoa(userid)) - hlog.Verbosef("process share directory at %q", v.SharePath) - - r, _ := os.LookupEnv(xdgRuntimeDir) - if a, err := container.NewAbs(r); err != nil { - // fall back to path in share since hakurei has no hard XDG dependency - v.RunDirPath = v.SharePath.Append("run") - v.RuntimePath = v.RunDirPath.Append("compat") - } else { - v.RuntimePath = a - v.RunDirPath = v.RuntimePath.Append("hakurei") - } - hlog.Verbosef("runtime directory at %q", v.RunDirPath) -} diff --git a/internal/sys/std.go b/internal/sys/std.go deleted file mode 100644 index 11334c72..00000000 --- a/internal/sys/std.go +++ /dev/null @@ -1,44 +0,0 @@ -package sys - -import ( - "io/fs" - "os" - "os/exec" - "os/user" - "path/filepath" - "sync" - - "hakurei.app/container" - "hakurei.app/hst" - "hakurei.app/internal" - "hakurei.app/internal/hlog" -) - -// Std implements System using the standard library. -type Std struct { - paths hst.Paths - pathsOnce sync.Once - Hsu -} - -func (s *Std) Getuid() int { return os.Getuid() } -func (s *Std) Getgid() int { return os.Getgid() } -func (s *Std) LookupEnv(key string) (string, bool) { return os.LookupEnv(key) } -func (s *Std) TempDir() string { return os.TempDir() } -func (s *Std) LookPath(file string) (string, error) { return exec.LookPath(file) } -func (s *Std) MustExecutable() string { return container.MustExecutable() } -func (s *Std) LookupGroup(name string) (*user.Group, error) { return user.LookupGroup(name) } -func (s *Std) ReadDir(name string) ([]os.DirEntry, error) { return os.ReadDir(name) } -func (s *Std) Stat(name string) (fs.FileInfo, error) { return os.Stat(name) } -func (s *Std) Open(name string) (fs.File, error) { return os.Open(name) } -func (s *Std) EvalSymlinks(path string) (string, error) { return filepath.EvalSymlinks(path) } -func (s *Std) Exit(code int) { internal.Exit(code) } -func (s *Std) Println(v ...any) { hlog.Verbose(v...) } -func (s *Std) Printf(format string, v ...any) { hlog.Verbosef(format, v...) } - -const xdgRuntimeDir = "XDG_RUNTIME_DIR" - -func (s *Std) Paths() hst.Paths { - s.pathsOnce.Do(func() { CopyPaths(s, &s.paths, MustGetUserID(s)) }) - return s.paths -} |
