client access: add support for snap permissions
This patch adds to wireplumber code to manage the Snap audio permissions. SNAP containers have two main "audio" rules: * audio-playback: the applications inside the container can send audio samples into a sink * audio-record: the applications inside the container can get audio samples from a source Also, old SNAP containers had the "pulseaudio" rule, which just exposed the pulseaudio socket directly, without limits. This is similar to the current Flatpak audio permissions. In the pulseaudio days, an specific pulseaudio module was used that checked the permissions given to the application and allowed or forbide access to the pulseaudio operations. With the change to pipewire, this functionality must be implemented in pipewire-pulse and wireplumber to guarantee the sandbox security. The current code checks for the presence of the pipewire.snap.id property in a client, in which case it will read the pipewire.snap.audio.playback and pipewire.snap.audio.record properties, and allow or deny access to that client to the nodes with Audio/Sink or Audio/Source media.class property. See !567 and pipewire!1779
This commit is contained in:

committed by
George Kiagiadakis

parent
598b3c83ce
commit
2ec202dfa1
@@ -406,10 +406,15 @@ wireplumber.components = [
|
||||
provides = script.client.access-portal
|
||||
requires = [ support.portal-permissionstore ]
|
||||
}
|
||||
{
|
||||
name = client/access-snap.lua, type = script/lua
|
||||
provides = script.client.access-snap
|
||||
}
|
||||
{
|
||||
type = virtual, provides = policy.client.access
|
||||
wants = [ script.client.access-default,
|
||||
script.client.access-portal ]
|
||||
script.client.access-portal,
|
||||
script.client.access-snap ]
|
||||
}
|
||||
|
||||
## Device profile selection hooks
|
||||
|
87
src/scripts/client/access-snap.lua
Normal file
87
src/scripts/client/access-snap.lua
Normal file
@@ -0,0 +1,87 @@
|
||||
-- Manage snap audio permissions
|
||||
--
|
||||
-- Copyright © 2023 Canonical Ltd.
|
||||
-- @author Sergio Costas Rodriguez <sergio.costas@canonical.com>
|
||||
--
|
||||
-- SPDX-License-Identifier: MIT
|
||||
|
||||
function removeClientPermissionsForOtherClients (client)
|
||||
-- Remove access to any other clients, but allow all the process of the
|
||||
-- same snap to access their elements
|
||||
local client_id = client.properties["pipewire.snap.id"]
|
||||
for snap_client in clients_snap:iterate() do
|
||||
local snap_client_id = snap_client.properties["pipewire.snap.id"]
|
||||
if snap_client_id ~= client_id then
|
||||
client:update_permissions { [snap_client["bound-id"]] = "-" }
|
||||
end
|
||||
end
|
||||
for no_snap_client in clients_no_snap:iterate() do
|
||||
client:update_permissions { [no_snap_client["bound-id"]] = "-" }
|
||||
end
|
||||
end
|
||||
|
||||
function updateClientPermissions (client)
|
||||
-- Remove access to Audio/Sources and Audio/Sinks based on snap permissions
|
||||
for node in nodes_om:iterate() do
|
||||
local node_id = node["bound-id"]
|
||||
local property = "pipewire.snap.audio.playback"
|
||||
|
||||
if node.properties["media.class"] == "Audio/Source" then
|
||||
property = "pipewire.snap.audio.record"
|
||||
end
|
||||
|
||||
if client.properties[property] ~= "true" then
|
||||
client:update_permissions { [node_id] = "-" }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
clients_snap = ObjectManager {
|
||||
Interest {
|
||||
type = "client",
|
||||
Constraint { "pipewire.snap.id", "+", type = "pw"},
|
||||
}
|
||||
}
|
||||
|
||||
clients_no_snap = ObjectManager {
|
||||
Interest {
|
||||
type = "client",
|
||||
Constraint { "pipewire.snap.id", "-", type = "pw"},
|
||||
}
|
||||
}
|
||||
|
||||
nodes_om = ObjectManager {
|
||||
Interest {
|
||||
type = "node",
|
||||
Constraint { "media.class", "matches", "Audio/*"}
|
||||
}
|
||||
}
|
||||
|
||||
clients_snap:connect("object-added", function (om, client)
|
||||
-- If a new snap client is added, adjust its permissions
|
||||
updateClientPermissions (client)
|
||||
removeClientPermissionsForOtherClients (client)
|
||||
end)
|
||||
|
||||
clients_no_snap:connect("object-added", function (om, client)
|
||||
-- If a new, non-snap client is added,
|
||||
-- remove access to it from other snaps
|
||||
client_id = client["bound-id"]
|
||||
for snap_client in clients_snap:iterate() do
|
||||
if client.properties["pipewire.snap.id"] ~= nil then
|
||||
snap_client:update_permissions { [client_id] = "-" }
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
nodes_om:connect("object-added", function (om, node)
|
||||
-- If a new Audio/Sink or Audio/Source node is added,
|
||||
-- adjust the permissions in the snap clients
|
||||
for client in clients_snap:iterate() do
|
||||
updateClientPermissions (client)
|
||||
end
|
||||
end)
|
||||
|
||||
clients_snap:activate()
|
||||
clients_no_snap:activate()
|
||||
nodes_om:activate()
|
Reference in New Issue
Block a user