diff options
| author | Ophestra <cat@gensokyo.uk> | 2025-07-02 21:52:07 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2025-07-02 21:52:07 +0900 |
| commit | 82561d62b66f17c05604e87f18187bb3a91f00d2 (patch) | |
| tree | c1543f85b4458b7d5cb2cf7b1baa9dee318debfe /dbus | |
| parent | eec021cc4b4eb42bc9c8311755826828bfba1996 (diff) | |
system: move system access packages
These packages loosely belong in the "system" package and "system" provides high level wrappers for all of them.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'dbus')
| -rw-r--r-- | dbus/address.go | 186 | ||||
| -rw-r--r-- | dbus/address_escape_test.go | 55 | ||||
| -rw-r--r-- | dbus/address_test.go | 119 | ||||
| -rw-r--r-- | dbus/config.go | 162 | ||||
| -rw-r--r-- | dbus/config_test.go | 159 | ||||
| -rw-r--r-- | dbus/dbus.go | 40 | ||||
| -rw-r--r-- | dbus/dbus_test.go | 213 | ||||
| -rw-r--r-- | dbus/export_test.go | 13 | ||||
| -rw-r--r-- | dbus/proc.go | 189 | ||||
| -rw-r--r-- | dbus/proxy.go | 117 | ||||
| -rw-r--r-- | dbus/samples_test.go | 228 | ||||
| -rw-r--r-- | dbus/stub_test.go | 9 | ||||
| -rw-r--r-- | dbus/testdata/dev.vencord.Vesktop.json | 18 | ||||
| -rw-r--r-- | dbus/testdata/org.chromium.Chromium+.json | 9 | ||||
| -rw-r--r-- | dbus/testdata/org.chromium.Chromium.json | 24 | ||||
| -rw-r--r-- | dbus/testdata/uk.gensokyo.CrashTestDummy.json | 21 |
16 files changed, 0 insertions, 1562 deletions
diff --git a/dbus/address.go b/dbus/address.go deleted file mode 100644 index bec49e62..00000000 --- a/dbus/address.go +++ /dev/null @@ -1,186 +0,0 @@ -package dbus - -import ( - "bytes" - "encoding/hex" - "errors" - "fmt" - "slices" -) - -type AddrEntry struct { - Method string `json:"method"` - Values [][2]string `json:"values"` -} - -// Parse parses D-Bus address according to -// https://dbus.freedesktop.org/doc/dbus-specification.html#addresses -func Parse(addr []byte) ([]AddrEntry, error) { - // Look for a semicolon - address := bytes.Split(bytes.TrimSuffix(addr, []byte{';'}), []byte{';'}) - - // Allocate for entries - v := make([]AddrEntry, len(address)) - - for i, s := range address { - var pairs [][]byte - - // Look for the colon : - if method, list, ok := bytes.Cut(s, []byte{':'}); !ok { - return v, &BadAddressError{ErrNoColon, i, s, -1, nil} - } else { - pairs = bytes.Split(list, []byte{','}) - v[i].Method = string(method) - v[i].Values = make([][2]string, len(pairs)) - } - - for j, pair := range pairs { - key, value, ok := bytes.Cut(pair, []byte{'='}) - if !ok { - return v, &BadAddressError{ErrBadPairSep, i, s, j, pair} - } - if len(key) == 0 { - return v, &BadAddressError{ErrBadPairKey, i, s, j, pair} - } - if len(value) == 0 { - return v, &BadAddressError{ErrBadPairVal, i, s, j, pair} - } - v[i].Values[j][0] = string(key) - - if val, errno := unescapeValue(value); errno != errSuccess { - return v, &BadAddressError{errno, i, s, j, pair} - } else { - v[i].Values[j][1] = string(val) - } - } - } - - return v, nil -} - -func unescapeValue(v []byte) (val []byte, errno ParseError) { - if l := len(v) - (bytes.Count(v, []byte{'%'}) * 2); l < 0 { - errno = ErrBadValLength - return - } else { - val = make([]byte, l) - } - - var i, skip int - for iu, b := range v { - if skip > 0 { - skip-- - continue - } - - if ib := bytes.IndexByte([]byte("-_/.\\*"), b); ib != -1 { // - // _/.\* - goto opt - } else if b >= '0' && b <= '9' { // 0-9 - goto opt - } else if b >= 'A' && b <= 'Z' { // A-Z - goto opt - } else if b >= 'a' && b <= 'z' { // a-z - goto opt - } - - if b != '%' { - errno = ErrBadValByte - break - } - - skip += 2 - if iu+2 >= len(v) { - errno = ErrBadValHexLength - break - } - if c, err := hex.Decode(val[i:i+1], v[iu+1:iu+3]); err != nil { - if errors.As(err, new(hex.InvalidByteError)) { - errno = ErrBadValHexByte - break - } - // unreachable - panic(err.Error()) - } else if c != 1 { - // unreachable - panic(fmt.Sprintf("invalid decode length %d", c)) - } - i++ - continue - - opt: - val[i] = b - i++ - } - - return -} - -type ParseError uint8 - -func (e ParseError) Error() string { - switch e { - case errSuccess: - panic("attempted to return success as error") - case ErrNoColon: - return "address does not contain a colon" - case ErrBadPairSep: - return "'=' character not found" - case ErrBadPairKey: - return "'=' character has no key preceding it" - case ErrBadPairVal: - return "'=' character has no value following it" - case ErrBadValLength: - return "unescaped value has impossible length" - case ErrBadValByte: - return "in D-Bus address, characters other than [-0-9A-Za-z_/.\\*] should have been escaped" - case ErrBadValHexLength: - return "in D-Bus address, percent character was not followed by two hex digits" - case ErrBadValHexByte: - return "in D-Bus address, percent character was followed by characters other than hex digits" - - default: - return fmt.Sprintf("parse error %d", e) - } -} - -const ( - errSuccess ParseError = iota - ErrNoColon - ErrBadPairSep - ErrBadPairKey - ErrBadPairVal - ErrBadValLength - ErrBadValByte - ErrBadValHexLength - ErrBadValHexByte -) - -type BadAddressError struct { - // error type - Type ParseError - - // bad entry position - EntryPos int - // bad entry value - EntryVal []byte - - // bad pair position - PairPos int - // bad pair value - PairVal []byte -} - -func (a *BadAddressError) Is(err error) bool { - var b *BadAddressError - return errors.As(err, &b) && a.Type == b.Type && - a.EntryPos == b.EntryPos && slices.Equal(a.EntryVal, b.EntryVal) && - a.PairPos == b.PairPos && slices.Equal(a.PairVal, b.PairVal) -} - -func (a *BadAddressError) Error() string { - return a.Type.Error() -} - -func (a *BadAddressError) Unwrap() error { - return a.Type -} diff --git a/dbus/address_escape_test.go b/dbus/address_escape_test.go deleted file mode 100644 index 3ea2cd26..00000000 --- a/dbus/address_escape_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package dbus - -import ( - "testing" -) - -func TestUnescapeValue(t *testing.T) { - testCases := []struct { - value string - want string - wantErr ParseError - }{ - // upstream test cases - {value: "abcde", want: "abcde"}, - {value: "", want: ""}, - {value: "%20%20", want: " "}, - {value: "%24", want: "$"}, - {value: "%25", want: "%"}, - {value: "abc%24", want: "abc$"}, - {value: "%24abc", want: "$abc"}, - {value: "abc%24abc", want: "abc$abc"}, - {value: "/", want: "/"}, - {value: "-", want: "-"}, - {value: "_", want: "_"}, - {value: "A", want: "A"}, - {value: "I", want: "I"}, - {value: "Z", want: "Z"}, - {value: "a", want: "a"}, - {value: "i", want: "i"}, - {value: "z", want: "z"}, - /* Bug: https://bugs.freedesktop.org/show_bug.cgi?id=53499 */ - {value: "%c3%b6", want: "\xc3\xb6"}, - - {value: "%a", wantErr: ErrBadValHexLength}, - {value: "%q", wantErr: ErrBadValHexLength}, - {value: "%az", wantErr: ErrBadValHexByte}, - {value: "%%", wantErr: ErrBadValLength}, - {value: "%$$", wantErr: ErrBadValHexByte}, - {value: "abc%a", wantErr: ErrBadValHexLength}, - {value: "%axyz", wantErr: ErrBadValHexByte}, - {value: "%", wantErr: ErrBadValLength}, - {value: "$", wantErr: ErrBadValByte}, - {value: " ", wantErr: ErrBadValByte}, - } - - for _, tc := range testCases { - t.Run("unescape "+tc.value, func(t *testing.T) { - if got, errno := unescapeValue([]byte(tc.value)); errno != tc.wantErr { - t.Errorf("unescapeValue() errno = %v, wantErr %v", errno, tc.wantErr) - } else if tc.wantErr == errSuccess && string(got) != tc.want { - t.Errorf("unescapeValue() = %q, want %q", got, tc.want) - } - }) - } -} diff --git a/dbus/address_test.go b/dbus/address_test.go deleted file mode 100644 index 8b66d141..00000000 --- a/dbus/address_test.go +++ /dev/null @@ -1,119 +0,0 @@ -package dbus_test - -import ( - "errors" - "reflect" - "testing" - - "git.gensokyo.uk/security/hakurei/dbus" -) - -func TestParse(t *testing.T) { - testCases := []struct { - name string - addr string - want []dbus.AddrEntry - wantErr error - }{ - { - name: "simple session unix", - addr: "unix:path=/run/user/1971/bus", - want: []dbus.AddrEntry{{ - Method: "unix", - Values: [][2]string{{"path", "/run/user/1971/bus"}}, - }}, - }, - { - name: "simple upper escape", - addr: "debug:name=Test,cat=cute,escaped=%c3%b6", - want: []dbus.AddrEntry{{ - Method: "debug", - Values: [][2]string{ - {"name", "Test"}, - {"cat", "cute"}, - {"escaped", "\xc3\xb6"}, - }, - }}, - }, - { - name: "simple bad escape", - addr: "debug:name=%", - wantErr: &dbus.BadAddressError{Type: dbus.ErrBadValLength, - EntryPos: 0, EntryVal: []byte("debug:name=%"), PairPos: 0, PairVal: []byte("name=%")}, - }, - - // upstream test cases - { - name: "full address success", - addr: "unix:path=/tmp/foo;debug:name=test,sliff=sloff;", - want: []dbus.AddrEntry{ - {Method: "unix", Values: [][2]string{{"path", "/tmp/foo"}}}, - {Method: "debug", Values: [][2]string{{"name", "test"}, {"sliff", "sloff"}}}, - }, - }, - { - name: "empty address", - addr: "", - wantErr: &dbus.BadAddressError{Type: dbus.ErrNoColon, - EntryVal: []byte{}, PairPos: -1}, - }, - { - name: "no body", - addr: "foo", - wantErr: &dbus.BadAddressError{Type: dbus.ErrNoColon, - EntryPos: 0, EntryVal: []byte("foo"), PairPos: -1}, - }, - { - name: "no pair separator", - addr: "foo:bar", - wantErr: &dbus.BadAddressError{Type: dbus.ErrBadPairSep, - EntryPos: 0, EntryVal: []byte("foo:bar"), PairPos: 0, PairVal: []byte("bar")}, - }, - { - name: "no pair separator multi pair", - addr: "foo:bar,baz", - wantErr: &dbus.BadAddressError{Type: dbus.ErrBadPairSep, - EntryPos: 0, EntryVal: []byte("foo:bar,baz"), PairPos: 0, PairVal: []byte("bar")}, - }, - { - name: "no pair separator single valid pair", - addr: "foo:bar=foo,baz", - wantErr: &dbus.BadAddressError{Type: dbus.ErrBadPairSep, - EntryPos: 0, EntryVal: []byte("foo:bar=foo,baz"), PairPos: 1, PairVal: []byte("baz")}, - }, - { - name: "no body single valid address", - addr: "foo:bar=foo;baz", - wantErr: &dbus.BadAddressError{Type: dbus.ErrNoColon, - EntryPos: 1, EntryVal: []byte("baz"), PairPos: -1}, - }, - { - name: "no key", - addr: "foo:=foo", - wantErr: &dbus.BadAddressError{Type: dbus.ErrBadPairKey, - EntryPos: 0, EntryVal: []byte("foo:=foo"), PairPos: 0, PairVal: []byte("=foo")}, - }, - { - name: "no value", - addr: "foo:foo=", - wantErr: &dbus.BadAddressError{Type: dbus.ErrBadPairVal, - EntryPos: 0, EntryVal: []byte("foo:foo="), PairPos: 0, PairVal: []byte("foo=")}, - }, - { - name: "no pair separator single valid pair trailing", - addr: "foo:foo,bar=baz", - wantErr: &dbus.BadAddressError{Type: dbus.ErrBadPairSep, - EntryPos: 0, EntryVal: []byte("foo:foo,bar=baz"), PairPos: 0, PairVal: []byte("foo")}, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - if got, err := dbus.Parse([]byte(tc.addr)); !errors.Is(err, tc.wantErr) { - t.Errorf("Parse() error = %v, wantErr %v", err, tc.wantErr) - } else if tc.wantErr == nil && !reflect.DeepEqual(got, tc.want) { - t.Errorf("Parse() = %#v, want %#v", got, tc.want) - } - }) - } -} diff --git a/dbus/config.go b/dbus/config.go deleted file mode 100644 index 3f66b2bb..00000000 --- a/dbus/config.go +++ /dev/null @@ -1,162 +0,0 @@ -package dbus - -import ( - "encoding/json" - "errors" - "io" - "os" - "strings" -) - -// ProxyPair is an upstream dbus address and a downstream socket path. -type ProxyPair [2]string - -type Config struct { - // See set 'see' policy for NAME (--see=NAME) - See []string `json:"see"` - // Talk set 'talk' policy for NAME (--talk=NAME) - Talk []string `json:"talk"` - // Own set 'own' policy for NAME (--own=NAME) - Own []string `json:"own"` - - // Call set RULE for calls on NAME (--call=NAME=RULE) - Call map[string]string `json:"call"` - // Broadcast set RULE for broadcasts from NAME (--broadcast=NAME=RULE) - Broadcast map[string]string `json:"broadcast"` - - Log bool `json:"log,omitempty"` - Filter bool `json:"filter"` -} - -func (c *Config) interfaces(yield func(string) bool) { - for _, iface := range c.See { - if !yield(iface) { - return - } - } - for _, iface := range c.Talk { - if !yield(iface) { - return - } - } - for _, iface := range c.Own { - if !yield(iface) { - return - } - } - - for iface := range c.Call { - if !yield(iface) { - return - } - } - for iface := range c.Broadcast { - if !yield(iface) { - return - } - } -} - -func (c *Config) checkInterfaces(segment string) error { - for iface := range c.interfaces { - /* - xdg-dbus-proxy fails without output when this condition is not met: - char *dot = strrchr (filter->interface, '.'); - if (dot != NULL) - { - *dot = 0; - if (strcmp (dot + 1, "*") != 0) - filter->member = g_strdup (dot + 1); - } - - trim ".*" since they are removed before searching for '.': - if (g_str_has_suffix (name, ".*")) - { - name[strlen (name) - 2] = 0; - wildcard = TRUE; - } - */ - if strings.IndexByte(strings.TrimSuffix(iface, ".*"), '.') == -1 { - return &BadInterfaceError{iface, segment} - } - } - return nil -} - -func (c *Config) Args(bus ProxyPair) (args []string) { - argc := 2 + len(c.See) + len(c.Talk) + len(c.Own) + len(c.Call) + len(c.Broadcast) - if c.Log { - argc++ - } - if c.Filter { - argc++ - } - - args = make([]string, 0, argc) - args = append(args, bus[0], bus[1]) - if c.Filter { - args = append(args, "--filter") - } - for _, name := range c.See { - args = append(args, "--see="+name) - } - for _, name := range c.Talk { - args = append(args, "--talk="+name) - } - for _, name := range c.Own { - args = append(args, "--own="+name) - } - for name, rule := range c.Call { - args = append(args, "--call="+name+"="+rule) - } - for name, rule := range c.Broadcast { - args = append(args, "--broadcast="+name+"="+rule) - } - if c.Log { - args = append(args, "--log") - } - - return -} - -func (c *Config) Load(r io.Reader) error { return json.NewDecoder(r).Decode(&c) } - -// NewConfigFromFile opens the target config file at path and parses its contents into *Config. -func NewConfigFromFile(path string) (*Config, error) { - if f, err := os.Open(path); err != nil { - return nil, err - } else { - c := new(Config) - err1 := c.Load(f) - err = f.Close() - - return c, errors.Join(err1, err) - } -} - -// NewConfig returns a reference to a Config struct with optional defaults. -// If id is an empty string own defaults are omitted. -func NewConfig(id string, defaults, mpris bool) (c *Config) { - c = &Config{ - Call: make(map[string]string), - Broadcast: make(map[string]string), - - Filter: true, - } - - if defaults { - c.Talk = []string{"org.freedesktop.DBus", "org.freedesktop.Notifications"} - - c.Call["org.freedesktop.portal.*"] = "*" - c.Broadcast["org.freedesktop.portal.*"] = "@/org/freedesktop/portal/*" - - if id != "" { - c.Own = []string{id + ".*"} - if mpris { - c.Own = append(c.Own, "org.mpris.MediaPlayer2."+id+".*") - } - } - } - - return -} diff --git a/dbus/config_test.go b/dbus/config_test.go deleted file mode 100644 index 2d5b24e4..00000000 --- a/dbus/config_test.go +++ /dev/null @@ -1,159 +0,0 @@ -package dbus_test - -import ( - "errors" - "os" - "path" - "reflect" - "slices" - "strings" - "testing" - - "git.gensokyo.uk/security/hakurei/dbus" -) - -func TestConfig_Args(t *testing.T) { - for _, tc := range makeTestCases() { - if tc.wantErr { - // args does not check for nulls - continue - } - - t.Run("build arguments for "+tc.id, func(t *testing.T) { - if got := tc.c.Args(tc.bus); !slices.Equal(got, tc.want) { - t.Errorf("Args(%q) = %v, want %v", - tc.bus, - got, tc.want) - } - }) - } -} - -func TestNewConfigFromFile(t *testing.T) { - for _, tc := range makeTestCases() { - name := new(strings.Builder) - name.WriteString("parse configuration file for application ") - name.WriteString(tc.id) - if tc.wantErr { - name.WriteString(" with unexpected results") - } - - samplePath := path.Join("testdata", tc.id+".json") - - t.Run(name.String(), func(t *testing.T) { - got, err := dbus.NewConfigFromFile(samplePath) - if errors.Is(err, os.ErrNotExist) != tc.wantErrF { - t.Errorf("NewConfigFromFile(%q) error = %v, wantErrF %v", - samplePath, - err, tc.wantErrF) - return - } - - if tc.wantErrF { - return - } - - if !tc.wantErr && !reflect.DeepEqual(got, tc.c) { - t.Errorf("NewConfigFromFile(%q) got = %v, want %v", - samplePath, - got, tc.c) - } - if tc.wantErr && reflect.DeepEqual(got, tc.c) { - t.Errorf("NewConfigFromFile(%q) got = %v, wantErr %v", - samplePath, - got, tc.wantErr) - } - }) - } -} - -func TestNewConfig(t *testing.T) { - ids := [...]string{"org.chromium.Chromium", "dev.vencord.Vesktop"} - - type newTestCase struct { - id string - args [2]bool - want *dbus.Config - } - - // populate tests from IDs in generic tests - tcs := make([]newTestCase, 0, (len(ids)+1)*4) - // tests for defaults without id - tcs = append(tcs, - newTestCase{"", [2]bool{false, false}, &dbus.Config{ - Call: make(map[string]string), - Broadcast: make(map[string]string), - Filter: true, - }}, - newTestCase{"", [2]bool{false, true}, &dbus.Config{ - Call: make(map[string]string), - Broadcast: make(map[string]string), - Filter: true, - }}, - newTestCase{"", [2]bool{true, false}, &dbus.Config{ - Talk: []string{"org.freedesktop.DBus", "org.freedesktop.Notifications"}, - Call: map[string]string{"org.freedesktop.portal.*": "*"}, - Broadcast: map[string]string{"org.freedesktop.portal.*": "@/org/freedesktop/portal/*"}, - Filter: true, - }}, - newTestCase{"", [2]bool{true, true}, &dbus.Config{ - Talk: []string{"org.freedesktop.DBus", "org.freedesktop.Notifications"}, - Call: map[string]string{"org.freedesktop.portal.*": "*"}, - Broadcast: map[string]string{"org.freedesktop.portal.*": "@/org/freedesktop/portal/*"}, - Filter: true, - }}, - ) - for _, id := range ids { - tcs = append(tcs, - newTestCase{id, [2]bool{false, false}, &dbus.Config{ - Call: make(map[string]string), - Broadcast: make(map[string]string), - Filter: true, - }}, - newTestCase{id, [2]bool{false, true}, &dbus.Config{ - Call: make(map[string]string), - Broadcast: make(map[string]string), - Filter: true, - }}, - newTestCase{id, [2]bool{true, false}, &dbus.Config{ - Talk: []string{"org.freedesktop.DBus", "org.freedesktop.Notifications"}, - Own: []string{id + ".*"}, - Call: map[string]string{"org.freedesktop.portal.*": "*"}, - Broadcast: map[string]string{"org.freedesktop.portal.*": "@/org/freedesktop/portal/*"}, - Filter: true, - }}, - newTestCase{id, [2]bool{true, true}, &dbus.Config{ - Talk: []string{"org.freedesktop.DBus", "org.freedesktop.Notifications"}, - Own: []string{id + ".*", "org.mpris.MediaPlayer2." + id + ".*"}, - Call: map[string]string{"org.freedesktop.portal.*": "*"}, - Broadcast: map[string]string{"org.freedesktop.portal.*": "@/org/freedesktop/portal/*"}, - Filter: true, - }}, - ) - } - - for _, tc := range tcs { - name := new(strings.Builder) - name.WriteString("create new configuration struct") - - if tc.args[0] { - name.WriteString(" with builtin defaults") - if tc.args[1] { - name.WriteString(" (mpris)") - } - } - - if tc.id != "" { - name.WriteString(" for application ID ") - name.WriteString(tc.id) - } - - t.Run(name.String(), func(t *testing.T) { - if gotC := dbus.NewConfig(tc.id, tc.args[0], tc.args[1]); !reflect.DeepEqual(gotC, tc.want) { - t.Errorf("NewConfig(%q, %t, %t) = %v, want %v", - tc.id, tc.args[0], tc.args[1], - gotC, tc.want) - } - }) - } -} diff --git a/dbus/dbus.go b/dbus/dbus.go deleted file mode 100644 index c5b4e812..00000000 --- a/dbus/dbus.go +++ /dev/null @@ -1,40 +0,0 @@ -// Package dbus wraps xdg-dbus-proxy and implements configuration and sandboxing of the underlying helper process. -package dbus - -import ( - "fmt" - "os" - "sync" -) - -const ( - SessionBusAddress = "DBUS_SESSION_BUS_ADDRESS" - SystemBusAddress = "DBUS_SYSTEM_BUS_ADDRESS" -) - -var ( - addresses [2]string - addressOnce sync.Once -) - -func Address() (session, system string) { - addressOnce.Do(func() { - // resolve upstream session bus address - if addr, ok := os.LookupEnv(SessionBusAddress); !ok { - // fall back to default format - addresses[0] = fmt.Sprintf("unix:path=/run/user/%d/bus", os.Getuid()) - } else { - addresses[0] = addr - } - - // resolve upstream system bus address - if addr, ok := os.LookupEnv(SystemBusAddress); !ok { - // fall back to default hardcoded value - addresses[1] = "unix:path=/run/dbus/system_bus_socket" - } else { - addresses[1] = addr - } - }) - - return addresses[0], addresses[1] -} diff --git a/dbus/dbus_test.go b/dbus/dbus_test.go deleted file mode 100644 index caf70980..00000000 --- a/dbus/dbus_test.go +++ /dev/null @@ -1,213 +0,0 @@ -package dbus_test - -import ( - "bytes" - "context" - "errors" - "fmt" - "io" - "os" - "os/exec" - "strings" - "syscall" - "testing" - "time" - - "git.gensokyo.uk/security/hakurei" - "git.gensokyo.uk/security/hakurei/dbus" - "git.gensokyo.uk/security/hakurei/helper" - "git.gensokyo.uk/security/hakurei/internal" - "git.gensokyo.uk/security/hakurei/internal/hlog" -) - -func TestFinalise(t *testing.T) { - if _, err := dbus.Finalise(dbus.ProxyPair{}, dbus.ProxyPair{}, nil, nil); !errors.Is(err, syscall.EBADE) { - t.Errorf("Finalise: error = %v, want %v", - err, syscall.EBADE) - } - - for id, tc := range testCasePairs() { - t.Run("create final for "+id, func(t *testing.T) { - var wt io.WriterTo - if v, err := dbus.Finalise(tc[0].bus, tc[1].bus, tc[0].c, tc[1].c); (errors.Is(err, syscall.EINVAL)) != tc[0].wantErr { - t.Errorf("Finalise: error = %v, wantErr %v", - err, tc[0].wantErr) - return - } else { - wt = v - } - - // rest of the tests happen for sealed instances - if tc[0].wantErr { - return - } - - // build null-terminated string from wanted args - want := new(strings.Builder) - args := append(tc[0].want, tc[1].want...) - for _, arg := range args { - want.WriteString(arg) - want.WriteByte(0) - } - - got := new(strings.Builder) - if _, err := wt.WriteTo(got); err != nil { - t.Errorf("WriteTo: error = %v", err) - } - - if want.String() != got.String() { - t.Errorf("Seal: %q, want %q", - got.String(), want.String()) - } - }) - } -} - -func TestProxyStartWaitCloseString(t *testing.T) { - oldWaitDelay := helper.WaitDelay - helper.WaitDelay = 16 * time.Second - t.Cleanup(func() { helper.WaitDelay = oldWaitDelay }) - - t.Run("sandbox", func(t *testing.T) { - proxyName := dbus.ProxyName - dbus.ProxyName = os.Args[0] - t.Cleanup(func() { dbus.ProxyName = proxyName }) - testProxyFinaliseStartWaitCloseString(t, true) - }) - t.Run("direct", func(t *testing.T) { testProxyFinaliseStartWaitCloseString(t, false) }) -} - -func testProxyFinaliseStartWaitCloseString(t *testing.T, useSandbox bool) { - var p *dbus.Proxy - - t.Run("string for nil proxy", func(t *testing.T) { - want := "(invalid dbus proxy)" - if got := p.String(); got != want { - t.Errorf("String: %q, want %q", - got, want) - } - }) - - t.Run("invalid start", func(t *testing.T) { - if !useSandbox { - p = dbus.NewDirect(t.Context(), nil, nil) - } else { - p = dbus.New(t.Context(), nil, nil) - } - - if err := p.Start(); !errors.Is(err, syscall.ENOTRECOVERABLE) { - t.Errorf("Start: error = %q, wantErr %q", - err, syscall.ENOTRECOVERABLE) - return - } - }) - - for id, tc := range testCasePairs() { - // this test does not test errors - if tc[0].wantErr { - continue - } - - t.Run("proxy for "+id, func(t *testing.T) { - var final *dbus.Final - t.Run("finalise", func(t *testing.T) { - if v, err := dbus.Finalise(tc[0].bus, tc[1].bus, tc[0].c, tc[1].c); err != nil { - t.Errorf("Finalise: error = %v, wantErr %v", - err, tc[0].wantErr) - return - } else { - final = v - } - }) - - ctx, cancel := context.WithTimeout(t.Context(), 5*time.Second) - defer cancel() - if !useSandbox { - p = dbus.NewDirect(ctx, final, nil) - } else { - p = dbus.New(ctx, final, nil) - } - - p.CommandContext = func(ctx context.Context) (cmd *exec.Cmd) { - return exec.CommandContext(ctx, os.Args[0], "-test.v", - "-test.run=TestHelperInit", "--", "init") - } - p.CmdF = func(v any) { - if useSandbox { - container := v.(*hakurei.Container) - if container.Args[0] != dbus.ProxyName { - panic(fmt.Sprintf("unexpected argv0 %q", os.Args[0])) - } - container.Args = append([]string{os.Args[0], "-test.run=TestHelperStub", "--"}, container.Args[1:]...) - } else { - cmd := v.(*exec.Cmd) - if cmd.Args[0] != dbus.ProxyName { - panic(fmt.Sprintf("unexpected argv0 %q", os.Args[0])) - } - cmd.Err = nil - cmd.Path = os.Args[0] - cmd.Args = append([]string{os.Args[0], "-test.run=TestHelperStub", "--"}, cmd.Args[1:]...) - } - } - p.FilterF = func(v []byte) []byte { return bytes.SplitN(v, []byte("TestHelperInit\n"), 2)[1] } - output := new(strings.Builder) - - t.Run("invalid wait", func(t *testing.T) { - wantErr := "dbus: not started" - if err := p.Wait(); err == nil || err.Error() != wantErr { - t.Errorf("Wait: error = %v, wantErr %v", - err, wantErr) - } - }) - - t.Run("string", func(t *testing.T) { - want := "(unused dbus proxy)" - if got := p.String(); got != want { - t.Errorf("String: %q, want %q", - got, want) - return - } - }) - - t.Run("start", func(t *testing.T) { - if err := p.Start(); err != nil { - t.Fatalf("Start: error = %v", - err) - } - - t.Run("string", func(t *testing.T) { - wantSubstr := fmt.Sprintf("%s -test.run=TestHelperStub -- --args=3 --fd=4", os.Args[0]) - if useSandbox { - wantSubstr = fmt.Sprintf(`argv: ["%s" "-test.run=TestHelperStub" "--" "--args=3" "--fd=4"], filter: true, rules: 0, flags: 0x1, presets: 0xf`, os.Args[0]) - } - if got := p.String(); !strings.Contains(got, wantSubstr) { - t.Errorf("String: %q, want %q", - got, wantSubstr) - return - } - }) - - t.Run("wait", func(t *testing.T) { - done := make(chan struct{}) - go func() { - if err := p.Wait(); err != nil { - t.Errorf("Wait: error = %v\noutput: %s", - err, output.String()) - } - close(done) - }() - p.Close() - <-done - }) - }) - }) - } -} - -func TestHelperInit(t *testing.T) { - if len(os.Args) != 5 || os.Args[4] != "init" { - return - } - hakurei.SetOutput(hlog.Output{}) - hakurei.Init(hlog.Prepare, internal.InstallOutput) -} diff --git a/dbus/export_test.go b/dbus/export_test.go deleted file mode 100644 index 574a4a73..00000000 --- a/dbus/export_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package dbus - -import ( - "context" - "io" -) - -// NewDirect returns a new instance of [Proxy] with its sandbox disabled. -func NewDirect(ctx context.Context, final *Final, output io.Writer) *Proxy { - p := New(ctx, final, output) - p.useSandbox = false - return p -} diff --git a/dbus/proc.go b/dbus/proc.go deleted file mode 100644 index e8cccd5f..00000000 --- a/dbus/proc.go +++ /dev/null @@ -1,189 +0,0 @@ -package dbus - -import ( - "context" - "errors" - "os" - "os/exec" - "path" - "path/filepath" - "slices" - "strconv" - "syscall" - - "git.gensokyo.uk/security/hakurei" - "git.gensokyo.uk/security/hakurei/helper" - "git.gensokyo.uk/security/hakurei/ldd" - "git.gensokyo.uk/security/hakurei/seccomp" -) - -// Start starts and configures a D-Bus proxy process. -func (p *Proxy) Start() error { - if p.final == nil || p.final.WriterTo == nil { - return syscall.ENOTRECOVERABLE - } - - p.mu.Lock() - defer p.mu.Unlock() - p.pmu.Lock() - defer p.pmu.Unlock() - - if p.cancel != nil || p.cause != nil { - return errors.New("dbus: already started") - } - - ctx, cancel := context.WithCancelCause(p.ctx) - - if !p.useSandbox { - p.helper = helper.NewDirect(ctx, p.name, p.final, true, argF, func(cmd *exec.Cmd) { - if p.CmdF != nil { - p.CmdF(cmd) - } - if p.output != nil { - cmd.Stdout, cmd.Stderr = p.output, p.output - } - cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} - cmd.Env = make([]string, 0) - }, nil) - } else { - toolPath := p.name - if filepath.Base(p.name) == p.name { - if s, err := exec.LookPath(p.name); err != nil { - return err - } else { - toolPath = s - } - } - - var libPaths []string - if entries, err := ldd.ExecFilter(ctx, p.CommandContext, p.FilterF, toolPath); err != nil { - return err - } else { - libPaths = ldd.Path(entries) - } - - p.helper = helper.New( - ctx, toolPath, - p.final, true, - argF, func(container *hakurei.Container) { - container.SeccompFlags |= seccomp.AllowMultiarch - container.SeccompPresets |= seccomp.PresetStrict - container.Hostname = "hakurei-dbus" - container.CommandContext = p.CommandContext - if p.output != nil { - container.Stdout, container.Stderr = p.output, p.output - } - - if p.CmdF != nil { - p.CmdF(container) - } - - // these lib paths are unpredictable, so mount them first so they cannot cover anything - for _, name := range libPaths { - container.Bind(name, name, 0) - } - - // upstream bus directories - upstreamPaths := make([]string, 0, 2) - for _, addr := range [][]AddrEntry{p.final.SessionUpstream, p.final.SystemUpstream} { - for _, ent := range addr { - if ent.Method != "unix" { - continue - } - for _, pair := range ent.Values { - if pair[0] != "path" || !path.IsAbs(pair[1]) { - continue - } - upstreamPaths = append(upstreamPaths, path.Dir(pair[1])) - } - } - } - slices.Sort(upstreamPaths) - upstreamPaths = slices.Compact(upstreamPaths) - for _, name := range upstreamPaths { - container.Bind(name, name, 0) - } - - // parent directories of bind paths - sockDirPaths := make([]string, 0, 2) - if d := path.Dir(p.final.Session[1]); path.IsAbs(d) { - sockDirPaths = append(sockDirPaths, d) - } - if d := path.Dir(p.final.System[1]); path.IsAbs(d) { - sockDirPaths = append(sockDirPaths, d) - } - slices.Sort(sockDirPaths) - sockDirPaths = slices.Compact(sockDirPaths) - for _, name := range sockDirPaths { - container.Bind(name, name, hakurei.BindWritable) - } - - // xdg-dbus-proxy bin path - binPath := path.Dir(toolPath) - container.Bind(binPath, binPath, 0) - }, nil) - } - - if err := p.helper.Start(); err != nil { - cancel(err) - p.helper = nil - return err - } - - p.cancel, p.cause = cancel, func() error { return context.Cause(ctx) } - return nil -} - -var proxyClosed = errors.New("proxy closed") - -// Wait blocks until xdg-dbus-proxy exits and releases resources. -func (p *Proxy) Wait() error { - p.mu.RLock() - defer p.mu.RUnlock() - - p.pmu.RLock() - if p.helper == nil || p.cancel == nil || p.cause == nil { - p.pmu.RUnlock() - return errors.New("dbus: not started") - } - - errs := make([]error, 3) - - errs[0] = p.helper.Wait() - if errors.Is(errs[0], context.Canceled) && - errors.Is(p.cause(), proxyClosed) { - errs[0] = nil - } - p.pmu.RUnlock() - - // ensure socket removal so ephemeral directory is empty at revert - if err := os.Remove(p.final.Session[1]); err != nil && !errors.Is(err, os.ErrNotExist) { - errs[1] = err - } - if p.final.System[1] != "" { - if err := os.Remove(p.final.System[1]); err != nil && !errors.Is(err, os.ErrNotExist) { - errs[2] = err - } - } - - return errors.Join(errs...) -} - -// Close cancels the context passed to the helper instance attached to xdg-dbus-proxy. -func (p *Proxy) Close() { - p.pmu.Lock() - defer p.pmu.Unlock() - - if p.cancel == nil { - panic("dbus: not started") - } - p.cancel(proxyClosed) -} - -func argF(argsFd, statFd int) []string { - if statFd == -1 { - return []string{"--args=" + strconv.Itoa(argsFd)} - } else { - return []string{"--args=" + strconv.Itoa(argsFd), "--fd=" + strconv.Itoa(statFd)} - } -} diff --git a/dbus/proxy.go b/dbus/proxy.go deleted file mode 100644 index cc0af1ea..00000000 --- a/dbus/proxy.go +++ /dev/null @@ -1,117 +0,0 @@ -package dbus - -import ( - "context" - "fmt" - "io" - "os/exec" - "sync" - "syscall" - - "git.gensokyo.uk/security/hakurei/helper" -) - -// ProxyName is the file name or path to the proxy program. -// Overriding ProxyName will only affect Proxy instance created after the change. -var ProxyName = "xdg-dbus-proxy" - -type BadInterfaceError struct { - Interface string - Segment string -} - -func (e *BadInterfaceError) Error() string { - return fmt.Sprintf("bad interface string %q in %s bus configuration", e.Interface, e.Segment) -} - -// Proxy holds the state of a xdg-dbus-proxy process, and should never be copied. -type Proxy struct { - helper helper.Helper - ctx context.Context - - cancel context.CancelCauseFunc - cause func() error - - final *Final - output io.Writer - useSandbox bool - - name string - CmdF func(any) - - CommandContext func(ctx context.Context) (cmd *exec.Cmd) - FilterF func([]byte) []byte - - mu, pmu sync.RWMutex -} - -func (p *Proxy) String() string { - if p == nil { - return "(invalid dbus proxy)" - } - - p.mu.RLock() - defer p.mu.RUnlock() - - if p.helper != nil { - return p.helper.String() - } - - return "(unused dbus proxy)" -} - -// Final describes the outcome of a proxy configuration. -type Final struct { - Session, System ProxyPair - // parsed upstream address - SessionUpstream, SystemUpstream []AddrEntry - io.WriterTo -} - -// Finalise creates a checked argument writer for [Proxy]. -func Finalise(sessionBus, systemBus ProxyPair, session, system *Config) (final *Final, err error) { - if session == nil && system == nil { - return nil, syscall.EBADE - } - - var args []string - if session != nil { - if err = session.checkInterfaces("session"); err != nil { - return - } - args = append(args, session.Args(sessionBus)...) - } - if system != nil { - if err = system.checkInterfaces("system"); err != nil { - return - } - args = append(args, system.Args(systemBus)...) - } - - final = &Final{Session: sessionBus, System: systemBus} - - final.WriterTo, err = helper.NewCheckedArgs(args) - if err != nil { - return - } - - if session != nil { - final.SessionUpstream, err = Parse([]byte(final.Session[0])) - if err != nil { - return - } - } - if system != nil { - final.SystemUpstream, err = Parse([]byte(final.System[0])) - if err != nil { - return - } - } - - return -} - -// New returns a new instance of [Proxy]. -func New(ctx context.Context, final *Final, output io.Writer) *Proxy { - return &Proxy{name: ProxyName, ctx: ctx, final: final, output: output, useSandbox: true} -} diff --git a/dbus/samples_test.go b/dbus/samples_test.go deleted file mode 100644 index b2284c5c..00000000 --- a/dbus/samples_test.go +++ /dev/null @@ -1,228 +0,0 @@ -package dbus_test - -import ( - "sync" - - "git.gensokyo.uk/security/hakurei/dbus" -) - -const ( - sampleHostPath = "/tmp/bus" - sampleHostAddr = "unix:path=" + sampleHostPath - sampleBindPath = "/tmp/proxied_bus" -) - -var samples = []dbusTestCase{ - { - "org.chromium.Chromium", &dbus.Config{ - See: nil, - Talk: []string{"org.freedesktop.Notifications", "org.freedesktop.FileManager1", "org.freedesktop.ScreenSaver", - "org.freedesktop.secrets", "org.kde.kwalletd5", "org.kde.kwalletd6", "org.gnome.SessionManager"}, - Own: []string{"org.chromium.Chromium.*", "org.mpris.MediaPlayer2.org.chromium.Chromium.*", - "org.mpris.MediaPlayer2.chromium.*"}, - Call: map[string]string{"org.freedesktop.portal.*": "*"}, - Broadcast: map[string]string{"org.freedesktop.portal.*": "@/org/freedesktop/portal/*"}, - Log: false, - Filter: true, - }, false, false, - [2]string{sampleHostAddr, sampleBindPath}, - []string{ - sampleHostAddr, - sampleBindPath, - "--filter", - "--talk=org.freedesktop.Notifications", - "--talk=org.freedesktop.FileManager1", - "--talk=org.freedesktop.ScreenSaver", - "--talk=org.freedesktop.secrets", - "--talk=org.kde.kwalletd5", - "--talk=org.kde.kwalletd6", - "--talk=org.gnome.SessionManager", - "--own=org.chromium.Chromium.*", - "--own=org.mpris.MediaPlayer2.org.chromium.Chromium.*", - "--own=org.mpris.MediaPlayer2.chromium.*", - "--call=org.freedesktop.portal.*=*", - "--broadcast=org.freedesktop.portal.*=@/org/freedesktop/portal/*", - }, - }, - { - "org.chromium.Chromium+", &dbus.Config{ - See: nil, - Talk: []string{"org.bluez", "org.freedesktop.Avahi", "org.freedesktop.UPower"}, - Own: nil, - Call: nil, - Broadcast: nil, - Log: false, - Filter: true, - }, false, false, - [2]string{sampleHostAddr, sampleBindPath}, - []string{ - sampleHostAddr, - sampleBindPath, - "--filter", - "--talk=org.bluez", - "--talk=org.freedesktop.Avahi", - "--talk=org.freedesktop.UPower", - }, - }, - - { - "dev.vencord.Vesktop", &dbus.Config{ - See: nil, - Talk: []string{"org.freedesktop.Notifications", "org.kde.StatusNotifierWatcher"}, - Own: []string{"dev.vencord.Vesktop.*", "org.mpris.MediaPlayer2.dev.vencord.Vesktop.*"}, - Call: map[string]string{"org.freedesktop.portal.*": "*"}, - Broadcast: map[string]string{"org.freedesktop.portal.*": "@/org/freedesktop/portal/*"}, - Log: false, - Filter: true, - }, false, false, - [2]string{sampleHostAddr, sampleBindPath}, - []string{ - sampleHostAddr, - sampleBindPath, - "--filter", - "--talk=org.freedesktop.Notifications", - "--talk=org.kde.StatusNotifierWatcher", - "--own=dev.vencord.Vesktop.*", - "--own=org.mpris.MediaPlayer2.dev.vencord.Vesktop.*", - "--call=org.freedesktop.portal.*=*", - "--broadcast=org.freedesktop.portal.*=@/org/freedesktop/portal/*"}, - }, - - { - "uk.gensokyo.CrashTestDummy", &dbus.Config{ - See: []string{"uk.gensokyo.CrashTestDummy1"}, - Talk: []string{"org.freedesktop.Notifications"}, - Own: []string{"uk.gensokyo.CrashTestDummy.*", "org.mpris.MediaPlayer2.uk.gensokyo.CrashTestDummy.*"}, - Call: map[string]string{"org.freedesktop.portal.*": "*"}, - Broadcast: map[string]string{"org.freedesktop.portal.*": "@/org/freedesktop/portal/*"}, - Log: true, - Filter: true, - }, false, false, - [2]string{sampleHostAddr, sampleBindPath}, - []string{ - sampleHostAddr, - sampleBindPath, - "--filter", - "--see=uk.gensokyo.CrashTestDummy1", - "--talk=org.freedesktop.Notifications", - "--own=uk.gensokyo.CrashTestDummy.*", - "--own=org.mpris.MediaPlayer2.uk.gensokyo.CrashTestDummy.*", - "--call=org.freedesktop.portal.*=*", - "--broadcast=org.freedesktop.portal.*=@/org/freedesktop/portal/*", - "--log"}, - }, - { - "uk.gensokyo.CrashTestDummy1", &dbus.Config{ - See: []string{"uk.gensokyo.CrashTestDummy"}, - Talk: []string{"org.freedesktop.Notifications"}, - Own: []string{"uk.gensokyo.CrashTestDummy1.*", "org.mpris.MediaPlayer2.uk.gensokyo.CrashTestDummy1.*"}, - Call: map[string]string{"org.freedesktop.portal.*": "*"}, - Broadcast: map[string]string{"org.freedesktop.portal.*": "@/org/freedesktop/portal/*"}, - Log: true, - Filter: true, - }, false, true, - [2]string{sampleHostAddr, sampleBindPath}, - []string{ - sampleHostAddr, - sampleBindPath, - "--filter", - "--see=uk.gensokyo.CrashTestDummy", - "--talk=org.freedesktop.Notifications", - "--own=uk.gensokyo.CrashTestDummy1.*", - "--own=org.mpris.MediaPlayer2.uk.gensokyo.CrashTestDummy1.*", - "--call=org.freedesktop.portal.*=*", - "--broadcast=org.freedesktop.portal.*=@/org/freedesktop/portal/*", - "--log"}, - }, -} - -type dbusTestCase struct { - id string - c *dbus.Config - wantErr bool - wantErrF bool - bus [2]string - want []string -} - -var ( - testCasesV []dbusTestCase - testCasePairsV map[string][2]dbusTestCase - - testCaseOnce sync.Once -) - -func makeTestCases() []dbusTestCase { - testCaseOnce.Do(testCaseGenerate) - return testCasesV -} - -func testCasePairs() map[string][2]dbusTestCase { - testCaseOnce.Do(testCaseGenerate) - return testCasePairsV -} - -func injectNulls(t *[]string) { - f := make([]string, len(*t)) - for i := range f { - f[i] = "\x00" + (*t)[i] + "\x00" - } - *t = f -} - -func testCaseGenerate() { - // create null-injected test cases - testCasesV = make([]dbusTestCase, len(samples)*2) - for i := range samples { - testCasesV[i] = samples[i] - testCasesV[len(samples)+i] = samples[i] - testCasesV[len(samples)+i].c = new(dbus.Config) - *testCasesV[len(samples)+i].c = *samples[i].c - - // inject nulls - fi := &testCasesV[len(samples)+i] - fi.wantErr = true - - injectNulls(&fi.c.See) - injectNulls(&fi.c.Talk) - injectNulls(&fi.c.Own) - } - - // enumerate test case pairs - var pc int - for _, tc := range samples { - if tc.id != "" { - pc++ - } - } - testCasePairsV = make(map[string][2]dbusTestCase, pc) - for i, tc := range testCasesV { - if tc.id == "" { - continue - } - - // skip already enumerated system bus test - if tc.id[len(tc.id)-1] == '+' { - continue - } - - ftp := [2]dbusTestCase{tc} - - // system proxy tests always place directly after its user counterpart with id ending in + - if i+1 < len(testCasesV) && testCasesV[i+1].id[len(testCasesV[i+1].id)-1] == '+' { - // attach system bus config - ftp[1] = testCasesV[i+1] - - // check for misplaced/mismatching tests - if ftp[0].wantErr != ftp[1].wantErr || ftp[0].id+"+" != ftp[1].id { - panic("mismatching session/system pairing") - } - } - - k := tc.id - if tc.wantErr { - k = "malformed_" + k - } - testCasePairsV[k] = ftp - } -} diff --git a/dbus/stub_test.go b/dbus/stub_test.go deleted file mode 100644 index b05efd61..00000000 --- a/dbus/stub_test.go +++ /dev/null @@ -1,9 +0,0 @@ -package dbus_test - -import ( - "testing" - - "git.gensokyo.uk/security/hakurei/helper" -) - -func TestHelperStub(t *testing.T) { helper.InternalHelperStub() } diff --git a/dbus/testdata/dev.vencord.Vesktop.json b/dbus/testdata/dev.vencord.Vesktop.json deleted file mode 100644 index 05259774..00000000 --- a/dbus/testdata/dev.vencord.Vesktop.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "talk":[ - "org.freedesktop.Notifications", - "org.kde.StatusNotifierWatcher" - ], - "own":[ - "dev.vencord.Vesktop.*", - "org.mpris.MediaPlayer2.dev.vencord.Vesktop.*" - ], - "call":{ - "org.freedesktop.portal.*":"*" - }, - "broadcast":{ - "org.freedesktop.portal.*":"@/org/freedesktop/portal/*" - }, - - "filter":true -} diff --git a/dbus/testdata/org.chromium.Chromium+.json b/dbus/testdata/org.chromium.Chromium+.json deleted file mode 100644 index 0a27d719..00000000 --- a/dbus/testdata/org.chromium.Chromium+.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "talk":[ - "org.bluez", - "org.freedesktop.Avahi", - "org.freedesktop.UPower" - ], - - "filter":true -}
\ No newline at end of file diff --git a/dbus/testdata/org.chromium.Chromium.json b/dbus/testdata/org.chromium.Chromium.json deleted file mode 100644 index be027f39..00000000 --- a/dbus/testdata/org.chromium.Chromium.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "talk":[ - "org.freedesktop.Notifications", - "org.freedesktop.FileManager1", - "org.freedesktop.ScreenSaver", - "org.freedesktop.secrets", - "org.kde.kwalletd5", - "org.kde.kwalletd6", - "org.gnome.SessionManager" - ], - "own":[ - "org.chromium.Chromium.*", - "org.mpris.MediaPlayer2.org.chromium.Chromium.*", - "org.mpris.MediaPlayer2.chromium.*" - ], - "call":{ - "org.freedesktop.portal.*":"*" - }, - "broadcast":{ - "org.freedesktop.portal.*":"@/org/freedesktop/portal/*" - }, - - "filter":true -} diff --git a/dbus/testdata/uk.gensokyo.CrashTestDummy.json b/dbus/testdata/uk.gensokyo.CrashTestDummy.json deleted file mode 100644 index 43272f67..00000000 --- a/dbus/testdata/uk.gensokyo.CrashTestDummy.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "see": [ - "uk.gensokyo.CrashTestDummy1" - ], - "talk":[ - "org.freedesktop.Notifications" - ], - "own":[ - "uk.gensokyo.CrashTestDummy.*", - "org.mpris.MediaPlayer2.uk.gensokyo.CrashTestDummy.*" - ], - "call":{ - "org.freedesktop.portal.*":"*" - }, - "broadcast":{ - "org.freedesktop.portal.*":"@/org/freedesktop/portal/*" - }, - - "log": true, - "filter":true -} |
