pulse-server: give Manager permission for Flatpak apps with devices=all

Some Flatpak apps want to manage sound fully (change default outputs,
move streams from other applications).  Real Pulseaudio always grants
full permissions, but pipewire-pulse doesn't, which breaks some
applications, e.g. Zoom.

Work around this by granting the manager permission if the application
also has devices=all access.

To do things properly, this probably should use the Portal media roles,
but this would need further work elsewhere.
This commit is contained in:
Pauli Virtanen 2022-07-31 15:25:20 +03:00 committed by Wim Taymans
parent 0e12242a1b
commit 6d4d77802a

View file

@ -418,7 +418,7 @@ on_connect(void *data, int fd, uint32_t mask)
client_access = server->client_access; client_access = server->client_access;
if (server->addr.ss_family == AF_UNIX) { if (server->addr.ss_family == AF_UNIX) {
char *app_id = NULL; char *app_id = NULL, *devices = NULL;
#ifdef SO_PRIORITY #ifdef SO_PRIORITY
val = 6; val = 6;
@ -426,11 +426,38 @@ on_connect(void *data, int fd, uint32_t mask)
pw_log_warn("setsockopt(SO_PRIORITY) failed: %m"); pw_log_warn("setsockopt(SO_PRIORITY) failed: %m");
#endif #endif
pid = get_client_pid(client, client_fd); pid = get_client_pid(client, client_fd);
if (pid != 0 && pw_check_flatpak(pid, &app_id, NULL) == 1) { if (pid != 0 && pw_check_flatpak(pid, &app_id, &devices) == 1) {
/*
* XXX: we should really use Portal client access here
*
* However, session managers currently support only camera
* permissions, and the XDG Portal doesn't have a "Sound Manager"
* permission defined. So for now, use access=flatpak, and determine
* extra permissions here.
*
* The application has access to the Pulseaudio socket,
* and with real PA it would always then have full sound access.
* We'll restrict the full access here behind devices=all;
* if the application can access all devices it can then
* also sound and camera devices directly, so granting also the
* Manager permissions here is reasonable.
*
* The "Manager" permission in any case is also currently not safe
* as the session manager does not check any permission store
* for it.
*/
client_access = "flatpak"; client_access = "flatpak";
pw_properties_set(client->props, "pipewire.access.portal.app_id", pw_properties_set(client->props, "pipewire.access.portal.app_id",
app_id); app_id);
if (devices && (spa_streq(devices, "all") ||
spa_strstartswith(devices, "all;") ||
strstr(devices, ";all;")))
pw_properties_set(client->props, PW_KEY_MEDIA_CATEGORY, "Manager");
else
pw_properties_set(client->props, PW_KEY_MEDIA_CATEGORY, NULL);
} }
free(devices);
free(app_id); free(app_id);
} }
else if (server->addr.ss_family == AF_INET || server->addr.ss_family == AF_INET6) { else if (server->addr.ss_family == AF_INET || server->addr.ss_family == AF_INET6) {