From 520f38d716c028618e434fb243d61ba59b4dcbc1 Mon Sep 17 00:00:00 2001 From: Robert Ancell Date: Wed, 5 Aug 2015 16:11:28 +1200 Subject: Add an option for XDMCP and VNC servers to only listen on one address --- data/lightdm.conf | 4 ++++ src/lightdm.c | 10 +++++++++- src/vnc-server.c | 48 +++++++++++++++++++++++++++++++++++++++++------- src/vnc-server.h | 4 ++++ src/xdmcp-server.c | 42 ++++++++++++++++++++++++++++++++++++++---- src/xdmcp-server.h | 4 ++++ 6 files changed, 100 insertions(+), 12 deletions(-) diff --git a/data/lightdm.conf b/data/lightdm.conf index 1c8cf58c..c29b00eb 100644 --- a/data/lightdm.conf +++ b/data/lightdm.conf @@ -135,6 +135,7 @@ # # enabled = True if XDMCP connections should be allowed # port = UDP/IP port to listen for connections on +# listen-address = Host/address to listen for XDMCP connections (use all addresses if not present) # key = Authentication key to use for XDM-AUTHENTICATION-1 or blank to not use authentication (stored in keys.conf) # # The authentication key is a 56 bit DES key specified in hex as 0xnnnnnnnnnnnnnn. Alternatively @@ -143,6 +144,7 @@ [XDMCPServer] #enabled=false #port=177 +#listen-address= #key= # @@ -151,6 +153,7 @@ # enabled = True if VNC connections should be allowed # command = Command to run Xvnc server with # port = TCP/IP port to listen for connections on +# listen-address = Host/address to listen for VNC connections (use all addresses if not present) # width = Width of display to use # height = Height of display to use # depth = Color depth of display to use @@ -159,6 +162,7 @@ #enabled=false #command=Xvnc #port=5900 +#listen-address= #width=1024 #height=768 #depth=8 diff --git a/src/lightdm.c b/src/lightdm.c index 2d110f25..d855c4cb 100644 --- a/src/lightdm.c +++ b/src/lightdm.c @@ -852,7 +852,7 @@ bus_acquired_cb (GDBusConnection *connection, /* Start the XDMCP server */ if (config_get_boolean (config_get_instance (), "XDMCPServer", "enabled")) { - gchar *key_name, *key = NULL; + gchar *key_name, *key = NULL, *listen_address; xdmcp_server = xdmcp_server_new (); if (config_has_key (config_get_instance (), "XDMCPServer", "port")) @@ -862,6 +862,9 @@ bus_acquired_cb (GDBusConnection *connection, if (port > 0) xdmcp_server_set_port (xdmcp_server, port); } + listen_address = config_get_string (config_get_instance (), "XDMCPServer", "listen-address"); + xdmcp_server_set_listen_address (xdmcp_server, listen_address); + g_free (listen_address); g_signal_connect (xdmcp_server, "new-session", G_CALLBACK (xdmcp_session_cb), NULL); key_name = config_get_string (config_get_instance (), "XDMCPServer", "key"); @@ -907,6 +910,8 @@ bus_acquired_cb (GDBusConnection *connection, path = g_find_program_in_path ("Xvnc"); if (path) { + gchar *listen_address; + vnc_server = vnc_server_new (); if (config_has_key (config_get_instance (), "VNCServer", "port")) { @@ -915,6 +920,9 @@ bus_acquired_cb (GDBusConnection *connection, if (port > 0) vnc_server_set_port (vnc_server, port); } + listen_address = config_get_string (config_get_instance (), "VNCServer", "listen-address"); + vnc_server_set_listen_address (vnc_server, listen_address); + g_free (listen_address); g_signal_connect (vnc_server, "new-connection", G_CALLBACK (vnc_connection_cb), NULL); g_debug ("Starting VNC server on TCP/IP port %d", vnc_server_get_port (vnc_server)); diff --git a/src/vnc-server.c b/src/vnc-server.c index b265e287..ff84987a 100644 --- a/src/vnc-server.c +++ b/src/vnc-server.c @@ -24,6 +24,9 @@ struct VNCServerPrivate /* Port to listen on */ guint port; + /* Address to listen on */ + gchar *listen_address; + /* Listening sockets */ GSocket *socket, *socket6; }; @@ -50,6 +53,22 @@ vnc_server_get_port (VNCServer *server) return server->priv->port; } +void +vnc_server_set_listen_address (VNCServer *server, const gchar *listen_address) +{ + g_return_if_fail (server != NULL); + + g_free (server->priv->listen_address); + server->priv->listen_address = g_strdup (listen_address); +} + +const gchar * +vnc_server_get_listen_address (VNCServer *server) +{ + g_return_val_if_fail (server != NULL, NULL); + return server->priv->listen_address; +} + static gboolean read_cb (GSocket *socket, GIOCondition condition, VNCServer *server) { @@ -78,7 +97,7 @@ read_cb (GSocket *socket, GIOCondition condition, VNCServer *server) } static GSocket * -open_tcp_socket (GSocketFamily family, guint port, GError **error) +open_tcp_socket (GSocketFamily family, guint port, const gchar *listen_address, GError **error) { GSocket *socket; GSocketAddress *address; @@ -87,7 +106,21 @@ open_tcp_socket (GSocketFamily family, guint port, GError **error) if (!socket) return NULL; - address = g_inet_socket_address_new (g_inet_address_new_any (family), port); + if (listen_address) + { + GList *addresses; + + addresses = g_resolver_lookup_by_name (g_resolver_get_default (), listen_address, NULL, error); + if (!addresses) + { + g_object_unref (socket); + return NULL; + } + address = g_inet_socket_address_new (addresses->data, port); + g_resolver_free_addresses (addresses); + } + else + address = g_inet_socket_address_new (g_inet_address_new_any (family), port); if (!g_socket_bind (socket, address, TRUE, error) || !g_socket_listen (socket, error)) { @@ -105,8 +138,8 @@ vnc_server_start (VNCServer *server) GError *error = NULL; g_return_val_if_fail (server != NULL, FALSE); - - server->priv->socket = open_tcp_socket (G_SOCKET_FAMILY_IPV4, server->priv->port, &error); + + server->priv->socket = open_tcp_socket (G_SOCKET_FAMILY_IPV4, server->priv->port, server->priv->listen_address, &error); if (error) g_warning ("Failed to create IPv4 VNC socket: %s", error->message); g_clear_error (&error); @@ -117,8 +150,8 @@ vnc_server_start (VNCServer *server) g_source_set_callback (source, (GSourceFunc) read_cb, server, NULL); g_source_attach (source, NULL); } - - server->priv->socket6 = open_tcp_socket (G_SOCKET_FAMILY_IPV6, server->priv->port, &error); + + server->priv->socket6 = open_tcp_socket (G_SOCKET_FAMILY_IPV6, server->priv->port, server->priv->listen_address, &error); if (error) g_warning ("Failed to create IPv6 VNC socket: %s", error->message); g_clear_error (&error); @@ -149,7 +182,8 @@ vnc_server_finalize (GObject *object) VNCServer *self; self = VNC_SERVER (object); - + + g_free (self->priv->listen_address); if (self->priv->socket) g_object_unref (self->priv->socket); if (self->priv->socket6) diff --git a/src/vnc-server.h b/src/vnc-server.h index 83f01cbb..6917a6d8 100644 --- a/src/vnc-server.h +++ b/src/vnc-server.h @@ -42,6 +42,10 @@ void vnc_server_set_port (VNCServer *server, guint port); guint vnc_server_get_port (VNCServer *server); +void vnc_server_set_listen_address (VNCServer *server, const gchar *listen_address); + +const gchar *vnc_server_get_listen_address (VNCServer *server); + gboolean vnc_server_start (VNCServer *server); G_END_DECLS diff --git a/src/xdmcp-server.c b/src/xdmcp-server.c index 9032cbf0..d12b0359 100644 --- a/src/xdmcp-server.c +++ b/src/xdmcp-server.c @@ -32,6 +32,9 @@ struct XDMCPServerPrivate /* Port to listen on */ guint port; + /* Address to listen on */ + gchar *listen_address; + /* Listening sockets */ GSocket *socket, *socket6; @@ -73,6 +76,22 @@ xdmcp_server_get_port (XDMCPServer *server) return server->priv->port; } +void +xdmcp_server_set_listen_address (XDMCPServer *server, const gchar *listen_address) +{ + g_return_if_fail (server != NULL); + + g_free (server->priv->listen_address); + server->priv->listen_address = g_strdup (listen_address); +} + +const gchar * +xdmcp_server_get_listen_address (XDMCPServer *server) +{ + g_return_val_if_fail (server != NULL, NULL); + return server->priv->listen_address; +} + void xdmcp_server_set_hostname (XDMCPServer *server, const gchar *hostname) { @@ -637,7 +656,7 @@ read_cb (GSocket *socket, GIOCondition condition, XDMCPServer *server) } static GSocket * -open_udp_socket (GSocketFamily family, guint port, GError **error) +open_udp_socket (GSocketFamily family, guint port, const gchar *listen_address, GError **error) { GSocket *socket; GSocketAddress *address; @@ -647,7 +666,21 @@ open_udp_socket (GSocketFamily family, guint port, GError **error) if (!socket) return NULL; - address = g_inet_socket_address_new (g_inet_address_new_any (family), port); + if (listen_address) + { + GList *addresses; + + addresses = g_resolver_lookup_by_name (g_resolver_get_default (), listen_address, NULL, error); + if (!addresses) + { + g_object_unref (socket); + return NULL; + } + address = g_inet_socket_address_new (addresses->data, port); + g_resolver_free_addresses (addresses); + } + else + address = g_inet_socket_address_new (g_inet_address_new_any (family), port); result = g_socket_bind (socket, address, TRUE, error); if (!result) { @@ -666,7 +699,7 @@ xdmcp_server_start (XDMCPServer *server) g_return_val_if_fail (server != NULL, FALSE); - server->priv->socket = open_udp_socket (G_SOCKET_FAMILY_IPV4, server->priv->port, &error); + 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); @@ -678,7 +711,7 @@ xdmcp_server_start (XDMCPServer *server) g_source_attach (source, NULL); } - server->priv->socket6 = open_udp_socket (G_SOCKET_FAMILY_IPV6, server->priv->port, &error); + 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); g_clear_error (&error); @@ -718,6 +751,7 @@ xdmcp_server_finalize (GObject *object) g_object_unref (self->priv->socket); if (self->priv->socket6) g_object_unref (self->priv->socket6); + g_free (self->priv->listen_address); g_free (self->priv->hostname); g_free (self->priv->status); g_free (self->priv->key); diff --git a/src/xdmcp-server.h b/src/xdmcp-server.h index 5c12a365..3af13d1b 100644 --- a/src/xdmcp-server.h +++ b/src/xdmcp-server.h @@ -44,6 +44,10 @@ void xdmcp_server_set_port (XDMCPServer *server, guint port); guint xdmcp_server_get_port (XDMCPServer *server); +void xdmcp_server_set_listen_address (XDMCPServer *server, const gchar *listen_address); + +const gchar *xdmcp_server_get_listen_address (XDMCPServer *server); + void xdmcp_server_set_hostname (XDMCPServer *server, const gchar *hostname); const gchar *xdmcp_server_get_hostname (XDMCPServer *server); -- cgit v1.2.1