]> rtime.felk.cvut.cz Git - sojka/lightdm.git/commitdiff
Store authorization in files
authorunknown <robert.ancell@gmail.com>
Sun, 18 Jul 2010 13:53:59 +0000 (15:53 +0200)
committerunknown <robert.ancell@gmail.com>
Sun, 18 Jul 2010 13:53:59 +0000 (15:53 +0200)
15 files changed:
NEWS
configure.ac
src/Makefile.am
src/display-manager.c
src/display.c
src/session.c
src/session.h
src/xauth.c [new file with mode: 0644]
src/xauth.h [new file with mode: 0644]
src/xdmcp-server.c
src/xdmcp-session-private.h
src/xdmcp-session.c
src/xdmcp-session.h
src/xserver.c
src/xserver.h

diff --git a/NEWS b/NEWS
index 999484780bc87cdb3370c137aa312b4113aa170c..abc1f1e068785dbf2fd865298c598235e1b69e2d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,7 @@ Overview of changes in lightdm 0.0.5
 
     * Make --test-mode which runs as the current user
     * Support displays acting as XDMCP terminals
+    * Support MIT-MAGIC-COOKIE-1 and XDM-AUTHORIZATION-1 authorization
 
 Overview of changes in lightdm 0.0.4
 
index 8ddbe1bfe17df2589817f564fb71814e1995d0e4..b78e290424009c1d42c7059929945c95e858e786 100644 (file)
@@ -88,6 +88,16 @@ AC_ARG_WITH(xserver-binary,
 )    
 AC_SUBST(XSERVER_BINARY)
 
