Permalink
Cannot retrieve contributors at this time
Fetching contributors…
| // -*- Mode: Go; indent-tabs-mode: t -*- | |
| /* | |
| * Copyright (C) 2016-2017 Canonical Ltd | |
| * | |
| * This program is free software: you can redistribute it and/or modify | |
| * it under the terms of the GNU General Public License version 3 as | |
| * published by the Free Software Foundation. | |
| * | |
| * This program is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| * GNU General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU General Public License | |
| * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| * | |
| */ | |
| package builtin | |
| import ( | |
| "strings" | |
| "github.com/snapcore/snapd/interfaces" | |
| "github.com/snapcore/snapd/interfaces/apparmor" | |
| "github.com/snapcore/snapd/interfaces/dbus" | |
| "github.com/snapcore/snapd/interfaces/seccomp" | |
| "github.com/snapcore/snapd/interfaces/udev" | |
| "github.com/snapcore/snapd/release" | |
| "github.com/snapcore/snapd/snap" | |
| ) | |
| const bluezSummary = `allows operating as the bluez service` | |
| const bluezBaseDeclarationSlots = ` | |
| bluez: | |
| allow-installation: | |
| slot-snap-type: | |
| - app | |
| - core | |
| deny-auto-connection: true | |
| deny-connection: | |
| on-classic: false | |
| ` | |
| const bluezPermanentSlotAppArmor = ` | |
| # Description: Allow operating as the bluez service. This gives privileged | |
| # access to the system. | |
| network bluetooth, | |
| capability net_admin, | |
| capability net_bind_service, | |
| # libudev | |
| network netlink raw, | |
| # File accesses | |
| /sys/bus/usb/drivers/btusb/ r, | |
| /sys/bus/usb/drivers/btusb/** r, | |
| /sys/class/bluetooth/ r, | |
| /sys/devices/**/bluetooth/ rw, | |
| /sys/devices/**/bluetooth/** rw, | |
| /sys/devices/**/id/chassis_type r, | |
| # TODO: use snappy hardware assignment for this once LP: #1498917 is fixed | |
| /dev/rfkill rw, | |
| # DBus accesses | |
| #include <abstractions/dbus-strict> | |
| dbus (send) | |
| bus=system | |
| path=/org/freedesktop/DBus | |
| interface=org.freedesktop.DBus | |
| member={Request,Release}Name | |
| peer=(name=org.freedesktop.DBus, label=unconfined), | |
| dbus (send) | |
| bus=system | |
| path=/org/freedesktop/* | |
| interface=org.freedesktop.DBus.Properties | |
| peer=(label=unconfined), | |
| # Allow binding the service to the requested connection name | |
| dbus (bind) | |
| bus=system | |
| name="org.bluez", | |
| # Allow binding the service to the requested connection name | |
| dbus (bind) | |
| bus=system | |
| name="org.bluez.obex", | |
| # Allow traffic to/from our interface with any method for unconfined clients | |
| # to talk to our bluez services. For the org.bluez interface we don't specify | |
| # an Object Path since according to the bluez specification these can be | |
| # anything (https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc). | |
| dbus (receive, send) | |
| bus=system | |
| interface=org.bluez.* | |
| peer=(label=unconfined), | |
| dbus (receive, send) | |
| bus=system | |
| path=/org/bluez{,/**} | |
| interface=org.freedesktop.DBus.* | |
| peer=(label=unconfined), | |
| # Allow traffic to/from org.freedesktop.DBus for bluez service. This rule is | |
| # not snap-specific and grants privileged access to the org.freedesktop.DBus | |
| # on the system bus. | |
| dbus (receive, send) | |
| bus=system | |
| path=/ | |
| interface=org.freedesktop.DBus.* | |
| peer=(label=unconfined), | |
| # Allow access to hostname system service | |
| dbus (receive, send) | |
| bus=system | |
| path=/org/freedesktop/hostname1 | |
| interface=org.freedesktop.DBus.Properties | |
| peer=(label=unconfined), | |
| ` | |
| const bluezConnectedSlotAppArmor = ` | |
| # Allow connected clients to interact with the service | |
| # Allow all access to bluez service | |
| dbus (receive, send) | |
| bus=system | |
| peer=(label=###PLUG_SECURITY_TAGS###), | |
| ` | |
| const bluezConnectedPlugAppArmor = ` | |
| # Description: Allow using bluez service. This gives privileged access to the | |
| # bluez service. | |
| #include <abstractions/dbus-strict> | |
| # Allow all access to bluez service | |
| dbus (receive, send) | |
| bus=system | |
| peer=(label=###SLOT_SECURITY_TAGS###), | |
| dbus (send) | |
| bus=system | |
| peer=(name=org.bluez, label=unconfined), | |
| dbus (send) | |
| bus=system | |
| peer=(name=org.bluez.obex, label=unconfined), | |
| dbus (receive) | |
| bus=system | |
| path=/ | |
| interface=org.freedesktop.DBus.ObjectManager | |
| peer=(label=unconfined), | |
| dbus (receive) | |
| bus=system | |
| path=/org/bluez{,/**} | |
| interface=org.freedesktop.DBus.* | |
| peer=(label=unconfined), | |
| ` | |
| const bluezPermanentSlotSecComp = ` | |
| # Description: Allow operating as the bluez service. This gives privileged | |
| # access to the system. | |
| accept | |
| accept4 | |
| bind | |
| listen | |
| # libudev | |
| socket AF_NETLINK - NETLINK_KOBJECT_UEVENT | |
| ` | |
| const bluezPermanentSlotDBus = ` | |
| <policy user="root"> | |
| <allow own="org.bluez"/> | |
| <allow own="org.bluez.obex"/> | |
| <allow send_destination="org.bluez"/> | |
| <allow send_destination="org.bluez.obex"/> | |
| <allow send_interface="org.bluez.Agent1"/> | |
| <allow send_interface="org.bluez.ThermometerWatcher1"/> | |
| <allow send_interface="org.bluez.AlertAgent1"/> | |
| <allow send_interface="org.bluez.Profile1"/> | |
| <allow send_interface="org.bluez.HeartRateWatcher1"/> | |
| <allow send_interface="org.bluez.CyclingSpeedWatcher1"/> | |
| <allow send_interface="org.bluez.GattCharacteristic1"/> | |
| <allow send_interface="org.bluez.GattDescriptor1"/> | |
| <allow send_interface="org.freedesktop.DBus.ObjectManager"/> | |
| <allow send_interface="org.freedesktop.DBus.Properties"/> | |
| </policy> | |
| <policy context="default"> | |
| <deny send_destination="org.bluez"/> | |
| </policy> | |
| ` | |
| type bluezInterface struct{} | |
| func (iface *bluezInterface) Name() string { | |
| return "bluez" | |
| } | |
| func (iface *bluezInterface) StaticInfo() interfaces.StaticInfo { | |
| return interfaces.StaticInfo{ | |
| Summary: bluezSummary, | |
| ImplicitOnClassic: true, | |
| BaseDeclarationSlots: bluezBaseDeclarationSlots, | |
| } | |
| } | |
| func (iface *bluezInterface) DBusPermanentSlot(spec *dbus.Specification, slot *snap.SlotInfo) error { | |
| if !release.OnClassic { | |
| spec.AddSnippet(bluezPermanentSlotDBus) | |
| } | |
| return nil | |
| } | |
| func (iface *bluezInterface) AppArmorConnectedPlug(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { | |
| old := "###SLOT_SECURITY_TAGS###" | |
| var new string | |
| if release.OnClassic { | |
| new = "unconfined" | |
| } else { | |
| new = slotAppLabelExpr(slot) | |
| } | |
| snippet := strings.Replace(bluezConnectedPlugAppArmor, old, new, -1) | |
| spec.AddSnippet(snippet) | |
| return nil | |
| } | |
| func (iface *bluezInterface) AppArmorConnectedSlot(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { | |
| if !release.OnClassic { | |
| old := "###PLUG_SECURITY_TAGS###" | |
| new := plugAppLabelExpr(plug) | |
| snippet := strings.Replace(bluezConnectedSlotAppArmor, old, new, -1) | |
| spec.AddSnippet(snippet) | |
| } | |
| return nil | |
| } | |
| func (iface *bluezInterface) UDevConnectedPlug(spec *udev.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { | |
| spec.TagDevice(`KERNEL=="rfkill"`) | |
| return nil | |
| } | |
| func (iface *bluezInterface) AppArmorPermanentSlot(spec *apparmor.Specification, slot *snap.SlotInfo) error { | |
| if !release.OnClassic { | |
| spec.AddSnippet(bluezPermanentSlotAppArmor) | |
| } | |
| return nil | |
| } | |
| func (iface *bluezInterface) SecCompPermanentSlot(spec *seccomp.Specification, slot *snap.SlotInfo) error { | |
| if !release.OnClassic { | |
| spec.AddSnippet(bluezPermanentSlotSecComp) | |
| } | |
| return nil | |
| } | |
| func (iface *bluezInterface) AutoConnect(*interfaces.Plug, *interfaces.Slot) bool { | |
| // allow what declarations allowed | |
| return true | |
| } | |
| func init() { | |
| registerIface(&bluezInterface{}) | |
| } |