github.com/bugraaydogar/snapd@v0.0.0-20210315170335-8c70bb858939/interfaces/builtin/avahi_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/snap" 29 ) 30 31 const avahiObserveSummary = `allows discovery on a local network via the mDNS/DNS-SD protocol suite` 32 33 const avahiObserveBaseDeclarationSlots = ` 34 avahi-observe: 35 allow-installation: 36 slot-snap-type: 37 - app 38 - core 39 deny-auto-connection: true 40 deny-connection: 41 on-classic: false 42 ` 43 44 const avahiObservePermanentSlotAppArmor = ` 45 network netlink, 46 47 # Allow access to daemon to create socket 48 /{,var/}run/avahi-daemon/ w, 49 /{,var/}run/avahi-daemon/{pid,socket} rwk, 50 51 # Description: Allow operating as the avahi service. This gives 52 # privileged access to the system. 53 #include <abstractions/dbus-strict> 54 55 dbus (send) 56 bus=system 57 path=/org/freedesktop/DBus 58 interface=org.freedesktop.DBus 59 member={Request,Release}Name 60 peer=(name=org.freedesktop.DBus, label=unconfined), 61 62 dbus (receive, send) 63 bus=system 64 path=/org/freedesktop/DBus 65 interface=org.freedesktop.DBus 66 member=GetConnectionUnixProcessID 67 peer=(label=unconfined), 68 69 dbus (receive, send) 70 bus=system 71 path=/org/freedesktop/DBus 72 interface=org.freedesktop.DBus 73 member=GetConnectionUnixUser 74 peer=(label=unconfined), 75 76 # Allow binding the service to the requested connection name 77 dbus (bind) 78 bus=system 79 name="org.freedesktop.Avahi", 80 81 # Allow traffic to/from our path and interface with any method for unconfined 82 # clients to talk to our service. 83 dbus (receive, send) 84 bus=system 85 path=/org/freedesktop/Avahi{,/**} 86 interface=org.freedesktop.Avahi* 87 peer=(label=unconfined), 88 89 # Allow traffic to/from org.freedesktop.DBus for Avahi service 90 dbus (receive, send) 91 bus=system 92 path=/org/freedesktop/Avahi{,/**} 93 interface=org.freedesktop.DBus.* 94 peer=(label=unconfined), 95 ` 96 97 // Note: avahiObserveConnectedSlotAppArmor is also used by avahi-control in AppArmorConnectedSlot 98 const avahiObserveConnectedSlotAppArmor = ` 99 # Description: Allow operating as the avahi service. This gives 100 # privileged access to the system. 101 #include <abstractions/dbus-strict> 102 103 # Allow all access to Avahi service 104 105 dbus (receive) 106 bus=system 107 path=/ 108 interface=org.freedesktop.DBus.Peer 109 member=Ping 110 peer=(label=###PLUG_SECURITY_TAGS###), 111 112 dbus (receive) 113 bus=system 114 path=/ 115 interface=org.freedesktop.Avahi.Server 116 peer=(label=###PLUG_SECURITY_TAGS###), 117 118 dbus (send) 119 bus=system 120 interface=org.freedesktop.Avahi.Server 121 member=StateChanged 122 peer=(label=###PLUG_SECURITY_TAGS###), 123 124 # address resolving 125 dbus (receive) 126 bus=system 127 path=/Client*/AddressResolver* 128 interface=org.freedesktop.Avahi.AddressResolver 129 peer=(label=###PLUG_SECURITY_TAGS###), 130 131 dbus (send) 132 bus=system 133 interface=org.freedesktop.Avahi.AddressResolver 134 peer=(name=org.freedesktop.Avahi, label=###PLUG_SECURITY_TAGS###), 135 136 # host name resolving 137 dbus (receive) 138 bus=system 139 path=/Client*/HostNameResolver* 140 interface=org.freedesktop.Avahi.HostNameResolver 141 peer=(label=###PLUG_SECURITY_TAGS###), 142 143 dbus (send) 144 bus=system 145 interface=org.freedesktop.Avahi.HostNameResolver 146 peer=(label=###PLUG_SECURITY_TAGS###), 147 148 # service resolving 149 dbus (receive) 150 bus=system 151 path=/Client*/ServiceResolver* 152 interface=org.freedesktop.Avahi.ServiceResolver 153 peer=(label=###PLUG_SECURITY_TAGS###), 154 155 dbus (send) 156 bus=system 157 interface=org.freedesktop.Avahi.ServiceResolver 158 peer=(label=###PLUG_SECURITY_TAGS###), 159 160 # domain browsing 161 dbus (receive) 162 bus=system 163 path=/Client*/DomainBrowser* 164 interface=org.freedesktop.Avahi.DomainBrowser 165 peer=(label=###PLUG_SECURITY_TAGS###), 166 167 dbus (send) 168 bus=system 169 interface=org.freedesktop.Avahi.DomainBrowser 170 peer=(label=###PLUG_SECURITY_TAGS###), 171 172 # record browsing 173 dbus (receive) 174 bus=system 175 path=/Client*/RecordBrowser* 176 interface=org.freedesktop.Avahi.RecordBrowser 177 peer=(label=###PLUG_SECURITY_TAGS###), 178 179 dbus (send) 180 bus=system 181 interface=org.freedesktop.Avahi.RecordBrowser 182 peer=(label=###PLUG_SECURITY_TAGS###), 183 184 # service browsing 185 dbus (receive) 186 bus=system 187 path=/Client*/ServiceBrowser* 188 interface=org.freedesktop.Avahi.ServiceBrowser 189 peer=(label=###PLUG_SECURITY_TAGS###), 190 191 dbus (send) 192 bus=system 193 interface=org.freedesktop.Avahi.ServiceBrowser 194 peer=(label=###PLUG_SECURITY_TAGS###), 195 196 # service type browsing 197 dbus (receive) 198 bus=system 199 path=/Client*/ServiceTypeBrowser* 200 interface=org.freedesktop.Avahi.ServiceTypeBrowser 201 peer=(label=###PLUG_SECURITY_TAGS###), 202 203 dbus (send) 204 bus=system 205 interface=org.freedesktop.Avahi.ServiceTypeBrowser 206 peer=(label=###PLUG_SECURITY_TAGS###), 207 ` 208 209 // Note: avahiObservePermanentSlotDBus is used by avahi-control in DBusPermanentSlot 210 const avahiObservePermanentSlotDBus = ` 211 <!-- Only root can own the Avahi service --> 212 <policy user="root"> 213 <allow own="org.freedesktop.Avahi"/> 214 </policy> 215 216 <!-- Allow anyone to invoke methods on Avahi server, except SetHostName --> 217 <policy context="default"> 218 <allow send_destination="org.freedesktop.Avahi"/> 219 <allow receive_sender="org.freedesktop.Avahi"/> 220 221 <deny send_destination="org.freedesktop.Avahi" 222 send_interface="org.freedesktop.Avahi.Server" send_member="SetHostName"/> 223 </policy> 224 225 <!-- bus policy for "netdev" group is removed as it does not apply to Ubuntu core --> 226 <!-- Allow root to set SetHostName --> 227 <policy user="root"> 228 <allow send_destination="org.freedesktop.Avahi"/> 229 <allow receive_sender="org.freedesktop.Avahi"/> 230 </policy> 231 ` 232 233 // Note: avahiObserveConnectedPlugAppArmor is also used by avahi-control in AppArmorConnectedPlug 234 const avahiObserveConnectedPlugAppArmor = ` 235 # Description: allows domain, record, service, and service type browsing 236 # as well as address, host and service resolving 237 238 /{,var/}run/avahi-daemon/socket rw, 239 240 #include <abstractions/dbus-strict> 241 dbus (send) 242 bus=system 243 path=/ 244 interface=org.freedesktop.DBus.Peer 245 member=Ping 246 peer=(name=org.freedesktop.Avahi,label=###SLOT_SECURITY_TAGS###), 247 248 # Allow accessing DBus properties and resolving 249 dbus (send) 250 bus=system 251 path=/ 252 interface=org.freedesktop.Avahi.Server 253 member={Get*,Resolve*,IsNSSSupportAvailable} 254 peer=(name=org.freedesktop.Avahi,label=###SLOT_SECURITY_TAGS###), 255 256 # Allow receiving anything from the slot server 257 dbus (receive) 258 bus=system 259 interface=org.freedesktop.Avahi.Server 260 peer=(label=###SLOT_SECURITY_TAGS###), 261 262 # Don't allow introspection since it reveals too much (path is not service 263 # specific for unconfined) 264 # do not use peer=(label=unconfined) here since this is DBus activated 265 #dbus (send) 266 # bus=system 267 # path=/ 268 # interface=org.freedesktop.DBus.Introspectable 269 # member=Introspect, 270 271 # These allows tampering with other snap's browsers, so don't autoconnect for 272 # now. 273 274 # address resolving 275 dbus (send) 276 bus=system 277 path=/ 278 interface=org.freedesktop.Avahi.Server 279 member=AddressResolverNew 280 peer=(name=org.freedesktop.Avahi, label=###SLOT_SECURITY_TAGS###), 281 282 dbus (send) 283 bus=system 284 path=/Client*/AddressResolver* 285 interface=org.freedesktop.Avahi.AddressResolver 286 member=Free 287 peer=(name=org.freedesktop.Avahi, label=###SLOT_SECURITY_TAGS###), 288 289 dbus (receive) 290 bus=system 291 interface=org.freedesktop.Avahi.AddressResolver 292 peer=(label=###SLOT_SECURITY_TAGS###), 293 294 # host name resolving 295 dbus (send) 296 bus=system 297 path=/ 298 interface=org.freedesktop.Avahi.Server 299 member=HostNameResolverNew 300 peer=(name=org.freedesktop.Avahi, label=###SLOT_SECURITY_TAGS###), 301 302 dbus (send) 303 bus=system 304 path=/Client*/HostNameResolver* 305 interface=org.freedesktop.Avahi.HostNameResolver 306 member=Free 307 peer=(name=org.freedesktop.Avahi, label=###SLOT_SECURITY_TAGS###), 308 309 dbus (receive) 310 bus=system 311 interface=org.freedesktop.Avahi.HostNameResolver 312 peer=(label=###SLOT_SECURITY_TAGS###), 313 314 # service resolving 315 dbus (send) 316 bus=system 317 path=/ 318 interface=org.freedesktop.Avahi.Server 319 member=ServiceResolverNew 320 peer=(name=org.freedesktop.Avahi, label=###SLOT_SECURITY_TAGS###), 321 322 dbus (send) 323 bus=system 324 path=/Client*/ServiceResolver* 325 interface=org.freedesktop.Avahi.ServiceResolver 326 member=Free 327 peer=(name=org.freedesktop.Avahi, label=###SLOT_SECURITY_TAGS###), 328 329 dbus (receive) 330 bus=system 331 interface=org.freedesktop.Avahi.ServiceResolver 332 peer=(label=###SLOT_SECURITY_TAGS###), 333 334 # domain browsing 335 dbus (send) 336 bus=system 337 path=/ 338 interface=org.freedesktop.Avahi.Server 339 member=DomainBrowserNew 340 peer=(name=org.freedesktop.Avahi, label=###SLOT_SECURITY_TAGS###), 341 342 dbus (send) 343 bus=system 344 path=/Client*/DomainBrowser* 345 interface=org.freedesktop.Avahi.DomainBrowser 346 member=Free 347 peer=(name=org.freedesktop.Avahi, label=###SLOT_SECURITY_TAGS###), 348 349 dbus (receive) 350 bus=system 351 interface=org.freedesktop.Avahi.DomainBrowser 352 peer=(label=###SLOT_SECURITY_TAGS###), 353 354 # record browsing 355 dbus (send) 356 bus=system 357 path=/ 358 interface=org.freedesktop.Avahi.Server 359 member=RecordBrowserNew 360 peer=(name=org.freedesktop.Avahi, label=###SLOT_SECURITY_TAGS###), 361 362 dbus (send) 363 bus=system 364 path=/Client*/RecordBrowser* 365 interface=org.freedesktop.Avahi.RecordBrowser 366 member=Free 367 peer=(name=org.freedesktop.Avahi, label=###SLOT_SECURITY_TAGS###), 368 369 dbus (receive) 370 bus=system 371 interface=org.freedesktop.Avahi.RecordBrowser 372 peer=(label=###SLOT_SECURITY_TAGS###), 373 374 # service browsing 375 dbus (send) 376 bus=system 377 path=/ 378 interface=org.freedesktop.Avahi.Server 379 member=ServiceBrowserNew 380 peer=(name=org.freedesktop.Avahi, label=###SLOT_SECURITY_TAGS###), 381 382 dbus (send) 383 bus=system 384 path=/Client*/ServiceBrowser* 385 interface=org.freedesktop.Avahi.ServiceBrowser 386 member=Free 387 peer=(name=org.freedesktop.Avahi, label=###SLOT_SECURITY_TAGS###), 388 389 dbus (receive) 390 bus=system 391 interface=org.freedesktop.Avahi.ServiceBrowser 392 peer=(label=###SLOT_SECURITY_TAGS###), 393 394 # Service type browsing 395 dbus (send) 396 bus=system 397 path=/ 398 interface=org.freedesktop.Avahi.Server 399 member=ServiceTypeBrowserNew 400 peer=(name=org.freedesktop.Avahi, label=###SLOT_SECURITY_TAGS###), 401 402 dbus (send) 403 bus=system 404 path=/Client*/ServiceTypeBrowser* 405 interface=org.freedesktop.Avahi.ServiceTypeBrowser 406 member=Free 407 peer=(name=org.freedesktop.Avahi, label=###SLOT_SECURITY_TAGS###), 408 409 dbus (receive) 410 bus=system 411 interface=org.freedesktop.Avahi.ServiceTypeBrowser 412 peer=(label=###SLOT_SECURITY_TAGS###), 413 ` 414 415 type avahiObserveInterface struct{} 416 417 func (iface *avahiObserveInterface) Name() string { 418 return "avahi-observe" 419 } 420 421 func (iface *avahiObserveInterface) StaticInfo() interfaces.StaticInfo { 422 return interfaces.StaticInfo{ 423 Summary: avahiObserveSummary, 424 ImplicitOnClassic: true, 425 BaseDeclarationSlots: avahiObserveBaseDeclarationSlots, 426 } 427 } 428 429 func (iface *avahiObserveInterface) AppArmorConnectedPlug(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 430 old := "###SLOT_SECURITY_TAGS###" 431 var new string 432 // If we're running on classic, Avahi may be installed either as a snap of 433 // as part of the OS. If it is part of the OS, it will not have a security 434 // label like it would when installed as a snap. 435 if implicitSystemConnectedSlot(slot) { 436 // avahi from the OS is typically unconfined but known to sometimes be confined 437 // with stock apparmor 2.13.2+ profiles the label is avahi-daemon 438 new = "\"{unconfined,/usr/sbin/avahi-daemon,avahi-daemon}\"" 439 } else { 440 new = slotAppLabelExpr(slot) 441 } 442 snippet := strings.Replace(avahiObserveConnectedPlugAppArmor, old, new, -1) 443 spec.AddSnippet(snippet) 444 return nil 445 } 446 447 func (iface *avahiObserveInterface) AppArmorPermanentSlot(spec *apparmor.Specification, slot *snap.SlotInfo) error { 448 // Only apply slot snippet when running as application snap 449 // on classic, slot side can be system or application 450 if !implicitSystemPermanentSlot(slot) { 451 spec.AddSnippet(avahiObservePermanentSlotAppArmor) 452 } 453 return nil 454 } 455 456 func (iface *avahiObserveInterface) AppArmorConnectedSlot(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 457 // Only apply slot snippet when running as application snap 458 // on classic, slot side can be system or application 459 if !implicitSystemConnectedSlot(slot) { 460 old := "###PLUG_SECURITY_TAGS###" 461 new := plugAppLabelExpr(plug) 462 snippet := strings.Replace(avahiObserveConnectedSlotAppArmor, old, new, -1) 463 spec.AddSnippet(snippet) 464 } 465 return nil 466 } 467 468 func (iface *avahiObserveInterface) DBusPermanentSlot(spec *dbus.Specification, slot *snap.SlotInfo) error { 469 // Only apply slot snippet when running as application snap 470 // on classic, slot side can be system or application 471 if !implicitSystemPermanentSlot(slot) { 472 spec.AddSnippet(avahiObservePermanentSlotDBus) 473 } 474 return nil 475 } 476 477 func (iface *avahiObserveInterface) AutoConnect(*snap.PlugInfo, *snap.SlotInfo) bool { 478 // allow what declarations allowed 479 return true 480 } 481 482 func init() { 483 registerIface(&avahiObserveInterface{}) 484 }