github.com/rigado/snapd@v2.42.5-go-mod+incompatible/interfaces/builtin/bluez.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2016-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 21 22 import ( 23 "strings" 24 25 "github.com/snapcore/snapd/interfaces" 26 "github.com/snapcore/snapd/interfaces/apparmor" 27 "github.com/snapcore/snapd/interfaces/dbus" 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 ) 33 34 const bluezSummary = `allows operating as the bluez service` 35 36 const bluezBaseDeclarationSlots = ` 37 bluez: 38 allow-installation: 39 slot-snap-type: 40 - app 41 - core 42 deny-auto-connection: true 43 deny-connection: 44 on-classic: false 45 ` 46 47 const bluezPermanentSlotAppArmor = ` 48 # Description: Allow operating as the bluez service. This gives privileged 49 # access to the system. 50 51 network bluetooth, 52 53 capability net_admin, 54 capability net_bind_service, 55 56 # libudev 57 network netlink raw, 58 59 # File accesses 60 /sys/bus/usb/drivers/btusb/ r, 61 /sys/bus/usb/drivers/btusb/** r, 62 /sys/class/bluetooth/ r, 63 /sys/devices/**/bluetooth/ rw, 64 /sys/devices/**/bluetooth/** rw, 65 /sys/devices/**/id/chassis_type r, 66 67 # TODO: use snappy hardware assignment for this once LP: #1498917 is fixed 68 /dev/rfkill rw, 69 70 # DBus accesses 71 #include <abstractions/dbus-strict> 72 dbus (send) 73 bus=system 74 path=/org/freedesktop/DBus 75 interface=org.freedesktop.DBus 76 member={Request,Release}Name 77 peer=(name=org.freedesktop.DBus, label=unconfined), 78 79 dbus (send) 80 bus=system 81 path=/org/freedesktop/* 82 interface=org.freedesktop.DBus.Properties 83 peer=(label=unconfined), 84 85 # Allow binding the service to the requested connection name 86 dbus (bind) 87 bus=system 88 name="org.bluez", 89 90 # Allow binding the service to the requested connection name 91 dbus (bind) 92 bus=system 93 name="org.bluez.obex", 94 95 # Allow binding the service to the requested connection name 96 dbus (bind) 97 bus=system 98 name="org.bluez.mesh", 99 100 # Allow traffic to/from our interface with any method for unconfined clients 101 # to talk to our bluez services. For the org.bluez interface we don't specify 102 # an Object Path since according to the bluez specification these can be 103 # anything (https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc). 104 dbus (receive, send) 105 bus=system 106 interface=org.bluez.* 107 peer=(label=unconfined), 108 dbus (receive, send) 109 bus=system 110 path=/org/bluez{,/**} 111 interface=org.freedesktop.DBus.* 112 peer=(label=unconfined), 113 114 # Allow traffic to/from org.freedesktop.DBus for bluez service. This rule is 115 # not snap-specific and grants privileged access to the org.freedesktop.DBus 116 # on the system bus. 117 dbus (receive, send) 118 bus=system 119 path=/ 120 interface=org.freedesktop.DBus.* 121 peer=(label=unconfined), 122 123 # Allow access to hostname system service 124 dbus (receive, send) 125 bus=system 126 path=/org/freedesktop/hostname1 127 interface=org.freedesktop.DBus.Properties 128 peer=(label=unconfined), 129 130 # do not use peer=(label=unconfined) here since this is DBus activated 131 dbus (send) 132 bus=system 133 path=/org/freedesktop/hostname1 134 interface=org.freedesktop.DBus.Properties 135 member="Get{,All}", 136 dbus (send) 137 bus=system 138 path=/org/freedesktop/hostname1 139 interface=org.freedesktop.DBus.Introspectable 140 member=Introspect, 141 ` 142 143 const bluezConnectedSlotAppArmor = ` 144 # Allow connected clients to interact with the service 145 146 # Allow all access to bluez service 147 dbus (receive, send) 148 bus=system 149 peer=(label=###PLUG_SECURITY_TAGS###), 150 ` 151 152 const bluezConnectedPlugAppArmor = ` 153 # Description: Allow using bluez service. This gives privileged access to the 154 # bluez service. 155 156 #include <abstractions/dbus-strict> 157 158 # Allow all access to bluez service 159 dbus (receive, send) 160 bus=system 161 peer=(label=###SLOT_SECURITY_TAGS###), 162 163 dbus (send) 164 bus=system 165 peer=(name=org.bluez, label=unconfined), 166 167 dbus (send) 168 bus=system 169 peer=(name=org.bluez.obex, label=unconfined), 170 171 dbus (send) 172 bus=system 173 peer=(name=org.bluez.mesh, label=unconfined), 174 175 dbus (receive) 176 bus=system 177 path=/ 178 interface=org.freedesktop.DBus.ObjectManager 179 peer=(label=unconfined), 180 181 dbus (receive) 182 bus=system 183 path=/org/bluez{,/**} 184 interface=org.freedesktop.DBus.* 185 peer=(label=unconfined), 186 ` 187 188 const bluezPermanentSlotSecComp = ` 189 # Description: Allow operating as the bluez service. This gives privileged 190 # access to the system. 191 accept 192 accept4 193 bind 194 listen 195 # libudev 196 socket AF_NETLINK - NETLINK_KOBJECT_UEVENT 197 ` 198 199 const bluezPermanentSlotDBus = ` 200 <policy user="root"> 201 <allow own="org.bluez"/> 202 <allow own="org.bluez.obex"/> 203 <allow own="org.bluez.mesh"/> 204 <allow send_destination="org.bluez"/> 205 <allow send_destination="org.bluez.obex"/> 206 <allow send_destination="org.bluez.mesh"/> 207 <allow send_interface="org.bluez.Agent1"/> 208 <allow send_interface="org.bluez.MediaEndpoint1"/> 209 <allow send_interface="org.bluez.MediaPlayer1"/> 210 <allow send_interface="org.bluez.ThermometerWatcher1"/> 211 <allow send_interface="org.bluez.AlertAgent1"/> 212 <allow send_interface="org.bluez.Profile1"/> 213 <allow send_interface="org.bluez.HeartRateWatcher1"/> 214 <allow send_interface="org.bluez.CyclingSpeedWatcher1"/> 215 <allow send_interface="org.bluez.GattCharacteristic1"/> 216 <allow send_interface="org.bluez.GattDescriptor1"/> 217 <allow send_interface="org.bluez.mesh.Element1"/> 218 <allow send_interface="org.bluez.mesh.Application1"/> 219 <allow send_interface="org.bluez.mesh.ProvisionAgent1"/> 220 <allow send_interface="org.bluez.mesh.Provisioner1"/> 221 <allow send_interface="org.bluez.mesh.Attention1"/> 222 <allow send_interface="org.bluez.mesh.Network1"/> 223 <allow send_interface="org.bluez.mesh.Node1"/> 224 <allow send_interface="org.bluez.mesh.Management1"/> 225 <allow send_interface="org.freedesktop.DBus.ObjectManager"/> 226 <allow send_interface="org.freedesktop.DBus.Properties"/> 227 </policy> 228 <policy context="default"> 229 <deny send_destination="org.bluez"/> 230 </policy> 231 ` 232 233 type bluezInterface struct{} 234 235 func (iface *bluezInterface) Name() string { 236 return "bluez" 237 } 238 239 func (iface *bluezInterface) StaticInfo() interfaces.StaticInfo { 240 return interfaces.StaticInfo{ 241 Summary: bluezSummary, 242 ImplicitOnClassic: true, 243 BaseDeclarationSlots: bluezBaseDeclarationSlots, 244 } 245 } 246 247 func (iface *bluezInterface) DBusPermanentSlot(spec *dbus.Specification, slot *snap.SlotInfo) error { 248 if !release.OnClassic { 249 spec.AddSnippet(bluezPermanentSlotDBus) 250 } 251 return nil 252 } 253 254 func (iface *bluezInterface) AppArmorConnectedPlug(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 255 old := "###SLOT_SECURITY_TAGS###" 256 var new string 257 if release.OnClassic { 258 new = "unconfined" 259 } else { 260 new = slotAppLabelExpr(slot) 261 } 262 snippet := strings.Replace(bluezConnectedPlugAppArmor, old, new, -1) 263 spec.AddSnippet(snippet) 264 return nil 265 } 266 267 func (iface *bluezInterface) AppArmorConnectedSlot(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 268 if !release.OnClassic { 269 old := "###PLUG_SECURITY_TAGS###" 270 new := plugAppLabelExpr(plug) 271 snippet := strings.Replace(bluezConnectedSlotAppArmor, old, new, -1) 272 spec.AddSnippet(snippet) 273 } 274 return nil 275 } 276 277 func (iface *bluezInterface) UDevConnectedPlug(spec *udev.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 278 spec.TagDevice(`KERNEL=="rfkill"`) 279 return nil 280 } 281 282 func (iface *bluezInterface) AppArmorPermanentSlot(spec *apparmor.Specification, slot *snap.SlotInfo) error { 283 if !release.OnClassic { 284 spec.AddSnippet(bluezPermanentSlotAppArmor) 285 } 286 return nil 287 } 288 289 func (iface *bluezInterface) SecCompPermanentSlot(spec *seccomp.Specification, slot *snap.SlotInfo) error { 290 if !release.OnClassic { 291 spec.AddSnippet(bluezPermanentSlotSecComp) 292 } 293 return nil 294 } 295 296 func (iface *bluezInterface) AutoConnect(*snap.PlugInfo, *snap.SlotInfo) bool { 297 // allow what declarations allowed 298 return true 299 } 300 301 func init() { 302 registerIface(&bluezInterface{}) 303 }