github.com/rigado/snapd@v2.42.5-go-mod+incompatible/interfaces/builtin/upower_observe.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 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/release" 30 "github.com/snapcore/snapd/snap" 31 ) 32 33 const upowerObserveSummary = `allows operating as or reading from the UPower service` 34 35 const upowerObserveBaseDeclarationSlots = ` 36 upower-observe: 37 allow-installation: 38 slot-snap-type: 39 - core 40 - app 41 deny-connection: 42 on-classic: false 43 ` 44 45 const upowerObservePermanentSlotAppArmor = ` 46 # Description: Allow operating as the UPower service. 47 48 network netlink raw, 49 50 # DBus accesses 51 #include <abstractions/dbus-strict> 52 53 dbus (send) 54 bus=system 55 path=/org/freedesktop/DBus 56 interface=org.freedesktop.DBus 57 member={Request,Release}Name 58 peer=(name=org.freedesktop.DBus), 59 60 dbus (receive, send) 61 bus=system 62 path=/org/freedesktop/DBus 63 interface=org.freedesktop.DBus 64 member="GetConnectionUnix{ProcessID,User}" 65 peer=(label=unconfined), 66 67 # Allow binding the service to the requested connection name 68 dbus (bind) 69 bus=system 70 name="org.freedesktop.UPower", 71 72 # Allow read-only access to service properties 73 dbus (receive) 74 bus=system 75 path=/org/freedesktop/login1{,/**} 76 interface=org.freedesktop.DBus.Properties 77 peer=(label=unconfined), 78 # do not use peer=(label=unconfined) here since this is DBus activated 79 dbus (send) 80 bus=system 81 path=/org/freedesktop/login1{,/**} 82 interface=org.freedesktop.DBus.Properties 83 member=Get{,All}, 84 85 # Allow receiving any signals from the logind service 86 dbus (receive) 87 bus=system 88 path=/org/freedesktop/login1{,/**} 89 interface=org.freedesktop.login1.* 90 peer=(label=unconfined), 91 92 # Allow access to logind service as we need to query it for possible 93 # power states and trigger these when the battery gets low and the 94 # system enters a critical state. 95 dbus (send) 96 bus=system 97 path=/org/freedesktop/login1{,/**} 98 interface=org.freedesktop.login1.Manager 99 member={CanPowerOff,CanSuspend,CanHibernate,CanHybridSleep,PowerOff,Suspend,Hibernate,HybridSleep} 100 peer=(label=unconfined), 101 ` 102 103 const upowerObserveConnectedSlotAppArmor = ` 104 # Allow traffic to/from our path and interface with any method 105 dbus (receive, send) 106 bus=system 107 path=/org/freedesktop/UPower{,/**} 108 interface=org.freedesktop.UPower* 109 peer=(label=###PLUG_SECURITY_TAGS###), 110 111 # Allow traffic to/from org.freedesktop.DBus for the UPower service 112 dbus (receive, send) 113 bus=system 114 path=/org/freedesktop/UPower{,/**} 115 interface=org.freedesktop.DBus.* 116 peer=(label=###PLUG_SECURITY_TAGS###), 117 ` 118 119 const upowerObservePermanentSlotSeccomp = ` 120 # libudev 121 bind 122 socket AF_NETLINK - NETLINK_KOBJECT_UEVENT 123 ` 124 125 const upowerObservePermanentSlotDBus = ` 126 <!-- DBus policy for upower (based on upstream version 0.99.4) --> 127 <policy user="root"> 128 <allow own="org.freedesktop.UPower"/> 129 </policy> 130 <policy context="default"> 131 <deny own="org.freedesktop.UPower"/> 132 133 <allow send_destination="org.freedesktop.UPower" 134 send_interface="org.freedesktop.DBus.Introspectable"/> 135 136 <allow send_destination="org.freedesktop.UPower" 137 send_interface="org.freedesktop.DBus.Peer"/> 138 <allow send_destination="org.freedesktop.UPower" 139 send_interface="org.freedesktop.DBus.Properties"/> 140 <allow send_destination="org.freedesktop.UPower.Device" 141 send_interface="org.freedesktop.DBus.Properties"/> 142 <allow send_destination="org.freedesktop.UPower.KbdBacklight" 143 send_interface="org.freedesktop.DBus.Properties"/> 144 <allow send_destination="org.freedesktop.UPower.Wakeups" 145 send_interface="org.freedesktop.DBus.Properties"/> 146 147 <allow send_destination="org.freedesktop.UPower" 148 send_interface="org.freedesktop.UPower"/> 149 <allow send_destination="org.freedesktop.UPower" 150 send_interface="org.freedesktop.UPower.Device"/> 151 <allow send_destination="org.freedesktop.UPower" 152 send_interface="org.freedesktop.UPower.KbdBacklight"/> 153 <allow send_destination="org.freedesktop.UPower" 154 send_interface="org.freedesktop.UPower.Wakeups"/> 155 </policy> 156 ` 157 158 const upowerObserveConnectedPlugAppArmor = ` 159 # Description: Can query UPower for power devices, history and statistics. 160 161 #include <abstractions/dbus-strict> 162 163 # Find all devices monitored by UPower 164 dbus (send) 165 bus=system 166 path=/org/freedesktop/UPower 167 interface=org.freedesktop.UPower 168 member=EnumerateDevices 169 peer=(label=###SLOT_SECURITY_TAGS###), 170 171 # Read all properties from UPower and devices 172 # do not use peer=(label=unconfined) here since this is DBus activated 173 dbus (send) 174 bus=system 175 path=/org/freedesktop/UPower{,/Wakeups,/devices/**} 176 interface=org.freedesktop.DBus.Properties 177 member=Get{,All}, 178 179 dbus (send) 180 bus=system 181 path=/org/freedesktop/UPower 182 interface=org.freedesktop.UPower 183 member=GetCriticalAction 184 peer=(label=###SLOT_SECURITY_TAGS###), 185 186 dbus (send) 187 bus=system 188 path=/org/freedesktop/UPower 189 interface=org.freedesktop.UPower 190 member=GetDisplayDevice 191 peer=(label=###SLOT_SECURITY_TAGS###), 192 193 dbus (send) 194 bus=system 195 path=/org/freedesktop/UPower/devices/** 196 interface=org.freedesktop.UPower.Device 197 member=GetHistory 198 peer=(label=###SLOT_SECURITY_TAGS###), 199 200 # Receive property changed events 201 dbus (receive) 202 bus=system 203 path=/org/freedesktop/UPower{,/devices/**} 204 interface=org.freedesktop.DBus.Properties 205 member=PropertiesChanged 206 peer=(label=###SLOT_SECURITY_TAGS###), 207 208 # Allow clients to introspect the service 209 # do not use peer=(label=unconfined) here since this is DBus activated 210 dbus (send) 211 bus=system 212 interface=org.freedesktop.DBus.Introspectable 213 path=/org/freedesktop/UPower 214 member=Introspect, 215 ` 216 217 type upowerObserveInterface struct{} 218 219 func (iface *upowerObserveInterface) Name() string { 220 return "upower-observe" 221 } 222 223 func (iface *upowerObserveInterface) StaticInfo() interfaces.StaticInfo { 224 return interfaces.StaticInfo{ 225 Summary: upowerObserveSummary, 226 ImplicitOnClassic: true, 227 BaseDeclarationSlots: upowerObserveBaseDeclarationSlots, 228 } 229 } 230 231 func (iface *upowerObserveInterface) AppArmorConnectedPlug(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 232 old := "###SLOT_SECURITY_TAGS###" 233 new := slotAppLabelExpr(slot) 234 if release.OnClassic { 235 // Let confined apps access unconfined upower on classic 236 new = "unconfined" 237 } 238 snippet := strings.Replace(upowerObserveConnectedPlugAppArmor, old, new, -1) 239 spec.AddSnippet(snippet) 240 return nil 241 } 242 243 func (iface *upowerObserveInterface) AppArmorPermanentSlot(spec *apparmor.Specification, slot *snap.SlotInfo) error { 244 spec.AddSnippet(upowerObservePermanentSlotAppArmor) 245 return nil 246 } 247 248 func (iface *upowerObserveInterface) SecCompPermanentSlot(spec *seccomp.Specification, slot *snap.SlotInfo) error { 249 spec.AddSnippet(upowerObservePermanentSlotSeccomp) 250 return nil 251 } 252 253 func (iface *upowerObserveInterface) DBusPermanentSlot(spec *dbus.Specification, slot *snap.SlotInfo) error { 254 spec.AddSnippet(upowerObservePermanentSlotDBus) 255 return nil 256 } 257 258 func (iface *upowerObserveInterface) AppArmorConnectedSlot(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 259 old := "###PLUG_SECURITY_TAGS###" 260 new := plugAppLabelExpr(plug) 261 snippet := strings.Replace(upowerObserveConnectedSlotAppArmor, old, new, -1) 262 spec.AddSnippet(snippet) 263 return nil 264 } 265 266 func (iface *upowerObserveInterface) AutoConnect(*snap.PlugInfo, *snap.SlotInfo) bool { 267 // allow what declarations allowed 268 return true 269 } 270 271 func init() { 272 registerIface(&upowerObserveInterface{}) 273 }