gitee.com/mysnapcore/mysnapd@v0.1.0/interfaces/builtin/dbus_test.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2016 Canonical Ltd
     5   *
     6   * This program is free software: you can redistribute it and/or modify
     7   * it under the terms of the GNU General Public License version 3 as
     8   * published by the Free Software Foundation.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  package builtin_test
    21  
    22  import (
    23  	. "gopkg.in/check.v1"
    24  
    25  	"gitee.com/mysnapcore/mysnapd/interfaces"
    26  	"gitee.com/mysnapcore/mysnapd/interfaces/apparmor"
    27  	"gitee.com/mysnapcore/mysnapd/interfaces/builtin"
    28  	"gitee.com/mysnapcore/mysnapd/interfaces/dbus"
    29  	"gitee.com/mysnapcore/mysnapd/interfaces/seccomp"
    30  	"gitee.com/mysnapcore/mysnapd/release"
    31  	"gitee.com/mysnapcore/mysnapd/snap"
    32  	"gitee.com/mysnapcore/mysnapd/snap/snaptest"
    33  	"gitee.com/mysnapcore/mysnapd/testutil"
    34  )
    35  
    36  type DbusInterfaceSuite struct {
    37  	testutil.BaseTest
    38  	iface interfaces.Interface
    39  
    40  	snapInfo *snap.Info
    41  
    42  	sessionPlugInfo          *snap.PlugInfo
    43  	sessionPlug              *interfaces.ConnectedPlug
    44  	systemPlugInfo           *snap.PlugInfo
    45  	systemPlug               *interfaces.ConnectedPlug
    46  	connectedSessionPlugInfo *snap.PlugInfo
    47  	connectedSessionPlug     *interfaces.ConnectedPlug
    48  	connectedSystemPlugInfo  *snap.PlugInfo
    49  	connectedSystemPlug      *interfaces.ConnectedPlug
    50  
    51  	sessionSlotInfo          *snap.SlotInfo
    52  	sessionSlot              *interfaces.ConnectedSlot
    53  	systemSlotInfo           *snap.SlotInfo
    54  	systemSlot               *interfaces.ConnectedSlot
    55  	connectedSessionSlotInfo *snap.SlotInfo
    56  	connectedSessionSlot     *interfaces.ConnectedSlot
    57  	connectedSystemSlotInfo  *snap.SlotInfo
    58  	connectedSystemSlot      *interfaces.ConnectedSlot
    59  }
    60  
    61  var _ = Suite(&DbusInterfaceSuite{
    62  	iface: builtin.MustInterface("dbus"),
    63  })
    64  
    65  func (s *DbusInterfaceSuite) SetUpSuite(c *C) {
    66  	s.snapInfo = snaptest.MockInfo(c, `
    67  name: test-dbus
    68  version: 0
    69  slots:
    70    test-session-slot:
    71      interface: dbus
    72      bus: session
    73      name: org.test-session-slot
    74    test-system-slot:
    75      interface: dbus
    76      bus: system
    77      name: org.test-system-slot
    78    test-system-connected-slot:
    79      interface: dbus
    80      bus: system
    81      name: org.test-system-connected
    82    test-session-connected-slot:
    83      interface: dbus
    84      bus: session
    85      name: org.test-session-connected
    86  
    87  plugs:
    88    test-session-plug:
    89      interface: dbus
    90      bus: session
    91      name: org.test-session-plug
    92    test-system-plug:
    93      interface: dbus
    94      bus: system
    95      name: org.test-system-plug
    96    test-system-connected-plug:
    97      interface: dbus
    98      bus: system
    99      name: org.test-system-connected
   100    test-session-connected-plug:
   101      interface: dbus
   102      bus: session
   103      name: org.test-session-connected
   104  
   105  apps:
   106    test-session-provider:
   107      slots:
   108      - test-session-slot
   109    test-system-provider:
   110      slots:
   111      - test-system-slot
   112    test-session-consumer:
   113      plugs:
   114      - test-session-plug
   115    test-system-consumer:
   116      plugs:
   117      - test-system-plug
   118  `, nil)
   119  }
   120  
   121  func (s *DbusInterfaceSuite) SetUpTest(c *C) {
   122  	s.sessionSlotInfo = s.snapInfo.Slots["test-session-slot"]
   123  	s.sessionSlot = interfaces.NewConnectedSlot(s.sessionSlotInfo, nil, nil)
   124  	s.systemSlotInfo = s.snapInfo.Slots["test-system-slot"]
   125  	s.systemSlot = interfaces.NewConnectedSlot(s.systemSlotInfo, nil, nil)
   126  	s.connectedSessionSlotInfo = s.snapInfo.Slots["test-session-connected-slot"]
   127  	s.connectedSessionSlot = interfaces.NewConnectedSlot(s.connectedSessionSlotInfo, nil, nil)
   128  	s.connectedSystemSlotInfo = s.snapInfo.Slots["test-system-connected-slot"]
   129  	s.connectedSystemSlot = interfaces.NewConnectedSlot(s.connectedSystemSlotInfo, nil, nil)
   130  
   131  	s.sessionPlugInfo = s.snapInfo.Plugs["test-session-plug"]
   132  	s.sessionPlug = interfaces.NewConnectedPlug(s.sessionPlugInfo, nil, nil)
   133  	s.systemPlugInfo = s.snapInfo.Plugs["test-system-plug"]
   134  	s.systemPlug = interfaces.NewConnectedPlug(s.systemPlugInfo, nil, nil)
   135  	s.connectedSessionPlugInfo = s.snapInfo.Plugs["test-session-connected-plug"]
   136  	s.connectedSessionPlug = interfaces.NewConnectedPlug(s.connectedSessionPlugInfo, nil, nil)
   137  	s.connectedSystemPlugInfo = s.snapInfo.Plugs["test-system-connected-plug"]
   138  	s.connectedSystemPlug = interfaces.NewConnectedPlug(s.connectedSystemPlugInfo, nil, nil)
   139  }
   140  
   141  func (s *DbusInterfaceSuite) TestName(c *C) {
   142  	c.Assert(s.iface.Name(), Equals, "dbus")
   143  }
   144  
   145  func (s *DbusInterfaceSuite) TestValidSessionBusName(c *C) {
   146  	var mockSnapYaml = `name: dbus-snap
   147  version: 1.0
   148  slots:
   149   dbus-slot:
   150    interface: dbus
   151    bus: session
   152    name: org.dbus-snap.session-a
   153  `
   154  
   155  	info := snaptest.MockInfo(c, mockSnapYaml, nil)
   156  
   157  	slot := info.Slots["dbus-slot"]
   158  	c.Assert(interfaces.BeforePrepareSlot(s.iface, slot), IsNil)
   159  }
   160  
   161  func (s *DbusInterfaceSuite) TestValidSystemBusName(c *C) {
   162  	var mockSnapYaml = `name: dbus-snap
   163  version: 1.0
   164  slots:
   165   dbus-slot:
   166    interface: dbus
   167    bus: system
   168    name: org.dbus-snap.system-a
   169  `
   170  
   171  	info := snaptest.MockInfo(c, mockSnapYaml, nil)
   172  
   173  	slot := info.Slots["dbus-slot"]
   174  	c.Assert(interfaces.BeforePrepareSlot(s.iface, slot), IsNil)
   175  }
   176  
   177  func (s *DbusInterfaceSuite) TestValidFullBusName(c *C) {
   178  	var mockSnapYaml = `name: dbus-snap
   179  version: 1.0
   180  slots:
   181   dbus-slot:
   182    interface: dbus
   183    bus: system
   184    name: org.dbus-snap.foo.bar.baz.n0rf_qux
   185  `
   186  
   187  	info := snaptest.MockInfo(c, mockSnapYaml, nil)
   188  
   189  	slot := info.Slots["dbus-slot"]
   190  	c.Assert(interfaces.BeforePrepareSlot(s.iface, slot), IsNil)
   191  }
   192  
   193  func (s *DbusInterfaceSuite) TestNonexistentBusName(c *C) {
   194  	var mockSnapYaml = `name: dbus-snap
   195  version: 1.0
   196  slots:
   197   dbus-slot:
   198    interface: dbus
   199    bus: nonexistent
   200    name: org.dbus-snap
   201  `
   202  
   203  	info := snaptest.MockInfo(c, mockSnapYaml, nil)
   204  
   205  	slot := info.Slots["dbus-slot"]
   206  	c.Assert(interfaces.BeforePrepareSlot(s.iface, slot), ErrorMatches, "bus 'nonexistent' must be one of 'session' or 'system'")
   207  }
   208  
   209  // If this test is failing, be sure to verify the AppArmor rules for binding to
   210  // a well-known name to avoid overlaps.
   211  func (s *DbusInterfaceSuite) TestInvalidBusNameEndsWithDashInt(c *C) {
   212  	var mockSnapYaml = `name: dbus-snap
   213  version: 1.0
   214  slots:
   215   dbus-slot:
   216    interface: dbus
   217    bus: session
   218    name: org.dbus-snap.session-12345
   219  `
   220  
   221  	info := snaptest.MockInfo(c, mockSnapYaml, nil)
   222  
   223  	slot := info.Slots["dbus-slot"]
   224  	c.Assert(interfaces.BeforePrepareSlot(s.iface, slot), ErrorMatches, "DBus bus name must not end with -NUMBER")
   225  }
   226  
   227  func (s *DbusInterfaceSuite) TestSanitizeSlotSystem(c *C) {
   228  	var mockSnapYaml = `name: dbus-snap
   229  version: 1.0
   230  slots:
   231   dbus-slot:
   232    interface: dbus
   233    bus: system
   234    name: org.dbus-snap.system
   235  `
   236  
   237  	info := snaptest.MockInfo(c, mockSnapYaml, nil)
   238  
   239  	slot := info.Slots["dbus-slot"]
   240  	c.Assert(interfaces.BeforePrepareSlot(s.iface, slot), IsNil)
   241  }
   242  
   243  func (s *DbusInterfaceSuite) TestSanitizeSlotSession(c *C) {
   244  	var mockSnapYaml = `name: dbus-snap
   245  version: 1.0
   246  slots:
   247   dbus-slot:
   248    interface: dbus
   249    bus: session
   250    name: org.dbus-snap.session
   251  `
   252  
   253  	info := snaptest.MockInfo(c, mockSnapYaml, nil)
   254  
   255  	slot := info.Slots["dbus-slot"]
   256  	c.Assert(interfaces.BeforePrepareSlot(s.iface, slot), IsNil)
   257  }
   258  
   259  func (s *DbusInterfaceSuite) TestSanitizePlugSystem(c *C) {
   260  	var mockSnapYaml = `name: dbus-snap
   261  version: 1.0
   262  plugs:
   263   dbus-plug:
   264    interface: dbus
   265    bus: system
   266    name: org.dbus-snap.system
   267  `
   268  
   269  	info := snaptest.MockInfo(c, mockSnapYaml, nil)
   270  
   271  	plug := info.Plugs["dbus-plug"]
   272  	c.Assert(interfaces.BeforePreparePlug(s.iface, plug), IsNil)
   273  }
   274  
   275  func (s *DbusInterfaceSuite) TestSanitizePlugSession(c *C) {
   276  	var mockSnapYaml = `name: dbus-snap
   277  version: 1.0
   278  plugs:
   279   dbus-plug:
   280    interface: dbus
   281    bus: session
   282    name: org.dbus-snap.session
   283  `
   284  
   285  	info := snaptest.MockInfo(c, mockSnapYaml, nil)
   286  
   287  	plug := info.Plugs["dbus-plug"]
   288  	c.Assert(interfaces.BeforePreparePlug(s.iface, plug), IsNil)
   289  }
   290  
   291  func (s *DbusInterfaceSuite) TestPermanentSlotAppArmorSession(c *C) {
   292  	apparmorSpec := &apparmor.Specification{}
   293  	err := apparmorSpec.AddPermanentSlot(s.iface, s.sessionSlotInfo)
   294  	c.Assert(err, IsNil)
   295  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.test-dbus.test-session-provider"})
   296  	snippet := apparmorSpec.SnippetForTag("snap.test-dbus.test-session-provider")
   297  
   298  	// verify abstraction rule
   299  	c.Check(snippet, testutil.Contains, "#include <abstractions/dbus-session-strict>\n")
   300  
   301  	// verify shared permanent slot policy
   302  	c.Check(snippet, testutil.Contains, "dbus (send)\n    bus=session\n    path=/org/freedesktop/DBus\n    interface=org.freedesktop.DBus\n    member=\"{Request,Release}Name\"\n    peer=(name=org.freedesktop.DBus, label=unconfined),\n")
   303  
   304  	// verify individual bind rules
   305  	c.Check(snippet, testutil.Contains, "dbus (bind)\n    bus=session\n    name=org.test-session-slot,\n")
   306  	c.Check(snippet, testutil.Contains, "dbus (bind)\n    bus=session\n    name=\"org.test-session-slot.*\",\n")
   307  
   308  	// verify individual path in rules
   309  	c.Check(snippet, testutil.Contains, "path=\"/org/test-session-slot{,/**}\"\n")
   310  
   311  	// verify interface in rule
   312  	c.Check(snippet, testutil.Contains, "interface=\"org.test-session-slot{,.*}\"\n")
   313  }
   314  
   315  func (s *DbusInterfaceSuite) TestPermanentSlotAppArmorSessionNative(c *C) {
   316  	restore := release.MockOnClassic(false)
   317  	defer restore()
   318  
   319  	apparmorSpec := &apparmor.Specification{}
   320  	err := apparmorSpec.AddPermanentSlot(s.iface, s.sessionSlotInfo)
   321  	c.Assert(err, IsNil)
   322  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.test-dbus.test-session-provider"})
   323  
   324  	// verify classic rule not present
   325  	c.Check(apparmorSpec.SnippetForTag("snap.test-dbus.test-session-provider"), Not(testutil.Contains), "# allow us to respond to unconfined clients via \"org.test-session-slot{,.*}\"\n")
   326  }
   327  
   328  func (s *DbusInterfaceSuite) TestPermanentSlotAppArmorSessionClassic(c *C) {
   329  	restore := release.MockOnClassic(true)
   330  	defer restore()
   331  
   332  	apparmorSpec := &apparmor.Specification{}
   333  	err := apparmorSpec.AddPermanentSlot(s.iface, s.sessionSlotInfo)
   334  	c.Assert(err, IsNil)
   335  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.test-dbus.test-session-provider"})
   336  
   337  	// verify classic rule
   338  	c.Check(apparmorSpec.SnippetForTag("snap.test-dbus.test-session-provider"), testutil.Contains, "# allow us to respond to unconfined clients via \"org.test-session-slot{,.*}\"\n")
   339  }
   340  
   341  func (s *DbusInterfaceSuite) TestPermanentSlotAppArmorSystem(c *C) {
   342  	apparmorSpec := &apparmor.Specification{}
   343  	err := apparmorSpec.AddPermanentSlot(s.iface, s.systemSlotInfo)
   344  	c.Assert(err, IsNil)
   345  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.test-dbus.test-system-provider"})
   346  	snippet := apparmorSpec.SnippetForTag("snap.test-dbus.test-system-provider")
   347  
   348  	// verify abstraction rule
   349  	c.Check(snippet, testutil.Contains, "#include <abstractions/dbus-strict>\n")
   350  
   351  	// verify bind rule
   352  	c.Check(snippet, testutil.Contains, "dbus (bind)\n    bus=system\n    name=org.test-system-slot,\n")
   353  	c.Check(snippet, testutil.Contains, "dbus (bind)\n    bus=system\n    name=\"org.test-system-slot.*\",\n")
   354  
   355  	// verify path in rule
   356  	c.Check(snippet, testutil.Contains, "path=\"/org/test-system-slot{,/**}\"\n")
   357  
   358  	// verify interface in rule
   359  	c.Check(snippet, testutil.Contains, "interface=\"org.test-system-slot{,.*}\"\n")
   360  
   361  	// verify dbus-daemon introspection rule
   362  	c.Check(snippet, testutil.Contains, "dbus (send)\n    bus=system\n    interface=org.freedesktop.DBus.Introspectable\n    member=Introspect\n    peer=(name=org.freedesktop.DBus, label=unconfined),\n")
   363  }
   364  
   365  func (s *DbusInterfaceSuite) TestPermanentSlotDBusSession(c *C) {
   366  	dbusSpec := &dbus.Specification{}
   367  	err := dbusSpec.AddPermanentSlot(s.iface, s.sessionSlotInfo)
   368  	c.Assert(err, IsNil)
   369  	c.Assert(dbusSpec.SecurityTags(), HasLen, 0)
   370  }
   371  
   372  func (s *DbusInterfaceSuite) TestPermanentSlotDBusSystem(c *C) {
   373  	dbusSpec := &dbus.Specification{}
   374  	err := dbusSpec.AddPermanentSlot(s.iface, s.systemSlotInfo)
   375  	c.Assert(err, IsNil)
   376  	c.Assert(dbusSpec.SecurityTags(), DeepEquals, []string{"snap.test-dbus.test-system-provider"})
   377  	snippet := dbusSpec.SnippetForTag("snap.test-dbus.test-system-provider")
   378  	c.Check(snippet, testutil.Contains, "<policy user=\"root\">\n    <allow own=\"org.test-system-slot\"/>")
   379  	c.Check(snippet, testutil.Contains, "<policy context=\"default\">\n    <allow send_destination=\"org.test-system-slot\"/>")
   380  }
   381  
   382  func (s *DbusInterfaceSuite) TestPermanentSlotSecCompSystem(c *C) {
   383  	seccompSpec := &seccomp.Specification{}
   384  	err := seccompSpec.AddPermanentSlot(s.iface, s.systemSlotInfo)
   385  	c.Assert(err, IsNil)
   386  	c.Assert(seccompSpec.SecurityTags(), DeepEquals, []string{"snap.test-dbus.test-system-provider"})
   387  	snippet := seccompSpec.SnippetForTag("snap.test-dbus.test-system-provider")
   388  	c.Check(snippet, testutil.Contains, "listen\naccept\naccept4\n")
   389  }
   390  
   391  func (s *DbusInterfaceSuite) TestPermanentSlotSecCompSession(c *C) {
   392  	seccompSpec := &seccomp.Specification{}
   393  	err := seccompSpec.AddPermanentSlot(s.iface, s.sessionSlotInfo)
   394  	c.Assert(err, IsNil)
   395  	c.Assert(seccompSpec.SecurityTags(), DeepEquals, []string{"snap.test-dbus.test-session-provider"})
   396  	snippet := seccompSpec.SnippetForTag("snap.test-dbus.test-session-provider")
   397  	c.Check(snippet, testutil.Contains, "listen\naccept\naccept4\n")
   398  }
   399  
   400  func (s *DbusInterfaceSuite) TestConnectedSlotAppArmorSession(c *C) {
   401  	apparmorSpec := &apparmor.Specification{}
   402  	err := apparmorSpec.AddConnectedSlot(s.iface, s.connectedSessionPlug, s.connectedSessionSlot)
   403  	c.Assert(err, IsNil)
   404  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.test-dbus.test-session-consumer", "snap.test-dbus.test-session-provider", "snap.test-dbus.test-system-consumer", "snap.test-dbus.test-system-provider"})
   405  	snippet := apparmorSpec.SnippetForTag("snap.test-dbus.test-session-provider")
   406  
   407  	// verify introspectable rule
   408  	c.Check(snippet, testutil.Contains, "dbus (receive)\n    bus=session\n    interface=org.freedesktop.DBus.Introspectable\n    member=Introspect\n    peer=(label=\"snap.test-dbus.*\"),\n")
   409  
   410  	// verify bind rule not present
   411  	c.Check(snippet, Not(testutil.Contains), "dbus (bind)")
   412  
   413  	// verify individual path in rules
   414  	c.Check(snippet, testutil.Contains, "path=\"/org/test-session-connected{,/**}\"\n")
   415  
   416  	// verify interface in rule
   417  	c.Check(snippet, testutil.Contains, "interface=\"org.test-session-connected{,.*}\"\n")
   418  }
   419  
   420  func (s *DbusInterfaceSuite) TestConnectedSlotAppArmorSystem(c *C) {
   421  	apparmorSpec := &apparmor.Specification{}
   422  	err := apparmorSpec.AddConnectedSlot(s.iface, s.connectedSystemPlug, s.connectedSystemSlot)
   423  	c.Assert(err, IsNil)
   424  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.test-dbus.test-session-consumer", "snap.test-dbus.test-session-provider", "snap.test-dbus.test-system-consumer", "snap.test-dbus.test-system-provider"})
   425  	snippet := apparmorSpec.SnippetForTag("snap.test-dbus.test-session-provider")
   426  
   427  	// verify introspectable rule
   428  	c.Check(snippet, testutil.Contains, "dbus (receive)\n    bus=system\n    interface=org.freedesktop.DBus.Introspectable\n    member=Introspect\n    peer=(label=\"snap.test-dbus.*\"),\n")
   429  
   430  	// verify bind rule not present
   431  	c.Check(snippet, Not(testutil.Contains), "dbus (bind)")
   432  
   433  	// verify individual path in rules
   434  	c.Check(snippet, testutil.Contains, "path=\"/org/test-system-connected{,/**}\"\n")
   435  
   436  	// verify interface in rule
   437  	c.Check(snippet, testutil.Contains, "interface=\"org.test-system-connected{,.*}\"\n")
   438  }
   439  
   440  func (s *DbusInterfaceSuite) TestConnectedPlugAppArmorSession(c *C) {
   441  	apparmorSpec := &apparmor.Specification{}
   442  	err := apparmorSpec.AddConnectedPlug(s.iface, s.connectedSessionPlug, s.connectedSessionSlot)
   443  	c.Assert(err, IsNil)
   444  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.test-dbus.test-session-consumer", "snap.test-dbus.test-session-provider", "snap.test-dbus.test-system-consumer", "snap.test-dbus.test-system-provider"})
   445  	snippet := apparmorSpec.SnippetForTag("snap.test-dbus.test-session-consumer")
   446  
   447  	// verify introspectable rule
   448  	c.Check(string(snippet), testutil.Contains, "dbus (send)\n    bus=session\n    interface=org.freedesktop.DBus.Introspectable\n    member=Introspect\n    peer=(label=\"snap.test-dbus.*\"),\n")
   449  
   450  	// verify bind rule not present
   451  	c.Check(string(snippet), Not(testutil.Contains), "dbus (bind)")
   452  
   453  	// verify well-known connection in rule
   454  	c.Check(string(snippet), testutil.Contains, "peer=(name=org.test-session-connected, label=")
   455  
   456  	// verify interface in rule
   457  
   458  	// verify individual path in rules
   459  	c.Check(string(snippet), testutil.Contains, "path=\"/org/test-session-connected{,/**}\"\n")
   460  
   461  	// verify interface in rule
   462  	c.Check(string(snippet), testutil.Contains, "interface=\"org.test-session-connected{,.*}\"\n")
   463  }
   464  
   465  func (s *DbusInterfaceSuite) TestConnectedPlugAppArmorSystem(c *C) {
   466  	apparmorSpec := &apparmor.Specification{}
   467  	err := apparmorSpec.AddConnectedPlug(s.iface, s.connectedSystemPlug, s.connectedSystemSlot)
   468  	c.Assert(err, IsNil)
   469  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.test-dbus.test-session-consumer", "snap.test-dbus.test-session-provider", "snap.test-dbus.test-system-consumer", "snap.test-dbus.test-system-provider"})
   470  	snippet := apparmorSpec.SnippetForTag("snap.test-dbus.test-session-consumer")
   471  
   472  	// verify introspectable rule
   473  	c.Check(string(snippet), testutil.Contains, "dbus (send)\n    bus=system\n    interface=org.freedesktop.DBus.Introspectable\n    member=Introspect\n    peer=(label=\"snap.test-dbus.*\"),\n")
   474  
   475  	// verify bind rule not present
   476  	c.Check(string(snippet), Not(testutil.Contains), "dbus (bind)")
   477  
   478  	// verify well-known connection in rule
   479  	c.Check(string(snippet), testutil.Contains, "peer=(name=org.test-system-connected, label=")
   480  
   481  	// verify individual path in rules
   482  	c.Check(string(snippet), testutil.Contains, "path=\"/org/test-system-connected{,/**}\"\n")
   483  
   484  	// verify interface in rule
   485  	c.Check(string(snippet), testutil.Contains, "interface=\"org.test-system-connected{,.*}\"\n")
   486  }
   487  
   488  func (s *DbusInterfaceSuite) TestConnectionFirst(c *C) {
   489  	const plugYaml = `name: plugger
   490  version: 1.0
   491  plugs:
   492   this:
   493    interface: dbus
   494    bus: session
   495    name: org.slotter.session
   496  apps:
   497   app:
   498    command: foo
   499  `
   500  	const slotYaml = `name: slotter
   501  version: 1.0
   502  slots:
   503   this:
   504    interface: dbus
   505    bus: session
   506    name: org.slotter.session
   507   that:
   508    interface: dbus
   509    bus: system
   510    name: org.slotter.other-session
   511  `
   512  
   513  	plugInfo := snaptest.MockInfo(c, plugYaml, nil)
   514  	matchingPlug := interfaces.NewConnectedPlug(plugInfo.Plugs["this"], nil, nil)
   515  
   516  	slotInfo := snaptest.MockInfo(c, slotYaml, nil)
   517  	matchingSlot := interfaces.NewConnectedSlot(slotInfo.Slots["this"], nil, nil)
   518  	nonmatchingSlot := interfaces.NewConnectedSlot(slotInfo.Slots["that"], nil, nil)
   519  
   520  	apparmorSpec := &apparmor.Specification{}
   521  	err := apparmorSpec.AddConnectedPlug(s.iface, matchingPlug, matchingSlot)
   522  	c.Assert(err, IsNil)
   523  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.plugger.app"})
   524  	snippet := apparmorSpec.SnippetForTag("snap.plugger.app")
   525  
   526  	c.Check(snippet, testutil.Contains, "org.slotter.session")
   527  	c.Check(snippet, testutil.Contains, "bus=session")
   528  	c.Check(snippet, Not(testutil.Contains), "org.slotter.other-session")
   529  	c.Check(snippet, Not(testutil.Contains), "bus=system")
   530  
   531  	apparmorSpec = &apparmor.Specification{}
   532  	err = apparmorSpec.AddConnectedPlug(s.iface, matchingPlug, nonmatchingSlot)
   533  	c.Assert(err, IsNil)
   534  	c.Assert(apparmorSpec.SecurityTags(), HasLen, 0)
   535  }
   536  
   537  func (s *DbusInterfaceSuite) TestConnectionSecond(c *C) {
   538  	const plugYaml = `name: plugger
   539  version: 1.0
   540  plugs:
   541   that:
   542    interface: dbus
   543    bus: system
   544    name: org.slotter.other-session
   545  apps:
   546   app:
   547    command: foo
   548  `
   549  	const slotYaml = `name: slotter
   550  version: 1.0
   551  slots:
   552   this:
   553    interface: dbus
   554    bus: session
   555    name: org.slotter.session
   556   that:
   557    interface: dbus
   558    bus: system
   559    name: org.slotter.other-session
   560  `
   561  
   562  	plugInfo := snaptest.MockInfo(c, plugYaml, nil)
   563  	matchingPlug := interfaces.NewConnectedPlug(plugInfo.Plugs["that"], nil, nil)
   564  
   565  	slotInfo := snaptest.MockInfo(c, slotYaml, nil)
   566  	matchingSlot := interfaces.NewConnectedSlot(slotInfo.Slots["that"], nil, nil)
   567  	nonmatchingSlot := interfaces.NewConnectedSlot(slotInfo.Slots["this"], nil, nil)
   568  
   569  	apparmorSpec := &apparmor.Specification{}
   570  	err := apparmorSpec.AddConnectedPlug(s.iface, matchingPlug, matchingSlot)
   571  	c.Assert(err, IsNil)
   572  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.plugger.app"})
   573  	snippet := apparmorSpec.SnippetForTag("snap.plugger.app")
   574  
   575  	c.Check(snippet, testutil.Contains, "org.slotter.other-session")
   576  	c.Check(snippet, testutil.Contains, "bus=system")
   577  	c.Check(snippet, Not(testutil.Contains), "org.slotter.session")
   578  	c.Check(snippet, Not(testutil.Contains), "bus=session")
   579  
   580  	apparmorSpec = &apparmor.Specification{}
   581  	err = apparmorSpec.AddConnectedPlug(s.iface, matchingPlug, nonmatchingSlot)
   582  	c.Assert(err, IsNil)
   583  	c.Assert(apparmorSpec.SecurityTags(), HasLen, 0)
   584  }
   585  
   586  func (s *DbusInterfaceSuite) TestConnectionBoth(c *C) {
   587  	const plugYaml = `name: plugger
   588  version: 1.0
   589  plugs:
   590   that:
   591    interface: dbus
   592    bus: system
   593    name: org.slotter.other-session
   594   this:
   595    interface: dbus
   596    bus: session
   597    name: org.slotter.session
   598  apps:
   599   app:
   600    command: foo
   601  `
   602  	const slotYaml = `name: slotter
   603  version: 1.0
   604  slots:
   605   this:
   606    interface: dbus
   607    bus: session
   608    name: org.slotter.session
   609   that:
   610    interface: dbus
   611    bus: system
   612    name: org.slotter.other-session
   613  `
   614  
   615  	plugInfo := snaptest.MockInfo(c, plugYaml, nil)
   616  	matchingPlug1 := interfaces.NewConnectedPlug(plugInfo.Plugs["this"], nil, nil)
   617  	matchingPlug2 := interfaces.NewConnectedPlug(plugInfo.Plugs["that"], nil, nil)
   618  
   619  	slotInfo := snaptest.MockInfo(c, slotYaml, nil)
   620  	matchingSlot1 := interfaces.NewConnectedSlot(slotInfo.Slots["this"], nil, nil)
   621  	matchingSlot2 := interfaces.NewConnectedSlot(slotInfo.Slots["that"], nil, nil)
   622  
   623  	apparmorSpec := &apparmor.Specification{}
   624  	err := apparmorSpec.AddConnectedPlug(s.iface, matchingPlug1, matchingSlot1)
   625  	c.Assert(err, IsNil)
   626  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.plugger.app"})
   627  	snippet := apparmorSpec.SnippetForTag("snap.plugger.app")
   628  	c.Check(snippet, testutil.Contains, "org.slotter.session")
   629  	c.Check(snippet, testutil.Contains, "bus=session")
   630  
   631  	apparmorSpec = &apparmor.Specification{}
   632  	err = apparmorSpec.AddConnectedPlug(s.iface, matchingPlug2, matchingSlot2)
   633  	c.Assert(err, IsNil)
   634  	c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.plugger.app"})
   635  	snippet = apparmorSpec.SnippetForTag("snap.plugger.app")
   636  	c.Check(snippet, testutil.Contains, "org.slotter.other-session")
   637  	c.Check(snippet, testutil.Contains, "bus=system")
   638  }
   639  
   640  func (s *DbusInterfaceSuite) TestConnectionMismatchBus(c *C) {
   641  	const plugYaml = `name: plugger
   642  version: 1.0
   643  plugs:
   644   this:
   645    interface: dbus
   646    bus: session
   647    name: org.slotter.session
   648  `
   649  	const slotYaml = `name: slotter
   650  version: 1.0
   651  slots:
   652   this:
   653    interface: dbus
   654    bus: system
   655    name: org.slotter.session
   656  `
   657  
   658  	plugInfo := snaptest.MockInfo(c, plugYaml, nil)
   659  	plug := interfaces.NewConnectedPlug(plugInfo.Plugs["this"], nil, nil)
   660  
   661  	slotInfo := snaptest.MockInfo(c, slotYaml, nil)
   662  	slot := interfaces.NewConnectedSlot(slotInfo.Slots["this"], nil, nil)
   663  
   664  	apparmorSpec := &apparmor.Specification{}
   665  	err := apparmorSpec.AddConnectedPlug(s.iface, plug, slot)
   666  	c.Assert(err, IsNil)
   667  	c.Assert(apparmorSpec.SecurityTags(), HasLen, 0)
   668  }
   669  
   670  func (s *DbusInterfaceSuite) TestConnectionMismatchName(c *C) {
   671  	const plugYaml = `name: plugger
   672  version: 1.0
   673  plugs:
   674   this:
   675    interface: dbus
   676    bus: session
   677    name: org.slotter.session
   678  `
   679  	const slotYaml = `name: slotter
   680  version: 1.0
   681  slots:
   682   this:
   683    interface: dbus
   684    bus: session
   685    name: org.slotter.nomatch
   686  `
   687  
   688  	plugInfo := snaptest.MockInfo(c, plugYaml, nil)
   689  	plug := interfaces.NewConnectedPlug(plugInfo.Plugs["this"], nil, nil)
   690  
   691  	slotInfo := snaptest.MockInfo(c, slotYaml, nil)
   692  	slot := interfaces.NewConnectedSlot(slotInfo.Slots["this"], nil, nil)
   693  
   694  	apparmorSpec := &apparmor.Specification{}
   695  	err := apparmorSpec.AddConnectedPlug(s.iface, plug, slot)
   696  	c.Assert(err, IsNil)
   697  	c.Assert(apparmorSpec.SecurityTags(), HasLen, 0)
   698  }
   699  
   700  func (s *DbusInterfaceSuite) TestInterfaces(c *C) {
   701  	c.Check(builtin.Interfaces(), testutil.DeepContains, s.iface)
   702  }