diff options
author | George Lebl <jirka@5z.com> | 2001-08-26 01:56:38 +0000 |
---|---|---|
committer | George Lebl <jirka@src.gnome.org> | 2001-08-26 01:56:38 +0000 |
commit | 5cc352a22b185e19d2389a98d7a3287fee6f7d44 (patch) | |
tree | 758bff7c550cd09464d17896dcf0be05ff2b1134 /gui | |
parent | 15c88eb6e482b2963b541a43c196c7c44949b1e9 (diff) | |
download | gdm-5cc352a22b185e19d2389a98d7a3287fee6f7d44.tar.gz |
Minor cleanup and paranoia
Sun Aug 26 01:45:33 2001 George Lebl <jirka@5z.com>
* daemon/auth.c, daemon/cookie.c: Minor cleanup and paranoia
* daemon/gdm-net.[ch], daemon/gdm.[ch], daemon/server.c,
daemon/slave.[ch]: The daemon now keeps track of the cookies in
text form at least so that it can do authentication of it's own.
FLEXI_XSERVER now requires an "authenticated" socket connection
using AUTH_LOCAL (a new opcode). This way only those users that
are logged in from gdm on a console can start new
console/fullscreen flexi servers. I mean for remote people it
wouldn't work anyway.
* gui/gdmflexiserver.c: implement AUTH_LOCAL authentication scheme
by reading from the .Xauthority file and looking for FamilyLocal
entries from gdm. (or those looking like it). Tests all candidates
and find the one that works for gdm. This could cause some
gdm_info messages in the log, but I suppose that's ok, vast
majority of the time there will only be one that is even tried.
Also added a debug flag and get xauth filename from XauFileName
rather then my own hand created method.
Diffstat (limited to 'gui')
-rw-r--r-- | gui/gdmflexiserver.c | 186 |
1 files changed, 140 insertions, 46 deletions
diff --git a/gui/gdmflexiserver.c b/gui/gdmflexiserver.c index 049cec69..91319a63 100644 --- a/gui/gdmflexiserver.c +++ b/gui/gdmflexiserver.c @@ -20,8 +20,11 @@ #include "config.h" #include <gnome.h> +#include <gdk/gdkx.h> +#include <X11/Xauth.h> #include <stdlib.h> +#include <stdio.h> #include <unistd.h> #include <stdio.h> #include <sys/types.h> @@ -35,6 +38,15 @@ #include "gdm.h" +static GSList *xservers = NULL; +static gboolean got_standard = FALSE; +static gboolean use_xnest = FALSE; +static const char *send_command = NULL; +static const char *server = NULL; +static const char *chosen_server = NULL; +static gboolean debug = FALSE; + + static char * do_command (int fd, const char *command, gboolean get_response) { @@ -42,7 +54,8 @@ do_command (int fd, const char *command, gboolean get_response) char buf[1]; char *cstr; - /* g_print ("Sending command: '%s'\n", command); */ + if (debug) + g_print ("Sending command: '%s'\n", command); cstr = g_strdup_printf ("%s\n", command); if (send (fd, cstr, strlen (cstr), MSG_NOSIGNAL) < 0) @@ -57,7 +70,8 @@ do_command (int fd, const char *command, gboolean get_response) g_string_append_c (str, buf[0]); } - /* g_print (" Got response: '%s'\n", str->str); */ + if (debug) + g_print (" Got response: '%s'\n", str->str); cstr = str->str; g_string_free (str, FALSE); @@ -85,7 +99,7 @@ version_ok_p (const char *version, const char *min_version) } static char * -call_gdm (const char *command, const char *min_version, int tries) +call_gdm (const char *command, const char * auth_cookie, const char *min_version, int tries) { struct sockaddr_un addr; int fd; @@ -96,7 +110,7 @@ call_gdm (const char *command, const char *min_version, int tries) fd = socket (AF_UNIX, SOCK_STREAM, 0); if (fd < 0) { - return call_gdm (command, min_version, tries - 1); + return call_gdm (command, auth_cookie, min_version, tries - 1); } strcpy (addr.sun_path, GDM_SUP_SOCKET); @@ -104,14 +118,14 @@ call_gdm (const char *command, const char *min_version, int tries) if (connect (fd, (struct sockaddr *)&addr, sizeof (addr)) < 0) { close (fd); - return call_gdm (command, min_version, tries - 1); + return call_gdm (command, auth_cookie, min_version, tries - 1); } /* Version check first */ ret = do_command (fd, GDM_SUP_VERSION, TRUE /* get_response */); if (ret == NULL) { close (fd); - return call_gdm (command, min_version, tries - 1); + return call_gdm (command, auth_cookie, min_version, tries - 1); } if (strncmp (ret, "GDM ", strlen ("GDM ")) != 0) { g_free (ret); @@ -124,11 +138,34 @@ call_gdm (const char *command, const char *min_version, int tries) close (fd); return NULL; } + g_free (ret); + + /* require authentication */ + if (auth_cookie != NULL) { + char *auth_cmd = g_strdup_printf + (GDM_SUP_AUTH_LOCAL " %s", auth_cookie); + ret = do_command (fd, auth_cmd, TRUE /* get_response */); + g_free (auth_cmd); + if (ret == NULL) { + close (fd); + return call_gdm (command, auth_cookie, + min_version, tries - 1); + } + /* not auth'ed */ + if (strcmp (ret, "OK") != 0) { + do_command (fd, GDM_SUP_CLOSE, + FALSE /* get_response */); + close (fd); + /* returns the error */ + return ret; + } + g_free (ret); + } ret = do_command (fd, command, TRUE /* get_response */); if (ret == NULL) { close (fd); - return call_gdm (command, min_version, tries - 1); + return call_gdm (command, auth_cookie, min_version, tries - 1); } do_command (fd, GDM_SUP_CLOSE, FALSE /* get_response */); @@ -144,39 +181,97 @@ get_display (void) static char *display = NULL; if (display == NULL) { - display = g_strdup (g_getenv ("DISPLAY")); - if (display == NULL) /*eek!*/ - display = g_strdup (":0"); + display = g_strdup (gdk_display_name); + if (display == NULL) { + display = g_strdup (g_getenv ("DISPLAY")); + if (display == NULL) /*eek!*/ { + display = g_strdup (":0"); + } + } } return display; } static char * -get_xauthfile (void) +get_auth_cookie (void) { - static char *xauthfile = NULL; - - if (xauthfile == NULL) { - xauthfile = g_strdup (g_getenv ("XAUTHORITY")); - if (ve_string_empty (xauthfile)) { - g_strdup (xauthfile); - xauthfile = g_concat_dir_and_file (g_get_home_dir (), - ".Xauthority"); - /* FIXME: perhaps if it doesn't exist, run - * xauth generate on this */ + FILE *fp; + char *number; + static gboolean tried = FALSE; + static char *cookie = NULL; + Xauth *xau; + + if (tried) + return cookie; + + fp = fopen (XauFileName (), "r"); + if (fp == NULL) { + cookie = NULL; + tried = TRUE; + return NULL; + } + + number = get_display (); + + /* whee! handles even DECnet crap */ + number = strchr (number, ':'); + if (number != NULL) { + while (*number == ':') { + number++; } + } else { + number = "0"; } - return xauthfile; -} + cookie = NULL; + + while ((xau = XauReadAuth (fp)) != NULL) { + char *cmd; + char *ret; + int i; + char buffer[40 /* 2*16 == 32, so 40 is enough */]; + + /* Only Family local things are considered, all console + * logins DO have this family (and even some local xdmcp + * logins, though those will not pass by gdm itself of + * course) */ + if (xau->family != FamilyLocal || + xau->number == NULL || + strncmp (xau->number, number, xau->number_length) != 0 || + /* gdm sends MIT-MAGIC-COOKIE-1 cookies of length 16, + * so just do those */ + xau->name_length != strlen ("MIT-MAGIC-COOKIE-1") || + strncmp (xau->name, "MIT-MAGIC-COOKIE-1", xau->name_length) != 0 || + xau->data_length != 16) { + XauDisposeAuth (xau); + continue; + } -static GSList *xservers = NULL; -static gboolean got_standard = FALSE; -static gboolean use_xnest = FALSE; -const char *send_command = NULL; -const char *server = NULL; -const char *chosen_server = NULL; + buffer[0] = '\0'; + for (i = 0; i < 16; i++) { + char sub[3]; + g_snprintf (sub, sizeof (sub), "%02x", (guint)(guchar)xau->data[i]); + strcat (buffer, sub); + } + + XauDisposeAuth (xau); + + cmd = g_strdup_printf (GDM_SUP_AUTH_LOCAL " %s", buffer); + ret = call_gdm (cmd, NULL /* auth cookie */, "2.2.4.0", 5); + if (ret != NULL && + strcmp (ret, "OK") == 0) { + g_free (ret); + cookie = g_strdup (buffer); + break; + } + g_free (ret); + } + fclose (fp); + + tried = TRUE; + return cookie; +} static void read_servers (void) @@ -318,6 +413,7 @@ choose_server (void) struct poptOption options [] = { { "command", 'c', POPT_ARG_STRING, &send_command, 0, N_("Send the specified protocol command to gdm"), N_("COMMAND") }, { "xnest", 'n', POPT_ARG_NONE, &use_xnest, 0, N_("Xnest mode"), NULL }, + { "debug", 'd', POPT_ARG_NONE, &debug, 0, N_("Debugging output"), NULL }, POPT_AUTOHELP { NULL, 0, 0, NULL, 0} }; @@ -334,6 +430,7 @@ main (int argc, char *argv[]) char *version; char *ret; char *message; + char *auth_cookie = NULL; poptContext ctx; const char **args; @@ -380,7 +477,8 @@ main (int argc, char *argv[]) } if (send_command != NULL) { - ret = call_gdm (send_command, "2.2.3.2", 5); + ret = call_gdm (send_command, NULL /* auth cookie */, + "2.2.4.0", 5); if (ret != NULL) { g_print ("%s\n", ret); return 0; @@ -397,21 +495,13 @@ main (int argc, char *argv[]) command = g_strdup_printf (GDM_SUP_FLEXI_XNEST " %s %s", get_display (), - get_xauthfile ()); - version = "2.2.3.2"; + XauFileName ()); + version = "2.2.4.0"; + auth_cookie = NULL; } else { - char *disp = ve_sure_string (g_getenv ("DISPLAY")); - char hostname[1024]; - - if (gethostname (hostname, sizeof (hostname)) < 0) - strcpy (hostname, "localhost"); - - if (disp[0] != ':' && - strncmp ("localhost:", disp, - strlen ("localhost:")) != 0 && - strncmp ("localhost.localdomain:", disp, - strlen ("localhost.localdomain:")) != 0 && - strncmp (hostname, disp, strlen (hostname)) != 0) { + auth_cookie = get_auth_cookie (); + + if (auth_cookie == NULL) { dialog = gnome_warning_dialog (_("You do not seem to be logged in on the " "console. Starting a new login only " @@ -427,10 +517,10 @@ main (int argc, char *argv[]) else command = g_strdup_printf (GDM_SUP_FLEXI_XSERVER " %s", server); - version = "2.2.3.2"; + version = "2.2.4.0"; } - ret = call_gdm (command, version, 5); + ret = call_gdm (command, auth_cookie, version, 5); if (ret != NULL && strncmp (ret, "OK ", 3) == 0) { /* all fine and dandy */ @@ -467,6 +557,10 @@ main (int argc, char *argv[]) message = _("The X server is not available, " "it is likely that gdm is badly " "configured."); + } else if (strncmp (ret, "ERROR 100 ", strlen ("ERROR 100 ")) == 0) { + message = _("You do not seem to be logged in on the " + "console. Starting a new login only " + "works correctly on the console."); } else { message = _("Unknown error occured."); } |