gitee.com/mysnapcore/mysnapd@v0.1.0/interfaces/builtin/desktop_legacy.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  )
    28  
    29  const desktopLegacySummary = `allows privileged access to desktop legacy methods`
    30  
    31  // While this gives privileged access to legacy methods we should auto-connect
    32  // this transitional interface since most desktop applications will need it.
    33  // When safe alternative methods are added to the desktop interface by default,
    34  // we can consider making this manually connected.
    35  const desktopLegacyBaseDeclarationSlots = `
    36    desktop-legacy:
    37      allow-installation:
    38        slot-snap-type:
    39          - core
    40  `
    41  
    42  const desktopLegacyConnectedPlugAppArmor = `
    43  # Description: Can access common desktop legacy methods. This gives privileged
    44  # access to the user's input.
    45  
    46  # accessibility (a11y)
    47  #include <abstractions/dbus-session-strict>
    48  dbus (send)
    49      bus=session
    50      path=/org/a11y/bus
    51      interface=org.a11y.Bus
    52      member=GetAddress
    53      peer=(label=unconfined),
    54  
    55  #include <abstractions/dbus-accessibility-strict>
    56  
    57  # Allow access to the non-abstract D-Bus socket used by at-spi > 2.42.0
    58  #   https://gitlab.gnome.org/GNOME/at-spi2-core/-/issues/43
    59  owner /{,var/}run/user/[0-9]*/at-spi/bus* rw,
    60  
    61  # Allow access to the socket used by speech-dispatcher
    62  owner /{,var/}run/user/[0-9]*/speech-dispatcher/speechd.sock rw,
    63  
    64  # Allow the accessibility services in the user session to send us any events
    65  dbus (receive)
    66      bus=accessibility
    67      peer=(label=unconfined),
    68  
    69  # Allow querying for capabilities and registering
    70  dbus (send)
    71      bus=accessibility
    72      path="/org/a11y/atspi/accessible/root"
    73      interface="org.a11y.atspi.Socket"
    74      member="Embed"
    75      peer=(name=org.a11y.atspi.Registry, label=unconfined),
    76  dbus (send)
    77      bus=accessibility
    78      path="/org/a11y/atspi/registry"
    79      interface="org.a11y.atspi.Registry"
    80      member="GetRegisteredEvents"
    81      peer=(name=org.a11y.atspi.Registry, label=unconfined),
    82  dbus (send)
    83      bus=accessibility
    84      path="/org/a11y/atspi/registry/deviceeventcontroller"
    85      interface="org.a11y.atspi.DeviceEventController"
    86      member="Get{DeviceEvent,Keystroke}Listeners"
    87      peer=(name=org.a11y.atspi.Registry, label=unconfined),
    88  dbus (send)
    89      bus=accessibility
    90      path="/org/a11y/atspi/registry/deviceeventcontroller"
    91      interface="org.a11y.atspi.DeviceEventController"
    92      member="NotifyListenersSync"
    93      peer=(name=org.a11y.atspi.Registry, label=unconfined),
    94  
    95  # org.a11y.atspi is not designed for application isolation and these rules
    96  # can be used to send change events for other processes.
    97  dbus (send)
    98      bus=accessibility
    99      path="/org/a11y/atspi/accessible/root"
   100      interface="org.a11y.atspi.Event.Object"
   101      member="ChildrenChanged"
   102      peer=(name=org.freedesktop.DBus, label=unconfined),
   103  dbus (send)
   104      bus=accessibility
   105      path="/org/a11y/atspi/accessible/root"
   106      interface="org.a11y.atspi.Accessible"
   107      member="Get*"
   108      peer=(label=unconfined),
   109  dbus (send)
   110      bus=accessibility
   111      path="/org/a11y/atspi/accessible/[0-9]*"
   112      interface="org.a11y.atspi.Event.Object"
   113      member="{ChildrenChanged,PropertyChange,StateChanged,TextCaretMoved}"
   114      peer=(name=org.freedesktop.DBus, label=unconfined),
   115  dbus (send)
   116      bus=accessibility
   117      path="/org/a11y/atspi/accessible/[0-9]*"
   118      interface="org.freedesktop.DBus.Properties"
   119      member="Get{,All}"
   120      peer=(label=unconfined),
   121  
   122  dbus (send)
   123      bus=accessibility
   124      path="/org/a11y/atspi/cache"
   125      interface="org.a11y.atspi.Cache"
   126      member="{Add,Remove}Accessible"
   127      peer=(name=org.freedesktop.DBus, label=unconfined),
   128  
   129  
   130  # ibus
   131  # subset of ibus abstraction
   132  /usr/lib/@{multiarch}/gtk-2.0/[0-9]*/immodules/im-ibus.so mr,
   133  owner @{HOME}/.config/ibus/      r,
   134  owner @{HOME}/.config/ibus/bus/  r,
   135  owner @{HOME}/.config/ibus/bus/* r,
   136  
   137  # allow communicating with ibus-daemon (this allows sniffing key events)
   138  unix (connect, receive, send)
   139      type=stream
   140      peer=(addr="@/tmp/ibus/dbus-*"),
   141  
   142  # abstract path in ibus >= 1.5.22 uses $XDG_CACHE_HOME (ie, @{HOME}/.cache)
   143  # This should use this, but due to LP: #1856738 we cannot
   144  #unix (connect, receive, send)
   145  #    type=stream
   146  #    peer=(addr="@@{HOME}/.cache/ibus/dbus-*"),
   147  unix (connect, receive, send)
   148       type=stream
   149       peer=(addr="@/home/*/.cache/ibus/dbus-*"),
   150  
   151  
   152  # mozc
   153  # allow communicating with mozc server
   154  unix (connect, receive, send)
   155       type=stream
   156       peer=(addr="@tmp/.mozc.*"),
   157  
   158  
   159  # fcitx
   160  # allow communicating with fcitx dbus service
   161  dbus send
   162      bus=fcitx
   163      path=/org/freedesktop/DBus
   164      interface=org.freedesktop.DBus
   165      member={Hello,AddMatch,RemoveMatch,GetNameOwner,NameHasOwner,StartServiceByName}
   166      peer=(name=org.freedesktop.DBus),
   167  
   168  owner @{HOME}/.config/fcitx/dbus/* r,
   169  
   170  # allow creating an input context
   171  dbus send
   172      bus={fcitx,session}
   173      path=/inputmethod
   174      interface=org.fcitx.Fcitx.InputMethod
   175      member=CreateIC*
   176      peer=(label=unconfined),
   177  
   178  # allow setting up and tearing down the input context
   179  dbus send
   180      bus={fcitx,session}
   181      path=/inputcontext_[0-9]*
   182      interface=org.fcitx.Fcitx.InputContext
   183      member="{Close,Destroy,Enable}IC"
   184      peer=(label=unconfined),
   185  
   186  dbus send
   187      bus={fcitx,session}
   188      path=/inputcontext_[0-9]*
   189      interface=org.fcitx.Fcitx.InputContext
   190      member=Reset
   191      peer=(label=unconfined),
   192  
   193  # allow service to send us signals
   194  dbus receive
   195      bus=fcitx
   196      peer=(label=unconfined),
   197  
   198  dbus receive
   199      bus=session
   200      interface=org.fcitx.Fcitx.*
   201      peer=(label=unconfined),
   202  
   203  # use the input context
   204  dbus send
   205      bus={fcitx,session}
   206      path=/inputcontext_[0-9]*
   207      interface=org.fcitx.Fcitx.InputContext
   208      member="Focus{In,Out}"
   209      peer=(label=unconfined),
   210  
   211  dbus send
   212      bus={fcitx,session}
   213      path=/inputcontext_[0-9]*
   214      interface=org.fcitx.Fcitx.InputContext
   215      member="{CommitPreedit,Set*}"
   216      peer=(label=unconfined),
   217  
   218  # this is an information leak and allows key and mouse sniffing. If the input
   219  # context path were tied to the process' security label, this would not be an
   220  # issue.
   221  dbus send
   222      bus={fcitx,session}
   223      path=/inputcontext_[0-9]*
   224      interface=org.fcitx.Fcitx.InputContext
   225      member="{MouseEvent,ProcessKeyEvent}"
   226      peer=(label=unconfined),
   227  
   228  # this method does not exist with the sunpinyin backend (at least), so allow
   229  # it for other input methods. This may consitute an information leak (which,
   230  # again, could be avoided if the path were tied to the process' security
   231  # label).
   232  dbus send
   233      bus={fcitx,session}
   234      path=/inputcontext_[0-9]*
   235      interface=org.freedesktop.DBus.Properties
   236      member=GetAll
   237      peer=(label=unconfined),
   238  
   239  # gtk2/gvfs gtk_show_uri()
   240  dbus (send)
   241      bus=session
   242      path=/org/gtk/vfs/mounttracker
   243      interface=org.gtk.vfs.MountTracker
   244      member=ListMountableInfo,
   245  dbus (send)
   246      bus=session
   247      path=/org/gtk/vfs/mounttracker
   248      interface=org.gtk.vfs.MountTracker
   249      member=LookupMount,
   250  
   251  ###SNAP_DESKTOP_FILE_RULES###
   252  # Snaps are unable to use the data in mimeinfo.cache (since they can't execute
   253  # the returned desktop file themselves). unity messaging menu doesn't require
   254  # mimeinfo.cache and xdg-mime will fallback to reading the desktop files
   255  # directly to look for MimeType. Since reading the snap's own desktop files is
   256  # allowed, we can safely deny access to this file (and xdg-mime will either
   257  # return one of the snap's mimetypes, or none).
   258  deny /var/lib/snapd/desktop/applications/mimeinfo.cache r,
   259  
   260  # glib-networking's GLib proxy (different than the portal's proxy service
   261  # org.freedesktop.portal.ProxyResolver). The Lookup API allows specifying
   262  # various URLs (eg, file://, http:// and https://) which will be given to the
   263  # unconfined glib-pacrunner.
   264  dbus (send)
   265      bus=session
   266      path=/org/gtk/GLib/PACRunner
   267      interface=org.gtk.GLib.PACRunner
   268      member=Lookup
   269      peer=(label=unconfined),
   270  
   271  # app-indicators
   272  dbus (send)
   273      bus=session
   274      path=/StatusNotifierWatcher
   275      interface=org.freedesktop.DBus.Introspectable
   276      member=Introspect
   277      peer=(name=org.kde.StatusNotifierWatcher, label=unconfined),
   278  
   279  dbus (send)
   280      bus=session
   281      path=/org/freedesktop/DBus
   282      interface=org.freedesktop.DBus
   283      member="{GetConnectionUnixProcessID,RequestName,ReleaseName}"
   284      peer=(name=org.freedesktop.DBus, label=unconfined),
   285  
   286  dbus (bind)
   287      bus=session
   288      name=org.kde.StatusNotifierItem-[0-9]*,
   289  
   290  dbus (send)
   291      bus=session
   292      path=/StatusNotifierWatcher
   293      interface=org.freedesktop.DBus.Properties
   294      member=Get
   295      peer=(name=org.kde.StatusNotifierWatcher, label=unconfined),
   296  
   297  dbus (send)
   298      bus=session
   299      path=/{StatusNotifierWatcher,org/ayatana/NotificationItem/*}
   300      interface=org.kde.StatusNotifierWatcher
   301      member=RegisterStatusNotifierItem
   302      peer=(label=unconfined),
   303  
   304  dbus (send)
   305      bus=session
   306      path=/{StatusNotifierItem,org/ayatana/NotificationItem/*}
   307      interface=org.kde.StatusNotifierItem
   308      member="New{AttentionIcon,Icon,IconThemePath,OverlayIcon,Status,Title,ToolTip}"
   309      peer=(name=org.freedesktop.DBus, label=unconfined),
   310  
   311  dbus (receive)
   312      bus=session
   313      path=/{StatusNotifierItem,org/ayatana/NotificationItem/*}
   314      interface=org.kde.StatusNotifierItem
   315      member={Activate,ContextMenu,Scroll,SecondaryActivate,XAyatanaSecondaryActivate}
   316      peer=(label=unconfined),
   317  
   318  dbus (send)
   319      bus=session
   320      path=/{StatusNotifierItem/menu,org/ayatana/NotificationItem/*/Menu}
   321      interface=com.canonical.dbusmenu
   322      member="{LayoutUpdated,ItemsPropertiesUpdated}"
   323      peer=(name=org.freedesktop.DBus, label=unconfined),
   324  
   325  dbus (receive)
   326      bus=session
   327      path=/{StatusNotifierItem,StatusNotifierItem/menu,org/ayatana/NotificationItem/**}
   328      interface={org.freedesktop.DBus.Properties,com.canonical.dbusmenu}
   329      member={Get*,AboutTo*,Event*}
   330      peer=(label=unconfined),
   331  
   332  # notifications
   333  dbus (send)
   334      bus=session
   335      path=/org/freedesktop/Notifications
   336      interface=org.freedesktop.Notifications
   337      member="{GetCapabilities,GetServerInformation,Notify,CloseNotification}"
   338      peer=(label=unconfined),
   339  
   340  dbus (receive)
   341      bus=session
   342      path=/org/freedesktop/Notifications
   343      interface=org.freedesktop.Notifications
   344      member={ActionInvoked,NotificationClosed,NotificationReplied}
   345      peer=(label=unconfined),
   346  
   347  # KDE Plasma's Inhibited property indicating "do not disturb" mode
   348  # https://invent.kde.org/plasma/plasma-workspace/-/blob/master/libnotificationmanager/dbus/org.freedesktop.Notifications.xml#L42
   349  dbus (send)
   350      bus=session
   351      path=/org/freedesktop/Notifications
   352      interface=org.freedesktop.DBus.Properties
   353      member="Get{,All}"
   354      peer=(label=unconfined),
   355  
   356  dbus (receive)
   357      bus=session
   358      path=/org/freedesktop/Notifications
   359      interface=org.freedesktop.DBus.Properties
   360      member=PropertiesChanged
   361      peer=(label=unconfined),
   362  
   363  dbus (send)
   364      bus=session
   365      path=/org/ayatana/NotificationItem/*
   366      interface=org.kde.StatusNotifierItem
   367      member=XAyatanaNew*
   368      peer=(name=org.freedesktop.DBus, label=unconfined),
   369  `
   370  
   371  const desktopLegacyConnectedPlugSecComp = `
   372  # Description: Can access common desktop legacy methods. This gives privileged
   373  # access to the user's input.
   374  
   375  listen
   376  accept
   377  accept4
   378  `
   379  
   380  type desktopLegacyInterface struct {
   381  	commonInterface
   382  }
   383  
   384  func (iface *desktopLegacyInterface) AppArmorConnectedPlug(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error {
   385  	snippet := strings.Join(getDesktopFileRules(plug.Snap().DesktopPrefix()), "\n")
   386  	spec.AddSnippet(strings.Replace(desktopLegacyConnectedPlugAppArmor, "###SNAP_DESKTOP_FILE_RULES###", snippet+"\n", -1))
   387  
   388  	return nil
   389  }
   390  
   391  func init() {
   392  	registerIface(&desktopLegacyInterface{
   393  		commonInterface: commonInterface{
   394  			name:                 "desktop-legacy",
   395  			summary:              desktopLegacySummary,
   396  			implicitOnClassic:    true,
   397  			baseDeclarationSlots: desktopLegacyBaseDeclarationSlots,
   398  			connectedPlugSecComp: desktopLegacyConnectedPlugSecComp,
   399  		},
   400  	})
   401  }