summaryrefslogtreecommitdiff
path: root/src/xdmcp-server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xdmcp-server.c')
-rw-r--r--src/xdmcp-server.c53
1 files changed, 49 insertions, 4 deletions
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;