--- common/gdm-common.c (revision 5497) +++ common/gdm-common.c (working copy) @@ -32,7 +32,6 @@ #include #include "gdm-common.h" -#include "gdm-md5.h" void gdm_set_fatal_warnings_if_unstable (void) @@ -273,203 +272,3 @@ gdm_string_hex_decode (const GString *so return retval; } - -static void -_gdm_generate_pseudorandom_bytes_buffer (char *buffer, - int n_bytes) -{ - int i; - - /* fall back to pseudorandom */ - g_debug ("Falling back to pseudorandom for %d bytes\n", - n_bytes); - - i = 0; - while (i < n_bytes) { - int b; - - b = g_random_int_range (0, 255); - - buffer[i] = b; - - ++i; - } -} - -static gboolean -_gdm_generate_pseudorandom_bytes (GString *str, - int n_bytes) -{ - int old_len; - char *p; - - old_len = str->len; - - str = g_string_set_size (str, old_len + n_bytes); - - p = str->str + old_len; - - _gdm_generate_pseudorandom_bytes_buffer (p, n_bytes); - - return TRUE; -} - - -static int -_gdm_fdread (int fd, - GString *buffer, - int count) -{ - int bytes_read; - int start; - char *data; - - g_assert (count >= 0); - - start = buffer->len; - - buffer = g_string_set_size (buffer, start + count); - - data = buffer->str + start; - - again: - bytes_read = read (fd, data, count); - - if (bytes_read < 0) { - if (errno == EINTR) { - goto again; - } else { - /* put length back (note that this doesn't actually realloc anything) */ - buffer = g_string_set_size (buffer, start); - return -1; - } - } else { - /* put length back (doesn't actually realloc) */ - buffer = g_string_set_size (buffer, start + bytes_read); - - return bytes_read; - } -} - -/** - * Closes a file descriptor. - * - * @param fd the file descriptor - * @param error error object - * @returns #FALSE if error set - */ -static gboolean -_gdm_fdclose (int fd) -{ - again: - if (close (fd) < 0) { - if (errno == EINTR) - goto again; - - g_warning ("Could not close fd %d: %s", - fd, - g_strerror (errno)); - return FALSE; - } - - return TRUE; -} - -/** - * Generates the given number of random bytes, - * using the best mechanism we can come up with. - * - * @param str the string - * @param n_bytes the number of random bytes to append to string - */ -gboolean -gdm_generate_random_bytes (GString *str, - int n_bytes) -{ - int old_len; - int fd; - - /* FALSE return means "no memory", if it could - * mean something else then we'd need to return - * a DBusError. So we always fall back to pseudorandom - * if the I/O fails. - */ - - old_len = str->len; - fd = -1; - - /* note, urandom on linux will fall back to pseudorandom */ - fd = g_open ("/dev/urandom", O_RDONLY, 0); - if (fd < 0) { - return _gdm_generate_pseudorandom_bytes (str, n_bytes); - } - - if (_gdm_fdread (fd, str, n_bytes) != n_bytes) { - _gdm_fdclose (fd); - str = g_string_set_size (str, old_len); - return _gdm_generate_pseudorandom_bytes (str, n_bytes); - } - - g_debug ("Read %d bytes from /dev/urandom\n", n_bytes); - - _gdm_fdclose (fd); - - return TRUE; -} - -/** - * Computes the ASCII hex-encoded md5sum of the given data and - * appends it to the output string. - * - * @param data input data to be hashed - * @param ascii_output string to append ASCII md5sum to - * @returns #FALSE if not enough memory - */ -static gboolean -gdm_md5_compute (const GString *data, - GString *ascii_output) -{ - GdmMD5Context context; - GString *digest; - - gdm_md5_init (&context); - - gdm_md5_update (&context, data); - - digest = g_string_new (NULL); - if (digest == NULL) - return FALSE; - - if (! gdm_md5_final (&context, digest)) - goto error; - - if (! gdm_string_hex_encode (digest, - 0, - ascii_output, - ascii_output->len)) - goto error; - - g_string_free (digest, TRUE); - - return TRUE; - - error: - g_string_free (digest, TRUE); - - return FALSE; -} - -gboolean -gdm_generate_cookie (GString *result) -{ - gboolean ret; - GString *data; - - data = g_string_new (NULL); - gdm_generate_random_bytes (data, 16); - - ret = gdm_md5_compute (data, result); - g_string_free (data, TRUE); - - return ret; -} Index: common/gdm-common.h =================================================================== --- common/gdm-common.h (revision 5497) +++ common/gdm-common.h (working copy) @@ -32,9 +32,6 @@ void gdm_set_fatal_warnings_if int gdm_signal_pid (int pid, int signal); -gboolean gdm_generate_random_bytes (GString *str, - int n_bytes); - gboolean gdm_string_hex_encode (const GString *source, int start, GString *dest, @@ -44,7 +41,6 @@ gboolean gdm_string_hex_decode int *end_return, GString *dest, int insert_at); -gboolean gdm_generate_cookie (GString *result); G_END_DECLS Index: daemon/gdm-local-display-factory.c =================================================================== --- daemon/gdm-local-display-factory.c (revision 5497) +++ daemon/gdm-local-display-factory.c (working copy) @@ -89,6 +89,12 @@ create_display_for_device (GdmLocalDispl return; } + if (! gdm_display_create_authority (display)) { + g_warning ("Unable to set up access control for display %d", + 0); + return; + } + gdm_display_store_add (store, display); /* let store own the ref */ g_object_unref (display); Index: daemon/gdm-server.c =================================================================== --- daemon/gdm-server.c (revision 5497) +++ daemon/gdm-server.c (working copy) @@ -743,6 +743,14 @@ _gdm_server_set_display_name (GdmServer } static void +_gdm_server_set_auth_file (GdmServer *server, + const char *auth_file) +{ + g_free (server->priv->auth_file); + server->priv->auth_file = g_strdup (auth_file); +} + +static void _gdm_server_set_user_name (GdmServer *server, const char *name) { @@ -764,6 +772,9 @@ gdm_server_set_property (GObject *o case PROP_DISPLAY_NAME: _gdm_server_set_display_name (self, g_value_get_string (value)); break; + case PROP_AUTH_FILE: + _gdm_server_set_auth_file (self, g_value_get_string (value)); + break; case PROP_USER_NAME: _gdm_server_set_user_name (self, g_value_get_string (value)); break; @@ -791,6 +802,9 @@ gdm_server_get_property (GObject *obj g_value_take_string (value, gdm_server_get_display_device (self)); break; + case PROP_AUTH_FILE: + g_value_set_string (value, self->priv->auth_file); + break; case PROP_USER_NAME: g_value_set_string (value, self->priv->user_name); break; @@ -853,6 +867,13 @@ gdm_server_class_init (GdmServerClass *k "Path to terminal display is running on", NULL, G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_AUTH_FILE, + g_param_spec_string ("auth-file", + "Authorization File", + "Path to X authorization file", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, PROP_USER_NAME, @@ -897,12 +918,14 @@ gdm_server_finalize (GObject *object) } GdmServer * -gdm_server_new (const char *display_name) +gdm_server_new (const char *display_name, + const char *auth_file) { GObject *object; object = g_object_new (GDM_TYPE_SERVER, "display-name", display_name, + "auth-file", auth_file, NULL); return GDM_SERVER (object); Index: daemon/gdm-server.h =================================================================== --- daemon/gdm-server.h (revision 5497) +++ daemon/gdm-server.h (working copy) @@ -49,7 +49,8 @@ typedef struct } GdmServerClass; GType gdm_server_get_type (void); -GdmServer * gdm_server_new (const char *display_id); +GdmServer * gdm_server_new (const char *display_id, + const char *auth_file); gboolean gdm_server_start (GdmServer *server); gboolean gdm_server_stop (GdmServer *server); char * gdm_server_get_display_device (GdmServer *server); Index: daemon/gdm-xdmcp-display.c =================================================================== --- daemon/gdm-xdmcp-display.c (revision 5497) +++ daemon/gdm-xdmcp-display.c (working copy) @@ -42,8 +42,6 @@ #include "gdm-common.h" #include "gdm-address.h" -#include "auth.h" - #define GDM_XDMCP_DISPLAY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_XDMCP_DISPLAY, GdmXdmcpDisplayPrivate)) struct GdmXdmcpDisplayPrivate @@ -83,75 +81,9 @@ gdm_xdmcp_display_get_remote_address (Gd static gboolean gdm_xdmcp_display_create_authority (GdmDisplay *display) { - FILE *af; - int closeret; - gboolean ret; - char *authfile; - int display_num; - char *x11_display; - GString *cookie; - GSList *authlist; - char *basename; - - ret = FALSE; - x11_display = NULL; - - g_object_get (display, - "x11-display-name", &x11_display, - "x11-display-number", &display_num, - NULL); - - /* Create new random cookie */ - cookie = g_string_new (NULL); - gdm_generate_cookie (cookie); - - g_debug ("GdmXdmcpDisplay: Setting up access for %s", x11_display); - - /* gdm and xserver authfile can be the same, server will run as root */ - basename = g_strconcat (x11_display, ".Xauth", NULL); - authfile = g_build_filename (AUTHDIR, basename, NULL); - g_free (basename); - - af = gdm_safe_fopen_w (authfile, 0644); - if (af == NULL) { - g_warning (_("Cannot safely open %s"), authfile); - g_free (authfile); - goto out; - } - - g_debug ("GdmXdmcpDisplay: Adding auth entry for xdmcp display:%d cookie:%s", display_num, cookie->str); - authlist = NULL; - if (! gdm_auth_add_entry_for_display (display_num, NULL, cookie, af, &authlist)) { - goto out; - } - - g_debug ("GdmXdmcpDisplay: Setting up access"); - - VE_IGNORE_EINTR (closeret = fclose (af)); - if (closeret < 0) { - g_warning (_("Could not write new authorization entry: %s"), - g_strerror (errno)); - goto out; - } - - g_debug ("GdmXdmcpDisplay: Set up access for %s - %d entries", - x11_display, - g_slist_length (authlist)); - - /* FIXME: save authlist */ - - g_object_set (display, - "x11-authority-file", authfile, - "x11-cookie", cookie->str, - NULL); - - ret = TRUE; - - out: - g_free (x11_display); - g_string_free (cookie, TRUE); + g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE); - return ret; + return GDM_DISPLAY_CLASS (gdm_xdmcp_display_parent_class)->create_authority (display); } static gboolean @@ -160,26 +92,7 @@ gdm_xdmcp_display_add_user_authorization char **filename, GError **error) { - gboolean res; - char *cookie; - char *hostname; - int display_num; - - res = gdm_display_get_x11_cookie (display, &cookie, NULL); - res = gdm_display_get_x11_display_number (display, &display_num, NULL); - - hostname = NULL; - res = gdm_address_get_hostname (GDM_XDMCP_DISPLAY (display)->priv->remote_address, &hostname); - g_debug ("GdmXdmcpDisplay: add user auth for xdmcp display: %s host:%s", username, hostname); - gdm_address_debug (GDM_XDMCP_DISPLAY (display)->priv->remote_address); - g_free (hostname); - - res = gdm_auth_user_add (display_num, - GDM_XDMCP_DISPLAY (display)->priv->remote_address, - username, - cookie, - filename); - return res; + return GDM_DISPLAY_CLASS (gdm_xdmcp_display_parent_class)->add_user_authorization (display, username, filename, error); } static gboolean @@ -187,7 +100,7 @@ gdm_xdmcp_display_remove_user_authorizat const char *username, GError **error) { - return TRUE; + return GDM_DISPLAY_CLASS (gdm_xdmcp_display_parent_class)->remove_user_authorization (display, username, error); } static gboolean @@ -206,7 +119,6 @@ gdm_xdmcp_display_unmanage (GdmDisplay * g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE); GDM_DISPLAY_CLASS (gdm_xdmcp_display_parent_class)->unmanage (display); - return TRUE; } Index: daemon/gdm-product-slave.c =================================================================== --- daemon/gdm-product-slave.c (revision 5497) +++ daemon/gdm-product-slave.c (working copy) @@ -335,11 +335,13 @@ static gboolean gdm_product_slave_create_server (GdmProductSlave *slave) { char *display_name; + char *auth_file; gboolean display_is_local; g_object_get (slave, "display-is-local", &display_is_local, "display-name", &display_name, + "display-x11-authority-file", &auth_file, NULL); /* if this is local display start a server if one doesn't @@ -347,7 +349,7 @@ gdm_product_slave_create_server (GdmProd if (display_is_local) { gboolean res; - slave->priv->server = gdm_server_new (display_name); + slave->priv->server = gdm_server_new (display_name, auth_file); g_signal_connect (slave->priv->server, "ready", @@ -373,6 +375,7 @@ gdm_product_slave_create_server (GdmProd } g_free (display_name); + g_free (auth_file); return TRUE; } Index: daemon/auth.c =================================================================== --- daemon/auth.c (revision 5497) +++ daemon/auth.c (working copy) @@ -1,240 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 1998, 1999, 2000 Martin K. Petersen - * Copyright (C) 2007 William Jon McCann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* Code for cookie handling. This really needs to be modularized to - * support other XAuth types and possibly DECnet... */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "auth.h" - -#include "gdm-common.h" -#include "gdm-address.h" -#include "gdm-log.h" - -gboolean -gdm_auth_add_entry (int display_num, - GdmAddress *address, - GString *binary_cookie, - FILE *af, - GSList **authlist) -{ - Xauth *xa; - char *dispnum; - - xa = malloc (sizeof (Xauth)); - - if (xa == NULL) { - return FALSE; - } - - if (address == NULL) { - xa->family = FamilyWild; - xa->address = NULL; - xa->address_length = 0; - } else { - gboolean res; - char *hostname; - - xa->family = gdm_address_get_family_type (address); - - res = gdm_address_get_hostname (address, &hostname); - if (! res) { - free (xa); - return FALSE; - } - - g_debug ("Got hostname: %s", hostname); - - xa->address = hostname; - xa->address_length = strlen (xa->address); - } - - dispnum = g_strdup_printf ("%d", display_num); - xa->number = strdup (dispnum); - xa->number_length = strlen (dispnum); - g_free (dispnum); - - xa->name = strdup ("MIT-MAGIC-COOKIE-1"); - xa->name_length = strlen ("MIT-MAGIC-COOKIE-1"); - xa->data = malloc (16); - if (xa->data == NULL) { - free (xa->number); - free (xa->name); - free (xa->address); - free (xa); - return FALSE; - } - - memcpy (xa->data, binary_cookie->str, binary_cookie->len); - xa->data_length = binary_cookie->len; - - g_debug ("Writing auth for address:%p %s:%d", address, xa->address, display_num); - - if (af != NULL) { - errno = 0; - if ( ! XauWriteAuth (af, xa)) { - free (xa->data); - free (xa->number); - free (xa->name); - free (xa->address); - free (xa); - - if (errno != 0) { - g_warning (_("%s: Could not write new authorization entry: %s"), - "add_auth_entry", g_strerror (errno)); - } else { - g_warning (_("%s: Could not write new authorization entry. " - "Possibly out of diskspace"), - "add_auth_entry"); - } - - return FALSE; - } - } - - if (authlist != NULL) { - *authlist = g_slist_append (*authlist, xa); - } - - return TRUE; -} - -gboolean -gdm_auth_add_entry_for_display (int display_num, - GdmAddress *address, - GString *cookie, - FILE *af, - GSList **authlist) -{ - GString *binary_cookie; - gboolean ret; - - binary_cookie = g_string_new (NULL); - - if (! gdm_string_hex_decode (cookie, - 0, - NULL, - binary_cookie, - 0)) { - ret = FALSE; - goto out; - } - - ret = gdm_auth_add_entry (display_num, - address, - binary_cookie, - af, - authlist); - - out: - g_string_free (binary_cookie, TRUE); - return ret; -} - -gboolean -gdm_auth_user_add (int display_num, - GdmAddress *address, - const char *username, - const char *cookie, - char **filenamep) -{ - int fd; - char *filename; - GError *error; - mode_t old_mask; - FILE *af; - gboolean ret; - struct passwd *pwent; - GString *cookie_str; - - g_debug ("Add user auth for address:%p num:%d user:%s", address, display_num, username); - - ret = FALSE; - filename = NULL; - af = NULL; - fd = -1; - - old_mask = umask (077); - - filename = NULL; - error = NULL; - fd = g_file_open_tmp (".gdmXXXXXX", &filename, &error); - - umask (old_mask); - - if (fd == -1) { - g_warning ("Unable to create temporary file: %s", error->message); - g_error_free (error); - goto out; - } - - if (filenamep != NULL) { - *filenamep = g_strdup (filename); - } - - VE_IGNORE_EINTR (af = fdopen (fd, "w")); - if (af == NULL) { - g_warning ("Unable to open cookie file: %s", filename); - goto out; - } - - /* FIXME: clean old files? */ - - cookie_str = g_string_new (cookie); - - /* FIXME: ?? */ - /*gdm_auth_add_entry_for_display (display_num, address, cookie_str, af, NULL);*/ - gdm_auth_add_entry_for_display (display_num, NULL, cookie_str, af, NULL); - g_string_free (cookie_str, TRUE); - - pwent = getpwnam (username); - if (pwent == NULL) { - goto out; - } - - fchown (fd, pwent->pw_uid, -1); - - ret = TRUE; - out: - g_free (filename); - - if (af != NULL) { - fclose (af); - } - - return ret; -} Index: daemon/auth.h =================================================================== --- daemon/auth.h (revision 5497) +++ daemon/auth.h (working copy) @@ -1,49 +0,0 @@ -/* GDM - The GNOME Display Manager - * Copyright (C) 1998, 1999, 2000 Martin K. Petersen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef GDM_AUTH_H -#define GDM_AUTH_H - -#include -#include "gdm-address.h" - -G_BEGIN_DECLS - -gboolean gdm_auth_add_entry_for_display (int display_num, - GdmAddress *address, - GString *cookie, - FILE *af, - GSList **authlist); - -gboolean gdm_auth_add_entry (int display_num, - GdmAddress *address, - GString *binary_cookie, - FILE *af, - GSList **authlist); - -gboolean gdm_auth_user_add (int display_num, - GdmAddress *address, - const char *cookie, - const char *username, - char **filenamep); - -void gdm_auth_free_auth_list (GSList *list); - -G_END_DECLS - -#endif /* GDM_AUTH_H */ Index: daemon/gdm-slave.c =================================================================== --- daemon/gdm-slave.c (revision 5497) +++ daemon/gdm-slave.c (working copy) @@ -75,7 +75,6 @@ struct GdmSlavePrivate gboolean display_is_local; gboolean display_is_parented; char *display_x11_authority_file; - char *display_x11_cookie; char *parent_display_name; char *parent_display_x11_authority_file; @@ -94,8 +93,7 @@ enum { PROP_DISPLAY_NUMBER, PROP_DISPLAY_HOSTNAME, PROP_DISPLAY_IS_LOCAL, - PROP_DISPLAY_X11_AUTHORITY_FILE, - PROP_DISPLAY_X11_COOKIE, + PROP_DISPLAY_X11_AUTHORITY_FILE }; enum { @@ -354,37 +352,6 @@ gdm_slave_set_busy_cursor (GdmSlave *sla } } -static void -set_local_auth (GdmSlave *slave) -{ - GString *binary_cookie; - GString *cookie; - - g_debug ("GdmSlave: Setting authorization key for display %s", slave->priv->display_x11_cookie); - - cookie = g_string_new (slave->priv->display_x11_cookie); - binary_cookie = g_string_new (NULL); - if (! gdm_string_hex_decode (cookie, - 0, - NULL, - binary_cookie, - 0)) { - g_warning ("Unable to decode hex cookie"); - goto out; - } - - g_debug ("GdmSlave: Decoded cookie len %d", (int) binary_cookie->len); - - XSetAuthorization ("MIT-MAGIC-COOKIE-1", - (int) strlen ("MIT-MAGIC-COOKIE-1"), - (char *)binary_cookie->str, - binary_cookie->len); - - out: - g_string_free (binary_cookie, TRUE); - g_string_free (cookie, TRUE); -} - gboolean gdm_slave_connect_to_x11_display (GdmSlave *slave) { @@ -400,9 +367,7 @@ gdm_slave_connect_to_x11_display (GdmSla g_debug ("GdmSlave: Server is ready - opening display %s", slave->priv->display_name); g_setenv ("DISPLAY", slave->priv->display_name, TRUE); - g_unsetenv ("XAUTHORITY"); /* just in case it's set */ - - set_local_auth (slave); + g_setenv ("XAUTHORITY", slave->priv->display_x11_authority_file, TRUE); #if 0 /* X error handlers to avoid the default one (i.e. exit (1)) */ @@ -574,24 +539,6 @@ gdm_slave_real_start (GdmSlave *slave) error = NULL; res = dbus_g_proxy_call (slave->priv->display_proxy, - "GetX11Cookie", - &error, - G_TYPE_INVALID, - G_TYPE_STRING, &slave->priv->display_x11_cookie, - G_TYPE_INVALID); - if (! res) { - if (error != NULL) { - g_warning ("Failed to get value: %s", error->message); - g_error_free (error); - } else { - g_warning ("Failed to get value"); - } - - return FALSE; - } - - error = NULL; - res = dbus_g_proxy_call (slave->priv->display_proxy, "GetX11AuthorityFile", &error, G_TYPE_INVALID, @@ -743,14 +690,6 @@ _gdm_slave_set_display_x11_authority_fil } static void -_gdm_slave_set_display_x11_cookie (GdmSlave *slave, - const char *name) -{ - g_free (slave->priv->display_x11_cookie); - slave->priv->display_x11_cookie = g_strdup (name); -} - -static void _gdm_slave_set_display_is_local (GdmSlave *slave, gboolean is) { @@ -783,9 +722,6 @@ gdm_slave_set_property (GObject *ob case PROP_DISPLAY_X11_AUTHORITY_FILE: _gdm_slave_set_display_x11_authority_file (self, g_value_get_string (value)); break; - case PROP_DISPLAY_X11_COOKIE: - _gdm_slave_set_display_x11_cookie (self, g_value_get_string (value)); - break; case PROP_DISPLAY_IS_LOCAL: _gdm_slave_set_display_is_local (self, g_value_get_boolean (value)); break; @@ -821,9 +757,6 @@ gdm_slave_get_property (GObject *obje case PROP_DISPLAY_X11_AUTHORITY_FILE: g_value_set_string (value, self->priv->display_x11_authority_file); break; - case PROP_DISPLAY_X11_COOKIE: - g_value_set_string (value, self->priv->display_x11_cookie); - break; case PROP_DISPLAY_IS_LOCAL: g_value_set_boolean (value, self->priv->display_is_local); break; @@ -938,13 +871,6 @@ gdm_slave_class_init (GdmSlaveClass *kla NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, - PROP_DISPLAY_X11_COOKIE, - g_param_spec_string ("display-x11-cookie", - "", - "", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, PROP_DISPLAY_IS_LOCAL, g_param_spec_boolean ("display-is-local", "display is local", Index: daemon/gdm-display.c =================================================================== --- daemon/gdm-display.c (revision 5497) +++ daemon/gdm-display.c (working copy) @@ -35,11 +35,10 @@ #include "gdm-display.h" #include "gdm-display-glue.h" +#include "gdm-display-access-file.h" #include "gdm-slave-proxy.h" -#include "auth.h" - static guint32 display_serial = 1; #define GDM_DISPLAY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_DISPLAY, GdmDisplayPrivate)) @@ -56,15 +55,18 @@ struct GdmDisplayPrivate char *x11_display_name; int status; time_t creation_time; - char *x11_cookie; - char *x11_authority_file; char *slave_command; + char *x11_cookie; + gsize x11_cookie_size; + GdmDisplayAccessFile *access_file; + gboolean is_local; guint finish_idle_id; GdmSlaveProxy *slave_proxy; DBusGConnection *connection; + GdmDisplayAccessFile *user_access_file; }; enum { @@ -127,10 +129,56 @@ gdm_display_get_status (GdmDisplay *disp return display->priv->status; } +static GdmDisplayAccessFile * +_create_access_file_for_user (GdmDisplay *display, + const char *username, + GError **error) +{ + GdmDisplayAccessFile *access_file; + GError *file_error; + + access_file = gdm_display_access_file_new (username); + + file_error = NULL; + if (!gdm_display_access_file_open (access_file, &file_error)) { + g_propagate_error (error, file_error); + return FALSE; + } + + return access_file; +} + static gboolean gdm_display_real_create_authority (GdmDisplay *display) { + GdmDisplayAccessFile *access_file; + GError *error; + g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE); + g_return_val_if_fail (display->priv->access_file == NULL, FALSE); + + error = NULL; + access_file = _create_access_file_for_user (display, "gdm", &error); + + if (access_file == NULL) { + g_critical ("could not create display access file: %s", error->message); + g_error_free (error); + return FALSE; + } + + if (!gdm_display_access_file_add_display (access_file, display, + &display->priv->x11_cookie, + &display->priv->x11_cookie_size, + &error)) { + + g_critical ("could not add display to access file: %s", error->message); + g_error_free (error); + gdm_display_access_file_close (access_file); + g_object_unref (access_file); + return FALSE; + } + + display->priv->access_file = access_file; return TRUE; } @@ -155,11 +203,35 @@ gdm_display_real_add_user_authorization char **filename, GError **error) { - gboolean ret; + GdmDisplayAccessFile *access_file; + GError *access_file_error; - ret = FALSE; + g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE); + g_return_val_if_fail (display->priv->access_file != NULL, FALSE); - return ret; + access_file_error = NULL; + access_file = _create_access_file_for_user (display, username, + &access_file_error); + + if (access_file == NULL) { + g_propagate_error (error, access_file_error); + return FALSE; + } + + if (!gdm_display_access_file_add_display_with_cookie (access_file, + display, display->priv->x11_cookie, + display->priv->x11_cookie_size, + &access_file_error)) { + g_propagate_error (error, access_file_error); + gdm_display_access_file_close (access_file); + g_object_unref (access_file); + return FALSE; + } + + *filename = gdm_display_access_file_get_path (access_file); + display->priv->user_access_file = access_file; + + return TRUE; } gboolean @@ -186,11 +258,9 @@ gdm_display_real_remove_user_authorizati const char *username, GError **error) { - gboolean ret; + gdm_display_access_file_close (display->priv->user_access_file); - ret = FALSE; - - return ret; + return TRUE; } gboolean @@ -214,12 +284,18 @@ gdm_display_remove_user_authorization (G gboolean gdm_display_get_x11_cookie (GdmDisplay *display, char **x11_cookie, + gsize *x11_cookie_size, GError **error) { g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE); if (x11_cookie != NULL) { - *x11_cookie = g_strdup (display->priv->x11_cookie); + *x11_cookie = g_memdup (display->priv->x11_cookie, + display->priv->x11_cookie_size); + } + + if (x11_cookie_size != NULL) { + *x11_cookie_size = display->priv->x11_cookie_size; } return TRUE; @@ -231,9 +307,12 @@ gdm_display_get_x11_authority_file (GdmD GError **error) { g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE); + g_return_val_if_fail (filename != NULL, FALSE); - if (filename != NULL) { - *filename = g_strdup (display->priv->x11_authority_file); + if (display->priv->access_file != NULL) { + *filename = gdm_display_access_file_get_path (display->priv->access_file); + } else { + *filename = NULL; } return TRUE; @@ -398,6 +477,14 @@ gdm_display_real_unmanage (GdmDisplay *d display->priv->slave_proxy = NULL; } + gdm_display_access_file_close (display->priv->user_access_file); + g_object_unref (display->priv->user_access_file); + display->priv->user_access_file = NULL; + + gdm_display_access_file_close (display->priv->access_file); + g_object_unref (display->priv->access_file); + display->priv->access_file = NULL; + return TRUE; } @@ -507,14 +594,6 @@ _gdm_display_set_x11_cookie (GdmDisplay } static void -_gdm_display_set_x11_authority_file (GdmDisplay *display, - const char *file) -{ - g_free (display->priv->x11_authority_file); - display->priv->x11_authority_file = g_strdup (file); -} - -static void _gdm_display_set_is_local (GdmDisplay *display, gboolean is_local) { @@ -558,9 +637,6 @@ gdm_display_set_property (GObject case PROP_X11_COOKIE: _gdm_display_set_x11_cookie (self, g_value_get_string (value)); break; - case PROP_X11_AUTHORITY_FILE: - _gdm_display_set_x11_authority_file (self, g_value_get_string (value)); - break; case PROP_IS_LOCAL: _gdm_display_set_is_local (self, g_value_get_boolean (value)); break; @@ -603,7 +679,8 @@ gdm_display_get_property (GObject g_value_set_string (value, self->priv->x11_cookie); break; case PROP_X11_AUTHORITY_FILE: - g_value_set_string (value, self->priv->x11_authority_file); + g_value_take_string (value, + gdm_display_access_file_get_path (self->priv->access_file)); break; case PROP_IS_LOCAL: g_value_set_boolean (value, self->priv->is_local); @@ -752,7 +829,7 @@ gdm_display_class_init (GdmDisplayClass "authority file", "authority file", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_IS_LOCAL, @@ -803,8 +880,15 @@ gdm_display_finalize (GObject *object) g_free (display->priv->remote_hostname); g_free (display->priv->x11_display_name); g_free (display->priv->x11_cookie); - g_free (display->priv->x11_authority_file); g_free (display->priv->slave_command); + if (display->priv->access_file != NULL) { + g_object_unref (display->priv->access_file); + } + + if (display->priv->user_access_file != NULL) { + g_object_unref (display->priv->user_access_file); + } + G_OBJECT_CLASS (gdm_display_parent_class)->finalize (object); } Index: daemon/gdm-manager.c =================================================================== --- daemon/gdm-manager.c (revision 5497) +++ daemon/gdm-manager.c (working copy) @@ -60,7 +60,6 @@ struct GdmManagerPrivate gboolean xdmcp_enabled; - GString *global_cookie; gboolean wait_for_go; gboolean no_console; @@ -137,38 +136,6 @@ gdm_manager_get_displays (GdmManager *ma return TRUE; } -static void -make_global_cookie (GdmManager *manager) -{ - FILE *fp; - char *file; - - gdm_generate_cookie (manager->priv->global_cookie); - - file = g_build_filename (AUTHDIR, ".cookie", NULL); - VE_IGNORE_EINTR (g_unlink (file)); - - fp = gdm_safe_fopen_w (file, 077); - if G_UNLIKELY (fp == NULL) { - g_warning (_("Can't open %s for writing"), file); - g_free (file); - return; - } - - VE_IGNORE_EINTR (fprintf (fp, "%s\n", manager->priv->global_cookie->str)); - - /* FIXME: What about out of disk space errors? */ - errno = 0; - VE_IGNORE_EINTR (fclose (fp)); - if G_UNLIKELY (errno != 0) { - g_warning (_("Can't write to %s: %s"), - file, - g_strerror (errno)); - } - - g_free (file); -} - void gdm_manager_start (GdmManager *manager) { @@ -420,10 +387,6 @@ gdm_manager_init (GdmManager *manager) manager->priv = GDM_MANAGER_GET_PRIVATE (manager); - manager->priv->global_cookie = g_string_new (NULL); - - make_global_cookie (manager); - manager->priv->display_store = gdm_display_store_new (); } @@ -446,8 +409,6 @@ gdm_manager_finalize (GObject *object) gdm_display_store_clear (manager->priv->display_store); g_object_unref (manager->priv->display_store); - g_string_free (manager->priv->global_cookie, TRUE); - G_OBJECT_CLASS (gdm_manager_parent_class)->finalize (object); } Index: daemon/gdm-display.h =================================================================== --- daemon/gdm-display.h (revision 5497) +++ daemon/gdm-display.h (working copy) @@ -69,7 +69,8 @@ typedef struct typedef enum { - GDM_DISPLAY_ERROR_GENERAL + GDM_DISPLAY_ERROR_GENERAL, + GDM_DISPLAY_ERROR_GETTING_USER_INFO } GdmDisplayError; #define GDM_DISPLAY_ERROR gdm_display_error_quark () @@ -107,6 +108,7 @@ gboolean gdm_display_is_local /* exported but protected */ gboolean gdm_display_get_x11_cookie (GdmDisplay *display, char **x11_cookie, + gsize *cookie_size, GError **error); gboolean gdm_display_get_x11_authority_file (GdmDisplay *display, char **filename, Index: daemon/gdm-factory-slave.c =================================================================== --- daemon/gdm-factory-slave.c (revision 5497) +++ daemon/gdm-factory-slave.c (working copy) @@ -565,11 +565,13 @@ static gboolean gdm_factory_slave_run (GdmFactorySlave *slave) { char *display_name; + char *auth_file; gboolean display_is_local; g_object_get (slave, "display-is-local", &display_is_local, "display-name", &display_name, + "display-x11-authority-file", &auth_file, NULL); /* if this is local display start a server if one doesn't @@ -577,7 +579,7 @@ gdm_factory_slave_run (GdmFactorySlave * if (display_is_local) { gboolean res; - slave->priv->server = gdm_server_new (display_name); + slave->priv->server = gdm_server_new (display_name, auth_file); g_signal_connect (slave->priv->server, "ready", @@ -603,6 +605,7 @@ gdm_factory_slave_run (GdmFactorySlave * } g_free (display_name); + g_free (auth_file); return TRUE; } Index: daemon/gdm-static-display.c =================================================================== --- daemon/gdm-static-display.c (revision 5497) +++ daemon/gdm-static-display.c (working copy) @@ -20,9 +20,11 @@ #include "config.h" +#include #include #include #include +#include #include #include #include @@ -34,6 +36,7 @@ #include #include +#include "gdm-common.h" #include "gdm-display.h" #include "gdm-static-display.h" #include "gdm-static-display-glue.h" @@ -71,7 +74,7 @@ gdm_static_display_add_user_authorizatio char **filename, GError **error) { - return TRUE; + return GDM_DISPLAY_CLASS (gdm_static_display_parent_class)->add_user_authorization (display, username, filename, error); } static gboolean @@ -79,7 +82,7 @@ gdm_static_display_remove_user_authoriza const char *username, GError **error) { - return TRUE; + return GDM_DISPLAY_CLASS (gdm_static_display_parent_class)->remove_user_authorization (display, username, error); } static gboolean Index: daemon/gdm-simple-slave.c =================================================================== --- daemon/gdm-simple-slave.c (revision 5497) +++ daemon/gdm-simple-slave.c (working copy) @@ -680,11 +680,13 @@ static gboolean gdm_simple_slave_run (GdmSimpleSlave *slave) { char *display_name; + char *auth_file; gboolean display_is_local; g_object_get (slave, "display-is-local", &display_is_local, "display-name", &display_name, + "display-x11-authority-file", &auth_file, NULL); /* if this is local display start a server if one doesn't @@ -692,7 +694,7 @@ gdm_simple_slave_run (GdmSimpleSlave *sl if (display_is_local) { gboolean res; - slave->priv->server = gdm_server_new (display_name); + slave->priv->server = gdm_server_new (display_name, auth_file); g_signal_connect (slave->priv->server, "ready", @@ -718,6 +720,7 @@ gdm_simple_slave_run (GdmSimpleSlave *sl } g_free (display_name); + g_free (auth_file); return TRUE; } Index: daemon/gdm-xdmcp-display-factory.c =================================================================== --- daemon/gdm-xdmcp-display-factory.c (revision 5497) +++ daemon/gdm-xdmcp-display-factory.c (working copy) @@ -57,8 +57,6 @@ #include "gdm-xdmcp-display-factory.h" #include "gdm-display-store.h" -#include "auth.h" - /* * On Sun, we need to define allow_severity and deny_severity to link * against libwrap. @@ -2043,57 +2041,29 @@ gdm_xdmcp_handle_request (GdmXdmcpDispla clnt_dspnum); if (display != NULL) { - ARRAY8 authentication_name; - ARRAY8 authentication_data; - ARRAY8 authorization_name; - ARRAY8 authorization_data; - gint32 session_number; - char *x11_cookie; - GString *cookie; - GString *binary_cookie; - GString *test_cookie; - - gdm_display_get_x11_cookie (display, &x11_cookie, NULL); - cookie = g_string_new (x11_cookie); - g_free (x11_cookie); - - binary_cookie = g_string_new (NULL); - - if (! gdm_string_hex_decode (cookie, - 0, - NULL, - binary_cookie, - 0)) { - g_warning ("Unable to decode hex cookie"); - /* FIXME: handle error */ - } + ARRAY8 authentication_name; + ARRAY8 authentication_data; + ARRAY8 authorization_name; + ARRAY8 authorization_data; + gint32 session_number; + char *cookie; + gsize cookie_size; + char *name; + + gdm_display_get_x11_cookie (display, &cookie, + &cookie_size, NULL); - test_cookie = g_string_new (NULL); - if (! gdm_string_hex_encode (binary_cookie, - 0, - test_cookie, - 0)) { - g_warning ("Unable to encode hex cookie"); - /* FIXME: handle error */ - } + gdm_display_get_x11_display_name (display, &name, NULL); - /* sanity check cookie */ - g_debug ("GdmXdmcpDisplayFactory: Original cookie len:%d '%s'; Reencoded cookie len:%d '%s'", - (int) cookie->len, - cookie->str, - (int) test_cookie->len, - test_cookie->str); - g_assert (test_cookie->len == cookie->len); - g_assert (strcmp (test_cookie->str, cookie->str) == 0); - g_string_free (test_cookie, TRUE); + g_debug ("GdmXdmcpDisplayFactory: Sending authorization key for display %s", name); + g_free (name); - g_debug ("GdmXdmcpDisplayFactory: Sending authorization key for display %s", cookie->str); - g_debug ("GdmXdmcpDisplayFactory: Decoded cookie len %d", (int) binary_cookie->len); + g_debug ("GdmXdmcpDisplayFactory: cookie len %d", (int) cookie_size); session_number = gdm_xdmcp_display_get_session_number (GDM_XDMCP_DISPLAY (display)); /* the send accept will fail if cookie is null */ - g_assert (binary_cookie != NULL); + g_assert (cookie != NULL); authentication_name.data = NULL; authentication_name.length = 0; @@ -2103,8 +2073,8 @@ gdm_xdmcp_handle_request (GdmXdmcpDispla authorization_name.data = (CARD8 *) "MIT-MAGIC-COOKIE-1"; authorization_name.length = strlen ((char *) authorization_name.data); - authorization_data.data = (CARD8 *) binary_cookie->str; - authorization_data.length = binary_cookie->len; + authorization_data.data = (CARD8 *) cookie; + authorization_data.length = cookie_size; /* the addrs are NOT copied */ gdm_xdmcp_send_accept (factory, @@ -2114,9 +2084,6 @@ gdm_xdmcp_handle_request (GdmXdmcpDispla &authentication_data, &authorization_name, &authorization_data); - - g_string_free (binary_cookie, TRUE); - g_string_free (cookie, TRUE); } } } else { Index: daemon/Makefile.am =================================================================== --- daemon/Makefile.am (revision 5497) +++ daemon/Makefile.am (working copy) @@ -125,8 +125,6 @@ gdm_simple_slave_SOURCES = \ gdm-slave.h \ gdm-simple-slave.c \ gdm-simple-slave.h \ - auth.c \ - auth.h \ $(NULL) gdm_simple_slave_LDFLAGS = \ @@ -190,8 +188,6 @@ gdm_product_slave_SOURCES = \ gdm-slave.h \ gdm-product-slave.c \ gdm-product-slave.h \ - auth.c \ - auth.h \ $(NULL) gdm_product_slave_LDFLAGS = \ @@ -226,6 +222,8 @@ sbin_PROGRAMS = \ gdm_binary_SOURCES = \ main.c \ + gdm-display-access-file.c \ + gdm-display-access-file.h \ gdm-display-store.c \ gdm-display-store.h \ gdm-display-factory.c \ @@ -246,8 +244,6 @@ gdm_binary_SOURCES = \ gdm-manager.h \ gdm-slave-proxy.c \ gdm-slave-proxy.h \ - auth.c \ - auth.h \ $(NULL) XDMCP_SOURCES = \