162 lines
4.5 KiB
Diff
162 lines
4.5 KiB
Diff
|
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
|
||
|
index 5e9eb5e..80cce87 100644
|
||
|
--- a/daemon/Makefile.am
|
||
|
+++ b/daemon/Makefile.am
|
||
|
@@ -147,11 +147,13 @@ nodist_gdm_session_worker_SOURCES = \
|
||
|
gdm-session-enum-types.h \
|
||
|
$(NULL)
|
||
|
|
||
|
+## We need XLIB_LIBS for Xauth.
|
||
|
gdm_wayland_session_LDADD = \
|
||
|
$(top_builddir)/common/libgdmcommon.la \
|
||
|
$(GTK_LIBS) \
|
||
|
$(COMMON_LIBS) \
|
||
|
$(SYSTEMD_LIBS) \
|
||
|
+ $(XLIB_LIBS) \
|
||
|
$(NULL)
|
||
|
|
||
|
gdm_wayland_session_SOURCES = \
|
||
|
diff --git a/daemon/gdm-wayland-session.c b/daemon/gdm-wayland-session.c
|
||
|
index b648e9d..bfadf9b 100644
|
||
|
--- a/daemon/gdm-wayland-session.c
|
||
|
+++ b/daemon/gdm-wayland-session.c
|
||
|
@@ -36,6 +36,8 @@
|
||
|
|
||
|
#include <gio/gunixinputstream.h>
|
||
|
|
||
|
+#include <X11/Xauth.h>
|
||
|
+
|
||
|
#define BUS_ADDRESS_FILENO (STDERR_FILENO + 1)
|
||
|
|
||
|
typedef struct
|
||
|
@@ -47,6 +49,8 @@ typedef struct
|
||
|
GDBusConnection *bus_connection;
|
||
|
char *bus_address;
|
||
|
|
||
|
+ char *x_auth_file;
|
||
|
+
|
||
|
char **environment;
|
||
|
|
||
|
GSubprocess *session_subprocess;
|
||
|
@@ -58,6 +62,102 @@ typedef struct
|
||
|
guint32 debug_enabled : 1;
|
||
|
} State;
|
||
|
|
||
|
+static FILE *
|
||
|
+create_auth_file (char **filename)
|
||
|
+{
|
||
|
+ char *auth_dir = NULL;
|
||
|
+ char *auth_file = NULL;
|
||
|
+ int fd;
|
||
|
+ FILE *fp = NULL;
|
||
|
+
|
||
|
+ auth_dir = g_build_filename (g_get_user_runtime_dir (),
|
||
|
+ "gdm",
|
||
|
+ NULL);
|
||
|
+
|
||
|
+ g_mkdir_with_parents (auth_dir, 0711);
|
||
|
+ auth_file = g_build_filename (auth_dir, "Xauthority", NULL);
|
||
|
+ g_clear_pointer (&auth_dir, g_free);
|
||
|
+
|
||
|
+ fd = g_open (auth_file, O_RDWR | O_CREAT | O_TRUNC, 0700);
|
||
|
+
|
||
|
+ if (fd < 0) {
|
||
|
+ g_debug ("could not open %s to store auth cookie: %m",
|
||
|
+ auth_file);
|
||
|
+ g_clear_pointer (&auth_file, g_free);
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ fp = fdopen (fd, "w+");
|
||
|
+
|
||
|
+ if (fp == NULL) {
|
||
|
+ g_debug ("could not set up stream for auth cookie file: %m");
|
||
|
+ g_clear_pointer (&auth_file, g_free);
|
||
|
+ close (fd);
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ *filename = auth_file;
|
||
|
+out:
|
||
|
+ return fp;
|
||
|
+}
|
||
|
+
|
||
|
+static char *
|
||
|
+prepare_auth_file (void)
|
||
|
+{
|
||
|
+ FILE *fp = NULL;
|
||
|
+ char *filename = NULL;
|
||
|
+ GError *error = NULL;
|
||
|
+ gboolean prepared = FALSE;
|
||
|
+ Xauth auth_entry = { 0 };
|
||
|
+ char localhost[HOST_NAME_MAX + 1] = "";
|
||
|
+
|
||
|
+ g_debug ("Preparing auth file for X server");
|
||
|
+
|
||
|
+ fp = create_auth_file (&filename);
|
||
|
+
|
||
|
+ if (fp == NULL) {
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (gethostname (localhost, HOST_NAME_MAX) < 0) {
|
||
|
+ strncpy (localhost, "localhost", sizeof (localhost) - 1);
|
||
|
+ }
|
||
|
+
|
||
|
+ auth_entry.family = FamilyLocal;
|
||
|
+ auth_entry.address = localhost;
|
||
|
+ auth_entry.address_length = strlen (auth_entry.address);
|
||
|
+ auth_entry.name = "MIT-MAGIC-COOKIE-1";
|
||
|
+ auth_entry.name_length = strlen (auth_entry.name);
|
||
|
+
|
||
|
+ auth_entry.data_length = 16;
|
||
|
+ auth_entry.data = gdm_generate_random_bytes (auth_entry.data_length, &error);
|
||
|
+
|
||
|
+ if (error != NULL) {
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (!XauWriteAuth (fp, &auth_entry) || fflush (fp) == EOF) {
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ auth_entry.family = FamilyWild;
|
||
|
+ if (!XauWriteAuth (fp, &auth_entry) || fflush (fp) == EOF) {
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ prepared = TRUE;
|
||
|
+
|
||
|
+out:
|
||
|
+ g_clear_pointer (&auth_entry.data, g_free);
|
||
|
+ g_clear_pointer (&fp, fclose);
|
||
|
+
|
||
|
+ if (!prepared) {
|
||
|
+ g_clear_pointer (&filename, g_free);
|
||
|
+ }
|
||
|
+
|
||
|
+ return filename;
|
||
|
+}
|
||
|
+
|
||
|
static void
|
||
|
on_bus_finished (GSubprocess *subprocess,
|
||
|
GAsyncResult *result,
|
||
|
@@ -333,6 +433,8 @@ spawn_session (State *state,
|
||
|
g_subprocess_launcher_setenv (launcher, "DBUS_SESSION_BUS_ADDRESS", state->bus_address, TRUE);
|
||
|
}
|
||
|
|
||
|
+ g_subprocess_launcher_setenv (launcher, "XAUTHORITY", state->x_auth_file, TRUE);
|
||
|
+
|
||
|
subprocess = g_subprocess_launcher_spawnv (launcher,
|
||
|
(const char * const *) argv,
|
||
|
&error);
|
||
|
@@ -510,6 +612,8 @@ main (int argc,
|
||
|
|
||
|
g_unix_signal_add (SIGTERM, (GSourceFunc) on_sigterm, state);
|
||
|
|
||
|
+ state->x_auth_file = prepare_auth_file ();
|
||
|
+
|
||
|
ret = spawn_bus (state, state->cancellable);
|
||
|
|
||
|
if (!ret) {
|