aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/system
diff options
context:
space:
mode:
authorOphestra Umiker <cat@ophivana.moe>2024-12-06 04:20:15 +0900
committerOphestra Umiker <cat@ophivana.moe>2024-12-06 04:20:15 +0900
commit38e92edb8efd7cc74031d013a13af5c1c8ddd284 (patch)
tree96459a765eb7e502a06ad4088b468f184fd67079 /internal/system
parent2d606b1f4b92fc9c037aaf5718bc3e24ef05a532 (diff)
system/wayland: integrate security-context-v1
Had to pass the sync fd through sys. The rest are just part of a standard Op. Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
Diffstat (limited to 'internal/system')
-rw-r--r--internal/system/op.go6
-rw-r--r--internal/system/wayland.go80
2 files changed, 86 insertions, 0 deletions
diff --git a/internal/system/op.go b/internal/system/op.go
index 7d293773..d2ca5dd7 100644
--- a/internal/system/op.go
+++ b/internal/system/op.go
@@ -2,6 +2,7 @@ package system
import (
"errors"
+ "os"
"sync"
"git.ophivana.moe/security/fortify/internal/fmsg"
@@ -56,6 +57,7 @@ func TypeString(e Enablement) string {
type I struct {
uid int
ops []Op
+ sp *os.File
state [2]bool
lock sync.Mutex
@@ -65,6 +67,10 @@ func (sys *I) UID() int {
return sys.uid
}
+func (sys *I) Sync() *os.File {
+ return sys.sp
+}
+
func (sys *I) Equal(v *I) bool {
if v == nil || sys.uid != v.uid || len(sys.ops) != len(v.ops) {
return false
diff --git a/internal/system/wayland.go b/internal/system/wayland.go
new file mode 100644
index 00000000..36a7fa6d
--- /dev/null
+++ b/internal/system/wayland.go
@@ -0,0 +1,80 @@
+package system
+
+import (
+ "errors"
+ "fmt"
+ "os"
+
+ "git.ophivana.moe/security/fortify/acl"
+ "git.ophivana.moe/security/fortify/internal/fmsg"
+ "git.ophivana.moe/security/fortify/wl"
+)
+
+// Wayland sets up a wayland socket with a security context attached.
+func (sys *I) Wayland(dst, src, appID, instanceID string) *I {
+ sys.lock.Lock()
+ defer sys.lock.Unlock()
+
+ sys.ops = append(sys.ops, Wayland{[2]string{dst, src}, new(wl.Conn), appID, instanceID})
+
+ return sys
+}
+
+type Wayland struct {
+ pair [2]string
+ conn *wl.Conn
+
+ appID, instanceID string
+}
+
+func (w Wayland) Type() Enablement {
+ return Process
+}
+
+func (w Wayland) apply(sys *I) error {
+ if err := w.conn.Attach(w.pair[1]); err != nil {
+ return fmsg.WrapErrorSuffix(err,
+ fmt.Sprintf("cannot attach to wayland on %q:", w.pair[1]))
+ } else {
+ fmsg.VPrintf("wayland attached on %q", w.pair[1])
+ }
+
+ if sp, err := w.conn.Bind(w.pair[0], w.appID, w.instanceID); err != nil {
+ return fmsg.WrapErrorSuffix(err,
+ fmt.Sprintf("cannot bind to socket on %q:", w.pair[0]))
+ } else {
+ sys.sp = sp
+ fmsg.VPrintf("wayland listening on %q", w.pair[0])
+ return fmsg.WrapErrorSuffix(errors.Join(os.Chmod(w.pair[0], 0), acl.UpdatePerm(w.pair[0], sys.uid, acl.Read, acl.Write, acl.Execute)),
+ fmt.Sprintf("cannot chmod socket on %q:", w.pair[0]))
+ }
+}
+
+func (w Wayland) revert(_ *I, ec *Criteria) error {
+ if ec.hasType(w) {
+ fmsg.VPrintf("removing wayland socket on %q", w.pair[0])
+ if err := os.Remove(w.pair[0]); err != nil && !errors.Is(err, os.ErrNotExist) {
+ return err
+ }
+
+ fmsg.VPrintf("detaching from wayland on %q", w.pair[1])
+ return fmsg.WrapErrorSuffix(w.conn.Close(),
+ fmt.Sprintf("cannot detach from wayland on %q:", w.pair[1]))
+ } else {
+ fmsg.VPrintf("skipping wayland cleanup on %q", w.pair[0])
+ return nil
+ }
+}
+
+func (w Wayland) Is(o Op) bool {
+ w0, ok := o.(Wayland)
+ return ok && w.pair == w0.pair
+}
+
+func (w Wayland) Path() string {
+ return w.pair[0]
+}
+
+func (w Wayland) String() string {
+ return fmt.Sprintf("wayland socket at %q", w.pair[0])
+}