gitee.com/mysnapcore/mysnapd@v0.1.0/interfaces/builtin/avahi_control.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 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  	"gitee.com/mysnapcore/mysnapd/interfaces"
    26  	"gitee.com/mysnapcore/mysnapd/interfaces/apparmor"
    27  	"gitee.com/mysnapcore/mysnapd/interfaces/dbus"
    28  	"gitee.com/mysnapcore/mysnapd/snap"
    29  )
    30  
    31  const avahiControlBaseDeclarationSlots = `
    32    avahi-control:
    33      allow-installation:
    34        slot-snap-type:
    35          - app
    36          - core
    37      deny-auto-connection: true
    38      deny-connection:
    39        on-classic: false
    40  `
    41  
    42  const avahiControlSummary = `allows control over service discovery on a local network via the mDNS/DNS-SD protocol suite`
    43  
    44  const avahiControlConnectedSlotAppArmor = `
    45  # Description: allows configuration of service discovery via mDNS/DNS-SD
    46  # EntryGroup
    47  dbus (receive)
    48      bus=system
    49      path=/Client*/EntryGroup*
    50      interface=org.freedesktop.Avahi.EntryGroup
    51      peer=(label=###PLUG_SECURITY_TAGS###),
    52  
    53  dbus (send)
    54      bus=system
    55      interface=org.freedesktop.Avahi.EntryGroup
    56      member=StateChanged
    57      peer=(name=org.freedesktop.Avahi, label=###PLUG_SECURITY_TAGS###),
    58  `
    59  
    60  const avahiControlConnectedPlugAppArmor = `
    61  dbus (send)
    62      bus=system
    63      path=/
    64      interface=org.freedesktop.Avahi.Server
    65      member=Set*
    66      peer=(name=org.freedesktop.Avahi,label=###SLOT_SECURITY_TAGS###),
    67  
    68  # EntryGroup
    69  dbus (send)
    70      bus=system
    71      path=/
    72      interface=org.freedesktop.Avahi.Server
    73      member=EntryGroupNew
    74      peer=(name=org.freedesktop.Avahi, label=###SLOT_SECURITY_TAGS###),
    75  
    76  dbus (send)
    77      bus=system
    78      path=/Client*/EntryGroup*
    79      interface=org.freedesktop.Avahi.EntryGroup
    80      member={Free,Commit,Reset}
    81      peer=(name=org.freedesktop.Avahi, label=###SLOT_SECURITY_TAGS###),
    82  
    83  dbus (send)
    84      bus=system
    85      path=/Client*/EntryGroup*
    86      interface=org.freedesktop.Avahi.EntryGroup
    87      member={GetState,IsEmpty,UpdateServiceTxt}
    88      peer=(name=org.freedesktop.Avahi, label=###SLOT_SECURITY_TAGS###),
    89  
    90  dbus (send)
    91      bus=system
    92      path=/Client*/EntryGroup*
    93      interface=org.freedesktop.Avahi.EntryGroup
    94      member=Add{Service,ServiceSubtype,Address,Record}
    95      peer=(name=org.freedesktop.Avahi, label=###SLOT_SECURITY_TAGS###),
    96  
    97  dbus (receive)
    98      bus=system
    99      path=/Client*/EntryGroup*
   100      interface=org.freedesktop.Avahi.EntryGroup
   101      peer=(label=###SLOT_SECURITY_TAGS###),
   102  `
   103  
   104  type avahiControlInterface struct{}
   105  
   106  func (iface *avahiControlInterface) Name() string {
   107  	return "avahi-control"
   108  }
   109  
   110  func (iface *avahiControlInterface) StaticInfo() interfaces.StaticInfo {
   111  	return interfaces.StaticInfo{
   112  		Summary:              avahiControlSummary,
   113  		ImplicitOnClassic:    true,
   114  		BaseDeclarationSlots: avahiControlBaseDeclarationSlots,
   115  	}
   116  }
   117  
   118  func (iface *avahiControlInterface) AppArmorConnectedPlug(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error {
   119  	old := "###SLOT_SECURITY_TAGS###"
   120  	var new string
   121  	// If we're running on classic, Avahi may be installed either as a snap of
   122  	// as part of the OS. If it is part of the OS, it will not have a security
   123  	// label like it would when installed as a snap.
   124  	if implicitSystemConnectedSlot(slot) {
   125  		// avahi from the OS is typically unconfined but known to sometimes be confined
   126  		// with stock apparmor 2.13.2+ profiles the label is avahi-daemon
   127  		new = "\"{unconfined,/usr/sbin/avahi-daemon,avahi-daemon}\""
   128  	} else {
   129  		new = slotAppLabelExpr(slot)
   130  	}
   131  	// avahi-control implies avahi-observe, so add snippets for both here
   132  	snippet := strings.Replace(avahiObserveConnectedPlugAppArmor, old, new, -1)
   133  	spec.AddSnippet(snippet)
   134  	snippet = strings.Replace(avahiControlConnectedPlugAppArmor, old, new, -1)
   135  	spec.AddSnippet(snippet)
   136  	return nil
   137  }
   138  
   139  func (iface *avahiControlInterface) AppArmorPermanentSlot(spec *apparmor.Specification, slot *snap.SlotInfo) error {
   140  	// Only apply slot snippet when running as application snap
   141  	// on classic, slot side can be system or application
   142  	if !implicitSystemPermanentSlot(slot) {
   143  		// NOTE: this is using avahi-observe permanent slot as it contains
   144  		// base declarations for running as the avahi service.
   145  		spec.AddSnippet(avahiObservePermanentSlotAppArmor)
   146  	}
   147  	return nil
   148  }
   149  
   150  func (iface *avahiControlInterface) AppArmorConnectedSlot(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error {
   151  	// Only apply slot snippet when running as application snap
   152  	// on classic, slot side can be system or application
   153  	if !implicitSystemConnectedSlot(slot) {
   154  		old := "###PLUG_SECURITY_TAGS###"
   155  		new := plugAppLabelExpr(plug)
   156  		// avahi-control implies avahi-observe, so add snippets for both here
   157  		snippet := strings.Replace(avahiObserveConnectedSlotAppArmor, old, new, -1)
   158  		spec.AddSnippet(snippet)
   159  		snippet = strings.Replace(avahiControlConnectedSlotAppArmor, old, new, -1)
   160  		spec.AddSnippet(snippet)
   161  	}
   162  	return nil
   163  }
   164  
   165  func (iface *avahiControlInterface) DBusPermanentSlot(spec *dbus.Specification, slot *snap.SlotInfo) error {
   166  	// Only apply slot snippet when running as application snap
   167  	// on classic, slot side can be system or application
   168  	if !implicitSystemPermanentSlot(slot) {
   169  		// NOTE: this is using avahi-observe permanent slot as it contains
   170  		// base declarations for running as the avahi service.
   171  		spec.AddSnippet(avahiObservePermanentSlotDBus)
   172  	}
   173  	return nil
   174  }
   175  
   176  func (iface *avahiControlInterface) AutoConnect(*snap.PlugInfo, *snap.SlotInfo) bool {
   177  	// allow what declarations allowed
   178  	return true
   179  }
   180  
   181  func init() {
   182  	registerIface(&avahiControlInterface{})
   183  }