aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/system.go
diff options
context:
space:
mode:
authorOphestra Umiker <cat@ophivana.moe>2024-10-23 21:46:21 +0900
committerOphestra Umiker <cat@ophivana.moe>2024-10-23 21:46:21 +0900
commit6bc5be7e5a2334274adf2945ad6d29d063a7086b (patch)
treed99223898a282b7ea40c41330b5748a3b5f2b310 /internal/system.go
parente35c5fe3ed995d352c001bd7e35bd1214ca583da (diff)
internal: wrap calls to os standard library functions
This change helps tests stub out and simulate OS behaviour during the sealing process. This also removes dependency on XDG_RUNTIME_DIR as the internal.System implementation provided to App provides a compat directory inside the tmpdir-based share when XDG_RUNTIME_DIR is unavailable. Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
Diffstat (limited to 'internal/system.go')
-rw-r--r--internal/system.go120
1 files changed, 120 insertions, 0 deletions
diff --git a/internal/system.go b/internal/system.go
new file mode 100644
index 00000000..6467ea05
--- /dev/null
+++ b/internal/system.go
@@ -0,0 +1,120 @@
+package internal
+
+import (
+ "io/fs"
+ "os"
+ "os/exec"
+ "os/user"
+ "path"
+ "strconv"
+ "sync"
+
+ "git.ophivana.moe/security/fortify/internal/fmsg"
+)
+
+// System provides safe access to operating system resources.
+type System interface {
+ // Geteuid provides [os.Geteuid].
+ Geteuid() 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)
+ // Executable provides [os.Executable].
+ Executable() (string, error)
+ // Lookup provides [user.Lookup].
+ Lookup(username string) (*user.User, error)
+ // ReadDir provides [os.ReadDir].
+ ReadDir(name string) ([]os.DirEntry, error)
+ // Stat provides [os.Stat].
+ Stat(name string) (fs.FileInfo, error)
+ // Open provides [os.Open]
+ Open(name string) (fs.File, error)
+ // Exit provides [os.Exit].
+ Exit(code int)
+
+ // Paths returns a populated [Paths] struct.
+ Paths() Paths
+}
+
+// Paths contains environment dependent paths used by fortify.
+type Paths struct {
+ // path to shared directory e.g. /tmp/fortify.%d
+ SharePath string `json:"share_path"`
+ // XDG_RUNTIME_DIR value e.g. /run/user/%d
+ RuntimePath string `json:"runtime_path"`
+ // application runtime directory e.g. /run/user/%d/fortify
+ RunDirPath string `json:"run_dir_path"`
+}
+
+// CopyPaths is a generic implementation of [System.Paths].
+func CopyPaths(os System, v *Paths) {
+ v.SharePath = path.Join(os.TempDir(), "fortify."+strconv.Itoa(os.Geteuid()))
+
+ fmsg.VPrintf("process share directory at %q", v.SharePath)
+
+ if r, ok := os.LookupEnv(xdgRuntimeDir); !ok {
+ // fall back to path in share since fortify has no hard XDG dependency
+ v.RunDirPath = path.Join(v.SharePath, "run")
+ v.RuntimePath = path.Join(v.RunDirPath, "compat")
+ } else {
+ v.RuntimePath = r
+ v.RunDirPath = path.Join(v.RuntimePath, "fortify")
+ }
+
+ fmsg.VPrintf("runtime directory at %q", v.RunDirPath)
+}
+
+// Std implements System using the standard library.
+type Std struct {
+ paths Paths
+ pathsOnce 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) {
+ os.Exit(code)
+}
+
+const xdgRuntimeDir = "XDG_RUNTIME_DIR"
+
+func (s *Std) Paths() Paths {
+ s.pathsOnce.Do(func() { CopyPaths(s, &s.paths) })
+ return s.paths
+}