+XAUTH_DIR=$localstatedir/run/lightdm/authority
+AC_ARG_WITH(xauth-dir,
+            AS_HELP_STRING([--with-xauth-dir=<dir>],
+                           [X server authorization directory]),
+    if test x$withval != x; then
+        XAUTH_DIR="$withval"
+    fi
+)    
+AC_SUBST(XAUTH_DIR)
+
 XSESSION_DIR=/usr/share/xsessions
 AC_ARG_WITH(xsession-dir,
             AS_HELP_STRING([--with-xsession-dir=<dir>],
@@ -183,6 +193,7 @@ echo "
         Config file:              ${CONFIG_FILE}
         D-Bus system directory:   ${DBUS_SYS_DIR}
         X server binary:          ${XSERVER_BINARY}
+        X authorization dir:      ${XAUTH_DIR}
         XSessions dir:            ${XSESSION_DIR}
         Default session:          ${DEFAULT_SESSION}
         Greeter user:             ${GREETER_USER}
index 7c9e6faf1423d187001b734be3998baf31e38b38..3388458a985fc579363c6ad93e5818075898d08b 100644 (file)
@@ -21,6 +21,8 @@ lightdm_SOURCES = \
        theme.h \
        user-manager.c \
        user-manager.h \
+       xauth.c \
+       xauth.h \
        xdmcp-protocol.c \
        xdmcp-protocol.h \
        xdmcp-server.c \
@@ -43,6 +45,7 @@ lightdm_CFLAGS = \
        -DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" \
        -DLOCALE_DIR=\"$(localedir)\" \
        -DXSERVER_BINARY=\"$(XSERVER_BINARY)\" \
+       -DXAUTH_DIR=\"$(XAUTH_DIR)\" \
        -DXSESSIONS_DIR=\"$(XSESSION_DIR)\" \
        -DDEFAULT_SESSION=\"$(DEFAULT_SESSION)\" \
        -DGREETER_USER=\"$(GREETER_USER)\" \
index f163fa0456d3f411947256868dd067304567bcd9..a2547407a2eece216a23abc6796e10447214ef70 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <sys/stat.h>
 #include <dbus/dbus-glib.h>
 
 #include "display-manager.h"
@@ -33,12 +34,16 @@ static guint signals[LAST_SIGNAL] = { 0 };
 struct DisplayManagerPrivate
 {
     GKeyFile *config;
+  
+    gchar *auth_dir;
 
     gboolean test_mode;
 
     GList *displays;
   
     XDMCPServer *xdmcp_server;
+  
+    guint auth_counter;
 };
 
 G_DEFINE_TYPE (DisplayManager, display_manager, G_TYPE_OBJECT);
@@ -93,10 +98,22 @@ get_free_display_number (DisplayManager *manager)
     return display_number;
 }
 
+static gchar *
+get_authorization_path (DisplayManager *manager)
+{
+    gchar *path;
+
+    path = g_strdup_printf ("%s/%d", manager->priv->auth_dir, manager->priv->auth_counter);
+    manager->priv->auth_counter++;
+
+    return path;
+}
+
 static void
 start_session_cb (Display *display, Session *session, DisplayManager *manager)
 {
     gchar *string;
+    XAuthorization *authorization;
 
     /* Connect using the session bus */
     if (manager->priv->test_mode)
@@ -109,6 +126,16 @@ start_session_cb (Display *display, Session *session, DisplayManager *manager)
     string = g_strdup_printf ("/org/gnome/LightDisplayManager/Display%d", display_get_index (display));
     session_set_env (session, "LDM_DISPLAY", string);
 
+    authorization = xserver_get_authorization (display_get_xserver (display));
+    if (authorization)
+    {
+        gchar *path;
+
+        path = get_authorization_path (manager);
+        session_set_authorization (session, authorization, path);
+        g_free (path);
+    }
+
     g_free (string);
 }
 
@@ -150,15 +177,22 @@ static void
 xdmcp_session_cb (XDMCPServer *server, XDMCPSession *session, DisplayManager *manager)
 {
     Display *display;
-    gchar *address;
+    gchar *address, *path;
     XServer *xserver;
+    XAuthorization *authorization;
 
     display = add_display (manager);
     address = g_inet_address_to_string (G_INET_ADDRESS (xdmcp_session_get_address (session)));
     xserver = xserver_new (XSERVER_TYPE_REMOTE, address, xdmcp_session_get_display_number (session));
+    authorization = xauth_new (xdmcp_session_get_authorization_name (session),
+                               xdmcp_session_get_authorization_data (session),
+                               xdmcp_session_get_authorization_data_length (session));
+    path = get_authorization_path (manager);
+    xserver_set_authorization (xserver, authorization, path);
     display_start (display, xserver, NULL, 0);
     g_object_unref (xserver);
     g_free (address);
+    g_free (path);
 }
 
 static guchar
@@ -198,11 +232,51 @@ string_to_xdm_auth_key (const gchar *key, guchar *data)
     }
 }
 
+static void
+setup_auth_dir (DisplayManager *manager)
+{
+    GDir *dir;
+    GError *error = NULL;
+
+    g_mkdir_with_parents (manager->priv->auth_dir, S_IRWXU);
+    dir = g_dir_open (manager->priv->auth_dir, 0, &error);
+    if (!dir)
+    {
+        g_warning ("Authorization dir not created: %s", error->message);
+        g_clear_error (&error);
+        return;
+    }
+
+    /* Clear out the directory */
+    while (TRUE)
+    {
+        const gchar *filename;
+        gchar *path;
+        GFile *file;
+
+        filename = g_dir_read_name (dir);
+        if (!filename)
+            break;
+
+        path = g_build_filename (manager->priv->auth_dir, filename, NULL);
+        file = g_file_new_for_path (filename);
+        g_file_delete (file, NULL, NULL);
+
+        g_free (path);
+        g_object_unref (file);
+    }
+
+    g_dir_close (dir);
+}
+
 void
 display_manager_start (DisplayManager *manager)
 {
     gchar *displays;
     gchar **tokens, **i;
+
+    /* Make an empty authorization directory */
+    setup_auth_dir (manager);
   
     /* Start the first display */
     displays = g_key_file_get_string (manager->priv->config, "LightDM", "displays", NULL);
@@ -258,14 +332,31 @@ display_manager_start (DisplayManager *manager)
             if (key)
             {
                 guchar data[8];
+                gchar *path;
+                XAuthorization *authorization;
 
                 string_to_xdm_auth_key (key, data);
                 xserver_set_authentication (xserver, "XDM-AUTHENTICATION-1", data, 8);
-                xserver_set_authorization (xserver, "XDM-AUTHORIZATION-1", data, 8);
+
+                authorization = xauth_new ("XDM-AUTHORIZATION-1", data, 8);
+                path = get_authorization_path (manager);
+                xserver_set_authorization (xserver, authorization, path);
+
+              g_free (path);
             }
         }
         else
