summaryrefslogtreecommitdiff
path: root/daemon/xdmcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/xdmcp.c')
-rw-r--r--daemon/xdmcp.c2788
1 files changed, 0 insertions, 2788 deletions
diff --git a/daemon/xdmcp.c b/daemon/xdmcp.c
deleted file mode 100644
index 42062d80..00000000
--- a/daemon/xdmcp.c
+++ /dev/null
@@ -1,2788 +0,0 @@
-/* GDM - The GNOME Display Manager
- * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- *
- * 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
- */
-
-/* This file contains the XDMCP implementation for managing remote
- * displays.
- */
-
-/* Theory of operation:
- *
- * Process idles waiting for UDP packets on port 177.
- * Incoming packets are decoded and checked against tcp_wrapper.
- *
- * A typical session looks like this:
- *
- * Display sends Query/BroadcastQuery to Manager.
- *
- * Manager selects an appropriate authentication scheme from the
- * display's list of supported ones and sends Willing/Unwilling.
- *
- * Assuming the display accepts the auth. scheme it sends back a
- * Request.
- *
- * If the manager accepts to service the display (i.e. loadavg is low)
- * it sends back an Accept containing a unique SessionID. The
- * SessionID is stored in an accept queue by the Manager. Should the
- * manager refuse to start a session a Decline is sent to the display.
- *
- * The display returns a Manage request containing the supplied
- * SessionID. The manager will then start a session on the display. In
- * case the SessionID is not on the accept queue the manager returns
- * Refuse. If the manager fails to open the display for connections
- * Failed is returned.
- *
- * During the session the display periodically sends KeepAlive packets
- * to the manager. The manager responds with Alive.
- *
- * Similarly the manager xpings the display once in a while and shuts
- * down the connection on failure.
- *
- */
-
-#include "config.h"
-
-#ifdef HAVE_LIBXDMCP
-#include <stdio.h>
-#include <unistd.h>
-#include <time.h>
-#include <stdlib.h>
-#include <syslog.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <X11/Xlib.h>
-#include <X11/Xmd.h>
-#include <X11/Xdmcp.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/utsname.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <fcntl.h>
-#ifdef HAVE_SYS_SOCKIO_H
-#include <sys/sockio.h>
-#endif
-
-#ifdef HAVE_TCPWRAPPERS
- #include <tcpd.h>
-#endif
-#endif /* HAVE_LIBXDMCP */
-
-#include <glib/gi18n.h>
-
-#ifdef HAVE_LIBXDMCP
-#include "gdm.h"
-#include "display.h"
-#include "auth.h"
-#endif /* HAVE_LIBXDMCP */
-
-#include "misc.h"
-#include "choose.h"
-#include "xdmcp.h"
-#include "cookie.h"
-#include "gdmconfig.h"
-
-#define XDMCP_MULTICAST_ADDRESS "ff02::1" /*This is to be changed when the Xdmcp Multicast address is decided */
-
-int gdm_xdmcpfd = -1;
-
-#ifdef HAVE_LIBXDMCP
-
-/* TCP Wrapper syslog control */
-gint allow_severity = LOG_INFO;
-gint deny_severity = LOG_WARNING;
-
-static guint xdmcp_source = 0;
-static CARD32 globsessid;
-static gchar *sysid;
-static ARRAY8 servhost;
-static XdmcpBuffer buf;
-static gboolean initted = FALSE;
-
-extern GSList *displays;
-extern gint xdmcp_pending;
-extern gint xdmcp_sessions;
-
-/* Local prototypes */
-static gboolean gdm_xdmcp_decode_packet (GIOChannel *source,
- GIOCondition cond,
- gpointer data);
-/*************************** IPv6 specific prototypes *****************************/
-
-#ifdef ENABLE_IPV6
-static void gdm_xdmcp_handle_query (struct sockaddr_storage *clnt_sa,
- gint len,
- gint type);
-static void gdm_xdmcp_handle_forward_query (struct sockaddr_storage *clnt_sa, gint len);
-static void gdm_xdmcp_handle_request (struct sockaddr_storage *clnt_sa, gint len);
-static void gdm_xdmcp_handle_manage (struct sockaddr_storage *clnt_sa, gint len);
-static void gdm_xdmcp_handle_managed_forward (struct sockaddr_storage *clnt_sa, gint len);
-static void gdm_xdmcp_handle_got_managed_forward (struct sockaddr_storage *clnt_sa, gint len);
-static void gdm_xdmcp_handle_keepalive (struct sockaddr_storage *clnt_sa, gint len);
-static void gdm_xdmcp_send_willing (struct sockaddr_storage *clnt_sa);
-static void gdm_xdmcp_send_unwilling (struct sockaddr_storage *clnt_sa, gint type);
-static void gdm_xdmcp_send_accept (GdmHostent *he, struct sockaddr_storage *clnt_sa,
- gint displaynum);
-static void gdm_xdmcp_send_decline (struct sockaddr_storage *clnt_sa, const char *reason);
-static void gdm_xdmcp_send_refuse (struct sockaddr_storage *clnt_sa, CARD32 sessid);
-static void gdm_xdmcp_send_failed (struct sockaddr_storage *clnt_sa, CARD32 sessid);
-static void gdm_xdmcp_send_alive (struct sockaddr_storage *clnt_sa, CARD16 dspnum, CARD32 sessid);
-static void gdm_xdmcp_send_managed_forward (struct sockaddr_storage *clnt_sa,
- struct sockaddr_storage *origin);
-static void gdm_xdmcp_send_forward_query6 (GdmIndirectDisplay *id,
- struct sockaddr_in6 *clnt_sa,
- struct in6_addr *display_addr,
- ARRAYofARRAY8Ptr authlist);
-static gboolean gdm_xdmcp_host_allow (struct sockaddr_storage *clnt_sa);
-static GdmForwardQuery * gdm_forward_query_alloc (struct sockaddr_storage *mgr_sa,
- struct sockaddr_storage *dsp_sa);
-static GdmForwardQuery * gdm_forward_query_lookup (struct sockaddr_storage *clnt_sa);
-static void gdm_xdmcp_whack_queued_managed_forwards6 (struct sockaddr_in6 *clnt_sa,
- struct in6_addr *origin);
-static void gdm_xdmcp_send_got_managed_forward6 (struct sockaddr_in6 *clnt_sa,
- struct in6_addr *origin);
-static int gdm_xdmcp_displays_from_host (struct sockaddr_storage *addr);
-static GdmDisplay *gdm_xdmcp_display_lookup_by_host (struct sockaddr_storage *addr, int dspnum);
-static GdmDisplay *gdm_xdmcp_display_alloc (struct sockaddr_storage *addr, GdmHostent *he, int displaynum);
-
-#else
-
-static void gdm_xdmcp_handle_forward_query (struct sockaddr_in *clnt_sa, gint len);
-static void gdm_xdmcp_handle_query (struct sockaddr_in *clnt_sa,
- gint len,
- gint type);
- static void gdm_xdmcp_handle_request (struct sockaddr_in *clnt_sa, gint len);
- static void gdm_xdmcp_handle_manage (struct sockaddr_in *clnt_sa, gint len);
- static void gdm_xdmcp_handle_managed_forward (struct sockaddr_in *clnt_sa, gint len);
- static void gdm_xdmcp_handle_got_managed_forward (struct sockaddr_in *clnt_sa, gint len);
- static void gdm_xdmcp_handle_keepalive (struct sockaddr_in *clnt_sa, gint len);
- static void gdm_xdmcp_send_willing (struct sockaddr_in *clnt_sa);
- static void gdm_xdmcp_send_unwilling (struct sockaddr_in *clnt_sa, gint type);
- static void gdm_xdmcp_send_accept (GdmHostent *he /* eaten and freed */,
- struct sockaddr_in *clnt_sa,
- int displaynum);
-static void gdm_xdmcp_send_decline (struct sockaddr_in *clnt_sa, const char *reason);
- static void gdm_xdmcp_send_refuse (struct sockaddr_in *clnt_sa, CARD32 sessid);
- static void gdm_xdmcp_send_failed (struct sockaddr_in *clnt_sa, CARD32 sessid);
- static void gdm_xdmcp_send_alive (struct sockaddr_in *clnt_sa, CARD16 dspnum, CARD32 sessid);
- static void gdm_xdmcp_send_managed_forward (struct sockaddr_in *clnt_sa,
- struct sockaddr_in *origin);
- static gboolean gdm_xdmcp_host_allow (struct sockaddr_in *clnt_sa);
-static GdmForwardQuery * gdm_forward_query_alloc (struct sockaddr_in *mgr_sa,
- struct sockaddr_in *dsp_sa);
-static GdmForwardQuery * gdm_forward_query_lookup (struct sockaddr_in *clnt_sa);
-static int gdm_xdmcp_displays_from_host (struct sockaddr_in *addr);
-static GdmDisplay *gdm_xdmcp_display_lookup_by_host (struct sockaddr_in *addr, int dspnum);
-static GdmDisplay *gdm_xdmcp_display_alloc (struct sockaddr_in *addr, GdmHostent *he, int displaynum);
-
-#endif /*IPv4 / IPv6*/
-
-static void gdm_xdmcp_whack_queued_managed_forwards (struct sockaddr_in *clnt_sa,
- struct in_addr *origin);
-static void gdm_xdmcp_send_got_managed_forward (struct sockaddr_in *clnt_sa,
- struct in_addr *origin);
-static void gdm_xdmcp_send_forward_query (GdmIndirectDisplay *id,
- struct sockaddr_in *clnt_sa,
- struct in_addr *display_addr,
- ARRAYofARRAY8Ptr authlist);
-static void gdm_xdmcp_whack_queued_managed_forwards (struct sockaddr_in *clnt_sa,
- struct in_addr *origin);
-static void gdm_xdmcp_send_got_managed_forward (struct sockaddr_in *clnt_sa,
- struct in_addr *origin);
-static GdmDisplay *gdm_xdmcp_display_lookup (CARD32 sessid);
-static void gdm_xdmcp_display_dispose_check (const gchar *hostname, int dspnum);
-static void gdm_xdmcp_displays_check (void);
-static void gdm_forward_query_dispose (GdmForwardQuery *q);
-
-static GSList *forward_queries = NULL;
-
-typedef struct {
- int times;
- guint handler;
-#ifdef ENABLE_IPV6
- struct sockaddr_storage manager;
- struct sockaddr_storage origin;
-#else
- struct sockaddr_in manager;
- struct sockaddr_in origin;
-#endif
-} ManagedForward;
-#define MANAGED_FORWARD_INTERVAL 1500 /* 1.5 seconds */
-
-static GSList *managed_forwards = NULL;
-
-
-/*
- * We don't support XDM-AUTHENTICATION-1 and XDM-AUTHORIZATION-1.
- *
- * The latter would be quite useful to avoid sending unencrypted
- * cookies over the wire. Unfortunately it isn't supported without
- * XDM-AUTHENTICATION-1 which requires a key database with private
- * keys from all X terminals on your LAN. Fun, fun, fun.
- *
- * Furthermore user passwords go over the wire in cleartext anyway so
- * protecting cookies is not that important.
- */
-
-typedef struct _XdmAuth {
- ARRAY8 authentication;
- ARRAY8 authorization;
-} XdmAuthRec, *XdmAuthPtr;
-
-static XdmAuthRec serv_authlist = {
- { (CARD16) 0, (CARD8 *) 0 },
- { (CARD16) 0, (CARD8 *) 0 }
-};
-
-#ifdef ENABLE_IPV6
-static gboolean have_ipv6 (void)
-{
- int s;
-
- s = socket (AF_INET6, SOCK_STREAM, 0);
- if (s != -1) {
- VE_IGNORE_EINTR (close (s));
- return TRUE;
- }
-
- return FALSE;
-}
-#endif
-
-static int
-#ifdef ENABLE_IPV6
-gdm_xdmcp_displays_from_host (struct sockaddr_storage *addr)
-#else
-gdm_xdmcp_displays_from_host (struct sockaddr_in *addr)
-#endif
-{
- GSList *li;
- int count = 0;
-
- for (li = displays; li != NULL; li = li->next) {
- GdmDisplay *disp = li->data;
- if (SERVER_IS_XDMCP (disp)) {
-#ifdef ENABLE_IPV6
- if (disp->addrtype == AF_INET6 &&
- memcmp (&disp->addr6, &((struct sockaddr_in6 *)addr)->sin6_addr, sizeof (struct in6_addr)) == 0)
- count++;
- else
-#endif
- if (disp->addrtype == AF_INET &&
- memcmp (&disp->addr, &((struct sockaddr_in *)addr)->sin_addr, sizeof (struct in_addr)) == 0)
- count++;
- }
- }
-
- return count;
-}
-
-static GdmDisplay *
-#ifdef ENABLE_IPV6
-gdm_xdmcp_display_lookup_by_host (struct sockaddr_storage *addr, int dspnum)
-#else
-gdm_xdmcp_display_lookup_by_host (struct sockaddr_in *addr, int dspnum)
-#endif
-{
- GSList *li;
-
- for (li = displays; li != NULL; li = li->next) {
- GdmDisplay *disp = li->data;
- if (SERVER_IS_XDMCP (disp)) {
-#ifdef ENABLE_IPV6
- if (disp->addrtype == AF_INET6) {
- if ((memcmp (&disp->addr6, &((struct sockaddr_in6 *)addr)->sin6_addr, sizeof (struct in6_addr)) == 0) && disp->xdmcp_dispnum == dspnum)
- return disp;
- }
- else
-#endif
- if ((memcmp (&disp->addr, &((struct sockaddr_in *)addr)->sin_addr, sizeof (struct in_addr)) == 0) && disp->xdmcp_dispnum == dspnum)
- return disp;
- }
- }
-
- return NULL;
-}
-
-
-gboolean
-gdm_xdmcp_init (void)
-{
-#ifdef ENABLE_IPV6
- struct sockaddr_storage serv_sa = {0};
-#else
- struct sockaddr_in serv_sa = {0};
-#endif
- gint addrlen;
- gchar hostbuf[1024];
- struct utsname name;
- int udpport = gdm_get_value_int (GDM_KEY_UDP_PORT);
-
- if ( ! gdm_get_value_bool (GDM_KEY_XDMCP))
- return TRUE;
-
- globsessid = g_random_int ();
-
- /* Fetch and store local hostname in XDMCP friendly format */
- hostbuf[1023] = '\0';
- if G_UNLIKELY (gethostname (hostbuf, 1023) != 0) {
- gdm_error (_("%s: Could not get server hostname: %s!"),
- "gdm_xdmcp_init", strerror (errno));
- strcmp (hostbuf, "localhost.localdomain");
- }
-
- if ( ! initted) {
- uname (&name);
- sysid = g_strconcat (name.sysname, " ", name.release, NULL);
-
- servhost.data = (CARD8 *) g_strdup (hostbuf);
- servhost.length = strlen ((char *) servhost.data);
-
- initted = TRUE;
- }
-
- gdm_debug ("XDMCP: Start up on host %s, port %d", hostbuf, udpport);
-
- /* Open socket for communications */
-#ifdef ENABLE_IPV6
- gdm_xdmcpfd = socket (AF_INET6, SOCK_DGRAM, 0); /* UDP */
- if (gdm_xdmcpfd < 0)
-#endif
- gdm_xdmcpfd = socket (AF_INET, SOCK_DGRAM, 0); /* UDP */
-
- if G_UNLIKELY (gdm_xdmcpfd < 0) {
- gdm_error (_("%s: Could not create socket!"), "gdm_xdmcp_init");
- gdm_set_value_bool (GDM_KEY_XDMCP, FALSE);
- return FALSE;
- }
-
-#ifdef ENABLE_IPV6
- if (have_ipv6 ()) {
- ((struct sockaddr_in6 *)(&serv_sa))->sin6_family = AF_INET6;
- ((struct sockaddr_in6 *)(&serv_sa))->sin6_port = htons (udpport); /* UDP 177 */
- ((struct sockaddr_in6 *)(&serv_sa))->sin6_addr = in6addr_any;
- addrlen = sizeof (struct sockaddr_in6);
-
- /* Checking and Setting Multicast options */
- if (gdm_get_value_bool (GDM_KEY_MULTICAST)) {
- int socktemp; /* temporary socket for getting info about available interfaces*/
- int i, num;
- char *buf;
- struct ipv6_mreq mreq;
-
- /* For interfaces' list */
- struct ifconf ifc;
- struct ifreq *ifr;
-
- /* Extract Multicast address for IPv6 */
- if (ve_string_empty (gdm_get_value_string (GDM_KEY_MULTICAST_ADDR))) {
-
- /* Stuff it with all-node multicast address */
- gdm_set_value_string (GDM_KEY_MULTICAST_ADDR, XDMCP_MULTICAST_ADDRESS);
- }
-
- socktemp = socket (AF_INET, SOCK_DGRAM, 0);
-#ifdef SIOCGIFNUM
- if (ioctl (socktemp, SIOCGIFNUM, &num) < 0) {
- num = 64;
- }
-#else
- num = 64;
-#endif
- ifc.ifc_len = sizeof (struct ifreq) * num;
- ifc.ifc_buf = buf = malloc (ifc.ifc_len);
- if (ioctl (socktemp, SIOCGIFCONF, &ifc) >= 0) {
- ifr = ifc.ifc_req;
- num = ifc.ifc_len / sizeof (struct ifreq); /* No of interfaces */
-
- /* Joining multicast group with all interfaces*/
- for (i = 0 ; i < num ; i++) {
- struct ifreq ifreq;
- int ifindex;
-
- memset (&ifreq, 0, sizeof (ifreq));
- strncpy (ifreq.ifr_name, ifr[i].ifr_name, sizeof (ifreq.ifr_name));
- /* paranoia */
- ifreq.ifr_name[sizeof (ifreq.ifr_name) - 1] = '\0';
-
- if (ioctl (socktemp, SIOCGIFFLAGS, &ifreq) < 0)
- gdm_debug ("XDMCP: Could not get SIOCGIFFLAGS for %s", ifr[i].ifr_name);
-
- ifindex = if_nametoindex (ifr[i].ifr_name);
-
- if ((!(ifreq.ifr_flags & IFF_UP) ||
- (ifreq.ifr_flags & IFF_LOOPBACK)) ||
- ((ifindex == 0 ) && (errno == ENXIO))) {
- /* Not a valid interface or loopback interface*/
- continue;
- }
-
- mreq.ipv6mr_interface = ifindex;
- inet_pton (AF_INET6, gdm_get_value_string (GDM_KEY_MULTICAST_ADDR), &mreq.ipv6mr_multiaddr);
- setsockopt (gdm_xdmcpfd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof (mreq));
- }
- }
- g_free (buf);
- close (socktemp);
- }
- }
- else
-#endif
- {
- ((struct sockaddr_in *)(&serv_sa))->sin_family = AF_INET;
- ((struct sockaddr_in *)(&serv_sa))->sin_port = htons (udpport); /* UDP 177 */
- ((struct sockaddr_in *)(&serv_sa))->sin_addr.s_addr = htonl (INADDR_ANY);
- addrlen = sizeof (struct sockaddr_in);
- }
-
- if G_UNLIKELY (bind (gdm_xdmcpfd, (struct sockaddr*) &serv_sa, addrlen) == -1) {
- gdm_error (_("%s: Could not bind to XDMCP socket!"), "gdm_xdmcp_init");
- gdm_xdmcp_close ();
- gdm_set_value_bool (GDM_KEY_XDMCP, FALSE);
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-void
-gdm_xdmcp_run (void)
-{
- GIOChannel *xdmcpchan;
-
- xdmcpchan = g_io_channel_unix_new (gdm_xdmcpfd);
- g_io_channel_set_encoding (xdmcpchan, NULL, NULL);
- g_io_channel_set_buffered (xdmcpchan, FALSE);
-
- xdmcp_source = g_io_add_watch_full
- (xdmcpchan, G_PRIORITY_DEFAULT,
- G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL,
- gdm_xdmcp_decode_packet, NULL, NULL);
- g_io_channel_unref (xdmcpchan);
-}
-
-
-void
-gdm_xdmcp_close (void)
-{
- if (xdmcp_source > 0) {
- g_source_remove (xdmcp_source);
- xdmcp_source = 0;
- }
-
- if (gdm_xdmcpfd > 0) {
- VE_IGNORE_EINTR (close (gdm_xdmcpfd));
- gdm_xdmcpfd = -1;
- }
-}
-
-
-static gboolean
-gdm_xdmcp_decode_packet (GIOChannel *source, GIOCondition cond, gpointer data)
-{
-#ifdef ENABLE_IPV6
- struct sockaddr_storage clnt_sa;
-#else
- struct sockaddr_in clnt_sa;
-#endif
- gint sa_len = sizeof (clnt_sa);
- XdmcpHeader header;
- static const char * const opcode_names[] = {
- NULL,
- "BROADCAST_QUERY", "QUERY", "INDIRECT_QUERY", "FORWARD_QUERY",
- "WILLING", "UNWILLING", "REQUEST", "ACCEPT", "DECLINE", "MANAGE", "REFUSE",
- "FAILED", "KEEPALIVE", "ALIVE"
- };
- static const char * const gdm_opcode_names[] = {
- "MANAGED_FORWARD", "GOT_MANAGED_FORWARD"
- };
-
- /* packets come at somewhat random times */
- gdm_random_tick ();
-
- if (cond != G_IO_IN)
- gdm_debug ("gdm_xdmcp_decode_packet: GIOCondition %d", (int)cond);
-
- if ( ! (cond & G_IO_IN))
- return TRUE;
-
- if G_UNLIKELY (!XdmcpFill (gdm_xdmcpfd, &buf, (XdmcpNetaddr)&clnt_sa, &sa_len)) {
- gdm_debug (_("%s: Could not create XDMCP buffer!"),
- "gdm_xdmcp_decode_packet");
- return TRUE;
- }
-
- if G_UNLIKELY (!XdmcpReadHeader (&buf, &header)) {
- gdm_error (_("%s: Could not read XDMCP header!"),
- "gdm_xdmcp_decode_packet");
- return TRUE;
- }
-
- if G_UNLIKELY (header.version != XDM_PROTOCOL_VERSION &&
- header.version != GDM_XDMCP_PROTOCOL_VERSION) {
- gdm_error (_("%s: Incorrect XDMCP version!"),
- "gdm_xdmcp_decode_packet");
- return TRUE;
- }
-
- if (header.opcode <= ALIVE) {
-#ifdef ENABLE_IPV6
- if (clnt_sa.ss_family == AF_INET6) {
- char buffer6[INET6_ADDRSTRLEN];
-
- gdm_debug ("gdm_xdmcp_decode: Received opcode %s from client %s", opcode_names[header.opcode], inet_ntop (AF_INET6, &((struct sockaddr_in6 *)(&clnt_sa))->sin6_addr, buffer6, INET6_ADDRSTRLEN));
- }
- else
-#endif
- {
- gdm_debug ("gdm_xdmcp_decode: Received opcode %s from client %s", opcode_names[header.opcode], inet_ntoa (((struct sockaddr_in *)(&clnt_sa))->sin_addr));
- }
- }
-
- if (header.opcode >= GDM_XDMCP_FIRST_OPCODE &&
- header.opcode < GDM_XDMCP_LAST_OPCODE) {
-#ifdef ENABLE_IPV6
- if (clnt_sa.ss_family == AF_INET6) {
-
- char buffer6[INET6_ADDRSTRLEN];
-
- gdm_debug ("gdm_xdmcp_decode: Received opcode %s from client %s", gdm_opcode_names[header.opcode - GDM_XDMCP_FIRST_OPCODE], inet_ntop (AF_INET6, &((struct sockaddr_in6 *)(&clnt_sa))->sin6_addr, buffer6, INET6_ADDRSTRLEN));
- }
- else
-#endif
- {
- char buffer[INET_ADDRSTRLEN];
-
- gdm_debug ("gdm_xdmcp_decode: Received opcode %s from client %s", gdm_opcode_names[header.opcode - GDM_XDMCP_FIRST_OPCODE], inet_ntop (AF_INET, &((struct sockaddr_in *)(&clnt_sa))->sin_addr, buffer, INET_ADDRSTRLEN));
- }
- }
-
- switch (header.opcode) {
-
- case BROADCAST_QUERY:
- gdm_xdmcp_handle_query (&clnt_sa, header.length, BROADCAST_QUERY);
- break;
-
- case QUERY:
- gdm_xdmcp_handle_query (&clnt_sa, header.length, QUERY);
- break;
-
- case INDIRECT_QUERY:
- gdm_xdmcp_handle_query (&clnt_sa, header.length, INDIRECT_QUERY);
- break;
-
- case FORWARD_QUERY:
- gdm_xdmcp_handle_forward_query (&clnt_sa, header.length);
- break;
-
- case REQUEST:
- gdm_xdmcp_handle_request (&clnt_sa, header.length);
- break;
-
- case MANAGE:
- gdm_xdmcp_handle_manage (&clnt_sa, header.length);
- break;
-
- case KEEPALIVE:
- gdm_xdmcp_handle_keepalive (&clnt_sa, header.length);
- break;
-
- case GDM_XDMCP_MANAGED_FORWARD:
- gdm_xdmcp_handle_managed_forward (&clnt_sa, header.length);
- break;
-
- case GDM_XDMCP_GOT_MANAGED_FORWARD:
- gdm_xdmcp_handle_got_managed_forward (&clnt_sa, header.length);
- break;
-
- default:
-#ifdef ENABLE_IPV6
- if (clnt_sa.ss_family == AF_INET6) {
- char buffer6[INET6_ADDRSTRLEN];
-
- gdm_error (_("%s: Unknown opcode from host %s"),
- "gdm_xdmcp_decode_packet",
- inet_ntop (AF_INET6, &(((struct sockaddr_in6 *)(&clnt_sa))->sin6_addr), buffer6, INET6_ADDRSTRLEN));
- }
- else
-#endif
- {
- gdm_error (_("%s: Unknown opcode from host %s"),
- "gdm_xdmcp_decode_packet",
- inet_ntoa (((struct sockaddr_in *)(&clnt_sa))->sin_addr));
- }
- break;
- }
-
- return TRUE;
-}
-
-static void
-#ifdef ENABLE_IPV6
-gdm_xdmcp_handle_query (struct sockaddr_storage *clnt_sa, gint len, gint type)
-#else
-gdm_xdmcp_handle_query (struct sockaddr_in *clnt_sa, gint len, gint type)
-#endif
-{
- ARRAYofARRAY8 clnt_authlist;
- gint i = 0, explen = 1;
-
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- char buffer6[INET6_ADDRSTRLEN];
-
- gdm_debug ("gdm_xdmcp_handle_query: Opcode %d from %s", type, inet_ntop (AF_INET6, &((struct sockaddr_in6 *)(clnt_sa))->sin6_addr, buffer6, INET6_ADDRSTRLEN));
- }
- else
-#endif
- {
- gdm_debug ("gdm_xdmcp_handle_query: Opcode %d from %s", type, inet_ntoa (((struct sockaddr_in *)(clnt_sa))->sin_addr));
- }
-
- /* Extract array of authentication names from Xdmcp packet */
- if G_UNLIKELY (! XdmcpReadARRAYofARRAY8 (&buf, &clnt_authlist)) {
- gdm_error (_("%s: Could not extract authlist from packet"),
- "gdm_xdmcp_handle_query");
- return;
- }
-
- /* Crude checksumming */
- for (i = 0 ; i < clnt_authlist.length ; i++) {
- if G_UNLIKELY (gdm_get_value_bool (GDM_KEY_DEBUG)) {
- char *s = g_strndup ((char *) clnt_authlist.data[i].data, clnt_authlist.length);
- gdm_debug ("gdm_xdmcp_handle_query: authlist: %s", ve_sure_string (s));
- g_free (s);
- }
- explen += 2+clnt_authlist.data[i].length;
- }
-
- if G_UNLIKELY (len != explen) {
- gdm_error (_("%s: Error in checksum"),
- "gdm_xdmcp_handle_query");
- XdmcpDisposeARRAYofARRAY8 (&clnt_authlist);
- return;
- }
-
- /* Check with tcp_wrappers if client is allowed to access */
- if (gdm_xdmcp_host_allow (clnt_sa)) {
-
- /* If this is an INDIRECT_QUERY, try to look up the display in
- * the pending list. If found send a FORWARD_QUERY to the
- * chosen manager. Otherwise alloc a new indirect display. */
-
- if (gdm_get_value_bool (GDM_KEY_INDIRECT) &&
- type == INDIRECT_QUERY) {
- GdmIndirectDisplay *id = gdm_choose_indirect_lookup (clnt_sa);
-
- if (id != NULL && (
-#ifdef ENABLE_IPV6
- (id->chosen_host6 != NULL) ||
-#endif
- (id->chosen_host != NULL)))
- {
- /* if user chose us, then just send willing */
- if ((((struct sockaddr_in *)clnt_sa)->sin_family == AF_INET && gdm_is_local_addr ((struct in_addr *)(id->chosen_host)))
-#ifdef ENABLE_IPV6
- || (clnt_sa->ss_family == AF_INET6 && gdm_is_local_addr6 ((struct in6_addr *)(id->chosen_host6)))
-#endif
- ) {
-
- /* get rid of indirect, so that we don't get
- * the chooser */
- gdm_choose_indirect_dispose (id);
- gdm_xdmcp_send_willing (clnt_sa);
- }
- else
- if ((((struct sockaddr_in *)clnt_sa)->sin_family == AF_INET && gdm_is_loopback_addr (&(((struct sockaddr_in *)clnt_sa)->sin_addr)))
-#ifdef ENABLE_IPV6
- || (clnt_sa->ss_family == AF_INET6 && gdm_is_loopback_addr6 (&(((struct sockaddr_in6 *)clnt_sa)->sin6_addr)))
-#endif
- ) {
-
- /* woohoo! fun, I have no clue how to get
- * the correct ip, SO I just send forward
- * queries with all the different IPs */
- const GList *list = gdm_peek_local_address_list ();
-
- while (list != NULL) {
- struct sockaddr *saddr = (struct sockaddr *)(list->data);
-#ifdef ENABLE_IPV6
- struct in6_addr *addr6;
-#endif
- struct in_addr *addr;
-
-#ifdef ENABLE_IPV6
- if (saddr->sa_family == AF_INET6) {
- addr6 = &(((struct sockaddr_in6 *)saddr)->sin6_addr);
- if ( ! gdm_is_loopback_addr6 (addr6)) {
- /* forward query to * chosen host */
- gdm_xdmcp_send_forward_query6 (id, (struct sockaddr_in6 *)clnt_sa, addr6, &clnt_authlist);
- }
- }
- else
-#endif
- {
- addr = &(((struct sockaddr_in *)saddr)->sin_addr);
- if ( ! gdm_is_loopback_addr (addr)) {
- /* forward query to * chosen host */
- gdm_xdmcp_send_forward_query (id, (struct sockaddr_in *)clnt_sa, addr, &clnt_authlist);
- }
-
- }
-
- list = list->next;
- }
- } else {
- /* or send forward query to chosen host */
- gdm_xdmcp_send_forward_query
- (id, (struct sockaddr_in *)clnt_sa,
- &(((struct sockaddr_in *)clnt_sa)->sin_addr),
- &clnt_authlist);
- }
- } else if (id == NULL) {
- id = gdm_choose_indirect_alloc (clnt_sa);
- if (id != NULL) {
- gdm_xdmcp_send_willing (clnt_sa);
- }
- } else {
- gdm_xdmcp_send_willing (clnt_sa);
- }
- } else {
- gdm_xdmcp_send_willing (clnt_sa);
- }
- } else if (type == QUERY) {
- /* unwilling is ONLY sent for direct queries, never for broadcast
- * nor indirects */
- gdm_xdmcp_send_unwilling (clnt_sa, type);
- }
-
- /* Dispose authlist from remote display */
- XdmcpDisposeARRAYofARRAY8 (&clnt_authlist);
-}
-
-#ifdef ENABLE_IPV6
-static void
-gdm_xdmcp_send_forward_query6 (GdmIndirectDisplay *id, struct sockaddr_in6 *clnt_sa, struct in6_addr *display_addr, ARRAYofARRAY8Ptr authlist)
-{
- struct sockaddr_in6 sock = {0};
- XdmcpHeader header;
- int i, authlen;
- ARRAY8 address;
- ARRAY8 port;
- char buffer6[INET6_ADDRSTRLEN];
-
- g_assert (id != NULL);
- g_assert (id->chosen_host != NULL);
-
- gdm_debug ("gdm_xdmcp_send_forward_query6: Sending forward query to %s", inet_ntop (AF_INET6, &(id->chosen_host6), buffer6, sizeof (buffer6)));
- gdm_debug ("gdm_xdmcp_send_forward_query6: Query contains %s:%d", inet_ntop (AF_INET6, display_addr, buffer6, sizeof (buffer6)), (int) ntohs (clnt_sa->sin6_port));
-
- authlen = 1;
- for (i = 0 ; i < authlist->length ; i++) {
- authlen += 2 + authlist->data[i].length;
- }
-
- /* we depend on this being 2 elsewhere as well */
- port.length = 2;
- port.data = g_new (char, 2);
- memcpy (port.data, &(clnt_sa->sin6_port), 2);
- address.length = sizeof (struct in6_addr);
- address.data = (void *)g_new (struct in6_addr, 1);
- memcpy (address.data, display_addr, sizeof (struct in6_addr));
-
-
- header.opcode = (CARD16) FORWARD_QUERY;
- header.length = authlen;
- header.length += 2 + address.length;
- header.length += 2 + port.length;
- header.version = XDM_PROTOCOL_VERSION;
- XdmcpWriteHeader (&buf, &header);
-
- XdmcpWriteARRAY8 (&buf, &address);
- XdmcpWriteARRAY8 (&buf, &port);
- XdmcpWriteARRAYofARRAY8 (&buf, authlist);
-
- memset (&sock, 0, sizeof (sock));
-
- sock.sin6_family = AF_INET6;
- sock.sin6_port = htons (XDM_UDP_PORT);
- memcpy (sock.sin6_addr.s6_addr, id->chosen_host6->s6_addr, sizeof (struct in6_addr));
- XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr) &sock, (int)sizeof (struct sockaddr_in6));
- g_free (port.data);
- g_free (address.data);
-}
-#endif
-
-static void
-gdm_xdmcp_send_forward_query (GdmIndirectDisplay *id,
- struct sockaddr_in *clnt_sa,
- struct in_addr *display_addr,
- ARRAYofARRAY8Ptr authlist)
-{
- struct sockaddr_in sock = {0};
- XdmcpHeader header;
- int i, authlen;
- ARRAY8 address;
- ARRAY8 port;
-
- gdm_assert (id != NULL);
- gdm_assert (id->chosen_host != NULL);
-
- gdm_debug ("gdm_xdmcp_send_forward_query: Sending forward query to %s",
- inet_ntoa (*id->chosen_host));
- gdm_debug ("gdm_xdmcp_send_forward_query: Query contains %s:%d",
- inet_ntoa (*display_addr),
- (int) ntohs (clnt_sa->sin_port));
-
- authlen = 1;
- for (i = 0 ; i < authlist->length ; i++) {
- authlen += 2 + authlist->data[i].length;
- }
-
- /* we depend on this being 2 elsewhere as well */
- port.length = 2;
- port.data = (CARD8 *) g_new (char, 2);
- memcpy (port.data, &(clnt_sa->sin_port), 2);
-
- address.length = sizeof (struct in_addr);
- address.data = (void *)g_new (struct in_addr, 1);
- memcpy (address.data, display_addr, sizeof (struct in_addr));
-
- header.opcode = (CARD16) FORWARD_QUERY;
- header.length = authlen;
- header.length += 2 + address.length;
- header.length += 2 + port.length;
- header.version = XDM_PROTOCOL_VERSION;
- XdmcpWriteHeader (&buf, &header);
-
- XdmcpWriteARRAY8 (&buf, &address);
- XdmcpWriteARRAY8 (&buf, &port);
- XdmcpWriteARRAYofARRAY8 (&buf, authlist);
-
- sock.sin_family = AF_INET;
- sock.sin_port = htons (XDM_UDP_PORT);
- sock.sin_addr.s_addr = id->chosen_host->s_addr;
- XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr) &sock,
- (int)sizeof (struct sockaddr_in));
-
- g_free (port.data);
- g_free (address.data);
-}
-
-static gboolean
-remove_oldest_forward (void)
-{
- GSList *li;
- GdmForwardQuery *oldest = NULL;
-
- for (li = forward_queries; li != NULL; li = li->next) {
- GdmForwardQuery *query = li->data;
-
- if (oldest == NULL ||
- query->acctime < oldest->acctime) {
- oldest = query;
- }
- }
-
- if (oldest != NULL) {
- gdm_forward_query_dispose (oldest);
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-static GdmForwardQuery *
-#ifdef ENABLE_IPV6
-gdm_forward_query_alloc (struct sockaddr_storage *mgr_sa,
- struct sockaddr_storage *dsp_sa)
-#else
-gdm_forward_query_alloc (struct sockaddr_in *mgr_sa,
- struct sockaddr_in *dsp_sa)
-#endif
-{
- GdmForwardQuery *q;
- int count;
-
- count = g_slist_length (forward_queries);
-
- while (count > GDM_MAX_FORWARD_QUERIES &&
- remove_oldest_forward ())
- count --;
-
- q = g_new0 (GdmForwardQuery, 1);
-#ifdef ENABLE_IPV6
- q->dsp_sa = g_new0 (struct sockaddr_storage, 1);
- memcpy (q->dsp_sa, dsp_sa, sizeof (struct sockaddr_storage));
- q->from_sa = g_new0 (struct sockaddr_storage, 1);
- memcpy (q->from_sa, mgr_sa, sizeof (struct sockaddr_storage));
-#else
- q->dsp_sa = g_new0 (struct sockaddr_in, 1);
- memcpy (q->dsp_sa, dsp_sa, sizeof (struct sockaddr_in));
- q->from_sa = g_new0 (struct sockaddr_in, 1);
- memcpy (q->from_sa, mgr_sa, sizeof (struct sockaddr_in));
-#endif
-
- forward_queries = g_slist_prepend (forward_queries, q);
-
- return q;
-}
-
-static GdmForwardQuery *
-#ifdef ENABLE_IPV6
-gdm_forward_query_lookup (struct sockaddr_storage *clnt_sa)
-#else
-gdm_forward_query_lookup (struct sockaddr_in *clnt_sa)
-#endif
-{
- GSList *li, *qlist;
- GdmForwardQuery *q;
- time_t curtime = time (NULL);
-
- qlist = g_slist_copy (forward_queries);
-
- for (li = qlist; li != NULL; li = li->next) {
- q = (GdmForwardQuery *) li->data;
- if (q == NULL)
- continue;
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- if (memcmp (((struct sockaddr_in6 *)(q->dsp_sa))->sin6_addr.s6_addr, ((struct sockaddr_in6 *)clnt_sa)->sin6_addr.s6_addr, sizeof (struct in6_addr)) == 0) {
- g_slist_free (qlist);
- return q;
- }
-
- if (q->acctime > 0 && curtime > q->acctime + GDM_FORWARD_QUERY_TIMEOUT) {
- char buffer6[INET6_ADDRSTRLEN];
-
- gdm_debug ("gdm_forward_query_lookup: Disposing stale forward query from %s", inet_ntop (AF_INET6, &((struct sockaddr_in6 *)q->dsp_sa)->sin6_addr, buffer6, INET6_ADDRSTRLEN));
- gdm_forward_query_dispose (q);
- continue;
- }
- }
- else
-#endif
- {
- if (((struct sockaddr_in *)(q->dsp_sa))->sin_addr.s_addr == ((struct sockaddr_in *)clnt_sa)->sin_addr.s_addr) {
- g_slist_free (qlist);
- return q;
- }
-
- if (q->acctime > 0 &&
- curtime > q->acctime + GDM_FORWARD_QUERY_TIMEOUT) {
- gdm_debug ("gdm_forward_query_lookup: Disposing stale forward query from %s",
- inet_ntoa (((struct sockaddr_in*)q->dsp_sa)->sin_addr));
- gdm_forward_query_dispose (q);
- continue;
- }
- }
-
- }
- g_slist_free (qlist);
-
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- char buffer6[INET6_ADDRSTRLEN];
-
- gdm_debug ("gdm_forward_query_lookup: Host %s not found", inet_ntop (AF_INET6, &((struct sockaddr_in6 *)clnt_sa)->sin6_addr, buffer6, INET6_ADDRSTRLEN));
- }
- else
-#endif
- {
- gdm_debug ("gdm_forward_query_lookup: Host %s not found",
- inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr));
- }
-
- return NULL;
-}
-
-
-static void
-gdm_forward_query_dispose (GdmForwardQuery *q)
-{
- if (q == NULL)
- return;
-
- forward_queries = g_slist_remove (forward_queries, q);
-
- q->acctime = 0;
-
-#ifdef ENABLE_IPV6
- if (q->dsp_sa->ss_family == AF_INET6) {
- char buffer6[INET6_ADDRSTRLEN];
-
- gdm_debug ("gdm_forward_query_dispose: Disposing %s", inet_ntop (AF_INET6, &(((struct sockaddr_in6 *)(q->dsp_sa))->sin6_addr), buffer6, INET6_ADDRSTRLEN));
- }
- else
-#endif
- {
- gdm_debug ("gdm_forward_query_dispose: Disposing %s",
- inet_ntoa (((struct sockaddr_in *)(q->dsp_sa))->sin_addr));
- }
-
- g_free (q->dsp_sa);
- q->dsp_sa = NULL;
- g_free (q->from_sa);
- q->from_sa = NULL;
-
- g_free (q);
-}
-
-
-static void
-#ifdef ENABLE_IPV6
-gdm_xdmcp_handle_forward_query (struct sockaddr_storage *clnt_sa, gint len)
-#else
-gdm_xdmcp_handle_forward_query (struct sockaddr_in *clnt_sa, gint len)
-#endif
-{
- ARRAY8 clnt_addr;
- ARRAY8 clnt_port;
- ARRAYofARRAY8 clnt_authlist;
- gint i = 0, explen = 1;
-#ifdef ENABLE_IPV6
- struct sockaddr_storage disp_sa = {0};
-#else
- struct sockaddr_in disp_sa = {0};
-#endif
-
- /* Check with tcp_wrappers if client is allowed to access */
- if (! gdm_xdmcp_host_allow (clnt_sa)) {
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- char buffer6[INET6_ADDRSTRLEN];
-
- gdm_error ("%s: Got FORWARD_QUERY from banned host %s",
- "gdm_xdmcp_handle_forward query",
- inet_ntop (AF_INET6, &(((struct sockaddr_in6 *)clnt_sa)->sin6_addr), buffer6, INET6_ADDRSTRLEN));
- }
- else
-#endif
- {
- gdm_error ("%s: Got FORWARD_QUERY from banned host %s",
- "gdm_xdmcp_handle_forward query",
- inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr));
- }
-
- return;
- }
-
- /* Read display address */
- if G_UNLIKELY (! XdmcpReadARRAY8 (&buf, &clnt_addr)) {
- gdm_error (_("%s: Could not read display address"),
- "gdm_xdmcp_handle_forward_query");
- return;
- }
-
- /* Read display port */
- if G_UNLIKELY (! XdmcpReadARRAY8 (&buf, &clnt_port)) {
- XdmcpDisposeARRAY8 (&clnt_addr);
- gdm_error (_("%s: Could not read display port number"),
- "gdm_xdmcp_handle_forward_query");
- return;
- }
-
- /* Extract array of authentication names from Xdmcp packet */
- if G_UNLIKELY (! XdmcpReadARRAYofARRAY8 (&buf, &clnt_authlist)) {
- XdmcpDisposeARRAY8 (&clnt_addr);
- XdmcpDisposeARRAY8 (&clnt_port);
- gdm_error (_("%s: Could not extract authlist from packet"),
- "gdm_xdmcp_handle_forward_query");
- return;
- }
-
- /* Crude checksumming */
- explen = 1;
- explen += 2+clnt_addr.length;
- explen += 2+clnt_port.length;
-
- for (i = 0 ; i < clnt_authlist.length ; i++) {
- if G_UNLIKELY (gdm_get_value_bool (GDM_KEY_DEBUG)) {
- char *s = g_strndup ((char *) clnt_authlist.data[i].data, clnt_authlist.length);
- gdm_debug ("gdm_xdmcp_handle_forward_query: authlist: %s", ve_sure_string (s));
- g_free (s);
- }
- explen += 2+clnt_authlist.data[i].length;
- }
-
- if G_UNLIKELY (len != explen) {
- gdm_error (_("%s: Error in checksum"),
- "gdm_xdmcp_handle_forward_query");
- goto out;
- }
-
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- char buffer6[INET6_ADDRSTRLEN];
-
- struct in6_addr ipv6_addr;
- struct in6_addr * ipv6_addr_ptr = NULL;
-
- if (clnt_port.length == 2 &&
- clnt_addr.length == 4) {
- char * ipv4_addr;
-
- /* Convert IPv4 address to IPv6 if needed */
- struct sockaddr_in tmp_disp_sa = {0};
- ((struct sockaddr_in *)(&tmp_disp_sa))->sin_family = AF_INET;
- memcpy (&((struct sockaddr_in *)(&tmp_disp_sa))->sin_port, clnt_port.data, 2);
- memcpy (&((struct sockaddr_in *)(&tmp_disp_sa))->sin_addr.s_addr, clnt_addr.data, 4);
-
- ipv4_addr = inet_ntoa (((struct sockaddr_in *)(&tmp_disp_sa))->sin_addr);
- strcpy (buffer6, "::ffff:");
- strncat (buffer6, ipv4_addr, INET_ADDRSTRLEN);
-
- inet_pton (AF_INET6, buffer6, &ipv6_addr);
- ipv6_addr_ptr = &ipv6_addr;
-
- } else if (clnt_port.length == 2 &&
- clnt_addr.length == 16) {
-
- ipv6_addr_ptr = (struct in6_addr *)clnt_addr.data;
-
- } else {
-
- gdm_error (_("%s: Bad address"),
- "gdm_xdmcp_handle_forward_query");
- goto out;
- }
-
- g_assert (16 == sizeof (struct in6_addr));
-
- gdm_xdmcp_whack_queued_managed_forwards6 ((struct sockaddr_in6 *)clnt_sa, ipv6_addr_ptr);
-
- ((struct sockaddr_in6 *)(&disp_sa))->sin6_family = AF_INET6;
-
- /* Find client port number */
- memcpy (&((struct sockaddr_in6 *)(&disp_sa))->sin6_port, clnt_port.data, 2);
-
- /* Find client address */
- memcpy (&((struct sockaddr_in6 *)(&disp_sa))->sin6_addr.s6_addr, ipv6_addr_ptr, 16);
-
- gdm_debug ("gdm_xdmcp_handle_forward_query: Got FORWARD_QUERY for display: %s, port %d", inet_ntop (AF_INET6, &((struct sockaddr_in6 *)(&disp_sa))->sin6_addr, buffer6, INET6_ADDRSTRLEN), ntohs (((struct sockaddr_in6 *)(&disp_sa))->sin6_port));
- }
- else
-#endif
- {
- if (clnt_port.length != 2 ||
- clnt_addr.length != 4) {
- gdm_error (_("%s: Bad address"),
- "gdm_xdmcp_handle_forward_query");
- goto out;
- }
-
- g_assert (4 == sizeof (struct in_addr));
- gdm_xdmcp_whack_queued_managed_forwards ((struct sockaddr_in *)clnt_sa, (struct in_addr *)clnt_addr.data);
- ((struct sockaddr_in *)(&disp_sa))->sin_family = AF_INET;
- /* Find client port number */
- memcpy (&((struct sockaddr_in *)(&disp_sa))->sin_port, clnt_port.data, 2);
- /* Find client address */
- memcpy (&((struct sockaddr_in *)(&disp_sa))->sin_addr.s_addr, clnt_addr.data, 4);
- gdm_debug ("gdm_xdmcp_handle_forward_query: Got FORWARD_QUERY for display: %s, port %d", inet_ntoa (((struct sockaddr_in *)(&disp_sa))->sin_addr), ntohs (((struct sockaddr_in *)(&disp_sa))->sin_port));
- }
-
-
-
-
-
- /* Check with tcp_wrappers if display is allowed to access */
- if (gdm_xdmcp_host_allow (&disp_sa)) {
- GdmForwardQuery *q;
-
- q = gdm_forward_query_lookup (&disp_sa);
- if (q != NULL)
- gdm_forward_query_dispose (q);
- gdm_forward_query_alloc (clnt_sa, &disp_sa);
-
- gdm_xdmcp_send_willing (&disp_sa);
- }
-
- out:
- /* Cleanup */
- XdmcpDisposeARRAYofARRAY8 (&clnt_authlist);
- XdmcpDisposeARRAY8 (&clnt_port);
- XdmcpDisposeARRAY8 (&clnt_addr);
-}
-
-
-static void
-#ifdef ENABLE_IPV6
-gdm_xdmcp_send_willing (struct sockaddr_storage *clnt_sa)
-#else
-gdm_xdmcp_send_willing (struct sockaddr_in *clnt_sa)
-#endif
-{
- ARRAY8 status;
- XdmcpHeader header;
- static char *last_status = NULL;
- static time_t last_willing = 0;
- char *bin;
- FILE *fd;
- char *willing = gdm_get_value_string (GDM_KEY_WILLING);
- int dispperhost = gdm_get_value_int (GDM_KEY_DISPLAYS_PER_HOST);
-
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- char buffer6[INET6_ADDRSTRLEN];
-
- gdm_debug ("gdm_xdmcp_send_willing: Sending WILLING to %s", inet_ntop (AF_INET6, &(((struct sockaddr_in6 *)clnt_sa)->sin6_addr), buffer6, INET6_ADDRSTRLEN));
- }
- else
-#endif
- {
- gdm_debug ("gdm_xdmcp_send_willing: Sending WILLING to %s", inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr));
- }
-
- if (last_willing == 0 ||
- time (NULL) - 3 > last_willing) {
- char statusBuf[256] = "";
- bin = ve_first_word (willing);
- if ( ! ve_string_empty (bin) &&
- g_access (bin, X_OK) == 0 &&
- (fd = popen (willing, "r")) != NULL) {
- if (fgets (statusBuf, sizeof (statusBuf), fd) != NULL &&
- ! ve_string_empty (g_strstrip (statusBuf))) {
- g_free (last_status);
- last_status = g_strdup (statusBuf);
- } else {
- g_free (last_status);
- last_status = g_strdup (sysid);
- }
- pclose (fd);
- } else {
- g_free (last_status);
- last_status = g_strdup (sysid);
- }
- last_willing = time (NULL);
- g_free (bin);
- }
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- if ( ! gdm_is_local_addr6 (&(((struct sockaddr_in6 *)clnt_sa)->sin6_addr)) &&
- gdm_xdmcp_displays_from_host (clnt_sa) >= dispperhost) {
- /* Don't translate, this goes over the wire to servers where we
- * don't know the charset or language, so it must be ascii */
- status.data = (CARD8 *) g_strdup_printf ("%s (Server is busy)", last_status);
- } else {
- status.data = (CARD8 *) g_strdup (last_status);
- }
- }
- else
-#endif
- {
- if ( ! gdm_is_local_addr (&(((struct sockaddr_in *)clnt_sa)->sin_addr)) &&
- gdm_xdmcp_displays_from_host (clnt_sa) >= dispperhost) {
- /* Don't translate, this goes over the wire to servers where we
- * don't know the charset or language, so it must be ascii */
- status.data = (CARD8 *) g_strdup_printf ("%s (Server is busy)", last_status);
- } else {
- status.data = (CARD8 *) g_strdup (last_status);
- }
- }
-
- status.length = strlen ((char *) status.data);
-
- header.opcode = (CARD16) WILLING;
- header.length = 6 + serv_authlist.authentication.length;
- header.length += servhost.length + status.length;
- header.version = XDM_PROTOCOL_VERSION;
- XdmcpWriteHeader (&buf, &header);
-
- XdmcpWriteARRAY8 (&buf, &serv_authlist.authentication); /* Hardcoded authentication */
- XdmcpWriteARRAY8 (&buf, &servhost);
- XdmcpWriteARRAY8 (&buf, &status);
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa, (int)sizeof (struct sockaddr_in6));
- }
- else
-#endif
- {
- XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa, (int)sizeof (struct sockaddr_in));
- }
-
- g_free (status.data);
-}
-
-static void
-#ifdef ENABLE_IPV6
-gdm_xdmcp_send_unwilling (struct sockaddr_storage *clnt_sa, gint type)
-#else
-gdm_xdmcp_send_unwilling (struct sockaddr_in *clnt_sa, gint type)
-#endif
-{
- ARRAY8 status;
- XdmcpHeader header;
- static time_t last_time = 0;
-
- /* only send at most one packet per second,
- no harm done if we don't send it at all */
- if (last_time + 1 >= time (NULL))
- return;
-
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- char buffer6[INET6_ADDRSTRLEN];
-
- gdm_debug ("gdm_xdmcp_send_unwilling: Sending UNWILLING to %s", inet_ntop (AF_INET6, &(((struct sockaddr_in6 *)clnt_sa)->sin6_addr), buffer6, INET6_ADDRSTRLEN));
- gdm_error (_("Denied XDMCP query from host %s"), buffer6);
- }
- else
-#endif
- {
- gdm_debug ("gdm_xdmcp_send_unwilling: Sending UNWILLING to %s", inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr));
-
- gdm_error (_("Denied XDMCP query from host %s"), inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr));
- }
-
- /* Don't translate, this goes over the wire to servers where we
- * don't know the charset or language, so it must be ascii */
- status.data = (CARD8 *) "Display not authorized to connect";
- status.length = strlen ((char *) status.data);
-
- header.opcode = (CARD16) UNWILLING;
- header.length = 4 + servhost.length + status.length;
- header.version = XDM_PROTOCOL_VERSION;
- XdmcpWriteHeader (&buf, &header);
-
- XdmcpWriteARRAY8 (&buf, &servhost);
- XdmcpWriteARRAY8 (&buf, &status);
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa, (int)sizeof (struct sockaddr_in6));
- }
- else
-#endif
- {
- XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa, (int)sizeof (struct sockaddr_in));
- }
-
- last_time = time (NULL);
-}
-
-static void
-#ifdef ENABLE_IPV6
-gdm_xdmcp_really_send_managed_forward (struct sockaddr_storage *clnt_sa,
- struct sockaddr_storage *origin)
-#else
-gdm_xdmcp_really_send_managed_forward (struct sockaddr_in *clnt_sa,
- struct sockaddr_in *origin)
-#endif
-{
- ARRAY8 address;
- XdmcpHeader header;
- struct in_addr addr;
-
-#ifdef ENABLE_IPV6
- struct in6_addr addr6;
-
- if (clnt_sa->ss_family == AF_INET6) {
- char buffer6[INET6_ADDRSTRLEN];
-
- gdm_debug ("gdm_xdmcp_really_send_managed_forward: "
- "Sending MANAGED_FORWARD to %s",
- inet_ntop (AF_INET6, &(((struct sockaddr_in6 *)clnt_sa)->sin6_addr), buffer6, INET6_ADDRSTRLEN));
-
- address.length = sizeof (struct in6_addr);
- address.data = (void *)&addr6;
- memcpy (address.data, &(((struct sockaddr_in6 *)origin)->sin6_addr), sizeof (struct in6_addr));
- }
- else
-#endif
- {
- gdm_debug ("gdm_xdmcp_really_send_managed_forward: "
- "Sending MANAGED_FORWARD to %s",
- inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr));
-
- address.length = sizeof (struct in_addr);
- address.data = (void *)&addr;
- memcpy (address.data, &(((struct sockaddr_in *)origin)->sin_addr), sizeof (struct in_addr));
- }
-
- header.opcode = (CARD16) GDM_XDMCP_MANAGED_FORWARD;
- header.length = 4 + address.length;
- header.version = GDM_XDMCP_PROTOCOL_VERSION;
- XdmcpWriteHeader (&buf, &header);
-
- XdmcpWriteARRAY8 (&buf, &address);
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa, (int)sizeof (struct sockaddr_in6));
- }
- else
-#endif
- {
- XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa, (int)sizeof (struct sockaddr_in));
- }
-
-}
-
-static gboolean
-managed_forward_handler (gpointer data)
-{
- ManagedForward *mf = data;
- if (gdm_xdmcpfd > 0)
- gdm_xdmcp_really_send_managed_forward (&(mf->manager),
- &(mf->origin));
- mf->times++;
- if (gdm_xdmcpfd <= 0 || mf->times >= 2) {
- managed_forwards = g_slist_remove (managed_forwards, mf);
- mf->handler = 0;
- /* mf freed by glib */
- return FALSE;
- }
- return TRUE;
-}
-
-static void
-#ifdef ENABLE_IPV6
-gdm_xdmcp_send_managed_forward (struct sockaddr_storage *clnt_sa,
- struct sockaddr_storage *origin)
-#else
-gdm_xdmcp_send_managed_forward (struct sockaddr_in *clnt_sa,
- struct sockaddr_in *origin)
-#endif
-{
- ManagedForward *mf;
-
- gdm_xdmcp_really_send_managed_forward (clnt_sa, origin);
-
- mf = g_new0 (ManagedForward, 1);
- mf->times = 0;
-#ifdef ENABLE_IPV6
- memcpy (&(mf->manager), clnt_sa, sizeof (struct sockaddr_storage));
- memcpy (&(mf->origin), origin, sizeof (struct sockaddr_storage));
-#else
- memcpy (&(mf->manager), clnt_sa, sizeof (struct sockaddr_in));
- memcpy (&(mf->origin), origin, sizeof (struct sockaddr_in));
-#endif
-
- mf->handler = g_timeout_add_full (G_PRIORITY_DEFAULT,
- MANAGED_FORWARD_INTERVAL,
- managed_forward_handler,
- mf,
- (GDestroyNotify) g_free);
- managed_forwards = g_slist_prepend (managed_forwards, mf);
-}
-
-#ifdef ENABLE_IPV6
-static void
-gdm_xdmcp_send_got_managed_forward6 (struct sockaddr_in6 *clnt_sa,
- struct in6_addr *origin)
-{
- ARRAY8 address;
- XdmcpHeader header;
- struct in6_addr addr;
- char buffer6[INET6_ADDRSTRLEN];
-
- gdm_debug ("gdm_xdmcp_send_managed_forward: "
- "Sending GOT_MANAGED_FORWARD to %s",
- inet_ntop (AF_INET6, &clnt_sa->sin6_addr, buffer6, INET6_ADDRSTRLEN));
-
- address.length = sizeof (struct in6_addr);
- address.data = (void *)&addr;
- memcpy (address.data, origin, sizeof (struct in6_addr));
-
- header.opcode = (CARD16) GDM_XDMCP_GOT_MANAGED_FORWARD;
- header.length = 16 + address.length;
- header.version = GDM_XDMCP_PROTOCOL_VERSION;
- XdmcpWriteHeader (&buf, &header);
-
- XdmcpWriteARRAY8 (&buf, &address);
- XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa,
- (int)sizeof (struct sockaddr_in6));
-}
-#endif
-
-static void
-gdm_xdmcp_send_got_managed_forward (struct sockaddr_in *clnt_sa,
- struct in_addr *origin)
-{
- ARRAY8 address;
- XdmcpHeader header;
- struct in_addr addr;
-
- gdm_debug ("gdm_xdmcp_send_managed_forward: "
- "Sending GOT_MANAGED_FORWARD to %s",
- inet_ntoa (clnt_sa->sin_addr));
-
- address.length = sizeof (struct in_addr);
- address.data = (void *)&addr;
- memcpy (address.data, origin, sizeof (struct in_addr));
-
- header.opcode = (CARD16) GDM_XDMCP_GOT_MANAGED_FORWARD;
- header.length = 4 + address.length;
- header.version = GDM_XDMCP_PROTOCOL_VERSION;
- XdmcpWriteHeader (&buf, &header);
-
- XdmcpWriteARRAY8 (&buf, &address);
- XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa,
- (int)sizeof (struct sockaddr_in));
-}
-
-static void
-#ifdef ENABLE_IPV6
-gdm_xdmcp_handle_request (struct sockaddr_storage *clnt_sa, gint len)
-#else
-gdm_xdmcp_handle_request (struct sockaddr_in *clnt_sa, gint len)
-#endif
-{
- CARD16 clnt_dspnum;
- ARRAY16 clnt_conntyp;
- ARRAYofARRAY8 clnt_addr;
- ARRAY8 clnt_authname;
- ARRAY8 clnt_authdata;
- ARRAYofARRAY8 clnt_authorization;
- ARRAY8 clnt_manufacturer;
- gint explen;
- gint i;
- gboolean mitauth = FALSE;
- gboolean entered = FALSE;
- int maxsessions = gdm_get_value_int (GDM_KEY_MAX_SESSIONS);
- int maxpending = gdm_get_value_int (GDM_KEY_MAX_PENDING);
- int dispperhost = gdm_get_value_int (GDM_KEY_DISPLAYS_PER_HOST);
-
-#ifdef ENABLE_IPV6
- char buffer6[INET6_ADDRSTRLEN];
-
- inet_ntop (AF_INET6, &((struct sockaddr_in6 *)clnt_sa)->sin6_addr, buffer6, INET6_ADDRSTRLEN);
-
- if (clnt_sa->ss_family == AF_INET6) {
- gdm_debug ("gdm_xdmcp_handle_request: Got REQUEST from %s",buffer6);
- }
- else
-#endif
- {
- gdm_debug ("gdm_xdmcp_handle_request: Got REQUEST from %s",
- inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr));
- }
-
- /* Check with tcp_wrappers if client is allowed to access */
- if (! gdm_xdmcp_host_allow (clnt_sa)) {
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- gdm_error (_("%s: Got REQUEST from banned host %s"),
- "gdm_xdmcp_handle_request",
- inet_ntop (AF_INET6, &((struct sockaddr_in6 *)clnt_sa)->sin6_addr, buffer6, INET6_ADDRSTRLEN));
- }
- else
-#endif
- {
- gdm_error (_("%s: Got REQUEST from banned host %s"),
- "gdm_xdmcp_handle_request",
- inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr));
- }
-
- return;
- }
-
- gdm_xdmcp_displays_check (); /* Purge pending displays */
-
- /* Remote display number */
- if G_UNLIKELY (! XdmcpReadCARD16 (&buf, &clnt_dspnum)) {
- gdm_error (_("%s: Could not read Display Number"),
- "gdm_xdmcp_handle_request");
- return;
- }
-
- /* We don't care about connection type. Address says it all */
- if G_UNLIKELY (! XdmcpReadARRAY16 (&buf, &clnt_conntyp)) {
- gdm_error (_("%s: Could not read Connection Type"),
- "gdm_xdmcp_handle_request");
- return;
- }
-
- /* This is TCP/IP - we don't care */
- if G_UNLIKELY (! XdmcpReadARRAYofARRAY8 (&buf, &clnt_addr)) {
- gdm_error (_("%s: Could not read Client Address"),
- "gdm_xdmcp_handle_request");
- XdmcpDisposeARRAY16 (&clnt_conntyp);
- return;
- }
-
- /* Read authentication type */
- if G_UNLIKELY (! XdmcpReadARRAY8 (&buf, &clnt_authname)) {
- gdm_error (_("%s: Could not read Authentication Names"),
- "gdm_xdmcp_handle_request");
- XdmcpDisposeARRAYofARRAY8 (&clnt_addr);
- XdmcpDisposeARRAY16 (&clnt_conntyp);
- return;
- }
-
- /* Read authentication data */
- if G_UNLIKELY (! XdmcpReadARRAY8 (&buf, &clnt_authdata)) {
- gdm_error (_("%s: Could not read Authentication Data"),
- "gdm_xdmcp_handle_request");
- XdmcpDisposeARRAYofARRAY8 (&clnt_addr);
- XdmcpDisposeARRAY16 (&clnt_conntyp);
- XdmcpDisposeARRAY8 (&clnt_authname);
- return;
- }
-
- /* Read and select from supported authorization list */
- if G_UNLIKELY (! XdmcpReadARRAYofARRAY8 (&buf, &clnt_authorization)) {
- gdm_error (_("%s: Could not read Authorization List"),
- "gdm_xdmcp_handle_request");
- XdmcpDisposeARRAY8 (&clnt_authdata);
- XdmcpDisposeARRAYofARRAY8 (&clnt_addr);
- XdmcpDisposeARRAY16 (&clnt_conntyp);
- XdmcpDisposeARRAY8 (&clnt_authname);
- return;
- }
-
- /* libXdmcp doesn't terminate strings properly so we cheat and use strncmp () */
- for (i = 0 ; i < clnt_authorization.length ; i++)
- if (clnt_authorization.data[i].length == 18 &&
- strncmp ((char *) clnt_authorization.data[i].data, "MIT-MAGIC-COOKIE-1", 18) == 0)
- mitauth = TRUE;
-
- /* Manufacturer ID */
- if G_UNLIKELY (! XdmcpReadARRAY8 (&buf, &clnt_manufacturer)) {
- gdm_error (_("%s: Could not read Manufacturer ID"),
- "gdm_xdmcp_handle_request");
- XdmcpDisposeARRAY8 (&clnt_authname);
- XdmcpDisposeARRAY8 (&clnt_authdata);
- XdmcpDisposeARRAYofARRAY8 (&clnt_addr);
- XdmcpDisposeARRAYofARRAY8 (&clnt_authorization);
- XdmcpDisposeARRAY16 (&clnt_conntyp);
- return;
- }
-
- /* Crude checksumming */
- explen = 2; /* Display Number */
- explen += 1+2*clnt_conntyp.length; /* Connection Type */
- explen += 1; /* Connection Address */
- for (i = 0 ; i < clnt_addr.length ; i++)
- explen += 2+clnt_addr.data[i].length;
- explen += 2+clnt_authname.length; /* Authentication Name */
- explen += 2+clnt_authdata.length; /* Authentication Data */
- explen += 1; /* Authorization Names */
- for (i = 0 ; i < clnt_authorization.length ; i++)
- explen += 2+clnt_authorization.data[i].length;
- explen += 2+clnt_manufacturer.length;
-
- if G_UNLIKELY (explen != len) {
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- gdm_error (_("%s: Failed checksum from %s"),
- "gdm_xdmcp_handle_request",
- inet_ntop (AF_INET6, &((struct sockaddr_in6 *)clnt_sa)->sin6_addr, buffer6, INET6_ADDRSTRLEN));
- }
- else
-#endif
- {
- gdm_error (_("%s: Failed checksum from %s"),
- "gdm_xdmcp_handle_request",
- inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr));
- }
-
- XdmcpDisposeARRAY8 (&clnt_authname);
- XdmcpDisposeARRAY8 (&clnt_authdata);
- XdmcpDisposeARRAY8 (&clnt_manufacturer);
- XdmcpDisposeARRAYofARRAY8 (&clnt_addr);
- XdmcpDisposeARRAYofARRAY8 (&clnt_authorization);
- XdmcpDisposeARRAY16 (&clnt_conntyp);
- return;
- }
-
- if G_UNLIKELY (gdm_get_value_bool (GDM_KEY_DEBUG)) {
- char *s = g_strndup ((char *) clnt_manufacturer.data, clnt_manufacturer.length);
- gdm_debug ("gdm_xdmcp_handle_request: xdmcp_pending=%d, MaxPending=%d, xdmcp_sessions=%d, MaxSessions=%d, ManufacturerID=%s",
- xdmcp_pending, maxpending, xdmcp_sessions, maxsessions, ve_sure_string (s));
- g_free (s);
- }
-
- /* Check if ok to manage display */
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- if (mitauth &&
- xdmcp_sessions < maxsessions &&
- (gdm_is_local_addr6 (&((struct sockaddr_in6 *)clnt_sa)->sin6_addr) || gdm_xdmcp_displays_from_host (clnt_sa) < dispperhost))
-
- entered = TRUE;
- } else
-#endif
- {
- if (mitauth &&
- xdmcp_sessions < maxsessions &&
- (gdm_is_local_addr (&(((struct sockaddr_in *)clnt_sa)->sin_addr)) ||
- gdm_xdmcp_displays_from_host (clnt_sa) < dispperhost))
-
- entered = TRUE;
- }
-
- if (entered) {
- GdmHostent *he;
- he = gdm_gethostbyaddr (clnt_sa);
-
- /* Check if we are already talking to this host */
- gdm_xdmcp_display_dispose_check (he->hostname, clnt_dspnum);
-
- if (xdmcp_pending >= maxpending) {
- gdm_debug ("gdm_xdmcp_handle_request: maximum pending");
- /* Don't translate, this goes over the wire to servers where we
- * don't know the charset or language, so it must be ascii */
- gdm_xdmcp_send_decline (clnt_sa, "Maximum pending servers");
- gdm_hostent_free (he);
- } else {
- /* the addrs are NOT copied */
- gdm_xdmcp_send_accept (he /* eaten and freed */, clnt_sa, clnt_dspnum);
- }
- } else {
- /* Don't translate, this goes over the wire to servers where we
- * don't know the charset or language, so it must be ascii */
- if ( ! mitauth) {
- gdm_xdmcp_send_decline (clnt_sa, "Only MIT-MAGIC-COOKIE-1 supported");
- } else if (xdmcp_sessions >= maxsessions) {
- gdm_info ("Maximum number of open XDMCP sessions reached");
- gdm_xdmcp_send_decline (clnt_sa, "Maximum number of open sessions reached");
- } else {
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6)
- gdm_info ("Maximum number of open XDMCP sessions from host %s reached", buffer6);
- else
-#endif
- gdm_info ("Maximum number of open XDMCP sessions from host %s reached",
- inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr));
- gdm_xdmcp_send_decline (clnt_sa, "Maximum number of open sessions from your host reached");
- }
- }
-
- XdmcpDisposeARRAY8 (&clnt_authname);
- XdmcpDisposeARRAY8 (&clnt_authdata);
- XdmcpDisposeARRAY8 (&clnt_manufacturer);
- XdmcpDisposeARRAYofARRAY8 (&clnt_addr);
- XdmcpDisposeARRAYofARRAY8 (&clnt_authorization);
- XdmcpDisposeARRAY16 (&clnt_conntyp);
-}
-
-
-static void
-gdm_xdmcp_send_accept (GdmHostent *he /* eaten and freed */,
-#ifdef ENABLE_IPV6
- struct sockaddr_storage *clnt_sa,
-#else
- struct sockaddr_in *clnt_sa,
-#endif
- gint displaynum)
-{
- XdmcpHeader header;
- ARRAY8 authentype;
- ARRAY8 authendata;
- ARRAY8 authname;
- ARRAY8 authdata;
- GdmDisplay *d;
-
- d = gdm_xdmcp_display_alloc (clnt_sa,
- he /* eaten and freed */,
- displaynum);
-
- authentype.data = (CARD8 *) 0;
- authentype.length = (CARD16) 0;
-
- authendata.data = (CARD8 *) 0;
- authendata.length = (CARD16) 0;
-
- authname.data = (CARD8 *) "MIT-MAGIC-COOKIE-1";
- authname.length = strlen ((char *) authname.data);
-
- authdata.data = (CARD8 *) d->bcookie;
- authdata.length = 16;
-
- header.version = XDM_PROTOCOL_VERSION;
- header.opcode = (CARD16) ACCEPT;
- header.length = 4;
- header.length += 2 + authentype.length;
- header.length += 2 + authendata.length;
- header.length += 2 + authname.length;
- header.length += 2 + authdata.length;
-
- XdmcpWriteHeader (&buf, &header);
-
- XdmcpWriteCARD32 (&buf, d->sessionid);
- XdmcpWriteARRAY8 (&buf, &authentype);
- XdmcpWriteARRAY8 (&buf, &authendata);
- XdmcpWriteARRAY8 (&buf, &authname);
- XdmcpWriteARRAY8 (&buf, &authdata);
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- char buffer6[INET6_ADDRSTRLEN];
-
- XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa,
- (int)sizeof (struct sockaddr_in6));
-
- gdm_debug ("gdm_xdmcp_send_accept: Sending ACCEPT to %s with SessionID=%ld", inet_ntop (AF_INET6, &((struct sockaddr_in6 *)clnt_sa)->sin6_addr, buffer6, INET6_ADDRSTRLEN), (long)d->sessionid);
- }
- else
-#endif
- {
- XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa,
- (int)sizeof (struct sockaddr_in));
-
- gdm_debug ("gdm_xdmcp_send_accept: Sending ACCEPT to %s with SessionID=%ld",
- inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr), (long)d->sessionid);
- }
-
-}
-
-
-static void
-#ifdef ENABLE_IPV6
-gdm_xdmcp_send_decline (struct sockaddr_storage *clnt_sa, const char *reason)
-#else
-gdm_xdmcp_send_decline (struct sockaddr_in *clnt_sa, const char *reason)
-#endif
-{
- XdmcpHeader header;
- ARRAY8 authentype;
- ARRAY8 authendata;
- ARRAY8 status;
- GdmForwardQuery *fq;
-
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- char buffer6[INET6_ADDRSTRLEN];
-
- gdm_debug ("gdm_xdmcp_send_decline: Sending DECLINE to %s",
- inet_ntop (AF_INET6, &((struct sockaddr_in6 *)clnt_sa)->sin6_addr, buffer6, INET6_ADDRSTRLEN));
- }
- else
-#endif
- {
- gdm_debug ("gdm_xdmcp_send_decline: Sending DECLINE to %s",
- inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr));
- }
-
-
- authentype.data = (CARD8 *) 0;
- authentype.length = (CARD16) 0;
-
- authendata.data = (CARD8 *) 0;
- authendata.length = (CARD16) 0;
-
- status.data = (CARD8 *) reason;
- status.length = strlen ((char *) status.data);
-
- header.version = XDM_PROTOCOL_VERSION;
- header.opcode = (CARD16) DECLINE;
- header.length = 2 + status.length;
- header.length += 2 + authentype.length;
- header.length += 2 + authendata.length;
- XdmcpWriteHeader (&buf, &header);
-
- XdmcpWriteARRAY8 (&buf, &status);
- XdmcpWriteARRAY8 (&buf, &authentype);
- XdmcpWriteARRAY8 (&buf, &authendata);
-
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa,
- (int)sizeof (struct sockaddr_in6));
- }
- else
-#endif
- {
- XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa,
- (int)sizeof (struct sockaddr_in));
- }
-
- /* Send MANAGED_FORWARD to indicate that the connection
- * reached some sort of resolution */
- fq = gdm_forward_query_lookup (clnt_sa);
- if (fq != NULL) {
- gdm_xdmcp_send_managed_forward (fq->from_sa, clnt_sa);
- gdm_forward_query_dispose (fq);
- }
-}
-
-
-static void
-#ifdef ENABLE_IPV6
-gdm_xdmcp_handle_manage (struct sockaddr_storage *clnt_sa, gint len)
-#else
-gdm_xdmcp_handle_manage (struct sockaddr_in *clnt_sa, gint len)
-#endif
-{
- CARD32 clnt_sessid;
- CARD16 clnt_dspnum;
- ARRAY8 clnt_dspclass;
- GdmDisplay *d;
- GdmIndirectDisplay *id;
- GdmForwardQuery *fq;
-
-#ifdef ENABLE_IPV6
- char buffer6[INET6_ADDRSTRLEN];
-
- inet_ntop (AF_INET6, &((struct sockaddr_in6 *)clnt_sa)->sin6_addr, buffer6, INET6_ADDRSTRLEN);
-
- if (clnt_sa->ss_family == AF_INET6) {
- gdm_debug ("gdm_xdmcp_handle_manage: Got MANAGE from %s", buffer6);
- }
- else
-#endif
- {
- gdm_debug ("gdm_xdmcp_handle_manage: Got MANAGE from %s", inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr));
- }
-
-
- /* Check with tcp_wrappers if client is allowed to access */
- if (! gdm_xdmcp_host_allow (clnt_sa)) {
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- gdm_error (_("%s: Got Manage from banned host %s"),
- "gdm_xdmcp_handle_manage",
- buffer6);
- }
- else
-#endif
- {
- gdm_error (_("%s: Got Manage from banned host %s"),
- "gdm_xdmcp_handle_manage",
- inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr));
- }
-
- return;
- }
-
- /* SessionID */
- if G_UNLIKELY (! XdmcpReadCARD32 (&buf, &clnt_sessid)) {
- gdm_error (_("%s: Could not read Session ID"),
- "gdm_xdmcp_handle_manage");
- return;
- }
-
- /* Remote display number */
- if G_UNLIKELY (! XdmcpReadCARD16 (&buf, &clnt_dspnum)) {
- gdm_error (_("%s: Could not read Display Number"),
- "gdm_xdmcp_handle_manage");
- return;
- }
-
- /* Display Class */
- if G_UNLIKELY (! XdmcpReadARRAY8 (&buf, &clnt_dspclass)) {
- gdm_error (_("%s: Could not read Display Class"),
- "gdm_xdmcp_handle_manage");
- return;
- }
-
- if G_UNLIKELY (gdm_get_value_bool (GDM_KEY_DEBUG)) {
- char *s = g_strndup ((char *) clnt_dspclass.data, clnt_dspclass.length);
-
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6)
- gdm_debug ("gdm_xdmcp-handle_manage: Got display=%d, SessionID=%ld Class=%s from %s", (int)clnt_dspnum, (long)clnt_sessid, ve_sure_string (s), buffer6);
- else
-#endif
- gdm_debug ("gdm_xdmcp_handle_manage: Got Display=%d, SessionID=%ld Class=%s from %s",
- (int)clnt_dspnum, (long)clnt_sessid, ve_sure_string (s), inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr));
-
- g_free (s);
- }
-
-
- d = gdm_xdmcp_display_lookup (clnt_sessid);
- if (d != NULL &&
- d->dispstat == XDMCP_PENDING) {
-
- gdm_debug ("gdm_xdmcp_handle_manage: Looked up %s", d->name);
-
- if (gdm_get_value_bool (GDM_KEY_INDIRECT)) {
- id = gdm_choose_indirect_lookup (clnt_sa);
-
- /* This was an indirect thingie and nothing was yet chosen,
- * use a chooser */
- if (d->dispstat == XDMCP_PENDING &&
- id != NULL &&
- id->chosen_host == NULL) {
- d->use_chooser = TRUE;
- d->indirect_id = id->id;
- } else {
- d->indirect_id = 0;
- d->use_chooser = FALSE;
- if (id != NULL)
- gdm_choose_indirect_dispose (id);
- }
- } else {
- d->indirect_id = 0;
- d->use_chooser = FALSE;
- }
-
- /* this was from a forwarded query quite apparently so
- * send MANAGED_FORWARD */
- fq = gdm_forward_query_lookup (clnt_sa);
- if (fq != NULL) {
- gdm_xdmcp_send_managed_forward (fq->from_sa, clnt_sa);
- gdm_forward_query_dispose (fq);
- }
-
- d->dispstat = XDMCP_MANAGED;
- xdmcp_sessions++;
- xdmcp_pending--;
-
- /* Start greeter/session */
- if G_UNLIKELY (!gdm_display_manage (d)) {
- gdm_xdmcp_send_failed (clnt_sa, clnt_sessid);
- XdmcpDisposeARRAY8(&clnt_dspclass);
- return;
- }
- }
- else if G_UNLIKELY (d != NULL && d->dispstat == XDMCP_MANAGED) {
- gdm_debug ("gdm_xdmcp_handle_manage: Session id %ld already managed",
- (long)clnt_sessid);
- }
- else {
- gdm_debug ("gdm_xdmcp_handle_manage: Failed to look up session id %ld",
- (long)clnt_sessid);
- gdm_xdmcp_send_refuse (clnt_sa, clnt_sessid);
- }
-
- XdmcpDisposeARRAY8(&clnt_dspclass);
-}
-
-static void
-#ifdef ENABLE_IPV6
-gdm_xdmcp_handle_managed_forward (struct sockaddr_storage *clnt_sa, gint len)
-#else
-gdm_xdmcp_handle_managed_forward (struct sockaddr_in *clnt_sa, gint len)
-#endif
-{
- ARRAY8 clnt_address;
- GdmIndirectDisplay *id;
-#ifdef ENABLE_IPV6
- char buffer6[INET6_ADDRSTRLEN];
-
- inet_ntop (AF_INET6, &((struct sockaddr_in6 *)clnt_sa)->sin6_addr, buffer6, INET6_ADDRSTRLEN);
-
- if (clnt_sa->ss_family == AF_INET6) {
- gdm_debug ("gdm_xdmcp_handle_managed_forward: "
- "Got MANAGED_FORWARD from %s",
- buffer6);
- /* Check with tcp_wrappers if client is allowed to access */
- if (! gdm_xdmcp_host_allow (clnt_sa)) {
- gdm_error ("%s: Got MANAGED_FORWARD from banned host %s", "gdm_xdmcp_handle_request", buffer6);
- return;
- }
- }
- else
-#endif
- {
- gdm_debug ("gdm_xdmcp_handle_managed_forward: "
- "Got MANAGED_FORWARD from %s",
- inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr));
-
- /* Check with tcp_wrappers if client is allowed to access */
- if (! gdm_xdmcp_host_allow (clnt_sa)) {
- gdm_error ("%s: Got MANAGED_FORWARD from banned host %s",
- "gdm_xdmcp_handle_request",
- inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr));
- return;
- }
- }
-
- /* Hostname */
- if G_UNLIKELY ( ! XdmcpReadARRAY8 (&buf, &clnt_address)) {
- gdm_error (_("%s: Could not read address"),
- "gdm_xdmcp_handle_managed_forward");
- return;
- }
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- if (clnt_address.length != sizeof (struct in6_addr)) {
- gdm_error (_("%s: Could not read address"),
- "gdm_xdmcp_handle_managed_forward");
- XdmcpDisposeARRAY8 (&clnt_address);
- return;
- }
-
- id = gdm_choose_indirect_lookup_by_chosen6 (&(((struct sockaddr_in6 *)clnt_sa)->sin6_addr), (struct in6_addr *)clnt_address.data);
- }
- else
-#endif
- {
- if (clnt_address.length != sizeof (struct in_addr)) {
- gdm_error (_("%s: Could not read address"),
- "gdm_xdmcp_handle_managed_forward");
- XdmcpDisposeARRAY8 (&clnt_address);
- return;
- }
-
- id = gdm_choose_indirect_lookup_by_chosen
- (&(((struct sockaddr_in *)clnt_sa)->sin_addr), (struct in_addr *)clnt_address.data);
- }
-
- if (id != NULL) {
- gdm_choose_indirect_dispose (id);
- }
-
- /* Note: we send GOT even on not found, just in case our previous
- * didn't get through and this was a second managed forward */
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- gdm_xdmcp_send_got_managed_forward6 ((struct sockaddr_in6 *)clnt_sa, (struct in6_addr *)clnt_address.data);
- }
- else
-#endif
- {
- gdm_xdmcp_send_got_managed_forward ((struct sockaddr_in *)clnt_sa, (struct in_addr *)clnt_address.data);
- }
-
- XdmcpDisposeARRAY8 (&clnt_address);
-}
-
-#ifdef ENABLE_IPV6
-static void
-gdm_xdmcp_whack_queued_managed_forwards6 (struct sockaddr_in6 *clnt_sa,
- struct in6_addr *origin)
-{
- GSList *li;
-
- for (li = managed_forwards; li != NULL; li = li->next) {
- ManagedForward *mf = li->data;
-
- if ((memcmp (((struct sockaddr_in6 *)(&(mf->manager)))->sin6_addr.s6_addr, (clnt_sa->sin6_addr.s6_addr), sizeof (struct in6_addr)) == 0) &&
- (memcmp (((struct sockaddr_in6 *)(&(mf->origin)))->sin6_addr.s6_addr, origin->s6_addr, sizeof (struct in6_addr)) == 0)) {
- managed_forwards = g_slist_remove_link (managed_forwards, li);
- g_slist_free_1 (li);
- g_source_remove (mf->handler);
- /* mf freed by glib */
- return;
- }
- }
-}
-#endif
-
-static void
-gdm_xdmcp_whack_queued_managed_forwards (struct sockaddr_in *clnt_sa,
- struct in_addr *origin)
-{
- GSList *li;
-
- for (li = managed_forwards; li != NULL; li = li->next) {
- ManagedForward *mf = li->data;
- if (((struct sockaddr_in *)(&mf->manager))->sin_addr.s_addr == clnt_sa->sin_addr.s_addr &&
- ((struct sockaddr_in *)(&mf->origin))->sin_addr.s_addr == origin->s_addr) {
-
- managed_forwards = g_slist_remove_link (managed_forwards, li);
- g_slist_free_1 (li);
- g_source_remove (mf->handler);
- /* mf freed by glib */
- return;
- }
- }
-}
-
-static void
-#ifdef ENABLE_IPV6
-gdm_xdmcp_handle_got_managed_forward (struct sockaddr_storage *clnt_sa, gint len)
-#else
-gdm_xdmcp_handle_got_managed_forward (struct sockaddr_in *clnt_sa, gint len)
-#endif
-{
- ARRAY8 clnt_address;
-
-#ifdef ENABLE_IPV6
- char buffer6[INET6_ADDRSTRLEN];
-
- if (clnt_sa->ss_family == AF_INET6) {
- gdm_debug ("gdm_xdmcp_handle_got_managed_forward: "
- "Got MANAGED_FORWARD from %s",
- inet_ntop (AF_INET6, &((struct sockaddr_in6 *)clnt_sa)->sin6_addr, buffer6, INET6_ADDRSTRLEN));
- if (! gdm_xdmcp_host_allow (clnt_sa)) {
- gdm_error ("%s: Got GOT_MANAGED_FORWARD from banned host %s", "gdm_xdmcp_handle_request", buffer6);
- return;
- }
- }
- else
-#endif
- {
- gdm_debug ("gdm_xdmcp_handle_got_managed_forward: "
- "Got MANAGED_FORWARD from %s",
- inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr));
-
- /* Check with tcp_wrappers if client is allowed to access */
- if (! gdm_xdmcp_host_allow (clnt_sa)) {
- gdm_error ("%s: Got GOT_MANAGED_FORWARD from banned host %s",
- "gdm_xdmcp_handle_request",
- inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr));
- return;
- }
- }
-
- /* Hostname */
- if G_UNLIKELY ( ! XdmcpReadARRAY8 (&buf, &clnt_address)) {
- gdm_error (_("%s: Could not read address"),
- "gdm_xdmcp_handle_got_managed_forward");
- return;
- }
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- if (clnt_address.length != sizeof (struct in6_addr)) {
- gdm_error (_("%s: Could not read address"),
- "gdm_xdmcp_handle_got_managed_forward");
- XdmcpDisposeARRAY8 (&clnt_address);
- return;
- }
-
- gdm_xdmcp_whack_queued_managed_forwards6 ((struct sockaddr_in6 *)clnt_sa, (struct in6_addr *)clnt_address.data);
- }
- else
-#endif
- {
- if (clnt_address.length != sizeof (struct in_addr)) {
- gdm_error (_("%s: Could not read address"),
- "gdm_xdmcp_handle_got_managed_forward");
- XdmcpDisposeARRAY8 (&clnt_address);
- return;
- }
- gdm_xdmcp_whack_queued_managed_forwards ((struct sockaddr_in *)clnt_sa, (struct in_addr *)clnt_address.data);
- }
-
- XdmcpDisposeARRAY8 (&clnt_address);
-}
-
-
-static void
-#ifdef ENABLE_IPV6
-gdm_xdmcp_send_refuse (struct sockaddr_storage *clnt_sa, CARD32 sessid)
-#else
-gdm_xdmcp_send_refuse (struct sockaddr_in *clnt_sa, CARD32 sessid)
-#endif
-{
- XdmcpHeader header;
- GdmForwardQuery *fq;
-
- gdm_debug ("gdm_xdmcp_send_refuse: Sending REFUSE to %ld", (long)sessid);
-
- header.version = XDM_PROTOCOL_VERSION;
- header.opcode= (CARD16) REFUSE;
- header.length = 4;
-
- XdmcpWriteHeader (&buf, &header);
- XdmcpWriteCARD32 (&buf, sessid);
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa,
- (int)sizeof (struct sockaddr_in6));
- }
- else
-#endif
- {
- XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa,
- (int)sizeof (struct sockaddr_in));
- }
-
- /* this was from a forwarded query quite apparently so
- * send MANAGED_FORWARD */
- fq = gdm_forward_query_lookup (clnt_sa);
- if (fq != NULL) {
- gdm_xdmcp_send_managed_forward (fq->from_sa, clnt_sa);
- gdm_forward_query_dispose (fq);
- }
-}
-
-
-static void
-#ifdef ENABLE_IPV6
-gdm_xdmcp_send_failed (struct sockaddr_storage *clnt_sa, CARD32 sessid)
-#else
-gdm_xdmcp_send_failed (struct sockaddr_in *clnt_sa, CARD32 sessid)
-#endif
-{
- XdmcpHeader header;
- ARRAY8 status;
-
- gdm_debug ("gdm_xdmcp_send_failed: Sending FAILED to %ld", (long)sessid);
-
- /* Don't translate, this goes over the wire to servers where we
- * don't know the charset or language, so it must be ascii */
- status.data = (CARD8 *) "Failed to start session";
- status.length = strlen ((char *) status.data);
-
- header.version = XDM_PROTOCOL_VERSION;
- header.opcode = (CARD16) FAILED;
- header.length = 6+status.length;
-
- XdmcpWriteHeader (&buf, &header);
- XdmcpWriteCARD32 (&buf, sessid);
- XdmcpWriteARRAY8 (&buf, &status);
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa,
- (int)sizeof (struct sockaddr_in6));
- }
- else
-#endif
- {
- XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa,
- (int)sizeof (struct sockaddr_in));
- }
-
-}
-
-
-static void
-#ifdef ENABLE_IPV6
-gdm_xdmcp_handle_keepalive (struct sockaddr_storage *clnt_sa, gint len)
-#else
-gdm_xdmcp_handle_keepalive (struct sockaddr_in *clnt_sa, gint len)
-#endif
-{
- CARD16 clnt_dspnum;
- CARD32 clnt_sessid;
-
-#ifdef ENABLE_IPV6
- char buffer6[INET6_ADDRSTRLEN];
-
- if (clnt_sa->ss_family == AF_INET6) {
- gdm_debug ("gdm_xdmcp_handle_keepalive: Got KEEPALIVE from %s",
- inet_ntop (AF_INET6, &(((struct sockaddr_in6 *)clnt_sa)->sin6_addr),
-buffer6, INET6_ADDRSTRLEN));
-
- /* Check with tcp_wrappers if client is allowed to access */
- if (! gdm_xdmcp_host_allow (clnt_sa)) {
- gdm_error (_("%s: Got KEEPALIVE from banned host %s"),
- "gdm_xdmcp_handle_keepalive", buffer6);
- return;
-
- }
- }
- else
-#endif
- {
- gdm_debug ("gdm_xdmcp_handle_keepalive: Got KEEPALIVE from %s",
- inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr));
-
- /* Check with tcp_wrappers if client is allowed to access */
- if (! gdm_xdmcp_host_allow (clnt_sa)) {
- gdm_error (_("%s: Got KEEPALIVE from banned host %s"),
- "gdm_xdmcp_handle_keepalive",
- inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr));
- return;
- }
- }
-
- /* Remote display number */
- if G_UNLIKELY (! XdmcpReadCARD16 (&buf, &clnt_dspnum)) {
- gdm_error (_("%s: Could not read Display Number"),
- "gdm_xdmcp_handle_keepalive");
- return;
- }
-
- /* SessionID */
- if G_UNLIKELY (! XdmcpReadCARD32 (&buf, &clnt_sessid)) {
- gdm_error (_("%s: Could not read Session ID"),
- "gdm_xdmcp_handle_keepalive");
- return;
- }
-
- gdm_xdmcp_send_alive (clnt_sa, clnt_dspnum, clnt_sessid);
-}
-
-
-static void
-#ifdef ENABLE_IPV6
-gdm_xdmcp_send_alive (struct sockaddr_storage *clnt_sa, CARD16 dspnum, CARD32 sessid)
-#else
-gdm_xdmcp_send_alive (struct sockaddr_in *clnt_sa, CARD16 dspnum, CARD32 sessid)
-#endif
-{
- XdmcpHeader header;
- GdmDisplay *d;
- int send_running = 0;
- CARD32 send_sessid = 0;
-
- d = gdm_xdmcp_display_lookup (sessid);
- if (d == NULL)
- d = gdm_xdmcp_display_lookup_by_host (clnt_sa, dspnum);
-
- if (d != NULL) {
- send_sessid = d->sessionid;
- if (d->dispstat == XDMCP_MANAGED)
- send_running = 1;
- }
-
- gdm_debug ("Sending ALIVE to %ld (running %d, sessid %ld)",
- (long)sessid, send_running, (long)send_sessid);
-
- header.version = XDM_PROTOCOL_VERSION;
- header.opcode = (CARD16) ALIVE;
- header.length = 5;
-
- XdmcpWriteHeader (&buf, &header);
- XdmcpWriteCARD8 (&buf, send_running);
- XdmcpWriteCARD32 (&buf, send_sessid);
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa,
- (int)sizeof (struct sockaddr_in6));
- }
- else
-#endif
- {
- XdmcpFlush (gdm_xdmcpfd, &buf, (XdmcpNetaddr)clnt_sa,
- (int)sizeof (struct sockaddr_in));
- }
-}
-
-
-static gboolean
-gdm_xdmcp_host_allow (
-#ifdef ENABLE_IPV6
- struct sockaddr_storage *clnt_sa
-#else
- struct sockaddr_in *clnt_sa
-#endif
- )
-{
-#ifdef HAVE_TCPWRAPPERS
-
- /* avoids a warning, my tcpd.h file doesn't include this prototype, even
- * though the library does include the function and the manpage mentions it
- */
- extern int hosts_ctl (char *daemon, char *client_name, char *client_addr, char *client_user);
-
- GdmHostent *client_he;
- char *client;
- gboolean ret;
-
- /* Find client hostname */
- client_he = gdm_gethostbyaddr (clnt_sa);
-
- if (client_he->not_found)
- client = "unknown";
- else {
- gdm_debug ("gdm_xdmcp_host_allow: client->hostname is %s\n", client_he->hostname);
- client = client_he->hostname;
- }
-
- /* Check with tcp_wrappers if client is allowed to access */
-#ifdef ENABLE_IPV6
- if (clnt_sa->ss_family == AF_INET6) {
- char buffer6[INET6_ADDRSTRLEN];
-
- ret = (hosts_ctl ("gdm", client, (char *) inet_ntop (AF_INET6, &((struct sockaddr_in6 *)clnt_sa)->sin6_addr, buffer6, INET6_ADDRSTRLEN), ""));
- } else
-#endif
- {
- ret = (hosts_ctl ("gdm", client, inet_ntoa (((struct sockaddr_in *)clnt_sa)->sin_addr), ""));
- }
-
- gdm_hostent_free (client_he);
-
- return ret;
-#else /* HAVE_TCPWRAPPERS */
- return (TRUE);
-#endif /* HAVE_TCPWRAPPERS */
-}
-
-
-static GdmDisplay *
-gdm_xdmcp_display_alloc (
-#ifdef ENABLE_IPV6
- struct sockaddr_storage *addr,
-#else
- struct sockaddr_in *addr,
-#endif
- GdmHostent *he /* eaten and freed */,
- int displaynum)
-{
- GdmDisplay *d = NULL;
- char *proxycmd = gdm_get_value_string (GDM_KEY_XDMCP_PROXY_XSERVER);
-
- d = g_new0 (GdmDisplay, 1);
-
- if (gdm_get_value_bool (GDM_KEY_XDMCP_PROXY) && proxycmd != NULL) {
- d->type = TYPE_XDMCP_PROXY;
- d->command = g_strdup (proxycmd);
- gdm_debug ("Using proxy server for XDMCP: %s\n", d->command);
- } else {
- d->type = TYPE_XDMCP;
- }
-
- d->logout_action = GDM_LOGOUT_ACTION_NONE;
- d->authfile = NULL;
- d->auths = NULL;
- d->userauth = NULL;
- d->greetpid = 0;
- d->servpid = 0;
- d->servstat = 0;
- d->sesspid = 0;
- d->slavepid = 0;
- d->attached = FALSE;
- d->dispstat = XDMCP_PENDING;
- d->sessionid = globsessid++;
- if (d->sessionid == 0)
- d->sessionid = globsessid++;
- d->acctime = time (NULL);
- d->dispnum = displaynum;
- d->xdmcp_dispnum = displaynum;
-
- d->handled = TRUE;
- d->tcp_disallowed = FALSE;
-
- d->vt = -1;
-
- d->x_servers_order = -1;
-
- d->logged_in = FALSE;
- d->login = NULL;
-
- d->sleep_before_run = 0;
- if (gdm_get_value_bool (GDM_KEY_ALLOW_REMOTE_AUTOLOGIN) &&
- ! ve_string_empty (gdm_get_value_string (GDM_KEY_TIMED_LOGIN))) {
- d->timed_login_ok = TRUE;
- } else {
- d->timed_login_ok = FALSE;
- }
-
- d->name = g_strdup_printf ("%s:%d", he->hostname,
- displaynum);
-#ifdef ENABLE_IPV6
- if (addr->ss_family == AF_INET6) {
- memcpy (&d->addr6, &((struct sockaddr_in6 *)addr)->sin6_addr, sizeof (struct in6_addr));
- d->addrtype = AF_INET6;
- }
- else
-#endif
- {
- memcpy (&d->addr, &((struct sockaddr_in *)addr)->sin_addr, sizeof (struct in_addr));
- d->addrtype = AF_INET;
- }
-
- d->hostname = he->hostname;
- he->hostname = NULL;
- d->addrs = he->addrs;
- he->addrs = NULL;
- d->addr_count = he->addr_count;
- he->addr_count = 0;
-
- gdm_hostent_free (he);
-
- d->slave_notify_fd = -1;
- d->master_notify_fd = -1;
-
- d->xsession_errors_bytes = 0;
- d->xsession_errors_fd = -1;
- d->session_output_fd = -1;
-
- d->chooser_output_fd = -1;
- d->chooser_last_line = NULL;
-
- d->theme_name = NULL;
-
- /* Secure display with cookie */
- if G_UNLIKELY (! gdm_auth_secure_display (d))
- gdm_error ("gdm_xdmcp_display_alloc: Error setting up cookies for %s", d->name);
-
- if (d->type == TYPE_XDMCP_PROXY) {
- d->parent_disp = d->name;
- d->name = g_strdup (":-1");
- d->dispnum = -1;
-
- d->server_uid = gdm_get_gdmuid ();
-
- d->parent_auth_file = d->authfile;
- d->authfile = NULL;
- }
-
- displays = g_slist_append (displays, d);
-
- xdmcp_pending++;
-
- gdm_debug ("gdm_xdmcp_display_alloc: display=%s, session id=%ld, xdmcp_pending=%d ",
- d->name, (long)d->sessionid, xdmcp_pending);
-
- return d;
-}
-
-
-static GdmDisplay *
-gdm_xdmcp_display_lookup (CARD32 sessid)
-{
- GSList *dlist = displays;
- GdmDisplay *d;
-
- if (!sessid)
- return (NULL);
-
- while (dlist) {
- d = (GdmDisplay *) dlist->data;
-
- if (d && d->sessionid == sessid)
- return (d);
-
- dlist = dlist->next;
- }
-
- return (NULL);
-}
-
-
-static void
-gdm_xdmcp_display_dispose_check (const gchar *hostname, int dspnum)
-{
- GSList *dlist;
-
- if (hostname == NULL)
- return;
-
- gdm_debug ("gdm_xdmcp_display_dispose_check (%s:%d)", hostname, dspnum);
-
- dlist = displays;
- while (dlist != NULL) {
- GdmDisplay *d = dlist->data;
-
- if (d != NULL &&
- SERVER_IS_XDMCP (d) &&
- d->xdmcp_dispnum == dspnum &&
- strcmp (d->hostname, hostname) == 0) {
- if (d->dispstat == XDMCP_MANAGED)
- gdm_display_unmanage (d);
- else
- gdm_display_dispose (d);
-
- /* restart as the list is now broken */
- dlist = displays;
- } else {
- /* just go on */
- dlist = dlist->next;
- }
- }
-}
-
-
-static void
-gdm_xdmcp_displays_check (void)
-{
- GSList *dlist;
- time_t curtime = time (NULL);
-
- dlist = displays;
- while (dlist != NULL) {
- GdmDisplay *d = dlist->data;
-
- if (d != NULL &&
- SERVER_IS_XDMCP (d) &&
- d->dispstat == XDMCP_PENDING &&
- curtime > d->acctime + gdm_get_value_int (GDM_KEY_MAX_WAIT)) {
- gdm_debug ("gdm_xdmcp_displays_check: Disposing session id %ld",
- (long)d->sessionid);
- gdm_display_dispose (d);
-
- /* restart as the list is now broken */
- dlist = displays;
- } else {
- /* just go on */
- dlist = dlist->next;
- }
- }
-}
-
-static void
-reconnect_to_parent (GdmDisplay *to)
-{
- GError *error;
- gchar *command_argv[10];
- gchar *proxyreconnect = gdm_get_value_string (GDM_KEY_XDMCP_PROXY_RECONNECT);
-
- command_argv[0] = proxyreconnect;
- command_argv[1] = "--display";
- command_argv[2] = to->parent_disp;
- command_argv[3] = "--display-authfile";
- command_argv[4] = to->parent_auth_file;
- command_argv[5] = "--to";
- command_argv[6] = to->name;
- command_argv[7] = "--to-authfile";
- command_argv[8] = to->authfile;
- command_argv[9] = NULL;
-
- gdm_debug ("XDMCP: migrating display by running "
- "'%s --display %s --display-authfile %s --to %s --to-authfile %s'",
- proxyreconnect,
- to->parent_disp, to->parent_auth_file,
- to->name, to->authfile);
-
- error = NULL;
- if (!g_spawn_async (NULL, command_argv, NULL, 0, NULL, NULL, NULL, &error)) {
- gdm_error (_("%s: Failed to run "
- "'%s --display %s --display-authfile %s --to %s --to-authfile %s': %s"),
- "gdm_xdmcp_migrate",
- proxyreconnect,
- to->parent_disp, to->parent_auth_file,
- to->name, to->authfile,
- error->message);
- g_error_free (error);
- }
-}
-
-void
-gdm_xdmcp_migrate (GdmDisplay *from, GdmDisplay *to)
-{
- if (from->type != TYPE_XDMCP_PROXY ||
- to->type != TYPE_XDMCP_PROXY)
- return;
-
- g_free (to->parent_disp);
- to->parent_disp = from->parent_disp;
- from->parent_disp = NULL;
-
- g_free (to->parent_auth_file);
- to->parent_auth_file = from->parent_auth_file;
- from->parent_auth_file = NULL;
-
- reconnect_to_parent (to);
-}
-
-#else /* HAVE_LIBXDMCP */
-
-/* Here come some empty stubs for no XDMCP support */
-int
-gdm_xdmcp_init (void)
-{
- gdm_error (_("%s: No XDMCP support"), "gdm_xdmcp_init");
- return FALSE;
-}
-
-void
-gdm_xdmcp_run (void)
-{
- gdm_error (_("%s: No XDMCP support"), "gdm_xdmcp_run");
-}
-
-void
-gdm_xdmcp_close (void)
-{
- gdm_error (_("%s: No XDMCP support"), "gdm_xdmcp_close");
-}
-
-void
-gdm_xdmcp_migrate (GdmDisplay *from, GdmDisplay *to)
-{
- gdm_error (_("%s: No XDMCP support"), "gdm_xdmcp_migrate");
-}
-
-#endif /* HAVE_LIBXDMCP */
-
-/* EOF */