Index: vino/server/libvncserver/main.c
===================================================================
--- vino.orig/server/libvncserver/main.c 2006-10-13 09:44:25.000000000 +0100
+++ vino.orig/server/libvncserver/main.c 2006-10-13 09:44:25.000000000 +0100
@@ -447,6 +447,7 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,
rfbErr("WARNING: Width (%d) is not a multiple of 4. VncViewer has problems with that.\n",width);
rfbScreen->autoPort=FALSE;
+ rfbScreen->localOnly=FALSE;
rfbScreen->rfbClientHead=0;
rfbScreen->rfbPort=5900;
rfbScreen->socketInitDone=FALSE;
Index: vino/server/libvncserver/rfb/rfb.h
===================================================================
--- vino.orig/server/libvncserver/rfb/rfb.h 2006-10-13 09:44:25.000000000 +0100
+++ vino.orig/server/libvncserver/rfb/rfb.h 2006-10-13 09:44:25.000000000 +0100
@@ -170,6 +170,7 @@ typedef struct _rfbScreenInfo
char rfbThisHost[255];
rfbBool autoPort;
+ rfbBool localOnly;
int rfbPort;
SOCKET rfbListenSock;
int maxSock;
@@ -468,6 +469,7 @@ extern char rfbEndianTest;
extern int rfbMaxClientWait;
extern void rfbInitSockets(rfbScreenInfoPtr rfbScreen);
+extern void rfbSetLocalOnly(rfbScreenInfoPtr rfbScreen, rfbBool localOnly);
extern void rfbCloseClient(rfbClientPtr cl);
extern int ReadExact(rfbClientPtr cl, char *buf, int len);
extern int ReadExactTimeout(rfbClientPtr cl, char *buf, int len,int timeout);
@@ -476,7 +478,7 @@ extern void rfbProcessNewConnection(rfbS
extern void rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec);
extern int rfbConnect(rfbScreenInfoPtr rfbScreen, char* host, int port);
extern int ConnectToTcpAddr(char* host, int port);
-extern int ListenOnTCPPort(int port);
+extern int ListenOnTCPPort(int port, rfbBool localOnly);
/* rfbserver.c */
Index: vino/server/libvncserver/sockets.c
===================================================================
--- vino.orig/server/libvncserver/sockets.c 2006-10-13 09:44:25.000000000 +0100
+++ vino.orig/server/libvncserver/sockets.c 2006-10-13 09:44:25.000000000 +0100
@@ -139,7 +139,7 @@ rfbInitSockets(rfbScreenInfoPtr rfbScree
rfbLog("Autoprobing TCP port \n");
for (i = 5900; i < 6000; i++) {
- if ((rfbScreen->rfbListenSock = ListenOnTCPPort(i)) >= 0) {
+ if ((rfbScreen->rfbListenSock = ListenOnTCPPort(i, rfbScreen->localOnly)) >= 0) {
rfbScreen->rfbPort = i;
break;
}
@@ -158,7 +158,7 @@ rfbInitSockets(rfbScreenInfoPtr rfbScree
else if(rfbScreen->rfbPort>0) {
rfbLog("Listening for VNC connections on TCP port %d\n", rfbScreen->rfbPort);
- if ((rfbScreen->rfbListenSock = ListenOnTCPPort(rfbScreen->rfbPort)) < 0) {
+ if ((rfbScreen->rfbListenSock = ListenOnTCPPort(rfbScreen->rfbPort, rfbScreen->localOnly)) < 0) {
rfbLogPerror("ListenOnTCPPort");
return;
}
@@ -170,6 +170,35 @@ rfbInitSockets(rfbScreenInfoPtr rfbScree
}
void
+rfbSetLocalOnly(rfbScreenInfoPtr rfbScreen, rfbBool localOnly)
+{
+ if (rfbScreen->localOnly == localOnly)
+ return;
+
+ rfbScreen->localOnly = localOnly;
+
+ if (!rfbScreen->socketInitDone)
+ return;
+
+ if (rfbScreen->rfbListenSock > 0) {
+ FD_CLR(rfbScreen->rfbListenSock, &(rfbScreen->allFds));
+ close(rfbScreen->rfbListenSock);
+ rfbScreen->rfbListenSock = -1;
+ }
+
+ rfbLog("Re-binding socket to listen for %s VNC connections on TCP port %d\n",
+ rfbScreen->localOnly ? "local" : "all", rfbScreen->rfbPort);
+
+ if ((rfbScreen->rfbListenSock = ListenOnTCPPort(rfbScreen->rfbPort, rfbScreen->localOnly)) < 0) {
+ rfbLogPerror("ListenOnTCPPort");
+ return;
+ }
+
+ FD_SET(rfbScreen->rfbListenSock, &(rfbScreen->allFds));
+ rfbScreen->maxFd = max(rfbScreen->rfbListenSock, rfbScreen->maxFd);
+}
+
+void
rfbProcessNewConnection(rfbScreenInfoPtr rfbScreen)
{
struct sockaddr_in addr;
@@ -537,8 +566,9 @@ WriteExact(rfbClientPtr cl, const char*
}
int
-ListenOnTCPPort(port)
+ListenOnTCPPort(port, localOnly)
int port;
+ rfbBool localOnly;
{
struct sockaddr_in addr;
int sock;
@@ -548,7 +578,7 @@ ListenOnTCPPort(port)
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
/* addr.sin_addr.s_addr = interface.s_addr; */
- addr.sin_addr.s_addr = INADDR_ANY;
+ addr.sin_addr.s_addr = localOnly ? htonl(INADDR_LOOPBACK) : htonl(INADDR_ANY);
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
return -1;
Index: vino/server/vino-prefs.c
===================================================================
--- vino.orig/server/vino-prefs.c 2006-10-13 09:45:41.000000000 +0100
+++ vino.orig/server/vino-prefs.c 2006-10-13 09:45:41.000000000 +0100
@@ -32,11 +32,12 @@
#define VINO_PREFS_ENABLED VINO_PREFS_DIR "/enabled"
#define VINO_PREFS_PROMPT_ENABLED VINO_PREFS_DIR "/prompt_enabled"
#define VINO_PREFS_VIEW_ONLY VINO_PREFS_DIR "/view_only"
+#define VINO_PREFS_LOCAL_ONLY VINO_PREFS_DIR "/local_only"
#define VINO_PREFS_REQUIRE_ENCRYPTION VINO_PREFS_DIR "/require_encryption"
#define VINO_PREFS_AUTHENTICATION_METHODS VINO_PREFS_DIR "/authentication_methods"
#define VINO_PREFS_VNC_PASSWORD VINO_PREFS_DIR "/vnc_password"
-#define VINO_N_LISTENERS 6
+#define VINO_N_LISTENERS 7
static GConfClient *vino_client = NULL;
static GSList *vino_servers = NULL;
@@ -45,6 +46,7 @@ static guint vino_listeners [VINO
static gboolean vino_enabled = FALSE;
static gboolean vino_prompt_enabled = FALSE;
static gboolean vino_view_only = FALSE;
+static gboolean vino_local_only = FALSE;
static gboolean vino_require_encryption = FALSE;
static VinoAuthMethod vino_auth_methods = VINO_AUTH_VNC;
static char *vino_vnc_password = NULL;
@@ -123,6 +125,30 @@ vino_prefs_view_only_changed (GConfClien
}
static void
+vino_prefs_local_only_changed (GConfClient *client,
+ guint cnxn_id,
+ GConfEntry *entry)
+{
+ gboolean local_only;
+ GSList *l;
+
+ if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
+ return;
+
+ local_only = gconf_value_get_bool (entry->value) != FALSE;
+
+ if (vino_local_only == local_only)
+ return;
+
+ vino_local_only = local_only;
+
+ dprintf (PREFS, "Local only changed: %s\n", vino_local_only ? "(true)" : "(false)");
+
+ for (l = vino_servers; l; l = l->next)
+ vino_server_set_local_only (l->data, local_only);
+}
+
+static void
vino_prefs_require_encryption_changed (GConfClient *client,
guint cnxn_id,
GConfEntry *entry)
@@ -241,6 +267,7 @@ vino_prefs_create_server (GdkScreen *scr
server = g_object_new (VINO_TYPE_SERVER,
"prompt-enabled", vino_prompt_enabled,
"view-only", vino_view_only,
+ "local-only", vino_local_only,
"auth-methods", vino_auth_methods,
"require-encryption", vino_require_encryption,
"vnc-password", vino_vnc_password,
@@ -284,6 +311,11 @@ vino_prefs_init (gboolean view_only)
}
dprintf (PREFS, "View only: %s\n", vino_view_only ? "(true)" : "(false)");
+ vino_local_only = gconf_client_get_bool (vino_client,
+ VINO_PREFS_LOCAL_ONLY,
+ NULL);
+ dprintf (PREFS, "Local only: %s\n", vino_local_only ? "(true)" : "(false)");
+
vino_require_encryption = gconf_client_get_bool (vino_client,
VINO_PREFS_REQUIRE_ENCRYPTION,
NULL);
@@ -333,6 +365,13 @@ vino_prefs_init (gboolean view_only)
vino_listeners [i] =
gconf_client_notify_add (vino_client,
+ VINO_PREFS_LOCAL_ONLY,
+ (GConfClientNotifyFunc) vino_prefs_local_only_changed,
+ NULL, NULL, NULL);
+ i++;
+
+ vino_listeners [i] =
+ gconf_client_notify_add (vino_client,
VINO_PREFS_REQUIRE_ENCRYPTION,
(GConfClientNotifyFunc) vino_prefs_require_encryption_changed,
NULL, NULL, NULL);
Index: vino/server/vino-server.c
===================================================================
--- vino.orig/server/vino-server.c 2006-10-13 09:45:41.000000000 +0100
+++ vino.orig/server/vino-server.c 2006-10-13 09:45:41.000000000 +0100
@@ -64,6 +64,7 @@ struct _VinoServerPrivate
#endif
guint on_hold : 1;
+ guint local_only : 1;
guint prompt_enabled : 1;
guint view_only : 1;
guint require_encryption : 1;
@@ -90,6 +91,7 @@ enum
PROP_ON_HOLD,
PROP_PROMPT_ENABLED,
PROP_VIEW_ONLY,
+ PROP_LOCAL_ONLY,
PROP_REQUIRE_ENCRYPTION,
PROP_AUTH_METHODS,
PROP_VNC_PASSWORD
@@ -669,6 +671,7 @@ vino_server_init_from_screen (VinoServer
* 5900-6000
*/
rfb_screen->rfbDeferUpdateTime = 0;
+ rfb_screen->localOnly = server->priv->local_only;
rfb_screen->autoPort = TRUE;
rfb_screen->rfbAlwaysShared = TRUE;
@@ -788,6 +791,9 @@ vino_server_set_property (GObject *
case PROP_VIEW_ONLY:
vino_server_set_view_only (server, g_value_get_boolean (value));
break;
+ case PROP_LOCAL_ONLY:
+ vino_server_set_local_only (server, g_value_get_boolean (value));
+ break;
case PROP_REQUIRE_ENCRYPTION:
vino_server_set_require_encryption (server, g_value_get_boolean (value));
break;
@@ -825,6 +831,9 @@ vino_server_get_property (GObject *ob
case PROP_VIEW_ONLY:
g_value_set_boolean (value, server->priv->view_only);
break;
+ case PROP_LOCAL_ONLY:
+ g_value_set_boolean (value, server->priv->local_only);
+ break;
case PROP_REQUIRE_ENCRYPTION:
g_value_set_boolean (value, server->priv->require_encryption);
break;
@@ -890,6 +899,14 @@ vino_server_class_init (VinoServerClass
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class,
+ PROP_LOCAL_ONLY,
+ g_param_spec_boolean ("local-only",
+ _("Local Only"),
+ _("Only allow local connections"),
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (gobject_class,
PROP_REQUIRE_ENCRYPTION,
g_param_spec_boolean ("require-encryption",
_("Require Encryption"),
@@ -989,6 +1006,34 @@ vino_server_set_view_only (VinoServer *s
}
gboolean
+vino_server_get_local_only (VinoServer *server)
+{
+ g_return_val_if_fail (VINO_IS_SERVER (server), FALSE);
+
+ return server->priv->local_only;
+}
+
+void
+vino_server_set_local_only (VinoServer *server,
+ gboolean local_only)
+{
+ g_return_if_fail (VINO_IS_SERVER (server));
+
+ local_only = local_only != FALSE;
+
+ if (server->priv->local_only != local_only)
+ {
+ server->priv->local_only = local_only;
+
+ if (server->priv->rfb_screen != NULL)
+ rfbSetLocalOnly (server->priv->rfb_screen,
+ server->priv->local_only);
+
+ g_object_notify (G_OBJECT (server), "local-only");
+ }
+}
+
+gboolean
vino_server_get_on_hold (VinoServer *server)
{
g_return_val_if_fail (VINO_IS_SERVER (server), FALSE);
Index: vino/server/vino-server.h
===================================================================
--- vino.orig/server/vino-server.h 2006-10-13 09:44:25.000000000 +0100
+++ vino.orig/server/vino-server.h 2006-10-13 09:44:25.000000000 +0100
@@ -72,6 +72,9 @@ gboolean vino_server_get_pro
void vino_server_set_view_only (VinoServer *server,
gboolean view_only);
gboolean vino_server_get_view_only (VinoServer *server);
+void vino_server_set_local_only (VinoServer *server,
+ gboolean local_only);
+gboolean vino_server_get_local_only (VinoServer *server);
void vino_server_set_require_encryption (VinoServer *server,
gboolean require_encryption);
gboolean vino_server_get_require_encryption (VinoServer *server);
Index: vino/server/vino-server.schemas.in
===================================================================
--- vino.orig/server/vino-server.schemas.in 2006-10-13 09:44:25.000000000 +0100
+++ vino.orig/server/vino-server.schemas.in 2006-10-13 09:44:25.000000000 +0100
@@ -51,6 +51,24 @@
+ /schemas/desktop/gnome/remote_access/local_only
+ /desktop/gnome/remote_access/local_only
+ gnome
+ bool
+ false
+
+ Only allow local connections
+
+ If true, the server will only accept connections from
+ localhost and network connections will be rejected.
+
+ Set this option to true if you wish to exclusively use
+ a tunneling mechanism to access the server, such as ssh.
+
+
+
+
+
/schemas/desktop/gnome/remote_access/require_encryption
/desktop/gnome/remote_access/require_encryption
gnome
Index: vino/server/libvncserver/CHANGES
===================================================================
--- vino.orig/server/libvncserver/CHANGES 2006-10-13 09:44:25.000000000 +0100
+++ vino.orig/server/libvncserver/CHANGES 2006-10-13 09:44:25.000000000 +0100
@@ -30,6 +30,10 @@
be prompted on whether to allow authenticated clients to
connect. A second level of authentication.
+ + Added rfbSetLocalOnly() - i.e. make the server only accept
+ connections from localhost. Useful for people who use
+ SSH tunnels.
+
+ Removed defaultNewClientHook and made accept new clients
by default.
Index: vino/ChangeLog
===================================================================
--- vino.orig/ChangeLog 2006-10-13 09:45:41.000000000 +0100
+++ vino.orig/ChangeLog 2006-10-13 09:45:41.000000000 +0100
@@ -0,0 +1,36 @@
+2006-10-12 Mark McLoughlin
+
+ Add a "local_only" GConf key, for people who want to exclusively
+ use SSH tunnels to access the server.
+
+ Based on patch from Shaya Potter
+ in bug #156242
+
+ * server/libvncserver/sockets.c:
+ (rfbInitSockets): pass rfbScreen->localOnly to ListenOnTcpPort()
+ (rfbSetLocalOnly): re-bind the socket if localOnly changes.
+ (ListenOnTcpPort): add localOnly argument and bind with
+ INADDR_LOOPBACK if true.
+
+ * server/libvncserver/rfb/rfb.h: modify ListenOnTcpPort()
+ prototype and add rfbSetLocalOnly()
+
+ * server/libvncserver/main.c: (rfbGetScreen): init localOnly.
+
+ * server/libvncserver/CHANGES: add note.
+
+ * server/vino-server.schemas.in: add local_only GConf key
+
+ * server/vino-prefs.c:
+ (vino_prefs_local_only_changed),
+ (vino_prefs_create_server),
+ (vino_prefs_init): add handling for local_only key
+
+ * server/vino-server.[ch]:
+ (vino_server_init_from_screen): propogate local_only to rfbScreen.
+ (vino_server_set_property), (vino_server_get_property),
+ (vino_server_class_init): add "local-only" property
+ (vino_server_get_local_only),
+ (vino_server_set_local_only): add accessors. Call rfbSetLocalOnly()
+ if it changes.
+