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  }