aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/linux/std.go
blob: e0a0994ce2006d73de5f2f349524c54d4f7c9b50 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package linux

import (
	"errors"
	"io"
	"io/fs"
	"os"
	"os/exec"
	"os/user"
	"sync"

	"git.ophivana.moe/security/fortify/internal"
	"git.ophivana.moe/security/fortify/internal/fmsg"
)

// Std implements System using the standard library.
type Std struct {
	paths     Paths
	pathsOnce sync.Once

	sdBooted     bool
	sdBootedOnce sync.Once

	fshim     string
	fshimOnce sync.Once
}

func (s *Std) Geteuid() int                               { return os.Geteuid() }
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) Executable() (string, error)                { return os.Executable() }
func (s *Std) Lookup(username string) (*user.User, error) { return user.Lookup(username) }
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) Exit(code int)                              { fmsg.Exit(code) }
func (s *Std) Stdout() io.Writer                          { return os.Stdout }

const xdgRuntimeDir = "XDG_RUNTIME_DIR"

func (s *Std) FshimPath() string {
	s.fshimOnce.Do(func() {
		p, ok := internal.Path(internal.Fshim)
		if !ok {
			fmsg.Fatal("invalid fshim path, this copy of fortify is not compiled correctly")
		}
		s.fshim = p
	})

	return s.fshim
}

func (s *Std) Paths() Paths {
	s.pathsOnce.Do(func() { CopyPaths(s, &s.paths) })
	return s.paths
}

func (s *Std) SdBooted() bool {
	s.sdBootedOnce.Do(func() { s.sdBooted = copySdBooted() })
	return s.sdBooted
}

const systemdCheckPath = "/run/systemd/system"

func copySdBooted() bool {
	if v, err := sdBooted(); err != nil {
		fmsg.Println("cannot read systemd marker:", err)
		return false
	} else {
		return v
	}
}

func sdBooted() (bool, error) {
	_, err := os.Stat(systemdCheckPath)
	if err != nil {
		if errors.Is(err, fs.ErrNotExist) {
			err = nil
		}
		return false, err
	}

	return true, nil
}