summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Ancell <robert.ancell@canonical.com>2015-10-30 12:10:32 +1300
committerRobert Ancell <robert.ancell@canonical.com>2015-10-30 12:10:32 +1300
commit4adae0d2ba823477edbbba6d3b75f0e01e87b676 (patch)
treed5098454d78550432371be0e4c0097731226d934
parentadb9291b3783e2c2ce9ae316b1a9d041c32a88c6 (diff)
downloadlightdm-4adae0d2ba823477edbbba6d3b75f0e01e87b676.tar.gz
Implement XDMCP ForwardQuery
-rw-r--r--src/xdmcp-protocol.c24
-rw-r--r--src/xdmcp-protocol.h4
-rw-r--r--src/xdmcp-server.c53
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;