diff options
author | Robert Ancell <robert.ancell@canonical.com> | 2015-10-30 12:10:32 +1300 |
---|---|---|
committer | Robert Ancell <robert.ancell@canonical.com> | 2015-10-30 12:10:32 +1300 |
commit | 4adae0d2ba823477edbbba6d3b75f0e01e87b676 (patch) | |
tree | d5098454d78550432371be0e4c0097731226d934 | |
parent | adb9291b3783e2c2ce9ae316b1a9d041c32a88c6 (diff) | |
download | lightdm-4adae0d2ba823477edbbba6d3b75f0e01e87b676.tar.gz |
Implement XDMCP ForwardQuery
-rw-r--r-- | src/xdmcp-protocol.c | 24 | ||||
-rw-r--r-- | src/xdmcp-protocol.h | 4 | ||||
-rw-r--r-- | src/xdmcp-server.c | 53 |
3 files changed, 65 insertions, 16 deletions
diff --git a/src/xdmcp-protocol.c b/src/xdmcp-protocol.c index f45e7aeb..2901837b 100644 --- a/src/xdmcp-protocol.c +++ b/src/xdmcp-protocol.c @@ -213,8 +213,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: @@ -326,8 +326,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: @@ -444,7 +444,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; @@ -466,10 +466,14 @@ 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')", @@ -565,8 +569,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 1c7a639b..d0a99cff 100644 --- a/src/xdmcp-protocol.h +++ b/src/xdmcp-protocol.h @@ -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 085352e7..01bf485e 100644 --- a/src/xdmcp-server.c +++ b/src/xdmcp-server.c @@ -199,17 +199,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) { @@ -240,6 +240,49 @@ handle_query (XDMCPServer *server, GSocket *socket, GSocketAddress *address, XDM 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) { @@ -636,8 +679,10 @@ read_cb (GSocket *socket, GIOCondition condition, XDMCPServer *server) 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); case XDMCP_Request: handle_request (server, socket, address, packet); break; |