Skip to content
Snippets Groups Projects
Commit 3e248562 authored by George Kiagiadakis's avatar George Kiagiadakis
Browse files

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
No related branches found
No related tags found
No related merge requests found
......@@ -3,6 +3,17 @@ common_c_args = [
'-DG_LOG_USE_STRUCTURED',
]
shared_library(
'wireplumber-module-client-permissions',
[
'module-client-permissions.c'
],
c_args : [common_c_args, '-DG_LOG_DOMAIN="m-client-permissions"'],
install : true,
install_dir : wireplumber_module_dir,
dependencies : [wp_dep, pipewire_dep],
)
shared_library(
'wireplumber-module-mixer',
[
......
/* WirePlumber
*
* Copyright © 2019 Collabora Ltd.
* @author George Kiagiadakis <george.kiagiadakis@collabora.com>
*
* 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);
return G_SOURCE_REMOVE;
}
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);
return G_SOURCE_REMOVE;
}
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 = {
PW_VERSION_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))
return;
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 = {
PW_VERSION_CLIENT_PROXY_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_TYPE_INTERFACE_Client);
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);
}
void
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,
NULL);
}
......@@ -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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment