6 #include <sys/socket.h>
10 #include "xdmcp-client.h"
12 G_DEFINE_TYPE (XDMCPClient, xdmcp_client, G_TYPE_OBJECT);
14 #define MAXIMUM_REQUEST_LENGTH 65535
18 XDMCP_BroadcastQuery = 1,
20 XDMCP_IndirectQuery = 3,
21 XDMCP_ForwardQuery = 4,
34 struct XDMCPClientPrivate
40 gchar *authorization_name;
41 gint authorization_data_length;
42 guint8 *authorization_data;
51 XDMCP_CLIENT_LAST_SIGNAL
53 static guint xdmcp_client_signals[XDMCP_CLIENT_LAST_SIGNAL] = { 0 };
56 xdmcp_write (XDMCPClient *client, const guint8 *buffer, gssize buffer_length)
61 n_written = g_socket_send (client->priv->socket, (const gchar *) buffer, buffer_length, NULL, &error);
63 g_warning ("Failed to send XDMCP request: %s", error->message);
64 else if (n_written != buffer_length)
65 g_warning ("Partial write for XDMCP request, wrote %zi, expected %zi", n_written, buffer_length);
66 g_clear_error (&error);
70 decode_willing (XDMCPClient *client, const guint8 *buffer, gssize buffer_length)
72 XDMCPWilling *message;
76 if (client->priv->query_timer == 0)
78 g_debug ("Ignoring XDMCP unrequested/duplicate Willing");
82 /* Stop sending queries */
83 g_source_remove (client->priv->query_timer);
84 client->priv->query_timer = 0;
86 message = g_malloc0 (sizeof (XDMCPWilling));
88 length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
89 message->authentication_name = read_string (buffer, buffer_length, length, &offset);
90 length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
91 message->hostname = read_string (buffer, buffer_length, length, &offset);
92 length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
93 message->status = read_string (buffer, buffer_length, length, &offset);
95 g_signal_emit (client, xdmcp_client_signals[XDMCP_CLIENT_WILLING], 0, message);
97 g_free (message->authentication_name);
98 g_free (message->hostname);
99 g_free (message->status);
104 decode_accept (XDMCPClient *client, const guint8 *buffer, gssize buffer_length)
106 XDMCPAccept *message;
110 message = g_malloc (sizeof (XDMCPAccept));
112 message->session_id = read_card32 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
113 length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
114 message->authentication_name = read_string (buffer, buffer_length, length, &offset);
115 length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
116 read_string8 (buffer, buffer_length, length, &offset);
117 length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
118 message->authorization_name = read_string (buffer, buffer_length, length, &offset);
119 message->authorization_data_length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
120 message->authorization_data = read_string8 (buffer, buffer_length, length, &offset);
122 g_signal_emit (client, xdmcp_client_signals[XDMCP_CLIENT_ACCEPT], 0, message);
124 g_free (message->authentication_name);
125 g_free (message->authorization_name);
126 g_free (message->authorization_data);
131 decode_decline (XDMCPClient *client, const guint8 *buffer, gssize buffer_length)
133 XDMCPDecline *message;
137 message = g_malloc0 (sizeof (XDMCPDecline));
139 length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
140 message->status = read_string (buffer, buffer_length, length, &offset);
141 length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
142 message->authentication_name = read_string (buffer, buffer_length, length, &offset);
143 length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
144 read_string8 (buffer, buffer_length, length, &offset);
146 g_signal_emit (client, xdmcp_client_signals[XDMCP_CLIENT_DECLINE], 0, message);
148 g_free (message->status);
149 g_free (message->authentication_name);
154 decode_failed (XDMCPClient *client, const guint8 *buffer, gssize buffer_length)
156 XDMCPFailed *message;
160 message = g_malloc0 (sizeof (XDMCPFailed));
162 message->session_id = read_card32 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
163 length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
164 message->status = read_string (buffer, buffer_length, length, &offset);
166 g_signal_emit (client, xdmcp_client_signals[XDMCP_CLIENT_FAILED], 0, message);
168 g_free (message->status);
173 xdmcp_data_cb (GIOChannel *channel, GIOCondition condition, gpointer data)
175 XDMCPClient *client = data;
176 guint8 buffer[MAXIMUM_REQUEST_LENGTH];
179 n_read = recv (g_io_channel_unix_get_fd (channel), buffer, MAXIMUM_REQUEST_LENGTH, 0);
181 g_warning ("Error reading from XDMCP socket: %s", strerror (errno));
182 else if (n_read == 0)
190 guint16 version, opcode, length;
192 version = read_card16 (buffer, n_read, X_BYTE_ORDER_MSB, &offset);
193 opcode = read_card16 (buffer, n_read, X_BYTE_ORDER_MSB, &offset);
194 length = read_card16 (buffer, n_read, X_BYTE_ORDER_MSB, &offset);
198 g_debug ("Ignoring XDMCP version %d message", version);
201 if (6 + length > n_read)
203 g_debug ("Ignoring XDMCP message of length %zi with invalid length field %d", n_read, length);
209 decode_willing (client, buffer + offset, n_read - offset);
213 decode_accept (client, buffer + offset, n_read - offset);
217 decode_decline (client, buffer + offset, n_read - offset);
221 decode_failed (client, buffer + offset, n_read - offset);
225 g_debug ("Ignoring unknown XDMCP opcode %d", opcode);
234 xdmcp_query_cb (gpointer data)
236 XDMCPClient *client = data;
237 g_signal_emit (client, xdmcp_client_signals[XDMCP_CLIENT_QUERY], 0);
238 xdmcp_client_send_query (client);
243 xdmcp_client_new (void)
245 return g_object_new (xdmcp_client_get_type (), NULL);
249 xdmcp_client_set_hostname (XDMCPClient *client, const gchar *hostname)
251 g_free (client->priv->host);
252 client->priv->host = g_strdup (hostname);
256 xdmcp_client_set_port (XDMCPClient *client, guint16 port)
258 client->priv->port = port;
262 xdmcp_client_start (XDMCPClient *client)
264 GSocketConnectable *address;
265 GSocketAddressEnumerator *enumerator;
267 GError *error = NULL;
269 client->priv->socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &error);
271 g_warning ("Error creating XDMCP socket: %s", error->message);
272 if (!client->priv->socket)
275 address = g_network_address_new (client->priv->host, client->priv->port);
276 enumerator = g_socket_connectable_enumerate (address);
280 GSocketAddress *socket_address;
283 socket_address = g_socket_address_enumerator_next (enumerator, NULL, &e);
285 g_warning ("Failed to get socket address: %s", e->message);
290 result = g_socket_connect (client->priv->socket, socket_address, NULL, error ? NULL : &error);
291 g_object_unref (socket_address);
294 g_clear_error (&error);
299 g_warning ("Unable to connect XDMCP socket: %s", error->message);
303 g_io_add_watch (g_io_channel_unix_new (g_socket_get_fd (client->priv->socket)), G_IO_IN, xdmcp_data_cb, client);
305 client->priv->query_timer = g_timeout_add (2000, xdmcp_query_cb, client);
306 xdmcp_query_cb (client);
312 xdmcp_client_get_local_address (XDMCPClient *client)
314 GSocketAddress *socket_address;
316 if (!client->priv->socket)
319 socket_address = g_socket_get_local_address (client->priv->socket, NULL);
320 return g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (socket_address));
324 xdmcp_client_init (XDMCPClient *client)
326 client->priv = G_TYPE_INSTANCE_GET_PRIVATE (client, xdmcp_client_get_type (), XDMCPClientPrivate);
327 client->priv->port = XDMCP_PORT;
331 xdmcp_client_send_query (XDMCPClient *client)
333 guint8 buffer[MAXIMUM_REQUEST_LENGTH];
336 write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, XDMCP_VERSION, &offset);
337 write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, XDMCP_Query, &offset);
338 write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, 1, &offset);
339 write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, 0, &offset);
341 xdmcp_write (client, buffer, offset);
345 xdmcp_client_send_request (XDMCPClient *client,
346 guint16 display_number,
347 GInetAddress **addresses,
348 const gchar *authentication_name,
349 const guint8 *authentication_data, guint16 authentication_data_length,
350 gchar **authorization_names, const gchar *mfid)
352 guint8 buffer[MAXIMUM_REQUEST_LENGTH];
353 gsize length = 0, offset = 0, n_addresses = 0, n_names = 0;
354 GInetAddress **address;
357 length = 11 + strlen (authentication_name) + authentication_data_length + strlen (mfid);
358 for (address = addresses; *address; address++)
360 gssize native_address_length = g_inet_address_get_native_size (*address);
361 length += 4 + native_address_length;
364 for (name = authorization_names; *name; name++)
366 length += 2 + strlen (*name);
370 write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, XDMCP_VERSION, &offset);
371 write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, XDMCP_Request, &offset);
372 write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, length, &offset);
374 write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, display_number, &offset);
375 write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, n_addresses, &offset);
376 for (address = addresses; *address; address++)
377 write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, 0, &offset); /* FamilyInternet */
378 write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, n_addresses, &offset);
379 for (address = addresses; *address; address++)
381 gssize native_address_length;
382 const guint8 *native_address;
384 native_address_length = g_inet_address_get_native_size (*address);
385 native_address = g_inet_address_to_bytes (*address);
386 write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, native_address_length, &offset);
387 write_string8 (buffer, MAXIMUM_REQUEST_LENGTH, native_address, native_address_length, &offset);
389 write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, strlen (authentication_name), &offset);
390 write_string (buffer, MAXIMUM_REQUEST_LENGTH, authentication_name, &offset);
391 write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, authentication_data_length, &offset);
392 write_string8 (buffer, MAXIMUM_REQUEST_LENGTH, authentication_data, authentication_data_length, &offset);
393 write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, n_names, &offset);
394 for (name = authorization_names; *name; name++)
396 write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, strlen (*name), &offset);
397 write_string (buffer, MAXIMUM_REQUEST_LENGTH, *name, &offset);
399 write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, strlen (mfid), &offset);
400 write_string (buffer, MAXIMUM_REQUEST_LENGTH, mfid, &offset);
402 xdmcp_write (client, buffer, offset);
406 xdmcp_client_send_manage (XDMCPClient *client, guint32 session_id, guint16 display_number, gchar *display_class)
408 guint8 buffer[MAXIMUM_REQUEST_LENGTH];
411 write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, XDMCP_VERSION, &offset);
412 write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, XDMCP_Manage, &offset);
413 write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, 8 + strlen (display_class), &offset);
415 write_card32 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, session_id, &offset);
416 write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, display_number, &offset);
417 write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, strlen (display_class), &offset);
418 write_string (buffer, MAXIMUM_REQUEST_LENGTH, display_class, &offset);
420 xdmcp_write (client, buffer, offset);
424 xdmcp_client_finalize (GObject *object)
426 XDMCPClient *client = (XDMCPClient *) object;
427 g_free (client->priv->host);
428 if (client->priv->socket)
429 g_object_unref (client->priv->socket);
430 g_free (client->priv->authorization_name);
431 g_free (client->priv->authorization_data);
435 xdmcp_client_class_init (XDMCPClientClass *klass)
437 GObjectClass *object_class = G_OBJECT_CLASS (klass);
438 object_class->finalize = xdmcp_client_finalize;
439 g_type_class_add_private (klass, sizeof (XDMCPClientPrivate));
440 xdmcp_client_signals[XDMCP_CLIENT_QUERY] =
441 g_signal_new (XDMCP_CLIENT_SIGNAL_QUERY,
442 G_TYPE_FROM_CLASS (klass),
444 G_STRUCT_OFFSET (XDMCPClientClass, query),
448 xdmcp_client_signals[XDMCP_CLIENT_WILLING] =
449 g_signal_new (XDMCP_CLIENT_SIGNAL_WILLING,
450 G_TYPE_FROM_CLASS (klass),
452 G_STRUCT_OFFSET (XDMCPClientClass, willing),
455 G_TYPE_NONE, 1, G_TYPE_POINTER);
456 xdmcp_client_signals[XDMCP_CLIENT_ACCEPT] =
457 g_signal_new (XDMCP_CLIENT_SIGNAL_ACCEPT,
458 G_TYPE_FROM_CLASS (klass),
460 G_STRUCT_OFFSET (XDMCPClientClass, accept),
463 G_TYPE_NONE, 1, G_TYPE_POINTER);
464 xdmcp_client_signals[XDMCP_CLIENT_DECLINE] =
465 g_signal_new (XDMCP_CLIENT_SIGNAL_DECLINE,
466 G_TYPE_FROM_CLASS (klass),
468 G_STRUCT_OFFSET (XDMCPClientClass, decline),
471 G_TYPE_NONE, 1, G_TYPE_POINTER);
472 xdmcp_client_signals[XDMCP_CLIENT_FAILED] =
473 g_signal_new (XDMCP_CLIENT_SIGNAL_FAILED,
474 G_TYPE_FROM_CLASS (klass),
476 G_STRUCT_OFFSET (XDMCPClientClass, failed),
479 G_TYPE_NONE, 1, G_TYPE_POINTER);