diff options
author | Robert Ancell <robert.ancell@canonical.com> | 2015-11-20 14:14:42 +1300 |
---|---|---|
committer | Robert Ancell <robert.ancell@canonical.com> | 2015-11-20 14:14:42 +1300 |
commit | 0eacdf1c6a096167a262e1462f738bccd68cf81a (patch) | |
tree | 4658d27ae672aa3159c994d93b77d3c1a8c3e53d | |
parent | 664bfb1c1f13c6862b9893e6f3ac477ace3f03aa (diff) | |
download | lightdm-git-0eacdf1c6a096167a262e1462f738bccd68cf81a.tar.gz |
Backport XDMCP improvements, including:
- Implement XDMCP ForwardQuery
- Don't start LightDM if the XDMCP server is configured with a key that doesn't exist
- Add IP addresses to XDMCP log messages
- Refactor XDMCP error handling
- Adding many more tests
67 files changed, 1530 insertions, 369 deletions
diff --git a/src/lightdm.c b/src/lightdm.c index d1d04b89..453fe85b 100644 --- a/src/lightdm.c +++ b/src/lightdm.c @@ -877,7 +877,7 @@ bus_acquired_cb (GDBusConnection *connection, keys = g_key_file_new (); result = g_key_file_load_from_file (keys, path, G_KEY_FILE_NONE, &error); if (error) - g_debug ("Error getting key %s", error->message); + g_warning ("Unable to load keys from %s: %s", path, error->message); g_clear_error (&error); if (result) @@ -885,7 +885,7 @@ bus_acquired_cb (GDBusConnection *connection, if (g_key_file_has_key (keys, "keyring", key_name, NULL)) key = g_key_file_get_string (keys, "keyring", key_name, NULL); else - g_debug ("Key %s not defined", key_name); + g_warning ("Key %s not defined", key_name); } g_free (path); g_key_file_free (keys); @@ -894,9 +894,18 @@ bus_acquired_cb (GDBusConnection *connection, xdmcp_server_set_key (xdmcp_server, key); g_free (key_name); g_free (key); - - g_debug ("Starting XDMCP server on UDP/IP port %d", xdmcp_server_get_port (xdmcp_server)); - xdmcp_server_start (xdmcp_server); + + if (key_name && !key) + { + exit_code = EXIT_FAILURE; + display_manager_stop (display_manager); + return; + } + else + { + g_debug ("Starting XDMCP server on UDP/IP port %d", xdmcp_server_get_port (xdmcp_server)); + xdmcp_server_start (xdmcp_server); + } } /* Start the VNC server */ diff --git a/src/xdmcp-protocol.c b/src/xdmcp-protocol.c index 698edba9..0f2af81a 100644 --- a/src/xdmcp-protocol.c +++ b/src/xdmcp-protocol.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2010-2011 Robert Ancell. * Author: Robert Ancell <robert.ancell@canonical.com> - * + * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later @@ -187,7 +187,7 @@ xdmcp_packet_decode (const guint8 *data, gsize data_length) length = read_card16 (&reader); if (reader.overflow) - { + { g_warning ("Ignoring short packet"); // FIXME: Use GError return NULL; } @@ -211,8 +211,8 @@ xdmcp_packet_decode (const guint8 *data, gsize data_length) packet->Query.authentication_names = read_string_array (&reader); break; case XDMCP_ForwardQuery: - packet->ForwardQuery.client_address = read_string (&reader); - packet->ForwardQuery.client_port = read_string (&reader); + read_data (&reader, &packet->ForwardQuery.client_address); + read_data (&reader, &packet->ForwardQuery.client_port); packet->ForwardQuery.authentication_names = read_string_array (&reader); break; case XDMCP_Willing: @@ -324,8 +324,8 @@ xdmcp_packet_encode (XDMCPPacket *packet, guint8 *data, gsize max_length) write_string_array (&writer, packet->Query.authentication_names); break; case XDMCP_ForwardQuery: - write_string (&writer, packet->ForwardQuery.client_address); - write_string (&writer, packet->ForwardQuery.client_port); + write_data (&writer, &packet->ForwardQuery.client_address); + write_data (&writer, &packet->ForwardQuery.client_port); write_string_array (&writer, packet->ForwardQuery.authentication_names); break; case XDMCP_Willing: @@ -351,7 +351,7 @@ xdmcp_packet_encode (XDMCPPacket *packet, guint8 *data, gsize max_length) write_string (&writer, packet->Request.manufacturer_display_id); break; case XDMCP_Accept: - write_card32 (&writer, packet->Accept.session_id); + write_card32 (&writer, packet->Accept.session_id); write_string (&writer, packet->Accept.authentication_name); write_data (&writer, &packet->Accept.authentication_data); write_string (&writer, packet->Accept.authorization_name); @@ -399,7 +399,7 @@ xdmcp_packet_encode (XDMCPPacket *packet, guint8 *data, gsize max_length) g_warning ("Overflow writing response"); return -1; } - + return length + 6; } @@ -425,8 +425,8 @@ string_list_tostring (gchar **strings) GString *s; gchar *string; gchar **i; - - s = g_string_new (""); + + s = g_string_new (""); for (i = strings; *i; i++) { if (i != strings) @@ -442,7 +442,7 @@ string_list_tostring (gchar **strings) gchar * xdmcp_packet_tostring (XDMCPPacket *packet) { - gchar *string, *t, *t2; + gchar *string, *t, *t2, *t5; gint i; GString *t3; @@ -464,17 +464,21 @@ xdmcp_packet_tostring (XDMCPPacket *packet) g_free (t); return string; case XDMCP_ForwardQuery: - t = string_list_tostring (packet->ForwardQuery.authentication_names); - string = g_strdup_printf ("ForwardQuery(client_address='%s' client_port='%s' authentication_names=[%s])", - packet->ForwardQuery.client_address, packet->ForwardQuery.client_port, t); + t = data_tostring (&packet->ForwardQuery.client_address); + t2 = data_tostring (&packet->ForwardQuery.client_port); + t5 = string_list_tostring (packet->ForwardQuery.authentication_names); + string = g_strdup_printf ("ForwardQuery(client_address=%s client_port=%s authentication_names=[%s])", + t, t2, t5); g_free (t); + g_free (t2); + g_free (t5); return string; case XDMCP_Willing: return g_strdup_printf ("Willing(authentication_name='%s' hostname='%s' status='%s')", packet->Willing.authentication_name, packet->Willing.hostname, packet->Willing.status); case XDMCP_Unwilling: return g_strdup_printf ("Unwilling(hostname='%s' status='%s')", - packet->Unwilling.hostname, packet->Unwilling.status); + packet->Unwilling.hostname, packet->Unwilling.status); case XDMCP_Request: t = string_list_tostring (packet->Request.authorization_names); t2 = data_tostring (&packet->Request.authentication_data); @@ -545,8 +549,8 @@ xdmcp_packet_free (XDMCPPacket *packet) g_strfreev (packet->Query.authentication_names); break; case XDMCP_ForwardQuery: - g_free (packet->ForwardQuery.client_address); - g_free (packet->ForwardQuery.client_port); + g_free (packet->ForwardQuery.client_address.data); + g_free (packet->ForwardQuery.client_port.data); g_strfreev (packet->ForwardQuery.authentication_names); break; case XDMCP_Willing: diff --git a/src/xdmcp-protocol.h b/src/xdmcp-protocol.h index b8eeda09..d0a99cff 100644 --- a/src/xdmcp-protocol.h +++ b/src/xdmcp-protocol.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2010-2011 Robert Ancell. * Author: Robert Ancell <robert.ancell@canonical.com> - * + * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later @@ -49,7 +49,7 @@ typedef struct typedef struct { XDMCPOpcode opcode; - + union { struct @@ -59,8 +59,8 @@ typedef struct struct { - gchar *client_address; - gchar *client_port; + XDMCPData client_address; + XDMCPData client_port; gchar **authentication_names; } ForwardQuery; diff --git a/src/xdmcp-server.c b/src/xdmcp-server.c index a8ad7769..47f53846 100644 --- a/src/xdmcp-server.c +++ b/src/xdmcp-server.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2010-2011 Robert Ancell. * Author: Robert Ancell <robert.ancell@canonical.com> - * + * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later @@ -167,14 +167,29 @@ get_session (XDMCPServer *server, guint16 id) return g_hash_table_lookup (server->priv->sessions, GINT_TO_POINTER ((gint) id)); } +static gchar * +socket_address_to_string (GSocketAddress *address) +{ + gchar *inet_text, *text; + + inet_text = g_inet_address_to_string (g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address))); + text = g_strdup_printf ("%s:%d", inet_text, g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address))); + g_free (inet_text); + + return text; +} + static void send_packet (GSocket *socket, GSocketAddress *address, XDMCPPacket *packet) { + gchar *address_string; guint8 data[1024]; gssize n_written; - g_debug ("Send %s", xdmcp_packet_tostring (packet)); - + address_string = socket_address_to_string (address); + g_debug ("Send %s to %s", xdmcp_packet_tostring (packet), address_string); + g_free (address_string); + n_written = xdmcp_packet_encode (packet, data, 1024); if (n_written < 0) g_critical ("Failed to encode XDMCP packet"); @@ -199,17 +214,17 @@ get_authentication_name (XDMCPServer *server) } static void -handle_query (XDMCPServer *server, GSocket *socket, GSocketAddress *address, XDMCPPacket *packet) +handle_query (XDMCPServer *server, GSocket *socket, GSocketAddress *address, gchar **authentication_names) { XDMCPPacket *response; gchar **i; gchar *authentication_name = NULL; /* If no authentication requested and we are configured for none then allow */ - if (packet->Query.authentication_names[0] == NULL && server->priv->key == NULL) + if (authentication_names[0] == NULL && server->priv->key == NULL) authentication_name = ""; - for (i = packet->Query.authentication_names; *i; i++) + for (i = authentication_names; *i; i++) { if (strcmp (*i, get_authentication_name (server)) == 0 && server->priv->key != NULL) { @@ -232,14 +247,57 @@ handle_query (XDMCPServer *server, GSocket *socket, GSocketAddress *address, XDM if (server->priv->key) response->Unwilling.status = g_strdup_printf ("No matching authentication, server requires %s", get_authentication_name (server)); else - response->Unwilling.status = g_strdup ("Server does not support authentication"); + response->Unwilling.status = g_strdup ("No matching authentication"); } - + send_packet (socket, address, response); xdmcp_packet_free (response); } +static void +handle_forward_query (XDMCPServer *server, GSocket *socket, GSocketAddress *address, XDMCPPacket *packet) +{ + GSocketFamily family; + GInetAddress *client_inet_address; + GSocketAddress *client_address; + gint i; + guint16 port = 0; + + family = g_socket_get_family (socket); + switch (family) + { + case G_SOCKET_FAMILY_IPV4: + if (packet->ForwardQuery.client_address.length != 4) + { + g_warning ("Ignoring IPv4 XDMCP ForwardQuery with client address of length %d", packet->ForwardQuery.client_address.length); + return; + } + break; + case G_SOCKET_FAMILY_IPV6: + if (packet->ForwardQuery.client_address.length != 16) + { + g_warning ("Ignoring IPv6 XDMCP ForwardQuery with client address of length %d", packet->ForwardQuery.client_address.length); + return; + } + break; + default: + g_warning ("Unknown socket family %d", family); + return; + } + + for (i = 0; i < packet->ForwardQuery.client_port.length; i++) + port = port << 8 | packet->ForwardQuery.client_port.data[i]; + + client_inet_address = g_inet_address_new_from_bytes (packet->ForwardQuery.client_address.data, family); + client_address = g_inet_socket_address_new (client_inet_address, port); + g_object_unref (client_inet_address); + + handle_query (server, socket, client_address, packet->ForwardQuery.authentication_names); + + g_object_unref (client_address); +} + static guint8 atox (char c) { @@ -347,95 +405,90 @@ choose_connection (XDMCPPacket *packet, GInetAddress *source_address) return &packet->Request.connections[index]; } +static gboolean +has_string (gchar **list, const gchar *text) +{ + gchar **i; + + for (i = list; *i; i++) + if (strcmp (*i, text) == 0) + return TRUE; + + return FALSE; +} + static void handle_request (XDMCPServer *server, GSocket *socket, GSocketAddress *address, XDMCPPacket *packet) { XDMCPPacket *response; XDMCPSession *session; - guint8 *authentication_data = NULL; - gsize authentication_data_length = 0; - gboolean match_authorization = FALSE; - gchar *authorization_name; - guint8 *authorization_data = NULL; - gsize authorization_data_length = 0; - guint8 *session_authorization_data = NULL; - gsize session_authorization_data_length = 0; - gchar **j; + gchar *authentication_name = NULL, *decline_status = NULL, *authorization_name, *display_number; + guint8 *authentication_data = NULL, *authorization_data = NULL, *session_authorization_data = NULL; + gsize authentication_data_length = 0, authorization_data_length = 0, session_authorization_data_length = 0; XDMCPConnection *connection; - gchar *display_number; XdmAuthKeyRec rho; - /* Choose an address to connect back on */ - connection = choose_connection (packet, g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address))); - - /* Decline if haven't got an address we can connect on */ - if (!connection) - { - response = xdmcp_packet_alloc (XDMCP_Decline); - response->Decline.status = g_strdup ("No valid address found"); - response->Decline.authentication_name = g_strdup (packet->Request.authentication_name); - response->Decline.authentication_data.data = authentication_data; - response->Decline.authentication_data.length = authentication_data_length; - send_packet (socket, address, response); - xdmcp_packet_free (response); - return; - } - - /* Must be using our authentication scheme */ - if (strcmp (packet->Request.authentication_name, get_authentication_name (server)) != 0) + /* Check authentication */ + if (strcmp (packet->Request.authentication_name, "") == 0) { - response = xdmcp_packet_alloc (XDMCP_Decline); - if (server->priv->key) - response->Decline.status = g_strdup_printf ("Server only supports %s authentication", get_authentication_name (server)); + if (!server->priv->key) + { + if (!has_string (packet->Request.authorization_names, "MIT-MAGIC-COOKIE-1")) + decline_status = g_strdup ("No matching authorization, server requires MIT-MAGIC-COOKIE-1"); + } else - response->Decline.status = g_strdup ("Server does not support authentication"); - response->Decline.authentication_name = g_strdup (""); - send_packet (socket, address, response); - xdmcp_packet_free (response); - return; + decline_status = g_strdup ("No matching authentication, server requires XDM-AUTHENTICATION-1"); } - - /* Perform requested authentication */ - if (server->priv->key) + else if (strcmp (packet->Request.authentication_name, "XDM-AUTHENTICATION-1") == 0 && server->priv->key) { - guint8 input[8], key[8]; - - memset (input, 0, 8); - memcpy (input, packet->Request.authentication_data.data, packet->Request.authentication_data.length > 8 ? 8 : packet->Request.authentication_data.length); + if (packet->Request.authentication_data.length == 8) + { + guint8 input[8], key[8]; - /* Setup key */ - decode_key (server->priv->key, key); + memcpy (input, packet->Request.authentication_data.data, packet->Request.authentication_data.length); - /* Decode message from server */ - authentication_data = g_malloc (sizeof (guint8) * 8); - authentication_data_length = 8; + /* Setup key */ + decode_key (server->priv->key, key); - XdmcpUnwrap (input, key, rho.data, authentication_data_length); - XdmcpIncrementKey (&rho); - XdmcpWrap (rho.data, key, authentication_data, authentication_data_length); + /* Decode message from server */ + authentication_name = g_strdup ("XDM-AUTHENTICATION-1"); + authentication_data = g_malloc (sizeof (guint8) * 8); + authentication_data_length = 8; + + XdmcpUnwrap (input, key, rho.data, authentication_data_length); + XdmcpIncrementKey (&rho); + XdmcpWrap (rho.data, key, authentication_data, authentication_data_length); - authorization_name = g_strdup ("XDM-AUTHORIZATION-1"); + if (!has_string (packet->Request.authorization_names, "XDM-AUTHORIZATION-1")) + decline_status = g_strdup ("No matching authorization, server requires XDM-AUTHORIZATION-1"); + } + else + decline_status = g_strdup ("Invalid XDM-AUTHENTICATION-1 data provided"); } else - authorization_name = g_strdup ("MIT-MAGIC-COOKIE-1"); - - /* Check if they support our authorization */ - for (j = packet->Request.authorization_names; *j; j++) { - if (strcmp (*j, authorization_name) == 0) - { - match_authorization = TRUE; - break; - } + if (strcmp (packet->Request.authentication_name, "") == 0) + decline_status = g_strdup_printf ("No matching authentication, server does not support unauthenticated connections"); + else if (server->priv->key) + decline_status = g_strdup ("No matching authentication, server requires XDM-AUTHENTICATION-1"); + else + decline_status = g_strdup ("No matching authentication, server only supports unauthenticated connections"); } - /* Decline if don't support out authorization */ - if (!match_authorization) + /* Choose an address to connect back on */ + connection = choose_connection (packet, g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address))); + if (!connection && !decline_status) + decline_status = g_strdup ("No valid address found"); + + if (!authentication_name) + authentication_name = g_strdup (""); + + /* Decline if request was not valid */ + if (decline_status) { response = xdmcp_packet_alloc (XDMCP_Decline); - response->Decline.status = g_strdup_printf ("Server requires %s authorization", authorization_name); - g_free (authorization_name); - response->Decline.authentication_name = g_strdup (packet->Request.authentication_name); + response->Decline.status = decline_status; + response->Decline.authentication_name = authentication_name; response->Decline.authentication_data.data = authentication_data; response->Decline.authentication_data.length = authentication_data_length; send_packet (socket, address, response); @@ -443,7 +496,7 @@ handle_request (XDMCPServer *server, GSocket *socket, GSocketAddress *address, X return; } - /* Perform requested authorization */ + /* Generate authorization data */ if (server->priv->key) { gint i; @@ -464,6 +517,7 @@ handle_request (XDMCPServer *server, GSocket *socket, GSocketAddress *address, X XdmcpWrap (session_key, key, authorization_data, authorization_data_length); /* Authorization data is the number received from the client followed by the private session key */ + authorization_name = g_strdup ("XDM-AUTHORIZATION-1"); session_authorization_data = g_malloc (16); session_authorization_data_length = 16; XdmcpDecrementKey (&rho); @@ -478,6 +532,7 @@ handle_request (XDMCPServer *server, GSocket *socket, GSocketAddress *address, X auth = x_authority_new_cookie (XAUTH_FAMILY_WILD, NULL, 0, ""); authorization_data = x_authority_copy_authorization_data (auth); authorization_data_length = x_authority_get_authorization_data_length (auth); + authorization_name = g_strdup ("MIT-MAGIC-COOKIE-1"); session_authorization_data = x_authority_copy_authorization_data (auth); session_authorization_data_length = x_authority_get_authorization_data_length (auth); @@ -517,7 +572,7 @@ handle_request (XDMCPServer *server, GSocket *socket, GSocketAddress *address, X response = xdmcp_packet_alloc (XDMCP_Accept); response->Accept.session_id = xdmcp_session_get_id (session); - response->Accept.authentication_name = g_strdup (packet->Request.authentication_name); + response->Accept.authentication_name = authentication_name; response->Accept.authentication_data.data = authentication_data; response->Accept.authentication_data.length = authentication_data_length; response->Accept.authorization_name = authorization_name; @@ -627,25 +682,30 @@ read_cb (GSocket *socket, GIOCondition condition, XDMCPServer *server) packet = xdmcp_packet_decode ((guint8 *)data, n_read); if (packet) - { - gchar *packet_string; + { + gchar *packet_string, *address_string; packet_string = xdmcp_packet_tostring (packet); - g_debug ("Got %s", packet_string); + address_string = socket_address_to_string (address); + g_debug ("Got %s from %s", packet_string, address_string); g_free (packet_string); + g_free (address_string); switch (packet->opcode) { case XDMCP_BroadcastQuery: case XDMCP_Query: case XDMCP_IndirectQuery: - handle_query (server, socket, address, packet); + handle_query (server, socket, address, packet->Query.authentication_names); + break; + case XDMCP_ForwardQuery: + handle_forward_query (server, socket, address, packet); break; case XDMCP_Request: handle_request (server, socket, address, packet); break; case XDMCP_Manage: - handle_manage (server, socket, address, packet); + handle_manage (server, socket, address, packet); break; case XDMCP_KeepAlive: handle_keep_alive (server, socket, address, packet); @@ -668,7 +728,7 @@ open_udp_socket (GSocketFamily family, guint port, const gchar *listen_address, GSocket *socket; GSocketAddress *address; gboolean result; - + socket = g_socket_new (family, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, error); if (!socket) return NULL; @@ -705,19 +765,19 @@ xdmcp_server_start (XDMCPServer *server) GError *error = NULL; g_return_val_if_fail (server != NULL, FALSE); - + server->priv->socket = open_udp_socket (G_SOCKET_FAMILY_IPV4, server->priv->port, server->priv->listen_address, &error); if (error) g_warning ("Failed to create IPv4 XDMCP socket: %s", error->message); g_clear_error (&error); - + if (server->priv->socket) { source = g_socket_create_source (server->priv->socket, G_IO_IN, NULL); g_source_set_callback (source, (GSourceFunc) read_cb, server, NULL); g_source_attach (source, NULL); } - + server->priv->socket6 = open_udp_socket (G_SOCKET_FAMILY_IPV6, server->priv->port, server->priv->listen_address, &error); if (error) g_warning ("Failed to create IPv6 XDMCP socket: %s", error->message); @@ -753,7 +813,7 @@ xdmcp_server_finalize (GObject *object) XDMCPServer *self; self = XDMCP_SERVER (object); - + if (self->priv->socket) g_object_unref (self->priv->socket); if (self->priv->socket6) @@ -763,8 +823,8 @@ xdmcp_server_finalize (GObject *object) g_free (self->priv->status); g_free (self->priv->key); g_hash_table_unref (self->priv->sessions); - - G_OBJECT_CLASS (xdmcp_server_parent_class)->finalize (object); + + G_OBJECT_CLASS (xdmcp_server_parent_class)->finalize (object); } static void @@ -772,7 +832,7 @@ xdmcp_server_class_init (XDMCPServerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = xdmcp_server_finalize; + object_class->finalize = xdmcp_server_finalize; g_type_class_add_private (klass, sizeof (XDMCPServerPrivate)); diff --git a/tests/Makefile.am b/tests/Makefile.am index c5168ff5..8b02650a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -161,11 +161,24 @@ TESTS = \ test-vnc-dimensions \ test-vnc-open-file-descriptors \ test-xremote-autologin \ - test-xremote-login \ + test-xremote-login \ test-xdmcp-client \ test-xdmcp-client-xorg-1.16 \ test-xdmcp-server-login \ + test-xdmcp-server-keep-alive \ + test-xdmcp-server-xdm-authentication \ + test-xdmcp-server-xdm-authentication-missing-data \ + test-xdmcp-server-xdm-authentication-short-data \ + test-xdmcp-server-xdm-authentication-long-data \ + test-xdmcp-server-xdm-authentication-required \ + test-xdmcp-server-xdm-authentication-missing-key \ + test-xdmcp-server-xdm-authentication-no-key \ + test-xdmcp-server-xdm-authentication-invalid-authorization \ + test-xdmcp-server-invalid-authentication \ test-xdmcp-server-request-without-addresses \ + test-xdmcp-server-request-without-authorization \ + test-xdmcp-server-request-invalid-authentication \ + test-xdmcp-server-request-invalid-authorization \ test-utmp-login \ test-utmp-autologin \ test-utmp-wrong-password \ @@ -344,6 +357,7 @@ EXTRA_DIST = \ data/greeters/test-python-greeter.desktop \ data/greeters/test-qt4-greeter.desktop \ data/greeters/test-qt5-greeter.desktop \ + data/keys.conf \ data/sessions/alternative.desktop \ data/sessions/default.desktop \ data/sessions/mir.desktop \ @@ -562,9 +576,22 @@ EXTRA_DIST = \ scripts/xdg-seat.conf \ scripts/xdmcp-client.conf \ scripts/xdmcp-client-xorg-1.16.conf \ + scripts/xdmcp-server-invalid-authentication.conf \ + scripts/xdmcp-server-keep-alive.conf \ scripts/xdmcp-server-login.conf \ scripts/xdmcp-server-open-file-descriptors.conf \ + scripts/xdmcp-server-request-invalid-authentication.conf \ + scripts/xdmcp-server-request-invalid-authorization.conf \ scripts/xdmcp-server-request-without-addresses.conf \ + scripts/xdmcp-server-request-without-authorization.conf \ + scripts/xdmcp-server-xdm-authentication.conf \ + scripts/xdmcp-server-xdm-authentication-invalid-authorization.conf \ + scripts/xdmcp-server-xdm-authentication-long-data.conf \ + scripts/xdmcp-server-xdm-authentication-missing-key.conf \ + scripts/xdmcp-server-xdm-authentication-missing-data.conf \ + scripts/xdmcp-server-xdm-authentication-no-key.conf \ + scripts/xdmcp-server-xdm-authentication-required.conf \ + scripts/xdmcp-server-xdm-authentication-short-data.conf \ scripts/xremote-autologin.conf \ scripts/xremote-login.conf \ scripts/xserver-config.conf \ diff --git a/tests/data/keys.conf b/tests/data/keys.conf new file mode 100644 index 00000000..08a0b873 --- /dev/null +++ b/tests/data/keys.conf @@ -0,0 +1,2 @@ +[keyring] +test-key=0123456789ABCDEF diff --git a/tests/scripts/allow-tcp-xorg-1.16.conf b/tests/scripts/allow-tcp-xorg-1.16.conf index 08cbc41a..e7db69c5 100644 --- a/tests/scripts/allow-tcp-xorg-1.16.conf +++ b/tests/scripts/allow-tcp-xorg-1.16.conf @@ -5,7 +5,7 @@ [test-xserver-config] version=1.16.0 -[Seat:*] +[SeatDefaults] autologin-user=have-password1 user-session=default xserver-allow-tcp=true diff --git a/tests/scripts/allow-tcp.conf b/tests/scripts/allow-tcp.conf index dcaf7e6d..26d8ea59 100644 --- a/tests/scripts/allow-tcp.conf +++ b/tests/scripts/allow-tcp.conf @@ -2,7 +2,7 @@ # Check can enable TCP listening # -[Seat:*] +[SeatDefaults] autologin-user=have-password1 user-session=default xserver-allow-tcp=true diff --git a/tests/scripts/audit-autologin.conf b/tests/scripts/audit-autologin.conf index 5216d1b0..c589a58c 100644 --- a/tests/scripts/audit-autologin.conf +++ b/tests/scripts/audit-autologin.conf @@ -5,7 +5,7 @@ [test-audit-config] check-events=true -[Seat:*] +[SeatDefaults] autologin-user=have-password1 user-session=default diff --git a/tests/scripts/vnc-command.conf b/tests/scripts/vnc-command.conf index a99cec7b..3a974b10 100644 --- a/tests/scripts/vnc-command.conf +++ b/tests/scripts/vnc-command.conf @@ -7,7 +7,6 @@ start-default-seat=false [VNCServer] enabled=true -port=9999 command=Xvnc -option #?*START-DAEMON @@ -15,9 +14,9 @@ command=Xvnc -option #?*WAIT # Start a VNC client -#?*START-VNC-CLIENT ARGS="::9999" +#?*START-VNC-CLIENT #?VNC-CLIENT START -#?VNC-CLIENT CONNECT SERVER=::9999 +#?VNC-CLIENT CONNECT # Xvnc server starts #?XSERVER-0 START GEOMETRY=1024x768 DEPTH=8 OPTION=TRUE diff --git a/tests/scripts/vnc-dimensions.conf b/tests/scripts/vnc-dimensions.conf index e1edba07..8acfff16 100644 --- a/tests/scripts/vnc-dimensions.conf +++ b/tests/scripts/vnc-dimensions.conf @@ -7,7 +7,6 @@ start-default-seat=false [VNCServer] enabled=true -port=9999 width=1440 height=900 depth=16 @@ -17,9 +16,9 @@ depth=16 #?*WAIT # Start a VNC client -#?*START-VNC-CLIENT ARGS="::9999" +#?*START-VNC-CLIENT #?VNC-CLIENT START -#?VNC-CLIENT CONNECT SERVER=::9999 +#?VNC-CLIENT CONNECT # Xvnc server starts #?XSERVER-0 START GEOMETRY=1440x900 DEPTH=16 OPTION=FALSE diff --git a/tests/scripts/vnc-login.conf b/tests/scripts/vnc-login.conf index def7cfe0..007d03fc 100644 --- a/tests/scripts/vnc-login.conf +++ b/tests/scripts/vnc-login.conf @@ -7,7 +7,6 @@ start-default-seat=false [VNCServer] enabled=true -port=9999 [SeatDefaults] user-session=default @@ -17,9 +16,9 @@ user-session=default #?*WAIT # Start a VNC client -#?*START-VNC-CLIENT ARGS="::9999" +#?*START-VNC-CLIENT #?VNC-CLIENT START -#?VNC-CLIENT CONNECT SERVER=::9999 +#?VNC-CLIENT CONNECT # Xvnc server starts #?XSERVER-0 START GEOMETRY=1024x768 DEPTH=8 OPTION=FALSE diff --git a/tests/scripts/vnc-open-file-descriptors.conf b/tests/scripts/vnc-open-file-descriptors.conf index ce54a393..a1fecad4 100644 --- a/tests/scripts/vnc-open-file-descriptors.conf +++ b/tests/scripts/vnc-open-file-descriptors.conf @@ -7,7 +7,6 @@ start-default-seat=false [VNCServer] enabled=true -port=9999 [SeatDefaults] user-session=default @@ -17,9 +16,9 @@ user-session=default #?*WAIT # Start a VNC client -#?*START-VNC-CLIENT ARGS="::9999" +#?*START-VNC-CLIENT #?VNC-CLIENT START -#?VNC-CLIENT CONNECT SERVER=::9999 +#?VNC-CLIENT CONNECT # Xvnc server starts #?XSERVER-0 START GEOMETRY=1024x768 DEPTH=8 OPTION=FALSE diff --git a/tests/scripts/xdmcp-client-xorg-1.16.conf b/tests/scripts/xdmcp-client-xorg-1.16.conf index c41cb13e..89b3c909 100644 --- a/tests/scripts/xdmcp-client-xorg-1.16.conf +++ b/tests/scripts/xdmcp-client-xorg-1.16.conf @@ -5,7 +5,7 @@ [test-xserver-config] version=1.16.0 -[Seat:*] +[SeatDefaults] xdmcp-manager=127.0.0.1 #?*START-DAEMON @@ -17,9 +17,8 @@ xdmcp-manager=127.0.0.1 #?XSERVER-0 INDICATE-READY #?XSERVER-0 ACCEPT-CONNECT -# Starts sending XDMCP queries -#?*XSERVER-0 START-XDMCP -#?XSERVER-0 SEND-QUERY +# Send an XDMCP query +#?*XSERVER-0 SEND-QUERY # Wait to check a greeter is not started #?*WAIT diff --git a/tests/scripts/xdmcp-client.conf b/tests/scripts/xdmcp-client.conf index 180cabbd..8fdbfb7a 100644 --- a/tests/scripts/xdmcp-client.conf +++ b/tests/scripts/xdmcp-client.conf @@ -3,8 +3,7 @@ # [SeatDefaults] -xdmcp-manager=localhost -xdmcp-port=9999 +xdmcp-manager=127.0.0.1 #?*START-DAEMON #?RUNNER DAEMON-START @@ -15,9 +14,8 @@ xdmcp-port=9999 #?XSERVER-0 INDICATE-READY #?XSERVER-0 ACCEPT-CONNECT -# Starts sending XDMCP queries -#?*XSERVER-0 START-XDMCP -#?XSERVER-0 SEND-QUERY +# Send an XDMCP query +#?*XSERVER-0 SEND-QUERY # Wait to check a greeter is not started #?*WAIT diff --git a/tests/scripts/xdmcp-client.conf.moved b/tests/scripts/xdmcp-client.conf.moved new file mode 100644 index 00000000..ea42cd8d --- /dev/null +++ b/tests/scripts/xdmcp-client.conf.moved @@ -0,0 +1,27 @@ +# +# Check can run a local XDMCP client +# + +[SeatDefaults] +xdmcp-manager=localhost +xdmcp-port=9999 + +#?*START-DAEMON +#?RUNNER DAEMON-START + +# X server starts +#?XSERVER-0 START VT=7 LISTEN-TCP SEAT=seat0 +#?*XSERVER-0 INDICATE-READY +#?XSERVER-0 INDICATE-READY +#?XSERVER-0 ACCEPT-CONNECT + +# Send an XDMCP queriy +#?*XSERVER-0 SEND-QUERY + +# Wait to check a greeter is not started +#?*WAIT + +# Cleanup +#?*STOP-DAEMON +#?XSERVER-0 TERMINATE SIGNAL=15 +#?RUNNER DAEMON-EXIT STATUS=0 diff --git a/tests/scripts/xdmcp-server-autologin.conf b/tests/scripts/xdmcp-server-autologin.conf index f0ac8740..cc151de5 100644 --- a/tests/scripts/xdmcp-server-autologin.conf +++ b/tests/scripts/xdmcp-server-autologin.conf @@ -20,14 +20,13 @@ autologin-user=have-password1 #?*START-XSERVER ARGS=":98 -query 127.0.0.1 -nolisten unix" #?XSERVER-98 START LISTEN-TCP NO-LISTEN-UNIX -# Start sending XDMCP queries -#?*XSERVER-98 START-XDMCP -#?XSERVER-98 SEND-QUERY - -# Negotiate with daemon +# Request to connect - daemon says OK +#?*XSERVER-98 SEND-QUERY #?XSERVER-98 GOT-WILLING AUTHENTICATION-NAME="" HOSTNAME="" STATUS="" -#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHORIZATION-NAMES="MIT-MAGIC-COOKIE-1" MFID="TEST XSERVER" -#?XSERVER-98 GOT-ACCEPT SESSION-ID=[0-9]* AUTHENTICATION-NAME="" AUTHORIZATION-NAME="MIT-MAGIC-COOKIE-1" + +# Connect - daemon says OK +#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHORIZATION-NAMES="MIT-MAGIC-COOKIE-1" +#?XSERVER-98 GOT-ACCEPT SESSION-ID=[0-9]+ AUTHENTICATION-NAME="" AUTHENTICATION-DATA= AUTHORIZATION-NAME="MIT-MAGIC-COOKIE-1" AUTHORIZATION-DATA=[0-9A-F]{32} #?*XSERVER-98 SEND-MANAGE # LightDM connects to X server diff --git a/tests/scripts/xdmcp-server-autologin.conf.moved b/tests/scripts/xdmcp-server-autologin.conf.moved new file mode 100644 index 00000000..f0ac8740 --- /dev/null +++ b/tests/scripts/xdmcp-server-autologin.conf.moved @@ -0,0 +1,45 @@ +# +# Check that a remote X server can autologin via XDMCP +# + +[LightDM] +start-default-seat=false + +[XDMCPServer] +enabled=true + +[SeatDefaults] +user-session=default +autologin-user=have-password1 + +#?*START-DAEMON +#?RUNNER DAEMON-START +#?*WAIT + +# Start a remote X server to log in with XDMCP +#?*START-XSERVER ARGS=":98 -query 127.0.0.1 -nolisten unix" +#?XSERVER-98 START LISTEN-TCP NO-LISTEN-UNIX + +# Start sending XDMCP queries +#?*XSERVER-98 START-XDMCP +#?XSERVER-98 SEND-QUERY + +# Negotiate with daemon +#?XSERVER-98 GOT-WILLING AUTHENTICATION-NAME="" HOSTNAME="" STATUS="" +#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHORIZATION-NAMES="MIT-MAGIC-COOKIE-1" MFID="TEST XSERVER" +#?XSERVER-98 GOT-ACCEPT SESSION-ID=[0-9]* AUTHENTICATION-NAME="" AUTHORIZATION-NAME="MIT-MAGIC-COOKIE-1" +#?*XSERVER-98 SEND-MANAGE + +# LightDM connects to X server +#?XSERVER-98 ACCEPT-CONNECT + +# Session starts +#?SESSION-X-127.0.0.1:98 START XDG_SESSION_TYPE=x11 XDG_SESSION_DESKTOP=default USER=have-password1 +#?LOGIN1 ACTIVATE-SESSION SESSION=c0 +#?XSERVER-98 ACCEPT-CONNECT +#?SESSION-X-127.0.0.1:98 CONNECT-XSERVER + +# Clean up +#?*STOP-DAEMON +#?SESSION-X-127.0.0.1:98 TERMINATE SIGNAL=15 +#?RUNNER DAEMON-EXIT STATUS=0 diff --git a/tests/scripts/xdmcp-server-double-login.conf b/tests/scripts/xdmcp-server-double-login.conf index 3c7a0506..455b4dc2 100644 --- a/tests/scripts/xdmcp-server-double-login.conf +++ b/tests/scripts/xdmcp-server-double-login.conf @@ -19,14 +19,13 @@ user-session=default #?*START-XSERVER ARGS=":98 -query 127.0.0.1 -nolisten unix" #?XSERVER-98 START LISTEN-TCP NO-LISTEN-UNIX -# Start sending XDMCP queries -#?*XSERVER-98 START-XDMCP -#?XSERVER-98 SEND-QUERY - -# Negotiate with daemon +# Request to connect - daemon says OK +#?*XSERVER-98 SEND-QUERY #?XSERVER-98 GOT-WILLING AUTHENTICATION-NAME="" HOSTNAME="" STATUS="" -#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHORIZATION-NAMES="MIT-MAGIC-COOKIE-1" MFID="TEST XSERVER" -#?XSERVER-98 GOT-ACCEPT SESSION-ID=[0-9]* AUTHENTICATION-NAME="" AUTHORIZATION-NAME="MIT-MAGIC-COOKIE-1" + +# Connect - daemon says OK +#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHORIZATION-NAMES="MIT-MAGIC-COOKIE-1" +#?XSERVER-98 GOT-ACCEPT SESSION-ID=[0-9]+ AUTHENTICATION-NAME="" AUTHENTICATION-DATA= AUTHORIZATION-NAME="MIT-MAGIC-COOKIE-1" AUTHORIZATION-DATA=[0-9A-F]{32} #?*XSERVER-98 SEND-MANAGE # LightDM connects to X server @@ -58,14 +57,13 @@ user-session=default #?*START-XSERVER ARGS=":99 -query 127.0.0.1 -nolisten unix" #?XSERVER-99 START LISTEN-TCP NO-LISTEN-UNIX -# Start sending XDMCP queries -#?*XSERVER-99 START-XDMCP -#?XSERVER-99 SEND-QUERY - -# Negotiate with daemon +# Request to connect - daemon says OK +#?*XSERVER-99 SEND-QUERY #?XSERVER-99 GOT-WILLING AUTHENTICATION-NAME="" HOSTNAME="" STATUS="" + +# Connect - daemon says OK #?*XSERVER-99 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHORIZATION-NAMES="MIT-MAGIC-COOKIE-1" MFID="TEST XSERVER" -#?XSERVER-99 GOT-ACCEPT SESSION-ID=[0-9]* AUTHENTICATION-NAME="" AUTHORIZATION-NAME="MIT-MAGIC-COOKIE-1" +#?XSERVER-99 GOT-ACCEPT SESSION-ID=[0-9]+ AUTHENTICATION-NAME="" AUTHENTICATION-DATA= AUTHORIZATION-NAME="MIT-MAGIC-COOKIE-1" AUTHORIZATION-DATA=[0-9A-F]{32} #?*XSERVER-99 SEND-MANAGE # LightDM connects to X server diff --git a/tests/scripts/xdmcp-server-double-login.conf.moved b/tests/scripts/xdmcp-server-double-login.conf.moved new file mode 100644 index 00000000..3c7a0506 --- /dev/null +++ b/tests/scripts/xdmcp-server-double-login.conf.moved @@ -0,0 +1,100 @@ +# +# Check that two remote X servers can login via XDMCP +# + +[LightDM] +start-default-seat=false + +[XDMCPServer] +enabled=true + +[SeatDefaults] +user-session=default + +#?*START-DAEMON +#?RUNNER DAEMON-START +#?*WAIT + +# Start a remote X server to log in with XDMCP +#?*START-XSERVER ARGS=":98 -query 127.0.0.1 -nolisten unix" +#?XSERVER-98 START LISTEN-TCP NO-LISTEN-UNIX + +# Start sending XDMCP queries +#?*XSERVER-98 START-XDMCP +#?XSERVER-98 SEND-QUERY + +# Negotiate with daemon +#?XSERVER-98 GOT-WILLING AUTHENTICATION-NAME="" HOSTNAME="" STATUS="" +#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHORIZATION-NAMES="MIT-MAGIC-COOKIE-1" MFID="TEST XSERVER" +#?XSERVER-98 GOT-ACCEPT SESSION-ID=[0-9]* AUTHENTICATION-NAME="" AUTHORIZATION-NAME="MIT-MAGIC-COOKIE-1" +#?*XSERVER-98 SEND-MANAGE + +# LightDM connects to X server +#?XSERVER-98 ACCEPT-CONNECT + +# Greeter starts and connects to remote X server +#?GREETER-X-127.0.0.1:98 START XDG_SESSION_CLASS=greeter +#?LOGIN1 ACTIVATE-SESSION SESSION=c0 +#?XSERVER-98 ACCEPT-CONNECT +#?GREETER-X-127.0.0.1:98 CONNECT-XSERVER +#?GREETER-X-127.0.0.1:98 CONNECT-TO-DAEMON +#?GREETER-X-127.0.0.1:98 CONNECTED-TO-DAEMON + +# Log in +#?*GREETER-X-127.0.0.1:98 AUTHENTICATE USERNAME=have-password1 +#?GREETER-X-127.0.0.1:98 SHOW-PROMPT TEXT="Password:" +#?*GREETER-X-127.0.0.1:98 RESPOND TEXT="password" +#?GREETER-X-127.0.0.1:98 AUTHENTICATION-COMPLETE USERNAME=have-password1 AUTHENTICATED=TRUE +#?*GREETER-X-127.0.0.1:98 START-SESSION +#?GREETER-X-127.0.0.1:98 TERMINATE SIGNAL=15 + +# Session starts +#?SESSION-X-127.0.0.1:98 START XDG_SESSION_TYPE=x11 XDG_SESSION_DESKTOP=default USER=have-password1 +#?LOGIN1 ACTIVATE-SESSION SESSION=c1 +#?XSERVER-98 ACCEPT-CONNECT +#?SESSION-X-127.0.0.1:98 CONNECT-XSERVER + +# Start a second remote X server to log in with XDMCP +#?*START-XSERVER ARGS=":99 -query 127.0.0.1 -nolisten unix" +#?XSERVER-99 START LISTEN-TCP NO-LISTEN-UNIX + +# Start sending XDMCP queries +#?*XSERVER-99 START-XDMCP +#?XSERVER-99 SEND-QUERY + +# Negotiate with daemon +#?XSERVER-99 GOT-WILLING AUTHENTICATION-NAME="" HOSTNAME="" STATUS="" +#?*XSERVER-99 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHORIZATION-NAMES="MIT-MAGIC-COOKIE-1" MFID="TEST XSERVER" +#?XSERVER-99 GOT-ACCEPT SESSION-ID=[0-9]* AUTHENTICATION-NAME="" AUTHORIZATION-NAME="MIT-MAGIC-COOKIE-1" +#?*XSERVER-99 SEND-MANAGE + +# LightDM connects to X server +#?XSERVER-99 ACCEPT-CONNECT + +# Greeter starts and connects to remote X server +#?GREETER-X-127.0.0.1:99 START XDG_SESSION_CLASS=greeter +#?LOGIN1 ACTIVATE-SESSION SESSION=c2 +#?XSERVER-99 ACCEPT-CONNECT +#?GREETER-X-127.0.0.1:99 CONNECT-XSERVER +#?GREETER-X-127.0.0.1:99 CONNECT-TO-DAEMON +#?GREETER-X-127.0.0.1:99 CONNECTED-TO-DAEMON + +# Log in +#?*GREETER-X-127.0.0.1:99 AUTHENTICATE USERNAME=have-password1 +#?GREETER-X-127.0.0.1:99 SHOW-PROMPT TEXT="Password:" +#?*GREETER-X-127.0.0.1:99 RESPOND TEXT="password" +#?GREETER-X-127.0.0.1:99 AUTHENTICATION-COMPLETE USERNAME=have-password1 AUTHENTICATED=TRUE +#?*GREETER-X-127.0.0.1:99 START-SESSION +#?GREETER-X-127.0.0.1:99 TERMINATE SIGNAL=15 + +# Session starts +#?SESSION-X-127.0.0.1:99 START XDG_SESSION_TYPE=x11 XDG_SESSION_DESKTOP=default USER=have-password1 +#?LOGIN1 ACTIVATE-SESSION SESSION=c3 +#?XSERVER-99 ACCEPT-CONNECT +#?SESSION-X-127.0.0.1:99 CONNECT-XSERVER + +# Clean up +#?*STOP-DAEMON +#?SESSION-X-127.0.0.1:98 TERMINATE SIGNAL=15 +#?SESSION-X-127.0.0.1:99 TERMINATE SIGNAL=15 +#?RUNNER DAEMON-EXIT STATUS=0 diff --git a/tests/scripts/xdmcp-server-guest.conf b/tests/scripts/xdmcp-server-guest.conf index 7cd25955..dc95f979 100644 --- a/tests/scripts/xdmcp-server-guest.conf +++ b/tests/scripts/xdmcp-server-guest.conf @@ -19,14 +19,13 @@ user-session=default #?*START-XSERVER ARGS=":98 -query 127.0.0.1 -nolisten unix" #?XSERVER-98 START LISTEN-TCP NO-LISTEN-UNIX -# Start sending XDMCP queries -#?*XSERVER-98 START-XDMCP -#?XSERVER-98 SEND-QUERY - -# Negotiate with daemon +# Request to connect - daemon says OK +#?*XSERVER-98 SEND-QUERY #?XSERVER-98 GOT-WILLING AUTHENTICATION-NAME="" HOSTNAME="" STATUS="" -#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHORIZATION-NAMES="MIT-MAGIC-COOKIE-1" MFID="TEST XSERVER" -#?XSERVER-98 GOT-ACCEPT SESSION-ID=[0-9]* AUTHENTICATION-NAME="" AUTHORIZATION-NAME="MIT-MAGIC-COOKIE-1" + +# Connect - daemon says OK +#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHORIZATION-NAMES="MIT-MAGIC-COOKIE-1" +#?XSERVER-98 GOT-ACCEPT SESSION-ID=[0-9]+ AUTHENTICATION-NAME="" AUTHENTICATION-DATA= AUTHORIZATION-NAME="MIT-MAGIC-COOKIE-1" AUTHORIZATION-DATA=[0-9A-F]{32} #?*XSERVER-98 SEND-MANAGE # LightDM connects to X server diff --git a/tests/scripts/xdmcp-server-guest.conf.moved b/tests/scripts/xdmcp-server-guest.conf.moved new file mode 100644 index 00000000..7cd25955 --- /dev/null +++ b/tests/scripts/xdmcp-server-guest.conf.moved @@ -0,0 +1,62 @@ +# +# Check can log into a guest account via XDMCP +# + +[LightDM] +start-default-seat=false + +[XDMCPServer] +enabled=true + +[SeatDefaults] +user-session=default + +#?*START-DAEMON +#?RUNNER DAEMON-START +#?*WAIT + +# Start a remote X server to log in with XDMCP +#?*START-XSERVER ARGS=":98 -query 127.0.0.1 -nolisten unix" +#?XSERVER-98 START LISTEN-TCP NO-LISTEN-UNIX + +# Start sending XDMCP queries +#?*XSERVER-98 START-XDMCP +#?XSERVER-98 SEND-QUERY + +# Negotiate with daemon +#?XSERVER-98 GOT-WILLING AUTHENTICATION-NAME="" HOSTNAME="" STATUS="" +#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHORIZATION-NAMES="MIT-MAGIC-COOKIE-1" MFID="TEST XSERVER" +#?XSERVER-98 GOT-ACCEPT SESSION-ID=[0-9]* AUTHENTICATION-NAME="" AUTHORIZATION-NAME="MIT-MAGIC-COOKIE-1" +#?*XSERVER-98 SEND-MANAGE + +# LightDM connects to X server +#?XSERVER-98 ACCEPT-CONNECT + +# Greeter starts and connects to remote X server +#?GREETER-X-127.0.0.1:98 START XDG_SESSION_CLASS=greeter +#?LOGIN1 ACTIVATE-SESSION SESSION=c0 +#?XSERVER-98 ACCEPT-CONNECT +#?GREETER-X-127.0.0.1:98 CONNECT-XSERVER +#?GREETER-X-127.0.0.1:98 CONNECT-TO-DAEMON +#?GREETER-X-127.0.0.1:98 CONNECTED-TO-DAEMON + +# Log in +#?*GREETER-X-127.0.0.1:98 AUTHENTICATE-GUEST +#?GREETER-X-127.0.0.1:98 AUTHENTICATION-COMPLETE AUTHENTICATED=TRUE +#?*GREETER-X-127.0.0.1:98 START-SESSION +#?GREETER-X-127.0.0.1:98 TERMINATE SIGNAL=15 + +# Guest account created +#?GUEST-ACCOUNT ADD USERNAME=guest-.* + +# Guest session starts +#?SESSION-X-127.0.0.1:98 START XDG_SESSION_TYPE=x11 XDG_SESSION_DESKTOP=default USER=guest-.* +#?LOGIN1 ACTIVATE-SESSION SESSION=c1 +#?XSERVER-98 ACCEPT-CONNECT +#?SESSION-X-127.0.0.1:98 CONNECT-XSERVER + +# Clean up +#?*STOP-DAEMON +#?SESSION-X-127.0.0.1:98 TERMINATE SIGNAL=15 +#?GUEST-ACCOUNT REMOVE USERNAME=guest-.* +#?RUNNER DAEMON-EXIT STATUS=0 diff --git a/tests/scripts/xdmcp-server-invalid-authentication.conf b/tests/scripts/xdmcp-server-invalid-authentication.conf new file mode 100644 index 00000000..76082ca7 --- /dev/null +++ b/tests/scripts/xdmcp-server-invalid-authentication.conf @@ -0,0 +1,33 @@ +# +# Check that a remote X server can't login if not using required authentication +# + +[LightDM] +start-default-seat=false + +[XDMCPServer] +enabled=true + +[SeatDefaults] +user-session=default +autologin-user=have-password1 + +#?*START-DAEMON +#?RUNNER DAEMON-START +#?*WAIT + +# Start a remote X server to log in with XDMCP +#?*START-XSERVER ARGS=":98 -query 127.0.0.1 -nolisten unix" +#?XSERVER-98 START LISTEN-TCP NO-LISTEN-UNIX + +# Connect with an invalid authentication name - daemon says no +#?*XSERVER-98 SEND-QUERY AUTHENTICATION-NAMES="NO-SUCH-AUTHENTICATION" +#?XSERVER-98 GOT-UNWILLING HOSTNAME="" STATUS="No matching authentication" + +# Try anyway - daemon declines +#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHENTICATION-NAME="NO-SUCH-AUTHENTICATION" AUTHORIZATION-NAMES="MIT-MAGIC-COOKIE-1" +#?XSERVER-98 GOT-DECLINE STATUS="No matching authentication, server only supports unauthenticated connections" AUTHENTICATION-NAME="" AUTHENTICATION-DATA= + +# Clean up +#?*STOP-DAEMON +#?RUNNER DAEMON-EXIT STATUS=0 diff --git a/tests/scripts/xdmcp-server-keep-alive.conf b/tests/scripts/xdmcp-server-keep-alive.conf new file mode 100644 index 00000000..124491a9 --- /dev/null +++ b/tests/scripts/xdmcp-server-keep-alive.conf @@ -0,0 +1,48 @@ +# +# Check that LightDM correctly responds to KeepAlive messages +# + +[LightDM] +start-default-seat=false + +[XDMCPServer] +enabled=true + +[SeatDefaults] +user-session=default +autologin-user=have-password1 + +#?*START-DAEMON +#?RUNNER DAEMON-START +#?*WAIT + +# Start a remote X server to log in with XDMCP +#?*START-XSERVER ARGS=":98 -query 127.0.0.1 -nolisten unix" +#?XSERVER-98 START LISTEN-TCP NO-LISTEN-UNIX + +# Request to connect - daemon says OK +#?*XSERVER-98 SEND-QUERY +#?XSERVER-98 GOT-WILLING AUTHENTICATION-NAME="" HOSTNAME="" STATUS="" + +# Connect - daemon says OK +#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHORIZATION-NAMES="MIT-MAGIC-COOKIE-1" +#?XSERVER-98 GOT-ACCEPT SESSION-ID=[0-9]+ AUTHENTICATION-NAME="" AUTHENTICATION-DATA= AUTHORIZATION-NAME="MIT-MAGIC-COOKIE-1" AUTHORIZATION-DATA=[0-9A-F]{32} +#?*XSERVER-98 SEND-MANAGE + +# LightDM connects to X server +#?XSERVER-98 ACCEPT-CONNECT + +# Session starts +#?SESSION-X-127.0.0.1:98 START DESKTOP_SESSION=default USER=have-password1 +#?LOGIN1 ACTIVATE-SESSION SESSION=c0 +#?XSERVER-98 ACCEPT-CONNECT +#?SESSION-X-127.0.0.1:98 CONNECT-XSERVER + +# Check daemon is alive +#?*XSERVER-98 SEND-KEEP-ALIVE +#?XSERVER-98 GOT-ALIVE SESSION-RUNNING=TRUE SESSION-ID=[0-9]+ + +# Clean up +#?*STOP-DAEMON +#?SESSION-X-127.0.0.1:98 TERMINATE SIGNAL=15 +#?RUNNER DAEMON-EXIT STATUS=0 diff --git a/tests/scripts/xdmcp-server-login.conf b/tests/scripts/xdmcp-server-login.conf index 42d8bc7f..87af9236 100644 --- a/tests/scripts/xdmcp-server-login.conf +++ b/tests/scripts/xdmcp-server-login.conf @@ -1,5 +1,5 @@ # -# Check that LightDM correctly negotiates the XDMCP and starts the session to the remote server. +# Check that a remote X server can login via XDMCP # [LightDM] @@ -7,7 +7,6 @@ start-default-seat=false [XDMCPServer] enabled=true -port=9999 [SeatDefaults] user-session=default @@ -17,17 +16,16 @@ user-session=default #?*WAIT # Start a remote X server to log in with XDMCP -#?*START-XSERVER ARGS=":98 -query localhost -port 9999 -nolisten unix" +#?*START-XSERVER ARGS=":98 -query 127.0.0.1 -nolisten unix" #?XSERVER-98 START LISTEN-TCP NO-LISTEN-UNIX -# Start sending XDMCP queries -#?*XSERVER-98 START-XDMCP -#?XSERVER-98 SEND-QUERY - -# Negotiate with daemon +# Request to connect - daemon says OK +#?*XSERVER-98 SEND-QUERY #?XSERVER-98 GOT-WILLING AUTHENTICATION-NAME="" HOSTNAME="" STATUS="" -#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHORIZATION-NAMES="MIT-MAGIC-COOKIE-1" MFID="TEST XSERVER" -#?XSERVER-98 GOT-ACCEPT SESSION-ID=[0-9]* AUTHENTICATION-NAME="" AUTHORIZATION-NAME="MIT-MAGIC-COOKIE-1" + +# Connect - daemon says OK +#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHORIZATION-NAMES="MIT-MAGIC-COOKIE-1" +#?XSERVER-98 GOT-ACCEPT SESSION-ID=[0-9]+ AUTHENTICATION-NAME="" AUTHENTICATION-DATA= AUTHORIZATION-NAME="MIT-MAGIC-COOKIE-1" AUTHORIZATION-DATA=[0-9A-F]{32} #?*XSERVER-98 SEND-MANAGE # LightDM connects to X server diff --git a/tests/scripts/xdmcp-server-open-file-descriptors.conf b/tests/scripts/xdmcp-server-open-file-descriptors.conf index 7606e154..fef6835a 100644 --- a/tests/scripts/xdmcp-server-open-file-descriptors.conf +++ b/tests/scripts/xdmcp-server-open-file-descriptors.conf @@ -7,7 +7,6 @@ start-default-seat=false [XDMCPServer] enabled=true -port=9999 [SeatDefaults] user-session=default @@ -17,17 +16,16 @@ user-session=default #?*WAIT # Start a remote X server to log in with XDMCP -#?*START-XSERVER ARGS=":98 -query localhost -port 9999 -nolisten unix" +#?*START-XSERVER ARGS=":98 -query 127.0.0.1 -nolisten unix" #?XSERVER-98 START LISTEN-TCP NO-LISTEN-UNIX -# Start sending XDMCP queries -#?*XSERVER-98 START-XDMCP -#?XSERVER-98 SEND-QUERY - -# Negotiate with daemon +# Request to connect - daemon says OK +#?*XSERVER-98 SEND-QUERY #?XSERVER-98 GOT-WILLING AUTHENTICATION-NAME="" HOSTNAME="" STATUS="" -#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHORIZATION-NAMES="MIT-MAGIC-COOKIE-1" MFID="TEST XSERVER" -#?XSERVER-98 GOT-ACCEPT SESSION-ID=[0-9]* AUTHENTICATION-NAME="" AUTHORIZATION-NAME="MIT-MAGIC-COOKIE-1" + +# Connect - daemon says OK +#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHORIZATION-NAMES="MIT-MAGIC-COOKIE-1" +#?XSERVER-98 GOT-ACCEPT SESSION-ID=[0-9]+ AUTHENTICATION-NAME="" AUTHENTICATION-DATA= AUTHORIZATION-NAME="MIT-MAGIC-COOKIE-1" AUTHORIZATION-DATA=[0-9A-F]{32} #?*XSERVER-98 SEND-MANAGE # LightDM connects to X server diff --git a/tests/scripts/xdmcp-server-request-invalid-authentication.conf b/tests/scripts/xdmcp-server-request-invalid-authentication.conf new file mode 100644 index 00000000..fbb63d2a --- /dev/null +++ b/tests/scripts/xdmcp-server-request-invalid-authentication.conf @@ -0,0 +1,29 @@ +# +# Check remote X server sending a request with an invalid authentication is declined +# + +[LightDM] +start-default-seat=false + +[XDMCPServer] +enabled=true + +#?*START-DAEMON +#?RUNNER DAEMON-START +#?*WAIT + +# Start a remote X server to log in with XDMCP +#?*START-XSERVER ARGS=":98 -query 127.0.0.1 -nolisten unix" +#?XSERVER-98 START LISTEN-TCP NO-LISTEN-UNIX + +# Request to connect - daemon says OK +#?*XSERVER-98 SEND-QUERY +#?XSERVER-98 GOT-WILLING AUTHENTICATION-NAME="" HOSTNAME="" STATUS="" + +# Connect with an invalid authentication - daemon declines +#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHENTICATION-NAME="NO-SUCH-AUTHENTICATION" AUTHORIZATION-NAMES="MIT-MAGIC-COOKIE-1" +#?XSERVER-98 GOT-DECLINE STATUS="No matching authentication, server only supports unauthenticated connections" AUTHENTICATION-NAME="" AUTHENTICATION-DATA= + +# Clean up +#?*STOP-DAEMON +#?RUNNER DAEMON-EXIT STATUS=0 diff --git a/tests/scripts/xdmcp-server-request-invalid-authorization.conf b/tests/scripts/xdmcp-server-request-invalid-authorization.conf new file mode 100644 index 00000000..47f41750 --- /dev/null +++ b/tests/scripts/xdmcp-server-request-invalid-authorization.conf @@ -0,0 +1,29 @@ +# +# Check remote X server sending a request with an invalid authorization is declined +# + +[LightDM] +start-default-seat=false + +[XDMCPServer] +enabled=true + +#?*START-DAEMON +#?RUNNER DAEMON-START +#?*WAIT + +# Start a remote X server to log in with XDMCP +#?*START-XSERVER ARGS=":98 -query 127.0.0.1 -nolisten unix" +#?XSERVER-98 START LISTEN-TCP NO-LISTEN-UNIX + +# Request to connect - daemon says OK +#?*XSERVER-98 SEND-QUERY +#?XSERVER-98 GOT-WILLING AUTHENTICATION-NAME="" HOSTNAME="" STATUS="" + +# Connect with an invalid authorization - daemon declines +#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHORIZATION-NAMES="NO-SUCH-AUTHORIZATION" +#?XSERVER-98 GOT-DECLINE STATUS="No matching authorization, server requires MIT-MAGIC-COOKIE-1" AUTHENTICATION-NAME="" AUTHENTICATION-DATA= + +# Clean up +#?*STOP-DAEMON +#?RUNNER DAEMON-EXIT STATUS=0 diff --git a/tests/scripts/xdmcp-server-request-without-addresses.conf b/tests/scripts/xdmcp-server-request-without-addresses.conf index b1604f69..f289d548 100644 --- a/tests/scripts/xdmcp-server-request-without-addresses.conf +++ b/tests/scripts/xdmcp-server-request-without-addresses.conf @@ -1,5 +1,5 @@ # -# Check remote X server sending a request without connections is ignored +# Check remote X server sending a request without connections is declined # [LightDM] @@ -7,24 +7,22 @@ start-default-seat=false [XDMCPServer] enabled=true -port=9999 #?*START-DAEMON #?RUNNER DAEMON-START #?*WAIT # Start a remote X server to log in with XDMCP -#?*START-XSERVER ARGS=":98 -query 127.0.0.1 -port 9999 -nolisten unix" +#?*START-XSERVER ARGS=":98 -query 127.0.0.1 -nolisten unix" #?XSERVER-98 START LISTEN-TCP NO-LISTEN-UNIX -# Start sending XDMCP queries -#?*XSERVER-98 START-XDMCP -#?XSERVER-98 SEND-QUERY - -# Negotiate with daemon +# Request to connect - daemon says OK +#?*XSERVER-98 SEND-QUERY #?XSERVER-98 GOT-WILLING AUTHENTICATION-NAME="" HOSTNAME="" STATUS="" -#?*XSERVER-98 SEND-REQUEST ADDRESSES="" AUTHORIZATION-NAMES="MIT-MAGIC-COOKIE-1" MFID="TEST XSERVER" -#?XSERVER-98 GOT-DECLINE STATUS="No valid address found" AUTHENTICATION-NAME="" + +# Connect without providing an address - daemon declines +#?*XSERVER-98 SEND-REQUEST ADDRESSES="" AUTHORIZATION-NAMES="MIT-MAGIC-COOKIE-1" +#?XSERVER-98 GOT-DECLINE STATUS="No valid address found" AUTHENTICATION-NAME="" AUTHENTICATION-DATA= # Clean up #?*STOP-DAEMON diff --git a/tests/scripts/xdmcp-server-request-without-authorization.conf b/tests/scripts/xdmcp-server-request-without-authorization.conf new file mode 100644 index 00000000..34499ac7 --- /dev/null +++ b/tests/scripts/xdmcp-server-request-without-authorization.conf @@ -0,0 +1,29 @@ +# +# Check remote X server sending a request without an authorization is declined +# + +[LightDM] +start-default-seat=false + +[XDMCPServer] +enabled=true + +#?*START-DAEMON +#?RUNNER DAEMON-START +#?*WAIT + +# Start a remote X server to log in with XDMCP +#?*START-XSERVER ARGS=":98 -query 127.0.0.1 -nolisten unix" +#?XSERVER-98 START LISTEN-TCP NO-LISTEN-UNIX + +# Request to connect - daemon says OK +#?*XSERVER-98 SEND-QUERY +#?XSERVER-98 GOT-WILLING AUTHENTICATION-NAME="" HOSTNAME="" STATUS="" + +# Connect without authorization - daemon says no +#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHORIZATION-NAMES="" +#?XSERVER-98 GOT-DECLINE STATUS="No matching authorization, server requires MIT-MAGIC-COOKIE-1" AUTHENTICATION-NAME="" AUTHENTICATION-DATA= + +# Clean up +#?*STOP-DAEMON +#?RUNNER DAEMON-EXIT STATUS=0 diff --git a/tests/scripts/xdmcp-server-xdm-authentication-invalid-authorization.conf b/tests/scripts/xdmcp-server-xdm-authentication-invalid-authorization.conf new file mode 100644 index 00000000..4b048e31 --- /dev/null +++ b/tests/scripts/xdmcp-server-xdm-authentication-invalid-authorization.conf @@ -0,0 +1,30 @@ +# +# Check that a remote X server needs both XDM authentication and authorization +# + +[LightDM] +start-default-seat=false + +[XDMCPServer] +enabled=true +key=test-key + +#?*START-DAEMON +#?RUNNER DAEMON-START +#?*WAIT + +# Start a remote X server to log in with XDMCP +#?*START-XSERVER ARGS=":98 -query 127.0.0.1 -nolisten unix" +#?XSERVER-98 START LISTEN-TCP NO-LISTEN-UNIX + +# Request to connect with XDM authentication - daemon says OK +#?*XSERVER-98 SEND-QUERY AUTHENTICATION-NAMES="XDM-AUTHENTICATION-1" +#?XSERVER-98 GOT-WILLING AUTHENTICATION-NAME="XDM-AUTHENTICATION-1" HOSTNAME="" STATUS="" + +# Connect with wrong authorization - daemon declines +#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHENTICATION-NAME="XDM-AUTHENTICATION-1" AUTHENTICATION-DATA="0123456789ABCDEF" AUTHORIZATION-NAMES="MIT-MAGIC-COOKIE-1" +#?XSERVER-98 GOT-DECLINE STATUS="No matching authorization, server requires XDM-AUTHORIZATION-1" AUTHENTICATION-NAME="XDM-AUTHENTICATION-1" AUTHENTICATION-DATA=E9D2BDD16E64C251 + +# Clean up +#?*STOP-DAEMON +#?RUNNER DAEMON-EXIT STATUS=0 diff --git a/tests/scripts/xdmcp-server-xdm-authentication-long-data.conf b/tests/scripts/xdmcp-server-xdm-authentication-long-data.conf new file mode 100644 index 00000000..de31641b --- /dev/null +++ b/tests/scripts/xdmcp-server-xdm-authentication-long-data.conf @@ -0,0 +1,30 @@ +# +# Check that a remote X server needs both XDM authentication and correct length authentication data +# + +[LightDM] +start-default-seat=false + +[XDMCPServer] +enabled=true +key=test-key + +#?*START-DAEMON +#?RUNNER DAEMON-START +#?*WAIT + +# Start a remote X server to log in with XDMCP +#?*START-XSERVER ARGS=":98 -query 127.0.0.1 -nolisten unix" +#?XSERVER-98 START LISTEN-TCP NO-LISTEN-UNIX + +# Request to connect with XDM authentication - daemon says OK +#?*XSERVER-98 SEND-QUERY AUTHENTICATION-NAMES="XDM-AUTHENTICATION-1" +#?XSERVER-98 GOT-WILLING AUTHENTICATION-NAME="XDM-AUTHENTICATION-1" HOSTNAME="" STATUS="" + +# Connect without any authentication data - daemon declines +#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHENTICATION-NAME="XDM-AUTHENTICATION-1" AUTHENTICATION-DATA="DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF" AUTHORIZATION-NAMES="XDM-AUTHORIZATION-1" +#?XSERVER-98 GOT-DECLINE STATUS="Invalid XDM-AUTHENTICATION-1 data provided" AUTHENTICATION-NAME="" AUTHENTICATION-DATA= + +# Clean up +#?*STOP-DAEMON +#?RUNNER DAEMON-EXIT STATUS=0 diff --git a/tests/scripts/xdmcp-server-xdm-authentication-missing-data.conf b/tests/scripts/xdmcp-server-xdm-authentication-missing-data.conf new file mode 100644 index 00000000..f71cee6d --- /dev/null +++ b/tests/scripts/xdmcp-server-xdm-authentication-missing-data.conf @@ -0,0 +1,30 @@ +# +# Check that a remote X server needs both XDM authentication and authentication data +# + +[LightDM] +start-default-seat=false + +[XDMCPServer] +enabled=true +key=test-key + +#?*START-DAEMON +#?RUNNER DAEMON-START +#?*WAIT + +# Start a remote X server to log in with XDMCP +#?*START-XSERVER ARGS=":98 -query 127.0.0.1 -nolisten unix" +#?XSERVER-98 START LISTEN-TCP NO-LISTEN-UNIX + +# Request to connect with XDM authentication - daemon says OK +#?*XSERVER-98 SEND-QUERY AUTHENTICATION-NAMES="XDM-AUTHENTICATION-1" +#?XSERVER-98 GOT-WILLING AUTHENTICATION-NAME="XDM-AUTHENTICATION-1" HOSTNAME="" STATUS="" + +# Connect without any authentication data - daemon declines +#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHENTICATION-NAME="XDM-AUTHENTICATION-1" AUTHENTICATION-DATA="" AUTHORIZATION-NAMES="XDM-AUTHORIZATION-1" +#?XSERVER-98 GOT-DECLINE STATUS="Invalid XDM-AUTHENTICATION-1 data provided" AUTHENTICATION-NAME="" AUTHENTICATION-DATA= + +# Clean up +#?*STOP-DAEMON +#?RUNNER DAEMON-EXIT STATUS=0 diff --git a/tests/scripts/xdmcp-server-xdm-authentication-missing-key.conf b/tests/scripts/xdmcp-server-xdm-authentication-missing-key.conf new file mode 100644 index 00000000..8a1bd1cf --- /dev/null +++ b/tests/scripts/xdmcp-server-xdm-authentication-missing-key.conf @@ -0,0 +1,16 @@ +# +# Check that a remote X server can't login if requires XDM authentication and we're not configured for it +# + +[LightDM] +start-default-seat=false + +[XDMCPServer] +enabled=true +key=no-such-key + +#?*START-DAEMON +#?RUNNER DAEMON-START + +# Daemon stops with error +#?RUNNER DAEMON-EXIT STATUS=1 diff --git a/tests/scripts/xdmcp-server-xdm-authentication-no-key.conf b/tests/scripts/xdmcp-server-xdm-authentication-no-key.conf new file mode 100644 index 00000000..b2144de6 --- /dev/null +++ b/tests/scripts/xdmcp-server-xdm-authentication-no-key.conf @@ -0,0 +1,29 @@ +# +# Check that a remote X server can't login if requires XDM authentication and we're not configured for it +# + +[LightDM] +start-default-seat=false + +[XDMCPServer] +enabled=true + +#?*START-DAEMON +#?RUNNER DAEMON-START +#?*WAIT + +# Start a remote X server to log in with XDMCP +#?*START-XSERVER ARGS=":98 -query 127.0.0.1 -nolisten unix" +#?XSERVER-98 START LISTEN-TCP NO-LISTEN-UNIX + +# Request to connect with XDM authentication - daemon says we don't do that +#?*XSERVER-98 SEND-QUERY AUTHENTICATION-NAMES="XDM-AUTHENTICATION-1" +#?XSERVER-98 GOT-UNWILLING HOSTNAME="" STATUS="No matching authentication" + +# Try anyway - daemon rejects +#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHENTICATION-NAME="XDM-AUTHENTICATION-1" AUTHORIZATION-NAME="XDM-AUTHORIZATION-1" +#?XSERVER-98 GOT-DECLINE STATUS="No matching authentication, server only supports unauthenticated connections" AUTHENTICATION-NAME="" AUTHENTICATION-DATA= + +# Clean up +#?*STOP-DAEMON +#?RUNNER DAEMON-EXIT STATUS=0 diff --git a/tests/scripts/xdmcp-server-xdm-authentication-required.conf b/tests/scripts/xdmcp-server-xdm-authentication-required.conf new file mode 100644 index 00000000..3c462940 --- /dev/null +++ b/tests/scripts/xdmcp-server-xdm-authentication-required.conf @@ -0,0 +1,30 @@ +# +# Check that a remote X server can't login if not using required authentication +# + +[LightDM] +start-default-seat=false + +[XDMCPServer] +enabled=true +key=test-key + +#?*START-DAEMON +#?RUNNER DAEMON-START +#?*WAIT + +# Start a remote X server to log in with XDMCP +#?*START-XSERVER ARGS=":98 -query 127.0.0.1 -nolisten unix" +#?XSERVER-98 START LISTEN-TCP NO-LISTEN-UNIX + +# Request to connection without authentication - daemon says we don't do that +#?*XSERVER-98 SEND-QUERY AUTHENTICATION-NAMES="" +#?XSERVER-98 GOT-UNWILLING HOSTNAME="" STATUS="No matching authentication, server requires XDM-AUTHENTICATION-1" + +# Try anyway - daemon rejects +#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHENTICATION-NAME="" AUTHORIZATION-NAMES="XDM-AUTHORIZATION-1" +#?XSERVER-98 GOT-DECLINE STATUS="No matching authentication, server requires XDM-AUTHENTICATION-1" AUTHENTICATION-NAME="" AUTHENTICATION-DATA= + +# Clean up +#?*STOP-DAEMON +#?RUNNER DAEMON-EXIT STATUS=0 diff --git a/tests/scripts/xdmcp-server-xdm-authentication-short-data.conf b/tests/scripts/xdmcp-server-xdm-authentication-short-data.conf new file mode 100644 index 00000000..ce6542f6 --- /dev/null +++ b/tests/scripts/xdmcp-server-xdm-authentication-short-data.conf @@ -0,0 +1,30 @@ +# +# Check that a remote X server needs both XDM authentication and correct length authentication data +# + +[LightDM] +start-default-seat=false + +[XDMCPServer] +enabled=true +key=test-key + +#?*START-DAEMON +#?RUNNER DAEMON-START +#?*WAIT + +# Start a remote X server to log in with XDMCP +#?*START-XSERVER ARGS=":98 -query 127.0.0.1 -nolisten unix" +#?XSERVER-98 START LISTEN-TCP NO-LISTEN-UNIX + +# Request to connect with XDM authentication - daemon says OK +#?*XSERVER-98 SEND-QUERY AUTHENTICATION-NAMES="XDM-AUTHENTICATION-1" +#?XSERVER-98 GOT-WILLING AUTHENTICATION-NAME="XDM-AUTHENTICATION-1" HOSTNAME="" STATUS="" + +# Connect without any authentication data - daemon declines +#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHENTICATION-NAME="XDM-AUTHENTICATION-1" AUTHENTICATION-DATA="00" AUTHORIZATION-NAMES="XDM-AUTHORIZATION-1" +#?XSERVER-98 GOT-DECLINE STATUS="Invalid XDM-AUTHENTICATION-1 data provided" AUTHENTICATION-NAME="" AUTHENTICATION-DATA= + +# Clean up +#?*STOP-DAEMON +#?RUNNER DAEMON-EXIT STATUS=0 diff --git a/tests/scripts/xdmcp-server-xdm-authentication.conf b/tests/scripts/xdmcp-server-xdm-authentication.conf new file mode 100644 index 00000000..5d587a72 --- /dev/null +++ b/tests/scripts/xdmcp-server-xdm-authentication.conf @@ -0,0 +1,45 @@ +# +# Check that a remote X server can autologin via XDMCP using XDM authentication +# + +[LightDM] +start-default-seat=false + +[XDMCPServer] +enabled=true +key=test-key + +[SeatDefaults] +user-session=default +autologin-user=have-password1 + +#?*START-DAEMON +#?RUNNER DAEMON-START +#?*WAIT + +# Start a remote X server to log in with XDMCP +#?*START-XSERVER ARGS=":98 -query 127.0.0.1 -nolisten unix" +#?XSERVER-98 START LISTEN-TCP NO-LISTEN-UNIX + +# Request to connect with XDM authentication - daemon says OK +#?*XSERVER-98 SEND-QUERY AUTHENTICATION-NAMES="XDM-AUTHENTICATION-1" +#?XSERVER-98 GOT-WILLING AUTHENTICATION-NAME="XDM-AUTHENTICATION-1" HOSTNAME="" STATUS="" + +# Connect - daemon says OK +#?*XSERVER-98 SEND-REQUEST ADDRESSES="127.0.0.1" AUTHENTICATION-NAME="XDM-AUTHENTICATION-1" AUTHENTICATION-DATA="0123456789ABCDEF" AUTHORIZATION-NAMES="XDM-AUTHORIZATION-1" +#?XSERVER-98 GOT-ACCEPT SESSION-ID=[0-9]+ AUTHENTICATION-NAME="XDM-AUTHENTICATION-1" AUTHENTICATION-DATA=E9D2BDD16E64C251 AUTHORIZATION-NAME="XDM-AUTHORIZATION-1" AUTHORIZATION-DATA=[0-9A-F]{16} +#?*XSERVER-98 SEND-MANAGE + +# LightDM connects to X server +#?XSERVER-98 ACCEPT-CONNECT + +# Session starts +#?SESSION-X-127.0.0.1:98 START DESKTOP_SESSION=default USER=have-password1 +#?LOGIN1 ACTIVATE-SESSION SESSION=c0 +#?XSERVER-98 ACCEPT-CONNECT +#?SESSION-X-127.0.0.1:98 CONNECT-XSERVER + +# Clean up +#?*STOP-DAEMON +#?SESSION-X-127.0.0.1:98 TERMINATE SIGNAL=15 +#?RUNNER DAEMON-EXIT STATUS=0 diff --git a/tests/scripts/xremote-autologin.conf b/tests/scripts/xremote-autologin.conf index cee1a2df..2895de1b 100644 --- a/tests/scripts/xremote-autologin.conf +++ b/tests/scripts/xremote-autologin.conf @@ -2,7 +2,7 @@ # Check can automatically log into a remote X server # -[Seat:*] +[SeatDefaults] type=xremote autologin-user=have-password1 user-session=default diff --git a/tests/scripts/xremote-login.conf b/tests/scripts/xremote-login.conf index 97b96976..ee970ee4 100644 --- a/tests/scripts/xremote-login.conf +++ b/tests/scripts/xremote-login.conf @@ -2,7 +2,7 @@ # Check can log into a remote X server # -[Seat:*] +[SeatDefaults] type=xremote user-session=default xserver-display-number=98 diff --git a/tests/scripts/xserver-config.conf b/tests/scripts/xserver-config.conf index b3206514..6aea5931 100644 --- a/tests/scripts/xserver-config.conf +++ b/tests/scripts/xserver-config.conf @@ -2,7 +2,7 @@ # Check can set X server configuration # -[Seat:*] +[SeatDefaults] autologin-user=have-password1 user-session=default xserver-config=custom.conf diff --git a/tests/src/X.c b/tests/src/X.c index e35d0086..618f8893 100644 --- a/tests/src/X.c +++ b/tests/src/X.c @@ -104,27 +104,46 @@ sigterm_cb (gpointer user_data) } static void -xdmcp_query_cb (XDMCPClient *client) +xdmcp_willing_cb (XDMCPClient *client, XDMCPWilling *message) { - static gboolean notified_query = FALSE; - - if (!notified_query) - { - status_notify ("%s SEND-QUERY", id); - notified_query = TRUE; - } + status_notify ("%s GOT-WILLING AUTHENTICATION-NAME=\"%s\" HOSTNAME=\"%s\" STATUS=\"%s\"", id, message->authentication_name, message->hostname, message->status); } static void -xdmcp_willing_cb (XDMCPClient *client, XDMCPWilling *message) +xdmcp_unwilling_cb (XDMCPClient *client, XDMCPUnwilling *message) { - status_notify ("%s GOT-WILLING AUTHENTICATION-NAME=\"%s\" HOSTNAME=\"%s\" STATUS=\"%s\"", id, message->authentication_name, message->hostname, message->status); + status_notify ("%s GOT-UNWILLING HOSTNAME=\"%s\" STATUS=\"%s\"", id, message->hostname, message->status); +} + +static gchar * +data_to_string (guint8 *data, gsize data_length) +{ + static gchar hex_char[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + gchar *text; + gsize i; + + text = malloc (data_length * 2 + 1); + for (i = 0; i < data_length; i++) + { + text[i*2] = hex_char [data[i] >> 4]; + text[i*2 + 1] = hex_char [data[i] & 0xF]; + } + text[i*2] = '\0'; + + return text; } static void xdmcp_accept_cb (XDMCPClient *client, XDMCPAccept *message) { - status_notify ("%s GOT-ACCEPT SESSION-ID=%d AUTHENTICATION-NAME=\"%s\" AUTHORIZATION-NAME=\"%s\"", id, message->session_id, message->authentication_name, message->authorization_name); + gchar *authentication_data_text, *authorization_data_text; + + authentication_data_text = data_to_string (message->authentication_data, message->authentication_data_length); + authorization_data_text = data_to_string (message->authorization_data, message->authorization_data_length); + status_notify ("%s GOT-ACCEPT SESSION-ID=%d AUTHENTICATION-NAME=\"%s\" AUTHENTICATION-DATA=%s AUTHORIZATION-NAME=\"%s\" AUTHORIZATION-DATA=%s", + id, message->session_id, message->authentication_name, authentication_data_text, message->authorization_name, authorization_data_text); + g_free (authentication_data_text); + g_free (authorization_data_text); xdmcp_session_id = message->session_id; @@ -137,7 +156,11 @@ xdmcp_accept_cb (XDMCPClient *client, XDMCPAccept *message) static void xdmcp_decline_cb (XDMCPClient *client, XDMCPDecline *message) { - status_notify ("%s GOT-DECLINE STATUS=\"%s\" AUTHENTICATION-NAME=\"%s\"", id, message->status, message->authentication_name); + gchar *authentication_data_text; + + authentication_data_text = data_to_string (message->authentication_data, message->authentication_data_length); + status_notify ("%s GOT-DECLINE STATUS=\"%s\" AUTHENTICATION-NAME=\"%s\" AUTHENTICATION-DATA=%s", id, message->status, message->authentication_name, authentication_data_text); + g_free (authentication_data_text); } static void @@ -147,6 +170,12 @@ xdmcp_failed_cb (XDMCPClient *client, XDMCPFailed *message) } static void +xdmcp_alive_cb (XDMCPClient *client, XDMCPAlive *message) +{ + status_notify ("%s GOT-ALIVE SESSION-RUNNING=%s SESSION-ID=%d", id, message->session_running ? "TRUE" : "FALSE", message->session_id); +} + +static void client_connected_cb (XServer *server, XClient *client) { status_notify ("%s ACCEPT-CONNECT", id); @@ -155,8 +184,21 @@ client_connected_cb (XServer *server, XClient *client) static void client_disconnected_cb (XServer *server, XClient *client) -{ - g_signal_handlers_disconnect_matched (client, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, NULL); +{ + g_signal_handlers_disconnect_matched (client, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, NULL); +} + +static guint8 +get_nibble (char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + else if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + else + return 0; } static void @@ -187,10 +229,113 @@ request_cb (const gchar *name, GHashTable *params) signal (SIGUSR1, handler); } - else if (strcmp (name, "START-XDMCP") == 0) + else if (strcmp (name, "SEND-QUERY") == 0) { + const gchar *authentication_names_list; + gchar **authentication_names; + if (!xdmcp_client_start (xdmcp_client)) quit (EXIT_FAILURE); + + authentication_names_list = g_hash_table_lookup (params, "AUTHENTICATION-NAMES"); + if (!authentication_names_list) + authentication_names_list = ""; + authentication_names = g_strsplit (authentication_names_list, " ", -1); + + xdmcp_client_send_query (xdmcp_client, authentication_names); + g_strfreev (authentication_names); + } + + else if (strcmp (name, "SEND-REQUEST") == 0) + { + const gchar *text, *addresses_list, *authentication_name, *authentication_data_text, *authorization_names_list, *mfid; + int request_display_number = display_number; + gchar **list, **authorization_names; + guint8 *authentication_data; + gsize authentication_data_length, list_length; + gint i; + GInetAddress **addresses; + + text = g_hash_table_lookup (params, "DISPLAY-NUMBER"); + if (text) + request_display_number = atoi (text); + addresses_list = g_hash_table_lookup (params, "ADDRESSES"); + if (!addresses_list) + addresses_list = ""; + authentication_name = g_hash_table_lookup (params, "AUTHENTICATION-NAME"); + if (!authentication_name) + authentication_name = ""; + authentication_data_text = g_hash_table_lookup (params, "AUTHENTICATION-DATA"); + if (!authentication_data_text) + authentication_data_text = ""; + authorization_names_list = g_hash_table_lookup (params, "AUTHORIZATION-NAMES"); + if (!authorization_names_list) + authorization_names_list = ""; + mfid = g_hash_table_lookup (params, "MFID"); + if (!mfid) + mfid = ""; + + list = g_strsplit (addresses_list, " ", -1); + list_length = g_strv_length (list); + addresses = g_malloc (sizeof (GInetAddress *) * (list_length + 1)); + for (i = 0; i < list_length; i++) + addresses[i] = g_inet_address_new_from_string (list[i]); + addresses[i] = NULL; + g_strfreev (list); + + authentication_data_length = strlen (authentication_data_text) / 2; + authentication_data = malloc (authentication_data_length); + for (i = 0; i < authentication_data_length; i++) + authentication_data[i] = get_nibble (authentication_data_text[i*2]) << 4 | get_nibble (authentication_data_text[i*2+1]); + + authorization_names = g_strsplit (authorization_names_list, " ", -1); + + xdmcp_client_send_request (xdmcp_client, + request_display_number, + addresses, + authentication_name, + authentication_data, authentication_data_length, + authorization_names, mfid); + g_free (authentication_data); + g_strfreev (authorization_names); + } + + else if (strcmp (name, "SEND-MANAGE") == 0) + { + const char *text, *display_class; + guint32 session_id = xdmcp_session_id; + guint16 manage_display_number = display_number; + + text = g_hash_table_lookup (params, "SESSION-ID"); + if (text) + session_id = atoi (text); + text = g_hash_table_lookup (params, "DISPLAY-NUMBER"); + if (text) + manage_display_number = atoi (text); + display_class = g_hash_table_lookup (params, "DISPLAY-CLASS"); + + if (!display_class) + display_class = ""; + xdmcp_client_send_manage (xdmcp_client, + session_id, + manage_display_number, + display_class); + } + + else if (strcmp (name, "SEND-KEEP-ALIVE") == 0) + { + const char *text; + guint32 session_id = xdmcp_session_id; + guint16 keep_alive_display_number = display_number; + + text = g_hash_table_lookup (params, "DISPLAY-NUMBER"); + if (text) + keep_alive_display_number = atoi (text); + text = g_hash_table_lookup (params, "SESSION-ID"); + if (text) + session_id = atoi (text); + + xdmcp_client_send_keep_alive (xdmcp_client, keep_alive_display_number, session_id); } else if (strcmp (name, "SEND-REQUEST") == 0) @@ -411,8 +556,8 @@ main (int argc, char **argv) status_connect (request_cb, id); xserver = x_server_new (display_number); - g_signal_connect (xserver, "client-connected", G_CALLBACK (client_connected_cb), NULL); - g_signal_connect (xserver, "client-disconnected", G_CALLBACK (client_disconnected_cb), NULL); + g_signal_connect (xserver, X_SERVER_SIGNAL_CLIENT_CONNECTED, G_CALLBACK (client_connected_cb), NULL); + g_signal_connect (xserver, X_SERVER_SIGNAL_CLIENT_DISCONNECTED, G_CALLBACK (client_disconnected_cb), NULL); status_text = g_string_new (""); g_string_printf (status_text, "%s START", id); @@ -466,7 +611,7 @@ main (int argc, char **argv) gchar *socket_path; socket_dir = g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "tmp", ".X11-unix", NULL); - g_mkdir_with_parents (socket_dir, 0755); + g_mkdir_with_parents (socket_dir, 0755); socket_filename = g_strdup_printf ("X%d", display_number); socket_path = g_build_filename (socket_dir, socket_filename, NULL); @@ -514,11 +659,12 @@ main (int argc, char **argv) xdmcp_client_set_hostname (xdmcp_client, xdmcp_host); if (xdmcp_port > 0) xdmcp_client_set_port (xdmcp_client, xdmcp_port); - g_signal_connect (xdmcp_client, "query", G_CALLBACK (xdmcp_query_cb), NULL); - g_signal_connect (xdmcp_client, "willing", G_CALLBACK (xdmcp_willing_cb), NULL); - g_signal_connect (xdmcp_client, "accept", G_CALLBACK (xdmcp_accept_cb), NULL); - g_signal_connect (xdmcp_client, "decline", G_CALLBACK (xdmcp_decline_cb), NULL); - g_signal_connect (xdmcp_client, "failed", G_CALLBACK (xdmcp_failed_cb), NULL); + g_signal_connect (xdmcp_client, XDMCP_CLIENT_SIGNAL_WILLING, G_CALLBACK (xdmcp_willing_cb), NULL); + g_signal_connect (xdmcp_client, XDMCP_CLIENT_SIGNAL_UNWILLING, G_CALLBACK (xdmcp_unwilling_cb), NULL); + g_signal_connect (xdmcp_client, XDMCP_CLIENT_SIGNAL_ACCEPT, G_CALLBACK (xdmcp_accept_cb), NULL); + g_signal_connect (xdmcp_client, XDMCP_CLIENT_SIGNAL_DECLINE, G_CALLBACK (xdmcp_decline_cb), NULL); + g_signal_connect (xdmcp_client, XDMCP_CLIENT_SIGNAL_FAILED, G_CALLBACK (xdmcp_failed_cb), NULL); + g_signal_connect (xdmcp_client, XDMCP_CLIENT_SIGNAL_ALIVE, G_CALLBACK (xdmcp_alive_cb), NULL); } g_main_loop_run (loop); diff --git a/tests/src/Xmir.c b/tests/src/Xmir.c index b133b0d3..8220a51e 100644 --- a/tests/src/Xmir.c +++ b/tests/src/Xmir.c @@ -213,8 +213,8 @@ main (int argc, char **argv) status_connect (request_cb, id); xserver = x_server_new (display_number); - g_signal_connect (xserver, "client-connected", G_CALLBACK (client_connected_cb), NULL); - g_signal_connect (xserver, "client-disconnected", G_CALLBACK (client_disconnected_cb), NULL); + g_signal_connect (xserver, X_SERVER_SIGNAL_CLIENT_CONNECTED, G_CALLBACK (client_connected_cb), NULL); + g_signal_connect (xserver, X_SERVER_SIGNAL_CLIENT_DISCONNECTED, G_CALLBACK (client_disconnected_cb), NULL); status_text = g_string_new (""); g_string_printf (status_text, "%s START", id); diff --git a/tests/src/libsystem.c b/tests/src/libsystem.c index ab8eeac8..8b392989 100644 --- a/tests/src/libsystem.c +++ b/tests/src/libsystem.c @@ -10,6 +10,8 @@ #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> +#include <sys/socket.h> +#include <netinet/in.h> #include <pwd.h> #include <unistd.h> #include <dirent.h> @@ -210,6 +212,9 @@ redirect_path (const gchar *path) if (g_str_has_prefix (path, "/tmp")) return g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "tmp", path + strlen ("/tmp"), NULL); + if (g_str_has_prefix (path, "/run")) + return g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "run", path + strlen ("/run"), NULL); + if (g_str_has_prefix (path, "/etc/xdg")) return g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "etc", "xdg", path + strlen ("/etc/xdg"), NULL); @@ -364,7 +369,7 @@ stat (const char *path, struct stat *buf) int (*_stat) (const char *path, struct stat *buf); gchar *new_path = NULL; int ret; - + _stat = (int (*)(const char *path, struct stat *buf)) dlsym (RTLD_NEXT, "stat"); new_path = redirect_path (path); @@ -396,7 +401,7 @@ __xstat (int version, const char *path, struct stat *buf) int (*___xstat) (int version, const char *path, struct stat *buf); gchar *new_path = NULL; int ret; - + ___xstat = (int (*)(int version, const char *path, struct stat *buf)) dlsym (RTLD_NEXT, "__xstat"); new_path = redirect_path (path); @@ -412,7 +417,7 @@ __xstat64 (int version, const char *path, struct stat64 *buf) int (*___xstat64) (int version, const char *path, struct stat64 *buf); gchar *new_path = NULL; int ret; - + ___xstat64 = (int (*)(int version, const char *path, struct stat64 *buf)) dlsym (RTLD_NEXT, "__xstat64"); new_path = redirect_path (path); @@ -428,7 +433,7 @@ __fxstatat(int ver, int dirfd, const char *pathname, struct stat *buf, int flags int (*___fxstatat) (int ver, int dirfd, const char *pathname, struct stat *buf, int flags); gchar *new_path = NULL; int ret; - + ___fxstatat = (int (*)(int ver, int dirfd, const char *pathname, struct stat *buf, int flags)) dlsym (RTLD_NEXT, "__fxstatat"); new_path = redirect_path (pathname); @@ -444,7 +449,7 @@ __fxstatat64(int ver, int dirfd, const char *pathname, struct stat64 *buf, int f int (*___fxstatat64) (int ver, int dirfd, const char *pathname, struct stat64 *buf, int flags); gchar *new_path = NULL; int ret; - + ___fxstatat64 = (int (*)(int ver, int dirfd, const char *pathname, struct stat64 *buf, int flags)) dlsym (RTLD_NEXT, "__fxstatat64"); new_path = redirect_path (pathname); @@ -467,7 +472,7 @@ opendir (const char *name) result = _opendir (new_path); g_free (new_path); - return result; + return result; } int @@ -557,6 +562,188 @@ ioctl (int d, unsigned long request, ...) } } +static void +add_port_redirect (int requested_port, int redirected_port) +{ + GKeyFile *file; + gchar *path, *name, *data; + + file = g_key_file_new (); + path = g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), ".port-redirects", NULL); + g_key_file_load_from_file (file, path, G_KEY_FILE_NONE, NULL); + + name = g_strdup_printf ("%d", requested_port); + g_key_file_set_integer (file, name, "redirected", redirected_port); + g_free (name); + + data = g_key_file_to_data (file, NULL, NULL); + g_file_set_contents (path, data, -1, NULL); + g_free (data); + g_free (path); + + g_key_file_free (file); +} + +static int +find_port_redirect (int port) +{ + GKeyFile *file; + gchar *path, *name; + int redirected_port; + + file = g_key_file_new (); + path = g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), ".port-redirects", NULL); + g_key_file_load_from_file (file, path, G_KEY_FILE_NONE, NULL); + g_free (path); + + name = g_strdup_printf ("%d", port); + redirected_port = g_key_file_get_integer (file, name, "redirected", NULL); + g_free (name); + g_key_file_free (file); + + return redirected_port; +} + +int +bind (int sockfd, const struct sockaddr *addr, socklen_t addrlen) +{ + int port = 0, redirected_port = 0; + int (*_bind) (int sockfd, const struct sockaddr *addr, socklen_t addrlen); + const struct sockaddr *modified_addr = addr; + struct sockaddr_in temp_addr; + struct sockaddr_in6 temp_addr6; + int retval; + + _bind = (int (*)(int sockfd, const struct sockaddr *addr, socklen_t addrlen)) dlsym (RTLD_NEXT, "bind"); + + switch (addr->sa_family) + { + case AF_INET: + port = ntohs (((const struct sockaddr_in *) addr)->sin_port); + redirected_port = find_port_redirect (port); + memcpy (&temp_addr, addr, sizeof (struct sockaddr_in)); + modified_addr = (struct sockaddr *) &temp_addr; + if (redirected_port != 0) + temp_addr.sin_port = htons (redirected_port); + else + temp_addr.sin_port = 0; + break; + case AF_INET6: + port = ntohs (((const struct sockaddr_in6 *) addr)->sin6_port); + redirected_port = find_port_redirect (port); + memcpy (&temp_addr6, addr, sizeof (struct sockaddr_in6)); + modified_addr = (struct sockaddr *) &temp_addr6; + if (redirected_port != 0) + temp_addr6.sin6_port = htons (redirected_port); + else + temp_addr6.sin6_port = 0; + break; + } + + retval = _bind (sockfd, modified_addr, addrlen); + + socklen_t temp_addr_len; + switch (addr->sa_family) + { + case AF_INET: + temp_addr_len = sizeof (temp_addr); + getsockname (sockfd, &temp_addr, &temp_addr_len); + if (redirected_port == 0) + { + redirected_port = ntohs (temp_addr.sin_port); + add_port_redirect (port, redirected_port); + } + break; + case AF_INET6: + temp_addr_len = sizeof (temp_addr6); + getsockname (sockfd, &temp_addr6, &temp_addr_len); + if (redirected_port == 0) + { + redirected_port = ntohs (temp_addr6.sin6_port); + add_port_redirect (port, redirected_port); + } + break; + } + + return retval; +} + +int +connect (int sockfd, const struct sockaddr *addr, socklen_t addrlen) +{ + int port, redirected_port; + const struct sockaddr *modified_addr = addr; + struct sockaddr_in temp_addr; + struct sockaddr_in6 temp_addr6; + int (*_connect) (int sockfd, const struct sockaddr *addr, socklen_t addrlen); + + _connect = (int (*)(int sockfd, const struct sockaddr *addr, socklen_t addrlen)) dlsym (RTLD_NEXT, "connect"); + + switch (addr->sa_family) + { + case AF_INET: + port = ntohs (((const struct sockaddr_in *) addr)->sin_port); + redirected_port = find_port_redirect (port); + if (redirected_port != 0) + { + memcpy (&temp_addr, addr, sizeof (struct sockaddr_in)); + temp_addr.sin_port = htons (redirected_port); + modified_addr = (struct sockaddr *) &temp_addr; + } + break; + case AF_INET6: + port = ntohs (((const struct sockaddr_in6 *) addr)->sin6_port); + redirected_port = find_port_redirect (port); + if (redirected_port != 0) + { + memcpy (&temp_addr6, addr, sizeof (struct sockaddr_in6)); + temp_addr6.sin6_port = htons (redirected_port); + modified_addr = (struct sockaddr *) &temp_addr6; + } + break; + } + + return _connect (sockfd, modified_addr, addrlen); +} + +ssize_t +sendto (int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) +{ + int port, redirected_port; + const struct sockaddr *modified_addr = dest_addr; + struct sockaddr_in temp_addr; + struct sockaddr_in6 temp_addr6; + ssize_t (*_sendto) (int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); + + _sendto = (ssize_t (*)(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen)) dlsym (RTLD_NEXT, "sendto"); + + switch (dest_addr->sa_family) + { + case AF_INET: + port = ntohs (((const struct sockaddr_in *) dest_addr)->sin_port); + redirected_port = find_port_redirect (port); + if (redirected_port != 0) + { + memcpy (&temp_addr, dest_addr, sizeof (struct sockaddr_in)); + temp_addr.sin_port = htons (redirected_port); + modified_addr = (struct sockaddr *) &temp_addr; + } + break; + case AF_INET6: + port = ntohs (((const struct sockaddr_in6 *) dest_addr)->sin6_port); + redirected_port = find_port_redirect (port); + if (redirected_port != 0) + { + memcpy (&temp_addr6, dest_addr, sizeof (struct sockaddr_in6)); + temp_addr6.sin6_port = htons (redirected_port); + modified_addr = (struct sockaddr *) &temp_addr6; + } + break; + } + + return _sendto (sockfd, buf, len, flags, modified_addr, addrlen); +} + int close (int fd) { @@ -574,7 +761,7 @@ static void free_user (gpointer data) { struct passwd *entry = data; - + g_free (entry->pw_name); g_free (entry->pw_passwd); g_free (entry->pw_gecos); @@ -667,10 +854,10 @@ struct passwd * getpwnam (const char *name) { GList *link; - + if (name == NULL) return NULL; - + load_passwd_file (); for (link = user_entries; link; link = link->next) @@ -708,7 +895,7 @@ static void free_group (gpointer data) { struct group *entry = data; - + g_free (entry->gr_name); g_free (entry->gr_passwd); g_strfreev (entry->gr_mem); @@ -865,7 +1052,7 @@ pam_authenticate (pam_handle_t *pamh, int flags) status_notify ("%s", status->str); g_string_free (status, TRUE); } - + if (strcmp (pamh->service_name, "test-remote") == 0) { int result; @@ -874,7 +1061,7 @@ pam_authenticate (pam_handle_t *pamh, int flags) msg = malloc (sizeof (struct pam_message *) * 1); msg[0] = malloc (sizeof (struct pam_message)); - msg[0]->msg_style = PAM_PROMPT_ECHO_ON; + msg[0]->msg_style = PAM_PROMPT_ECHO_ON; msg[0]->msg = "remote-login:"; result = pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr); free (msg[0]); @@ -937,7 +1124,7 @@ pam_authenticate (pam_handle_t *pamh, int flags) msg = malloc (sizeof (struct pam_message *) * 1); msg[0] = malloc (sizeof (struct pam_message)); - msg[0]->msg_style = PAM_PROMPT_ECHO_ON; + msg[0]->msg_style = PAM_PROMPT_ECHO_ON; msg[0]->msg = LOGIN_PROMPT; result = pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr); free (msg[0]); @@ -952,7 +1139,7 @@ pam_authenticate (pam_handle_t *pamh, int flags) free (resp); return PAM_CONV_ERR; } - + pamh->user = strdup (resp[0].resp); free (resp[0].resp); free (resp); @@ -1048,6 +1235,8 @@ pam_authenticate (pam_handle_t *pamh, int flags) result = pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr); free (msg[0]); free (msg); + if (result != PAM_SUCCESS) + return result; if (resp == NULL) return PAM_CONV_ERR; @@ -1090,7 +1279,7 @@ static const char * get_env_value (const char *name_value, const char *name) { int j; - + for (j = 0; name[j] && name_value[j] && name[j] == name_value[j]; j++); if (name[j] == '\0' && name_value[j] == '=') return &name_value[j + 1]; @@ -1185,13 +1374,13 @@ pam_get_item (const pam_handle_t *pamh, int item_type, const void **item) { if (pamh == NULL || item == NULL) return PAM_SYSTEM_ERR; - + switch (item_type) { case PAM_SERVICE: *item = pamh->service_name; return PAM_SUCCESS; - + case PAM_USER: *item = pamh->user; return PAM_SUCCESS; @@ -1203,11 +1392,11 @@ pam_get_item (const pam_handle_t *pamh, int item_type, const void **item) case PAM_RUSER: *item = pamh->ruser; return PAM_SUCCESS; - + case PAM_USER_PROMPT: *item = LOGIN_PROMPT; return PAM_SUCCESS; - + case PAM_TTY: *item = pamh->tty; return PAM_SUCCESS; @@ -1328,7 +1517,7 @@ pam_acct_mgmt (pam_handle_t *pamh, int flags) status_notify ("%s", status->str); g_string_free (status, TRUE); } - + if (!pamh->user) return PAM_USER_UNKNOWN; @@ -1684,7 +1873,7 @@ xcb_connect_to_display_with_auth_info (const char *display, xcb_auth_info_t *aut xcb_connection_t *c; gchar *socket_path; GError *error = NULL; - + c = malloc (sizeof (xcb_connection_t)); c->display = g_strdup (display); c->error = 0; diff --git a/tests/src/plymouth.c b/tests/src/plymouth.c index 1b70f304..ab9bc39d 100644 --- a/tests/src/plymouth.c +++ b/tests/src/plymouth.c @@ -38,7 +38,7 @@ main (int argc, char **argv) if (argc == 2 && strcmp (argv[1], "--has-active-vt") == 0) { if (g_key_file_get_boolean (config, "test-plymouth-config", "has-active-vt", NULL)) - { + { status_notify ("PLYMOUTH HAS-ACTIVE-VT=TRUE"); return EXIT_SUCCESS; } diff --git a/tests/src/status.c b/tests/src/status.c index 34062da4..e66e22bc 100644 --- a/tests/src/status.c +++ b/tests/src/status.c @@ -24,7 +24,7 @@ status_request_cb (GSocket *socket, GIOCondition condition, gpointer data) gchar *id, *name = NULL; gboolean id_matches; GHashTable *params; - GError *error = NULL; + GError *error = NULL; n_read = g_socket_receive (socket, (gchar *)&length, sizeof (length), NULL, &error); if (n_read > 0) diff --git a/tests/src/status.h b/tests/src/status.h index 29d19370..f22c888b 100644 --- a/tests/src/status.h +++ b/tests/src/status.h @@ -4,7 +4,7 @@ #ifdef __cplusplus extern "C" { #endif - + #include <glib-object.h> typedef void (*StatusRequestFunc)(const gchar *name, GHashTable *params); diff --git a/tests/src/test-runner.c b/tests/src/test-runner.c index bace8929..234356eb 100644 --- a/tests/src/test-runner.c +++ b/tests/src/test-runner.c @@ -2449,6 +2449,8 @@ main (int argc, char **argv) if (!g_key_file_has_key (config, "test-runner-config", "have-config", NULL) || g_key_file_get_boolean (config, "test-runner-config", "have-config", NULL)) if (system (g_strdup_printf ("cp %s %s/etc/lightdm/lightdm.conf", config_path, temp_dir))) perror ("Failed to copy configuration"); + if (system (g_strdup_printf ("cp %s/tests/data/keys.conf %s/etc/lightdm/", SRCDIR, temp_dir))) + perror ("Failed to copy key configuration"); additional_system_config = g_key_file_get_string (config, "test-runner-config", "additional-system-config", NULL); if (additional_system_config) diff --git a/tests/src/vnc-client.c b/tests/src/vnc-client.c index a8a4b591..f70cd568 100644 --- a/tests/src/vnc-client.c +++ b/tests/src/vnc-client.c @@ -12,13 +12,9 @@ static GKeyFile *config; int main (int argc, char **argv) { - gchar *server_address; - gchar *hostname, *c; - gint port; GError *error = NULL; GSocket *socket; - GSocketConnectable *address; - GSocketAddressEnumerator *enumerator; + GSocketAddress *address; gboolean result; gchar buffer[1024]; gssize n_read, n_sent; @@ -33,13 +29,8 @@ main (int argc, char **argv) config = g_key_file_new (); g_key_file_load_from_file (config, g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "script", NULL), G_KEY_FILE_NONE, NULL); - - if (argc > 1) - server_address = g_strdup (argv[1]); - else - server_address = g_strdup (":0"); - status_notify ("VNC-CLIENT CONNECT SERVER=%s", server_address); + status_notify ("VNC-CLIENT CONNECT"); socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, &error); if (error) @@ -48,48 +39,9 @@ main (int argc, char **argv) if (!socket) return EXIT_FAILURE; - hostname = g_strdup (server_address); - c = strchr (hostname, ':'); - if (c) - { - *c = '\0'; - gchar *port_string = c + 1; - if (g_str_has_prefix (port_string, ":")) - port = atoi (port_string + 1); - else - port = 5900 + atoi (port_string); - } - else - port = 5900; - if (strcmp (hostname, "") == 0) - { - g_free (hostname); - hostname = g_strdup ("localhost"); - } - - address = g_network_address_new (hostname, port); - enumerator = g_socket_connectable_enumerate (address); - result = FALSE; - while (TRUE) - { - GSocketAddress *socket_address; - GError *e = NULL; - - socket_address = g_socket_address_enumerator_next (enumerator, NULL, &e); - if (e) - g_warning ("Failed to get socket address: %s", e->message); - g_clear_error (&e); - if (!socket_address) - break; - - result = g_socket_connect (socket, socket_address, NULL, error ? NULL : &error); - g_object_unref (socket_address); - if (result) - { - g_clear_error (&error); - break; - } - } + address = g_inet_socket_address_new (g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4), 5900); + result = g_socket_connect (socket, address, NULL, &error); + g_object_unref (address); if (error) g_warning ("Unable to connect VNC socket: %s", error->message); g_clear_error (&error); diff --git a/tests/src/x-authority.c b/tests/src/x-authority.c index 5f692fe0..6344b4a2 100644 --- a/tests/src/x-authority.c +++ b/tests/src/x-authority.c @@ -68,10 +68,10 @@ x_authority_match_local (XAuthority *authority, const gchar *authorization_name) for (link = authority->priv->records; link; link = link->next) { XAuthorityRecord *record = link->data; - + if (strcmp (record->priv->authorization_name, authorization_name) != 0) continue; - + if (record->priv->family == XAUTH_FAMILY_WILD || record->priv->family == XAUTH_FAMILY_LOCAL) return record; } @@ -87,10 +87,10 @@ x_authority_match_localhost (XAuthority *authority, const gchar *authorization_n for (link = authority->priv->records; link; link = link->next) { XAuthorityRecord *record = link->data; - + if (strcmp (record->priv->authorization_name, authorization_name) != 0) continue; - + if (record->priv->family == XAUTH_FAMILY_WILD || record->priv->family == XAUTH_FAMILY_LOCALHOST) return record; } @@ -193,7 +193,7 @@ x_authority_record_check_cookie (XAuthorityRecord *record, const guint8 *cookie_ if (strcmp (record->priv->authorization_name, "MIT-MAGIC-COOKIE-1") != 0) return FALSE; - + if (cookie_data_length != record->priv->authorization_data_length) return FALSE; diff --git a/tests/src/x-server.c b/tests/src/x-server.c index a9ae7f2f..d756c58c 100644 --- a/tests/src/x-server.c +++ b/tests/src/x-server.c @@ -37,7 +37,7 @@ struct XServerPrivate struct XClientPrivate { XServer *server; - GSocket *socket; + GSocket *socket; GIOChannel *channel; }; @@ -52,7 +52,7 @@ void x_client_send_failed (XClient *client, const gchar *reason) { gchar *message; - + message = g_strdup_printf ("FAILED:%s", reason); errno = 0; if (send (g_io_channel_unix_get_fd (client->priv->channel), message, strlen (message), 0) != strlen (message)) @@ -60,7 +60,7 @@ x_client_send_failed (XClient *client, const gchar *reason) g_free (message); } -void +void x_client_send_success (XClient *client) { gchar *message; @@ -90,7 +90,7 @@ x_client_class_init (XClientClass *klass) g_type_class_add_private (klass, sizeof (XClientPrivate)); x_client_signals[X_CLIENT_DISCONNECTED] = - g_signal_new ("disconnected", + g_signal_new (X_CLIENT_SIGNAL_DISCONNECTED, G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (XClientClass, disconnected), @@ -132,7 +132,7 @@ socket_connect_cb (GIOChannel *channel, GIOCondition condition, gpointer data) client = g_object_new (x_client_get_type (), NULL); client->priv->server = server; - g_signal_connect (client, "disconnected", G_CALLBACK (x_client_disconnected_cb), server); + g_signal_connect (client, X_CLIENT_SIGNAL_DISCONNECTED, G_CALLBACK (x_client_disconnected_cb), server); client->priv->socket = data_socket; client->priv->channel = g_io_channel_unix_new (g_socket_get_fd (data_socket)); g_hash_table_insert (server->priv->clients, client->priv->channel, client); @@ -195,7 +195,7 @@ x_server_class_init (XServerClass *klass) object_class->finalize = x_server_finalize; g_type_class_add_private (klass, sizeof (XServerPrivate)); x_server_signals[X_SERVER_CLIENT_CONNECTED] = - g_signal_new ("client-connected", + g_signal_new (X_SERVER_SIGNAL_CLIENT_CONNECTED, G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (XServerClass, client_connected), @@ -203,7 +203,7 @@ x_server_class_init (XServerClass *klass) NULL, G_TYPE_NONE, 1, x_client_get_type ()); x_server_signals[X_SERVER_CLIENT_DISCONNECTED] = - g_signal_new ("client-disconnected", + g_signal_new (X_SERVER_SIGNAL_CLIENT_DISCONNECTED, G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (XServerClass, client_disconnected), diff --git a/tests/src/x-server.h b/tests/src/x-server.h index 5f5b4728..7ce8c3fe 100644 --- a/tests/src/x-server.h +++ b/tests/src/x-server.h @@ -6,6 +6,11 @@ G_BEGIN_DECLS +#define X_CLIENT_SIGNAL_DISCONNECTED "disconnected" + +#define X_SERVER_SIGNAL_CLIENT_CONNECTED "client-connected" +#define X_SERVER_SIGNAL_CLIENT_DISCONNECTED "client-disconnected" + typedef struct XClientPrivate XClientPrivate; typedef struct 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); } diff --git a/tests/src/xdmcp-client.h b/tests/src/xdmcp-client.h index 0f08fcc6..89e97b7b 100644 --- a/tests/src/xdmcp-client.h +++ b/tests/src/xdmcp-client.h @@ -7,6 +7,13 @@ #define XDMCP_VERSION 1 #define XDMCP_PORT 177 +#define XDMCP_CLIENT_SIGNAL_WILLING "willing" +#define XDMCP_CLIENT_SIGNAL_UNWILLING "unwilling" +#define XDMCP_CLIENT_SIGNAL_ACCEPT "accept" +#define XDMCP_CLIENT_SIGNAL_DECLINE "decline" +#define XDMCP_CLIENT_SIGNAL_FAILED "failed" +#define XDMCP_CLIENT_SIGNAL_ALIVE "alive" + typedef struct { gchar *authentication_name; @@ -16,8 +23,16 @@ typedef struct typedef struct { + gchar *hostname; + gchar *status; +} XDMCPUnwilling; + +typedef struct +{ guint32 session_id; gchar *authentication_name; + guint16 authentication_data_length; + guint8 *authentication_data; gchar *authorization_name; guint16 authorization_data_length; guint8 *authorization_data; @@ -27,6 +42,8 @@ typedef struct { gchar *status; gchar *authentication_name; + guint16 authentication_data_length; + guint8 *authentication_data; } XDMCPDecline; typedef struct @@ -35,6 +52,12 @@ typedef struct gchar *status; } XDMCPFailed; +typedef struct +{ + gboolean session_running; + guint32 session_id; +} XDMCPAlive; + typedef struct XDMCPClientPrivate XDMCPClientPrivate; typedef struct @@ -46,11 +69,12 @@ typedef struct typedef struct { GObjectClass parent_class; - void (*query)(XDMCPClient *client); void (*willing)(XDMCPClient *client, XDMCPWilling *message); + void (*unwilling)(XDMCPClient *client, XDMCPUnwilling *message); void (*accept)(XDMCPClient *client, XDMCPAccept *message); void (*decline)(XDMCPClient *client, XDMCPDecline *message); void (*failed)(XDMCPClient *client, XDMCPFailed *message); + void (*alive)(XDMCPClient *client, XDMCPAlive *message); } XDMCPClientClass; GType xdmcp_client_get_type (void); @@ -65,7 +89,11 @@ gboolean xdmcp_client_start (XDMCPClient *client); GInetAddress *xdmcp_client_get_local_address (XDMCPClient *client); -void xdmcp_client_send_query (XDMCPClient *client); +void xdmcp_client_send_query (XDMCPClient *client, gchar **authentication_names); + +void xdmcp_client_send_broadcast_query (XDMCPClient *client, gchar **authentication_names); + +void xdmcp_client_send_indirect_query (XDMCPClient *client, gchar **authentication_names); void xdmcp_client_send_request (XDMCPClient *client, guint16 display_number, @@ -74,7 +102,9 @@ void xdmcp_client_send_request (XDMCPClient *client, const guint8 *authentication_data, guint16 authentication_data_length, gchar **authorization_names, const gchar *mfid); -void xdmcp_client_send_manage (XDMCPClient *client, guint32 session_id, guint16 display_number, gchar *display_class); +void xdmcp_client_send_manage (XDMCPClient *client, guint32 session_id, guint16 display_number, const gchar *display_class); + +void xdmcp_client_send_keep_alive (XDMCPClient *client, guint16 display_number, guint32 session_id); G_END_DECLS diff --git a/tests/test-xdmcp-server-invalid-authentication b/tests/test-xdmcp-server-invalid-authentication new file mode 100755 index 00000000..c918e053 --- /dev/null +++ b/tests/test-xdmcp-server-invalid-authentication @@ -0,0 +1,2 @@ +#!/bin/sh +./src/dbus-env ./src/test-runner xdmcp-server-invalid-authentication test-gobject-greeter diff --git a/tests/test-xdmcp-server-keep-alive b/tests/test-xdmcp-server-keep-alive new file mode 100755 index 00000000..f6190de3 --- /dev/null +++ b/tests/test-xdmcp-server-keep-alive @@ -0,0 +1,2 @@ +#!/bin/sh +./src/dbus-env ./src/test-runner xdmcp-server-keep-alive test-gobject-greeter diff --git a/tests/test-xdmcp-server-request-invalid-authentication b/tests/test-xdmcp-server-request-invalid-authentication new file mode 100755 index 00000000..f36894ba --- /dev/null +++ b/tests/test-xdmcp-server-request-invalid-authentication @@ -0,0 +1,2 @@ +#!/bin/sh +./src/dbus-env ./src/test-runner xdmcp-server-request-invalid-authentication test-gobject-greeter diff --git a/tests/test-xdmcp-server-request-invalid-authorization b/tests/test-xdmcp-server-request-invalid-authorization new file mode 100755 index 00000000..eb71dd1c --- /dev/null +++ b/tests/test-xdmcp-server-request-invalid-authorization @@ -0,0 +1,2 @@ +#!/bin/sh +./src/dbus-env ./src/test-runner xdmcp-server-request-invalid-authorization test-gobject-greeter diff --git a/tests/test-xdmcp-server-request-without-authorization b/tests/test-xdmcp-server-request-without-authorization new file mode 100755 index 00000000..c07cad6d --- /dev/null +++ b/tests/test-xdmcp-server-request-without-authorization @@ -0,0 +1,2 @@ +#!/bin/sh +./src/dbus-env ./src/test-runner xdmcp-server-request-without-authorization test-gobject-greeter diff --git a/tests/test-xdmcp-server-xdm-authentication b/tests/test-xdmcp-server-xdm-authentication new file mode 100755 index 00000000..21fbf992 --- /dev/null +++ b/tests/test-xdmcp-server-xdm-authentication @@ -0,0 +1,2 @@ +#!/bin/sh +./src/dbus-env ./src/test-runner xdmcp-server-xdm-authentication test-gobject-greeter diff --git a/tests/test-xdmcp-server-xdm-authentication-invalid-authorization b/tests/test-xdmcp-server-xdm-authentication-invalid-authorization new file mode 100755 index 00000000..10e87ea9 --- /dev/null +++ b/tests/test-xdmcp-server-xdm-authentication-invalid-authorization @@ -0,0 +1,2 @@ +#!/bin/sh +./src/dbus-env ./src/test-runner xdmcp-server-xdm-authentication-invalid-authorization test-gobject-greeter diff --git a/tests/test-xdmcp-server-xdm-authentication-long-data b/tests/test-xdmcp-server-xdm-authentication-long-data new file mode 100755 index 00000000..9d203f2e --- /dev/null +++ b/tests/test-xdmcp-server-xdm-authentication-long-data @@ -0,0 +1,2 @@ +#!/bin/sh +./src/dbus-env ./src/test-runner xdmcp-server-xdm-authentication-long-data test-gobject-greeter diff --git a/tests/test-xdmcp-server-xdm-authentication-missing-data b/tests/test-xdmcp-server-xdm-authentication-missing-data new file mode 100755 index 00000000..6c153273 --- /dev/null +++ b/tests/test-xdmcp-server-xdm-authentication-missing-data @@ -0,0 +1,2 @@ +#!/bin/sh +./src/dbus-env ./src/test-runner xdmcp-server-xdm-authentication-missing-data test-gobject-greeter diff --git a/tests/test-xdmcp-server-xdm-authentication-missing-key b/tests/test-xdmcp-server-xdm-authentication-missing-key new file mode 100755 index 00000000..5f94e062 --- /dev/null +++ b/tests/test-xdmcp-server-xdm-authentication-missing-key @@ -0,0 +1,2 @@ +#!/bin/sh +./src/dbus-env ./src/test-runner xdmcp-server-xdm-authentication-missing-key test-gobject-greeter diff --git a/tests/test-xdmcp-server-xdm-authentication-no-key b/tests/test-xdmcp-server-xdm-authentication-no-key new file mode 100755 index 00000000..003f0045 --- /dev/null +++ b/tests/test-xdmcp-server-xdm-authentication-no-key @@ -0,0 +1,2 @@ +#!/bin/sh +./src/dbus-env ./src/test-runner xdmcp-server-xdm-authentication-no-key test-gobject-greeter diff --git a/tests/test-xdmcp-server-xdm-authentication-required b/tests/test-xdmcp-server-xdm-authentication-required new file mode 100755 index 00000000..f2d3624f --- /dev/null +++ b/tests/test-xdmcp-server-xdm-authentication-required @@ -0,0 +1,2 @@ +#!/bin/sh +./src/dbus-env ./src/test-runner xdmcp-server-xdm-authentication-required test-gobject-greeter diff --git a/tests/test-xdmcp-server-xdm-authentication-short-data b/tests/test-xdmcp-server-xdm-authentication-short-data new file mode 100755 index 00000000..31e2026d --- /dev/null +++ b/tests/test-xdmcp-server-xdm-authentication-short-data @@ -0,0 +1,2 @@ +#!/bin/sh +./src/dbus-env ./src/test-runner xdmcp-server-xdm-authentication-short-data test-gobject-greeter |