Replace spaces with tabs

This commit is contained in:
Sergio Costas Rodriguez 2023-11-22 13:49:11 +01:00 committed by Wim Taymans
parent fda4addf1e
commit 6506bb2f44

View file

@ -18,172 +18,172 @@
#include <fcntl.h> #include <fcntl.h>
#include <assert.h> #include <assert.h>
#define SNAP_LABEL_PREFIX "snap." #define SNAP_LABEL_PREFIX "snap."
static gboolean check_is_same_snap(gchar *snap1, gchar *snap2) static gboolean check_is_same_snap(gchar *snap1, gchar *snap2)
{ {
// Checks if two apparmor labels belong to the same snap // Checks if two apparmor labels belong to the same snap
g_auto(GStrv) strings1 = NULL; g_auto(GStrv) strings1 = NULL;
g_auto(GStrv) strings2 = NULL; g_auto(GStrv) strings2 = NULL;
if (!g_str_has_prefix(snap1, SNAP_LABEL_PREFIX)) { if (!g_str_has_prefix(snap1, SNAP_LABEL_PREFIX)) {
return FALSE; return FALSE;
} }
if (!g_str_has_prefix(snap2, SNAP_LABEL_PREFIX)) { if (!g_str_has_prefix(snap2, SNAP_LABEL_PREFIX)) {
return FALSE; return FALSE;
} }
strings1 = g_strsplit(snap1, ".", 3); strings1 = g_strsplit(snap1, ".", 3);
strings2 = g_strsplit(snap2, ".", 3); strings2 = g_strsplit(snap2, ".", 3);
if (g_str_equal(strings1[1], strings2[1]) && (strings1[1] != NULL)) { if (g_str_equal(strings1[1], strings2[1]) && (strings1[1] != NULL)) {
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
} }
pw_sandbox_access_t pw_snap_get_audio_permissions(struct client *client, int fd, char **app_id) pw_sandbox_access_t pw_snap_get_audio_permissions(struct client *client, int fd, char **app_id)
{ {
g_autofree gchar* aa_label = NULL; g_autofree gchar* aa_label = NULL;
gchar* snap_id = NULL; gchar* snap_id = NULL;
gchar* snap_confinement = NULL; gchar* snap_confinement = NULL;
gchar *separator = NULL; gchar *separator = NULL;
g_autofree gchar *aacon = NULL; g_autofree gchar *aacon = NULL;
gchar *aamode = NULL; gchar *aamode = NULL;
g_autoptr(SnapdClient) snapdclient = NULL; g_autoptr(SnapdClient) snapdclient = NULL;
g_autoptr(GPtrArray) plugs = NULL; g_autoptr(GPtrArray) plugs = NULL;
gboolean retv; gboolean retv;
pw_sandbox_access_t permissions = PW_SANDBOX_ACCESS_NONE; pw_sandbox_access_t permissions = PW_SANDBOX_ACCESS_NONE;
SnapdPlug **plug = NULL; SnapdPlug **plug = NULL;
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
int exit_code; int exit_code;
*app_id = g_strdup("unknown"); *app_id = g_strdup("unknown");
assert(client != NULL); assert(client != NULL);
if (aa_getpeercon(fd, &aa_label, &snap_confinement) == -1) { if (aa_getpeercon(fd, &aa_label, &snap_confinement) == -1) {
if (errno == EINVAL) { if (errno == EINVAL) {
// if apparmor isn't enabled, we can safely assume that there are no SNAPs in the system // if apparmor isn't enabled, we can safely assume that there are no SNAPs in the system
return PW_SANDBOX_ACCESS_NOT_A_SANDBOX; return PW_SANDBOX_ACCESS_NOT_A_SANDBOX;
} }
pw_log_warn("snap_get_audio_permissions: failed to get the AppArmor info."); pw_log_warn("snap_get_audio_permissions: failed to get the AppArmor info.");
return PW_SANDBOX_ACCESS_NONE; return PW_SANDBOX_ACCESS_NONE;
} }
if (!g_str_has_prefix(aa_label, SNAP_LABEL_PREFIX)) { if (!g_str_has_prefix(aa_label, SNAP_LABEL_PREFIX)) {
// not a SNAP. // not a SNAP.
pw_log_info("snap_get_audio_permissions: not an snap."); pw_log_info("snap_get_audio_permissions: not an snap.");
return PW_SANDBOX_ACCESS_NOT_A_SANDBOX; return PW_SANDBOX_ACCESS_NOT_A_SANDBOX;
} }
snap_id = g_strdup(aa_label + strlen(SNAP_LABEL_PREFIX)); snap_id = g_strdup(aa_label + strlen(SNAP_LABEL_PREFIX));
separator = strchr(snap_id, '.'); separator = strchr(snap_id, '.');
if (separator == NULL) { if (separator == NULL) {
pw_log_info("snap_get_audio_permissions: aa_label has only one dot; not a valid ID."); pw_log_info("snap_get_audio_permissions: aa_label has only one dot; not a valid ID.");
return PW_SANDBOX_ACCESS_NONE; return PW_SANDBOX_ACCESS_NONE;
} }
*separator = 0; *separator = 0;
g_free(*app_id); g_free(*app_id);
*app_id = snap_id; *app_id = snap_id;
// it's a "classic" or a "devmode" confinement snap, so we give it full access // it's a "classic" or a "devmode" confinement snap, so we give it full access
if (g_str_equal(snap_confinement, "complain")) { if (g_str_equal(snap_confinement, "complain")) {
return PW_SANDBOX_ACCESS_ALL; return PW_SANDBOX_ACCESS_ALL;
} }
snapdclient = snapd_client_new(); snapdclient = snapd_client_new();
if (snapdclient == NULL) { if (snapdclient == NULL) {
pw_log_warn("snap_get_audio_permissions: error creating SnapdClient object."); pw_log_warn("snap_get_audio_permissions: error creating SnapdClient object.");
return PW_SANDBOX_ACCESS_NONE; return PW_SANDBOX_ACCESS_NONE;
} }
if (aa_getcon(&aacon, &aamode) == -1) { if (aa_getcon(&aacon, &aamode) == -1) {
pw_log_warn("snap_get_audio_permissions: error checking if pipewire-pulse is inside a snap."); pw_log_warn("snap_get_audio_permissions: error checking if pipewire-pulse is inside a snap.");
return PW_SANDBOX_ACCESS_NONE; // failed to get access to apparmor return PW_SANDBOX_ACCESS_NONE; // failed to get access to apparmor
} }
// If pipewire-pulse is inside a snap, use snapctl API // If pipewire-pulse is inside a snap, use snapctl API
if (g_str_has_prefix(aacon, SNAP_LABEL_PREFIX)) { if (g_str_has_prefix(aacon, SNAP_LABEL_PREFIX)) {
// If the snap wanting to get access is the same that contains pipewire, // If the snap wanting to get access is the same that contains pipewire,
// give to it full access. // give to it full access.
if (check_is_same_snap(aacon, aa_label)) if (check_is_same_snap(aacon, aa_label))
return PW_SANDBOX_ACCESS_ALL; return PW_SANDBOX_ACCESS_ALL;
snapd_client_set_socket_path(snapdclient, "/run/snapd-snap.socket"); snapd_client_set_socket_path(snapdclient, "/run/snapd-snap.socket");
/* Take context from the environment if available */ /* Take context from the environment if available */
const char *context = g_getenv("SNAP_COOKIE"); const char *context = g_getenv("SNAP_COOKIE");
if (!context) if (!context)
context = ""; context = "";
char *snapctl_command[] = { "is-connected", "--apparmor-label", aa_label, "pulseaudio", NULL }; char *snapctl_command[] = { "is-connected", "--apparmor-label", aa_label, "pulseaudio", NULL };
if (!snapd_client_run_snapctl2_sync(snapdclient, context, (char **) snapctl_command, NULL, NULL, &exit_code, NULL, &error)) { if (!snapd_client_run_snapctl2_sync(snapdclient, context, (char **) snapctl_command, NULL, NULL, &exit_code, NULL, &error)) {
pw_log_warn("snap_get_audio_permissions: error summoning snapctl2 for pulseaudio interface: %s", error->message); pw_log_warn("snap_get_audio_permissions: error summoning snapctl2 for pulseaudio interface: %s", error->message);
return PW_SANDBOX_ACCESS_NONE; return PW_SANDBOX_ACCESS_NONE;
} }
if (exit_code != 1) { if (exit_code != 1) {
// 0 = Connected // 0 = Connected
// 10 = Classic environment // 10 = Classic environment
// 11 = Not a snap // 11 = Not a snap
return PW_SANDBOX_ACCESS_ALL; return PW_SANDBOX_ACCESS_ALL;
} }
char *snapctl_command2[] = { "is-connected", "--apparmor-label", aa_label, "audio-record", NULL }; char *snapctl_command2[] = { "is-connected", "--apparmor-label", aa_label, "audio-record", NULL };
if (!snapd_client_run_snapctl2_sync(snapdclient, context, (char **) snapctl_command2, NULL, NULL, &exit_code, NULL, &error)) { if (!snapd_client_run_snapctl2_sync(snapdclient, context, (char **) snapctl_command2, NULL, NULL, &exit_code, NULL, &error)) {
pw_log_warn("snap_get_audio_permissions: error summoning snapctl2 for audio-record interface: %s", error->message); pw_log_warn("snap_get_audio_permissions: error summoning snapctl2 for audio-record interface: %s", error->message);
return PW_SANDBOX_ACCESS_NONE; return PW_SANDBOX_ACCESS_NONE;
} }
if (exit_code == 1) { if (exit_code == 1) {
return PW_SANDBOX_ACCESS_PLAYBACK; return PW_SANDBOX_ACCESS_PLAYBACK;
} }
return PW_SANDBOX_ACCESS_ALL; return PW_SANDBOX_ACCESS_ALL;
} }
retv = snapd_client_get_connections2_sync(snapdclient, retv = snapd_client_get_connections2_sync(snapdclient,
SNAPD_GET_CONNECTIONS_FLAGS_NONE, SNAPD_GET_CONNECTIONS_FLAGS_NONE,
snap_id, snap_id,
NULL, NULL,
NULL, NULL,
NULL, NULL,
&plugs, &plugs,
NULL, NULL,
NULL, NULL,
&error); &error);
if (retv == FALSE) { if (retv == FALSE) {
pw_log_warn("Failed to get Snap connections for snap %s: %s\n", snap_id, error->message); pw_log_warn("Failed to get Snap connections for snap %s: %s\n", snap_id, error->message);
return PW_SANDBOX_ACCESS_NONE; return PW_SANDBOX_ACCESS_NONE;
} }
if (plugs == NULL) { if (plugs == NULL) {
pw_log_warn("Failed to get Snap connections for snap %s: %s\n", snap_id, error->message); pw_log_warn("Failed to get Snap connections for snap %s: %s\n", snap_id, error->message);
return PW_SANDBOX_ACCESS_NONE; return PW_SANDBOX_ACCESS_NONE;
} }
if (plugs->pdata == NULL) { if (plugs->pdata == NULL) {
pw_log_warn("Failed to get Snap connections for snap %s: %s\n", snap_id, error->message); pw_log_warn("Failed to get Snap connections for snap %s: %s\n", snap_id, error->message);
return PW_SANDBOX_ACCESS_NONE; return PW_SANDBOX_ACCESS_NONE;
} }
plug = (SnapdPlug **)plugs->pdata; plug = (SnapdPlug **)plugs->pdata;
for (guint p = 0; p < plugs->len; p++, plug++) { for (guint p = 0; p < plugs->len; p++, plug++) {
pw_sandbox_access_t add_permission; pw_sandbox_access_t add_permission;
const gchar *plug_name = snapd_plug_get_name(*plug); const gchar *plug_name = snapd_plug_get_name(*plug);
if (g_str_equal("audio-record", plug_name)) { if (g_str_equal("audio-record", plug_name)) {
add_permission = PW_SANDBOX_ACCESS_RECORD; add_permission = PW_SANDBOX_ACCESS_RECORD;
} else if (g_str_equal("audio-playback", plug_name)) { } else if (g_str_equal("audio-playback", plug_name)) {
add_permission = PW_SANDBOX_ACCESS_PLAYBACK; add_permission = PW_SANDBOX_ACCESS_PLAYBACK;
} else if (g_str_equal("pulseaudio", plug_name)) { } else if (g_str_equal("pulseaudio", plug_name)) {
add_permission = PW_SANDBOX_ACCESS_ALL; add_permission = PW_SANDBOX_ACCESS_ALL;
} else { } else {
continue; continue;
} }
GPtrArray *slots = snapd_plug_get_connected_slots(*plug); GPtrArray *slots = snapd_plug_get_connected_slots(*plug);
if (slots == NULL) if (slots == NULL)
continue; continue;
SnapdSlotRef **slot = (SnapdSlotRef**) slots->pdata; SnapdSlotRef **slot = (SnapdSlotRef**) slots->pdata;
for (guint q = 0; q < slots->len; q++, slot++) { for (guint q = 0; q < slots->len; q++, slot++) {
const gchar *slot_name = snapd_slot_ref_get_slot(*slot); const gchar *slot_name = snapd_slot_ref_get_slot(*slot);
const gchar *snap_name = snapd_slot_ref_get_snap(*slot); const gchar *snap_name = snapd_slot_ref_get_snap(*slot);
if (g_str_equal(snap_name, "snapd") && if (g_str_equal(snap_name, "snapd") &&
g_str_equal(slot_name, plug_name)) g_str_equal(slot_name, plug_name))
permissions |= add_permission; permissions |= add_permission;
} }
} }
return permissions; return permissions;
} }