diff --git a/pkg/prebuild/directive/core_test.go b/pkg/prebuild/directive/core_test.go index faf39df4..229dda63 100644 --- a/pkg/prebuild/directive/core_test.go +++ b/pkg/prebuild/directive/core_test.go @@ -20,7 +20,7 @@ func TestNewOption(t *testing.T) { }{ { name: "dbus", - file: nil, + file: paths.New("dbus"), match: []string{ " #aa:dbus own bus=system name=org.gnome.DisplayManager", "dbus", @@ -34,13 +34,13 @@ func TestNewOption(t *testing.T) { "own": "", }, ArgList: []string{"own", "bus=system", "name=org.gnome.DisplayManager"}, - File: nil, + File: paths.New("dbus"), Raw: " #aa:dbus own bus=system name=org.gnome.DisplayManager", }, }, { name: "only", - file: nil, + file: paths.New("only"), match: []string{ " #aa:only opensuse", "only", @@ -50,7 +50,7 @@ func TestNewOption(t *testing.T) { Name: "only", ArgMap: map[string]string{"opensuse": ""}, ArgList: []string{"opensuse"}, - File: nil, + File: paths.New("only"), Raw: " #aa:only opensuse", }, }, @@ -74,13 +74,13 @@ func TestRun(t *testing.T) { }{ { name: "none", - file: nil, + file: paths.New("dummy"), profile: ` `, want: ` `, }, { name: "present", - file: nil, + file: paths.New("fake-own"), profile: ` #aa:dbus own bus=system name=org.freedesktop.systemd1`, want: dbusOwnSystemd1, }, diff --git a/pkg/prebuild/directive/dbus.go b/pkg/prebuild/directive/dbus.go index a1135d67..4a903050 100644 --- a/pkg/prebuild/directive/dbus.go +++ b/pkg/prebuild/directive/dbus.go @@ -21,11 +21,6 @@ import ( "github.com/roddhjav/apparmor.d/pkg/prebuild" ) -var defaultInterfaces = []string{ - "org.freedesktop.DBus.Properties", - "org.freedesktop.DBus.ObjectManager", -} - type Dbus struct { prebuild.Base } @@ -43,15 +38,6 @@ func init() { ) } -func setInterfaces(rules map[string]string) []string { - interfaces := []string{rules["name"]} - if _, present := rules["interface"]; present { - interfaces = append(interfaces, rules["interface"]) - } - interfaces = append(interfaces, defaultInterfaces...) - return interfaces -} - func (d Dbus) Apply(opt *Option, profile string) (string, error) { var r aa.Rules @@ -59,11 +45,15 @@ func (d Dbus) Apply(opt *Option, profile string) (string, error) { if err != nil { return "", err } + name := opt.File.Base() + if len(name) > 15 { + name = name[:15] + } switch action { case "own": - r = d.own(opt.ArgMap) + r = d.own(opt.ArgMap, name) case "talk": - r = d.talk(opt.ArgMap) + r = d.talk(opt.ArgMap, name) } aa.IndentationLevel = strings.Count( @@ -103,63 +93,132 @@ func (d Dbus) sanityCheck(opt *Option) (string, error) { return action, nil } -func (d Dbus) own(rules map[string]string) aa.Rules { - interfaces := setInterfaces(rules) - res := aa.Rules{} - res = append(res, &aa.Dbus{ - Access: []string{"bind"}, Bus: rules["bus"], Name: rules["name"], - }) - for _, iface := range interfaces { - res = append(res, &aa.Dbus{ - Access: []string{"receive"}, - Bus: rules["bus"], - Path: rules["path"], - Interface: iface, - PeerName: `":1.@{int}"`, - }) +func getInterfaces(rules map[string]string) []string { + var interfaces []string + if _, present := rules["interface"]; present { + interfaces = []string{rules["interface"]} + } else { + interfaces = []string{rules["name"]} } - for _, iface := range interfaces { - res = append(res, &aa.Dbus{ - Access: []string{"send"}, - Bus: rules["bus"], - Path: rules["path"], - Interface: iface, - PeerName: `"{:1.@{int},org.freedesktop.DBus}"`, - }) + + if _, present := rules["interface+"]; present { + interfaces = append(interfaces, rules["interface+"]) } - res = append(res, &aa.Dbus{ - Access: []string{"receive"}, - Bus: rules["bus"], - Path: rules["path"], - Interface: "org.freedesktop.DBus.Introspectable", - Member: "Introspect", - PeerName: `":1.@{int}"`, - }) + return interfaces +} + +func (d Dbus) own(rules map[string]string, name string) aa.Rules { + interfaces := getInterfaces(rules) + + res := aa.Rules{ + &aa.Unix{ + Access: []string{"bind"}, Type: "stream", + Address: `@@{udbus}/bus/` + name + `/` + rules["bus"], + }, + &aa.Dbus{ + Access: []string{"bind"}, Bus: rules["bus"], Name: rules["name"], + }, + } + + // Interfaces + for _, iface := range interfaces { + res = append(res, + &aa.Dbus{ + Access: []string{"receive"}, Bus: rules["bus"], Path: rules["path"], + Interface: iface, + PeerName: `"@{busname}"`, + }, + &aa.Dbus{ + Access: []string{"send"}, Bus: rules["bus"], Path: rules["path"], + Interface: iface, + PeerName: `"{@{busname},org.freedesktop.DBus}"`, + }, + ) + } + + res = append(res, + // DBus.Properties + &aa.Dbus{ + Access: []string{"send", "receive"}, Bus: rules["bus"], Path: rules["path"], + Interface: "org.freedesktop.DBus.Properties", + Member: "{Get,GetAll,Set,PropertiesChanged}", + PeerName: `"{@{busname},org.freedesktop.DBus}"`, + }, + + // DBus.Introspectable + &aa.Dbus{ + Access: []string{"receive"}, Bus: rules["bus"], Path: rules["path"], + Interface: "org.freedesktop.DBus.Introspectable", + Member: "Introspect", + PeerName: `"@{busname}"`, + }, + + // DBus.ObjectManager + &aa.Dbus{ + Access: []string{"receive"}, Bus: rules["bus"], Path: rules["path"], + Interface: "org.freedesktop.DBus.ObjectManager", + Member: "GetManagedObjects", + PeerName: `"{@{busname},` + rules["name"] + `}"`, + }, + &aa.Dbus{ + Access: []string{"send"}, Bus: rules["bus"], Path: rules["path"], + Interface: "org.freedesktop.DBus.ObjectManager", + Member: "{InterfacesAdded,InterfacesRemoved}", + PeerName: `"{@{busname},org.freedesktop.DBus}"`, + }, + ) return res } -func (d Dbus) talk(rules map[string]string) aa.Rules { - interfaces := setInterfaces(rules) - res := aa.Rules{} +func (d Dbus) talk(rules map[string]string, name string) aa.Rules { + interfaces := getInterfaces(rules) + + res := aa.Rules{ + &aa.Unix{ + Access: []string{"bind"}, Type: "stream", + Address: `@@{udbus}/bus/` + name + `/` + rules["bus"], + }, + } + + // Interfaces for _, iface := range interfaces { res = append(res, &aa.Dbus{ - Access: []string{"send"}, - Bus: rules["bus"], - Path: rules["path"], + Access: []string{"send", "receive"}, Bus: rules["bus"], Path: rules["path"], Interface: iface, - PeerName: `"{:1.@{int},` + rules["name"] + `}"`, - PeerLabel: rules["label"], - }) - } - for _, iface := range interfaces { - res = append(res, &aa.Dbus{ - Access: []string{"receive"}, - Bus: rules["bus"], - Path: rules["path"], - Interface: iface, - PeerName: `"{:1.@{int},` + rules["name"] + `}"`, - PeerLabel: rules["label"], + PeerName: `"{@{busname},` + rules["name"] + `}"`, PeerLabel: rules["label"], }) } + + res = append(res, + // DBus.Properties + &aa.Dbus{ + Access: []string{"send", "receive"}, Bus: rules["bus"], Path: rules["path"], + Interface: "org.freedesktop.DBus.Properties", + Member: "{Get,GetAll,Set,PropertiesChanged}", + PeerName: `"{@{busname},` + rules["name"] + `}"`, PeerLabel: rules["label"], + }, + + // DBus.Introspectable + &aa.Dbus{ + Access: []string{"send"}, Bus: rules["bus"], Path: rules["path"], + Interface: "org.freedesktop.DBus.Introspectable", + Member: "Introspect", + PeerName: `"{@{busname},` + rules["name"] + `}"`, PeerLabel: rules["label"], + }, + + // DBus.ObjectManager + &aa.Dbus{ + Access: []string{"send"}, Bus: rules["bus"], Path: rules["path"], + Interface: "org.freedesktop.DBus.ObjectManager", + Member: "GetManagedObjects", + PeerName: `"{@{busname},` + rules["name"] + `}"`, PeerLabel: rules["label"], + }, + &aa.Dbus{ + Access: []string{"receive"}, Bus: rules["bus"], Path: rules["path"], + Interface: "org.freedesktop.DBus.ObjectManager", + Member: "{InterfacesAdded,InterfacesRemoved}", + PeerName: `"{@{busname},` + rules["name"] + `}"`, PeerLabel: rules["label"], + }, + ) return res } diff --git a/pkg/prebuild/directive/dbus_test.go b/pkg/prebuild/directive/dbus_test.go index 65e55e78..f2d4997e 100644 --- a/pkg/prebuild/directive/dbus_test.go +++ b/pkg/prebuild/directive/dbus_test.go @@ -6,31 +6,35 @@ package directive import ( "testing" + + "github.com/roddhjav/apparmor.d/pkg/paths" ) -const dbusOwnSystemd1 = ` dbus bind bus=system name=org.freedesktop.systemd1{,.*}, +const dbusOwnSystemd1 = ` unix bind type=stream addr=@@{udbus}/bus/fake-own/system, + + dbus bind bus=system name=org.freedesktop.systemd1{,.*}, dbus receive bus=system path=/org/freedesktop/systemd1{,/**} interface=org.freedesktop.systemd1{,.*} - peer=(name=":1.@{int}"), - dbus receive bus=system path=/org/freedesktop/systemd1{,/**} - interface=org.freedesktop.DBus.Properties - peer=(name=":1.@{int}"), - dbus receive bus=system path=/org/freedesktop/systemd1{,/**} - interface=org.freedesktop.DBus.ObjectManager - peer=(name=":1.@{int}"), + peer=(name="@{busname}"), dbus send bus=system path=/org/freedesktop/systemd1{,/**} interface=org.freedesktop.systemd1{,.*} - peer=(name="{:1.@{int},org.freedesktop.DBus}"), - dbus send bus=system path=/org/freedesktop/systemd1{,/**} + peer=(name="{@{busname},org.freedesktop.DBus}"), + dbus (send receive) bus=system path=/org/freedesktop/systemd1{,/**} interface=org.freedesktop.DBus.Properties - peer=(name="{:1.@{int},org.freedesktop.DBus}"), - dbus send bus=system path=/org/freedesktop/systemd1{,/**} - interface=org.freedesktop.DBus.ObjectManager - peer=(name="{:1.@{int},org.freedesktop.DBus}"), + member={Get,GetAll,Set,PropertiesChanged} + peer=(name="{@{busname},org.freedesktop.DBus}"), dbus receive bus=system path=/org/freedesktop/systemd1{,/**} interface=org.freedesktop.DBus.Introspectable member=Introspect - peer=(name=":1.@{int}"),` + peer=(name="@{busname}"), + dbus receive bus=system path=/org/freedesktop/systemd1{,/**} + interface=org.freedesktop.DBus.ObjectManager + member=GetManagedObjects + peer=(name="{@{busname},org.freedesktop.systemd1{,.*}}"), + dbus send bus=system path=/org/freedesktop/systemd1{,/**} + interface=org.freedesktop.DBus.ObjectManager + member={InterfacesAdded,InterfacesRemoved} + peer=(name="{@{busname},org.freedesktop.DBus}"),` func TestDbus_Apply(t *testing.T) { tests := []struct { @@ -50,7 +54,7 @@ func TestDbus_Apply(t *testing.T) { "own": "", }, ArgList: []string{"own", "bus=system", "name=org.freedesktop.systemd1"}, - File: nil, + File: paths.New("fake-own"), Raw: " #aa:dbus own bus=system name=org.freedesktop.systemd1", }, profile: " #aa:dbus own bus=system name=org.freedesktop.systemd1", @@ -61,45 +65,47 @@ func TestDbus_Apply(t *testing.T) { opt: &Option{ Name: "dbus", ArgMap: map[string]string{ - "bus": "session", - "name": "com.rastersoft.dingextension", - "interface": "org.gtk.Actions", - "own": "", + "bus": "session", + "name": "com.rastersoft.ding", + "interface+": "org.gtk.Actions", + "own": "", }, - ArgList: []string{"own", "bus=session", "name=com.rastersoft.dingextension", "interface=org.gtk.Actions"}, - File: nil, - Raw: " #aa:dbus own bus=session name=com.rastersoft.dingextension interface=org.gtk.Actions", + ArgList: []string{"own", "bus=session", "name=com.rastersoft.ding", "interface+=org.gtk.Actions"}, + File: paths.New("fake-interface"), + Raw: " #aa:dbus own bus=session name=com.rastersoft.ding interface+=org.gtk.Actions", }, - profile: " #aa:dbus own bus=session name=com.rastersoft.dingextension interface=org.gtk.Actions", - want: ` dbus bind bus=session name=com.rastersoft.dingextension{,.*}, - dbus receive bus=session path=/com/rastersoft/dingextension{,/**} - interface=com.rastersoft.dingextension{,.*} - peer=(name=":1.@{int}"), - dbus receive bus=session path=/com/rastersoft/dingextension{,/**} + profile: " #aa:dbus own bus=session name=com.rastersoft.ding interface+=org.gtk.Actions", + want: ` unix bind type=stream addr=@@{udbus}/bus/fake-interface/session, + + dbus bind bus=session name=com.rastersoft.ding{,.*}, + dbus receive bus=session path=/com/rastersoft/ding{,/**} + interface=com.rastersoft.ding{,.*} + peer=(name="@{busname}"), + dbus send bus=session path=/com/rastersoft/ding{,/**} + interface=com.rastersoft.ding{,.*} + peer=(name="{@{busname},org.freedesktop.DBus}"), + dbus receive bus=session path=/com/rastersoft/ding{,/**} interface=org.gtk.Actions - peer=(name=":1.@{int}"), - dbus receive bus=session path=/com/rastersoft/dingextension{,/**} - interface=org.freedesktop.DBus.Properties - peer=(name=":1.@{int}"), - dbus receive bus=session path=/com/rastersoft/dingextension{,/**} - interface=org.freedesktop.DBus.ObjectManager - peer=(name=":1.@{int}"), - dbus send bus=session path=/com/rastersoft/dingextension{,/**} - interface=com.rastersoft.dingextension{,.*} - peer=(name="{:1.@{int},org.freedesktop.DBus}"), - dbus send bus=session path=/com/rastersoft/dingextension{,/**} + peer=(name="@{busname}"), + dbus send bus=session path=/com/rastersoft/ding{,/**} interface=org.gtk.Actions - peer=(name="{:1.@{int},org.freedesktop.DBus}"), - dbus send bus=session path=/com/rastersoft/dingextension{,/**} + peer=(name="{@{busname},org.freedesktop.DBus}"), + dbus (send receive) bus=session path=/com/rastersoft/ding{,/**} interface=org.freedesktop.DBus.Properties - peer=(name="{:1.@{int},org.freedesktop.DBus}"), - dbus send bus=session path=/com/rastersoft/dingextension{,/**} - interface=org.freedesktop.DBus.ObjectManager - peer=(name="{:1.@{int},org.freedesktop.DBus}"), - dbus receive bus=session path=/com/rastersoft/dingextension{,/**} + member={Get,GetAll,Set,PropertiesChanged} + peer=(name="{@{busname},org.freedesktop.DBus}"), + dbus receive bus=session path=/com/rastersoft/ding{,/**} interface=org.freedesktop.DBus.Introspectable member=Introspect - peer=(name=":1.@{int}"),`, + peer=(name="@{busname}"), + dbus receive bus=session path=/com/rastersoft/ding{,/**} + interface=org.freedesktop.DBus.ObjectManager + member=GetManagedObjects + peer=(name="{@{busname},com.rastersoft.ding{,.*}}"), + dbus send bus=session path=/com/rastersoft/ding{,/**} + interface=org.freedesktop.DBus.ObjectManager + member={InterfacesAdded,InterfacesRemoved} + peer=(name="{@{busname},org.freedesktop.DBus}"),`, }, { name: "talk", @@ -112,28 +118,31 @@ func TestDbus_Apply(t *testing.T) { "talk": "", }, ArgList: []string{"talk", "bus=system", "name=org.freedesktop.Accounts", "label=accounts-daemon"}, - File: nil, + File: paths.New("gdm-session-worker"), Raw: " #aa:dbus talk bus=system name=org.freedesktop.Accounts label=accounts-daemon", }, profile: " #aa:dbus talk bus=system name=org.freedesktop.Accounts label=accounts-daemon", - want: ` dbus send bus=system path=/org/freedesktop/Accounts{,/**} + want: ` unix bind type=stream addr=@@{udbus}/bus/gdm-session-wor/system, + + dbus (send receive) bus=system path=/org/freedesktop/Accounts{,/**} interface=org.freedesktop.Accounts{,.*} - peer=(name="{:1.@{int},org.freedesktop.Accounts{,.*}}", label=accounts-daemon), - dbus send bus=system path=/org/freedesktop/Accounts{,/**} + peer=(name="{@{busname},org.freedesktop.Accounts{,.*}}", label=accounts-daemon), + dbus (send receive) bus=system path=/org/freedesktop/Accounts{,/**} interface=org.freedesktop.DBus.Properties - peer=(name="{:1.@{int},org.freedesktop.Accounts{,.*}}", label=accounts-daemon), + member={Get,GetAll,Set,PropertiesChanged} + peer=(name="{@{busname},org.freedesktop.Accounts{,.*}}", label=accounts-daemon), + dbus send bus=system path=/org/freedesktop/Accounts{,/**} + interface=org.freedesktop.DBus.Introspectable + member=Introspect + peer=(name="{@{busname},org.freedesktop.Accounts{,.*}}", label=accounts-daemon), dbus send bus=system path=/org/freedesktop/Accounts{,/**} interface=org.freedesktop.DBus.ObjectManager - peer=(name="{:1.@{int},org.freedesktop.Accounts{,.*}}", label=accounts-daemon), - dbus receive bus=system path=/org/freedesktop/Accounts{,/**} - interface=org.freedesktop.Accounts{,.*} - peer=(name="{:1.@{int},org.freedesktop.Accounts{,.*}}", label=accounts-daemon), - dbus receive bus=system path=/org/freedesktop/Accounts{,/**} - interface=org.freedesktop.DBus.Properties - peer=(name="{:1.@{int},org.freedesktop.Accounts{,.*}}", label=accounts-daemon), + member=GetManagedObjects + peer=(name="{@{busname},org.freedesktop.Accounts{,.*}}", label=accounts-daemon), dbus receive bus=system path=/org/freedesktop/Accounts{,/**} interface=org.freedesktop.DBus.ObjectManager - peer=(name="{:1.@{int},org.freedesktop.Accounts{,.*}}", label=accounts-daemon),`, + member={InterfacesAdded,InterfacesRemoved} + peer=(name="{@{busname},org.freedesktop.Accounts{,.*}}", label=accounts-daemon),`, }, } for _, tt := range tests {