app/dbus: manage dbus proxy and pass address to child
This commit adds code that starts and registers the D-Bus proxy, as well as cleanup code that tracks and closes the daemon once our child exits. A few more flags were added to pass D-Bus config to xdg-dbus-proxy. Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
This commit is contained in:
parent
357cc4ce4d
commit
38ef2b4d0c
8
cli.go
8
cli.go
|
@ -8,6 +8,9 @@ import (
|
|||
|
||||
var (
|
||||
userName string
|
||||
dbusConfig string
|
||||
dbusID string
|
||||
mpris bool
|
||||
|
||||
mustWayland bool
|
||||
mustX bool
|
||||
|
@ -19,7 +22,10 @@ var (
|
|||
)
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&userName, "u", "chronos", "Specify a username")
|
||||
flag.StringVar(&userName, "u", "chronos", "Passwd name of user to run as")
|
||||
flag.StringVar(&dbusConfig, "dbus-config", "builtin", "Path to D-Bus proxy config file, or \"builtin\" for defaults")
|
||||
flag.StringVar(&dbusID, "dbus-id", "", "D-Bus ID of application, leave empty to disable own paths, has no effect if custom config is available")
|
||||
flag.BoolVar(&mpris, "mpris", false, "Allow owning MPRIS D-Bus path, has no effect if custom config is available")
|
||||
|
||||
flag.BoolVar(&mustWayland, "wayland", false, "Share Wayland socket")
|
||||
flag.BoolVar(&mustX, "X", false, "Share X11 socket and allow connection")
|
||||
|
|
|
@ -1,14 +1,92 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
|
||||
"git.ophivana.moe/cat/fortify/dbus"
|
||||
"git.ophivana.moe/cat/fortify/internal/acl"
|
||||
"git.ophivana.moe/cat/fortify/internal/state"
|
||||
"git.ophivana.moe/cat/fortify/internal/system"
|
||||
"git.ophivana.moe/cat/fortify/internal/util"
|
||||
)
|
||||
|
||||
func (a *App) ShareDBus() {
|
||||
const dbusSessionBusAddress = "DBUS_SESSION_BUS_ADDRESS"
|
||||
|
||||
var dbusAddress string
|
||||
|
||||
func (a *App) ShareDBus(c *dbus.Config) {
|
||||
a.setEnablement(state.EnableDBus)
|
||||
|
||||
// TODO: start xdg-dbus-proxy
|
||||
fmt.Println("warn: dbus proxy not implemented")
|
||||
var binPath, address string
|
||||
target := path.Join(system.V.Share, strconv.Itoa(os.Getpid()))
|
||||
|
||||
if b, ok := util.Which("xdg-dbus-proxy"); !ok {
|
||||
state.Fatal("D-Bus: Did not find 'xdg-dbus-proxy' in PATH")
|
||||
} else {
|
||||
binPath = b
|
||||
}
|
||||
|
||||
if addr, ok := os.LookupEnv(dbusSessionBusAddress); !ok {
|
||||
state.Fatal("D-Bus: DBUS_SESSION_BUS_ADDRESS not set")
|
||||
} else {
|
||||
address = addr
|
||||
}
|
||||
|
||||
c.Log = system.V.Verbose
|
||||
p := dbus.New(binPath, address, target)
|
||||
if system.V.Verbose {
|
||||
fmt.Println("D-Bus: sealing proxy", c.Args(address, target))
|
||||
}
|
||||
if err := p.Seal(c); err != nil {
|
||||
state.Fatal("D-Bus: invalid config when sealing proxy,", err)
|
||||
}
|
||||
|
||||
ready := make(chan bool, 1)
|
||||
done := make(chan struct{})
|
||||
|
||||
if system.V.Verbose {
|
||||
fmt.Printf("Starting session bus proxy '%s' for address '%s'\n", dbusAddress, address)
|
||||
}
|
||||
if err := p.Start(&ready); err != nil {
|
||||
state.Fatal("D-Bus: error starting proxy,", err)
|
||||
}
|
||||
if system.V.Verbose {
|
||||
fmt.Println("D-Bus proxy launch:", p)
|
||||
}
|
||||
|
||||
go func() {
|
||||
if err := p.Wait(); err != nil {
|
||||
fmt.Println("warn: D-Bus proxy returned error,", err)
|
||||
} else {
|
||||
if system.V.Verbose {
|
||||
fmt.Println("D-Bus proxy uneventful wait")
|
||||
}
|
||||
}
|
||||
if err := os.Remove(target); err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||
fmt.Println("Error removing dangling D-Bus socket:", err)
|
||||
}
|
||||
done <- struct{}{}
|
||||
}()
|
||||
|
||||
// register early to enable Fatal cleanup
|
||||
state.RegisterDBus(p, &done)
|
||||
dbusAddress = "unix:path=" + target
|
||||
|
||||
if !<-ready {
|
||||
state.Fatal("D-Bus: proxy did not start correctly")
|
||||
}
|
||||
|
||||
a.AppendEnv(dbusSessionBusAddress, dbusAddress)
|
||||
if err := acl.UpdatePerm(target, a.UID(), acl.Read, acl.Write); err != nil {
|
||||
state.Fatal(fmt.Sprintf("Error preparing D-Bus proxy '%s':", dbusAddress), err)
|
||||
} else {
|
||||
state.RegisterRevertPath(target)
|
||||
}
|
||||
if system.V.Verbose {
|
||||
fmt.Printf("Session bus proxy '%s' for address '%s' configured\n", dbusAddress, address)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -166,6 +166,9 @@ func (a *App) commandBuilderMachineCtl() (args []string) {
|
|||
if executable, err := os.Executable(); err != nil {
|
||||
state.Fatal("Error reading executable path:", err)
|
||||
} else {
|
||||
if a.enablements.Has(state.EnableDBus) {
|
||||
innerCommand.WriteString(dbusSessionBusAddress + "=" + "'" + dbusAddress + "' ")
|
||||
}
|
||||
innerCommand.WriteString("exec " + executable + " -V")
|
||||
}
|
||||
args = append(args, innerCommand.String())
|
||||
|
|
|
@ -65,4 +65,23 @@ func BeforeExit() {
|
|||
fmt.Printf("Stripped ACL entry for user '%s' from '%s'\n", u.Username, candidate)
|
||||
}
|
||||
}
|
||||
|
||||
if dbusProxy != nil {
|
||||
if system.V.Verbose {
|
||||
fmt.Println("D-Bus proxy registered, cleaning up")
|
||||
}
|
||||
|
||||
if err := dbusProxy.Close(); err != nil {
|
||||
if errors.Is(err, os.ErrClosed) {
|
||||
if system.V.Verbose {
|
||||
fmt.Println("D-Bus proxy already closed")
|
||||
}
|
||||
} else {
|
||||
fmt.Println("Error closing D-Bus proxy:", err)
|
||||
}
|
||||
}
|
||||
|
||||
// wait for Proxy.Wait to return
|
||||
<-*dbusDone
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
package state
|
||||
|
||||
import "git.ophivana.moe/cat/fortify/dbus"
|
||||
|
||||
var (
|
||||
cleanupCandidate []string
|
||||
enablements *Enablements
|
||||
xcbActionComplete bool
|
||||
|
||||
dbusProxy *dbus.Proxy
|
||||
dbusDone *chan struct{}
|
||||
)
|
||||
|
||||
func RegisterRevertPath(p string) {
|
||||
|
@ -23,3 +28,8 @@ func XcbActionComplete() {
|
|||
}
|
||||
xcbActionComplete = true
|
||||
}
|
||||
|
||||
func RegisterDBus(p *dbus.Proxy, done *chan struct{}) {
|
||||
dbusProxy = p
|
||||
dbusDone = done
|
||||
}
|
||||
|
|
21
main.go
21
main.go
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
|
@ -9,6 +10,7 @@ import (
|
|||
"strconv"
|
||||
"syscall"
|
||||
|
||||
"git.ophivana.moe/cat/fortify/dbus"
|
||||
"git.ophivana.moe/cat/fortify/internal/acl"
|
||||
"git.ophivana.moe/cat/fortify/internal/app"
|
||||
"git.ophivana.moe/cat/fortify/internal/state"
|
||||
|
@ -17,7 +19,9 @@ import (
|
|||
|
||||
var (
|
||||
Version = "impure"
|
||||
|
||||
a *app.App
|
||||
c *dbus.Config
|
||||
)
|
||||
|
||||
func tryVersion() {
|
||||
|
@ -41,6 +45,21 @@ func main() {
|
|||
a = app.New(userName, flag.Args())
|
||||
state.Set(*a.User, a.Command(), a.UID())
|
||||
|
||||
// parse D-Bus config file if applicable
|
||||
if mustDBus {
|
||||
if dbusConfig == "builtin" {
|
||||
c = dbus.NewConfig(dbusID, true, mpris)
|
||||
} else {
|
||||
if f, err := os.Open(dbusConfig); err != nil {
|
||||
state.Fatal("Error opening D-Bus proxy config file:", err)
|
||||
} else {
|
||||
if err = json.NewDecoder(f).Decode(&c); err != nil {
|
||||
state.Fatal("Error parsing D-Bus proxy config file:", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ensure RunDir (e.g. `/run/user/%d/fortify`)
|
||||
if err := os.Mkdir(system.V.RunDir, 0700); err != nil && !errors.Is(err, fs.ErrExist) {
|
||||
state.Fatal("Error creating runtime directory:", err)
|
||||
|
@ -103,7 +122,7 @@ func main() {
|
|||
}
|
||||
|
||||
if mustDBus {
|
||||
a.ShareDBus()
|
||||
a.ShareDBus(c)
|
||||
}
|
||||
|
||||
if mustPulse {
|
||||
|
|
Loading…
Reference in New Issue