summaryrefslogtreecommitdiff
path: root/tests/src/xdmcp-client.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/src/xdmcp-client.c')
-rw-r--r--tests/src/xdmcp-client.c190
1 files changed, 137 insertions, 53 deletions
diff --git a/tests/src/xdmcp-client.c b/tests/src/xdmcp-client.c
index 4308da87..84b0b599 100644
--- a/tests/src/xdmcp-client.c
+++ b/tests/src/xdmcp-client.c
@@ -36,18 +36,19 @@ struct XDMCPClientPrivate
gchar *host;
gint port;
GSocket *socket;
- guint query_timer;
+ gchar *authentication_names;
gchar *authorization_name;
gint authorization_data_length;
guint8 *authorization_data;
};
enum {
- XDMCP_CLIENT_QUERY,
XDMCP_CLIENT_WILLING,
+ XDMCP_CLIENT_UNWILLING,
XDMCP_CLIENT_ACCEPT,
XDMCP_CLIENT_DECLINE,
XDMCP_CLIENT_FAILED,
+ XDMCP_CLIENT_ALIVE,
XDMCP_CLIENT_LAST_SIGNAL
};
static guint xdmcp_client_signals[XDMCP_CLIENT_LAST_SIGNAL] = { 0 };
@@ -73,16 +74,6 @@ decode_willing (XDMCPClient *client, const guint8 *buffer, gssize buffer_length)
gsize offset = 0;
guint16 length;
- if (client->priv->query_timer == 0)
- {
- g_debug ("Ignoring XDMCP unrequested/duplicate Willing");
- return;
- }
-
- /* Stop sending queries */
- g_source_remove (client->priv->query_timer);
- client->priv->query_timer = 0;
-
message = g_malloc0 (sizeof (XDMCPWilling));
length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
@@ -93,7 +84,7 @@ decode_willing (XDMCPClient *client, const guint8 *buffer, gssize buffer_length)
message->status = read_string (buffer, buffer_length, length, &offset);
g_signal_emit (client, xdmcp_client_signals[XDMCP_CLIENT_WILLING], 0, message);
-
+
g_free (message->authentication_name);
g_free (message->hostname);
g_free (message->status);
@@ -101,6 +92,27 @@ decode_willing (XDMCPClient *client, const guint8 *buffer, gssize buffer_length)
}
static void
+decode_unwilling (XDMCPClient *client, const guint8 *buffer, gssize buffer_length)
+{
+ XDMCPUnwilling *message;
+ gsize offset = 0;
+ guint16 length;
+
+ message = g_malloc0 (sizeof (XDMCPUnwilling));
+
+ length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
+ message->hostname = read_string (buffer, buffer_length, length, &offset);
+ length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
+ message->status = read_string (buffer, buffer_length, length, &offset);
+
+ g_signal_emit (client, xdmcp_client_signals[XDMCP_CLIENT_UNWILLING], 0, message);
+
+ g_free (message->hostname);
+ g_free (message->status);
+ g_free (message);
+}
+
+static void
decode_accept (XDMCPClient *client, const guint8 *buffer, gssize buffer_length)
{
XDMCPAccept *message;
@@ -112,8 +124,8 @@ decode_accept (XDMCPClient *client, const guint8 *buffer, gssize buffer_length)
message->session_id = read_card32 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
message->authentication_name = read_string (buffer, buffer_length, length, &offset);
- length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
- read_string8 (buffer, buffer_length, length, &offset);
+ message->authentication_data_length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
+ message->authentication_data = read_string8 (buffer, buffer_length, message->authentication_data_length, &offset);
length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
message->authorization_name = read_string (buffer, buffer_length, length, &offset);
message->authorization_data_length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
@@ -122,6 +134,7 @@ decode_accept (XDMCPClient *client, const guint8 *buffer, gssize buffer_length)
g_signal_emit (client, xdmcp_client_signals[XDMCP_CLIENT_ACCEPT], 0, message);
g_free (message->authentication_name);
+ g_free (message->authentication_data);
g_free (message->authorization_name);
g_free (message->authorization_data);
g_free (message);
@@ -133,20 +146,21 @@ decode_decline (XDMCPClient *client, const guint8 *buffer, gssize buffer_length)
XDMCPDecline *message;
gsize offset = 0;
guint16 length;
-
+
message = g_malloc0 (sizeof (XDMCPDecline));
length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
message->status = read_string (buffer, buffer_length, length, &offset);
length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
message->authentication_name = read_string (buffer, buffer_length, length, &offset);
- length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
- read_string8 (buffer, buffer_length, length, &offset);
-
+ message->authentication_data_length = read_card16 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
+ message->authentication_data = read_string8 (buffer, buffer_length, message->authentication_data_length, &offset);
+
g_signal_emit (client, xdmcp_client_signals[XDMCP_CLIENT_DECLINE], 0, message);
g_free (message->status);
g_free (message->authentication_name);
+ g_free (message->authentication_data);
g_free (message);
}
@@ -169,6 +183,22 @@ decode_failed (XDMCPClient *client, const guint8 *buffer, gssize buffer_length)
g_free (message);
}
+static void
+decode_alive (XDMCPClient *client, const guint8 *buffer, gssize buffer_length)
+{
+ XDMCPAlive *message;
+ gsize offset = 0;
+
+ message = g_malloc0 (sizeof (XDMCPAlive));
+
+ message->session_running = read_card8 (buffer, buffer_length, &offset) != 0 ? TRUE : FALSE;
+ message->session_id = read_card32 (buffer, buffer_length, X_BYTE_ORDER_MSB, &offset);
+
+ g_signal_emit (client, xdmcp_client_signals[XDMCP_CLIENT_ALIVE], 0, message);
+
+ g_free (message);
+}
+
static gboolean
xdmcp_data_cb (GIOChannel *channel, GIOCondition condition, gpointer data)
{
@@ -209,6 +239,10 @@ xdmcp_data_cb (GIOChannel *channel, GIOCondition condition, gpointer data)
decode_willing (client, buffer + offset, n_read - offset);
break;
+ case XDMCP_Unwilling:
+ decode_unwilling (client, buffer + offset, n_read - offset);
+ break;
+
case XDMCP_Accept:
decode_accept (client, buffer + offset, n_read - offset);
break;
@@ -221,6 +255,10 @@ xdmcp_data_cb (GIOChannel *channel, GIOCondition condition, gpointer data)
decode_failed (client, buffer + offset, n_read - offset);
break;
+ case XDMCP_Alive:
+ decode_alive (client, buffer + offset, n_read - offset);
+ break;
+
default:
g_debug ("Ignoring unknown XDMCP opcode %d", opcode);
break;
@@ -230,15 +268,6 @@ xdmcp_data_cb (GIOChannel *channel, GIOCondition condition, gpointer data)
return TRUE;
}
-static gboolean
-xdmcp_query_cb (gpointer data)
-{
- XDMCPClient *client = data;
- g_signal_emit (client, xdmcp_client_signals[XDMCP_CLIENT_QUERY], 0);
- xdmcp_client_send_query (client);
- return TRUE;
-}
-
XDMCPClient *
xdmcp_client_new (void)
{
@@ -266,16 +295,20 @@ xdmcp_client_start (XDMCPClient *client)
gboolean result;
GError *error = NULL;
+ if (client->priv->socket)
+ return TRUE;
+
client->priv->socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &error);
if (error)
g_warning ("Error creating XDMCP socket: %s", error->message);
+ g_clear_error (&error);
if (!client->priv->socket)
return FALSE;
address = g_network_address_new (client->priv->host, client->priv->port);
enumerator = g_socket_connectable_enumerate (address);
result = FALSE;
- while (TRUE)
+ while (TRUE)
{
GSocketAddress *socket_address;
GError *e = NULL;
@@ -299,11 +332,8 @@ xdmcp_client_start (XDMCPClient *client)
g_warning ("Unable to connect XDMCP socket: %s", error->message);
if (!result)
return FALSE;
-
- g_io_add_watch (g_io_channel_unix_new (g_socket_get_fd (client->priv->socket)), G_IO_IN, xdmcp_data_cb, client);
- client->priv->query_timer = g_timeout_add (2000, xdmcp_query_cb, client);
- xdmcp_query_cb (client);
+ g_io_add_watch (g_io_channel_unix_new (g_socket_get_fd (client->priv->socket)), G_IO_IN, xdmcp_data_cb, client);
return TRUE;
}
@@ -312,7 +342,7 @@ GInetAddress *
xdmcp_client_get_local_address (XDMCPClient *client)
{
GSocketAddress *socket_address;
-
+
if (!client->priv->socket)
return NULL;
@@ -327,18 +357,48 @@ xdmcp_client_init (XDMCPClient *client)
client->priv->port = XDMCP_PORT;
}
-void
-xdmcp_client_send_query (XDMCPClient *client)
+static void
+send_query (XDMCPClient *client, guint16 opcode, gchar **authentication_names)
{
guint8 buffer[MAXIMUM_REQUEST_LENGTH];
- gsize offset = 0;
+ gsize length, offset = 0, n_names = 0;
+ gchar **name;
+
+ length = 1;
+ for (name = authentication_names; authentication_names && *name; name++)
+ {
+ length += 2 + strlen (*name);
+ n_names++;
+ }
write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, XDMCP_VERSION, &offset);
- write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, XDMCP_Query, &offset);
- write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, 1, &offset);
- write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, 0, &offset);
+ write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, opcode, &offset);
+ write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, length, &offset);
+ write_card8 (buffer, MAXIMUM_REQUEST_LENGTH, n_names, &offset);
+ for (name = authentication_names; authentication_names && *name; name++)
+ {
+ write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, strlen (*name), &offset);
+ write_string (buffer, MAXIMUM_REQUEST_LENGTH, *name, &offset);
+ }
+ xdmcp_write (client, buffer, offset);
+}
- xdmcp_write (client, buffer, offset);
+void
+xdmcp_client_send_query (XDMCPClient *client, gchar **authentication_names)
+{
+ send_query (client, XDMCP_Query, authentication_names);
+}
+
+void
+xdmcp_client_send_broadcast_query (XDMCPClient *client, gchar **authentication_names)
+{
+ send_query (client, XDMCP_BroadcastQuery, authentication_names);
+}
+
+void
+xdmcp_client_send_indirect_query (XDMCPClient *client, gchar **authentication_names)
+{
+ send_query (client, XDMCP_IndirectQuery, authentication_names);
}
void
@@ -403,7 +463,7 @@ xdmcp_client_send_request (XDMCPClient *client,
}
void
-xdmcp_client_send_manage (XDMCPClient *client, guint32 session_id, guint16 display_number, gchar *display_class)
+xdmcp_client_send_manage (XDMCPClient *client, guint32 session_id, guint16 display_number, const gchar *display_class)
{
guint8 buffer[MAXIMUM_REQUEST_LENGTH];
gsize offset = 0;
@@ -417,7 +477,23 @@ xdmcp_client_send_manage (XDMCPClient *client, guint32 session_id, guint16 displ
write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, strlen (display_class), &offset);
write_string (buffer, MAXIMUM_REQUEST_LENGTH, display_class, &offset);
- xdmcp_write (client, buffer, offset);
+ xdmcp_write (client, buffer, offset);
+}
+
+void
+xdmcp_client_send_keep_alive (XDMCPClient *client, guint16 display_number, guint32 session_id)
+{
+ guint8 buffer[MAXIMUM_REQUEST_LENGTH];
+ gsize offset = 0;
+
+ write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, XDMCP_VERSION, &offset);
+ write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, XDMCP_KeepAlive, &offset);
+ write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, 6, &offset);
+
+ write_card16 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, display_number, &offset);
+ write_card32 (buffer, MAXIMUM_REQUEST_LENGTH, X_BYTE_ORDER_MSB, session_id, &offset);
+
+ xdmcp_write (client, buffer, offset);
}
static void
@@ -437,24 +513,24 @@ xdmcp_client_class_init (XDMCPClientClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = xdmcp_client_finalize;
g_type_class_add_private (klass, sizeof (XDMCPClientPrivate));
- xdmcp_client_signals[XDMCP_CLIENT_QUERY] =
- g_signal_new ("query",
+ xdmcp_client_signals[XDMCP_CLIENT_WILLING] =
+ g_signal_new (XDMCP_CLIENT_SIGNAL_WILLING,
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (XDMCPClientClass, query),
+ G_STRUCT_OFFSET (XDMCPClientClass, willing),
NULL, NULL,
NULL,
- G_TYPE_NONE, 0);
- xdmcp_client_signals[XDMCP_CLIENT_WILLING] =
- g_signal_new ("willing",
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ xdmcp_client_signals[XDMCP_CLIENT_UNWILLING] =
+ g_signal_new (XDMCP_CLIENT_SIGNAL_UNWILLING,
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (XDMCPClientClass, willing),
+ G_STRUCT_OFFSET (XDMCPClientClass, unwilling),
NULL, NULL,
NULL,
G_TYPE_NONE, 1, G_TYPE_POINTER);
xdmcp_client_signals[XDMCP_CLIENT_ACCEPT] =
- g_signal_new ("accept",
+ g_signal_new (XDMCP_CLIENT_SIGNAL_ACCEPT,
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (XDMCPClientClass, accept),
@@ -462,7 +538,7 @@ xdmcp_client_class_init (XDMCPClientClass *klass)
NULL,
G_TYPE_NONE, 1, G_TYPE_POINTER);
xdmcp_client_signals[XDMCP_CLIENT_DECLINE] =
- g_signal_new ("decline",
+ g_signal_new (XDMCP_CLIENT_SIGNAL_DECLINE,
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (XDMCPClientClass, decline),
@@ -470,11 +546,19 @@ xdmcp_client_class_init (XDMCPClientClass *klass)
NULL,
G_TYPE_NONE, 1, G_TYPE_POINTER);
xdmcp_client_signals[XDMCP_CLIENT_FAILED] =
- g_signal_new ("failed",
+ g_signal_new (XDMCP_CLIENT_SIGNAL_FAILED,
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (XDMCPClientClass, failed),
NULL, NULL,
NULL,
G_TYPE_NONE, 1, G_TYPE_POINTER);
+ xdmcp_client_signals[XDMCP_CLIENT_ALIVE] =
+ g_signal_new (XDMCP_CLIENT_SIGNAL_ALIVE,
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (XDMCPClientClass, alive),
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
}