Commit 3e248562 authored by George Kiagiadakis's avatar George Kiagiadakis

modules: add new module to manage client permissions

Currently this will just grant full access to all clients.
A future version will refine that to grant access to specific
objects only.
parent f4121663
......@@ -3,6 +3,17 @@ common_c_args = [
c_args : [common_c_args, '-DG_LOG_DOMAIN="m-client-permissions"'],
install : true,
install_dir : wireplumber_module_dir,
dependencies : [wp_dep, pipewire_dep],
/* WirePlumber
* Copyright © 2019 Collabora Ltd.
* @author George Kiagiadakis <>
* SPDX-License-Identifier: MIT
#include <wp/wp.h>
#include <pipewire/pipewire.h>
struct client_data
union {
struct pw_proxy *proxy;
struct pw_client_proxy *client_proxy;
struct spa_hook proxy_listener;
struct spa_hook client_listener;
gboolean done;
static gboolean
do_free_client_data (gpointer data)
g_slice_free (struct client_data, data);
static void
proxy_destroy (void *data)
g_idle_add (do_free_client_data, data);
static gboolean
do_destroy_proxy (gpointer data)
g_debug ("Destroying client proxy %p", data);
pw_proxy_destroy ((struct pw_proxy *) data);
static void
proxy_done (void *data, int seq)
struct client_data *d = data;
/* the proxy is not useful to keep around once we have changed permissions */
if (d->done)
g_idle_add (do_destroy_proxy, d->proxy);
static const struct pw_proxy_events proxy_events = {
.destroy = proxy_destroy,
.done = proxy_done,
static void
client_info (void *object, const struct pw_client_info *info)
struct client_data *d = object;
const char *access;
if (!(info->change_mask & PW_CLIENT_CHANGE_MASK_PROPS))
g_return_if_fail (info->props);
access = spa_dict_lookup (info->props, "pipewire.access");
/* grant full permissions to restricted or security confined apps
TODO: we should eventually build a system where we can use the role
and the client's security label to grant access only to specific nodes
and endpoints in the graph */
if (!g_strcmp0 (access, "flatpak") || !g_strcmp0 (access, "restricted")) {
const struct pw_permission perm = PW_PERMISSION_INIT(-1, PW_PERM_RWX);
g_debug ("Granting full access to client %d (%p)", info->id, d->proxy);
pw_client_proxy_update_permissions (d->client_proxy, 1, &perm);
d->done = TRUE;
pw_proxy_sync (d->proxy, 123456);
static const struct pw_client_proxy_events client_events = {
.info = client_info,
static void
client_added (WpRemotePipewire * remote, guint32 id, guint32 parent_id,
const struct spa_dict *properties, gpointer data)
struct client_data *d;
d = g_slice_new0 (struct client_data);
d->proxy = wp_remote_pipewire_proxy_bind (remote, id,
pw_proxy_add_listener (d->proxy, &d->proxy_listener, &proxy_events, d);
pw_client_proxy_add_listener (d->client_proxy, &d->client_listener,
&client_events, d);
g_debug ("Bound to client %d (%p)", id, d->proxy);
wireplumber__module_init (WpModule * module, WpCore * core, GVariant * args)
WpRemote *remote = wp_core_get_global (core, WP_GLOBAL_REMOTE_PIPEWIRE);
g_return_if_fail (remote != NULL);
g_signal_connect(remote, "global-added::client", (GCallback) client_added,
......@@ -3,3 +3,4 @@ load-module C libwireplumber-module-pw-audio-softdsp-endpoint
load-module C libwireplumber-module-pw-alsa-udev
load-module C libwireplumber-module-simple-policy
load-module C libwireplumber-module-mixer
load-module C libwireplumber-module-client-permissions
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment