[mutter] xwayland: Generate a Xauth file and pass this to Xwayland when starting it



commit a8984a81c2e887623d69ec9989ae8a5025f7bd47
Author: Hans de Goede <hdegoede redhat com>
Date:   Tue Jun 18 16:12:46 2019 +0200

    xwayland: Generate a Xauth file and pass this to Xwayland when starting it
    
    Before this commit, sudo x11-app, e.g. sudo gvim /etc/some-file, fails
    when running a Wayland session. Where as doing this under a "GNOME on Xorg"
    session works fine. For a user switching from the Xorg session to the
    Wayland session, this is regression, which we want to avoid.
    
    This commit fixes this by creating and passing an xauth file to Xwayland when
    mutter starts it. Just like gdm or startx pass a xauth file to Xorg when they
    start Xorg.
    
    Fixes #643
    
    https://gitlab.gnome.org/GNOME/mutter/issues/643

 meson.build                        |  1 +
 src/meson.build                    |  1 +
 src/wayland/meta-wayland-private.h |  1 +
 src/wayland/meta-wayland.c         | 11 +++++-
 src/wayland/meta-xwayland.c        | 81 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 94 insertions(+), 1 deletion(-)
---
diff --git a/meson.build b/meson.build
index adc9faacc..d88a8653d 100644
--- a/meson.build
+++ b/meson.build
@@ -116,6 +116,7 @@ xrandr_dep = dependency('xrandr', version: xrandr_req)
 xcb_randr_dep = dependency('xcb-randr')
 xcb_res_dep = dependency('xcb-res')
 xinerama_dep = dependency('xinerama')
+xau_dep = dependency('xau')
 ice_dep = dependency('ice')
 atk_dep = dependency('atk', version: atk_req)
 libcanberra_dep = dependency('libcanberra', version: libcanberra_req)
diff --git a/src/meson.build b/src/meson.build
index 53db81e85..805b9a20e 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -101,6 +101,7 @@ if have_x11
     x11_xcb_dep,
     xcb_randr_dep,
     xcb_res_dep,
+    xau_dep,
   ]
 
   if have_sm
diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h
index f2410be4c..594088535 100644
--- a/src/wayland/meta-wayland-private.h
+++ b/src/wayland/meta-wayland-private.h
@@ -52,6 +52,7 @@ typedef struct
   struct wl_client *client;
   struct wl_resource *xserver_resource;
   char *display_name;
+  char *auth_file;
 
   GCancellable *xserver_died_cancellable;
   GSubprocess *proc;
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index f6ce88ee6..dee5cdd59 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -361,6 +361,12 @@ meta_wayland_override_display_name (const char *display_name)
   _display_name_override = g_strdup (display_name);
 }
 
+static const char *
+meta_wayland_get_xwayland_auth_file (MetaWaylandCompositor *compositor)
+{
+  return compositor->xwayland_manager.auth_file;
+}
+
 void
 meta_wayland_init (void)
 {
@@ -438,7 +444,10 @@ meta_wayland_init (void)
     }
 
   if (meta_should_autostart_x11_display ())
-    set_gnome_env ("DISPLAY", meta_wayland_get_xwayland_display_name (compositor));
+    {
+      set_gnome_env ("DISPLAY", meta_wayland_get_xwayland_display_name (compositor));
+      set_gnome_env ("XAUTHORITY", meta_wayland_get_xwayland_auth_file (compositor));
+    }
 
   set_gnome_env ("WAYLAND_DISPLAY", meta_wayland_get_wayland_display_name (compositor));
 }
diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c
index 43bf4c1e3..92a2224b2 100644
--- a/src/wayland/meta-xwayland.c
+++ b/src/wayland/meta-xwayland.c
@@ -31,6 +31,9 @@
 #include <glib.h>
 #include <sys/socket.h>
 #include <sys/un.h>
+#include <sys/random.h>
+#include <unistd.h>
+#include <X11/Xauth.h>
 
 #include "compositor/meta-surface-actor-wayland.h"
 #include "meta/main.h"
@@ -438,6 +441,75 @@ choose_xdisplay (MetaXWaylandManager *manager)
   return TRUE;
 }
 
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (FILE, fclose)
+
+static gboolean
+prepare_auth_file (MetaXWaylandManager *manager)
+{
+  Xauth auth_entry = { 0 };
+  g_autoptr (FILE) fp = NULL;
+  char hostname[HOST_NAME_MAX + 1];
+  char auth_data[16];
+  int fd;
+
+  manager->auth_file = g_build_filename (g_get_user_runtime_dir (),
+                                         ".mutter-Xwaylandauth.XXXXXX",
+                                         NULL);
+
+  if (gethostname (hostname, HOST_NAME_MAX) < 0)
+    g_strlcpy (hostname, "localhost", HOST_NAME_MAX);
+
+  if (getrandom (auth_data, sizeof (auth_data), 0) != sizeof (auth_data))
+    {
+      g_warning ("Failed to get random data: %s", g_strerror (errno));
+      return FALSE;
+    }
+
+  auth_entry.family = FamilyLocal;
+  auth_entry.address = hostname;
+  auth_entry.address_length = strlen (auth_entry.address);
+  auth_entry.name = (char *) "MIT-MAGIC-COOKIE-1";
+  auth_entry.name_length = strlen (auth_entry.name);
+  auth_entry.data = auth_data;
+  auth_entry.data_length = sizeof (auth_data);
+
+  fd = g_mkstemp (manager->auth_file);
+  if (fd < 0)
+    {
+      g_warning ("Failed to open Xauthority file: %s", g_strerror (errno));
+      return FALSE;
+    }
+
+  fp = fdopen (fd, "w+");
+  if (!fp)
+    {
+      g_warning ("Failed to open Xauthority stream: %s", g_strerror (errno));
+      close (fd);
+      return FALSE;
+    }
+
+  if (!XauWriteAuth (fp, &auth_entry))
+    {
+      g_warning ("Error writing to Xauthority file: %s", g_strerror (errno));
+      return FALSE;
+    }
+
+  auth_entry.family = FamilyWild;
+  if (!XauWriteAuth (fp, &auth_entry))
+    {
+      g_warning ("Error writing to Xauthority file: %s", g_strerror (errno));
+      return FALSE;
+    }
+
+  if (fflush (fp) == EOF)
+    {
+      g_warning ("Error writing to Xauthority file: %s", g_strerror (errno));
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
 static void
 xserver_finished_init (MetaXWaylandManager *manager)
 {
@@ -512,6 +584,7 @@ meta_xwayland_init_xserver (MetaXWaylandManager *manager)
                                                "-noreset",
                                                "-accessx",
                                                "-core",
+                                               "-auth", manager->auth_file,
                                                "-listen", "4",
                                                "-listen", "5",
                                                "-displayfd", "6",
@@ -545,6 +618,9 @@ meta_xwayland_start (MetaXWaylandManager *manager,
   if (!choose_xdisplay (manager))
     return FALSE;
 
+  if (!prepare_auth_file (manager))
+    return FALSE;
+
   manager->wayland_display = wl_display;
   return meta_xwayland_init_xserver (manager);
 }
@@ -584,6 +660,11 @@ meta_xwayland_stop (MetaXWaylandManager *manager)
   unlink (path);
 
   g_clear_pointer (&manager->display_name, g_free);
+  if (manager->auth_file)
+    {
+      unlink (manager->auth_file);
+      g_clear_pointer (&manager->auth_file, g_free);
+    }
   if (manager->lock_file)
     {
       unlink (manager->lock_file);


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