[mutter] window: Support snap packages for sandboxed app IDs



commit 6dc499f3054d2e7c3db4966079ba1114a9c169d7
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Tue Sep 26 17:22:43 2017 -0400

    window: Support snap packages for sandboxed app IDs
    
    For now we abuse of meta_window_get_flatpak_id not to break the APIs,
    so that it's working seamlessly in gnone shell too.
    
    Rename flatpak_id to sandboxed_app_id internally to get prepared to the future
    API.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=788217

 src/core/window-private.h |    2 +-
 src/core/window.c         |   95 +++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 85 insertions(+), 12 deletions(-)
---
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 521682d..013bad7 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -164,7 +164,7 @@ struct _MetaWindow
 
   char *startup_id;
   char *mutter_hints;
-  char *flatpak_id;
+  char *sandboxed_app_id;
   char *gtk_theme_variant;
   char *gtk_application_id;
   char *gtk_unique_bus_name;
diff --git a/src/core/window.c b/src/core/window.c
index af1140c..b9c07ec 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -71,6 +71,8 @@
  */
 #define MAX_UNMAXIMIZED_WINDOW_AREA .8
 
+#define SNAP_SECURITY_LABEL_PREFIX "snap."
+
 static int destroying_windows_disallowed = 0;
 
 /* Each window has a "stamp" which is a non-recycled 64-bit ID. They
@@ -294,7 +296,7 @@ meta_window_finalize (GObject *object)
   g_free (window->res_name);
   g_free (window->title);
   g_free (window->desc);
-  g_free (window->flatpak_id);
+  g_free (window->sandboxed_app_id);
   g_free (window->gtk_theme_variant);
   g_free (window->gtk_application_id);
   g_free (window->gtk_unique_bus_name);
@@ -766,25 +768,94 @@ sync_client_window_mapped (MetaWindow *window)
   meta_error_trap_pop (window->display);
 }
 
-static void
-meta_window_update_flatpak_id (MetaWindow *window)
+static gboolean
+meta_window_update_flatpak_id (MetaWindow *window,
+                               uint32_t    pid)
 {
-  uint32_t pid = meta_window_get_client_pid (window);
   g_autoptr(GKeyFile) key_file = NULL;
   g_autofree char *info_filename = NULL;
 
-  g_clear_pointer (&window->flatpak_id, g_free);
-
-  if (pid == 0)
-    return;
+  g_return_val_if_fail (pid != 0, FALSE);
+  g_return_val_if_fail (window->sandboxed_app_id == NULL, FALSE);
 
   key_file = g_key_file_new ();
   info_filename = g_strdup_printf ("/proc/%u/root/.flatpak-info", pid);
 
   if (!g_key_file_load_from_file (key_file, info_filename, G_KEY_FILE_NONE, NULL))
+    return FALSE;
+
+  window->sandboxed_app_id = g_key_file_get_string (key_file, "Application", "name", NULL);
+
+  return TRUE;
+}
+
+static gboolean
+meta_window_update_snap_id (MetaWindow *window,
+                            uint32_t    pid)
+{
+  g_autofree char *security_label_filename = NULL;
+  g_autofree char *security_label_contents = NULL;
+  gsize i, security_label_contents_size = 0;
+  char *contents_start;
+  char *contents_end;
+  char *sandboxed_app_id;
+
+  g_return_val_if_fail (pid != 0, FALSE);
+  g_return_val_if_fail (window->sandboxed_app_id == NULL, FALSE);
+
+  security_label_filename = g_strdup_printf ("/proc/%u/attr/current", pid);
+
+  if (!g_file_get_contents (security_label_filename,
+                            &security_label_contents,
+                            &security_label_contents_size,
+                            NULL))
+    return FALSE;
+
+  if (!g_str_has_prefix (security_label_contents, SNAP_SECURITY_LABEL_PREFIX))
+    return FALSE;
+
+  /* We need to translate the security profile into the desktop-id.
+   * The profile is in the form of 'snap.name-space.binary-name (current)'
+   * while the desktop id will be name-space_binary-name.
+   */
+  security_label_contents_size -= sizeof (SNAP_SECURITY_LABEL_PREFIX) - 1;
+  contents_start = security_label_contents + sizeof (SNAP_SECURITY_LABEL_PREFIX) - 1;
+  contents_end = strchr (contents_start, ' ');
+
+  if (contents_end)
+    security_label_contents_size = contents_end - contents_start;
+
+  for (i = 0; i < security_label_contents_size; ++i)
+    {
+      if (contents_start[i] == '.')
+        contents_start[i] = '_';
+    }
+
+  sandboxed_app_id = g_malloc0 (security_label_contents_size + 1);
+  memcpy (sandboxed_app_id, contents_start, security_label_contents_size);
+
+  window->sandboxed_app_id = sandboxed_app_id;
+
+  return TRUE;
+}
+
+static void
+meta_window_update_sandboxed_app_id (MetaWindow *window)
+{
+  uint32_t pid;
+
+  g_clear_pointer (&window->sandboxed_app_id, g_free);
+
+  pid = meta_window_get_client_pid (window);
+
+  if (pid == 0)
     return;
 
-  window->flatpak_id = g_key_file_get_string (key_file, "Application", "name", NULL);
+  if (meta_window_update_flatpak_id (window, pid))
+    return;
+
+  if (meta_window_update_snap_id (window, pid))
+    return;
 }
 
 static void
@@ -897,7 +968,7 @@ _meta_window_shared_new (MetaDisplay         *display,
 
   window->screen = screen;
 
-  meta_window_update_flatpak_id (window);
+  meta_window_update_sandboxed_app_id (window);
   meta_window_update_desc (window);
 
   window->override_redirect = attrs->override_redirect;
@@ -7005,7 +7076,9 @@ meta_window_get_wm_class_instance (MetaWindow *window)
 const char *
 meta_window_get_flatpak_id (MetaWindow *window)
 {
-  return window->flatpak_id;
+  /* We're abusing this API here not to break the gnome shell assumptions
+   * or adding a new function, to be renamed to generic names in new versions */
+  return window->sandboxed_app_id;
 }
 
 /**


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]