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
10
cli.go
10
cli.go
@ -7,7 +7,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
userName string
|
userName string
|
||||||
|
dbusConfig string
|
||||||
|
dbusID string
|
||||||
|
mpris bool
|
||||||
|
|
||||||
mustWayland bool
|
mustWayland bool
|
||||||
mustX bool
|
mustX bool
|
||||||
@ -19,7 +22,10 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
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(&mustWayland, "wayland", false, "Share Wayland socket")
|
||||||
flag.BoolVar(&mustX, "X", false, "Share X11 socket and allow connection")
|
flag.BoolVar(&mustX, "X", false, "Share X11 socket and allow connection")
|
||||||
|
@ -1,14 +1,92 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"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/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)
|
a.setEnablement(state.EnableDBus)
|
||||||
|
|
||||||
// TODO: start xdg-dbus-proxy
|
var binPath, address string
|
||||||
fmt.Println("warn: dbus proxy not implemented")
|
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 {
|
if executable, err := os.Executable(); err != nil {
|
||||||
state.Fatal("Error reading executable path:", err)
|
state.Fatal("Error reading executable path:", err)
|
||||||
} else {
|
} else {
|
||||||
|
if a.enablements.Has(state.EnableDBus) {
|
||||||
|
innerCommand.WriteString(dbusSessionBusAddress + "=" + "'" + dbusAddress + "' ")
|
||||||
|
}
|
||||||
innerCommand.WriteString("exec " + executable + " -V")
|
innerCommand.WriteString("exec " + executable + " -V")
|
||||||
}
|
}
|
||||||
args = append(args, innerCommand.String())
|
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)
|
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
|
package state
|
||||||
|
|
||||||
|
import "git.ophivana.moe/cat/fortify/dbus"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
cleanupCandidate []string
|
cleanupCandidate []string
|
||||||
enablements *Enablements
|
enablements *Enablements
|
||||||
xcbActionComplete bool
|
xcbActionComplete bool
|
||||||
|
|
||||||
|
dbusProxy *dbus.Proxy
|
||||||
|
dbusDone *chan struct{}
|
||||||
)
|
)
|
||||||
|
|
||||||
func RegisterRevertPath(p string) {
|
func RegisterRevertPath(p string) {
|
||||||
@ -23,3 +28,8 @@ func XcbActionComplete() {
|
|||||||
}
|
}
|
||||||
xcbActionComplete = true
|
xcbActionComplete = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RegisterDBus(p *dbus.Proxy, done *chan struct{}) {
|
||||||
|
dbusProxy = p
|
||||||
|
dbusDone = done
|
||||||
|
}
|
||||||
|
23
main.go
23
main.go
@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -9,6 +10,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"git.ophivana.moe/cat/fortify/dbus"
|
||||||
"git.ophivana.moe/cat/fortify/internal/acl"
|
"git.ophivana.moe/cat/fortify/internal/acl"
|
||||||
"git.ophivana.moe/cat/fortify/internal/app"
|
"git.ophivana.moe/cat/fortify/internal/app"
|
||||||
"git.ophivana.moe/cat/fortify/internal/state"
|
"git.ophivana.moe/cat/fortify/internal/state"
|
||||||
@ -17,7 +19,9 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
Version = "impure"
|
Version = "impure"
|
||||||
a *app.App
|
|
||||||
|
a *app.App
|
||||||
|
c *dbus.Config
|
||||||
)
|
)
|
||||||
|
|
||||||
func tryVersion() {
|
func tryVersion() {
|
||||||
@ -41,6 +45,21 @@ func main() {
|
|||||||
a = app.New(userName, flag.Args())
|
a = app.New(userName, flag.Args())
|
||||||
state.Set(*a.User, a.Command(), a.UID())
|
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`)
|
// ensure RunDir (e.g. `/run/user/%d/fortify`)
|
||||||
if err := os.Mkdir(system.V.RunDir, 0700); err != nil && !errors.Is(err, fs.ErrExist) {
|
if err := os.Mkdir(system.V.RunDir, 0700); err != nil && !errors.Is(err, fs.ErrExist) {
|
||||||
state.Fatal("Error creating runtime directory:", err)
|
state.Fatal("Error creating runtime directory:", err)
|
||||||
@ -103,7 +122,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if mustDBus {
|
if mustDBus {
|
||||||
a.ShareDBus()
|
a.ShareDBus(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
if mustPulse {
|
if mustPulse {
|
||||||
|
Loading…
Reference in New Issue
Block a user