github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/interfaces/builtin/ofono_test.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2017 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 "github.com/snapcore/snapd/interfaces" 26 "github.com/snapcore/snapd/interfaces/apparmor" 27 "github.com/snapcore/snapd/interfaces/builtin" 28 "github.com/snapcore/snapd/interfaces/seccomp" 29 "github.com/snapcore/snapd/interfaces/udev" 30 "github.com/snapcore/snapd/release" 31 "github.com/snapcore/snapd/snap" 32 "github.com/snapcore/snapd/snap/snaptest" 33 "github.com/snapcore/snapd/testutil" 34 ) 35 36 type OfonoInterfaceSuite struct { 37 iface interfaces.Interface 38 slotInfo *snap.SlotInfo 39 slot *interfaces.ConnectedSlot 40 plugInfo *snap.PlugInfo 41 plug *interfaces.ConnectedPlug 42 } 43 44 var _ = Suite(&OfonoInterfaceSuite{ 45 iface: builtin.MustInterface("ofono"), 46 }) 47 48 func (s *OfonoInterfaceSuite) SetUpTest(c *C) { 49 var mockPlugSnapInfoYaml = `name: other 50 version: 1.0 51 apps: 52 app: 53 command: foo 54 plugs: [ofono] 55 ` 56 const mockSlotSnapInfoYaml = `name: ofono 57 version: 1.0 58 slots: 59 ofono: 60 interface: ofono 61 apps: 62 app: 63 command: foo 64 slots: [ofono] 65 ` 66 snapInfo := snaptest.MockInfo(c, mockSlotSnapInfoYaml, nil) 67 s.slotInfo = snapInfo.Slots["ofono"] 68 s.slot = interfaces.NewConnectedSlot(s.slotInfo, nil, nil) 69 snapInfo = snaptest.MockInfo(c, mockPlugSnapInfoYaml, nil) 70 s.plugInfo = snapInfo.Plugs["ofono"] 71 s.plug = interfaces.NewConnectedPlug(s.plugInfo, nil, nil) 72 } 73 74 func (s *OfonoInterfaceSuite) TestName(c *C) { 75 c.Assert(s.iface.Name(), Equals, "ofono") 76 } 77 78 // The label glob when all apps are bound to the ofono slot 79 func (s *OfonoInterfaceSuite) TestConnectedPlugSnippetUsesSlotLabelAll(c *C) { 80 app1 := &snap.AppInfo{Name: "app1"} 81 app2 := &snap.AppInfo{Name: "app2"} 82 slot := interfaces.NewConnectedSlot(&snap.SlotInfo{ 83 Snap: &snap.Info{ 84 SuggestedName: "ofono", 85 Apps: map[string]*snap.AppInfo{"app1": app1, "app2": app2}, 86 }, 87 Name: "ofono", 88 Interface: "ofono", 89 Apps: map[string]*snap.AppInfo{"app1": app1, "app2": app2}, 90 }, nil, nil) 91 92 release.OnClassic = false 93 94 apparmorSpec := &apparmor.Specification{} 95 err := apparmorSpec.AddConnectedPlug(s.iface, s.plug, slot) 96 c.Assert(err, IsNil) 97 c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.other.app"}) 98 c.Assert(apparmorSpec.SnippetForTag("snap.other.app"), testutil.Contains, `peer=(label="snap.ofono.*"),`) 99 } 100 101 // The label uses alternation when some, but not all, apps is bound to the ofono slot 102 func (s *OfonoInterfaceSuite) TestConnectedPlugSnippetUsesSlotLabelSome(c *C) { 103 app1 := &snap.AppInfo{Name: "app1"} 104 app2 := &snap.AppInfo{Name: "app2"} 105 app3 := &snap.AppInfo{Name: "app3"} 106 slot := interfaces.NewConnectedSlot(&snap.SlotInfo{ 107 Snap: &snap.Info{ 108 SuggestedName: "ofono", 109 Apps: map[string]*snap.AppInfo{"app1": app1, "app2": app2, "app3": app3}, 110 }, 111 Name: "ofono", 112 Interface: "ofono", 113 Apps: map[string]*snap.AppInfo{"app1": app1, "app2": app2}, 114 }, nil, nil) 115 116 release.OnClassic = false 117 118 apparmorSpec := &apparmor.Specification{} 119 err := apparmorSpec.AddConnectedPlug(s.iface, s.plug, slot) 120 c.Assert(err, IsNil) 121 c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.other.app"}) 122 c.Assert(apparmorSpec.SnippetForTag("snap.other.app"), testutil.Contains, `peer=(label="snap.ofono.{app1,app2}"),`) 123 } 124 125 // The label uses short form when exactly one app is bound to the ofono slot 126 func (s *OfonoInterfaceSuite) TestConnectedPlugSnippetUsesSlotLabelOne(c *C) { 127 app := &snap.AppInfo{Name: "app"} 128 slot := interfaces.NewConnectedSlot(&snap.SlotInfo{ 129 Snap: &snap.Info{ 130 SuggestedName: "ofono", 131 Apps: map[string]*snap.AppInfo{"app": app}, 132 }, 133 Name: "ofono", 134 Interface: "ofono", 135 Apps: map[string]*snap.AppInfo{"app": app}, 136 }, nil, nil) 137 138 release.OnClassic = false 139 140 apparmorSpec := &apparmor.Specification{} 141 err := apparmorSpec.AddConnectedPlug(s.iface, s.plug, slot) 142 c.Assert(err, IsNil) 143 c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.other.app"}) 144 c.Assert(apparmorSpec.SnippetForTag("snap.other.app"), testutil.Contains, `peer=(label="snap.ofono.app"),`) 145 } 146 147 func (s *OfonoInterfaceSuite) TestConnectedPlugSnippetUsesUnconfinedLabelOnClassic(c *C) { 148 release.OnClassic = true 149 150 apparmorSpec := &apparmor.Specification{} 151 err := apparmorSpec.AddConnectedPlug(s.iface, s.plug, s.slot) 152 c.Assert(err, IsNil) 153 c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.other.app"}) 154 snippet := apparmorSpec.SnippetForTag("snap.other.app") 155 // verify apparmor connected 156 c.Assert(snippet, testutil.Contains, "#include <abstractions/dbus-strict>") 157 // verify classic connected 158 c.Assert(snippet, testutil.Contains, "peer=(label=unconfined),") 159 } 160 161 func (s *OfonoInterfaceSuite) TestConnectedPlugSnippetAppArmor(c *C) { 162 release.OnClassic = false 163 apparmorSpec := &apparmor.Specification{} 164 err := apparmorSpec.AddConnectedPlug(s.iface, s.plug, s.slot) 165 c.Assert(err, IsNil) 166 c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.other.app"}) 167 snippet := apparmorSpec.SnippetForTag("snap.other.app") 168 // verify apparmor connected 169 c.Assert(snippet, testutil.Contains, "#include <abstractions/dbus-strict>") 170 // verify classic didn't connect 171 c.Assert(snippet, Not(testutil.Contains), "peer=(label=unconfined),") 172 } 173 174 func (s *OfonoInterfaceSuite) TestConnectedSlotSnippetAppArmor(c *C) { 175 apparmorSpec := &apparmor.Specification{} 176 err := apparmorSpec.AddConnectedSlot(s.iface, s.plug, s.slot) 177 c.Assert(err, IsNil) 178 aasnippets := apparmorSpec.Snippets() 179 c.Assert(aasnippets, HasLen, 1) 180 c.Assert(aasnippets["snap.ofono.app"], HasLen, 1) 181 snippet := string(aasnippets["snap.ofono.app"][0]) 182 c.Check(string(snippet), testutil.Contains, "peer=(label=\"snap.other.app\")") 183 } 184 185 func (s *OfonoInterfaceSuite) TestPermanentSlotSnippetAppArmor(c *C) { 186 apparmorSpec := &apparmor.Specification{} 187 err := apparmorSpec.AddPermanentSlot(s.iface, s.slotInfo) 188 c.Assert(err, IsNil) 189 c.Assert(apparmorSpec.SecurityTags(), DeepEquals, []string{"snap.ofono.app"}) 190 c.Assert(apparmorSpec.SnippetForTag("snap.ofono.app"), testutil.Contains, "/dev/net/tun rw,") 191 } 192 193 func (s *OfonoInterfaceSuite) TestPermanentSlotSnippetSecComp(c *C) { 194 seccompSpec := &seccomp.Specification{} 195 err := seccompSpec.AddPermanentSlot(s.iface, s.slotInfo) 196 c.Assert(err, IsNil) 197 c.Assert(seccompSpec.SecurityTags(), DeepEquals, []string{"snap.ofono.app"}) 198 c.Assert(seccompSpec.SnippetForTag("snap.ofono.app"), testutil.Contains, "listen\n") 199 } 200 201 func (s *OfonoInterfaceSuite) TestPermanentSlotSnippetUDev(c *C) { 202 spec := &udev.Specification{} 203 c.Assert(spec.AddPermanentSlot(s.iface, s.slotInfo), IsNil) 204 c.Assert(spec.Snippets(), HasLen, 5) 205 c.Assert(spec.Snippets()[0], testutil.Contains, `LABEL="ofono_isi_end"`) 206 c.Assert(spec.Snippets(), testutil.Contains, `# ofono 207 KERNEL=="tty[a-zA-Z]*[0-9]*|cdc-wdm[0-9]*", TAG+="snap_ofono_app"`) 208 c.Assert(spec.Snippets(), testutil.Contains, `# ofono 209 KERNEL=="tun", TAG+="snap_ofono_app"`) 210 c.Assert(spec.Snippets(), testutil.Contains, `# ofono 211 KERNEL=="dsp", TAG+="snap_ofono_app"`) 212 c.Assert(spec.Snippets(), testutil.Contains, `TAG=="snap_ofono_app", RUN+="/usr/lib/snapd/snap-device-helper $env{ACTION} snap_ofono_app $devpath $major:$minor"`) 213 } 214 215 func (s *OfonoInterfaceSuite) TestInterfaces(c *C) { 216 c.Check(builtin.Interfaces(), testutil.DeepContains, s.iface) 217 }