+        {
+            gchar *path;
+            XAuthorization *authorization;
+
             xserver = xserver_new (XSERVER_TYPE_LOCAL, NULL, display_number);
+
+            authorization = xauth_new_cookie ();
+            path = get_authorization_path (manager);
+            xserver_set_authorization (xserver, authorization, path);
+            g_free (path);
+        }
         g_free (xdmcp_manager);
 
         if (manager->priv->test_mode)
@@ -326,6 +417,10 @@ display_manager_set_property (GObject      *object,
     case PROP_CONFIG:
         self->priv->config = g_value_get_pointer (value);
         self->priv->test_mode = g_key_file_get_boolean (self->priv->config, "LightDM", "test-mode", NULL);
+        if (self->priv->test_mode)
+            self->priv->auth_dir = g_build_filename (g_get_user_cache_dir (), "lightdm", "authority", NULL);
+        else
+            self->priv->auth_dir = g_strdup (XAUTH_DIR);       
         break;
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -333,7 +428,6 @@ display_manager_set_property (GObject      *object,
     }
 }
 
-
 static void
 display_manager_get_property (GObject    *object,
                               guint       prop_id,
@@ -366,6 +460,7 @@ display_manager_finalize (GObject *object)
         g_object_unref (self->priv->xdmcp_server);
     for (link = self->priv->displays; link; link = link->next)
         g_object_unref (link->data);
+    g_list_free (self->priv->displays);
 }
 
 static void
index 9875ba5056b4a0618bc15433cb568d862617bf70..d14bf09b9a70092aa2cc886c5a3365e3dc33a0d2 100644 (file)
@@ -188,7 +188,7 @@ session_exit_cb (Session *session, Display *display)
     case SESSION_NONE:
         break;
     case SESSION_GREETER_PRE_CONNECT:
-        g_error ("Failed to start greeter");
+        g_warning ("Failed to start greeter");
         break;
     case SESSION_GREETER:
         if (display->priv->default_user && display->priv->timeout > 0)
index 2f162d267d5a0325e5ed6285d3a9e04041be6bb6..7444cce91f3e6ba1a80b4180912a0021e53bed3e 100644 (file)
@@ -43,6 +43,11 @@ struct SessionPrivate
 
     /* Session process */
     GPid pid;
+
+    /* X authorization */
+    XAuthorization *authorization;
+    gchar *authorization_path;
+    GFile *authorization_file;
 };
 
 G_DEFINE_TYPE (Session, session, G_TYPE_OBJECT);
@@ -71,6 +76,18 @@ session_set_env (Session *session, const gchar *name, const gchar *value)
     g_hash_table_insert (session->priv->env, g_strdup (name), g_strdup (value));
 }
 
+void
+session_set_authorization (Session *session, XAuthorization *authorization, const gchar *path)
+{
+    session->priv->authorization = authorization;
+    session->priv->authorization_path = g_strdup (path);
+}
+
+XAuthorization *session_get_authorization (Session *session)
+{
+    return session->priv->authorization;
+}
+
 static void
 session_watch_cb (GPid pid, gint status, gpointer data)
 {
@@ -155,7 +172,7 @@ session_start (Session *session)
                 g_warning ("Unable to get information on user %s: %s", session->priv->username, strerror (errno));
             return FALSE;
         }
