From 22e5df43990d87082e3cd516bfdea7bc087c6a11 Mon Sep 17 00:00:00 2001 From: Paul Fawkesley Date: Fri, 19 Oct 2018 16:55:36 +0100 Subject: [PATCH] look for DBUS_SESSION_BUS_ADDRESS if not set if DBUS_SESSION_BUS_ADDRESS is not set (like if running from crontab) we end up with a fresh dbus session. This breaks things like access to secret service (password manager). If DBUS_SESSION_BUS_ADDRESS is empty, look in several locations inside XDG_RUNTIME_DIR (/run/user//) and if an existing dbus session bus address is found, update DBUS_SESSION_BUS_ADDRESS with that and continue. --- conn.go | 7 ++++-- conn_other.go | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/conn.go b/conn.go index 02471a58..b38920ba 100644 --- a/conn.go +++ b/conn.go @@ -77,8 +77,11 @@ func SessionBus() (conn *Conn, err error) { } func getSessionBusAddress() (string, error) { - address := os.Getenv("DBUS_SESSION_BUS_ADDRESS") - if address != "" && address != "autolaunch:" { + if address := os.Getenv("DBUS_SESSION_BUS_ADDRESS"); address != "" && address != "autolaunch:" { + return address, nil + + } else if address := tryDiscoverDbusSessionBusAddress(); address != "" { + os.Setenv("DBUS_SESSION_BUS_ADDRESS", address) return address, nil } return getSessionBusPlatformAddress() diff --git a/conn_other.go b/conn_other.go index 0a73c501..289044a4 100644 --- a/conn_other.go +++ b/conn_other.go @@ -5,8 +5,13 @@ package dbus import ( "bytes" "errors" + "fmt" + "io/ioutil" "os" "os/exec" + "os/user" + "path" + "strings" ) func getSessionBusPlatformAddress() (string, error) { @@ -30,3 +35,57 @@ func getSessionBusPlatformAddress() (string, error) { return addr, nil } +// tryDiscoverDbusSessionBusAddress tries to discover an existing dbus session +// and return the value of its DBUS_SESSION_BUS_ADDRESS. +// It tries different techniques employed by different operating systems, +// returning the first valid address it finds, or an empty string. +// +// * /run/user//bus if this exists, it *is* the bus socket. present on +// Ubuntu 18.04 +// * /run/user//dbus-session: if this exists, it can be parsed for the bus +// address. present on Ubuntu 16.04 +// +// See https://dbus.freedesktop.org/doc/dbus-launch.1.html +func tryDiscoverDbusSessionBusAddress() string { + if runtimeDirectory, err := getRuntimeDirectory(); err == nil { + + if runUserBusFile := path.Join(runtimeDirectory, "bus"); fileExists(runUserBusFile) { + // if /run/user//bus exists, that file itself + // *is* the unix socket, so return its path + return fmt.Sprintf("unix:path=%s", runUserBusFile) + } + if runUserSessionDbusFile := path.Join(runtimeDirectory, "dbus-session"); fileExists(runUserSessionDbusFile) { + // if /run/user//dbus-session exists, it's a + // text file // containing the address of the socket, e.g.: + // DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-E1c73yNqrG + + if f, err := ioutil.ReadFile(runUserSessionDbusFile); err == nil { + fileContent := string(f) + + prefix := "DBUS_SESSION_BUS_ADDRESS=" + + if strings.HasPrefix(fileContent, prefix) { + address := strings.TrimRight(strings.TrimPrefix(fileContent, prefix), "\n\r") + return address + } + } + } + } + return "" +} + +func getRuntimeDirectory() (string, error) { + if currentUser, err := user.Current(); err != nil { + return "", err + } else { + return fmt.Sprintf("/run/user/%s", currentUser.Uid), nil + } +} + +func fileExists(filename string) bool { + if _, err := os.Stat(filename); !os.IsNotExist(err) { + return true + } else { + return false + } +}