diff options
Diffstat (limited to 'internal/app/share.dbus.go')
| -rw-r--r-- | internal/app/share.dbus.go | 118 |
1 files changed, 11 insertions, 107 deletions
diff --git a/internal/app/share.dbus.go b/internal/app/share.dbus.go index 912cd97b..6b0ff43c 100644 --- a/internal/app/share.dbus.go +++ b/internal/app/share.dbus.go @@ -1,15 +1,11 @@ package app import ( - "errors" - "fmt" - "os" "path" "git.ophivana.moe/cat/fortify/acl" "git.ophivana.moe/cat/fortify/dbus" "git.ophivana.moe/cat/fortify/internal/state" - "git.ophivana.moe/cat/fortify/internal/verbose" ) const ( @@ -17,122 +13,30 @@ const ( dbusSystemBusAddress = "DBUS_SYSTEM_BUS_ADDRESS" ) -var ( - ErrDBusConfig = errors.New("dbus config not supplied") -) - -type ( - SealDBusError BaseError - LookupDBusError BaseError - StartDBusError BaseError - CloseDBusError BaseError -) - func (seal *appSeal) shareDBus(config [2]*dbus.Config) error { if !seal.et.Has(state.EnableDBus) { return nil } - // session bus is mandatory - if config[0] == nil { - return (*SealDBusError)(wrapError(ErrDBusConfig, "attempted to seal session bus proxy with nil config")) - } - - // system bus is optional - seal.sys.dbusSystem = config[1] != nil - - // upstream address, downstream socket path - var sessionBus, systemBus [2]string - // downstream socket paths - sessionBus[1] = path.Join(seal.share, "bus") - systemBus[1] = path.Join(seal.share, "system_bus_socket") - - // resolve upstream bus addresses - sessionBus[0], systemBus[0] = dbus.Address() + sessionPath, systemPath := path.Join(seal.share, "bus"), path.Join(seal.share, "system_bus_socket") - // create proxy instance - seal.sys.dbus = dbus.New(sessionBus, systemBus) - - // seal dbus proxy - if err := seal.sys.dbus.Seal(config[0], config[1]); err != nil { - return (*SealDBusError)(wrapError(err, "cannot seal message bus proxy:", err)) + // configure dbus proxy + if err := seal.sys.ProxyDBus(config[0], config[1], sessionPath, systemPath); err != nil { + return err } - // store addresses for cleanup and logging - seal.sys.dbusAddr = &[2][2]string{sessionBus, systemBus} - // share proxy sockets sessionInner := path.Join(seal.sys.runtime, "bus") - seal.sys.setEnv(dbusSessionBusAddress, "unix:path="+sessionInner) - seal.sys.bwrap.Bind(sessionBus[1], sessionInner) - seal.sys.updatePerm(sessionBus[1], acl.Read, acl.Write) - if seal.sys.dbusSystem { + seal.sys.bwrap.SetEnv[dbusSessionBusAddress] = "unix:path=" + sessionInner + seal.sys.bwrap.Bind(sessionPath, sessionInner) + seal.sys.UpdatePerm(sessionPath, acl.Read, acl.Write) + if config[1] != nil { systemInner := "/run/dbus/system_bus_socket" - seal.sys.setEnv(dbusSystemBusAddress, "unix:path="+systemInner) - seal.sys.bwrap.Bind(systemBus[1], systemInner) - seal.sys.updatePerm(systemBus[1], acl.Read, acl.Write) - } - - return nil -} - -func (tx *appSealTx) startDBus() error { - // ready channel passed to dbus package - ready := make(chan error, 1) - // used by waiting goroutine to notify process return - tx.dbusWait = make(chan struct{}) - - // background dbus proxy start - if err := tx.dbus.Start(ready, os.Stderr, true); err != nil { - return (*StartDBusError)(wrapError(err, "cannot start message bus proxy:", err)) - } - verbose.Println("starting message bus proxy:", tx.dbus) - verbose.Println("message bus proxy bwrap args:", tx.dbus.Bwrap()) - - // background wait for proxy instance and notify completion - go func() { - if err := tx.dbus.Wait(); err != nil { - fmt.Println("fortify: warn: message bus proxy returned error:", err) - go func() { ready <- err }() - } else { - verbose.Println("message bus proxy exit") - } - - // ensure socket removal so ephemeral directory is empty at revert - if err := os.Remove(tx.dbusAddr[0][1]); err != nil && !errors.Is(err, os.ErrNotExist) { - fmt.Println("fortify: cannot remove dangling session bus socket:", err) - } - if tx.dbusSystem { - if err := os.Remove(tx.dbusAddr[1][1]); err != nil && !errors.Is(err, os.ErrNotExist) { - fmt.Println("fortify: cannot remove dangling system bus socket:", err) - } - } - - // notify proxy completion - tx.dbusWait <- struct{}{} - }() - - // ready is not nil if the proxy process faulted - if err := <-ready; err != nil { - // note that err here is either an I/O related error or a predetermined unexpected behaviour error - return (*StartDBusError)(wrapError(err, "message bus proxy fault after start:", err)) - } - verbose.Println("message bus proxy ready") - - return nil -} - -func (tx *appSealTx) stopDBus() error { - if err := tx.dbus.Close(); err != nil { - if errors.Is(err, os.ErrClosed) { - return (*CloseDBusError)(wrapError(err, "message bus proxy already closed")) - } else { - return (*CloseDBusError)(wrapError(err, "cannot close message bus proxy:", err)) - } + seal.sys.bwrap.SetEnv[dbusSystemBusAddress] = "unix:path=" + systemInner + seal.sys.bwrap.Bind(systemPath, systemInner) + seal.sys.UpdatePerm(systemPath, acl.Read, acl.Write) } - // block until proxy wait returns - <-tx.dbusWait return nil } |