-  
+
         working_dir = user_info->pw_dir;
         session_set_env (session, "USER", user_info->pw_name);
         session_set_env (session, "HOME", user_info->pw_dir);
@@ -168,11 +185,21 @@ session_start (Session *session)
         session_set_env (session, "SHELL", getenv ("SHELL"));
     }
 
+    if (session->priv->authorization)
+    {
+        session->priv->authorization_file = xauth_write (session->priv->authorization, session->priv->authorization_path, &error);
+        if (session->priv->authorization_file)
+            session_set_env (session, "XAUTHORITY", session->priv->authorization_path);
+        else
+            g_warning ("Failed to write authorization: %s", error->message);
+        g_clear_error (&error);
+    }
+
     env = session_get_env (session);
 
     result = g_shell_parse_argv (session->priv->command, &argc, &argv, &error);
     if (!result)
-        g_error ("Failed to parse session command line: %s", error->message);
+        g_warning ("Failed to parse session command line: %s", error->message);
     g_clear_error (&error);
     if (!result)
         return FALSE;
@@ -263,6 +290,14 @@ session_finalize (GObject *object)
     g_free (self->priv->username);
     g_hash_table_unref (self->priv->env);
     g_free (self->priv->command);
+    if (self->priv->authorization)
+        g_object_unref (self->priv->authorization);
+    g_free (self->priv->authorization_path);
+    if (self->priv->authorization_file)
+    {
+        g_file_delete (self->priv->authorization_file, NULL, NULL);
+        g_object_unref (self->priv->authorization_file);
+    }
 }
 
 static void
index 0aef17c1f5b65ee4fa9711ee74a09c2a0c832c57..1ddb94340fd66c8bd2234d441252cc2bf02e3454 100644 (file)
@@ -13,6 +13,7 @@
 #define _SESSION_H_
 
 #include <glib-object.h>
+#include "xauth.h"
 
 G_BEGIN_DECLS
 
@@ -44,6 +45,10 @@ const gchar *session_get_command (Session *session);
 
 void session_set_env (Session *session, const gchar *name, const gchar *value);
 
+void session_set_authorization (Session *session, XAuthorization *authorization, const gchar *path);
+
+XAuthorization *session_get_authorization (Session *session);
+
 gboolean session_start (Session *session);
 
 G_END_DECLS
