-
Notifications
You must be signed in to change notification settings - Fork 574
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
iface builtin: Add new systemd-user-control interface
This is meant to support desktop sessions boots fully driven by systemd and D-Bus activation on the user session.
- Loading branch information
Showing
4 changed files
with
234 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
// -*- Mode: Go; indent-tabs-mode: t -*- | ||
|
||
/* | ||
* Copyright (C) 2024 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 | ||
|
||
const systemdUserControlSummary = `allows to control the user session service manager` | ||
|
||
const systemdUserControlBaseDeclarationPlugs = ` | ||
systemd-user-control: | ||
allow-installation: false | ||
deny-auto-connection: true | ||
` | ||
|
||
const systemdUserControlBaseDeclarationSlots = ` | ||
systemd-user-control: | ||
allow-installation: | ||
slot-snap-type: | ||
- core | ||
deny-auto-connection: true | ||
` | ||
|
||
const systemdUserControlConnectedPlugAppArmor = ` | ||
# Description: Can control the user session service manager | ||
#include <abstractions/dbus-session-strict> | ||
#include <abstractions/dbus-strict> | ||
# Supporting session boot fully driven by user session systemd | ||
# and D-Bus activation | ||
# Please note that UpdateActivationEnvironment can alter D-Bus activated services behavior | ||
# (e.g. by setting LD_PRELOAD) | ||
# It is thus intended to be restricted only to snaps acting as a desktop session on Ubuntu Core systems | ||
# | ||
# For such snaps, it allows the session to pass important variables to other processes in the session | ||
# (e.g. DISPLAY, WAYLAND_DISPLAY) | ||
dbus (send) | ||
bus=session | ||
path={/,/org/freedesktop/DBus} | ||
interface=org.freedesktop.DBus | ||
member=UpdateActivationEnvironment | ||
peer=(label=unconfined), | ||
dbus (send) | ||
bus=session | ||
path=/org/freedesktop/systemd1 | ||
interface=org.freedesktop.DBus.Properties | ||
member={Set,Get,GetAll} | ||
peer=(label=unconfined), | ||
# Please note that SetEnvironment can alter existing units behavior (e.g. by setting LD_PRELOAD) | ||
# It is thus intended to be restricted only to snaps acting as a desktop session on Ubuntu Core systems | ||
# | ||
# For such snaps, it allows the session to pass important variables to other processes in the session | ||
# (e.g. DISPLAY, WAYLAND_DISPLAY) | ||
dbus (send) | ||
bus=session | ||
path=/org/freedesktop/systemd1 | ||
interface=org.freedesktop.systemd1.Manager | ||
member={SetEnvironment,UnsetEnvironment,UnsetAndSetEnvironment} | ||
peer=(label=unconfined), | ||
# Allow to introspect the units available in the session | ||
dbus (send) | ||
bus=session | ||
path=/org/freedesktop/systemd1 | ||
interface=org.freedesktop.systemd1.Manager | ||
member={Reload,ListUnitFiles,ListUnitFilesByPatterns} | ||
peer=(label=unconfined), | ||
# Allow to manage the units available in the session | ||
# (e.g. to start the target describing the full session, phase parts of the startup) | ||
dbus (send) | ||
bus=session | ||
path=/org/freedesktop/systemd1 | ||
interface=org.freedesktop.systemd1.Manager | ||
member={ResetFailed,Reload,StartUnit,StopUnit,RestartUnit} | ||
peer=(label=unconfined), | ||
` | ||
|
||
func init() { | ||
registerIface(&commonInterface{ | ||
name: "systemd-user-control", | ||
summary: systemdUserControlSummary, | ||
implicitOnCore: true, | ||
implicitOnClassic: false, // This is meant for use by session snaps on core, no use for apps in classic mode | ||
baseDeclarationPlugs: systemdUserControlBaseDeclarationPlugs, | ||
baseDeclarationSlots: systemdUserControlBaseDeclarationSlots, | ||
connectedPlugAppArmor: systemdUserControlConnectedPlugAppArmor, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// -*- Mode: Go; indent-tabs-mode: t -*- | ||
|
||
/* | ||
* Copyright (C) 2024 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_test | ||
|
||
import ( | ||
. "gopkg.in/check.v1" | ||
|
||
"github.com/snapcore/snapd/interfaces" | ||
"github.com/snapcore/snapd/interfaces/apparmor" | ||
"github.com/snapcore/snapd/interfaces/builtin" | ||
"github.com/snapcore/snapd/snap" | ||
"github.com/snapcore/snapd/testutil" | ||
) | ||
|
||
type SystemdUserControlInterfaceSuite struct { | ||
iface interfaces.Interface | ||
slotInfo *snap.SlotInfo | ||
slot *interfaces.ConnectedSlot | ||
plugInfo *snap.PlugInfo | ||
plug *interfaces.ConnectedPlug | ||
} | ||
|
||
var _ = Suite(&SystemdUserControlInterfaceSuite{ | ||
iface: builtin.MustInterface("systemd-user-control"), | ||
}) | ||
|
||
func (s *SystemdUserControlInterfaceSuite) SetUpTest(c *C) { | ||
var mockPlugSnapInfoYaml = `name: other | ||
version: 1.0 | ||
apps: | ||
app: | ||
command: foo | ||
plugs: [systemd-user-control] | ||
` | ||
var mockSlotSnapInfoYaml = `name: core | ||
version: 0 | ||
type: os | ||
slots: | ||
systemd-user-control: | ||
` | ||
s.plug, s.plugInfo = MockConnectedPlug(c, mockPlugSnapInfoYaml, nil, "systemd-user-control") | ||
s.slot, s.slotInfo = MockConnectedSlot(c, mockSlotSnapInfoYaml, nil, "systemd-user-control") | ||
} | ||
|
||
func (s *SystemdUserControlInterfaceSuite) TestName(c *C) { | ||
c.Assert(s.iface.Name(), Equals, "systemd-user-control") | ||
} | ||
|
||
func (s *SystemdUserControlInterfaceSuite) TestSanitizeSlot(c *C) { | ||
c.Assert(interfaces.BeforePrepareSlot(s.iface, s.slotInfo), IsNil) | ||
} | ||
|
||
func (s *SystemdUserControlInterfaceSuite) TestSanitizePlug(c *C) { | ||
c.Assert(interfaces.BeforePreparePlug(s.iface, s.plugInfo), IsNil) | ||
} | ||
|
||
func (s *SystemdUserControlInterfaceSuite) TestUsedSecuritySystems(c *C) { | ||
// connected plugs have a non-nil security snippet for apparmor | ||
appSet, err := interfaces.NewSnapAppSet(s.plug.Snap(), nil) | ||
c.Assert(err, IsNil) | ||
apparmorSpec := apparmor.NewSpecification(appSet) | ||
err = apparmorSpec.AddConnectedPlug(s.iface, s.plug, s.slot) | ||
c.Assert(err, IsNil) | ||
c.Assert(apparmorSpec.Snippets(), HasLen, 1) | ||
c.Assert(apparmorSpec.SnippetForTag("snap.other.app"), testutil.Contains, "bus=session") | ||
c.Assert(apparmorSpec.SnippetForTag("snap.other.app"), Not(testutil.Contains), "bus=system") | ||
c.Assert(apparmorSpec.SnippetForTag("snap.other.app"), testutil.Contains, "UpdateActivationEnvironment") | ||
} | ||
|
||
func (s *SystemdUserControlInterfaceSuite) TestInterfaces(c *C) { | ||
c.Check(builtin.Interfaces(), testutil.DeepContains, s.iface) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters