aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/app/launch.machinectl.go4
-rw-r--r--internal/app/launch.sudo.go4
-rw-r--r--internal/app/seal.go5
-rw-r--r--internal/app/start.go18
-rw-r--r--internal/early.go5
-rw-r--r--internal/environ.go9
-rw-r--r--internal/fmsg/fmsg.go39
-rw-r--r--internal/fmsg/verbose.go21
-rw-r--r--internal/init/main.go38
-rw-r--r--internal/shim/main.go49
-rw-r--r--internal/shim/parent.go25
-rw-r--r--internal/state/print.go20
-rw-r--r--internal/system/acl.go9
-rw-r--r--internal/system/dbus.go32
-rw-r--r--internal/system/mkdir.go7
-rw-r--r--internal/system/op.go5
-rw-r--r--internal/system/tmpfiles.go11
-rw-r--r--internal/system/xhost.go7
-rw-r--r--internal/verbose/print.go19
-rw-r--r--internal/verbose/print_test.go67
-rw-r--r--internal/verbose/state.go13
-rw-r--r--internal/verbose/state_test.go20
22 files changed, 173 insertions, 254 deletions
diff --git a/internal/app/launch.machinectl.go b/internal/app/launch.machinectl.go
index c06e8a6c..32f06740 100644
--- a/internal/app/launch.machinectl.go
+++ b/internal/app/launch.machinectl.go
@@ -4,7 +4,7 @@ import (
"os/exec"
"strings"
- "git.ophivana.moe/security/fortify/internal/verbose"
+ "git.ophivana.moe/security/fortify/internal/fmsg"
)
func (a *app) commandBuilderMachineCtl(shimEnv string) (args []string) {
@@ -14,7 +14,7 @@ func (a *app) commandBuilderMachineCtl(shimEnv string) (args []string) {
args = append(args, "shell", "--uid="+a.seal.sys.user.Username)
// --quiet
- if !verbose.Get() {
+ if !fmsg.Verbose() {
args = append(args, "--quiet")
}
diff --git a/internal/app/launch.sudo.go b/internal/app/launch.sudo.go
index 129ef328..2df7be0f 100644
--- a/internal/app/launch.sudo.go
+++ b/internal/app/launch.sudo.go
@@ -3,7 +3,7 @@ package app
import (
"os"
- "git.ophivana.moe/security/fortify/internal/verbose"
+ "git.ophivana.moe/security/fortify/internal/fmsg"
)
const (
@@ -18,7 +18,7 @@ func (a *app) commandBuilderSudo(shimEnv string) (args []string) {
// -A?
if _, ok := os.LookupEnv(sudoAskPass); ok {
- verbose.Printf("%s set, adding askpass flag\n", sudoAskPass)
+ fmsg.VPrintln(sudoAskPass, "set, adding askpass flag")
args = append(args, "-A")
}
diff --git a/internal/app/seal.go b/internal/app/seal.go
index 7de6aecb..f0fe5582 100644
--- a/internal/app/seal.go
+++ b/internal/app/seal.go
@@ -14,7 +14,6 @@ import (
"git.ophivana.moe/security/fortify/internal/shim"
"git.ophivana.moe/security/fortify/internal/state"
"git.ophivana.moe/security/fortify/internal/system"
- "git.ophivana.moe/security/fortify/internal/verbose"
)
const (
@@ -152,7 +151,7 @@ func (a *app) Seal(config *Config) error {
// map sandbox config to bwrap
if config.Confinement.Sandbox == nil {
- verbose.Println("sandbox configuration not supplied, PROCEED WITH CAUTION")
+ fmsg.VPrintln("sandbox configuration not supplied, PROCEED WITH CAUTION")
// permissive defaults
conf := &SandboxConfig{
@@ -242,7 +241,7 @@ func (a *app) Seal(config *Config) error {
}
// verbose log seal information
- verbose.Println("created application seal as user",
+ fmsg.VPrintln("created application seal as user",
seal.sys.user.Username, "("+seal.sys.user.Uid+"),",
"method:", config.Method+",",
"launcher:", seal.toolPath+",",
diff --git a/internal/app/start.go b/internal/app/start.go
index 3106a1e8..b6c94041 100644
--- a/internal/app/start.go
+++ b/internal/app/start.go
@@ -7,7 +7,6 @@ import (
"os/exec"
"path"
"path/filepath"
- "strconv"
"strings"
"time"
@@ -16,7 +15,6 @@ import (
"git.ophivana.moe/security/fortify/internal/shim"
"git.ophivana.moe/security/fortify/internal/state"
"git.ophivana.moe/security/fortify/internal/system"
- "git.ophivana.moe/security/fortify/internal/verbose"
)
// Start starts the fortified child
@@ -71,14 +69,14 @@ func (a *app) Start() error {
Bwrap: a.seal.sys.bwrap,
WL: a.seal.wl != nil,
- Verbose: verbose.Get(),
+ Verbose: fmsg.Verbose(),
}, a.seal.wl); err != nil {
return fmsg.WrapErrorSuffix(err,
"cannot serve shim setup:")
}
// start shim
- verbose.Println("starting shim as target user:", a.cmd)
+ fmsg.VPrintln("starting shim as target user:", a.cmd)
if err := a.cmd.Start(); err != nil {
return fmsg.WrapErrorSuffix(err,
"cannot start process:")
@@ -178,12 +176,12 @@ func (a *app) Wait() (int, error) {
r = a.cmd.ProcessState.ExitCode()
}
- verbose.Println("process", strconv.Itoa(a.cmd.Process.Pid), "exited with exit code", r)
+ fmsg.VPrintf("process %d exited with exit code %d", a.cmd.Process.Pid, r)
// close wayland connection
if a.seal.wl != nil {
if err := a.seal.wl.Close(); err != nil {
- fmt.Println("fortify: cannot close wayland connection:", err)
+ fmsg.Println("cannot close wayland connection:", err)
}
}
@@ -205,10 +203,10 @@ func (a *app) Wait() (int, error) {
} else {
if l := len(states); l == 0 {
// cleanup globals as the final launcher
- verbose.Println("no other launchers active, will clean up globals")
+ fmsg.VPrintln("no other launchers active, will clean up globals")
ec.Set(system.User)
} else {
- verbose.Printf("found %d active launchers, cleaning up without globals\n", l)
+ fmsg.VPrintf("found %d active launchers, cleaning up without globals", l)
}
// accumulate capabilities of other launchers
@@ -222,7 +220,7 @@ func (a *app) Wait() (int, error) {
ec.Set(i)
}
}
- if verbose.Get() {
+ if fmsg.Verbose() {
labels := make([]string, 0, system.ELen+1)
for i := system.Enablement(0); i < system.Enablement(system.ELen+2); i++ {
if ec.Has(i) {
@@ -230,7 +228,7 @@ func (a *app) Wait() (int, error) {
}
}
if len(labels) > 0 {
- verbose.Println("reverting operations labelled", strings.Join(labels, ", "))
+ fmsg.VPrintln("reverting operations labelled", strings.Join(labels, ", "))
}
}
diff --git a/internal/early.go b/internal/early.go
index 218105f2..81ca49cd 100644
--- a/internal/early.go
+++ b/internal/early.go
@@ -2,9 +2,10 @@ package internal
import (
"errors"
- "fmt"
"io/fs"
"os"
+
+ "git.ophivana.moe/security/fortify/internal/fmsg"
)
const (
@@ -13,7 +14,7 @@ const (
var SdBootedV = func() bool {
if v, err := SdBooted(); err != nil {
- fmt.Println("warn: read systemd marker:", err)
+ fmsg.Println("cannot read systemd marker:", err)
return false
} else {
return v
diff --git a/internal/environ.go b/internal/environ.go
index 441c74ae..8f03cb34 100644
--- a/internal/environ.go
+++ b/internal/environ.go
@@ -1,13 +1,12 @@
package internal
import (
- "fmt"
"os"
"path"
"strconv"
"sync"
- "git.ophivana.moe/security/fortify/internal/verbose"
+ "git.ophivana.moe/security/fortify/internal/fmsg"
)
// state that remain constant for the lifetime of the process
@@ -37,16 +36,16 @@ func copySC() {
SharePath: path.Join(os.TempDir(), "fortify."+strconv.Itoa(os.Geteuid())),
}
- verbose.Println("process share directory at", sc.SharePath)
+ fmsg.VPrintf("process share directory at %q", sc.SharePath)
// runtimePath, runDirPath
if r, ok := os.LookupEnv(xdgRuntimeDir); !ok {
- fmt.Println("Env variable", xdgRuntimeDir, "unset")
+ fmsg.Println("variable", xdgRuntimeDir, "unset")
os.Exit(1)
} else {
sc.RuntimePath = r
sc.RunDirPath = path.Join(sc.RuntimePath, "fortify")
- verbose.Println("XDG runtime directory at", sc.RunDirPath)
+ fmsg.VPrintf("XDG runtime directory at %q", sc.RunDirPath)
}
scVal = sc
diff --git a/internal/fmsg/fmsg.go b/internal/fmsg/fmsg.go
index 40d34108..c72913f8 100644
--- a/internal/fmsg/fmsg.go
+++ b/internal/fmsg/fmsg.go
@@ -1,2 +1,41 @@
// Package fmsg provides various functions for output messages.
package fmsg
+
+import (
+ "log"
+ "os"
+ "sync/atomic"
+)
+
+var (
+ std = log.New(os.Stdout, "fortify: ", 0)
+ warn = log.New(os.Stderr, "fortify: ", 0)
+
+ verbose = new(atomic.Bool)
+)
+
+func SetPrefix(prefix string) {
+ prefix += ": "
+ std.SetPrefix(prefix)
+ warn.SetPrefix(prefix)
+}
+
+func Print(v ...any) {
+ warn.Print(v...)
+}
+
+func Printf(format string, v ...any) {
+ warn.Printf(format, v...)
+}
+
+func Println(v ...any) {
+ warn.Println(v...)
+}
+
+func Fatal(v ...any) {
+ warn.Fatal(v...)
+}
+
+func Fatalf(format string, v ...any) {
+ warn.Fatalf(format, v...)
+}
diff --git a/internal/fmsg/verbose.go b/internal/fmsg/verbose.go
new file mode 100644
index 00000000..36faadeb
--- /dev/null
+++ b/internal/fmsg/verbose.go
@@ -0,0 +1,21 @@
+package fmsg
+
+func Verbose() bool {
+ return verbose.Load()
+}
+
+func SetVerbose(v bool) {
+ verbose.Store(v)
+}
+
+func VPrintf(format string, v ...any) {
+ if verbose.Load() {
+ std.Printf(format, v...)
+ }
+}
+
+func VPrintln(v ...any) {
+ if verbose.Load() {
+ std.Println(v...)
+ }
+}
diff --git a/internal/init/main.go b/internal/init/main.go
index d0d81054..7a340a8e 100644
--- a/internal/init/main.go
+++ b/internal/init/main.go
@@ -4,7 +4,6 @@ import (
"encoding/gob"
"errors"
"flag"
- "fmt"
"os"
"os/exec"
"os/signal"
@@ -13,7 +12,7 @@ import (
"syscall"
"time"
- "git.ophivana.moe/security/fortify/internal/verbose"
+ "git.ophivana.moe/security/fortify/internal/fmsg"
)
const (
@@ -25,49 +24,46 @@ const (
// proceed with caution!
func doInit(fd uintptr) {
+ fmsg.SetPrefix("init")
+
// re-exec
if len(os.Args) > 0 && os.Args[0] != "fortify" && path.IsAbs(os.Args[0]) {
if err := syscall.Exec(os.Args[0], []string{"fortify", "init"}, os.Environ()); err != nil {
- fmt.Println("fortify-init: cannot re-exec self:", err)
+ fmsg.Println("cannot re-exec self:", err)
// continue anyway
}
}
- verbose.Prefix = "fortify-init:"
-
var payload Payload
p := os.NewFile(fd, "config-stream")
if p == nil {
- fmt.Println("fortify-init: invalid config descriptor")
- os.Exit(1)
+ fmsg.Fatal("invalid config descriptor")
}
if err := gob.NewDecoder(p).Decode(&payload); err != nil {
- fmt.Println("fortify-init: cannot decode init payload:", err)
- os.Exit(1)
+ fmsg.Fatal("cannot decode init payload:", err)
} else {
// sharing stdout with parent
// USE WITH CAUTION
- verbose.Set(payload.Verbose)
+ fmsg.SetVerbose(payload.Verbose)
// child does not need to see this
if err = os.Unsetenv(EnvInit); err != nil {
- fmt.Println("fortify-init: cannot unset", EnvInit+":", err)
+ fmsg.Println("cannot unset", EnvInit+":", err)
// not fatal
} else {
- verbose.Println("received configuration")
+ fmsg.VPrintln("received configuration")
}
}
// close config fd
if err := p.Close(); err != nil {
- fmt.Println("fortify-init: cannot close config fd:", err)
+ fmsg.Println("cannot close config fd:", err)
// not fatal
}
// die with parent
if _, _, errno := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_PDEATHSIG, uintptr(syscall.SIGKILL), 0); errno != 0 {
- fmt.Println("fortify-init: prctl(PR_SET_PDEATHSIG, SIGKILL):", errno.Error())
- os.Exit(1)
+ fmsg.Fatal("prctl(PR_SET_PDEATHSIG, SIGKILL):", errno.Error())
}
cmd := exec.Command(payload.Argv0)
@@ -84,8 +80,7 @@ func doInit(fd uintptr) {
}
if err := cmd.Start(); err != nil {
- fmt.Printf("fortify-init: cannot start %q: %v", payload.Argv0, err)
- os.Exit(1)
+ fmsg.Fatalf("cannot start %q: %v", payload.Argv0, err)
}
sig := make(chan os.Signal, 2)
@@ -121,7 +116,7 @@ func doInit(fd uintptr) {
}
}
if !errors.Is(err, syscall.ECHILD) {
- fmt.Println("fortify-init: unexpected wait4 response:", err)
+ fmsg.Println("unexpected wait4 response:", err)
}
close(done)
@@ -133,7 +128,7 @@ func doInit(fd uintptr) {
for {
select {
case s := <-sig:
- verbose.Println("received", s.String())
+ fmsg.VPrintln("received", s.String())
os.Exit(0)
case w := <-info:
if w.wpid == cmd.Process.Pid {
@@ -154,7 +149,7 @@ func doInit(fd uintptr) {
case <-done:
os.Exit(r)
case <-timeout:
- fmt.Println("fortify-init: timeout exceeded waiting for lingering processes")
+ fmsg.Println("timeout exceeded waiting for lingering processes")
os.Exit(r)
}
}
@@ -169,8 +164,7 @@ func Try() {
if args := flag.Args(); len(args) == 1 && args[0] == "init" {
if s, ok := os.LookupEnv(EnvInit); ok {
if fd, err := strconv.Atoi(s); err != nil {
- fmt.Printf("fortify-init: cannot parse %q: %v", s, err)
- os.Exit(1)
+ fmsg.Fatalf("cannot parse %q: %v", s, err)
} else {
doInit(uintptr(fd))
}
diff --git a/internal/shim/main.go b/internal/shim/main.go
index 051d945d..f53e8fb6 100644
--- a/internal/shim/main.go
+++ b/internal/shim/main.go
@@ -4,7 +4,6 @@ import (
"encoding/gob"
"errors"
"flag"
- "fmt"
"net"
"os"
"path"
@@ -12,29 +11,29 @@ import (
"syscall"
"git.ophivana.moe/security/fortify/helper"
+ "git.ophivana.moe/security/fortify/internal/fmsg"
init0 "git.ophivana.moe/security/fortify/internal/init"
- "git.ophivana.moe/security/fortify/internal/verbose"
)
// everything beyond this point runs as target user
// proceed with caution!
func doShim(socket string) {
+ fmsg.SetPrefix("shim")
+
// re-exec
if len(os.Args) > 0 && os.Args[0] != "fortify" && path.IsAbs(os.Args[0]) {
if err := syscall.Exec(os.Args[0], []string{"fortify", "shim"}, os.Environ()); err != nil {
- fmt.Println("fortify-shim: cannot re-exec self:", err)
+ fmsg.Println("cannot re-exec self:", err)
// continue anyway
}
}
- verbose.Prefix = "fortify-shim:"
-
// dial setup socket
var conn *net.UnixConn
if c, err := net.DialUnix("unix", nil, &net.UnixAddr{Name: socket, Net: "unix"}); err != nil {
- fmt.Println("fortify-shim: cannot dial setup socket:", err)
- os.Exit(1)
+ fmsg.Fatal("cannot dial setup socket:", err)
+ panic("unreachable")
} else {
conn = c
}
@@ -42,25 +41,22 @@ func doShim(socket string) {
// decode payload gob stream
var payload Payload
if err := gob.NewDecoder(conn).Decode(&payload); err != nil {
- fmt.Println("fortify-shim: cannot decode shim payload:", err)
- os.Exit(1)
+ fmsg.Fatal("cannot decode shim payload:", err)
} else {
// sharing stdout with parent
// USE WITH CAUTION
- verbose.Set(payload.Verbose)
+ fmsg.SetVerbose(payload.Verbose)
}
if payload.Bwrap == nil {
- fmt.Println("fortify-shim: bwrap config not supplied")
- os.Exit(1)
+ fmsg.Fatal("bwrap config not supplied")
}
// receive wayland fd over socket
wfd := -1
if payload.WL {
if fd, err := receiveWLfd(conn); err != nil {
- fmt.Println("fortify-shim: cannot receive wayland fd:", err)
- os.Exit(1)
+ fmsg.Fatal("cannot receive wayland fd:", err)
} else {
wfd = fd
}
@@ -68,7 +64,7 @@ func doShim(socket string) {
// close setup socket
if err := conn.Close(); err != nil {
- fmt.Println("fortify-shim: cannot close setup socket:", err)
+ fmsg.Println("cannot close setup socket:", err)
// not fatal
}
@@ -83,8 +79,7 @@ func doShim(socket string) {
// no argv, look up shell instead
var ok bool
if ic.Argv0, ok = os.LookupEnv("SHELL"); !ok {
- fmt.Println("fortify-shim: no command was specified and $SHELL was unset")
- os.Exit(1)
+ fmsg.Fatal("no command was specified and $SHELL was unset")
}
ic.Argv = []string{ic.Argv0}
@@ -106,41 +101,37 @@ func doShim(socket string) {
// share config pipe
if r, w, err := os.Pipe(); err != nil {
- fmt.Println("fortify-shim: cannot pipe:", err)
- os.Exit(1)
+ fmsg.Fatal("cannot pipe:", err)
} else {
conf.SetEnv[init0.EnvInit] = strconv.Itoa(3 + len(extraFiles))
extraFiles = append(extraFiles, r)
- verbose.Println("transmitting config to init")
+ fmsg.VPrintln("transmitting config to init")
go func() {
// stream config to pipe
if err = gob.NewEncoder(w).Encode(&ic); err != nil {
- fmt.Println("fortify-shim: cannot transmit init config:", err)
- os.Exit(1)
+ fmsg.Fatal("cannot transmit init config:", err)
}
}()
}
helper.BubblewrapName = payload.Exec[1] // resolved bwrap path by parent
if b, err := helper.NewBwrap(conf, nil, payload.Exec[0], func(int, int) []string { return []string{"init"} }); err != nil {
- fmt.Println("fortify-shim: malformed sandbox config:", err)
- os.Exit(1)
+ fmsg.Fatal("malformed sandbox config:", err)
} else {
cmd := b.Unwrap()
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
cmd.ExtraFiles = extraFiles
- if verbose.Get() {
- verbose.Println("bwrap args:", conf.Args())
+ if fmsg.Verbose() {
+ fmsg.VPrintln("bwrap args:", conf.Args())
}
// run and pass through exit code
if err = b.Start(); err != nil {
- fmt.Println("fortify-shim: cannot start target process:", err)
- os.Exit(1)
+ fmsg.Fatal("cannot start target process:", err)
} else if err = b.Wait(); err != nil {
- verbose.Println("wait:", err)
+ fmsg.VPrintln("wait:", err)
}
if b.Unwrap().ProcessState != nil {
os.Exit(b.Unwrap().ProcessState.ExitCode())
diff --git a/internal/shim/parent.go b/internal/shim/parent.go
index 0e903838..6c393c58 100644
--- a/internal/shim/parent.go
+++ b/internal/shim/parent.go
@@ -3,13 +3,12 @@ package shim
import (
"encoding/gob"
"errors"
- "fmt"
"net"
"os"
"syscall"
"git.ophivana.moe/security/fortify/acl"
- "git.ophivana.moe/security/fortify/internal/verbose"
+ "git.ophivana.moe/security/fortify/internal/fmsg"
)
// called in the parent process
@@ -19,7 +18,7 @@ func ServeConfig(socket string, uid int, payload *Payload, wl *Wayland) error {
if f, err := net.DialUnix("unix", nil, &net.UnixAddr{Name: wl.Path, Net: "unix"}); err != nil {
return err
} else {
- verbose.Println("connected to wayland at", wl)
+ fmsg.VPrintf("connected to wayland at %q", wl.Path)
wl.UnixConn = f
}
}
@@ -27,18 +26,18 @@ func ServeConfig(socket string, uid int, payload *Payload, wl *Wayland) error {
if c, err := net.ListenUnix("unix", &net.UnixAddr{Name: socket, Net: "unix"}); err != nil {
return err
} else {
- verbose.Println("configuring shim on socket", socket)
+ fmsg.VPrintf("configuring shim on socket %q", socket)
if err = acl.UpdatePerm(socket, uid, acl.Read, acl.Write, acl.Execute); err != nil {
- fmt.Println("fortify: cannot change permissions of shim setup socket:", err)
+ fmsg.Println("cannot change permissions of shim setup socket:", err)
}
go func() {
var conn *net.UnixConn
if conn, err = c.AcceptUnix(); err != nil {
- fmt.Println("fortify: cannot accept connection from shim:", err)
+ fmsg.Println("cannot accept connection from shim:", err)
} else {
if err = gob.NewEncoder(conn).Encode(*payload); err != nil {
- fmt.Println("fortify: cannot stream shim payload:", err)
+ fmsg.Println("cannot stream shim payload:", err)
_ = os.Remove(socket)
return
}
@@ -47,23 +46,23 @@ func ServeConfig(socket string, uid int, payload *Payload, wl *Wayland) error {
// get raw connection
var rc syscall.RawConn
if rc, err = wl.SyscallConn(); err != nil {
- fmt.Println("fortify: cannot obtain raw wayland connection:", err)
+ fmsg.Println("cannot obtain raw wayland connection:", err)
return
} else {
go func() {
// pass wayland socket fd
if err = rc.Control(func(fd uintptr) {
if _, _, err = conn.WriteMsgUnix(nil, syscall.UnixRights(int(fd)), nil); err != nil {
- fmt.Println("fortify: cannot pass wayland connection to shim:", err)
+ fmsg.Println("cannot pass wayland connection to shim:", err)
return
}
_ = conn.Close()
// block until shim exits
<-wl.done
- verbose.Println("releasing wayland connection")
+ fmsg.VPrintln("releasing wayland connection")
}); err != nil {
- fmt.Println("fortify: cannot obtain wayland connection fd:", err)
+ fmsg.Println("cannot obtain wayland connection fd:", err)
}
}()
}
@@ -72,10 +71,10 @@ func ServeConfig(socket string, uid int, payload *Payload, wl *Wayland) error {
}
}
if err = c.Close(); err != nil {
- fmt.Println("fortify: cannot close shim socket:", err)
+ fmsg.Println("cannot close shim socket:", err)
}
if err = os.Remove(socket); err != nil && !errors.Is(err, os.ErrNotExist) {
- fmt.Println("fortify: cannot remove dangling shim socket:", err)
+ fmsg.Println("cannot remove dangling shim socket:", err)
}
}()
return nil
diff --git a/internal/state/print.go b/internal/state/print.go
index e04a690b..d8f08fac 100644
--- a/internal/state/print.go
+++ b/internal/state/print.go
@@ -10,8 +10,8 @@ import (
"text/tabwriter"
"time"
+ "git.ophivana.moe/security/fortify/internal/fmsg"
"git.ophivana.moe/security/fortify/internal/system"
- "git.ophivana.moe/security/fortify/internal/verbose"
)
// MustPrintLauncherStateSimpleGlobal prints active launcher states of all simple stores
@@ -21,19 +21,19 @@ func MustPrintLauncherStateSimpleGlobal(w **tabwriter.Writer, runDir string) {
// read runtime directory to get all UIDs
if dirs, err := os.ReadDir(path.Join(runDir, "state")); err != nil && !errors.Is(err, os.ErrNotExist) {
- fmt.Println("cannot read runtime directory:", err)
+ fmsg.Println("cannot read runtime directory:", err)
os.Exit(1)
} else {
for _, e := range dirs {
// skip non-directories
if !e.IsDir() {
- verbose.Println("skipped non-directory entry", e.Name())
+ fmsg.VPrintf("skipped non-directory entry %q", e.Name())
continue
}
// skip non-numerical names
if _, err = strconv.Atoi(e.Name()); err != nil {
- verbose.Println("skipped non-uid entry", e.Name())
+ fmsg.VPrintf("skipped non-uid entry %q", e.Name())
continue
}
@@ -45,7 +45,7 @@ func MustPrintLauncherStateSimpleGlobal(w **tabwriter.Writer, runDir string) {
// mustPrintLauncherState causes store activity so store needs to be closed
if err = s.Close(); err != nil {
- fmt.Printf("warn: error closing store for user %s: %s\n", e.Name(), err)
+ fmsg.Printf("cannot close store for user %q: %s", e.Name(), err)
}
}
}
@@ -67,7 +67,7 @@ func (s *simpleStore) mustPrintLauncherState(w **tabwriter.Writer, now time.Time
*w = tabwriter.NewWriter(os.Stdout, 0, 1, 4, ' ', 0)
// write header when initialising
- if !verbose.Get() {
+ if !fmsg.Verbose() {
_, _ = fmt.Fprintln(*w, "\tUID\tPID\tUptime\tEnablements\tMethod\tCommand")
} else {
// argv is emitted in body when verbose
@@ -96,7 +96,7 @@ func (s *simpleStore) mustPrintLauncherState(w **tabwriter.Writer, now time.Time
ets.WriteString("(No enablements)")
}
- if !verbose.Get() {
+ if !fmsg.Verbose() {
_, _ = fmt.Fprintf(*w, "\t%s\t%d\t%s\t%s\t%s\t%s\n",
s.path[len(s.path)-1], state.PID, now.Sub(state.Time).Round(time.Second).String(), strings.TrimPrefix(ets.String(), ", "), state.Method,
state.Command)
@@ -110,15 +110,15 @@ func (s *simpleStore) mustPrintLauncherState(w **tabwriter.Writer, now time.Time
return nil
}()
}); err != nil {
- fmt.Printf("cannot perform action on store '%s': %s\n", path.Join(s.path...), err)
+ fmsg.Printf("cannot perform action on store %q: %s", path.Join(s.path...), err)
if !ok {
- fmt.Println("warn: store faulted before printing")
+ fmsg.Println("store faulted before printing")
os.Exit(1)
}
}
if innerErr != nil {
- fmt.Printf("cannot print launcher state for store '%s': %s\n", path.Join(s.path...), innerErr)
+ fmsg.Printf("cannot print launcher state for store %q: %s", path.Join(s.path...), innerErr)
os.Exit(1)
}
}
diff --git a/internal/system/acl.go b/internal/system/acl.go
index e4bc9359..f8f1dc68 100644
--- a/internal/system/acl.go
+++ b/internal/system/acl.go
@@ -6,7 +6,6 @@ import (
"git.ophivana.moe/security/fortify/acl"
"git.ophivana.moe/security/fortify/internal/fmsg"
- "git.ophivana.moe/security/fortify/internal/verbose"
)
// UpdatePerm appends an ephemeral acl update Op.
@@ -33,18 +32,20 @@ func (a *ACL) Type() Enablement {
}
func (a *ACL) apply(sys *I) error {
- verbose.Println("applying ACL", a, "uid:", sys.uid, "type:", TypeString(a.et), "path:", a.path)
+ fmsg.VPrintf("applying ACL %s uid: %d type: %s path: %q",
+ a, sys.uid, TypeString(a.et), a.path)
return fmsg.WrapErrorSuffix(acl.UpdatePerm(a.path, sys.uid, a.perms...),
fmt.Sprintf("cannot apply ACL entry to %q:", a.path))
}
func (a *ACL) revert(sys *I, ec *Criteria) error {
if ec.hasType(a) {
- verbose.Println("stripping ACL", a, "uid:", sys.uid, "type:", TypeString(a.et), "path:", a.path)
+ fmsg.VPrintf("stripping ACL %s uid: %d type: %s path: %q",
+ a, sys.uid, TypeString(a.et), a.path)
return fmsg.WrapErrorSuffix(acl.UpdatePerm(a.path, sys.uid),
fmt.Sprintf("cannot strip ACL entry from %q:", a.path))
} else {
- verbose.Println("skipping ACL", a, "uid:", sys.uid, "tag:", TypeString(a.et), "path:", a.path)
+ fmsg.VPrintln("skipping ACL", a, "uid:", sys.uid, "tag:", TypeString(a.et), "path:", a.path)
return nil
}
}
diff --git a/internal/system/dbus.go b/internal/system/dbus.go
index 8fe7d510..7c003e4e 100644
--- a/internal/system/dbus.go
+++ b/internal/system/dbus.go
@@ -2,12 +2,10 @@ package system
import (
"errors"
- "fmt"
"os"
"git.ophivana.moe/security/fortify/dbus"
"git.ophivana.moe/security/fortify/internal/fmsg"
- "git.ophivana.moe/security/fortify/internal/verbose"
)
var (
@@ -42,12 +40,12 @@ func (sys *I) ProxyDBus(session, system *dbus.Config, sessionPath, systemPath st
d.proxy = dbus.New(sessionBus, systemBus)
defer func() {
- if verbose.Get() && d.proxy.Sealed() {
- verbose.Println("sealed session proxy", session.Args(sessionBus))
+ if fmsg.Verbose() && d.proxy.Sealed() {
+ fmsg.VPrintln("sealed session proxy", session.Args(sessionBus))
if system != nil {
- verbose.Println("sealed system proxy", system.Args(systemBus))
+ fmsg.VPrintln("sealed system proxy", system.Args(systemBus))
}
- verbose.Println("message bus proxy final args:", d.proxy)
+ fmsg.VPrintln("message bus proxy final args:", d.proxy)
}
}()
@@ -73,9 +71,9 @@ func (d *DBus) Type() Enablement {
}
func (d *DBus) apply(_ *I) error {
- verbose.Printf("session bus proxy on %q for upstream %q\n", d.proxy.Session()[1], d.proxy.Session()[0])
+ fmsg.VPrintf("session bus proxy on %q for upstream %q", d.proxy.Session()[1], d.proxy.Session()[0])
if d.system {
- verbose.Printf("system bus proxy on %q for upstream %q\n", d.proxy.System()[1], d.proxy.System()[0])
+ fmsg.VPrintf("system bus proxy on %q for upstream %q", d.proxy.System()[1], d.proxy.System()[0])
}
// ready channel passed to dbus package
@@ -86,27 +84,27 @@ func (d *DBus) apply(_ *I) error {
return fmsg.WrapErrorSuffix(err,
"cannot start message bus proxy:")
}
- verbose.Println("starting message bus proxy:", d.proxy)
- if verbose.Get() { // save the extra bwrap arg build when verbose logging is off
- verbose.Println("message bus proxy bwrap args:", d.proxy.Bwrap())
+ fmsg.VPrintln("starting message bus proxy:", d.proxy)
+ if fmsg.Verbose() { // save the extra bwrap arg build when verbose logging is off
+ fmsg.VPrintln("message bus proxy bwrap args:", d.proxy.Bwrap())
}
// background wait for proxy instance and notify completion
go func() {
if err := d.proxy.Wait(); err != nil {
- fmt.Println("fortify: message bus proxy exited with error:", err)
+ fmsg.Println("message bus proxy exited with error:", err)
go func() { ready <- err }()
} else {
- verbose.Println("message bus proxy exit")
+ fmsg.VPrintln("message bus proxy exit")
}
// ensure socket removal so ephemeral directory is empty at revert
if err := os.Remove(d.proxy.Session()[1]); err != nil && !errors.Is(err, os.ErrNotExist) {
- fmt.Println("fortify: cannot remove dangling session bus socket:", err)
+ fmsg.Println("cannot remove dangling session bus socket:", err)
}
if d.system {
if err := os.Remove(d.proxy.System()[1]); err != nil && !errors.Is(err, os.ErrNotExist) {
- fmt.Println("fortify: cannot remove dangling system bus socket:", err)
+ fmsg.Println("cannot remove dangling system bus socket:", err)
}
}
@@ -120,14 +118,14 @@ func (d *DBus) apply(_ *I) error {
return fmsg.WrapErrorSuffix(err,
"message bus proxy fault after start:")
}
- verbose.Println("message bus proxy ready")
+ fmsg.VPrintln("message bus proxy ready")
return nil
}
func (d *DBus) revert(_ *I, _ *Criteria) error {
// criteria ignored here since dbus is always process-scoped
- verbose.Println("terminating message bus proxy")
+ fmsg.VPrintln("terminating message bus proxy")
if err := d.proxy.Close(); err != nil {
if errors.Is(err, os.ErrClosed) {
diff --git a/internal/system/mkdir.go b/internal/system/mkdir.go
index 89dcd481..0f3787f6 100644
--- a/internal/system/mkdir.go
+++ b/internal/system/mkdir.go
@@ -6,7 +6,6 @@ import (
"os"
"git.ophivana.moe/security/fortify/internal/fmsg"
- "git.ophivana.moe/security/fortify/internal/verbose"
)
// Ensure the existence and mode of a directory.
@@ -37,7 +36,7 @@ func (m *Mkdir) Type() Enablement {
}
func (m *Mkdir) apply(_ *I) error {
- verbose.Println("ensuring directory", m)
+ fmsg.VPrintln("ensuring directory", m)
// create directory
err := os.Mkdir(m.path, m.perm)
@@ -58,11 +57,11 @@ func (m *Mkdir) revert(_ *I, ec *Criteria) error {
}
if ec.hasType(m) {
- verbose.Println("destroying ephemeral directory", m)
+ fmsg.VPrintln("destroying ephemeral directory", m)
return fmsg.WrapErrorSuffix(os.Remove(m.path),
fmt.Sprintf("cannot remove ephemeral directory %q:", m.path))
} else {
- verbose.Println("skipping ephemeral directory", m)
+ fmsg.VPrintln("skipping ephemeral directory", m)
return nil
}
}
diff --git a/internal/system/op.go b/internal/system/op.go
index a9040187..67a637bf 100644
--- a/internal/system/op.go
+++ b/internal/system/op.go
@@ -2,8 +2,9 @@ package system
import (
"errors"
- "fmt"
"sync"
+
+ "git.ophivana.moe/security/fortify/internal/fmsg"
)
const (
@@ -80,7 +81,7 @@ func (sys *I) Commit() error {
if sp != nil {
// rollback partial commit
if err := sp.Revert(&Criteria{nil}); err != nil {
- fmt.Println("fortify: errors returned reverting partial commit:", err)
+ fmsg.Println("errors returned reverting partial commit:", err)
}
}
}()
diff --git a/internal/system/tmpfiles.go b/internal/system/tmpfiles.go
index 7b23e0e6..9215bd33 100644
--- a/internal/system/tmpfiles.go
+++ b/internal/system/tmpfiles.go
@@ -9,7 +9,6 @@ import (
"git.ophivana.moe/security/fortify/acl"
"git.ophivana.moe/security/fortify/internal/fmsg"
- "git.ophivana.moe/security/fortify/internal/verbose"
)
// CopyFile registers an Op that copies path dst from src.
@@ -72,15 +71,15 @@ func (t *Tmpfile) Type() Enablement {
func (t *Tmpfile) apply(_ *I) error {
switch t.method {
case tmpfileCopy:
- verbose.Printf("publishing tmpfile %s\n", t)
+ fmsg.VPrintln("publishing tmpfile", t)
return fmsg.WrapErrorSuffix(copyFile(t.dst, t.src),
fmt.Sprintf("cannot copy tmpfile %q:", t.dst))
case tmpfileLink:
- verbose.Printf("linking tmpfile %s\n", t)
+ fmsg.VPrintln("linking tmpfile", t)
return fmsg.WrapErrorSuffix(os.Link(t.src, t.dst),
fmt.Sprintf("cannot link tmpfile %q:", t.dst))
case tmpfileWrite:
- verbose.Printf("writing %s\n", t)
+ fmsg.VPrintln("writing", t)
return fmsg.WrapErrorSuffix(os.WriteFile(t.dst, []byte(t.src), 0600),
fmt.Sprintf("cannot write tmpfile %q:", t.dst))
default:
@@ -90,11 +89,11 @@ func (t *Tmpfile) apply(_ *I) error {
func (t *Tmpfile) revert(_ *I, ec *Criteria) error {
if ec.hasType(t) {
- verbose.Printf("removing tmpfile %q\n", t.dst)
+ fmsg.VPrintf("removing tmpfile %q", t.dst)
return fmsg.WrapErrorSuffix(os.Remove(t.dst),
fmt.Sprintf("cannot remove tmpfile %q:", t.dst))
} else {
- verbose.Printf("skipping tmpfile %q\n", t.dst)
+ fmsg.VPrintf("skipping tmpfile %q", t.dst)
return nil
}
}
diff --git a/internal/system/xhost.go b/internal/system/xhost.go
index 4ed3f8bd..51c8d24f 100644
--- a/internal/system/xhost.go
+++ b/internal/system/xhost.go
@@ -4,7 +4,6 @@ import (
"fmt"
"git.ophivana.moe/security/fortify/internal/fmsg"
- "git.ophivana.moe/security/fortify/internal/verbose"
"git.ophivana.moe/security/fortify/xcb"
)
@@ -23,18 +22,18 @@ func (x XHost) Type() Enablement {
}
func (x XHost) apply(_ *I) error {
- verbose.Printf("inserting entry %s to X11\n", x)
+ fmsg.VPrintf("inserting entry %s to X11", x)
return fmsg.WrapErrorSuffix(xcb.ChangeHosts(xcb.HostModeInsert, xcb.FamilyServerInterpreted, "localuser\x00"+string(x)),
fmt.Sprintf("cannot insert entry %s to X11:", x))
}
func (x XHost) revert(_ *I, ec *Criteria) error {
if ec.hasType(x) {
- verbose.Printf("deleting entry %s from X11\n", x)
+ fmsg.VPrintf("deleting entry %s from X11", x)
return fmsg.WrapErrorSuffix(xcb.ChangeHosts(xcb.HostModeDelete, xcb.FamilyServerInterpreted, "localuser\x00"+string(x)),
fmt.Sprintf("cannot delete entry %s from X11:", x))
} else {
- verbose.Printf("skipping entry %s in X11\n", x)
+ fmsg.VPrintf("skipping entry %s in X11", x)
return nil
}
}
diff --git a/internal/verbose/print.go b/internal/verbose/print.go
deleted file mode 100644
index 3d0686b1..00000000
--- a/internal/verbose/print.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package verbose
-
-import (
- "fmt"
-)
-
-var Prefix = "fortify:"
-
-func Println(a ...any) {
- if verbose.Load() {
- fmt.Println(append([]any{Prefix}, a...)...)
- }
-}
-
-func Printf(format string, a ...any) {
- if verbose.Load() {
- fmt.Printf(Prefix+" "+format, a...)
- }
-}
diff --git a/internal/verbose/print_test.go b/internal/verbose/print_test.go
deleted file mode 100644
index d74b70ed..00000000
--- a/internal/verbose/print_test.go
+++ /dev/null
@@ -1,67 +0,0 @@
-package verbose_test
-
-import (
- "os"
- "os/exec"
- "strconv"
- "strings"
- "testing"
-
- "git.ophivana.moe/security/fortify/internal/verbose"
-)
-
-const (
- testVerbose = "GO_TEST_VERBOSE"
- wantStdout = "fortify: println\nfortify: printf"
-)
-
-func TestPrinter(t *testing.T) {
- switch os.Getenv(testVerbose) {
- case "0":
- verbose.Set(false)
- case "1":
- verbose.Set(true)
- default:
- return
- }
-
- verbose.Println("println")
- verbose.Printf("%s", "printf")
-}
-
-func TestPrintf_Println(t *testing.T) {
- testPrintfPrintln(t, false)
- testPrintfPrintln(t, true)
-
- // make -cover happy
- stdout := os.Stdout
- t.Cleanup(func() {
- os.Stdout = stdout
- })
- os.Stdout = nil
- verbose.Set(true)
- verbose.Printf("")
- verbose.Println()
-}
-
-func testPrintfPrintln(t *testing.T, v bool) {
- t.Run("start verbose printer with verbose "+strconv.FormatBool(v), func(t *testing.T) {
- stdout, stderr := new(strings.Builder), new(strings.Builder)
- stdout.Grow(len(wantStdout))
- cmd := exec.Command(os.Args[0], "-test.run=TestPrinter")
- cmd.Stdout, cmd.Stderr = stdout, stderr
- if v {
- cmd.Env = append(cmd.Env, testVerbose+"=1")
- } else {
- cmd.Env = append(cmd.Env, testVerbose+"=0")
- }
- if err := cmd.Run(); err != nil {
- panic("cannot run printer process: " + err.Error() + " stderr: " + stderr.String())
- }
-
- if got := stdout.String(); strings.Contains(got, wantStdout) != v {
- t.Errorf("Print: got %v; want %t",
- got, v)
- }
- })
-}
diff --git a/internal/verbose/state.go b/internal/verbose/state.go
deleted file mode 100644
index e63e7a10..00000000
--- a/internal/verbose/state.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package verbose
-
-import "sync/atomic"
-
-var verbose = new(atomic.Bool)
-
-func Get() bool {
- return verbose.Load()
-}
-
-func Set(v bool) {
- verbose.Store(v)
-}
diff --git a/internal/verbose/state_test.go b/internal/verbose/state_test.go
deleted file mode 100644
index f8179eea..00000000
--- a/internal/verbose/state_test.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package verbose_test
-
-import (
- "testing"
-
- "git.ophivana.moe/security/fortify/internal/verbose"
-)
-
-func TestGetSet(t *testing.T) {
- verbose.Set(false)
- if verbose.Get() {
- t.Errorf("Get() = true, want false")
- }
-
- verbose.Set(true)
- if !verbose.Get() {
- t.Errorf("Get() = false, want true")
- }
-
-}