diff --git a/src/xauth.c b/src/xauth.c
new file mode 100644 (file)
index 0000000..e59760f
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2010 Robert Ancell.
+ * Author: Robert Ancell <robert.ancell@canonical.com>
+ * 
+ * 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 3 of the License, or (at your option) any later
+ * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
+ * license.
+ */
+
+#include <string.h>
+
+#include "xauth.h"
+
+struct XAuthorizationPrivate
+{
+    /* User who is using this authorization */
+    gchar *username;
+
+    /* Authorization scheme */
+    gchar *authorization_name;
+
+    /* Authorization data */
+    guchar *authorization_data;
+    gsize authorization_data_length;
+};
+
+G_DEFINE_TYPE (XAuthorization, xauth, G_TYPE_OBJECT);
+
+XAuthorization *
+xauth_new (const gchar *name, const guchar *data, gsize data_length)
+{
+    XAuthorization *auth = g_object_new (XAUTH_TYPE, NULL);
+
+    auth->priv->authorization_name = g_strdup (name);
+    auth->priv->authorization_data = g_malloc (data_length);
+    auth->priv->authorization_data_length = data_length;
+    memcpy (auth->priv->authorization_data, data, data_length);
+
+    return auth;
+}
+
+XAuthorization *xauth_new_cookie (void)
+{
+    guchar cookie[16];
+    gint i;
+  
+    for (i = 0; i < 16; i++)
+        cookie[i] = g_random_int () & 0xFF;
+
+    return xauth_new ("MIT-MAGIC-COOKIE-1", cookie, 16);
+}
+
+const gchar *
+xauth_get_authorization_name (XAuthorization *auth)
+{
+    return auth->priv->authorization_name;
+}
+
+const guchar *
+xauth_get_authorization_data (XAuthorization *auth)
+{
+    return auth->priv->authorization_data;
+}
+
+gsize
+xauth_get_authorization_data_length (XAuthorization *auth)
+{
+    return auth->priv->authorization_data_length;
+}
+
+static void
+write_uint16 (GString *string, guint16 value)
+{
+    g_string_append_c (string, (gchar) value >> 8);
+    g_string_append_c (string, (gchar) value);
+}
+
+static void
+write_data (GString *string, guchar *value, gsize value_len)
+{
+    g_string_append_len (string, (gchar *) value, value_len);
+}
+
+static void
+write_string (GString *string, const gchar *value)
+{
+    write_uint16 (string, strlen (value));
+    g_string_append (string, value);
+}
+
+GFile *
+xauth_write (XAuthorization *auth, const gchar *path, GError **error)
+{
+    GFile *file;
+    GFileOutputStream *stream;
+    GString *data;
+    gboolean result;
+    gsize n_written;
+
+    file = g_file_new_for_path (path);
+
+    stream = g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, error);
+    if (!stream)
+    {
+        g_object_unref (file);
+        return FALSE;
+    }
+  
+    data = g_string_sized_new (1024);
+    write_uint16 (data, 0xFFFF); /* FamilyWild - this entry is used for all connections */
+    write_string (data, ""); /* Not requires as using FamilyWild */
+    write_string (data, ""); /* Not requires as using FamilyWild */
+    write_string (data, auth->priv->authorization_name);
+    write_uint16 (data, auth->priv->authorization_data_length);
+    write_data (data, auth->priv->authorization_data, auth->priv->authorization_data_length);
+
+    result = g_output_stream_write_all (G_OUTPUT_STREAM (stream), data->str, data->len, &n_written, NULL, error);
+    g_string_free (data, TRUE);
+
+    g_object_unref (stream);
+    if (!result)
+    {
+        g_object_unref (file);
+        file = NULL;
+    }
+  
+    return file;
+}
+
+static void
+xauth_init (XAuthorization *auth)
+{
+    auth->priv = G_TYPE_INSTANCE_GET_PRIVATE (auth, XAUTH_TYPE, XAuthorizationPrivate);
+    auth->priv->authorization_name = g_strdup ("");
+}
+
+static void
+xauth_finalize (GObject *object)
+{
+    XAuthorization *self;
+
+    self = XAUTH (object);
+
+    g_free (self->priv->username);
+    g_free (self->priv->authorization_name);
+    g_free (self->priv->authorization_data);
+}
+
+static void
+xauth_class_init (XAuthorizationClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+    object_class->finalize = xauth_finalize;  
+
+    g_type_class_add_private (klass, sizeof (XAuthorizationPrivate));
+}
diff --git a/src/xauth.h b/src/xauth.h
new file mode 100644 (file)
index 0000000..fa2600f
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 Robert Ancell.
+ * Author: Robert Ancell <robert.ancell@canonical.com>
+ * 
+ * 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 3 of the License, or (at your option) any later
+ * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
+ * license.
+ */
+
+#ifndef _XAUTH_H_
+#define _XAUTH_H_
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define XAUTH_TYPE (xauth_get_type())
+#define XAUTH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XAUTH_TYPE, XAuthorization));
+
+typedef struct XAuthorizationPrivate XAuthorizationPrivate;
+
+typedef struct
+{
+    GObject         parent_instance;
+    XAuthorizationPrivate *priv;
+} XAuthorization;
+
+typedef struct
+{
+    GObjectClass parent_class;
+} XAuthorizationClass;
+
+GType xauth_get_type (void);
+
+XAuthorization *xauth_new (const gchar *name, const guchar *data, gsize data_length);
+
+XAuthorization *xauth_new_cookie (void);
+
+const gchar *xauth_get_authorization_name (XAuthorization *auth);
+
+const guchar *xauth_get_authorization_data (XAuthorization *auth);
+
+gsize xauth_get_authorization_data_length (XAuthorization *auth);
+
+GFile *xauth_write (XAuthorization *auth, const gchar *path, GError **error);
+
+G_END_DECLS
+
+#endif /* _XAUTH_H_ */
index cce3ff2ea0952e9c7da702697a35e651769affd4..b69b960e707f4078cd92397df357f8d7bda766a3 100644 (file)
@@ -267,8 +267,9 @@ handle_request (XDMCPServer *server, GSocket *socket, GSocketAddress *address, X
     gboolean match_authorization = FALSE;
     guchar *authorization_data = NULL;
     gsize authorization_data_length = 0;
+    guchar *session_authorization_data = NULL;
+    gsize session_authorization_data_length = 0;
     gchar **j;
-    guchar session_key[8];
     GInetAddress *address4 = NULL; /*, *address6 = NULL;*/
   
     /* Must be using our authentication scheme */
@@ -333,7 +334,6 @@ handle_request (XDMCPServer *server, GSocket *socket, GSocketAddress *address, X
     }
 
     /* Perform requested authorization */
-    memset (session_key, 0, sizeof (session_key));
     if (strcmp (server->priv->authorization_name, "MIT-MAGIC-COOKIE-1") == 0)
     {
         /* Data is the cookie */
@@ -344,18 +344,28 @@ handle_request (XDMCPServer *server, GSocket *socket, GSocketAddress *address, X
     else if (strcmp (server->priv->authorization_name, "XDM-AUTHORIZATION-1") == 0)
     {
         gint i;
-        guchar key[8];
+        guchar key[8], session_key[8];
 
         /* Setup key */
         memset (key, 0, 8);
         memcpy (key, server->priv->authentication_data, server->priv->authentication_data_length > 8 ? 8 : server->priv->authentication_data_length);
 
-        /* Generate a private session key and encode it */
+        /* Generate a private session key */
+        // FIXME: Pick a good DES key?
         for (i = 0; i < 8; i++)
             session_key[i] = g_random_int () & 0xFF;
+
+        /* Encrypt the session key and send it to the server */
         authorization_data = g_malloc (sizeof (guchar) * 8);
         authorization_data_length = 8;
         XdmcpWrap (session_key, key, authorization_data, authorization_data_length);
+
+        /* Authorization data is the session key (64 bit) followed by the private key (56 bit) followed by an empty byte */
+        session_authorization_data = g_malloc (sizeof (guchar) * 16);
+        session_authorization_data_length = 8;
+        memcpy (session_authorization_data, session_key, 8);
+        memcpy (session_authorization_data + 8, key + 1, 7);
+        session_authorization_data[15] = 0;
     }
 
     for (i = 0; i < packet->Request.n_connections; i++)
@@ -390,7 +400,9 @@ handle_request (XDMCPServer *server, GSocket *socket, GSocketAddress *address, X
 
     session = add_session (server);
     session->priv->address = address4; /*address6 ? address6 : address4;*/
-    memcpy (session->priv->key, session_key, 8);
+    session->priv->authorization_name = g_strdup (server->priv->authorization_name);
+    session->priv->authorization_data = session_authorization_data;
+    session->priv->authorization_data_length = session_authorization_data_length;
 
     response = xdmcp_packet_alloc (XDMCP_Accept);
     response->Accept.session_id = xdmcp_session_get_id (session);
@@ -574,7 +586,7 @@ xdmcp_server_init (XDMCPServer *server)
     server->priv->port = XDM_UDP_PORT;
     server->priv->hostname = g_strdup ("");
     server->priv->status = g_strdup ("");
-    server->priv->sessions = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
+    server->priv->sessions = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
     server->priv->authentication_name = g_strdup ("");
     server->priv->authorization_name = g_strdup ("");
 }
index c65597c9504da0630cb88d86c94cca34c9263bc5..d51683311ffbe9cabe0939f558f3dfda62b2ea6b 100644 (file)
@@ -29,8 +29,8 @@ struct XDMCPSessionPrivate
 
     gchar *authorization_name;
   
-    /* Session key for XDM-AUTHORIZATION-1 */
-    guchar key[8];
+    guchar *authorization_data;
+    gsize authorization_data_length;
   
     gboolean started;
 
index 6c0ff36e0e182b90c3ecb5087d85d5435651dcb7..c4a09683124589cc6816873a4d45365f46d9451a 100644 (file)
@@ -50,6 +50,18 @@ xdmcp_session_get_authorization_name (XDMCPSession *session)
     return session->priv->authorization_name;
 }
 
+const guchar *
+xdmcp_session_get_authorization_data (XDMCPSession *session)
+{
+    return session->priv->authorization_data;  
+}
+
+const gsize
+xdmcp_session_get_authorization_data_length (XDMCPSession *session)
+{
+    return session->priv->authorization_data_length;
+}
+
 guint16
 xdmcp_session_get_display_number (XDMCPSession *session)
 {
index c2138507119055b1000f53bb27211a2d1f6aaaad..7d92106043c976f49ccd9bb209b9b170dbeb51a7 100644 (file)
@@ -45,6 +45,10 @@ const GInetAddress *xdmcp_session_get_address (XDMCPSession *session);
 
 const gchar *xdmcp_session_get_authorization_name (XDMCPSession *session);
 
+const guchar *xdmcp_session_get_authorization_data (XDMCPSession *session);
+
+const gsize xdmcp_session_get_authorization_data_length (XDMCPSession *session);
+
 guint16 xdmcp_session_get_display_number (XDMCPSession *session);
 
 const gchar *xdmcp_session_get_display_class (XDMCPSession *session);
index ed8286c662c20f6920ddad5ffffe97f4459e450e..bbf3607c024409c2e334b6c2098426291e103e8f 100644 (file)
@@ -58,12 +58,10 @@ struct XServerPrivate
     guchar *authentication_data;
     gsize authentication_data_length;
 
-    /* Authorization scheme to use */
-    gchar *authorization_name;
-
-    /* Authorization data */
-    guchar *authorization_data;
-    gsize authorization_data_length;
+    /* Authorization */
+    XAuthorization *authorization;
+    gchar *authorization_path;
+    GFile *authorization_file;
 
     /* Display number */
     gint display_number;
@@ -188,32 +186,16 @@ xserver_get_authentication_data_length (XServer *server)
 }
 
 void
-xserver_set_authorization (XServer *server, const gchar *name, const guchar *data, gsize data_length)
-{
-    g_free (server->priv->authorization_name);
-    server->priv->authorization_name = g_strdup (name);
-    g_free (server->priv->authorization_data);
-    server->priv->authorization_data = g_malloc (data_length);
-    server->priv->authorization_data_length = data_length;
-    memcpy (server->priv->authorization_data, data, data_length);
-}
-
-const gchar *
-xserver_get_authorization_name (XServer *server)
+xserver_set_authorization (XServer *server, XAuthorization *authorization, const gchar *path)
 {
-    return server->priv->authorization_name;
+    server->priv->authorization = authorization;
+    server->priv->authorization_path = g_strdup (path);
 }
 
-const guchar *
-xserver_get_authorization_data (XServer *server)
-{
-    return server->priv->authorization_data;
-}
-
-gsize
-xserver_get_authorization_data_length (XServer *server)
+XAuthorization *
+xserver_get_authorization (XServer *server)
 {
-    return server->priv->authorization_data_length;
+    return server->priv->authorization;
 }
 
 static void
@@ -252,6 +234,8 @@ xserver_start (XServer *server)
     gint n_env = 0;
     gchar *env_string;
     //gint xserver_stdin, xserver_stdout, xserver_stderr;
+
+    g_return_val_if_fail (server->priv->pid == 0, FALSE);
  
     /* Don't need to do anything if a remote server */
     if (server->priv->type == XSERVER_TYPE_REMOTE)
@@ -269,10 +253,25 @@ xserver_start (XServer *server)
         env[n_env++] = g_strdup_printf ("XAUTHORITY=%s", getenv ("XAUTHORITY"));
     env[n_env] = NULL;
 
+    /* Write the authorization file */
+    if (server->priv->authorization)
+    {
+        GError *error = NULL;
+
+        server->priv->authorization_file = xauth_write (server->priv->authorization, server->priv->authorization_path, &error);
+        if (!server->priv->authorization_file)
+            g_warning ("Failed to write authorization: %s", error->message);
+        g_clear_error (&error);
+    }
+
     command = g_string_new (server->priv->command);
     g_string_append_printf (command, " :%d", server->priv->display_number);
     g_string_append (command, " -nr");           /* No root background */
     //g_string_append_printf (command, " vt%d");
+
+    if (server->priv->authorization)
+         g_string_append_printf (command, " -auth %s", server->priv->authorization_path);
+
     if (server->priv->type == XSERVER_TYPE_LOCAL_TERMINAL)
     {
         if (server->priv->port != 0)
@@ -300,7 +299,7 @@ xserver_start (XServer *server)
     result = g_shell_parse_argv (command->str, &argc, &argv, &error);
     g_string_free (command, TRUE);
     if (!result)
-        g_error ("Failed to parse X server command line: %s", error->message);
+        g_warning ("Failed to parse X server command line: %s", error->message);
     g_clear_error (&error);
     if (!result)
         return FALSE;
@@ -310,7 +309,7 @@ xserver_start (XServer *server)
                                        env,
                                        G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
                                        xserver_fork_cb,
-                                       NULL,
+                                       server,
                                        &server->priv->pid,
                                        //&xserver_stdin, &xserver_stdout, &xserver_stderr,
                                        &error);
@@ -334,7 +333,6 @@ xserver_init (XServer *server)
     server->priv = G_TYPE_INSTANCE_GET_PRIVATE (server, XSERVER_TYPE, XServerPrivate);
     server->priv->command = g_strdup (XSERVER_BINARY);
     server->priv->authentication_name = g_strdup ("");
-    server->priv->authorization_name = g_strdup ("");
 }
 
 static void
@@ -419,9 +417,15 @@ xserver_finalize (GObject *object)
     g_free (self->priv->hostname);
     g_free (self->priv->authentication_name);
     g_free (self->priv->authentication_data);
-    g_free (self->priv->authorization_name);
-    g_free (self->priv->authorization_data);
     g_free (self->priv->address);
+    if (self->priv->authorization)
+        g_object_unref (self->priv->authorization);
+    g_free (self->priv->authorization_path);
+    if (self->priv->authorization_file)
+    {
+        g_file_delete (self->priv->authorization_file, NULL, NULL);
+        g_object_unref (self->priv->authorization_file);
+    }
 }
 
 static void
index c0710a610dd599213c76680e22cc1189bb2dc638..b916205fa84bdeeaabd7d28dd2c6d4de55e5f69b 100644 (file)
@@ -15,6 +15,8 @@
 #include <glib-object.h>
 #include <dbus/dbus-glib.h>
 
+#include "xauth.h"
+
 G_BEGIN_DECLS
 
 #define XSERVER_TYPE (xserver_get_type())
@@ -78,13 +80,9 @@ const guchar *xserver_get_authentication_data (XServer *server);
 
 gsize xserver_get_authentication_data_length (XServer *server);
 
-void xserver_set_authorization (XServer *server, const gchar *name, const guchar *data, gsize data_length);
-
-const gchar *xserver_get_authorization_name (XServer *server);
-
-const guchar *xserver_get_authorization_data (XServer *server);
+void xserver_set_authorization (XServer *server, XAuthorization *authorization, const gchar *path);
 
-gsize xserver_get_authorization_data_length (XServer *server);
+XAuthorization *xserver_get_authorization (XServer *server);
 
 gboolean xserver_start (XServer *server);