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 +#include + #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) {