summaryrefslogtreecommitdiffstats
path: root/x11vnc/remote.c
diff options
context:
space:
mode:
authorrunge <runge@karlrunge.com>2010-04-09 20:09:15 -0400
committerrunge <runge@karlrunge.com>2010-04-09 20:09:15 -0400
commit2a8ba97ec5b0f7fbfcfc8adab6732a95e95c7204 (patch)
tree7da693c36f06f4e16e8bc2b030c54b67f01d8671 /x11vnc/remote.c
parent5c53ccbbe99dbf098dbb396a65b487f08315d825 (diff)
downloadlibtdevnc-2a8ba97ec5b0f7fbfcfc8adab6732a95e95c7204.tar.gz
libtdevnc-2a8ba97ec5b0f7fbfcfc8adab6732a95e95c7204.zip
x11vnc: exit(1) for -connect_or_exit failure, quiet query mode for grab_state, pointer_pos, etc. ipv6 support. STUNNEL_LISTEN for particular interface. -input_eagerly in addition to -allinput. quiet Xinerama message.
Diffstat (limited to 'x11vnc/remote.c')
-rw-r--r--x11vnc/remote.c306
1 files changed, 242 insertions, 64 deletions
diff --git a/x11vnc/remote.c b/x11vnc/remote.c
index 953f963..6c9ae42 100644
--- a/x11vnc/remote.c
+++ b/x11vnc/remote.c
@@ -59,6 +59,7 @@ so, delete this exception statement from your version.
#include "uinput.h"
#include "userinput.h"
#include "avahi.h"
+#include "sslhelper.h"
int send_remote_cmd(char *cmd, int query, int wait);
int do_remote_query(char *remote_cmd, char *query_cmd, int remote_sync,
@@ -480,6 +481,15 @@ static void rfb_http_init_sockets(void) {
screen->listenInterface = htonl(INADDR_LOOPBACK);
}
rfbHttpInitSockets(screen);
+ if (noipv4 || getenv("IPV4_FAILS")) {
+ if (getenv("IPV4_FAILS")) {
+ rfbLog("TESTING: IPV4_FAILS for rfb_http_init_sockets()\n");
+ }
+ if (screen->httpListenSock > -1) {
+ close(screen->httpListenSock);
+ screen->httpListenSock = -1;
+ }
+ }
screen->listenInterface = iface;
}
@@ -505,95 +515,169 @@ void http_connections(int on) {
}
screen->httpInitDone = FALSE;
if (check_httpdir()) {
+ int fd6 = -1;
screen->httpDir = http_dir;
rfb_http_init_sockets();
if (screen->httpPort != 0 && screen->httpListenSock < 0) {
rfbLog("http_connections: failed to listen on http port: %d\n", screen->httpPort);
- clean_up_exit(1);
+ if (ipv6_listen) {
+ fd6 = listen6(screen->httpPort);
+ }
+ if (fd6 < 0) {
+ clean_up_exit(1);
+ }
+ rfbLog("http_connections: trying IPv6 only mode.\n");
+ }
+ if (ipv6_listen && screen->httpPort > 0) {
+ if (fd6 < 0) {
+ fd6 = listen6(screen->httpPort);
+ }
+ ipv6_http_fd = fd6;
+ if (ipv6_http_fd >= 0) {
+ rfbLog("http_connections: %s listening on IPv6 port=%d sock=%d\n",
+ screen->httpListenSock < 0 ? "Only" : "Also",
+ screen->httpPort, ipv6_http_fd);
+ }
}
}
} else {
rfbLog("http_connections: turning off http service.\n");
if (screen->httpListenSock > -1) {
close(screen->httpListenSock);
+ screen->httpListenSock = -1;
}
- screen->httpListenSock = -1;
screen->httpDir = NULL;
+ if (ipv6_http_fd >= 0) {
+ close(ipv6_http_fd);
+ ipv6_http_fd = -1;
+ }
}
}
static void reset_httpport(int old, int new) {
int hp = new;
- if (hp < 0) {
+
+ if (! screen->httpDir) {
+ return;
+ } else if (inetd) {
+ rfbLog("reset_httpport: cannot set httpport: %d in inetd.\n", hp);
+ return;
+ } else if (!screen) {
+ rfbLog("reset_httpport: no screen.\n");
+ return;
+ } else if (hp < 0) {
rfbLog("reset_httpport: invalid httpport: %d\n", hp);
+ return;
} else if (hp == old) {
rfbLog("reset_httpport: unchanged httpport: %d\n", hp);
- } else if (inetd) {
- rfbLog("reset_httpport: cannot set httpport: %d"
- " in inetd.\n", hp);
- } else if (screen) {
- /* mutex */
- screen->httpPort = hp;
- screen->httpInitDone = FALSE;
- if (screen->httpListenSock > -1) {
- close(screen->httpListenSock);
+ return;
+ }
+
+ if (screen->httpListenSock > -1) {
+ close(screen->httpListenSock);
+ screen->httpListenSock = -1;
+ }
+
+ screen->httpPort = hp;
+ screen->httpInitDone = FALSE;
+
+ rfbLog("reset_httpport: setting httpport %d -> %d.\n",
+ old == -1 ? hp : old, hp);
+
+ if (noipv4 || getenv("IPV4_FAILS")) {
+ if (getenv("IPV4_FAILS")) {
+ rfbLog("TESTING: IPV4_FAILS for reset_httpport()\n");
}
- rfbLog("reset_httpport: setting httpport %d -> %d.\n",
- old == -1 ? hp : old, hp);
+ } else if (screen->httpPort == 0) {
+ ;
+ } else {
rfb_http_init_sockets();
- if (screen->httpPort != 0 && screen->httpListenSock < 0) {
- rfbLog("reset_httpport: failed to listen on http port: %d\n", screen->httpPort);
- }
+ }
+
+ if (screen->httpPort != 0 && screen->httpListenSock < 0) {
+ rfbLog("reset_httpport: failed to listen on http port: %d\n",
+ screen->httpPort);
+ }
+
+ if (ipv6_http_fd >= 0) {
+ close(ipv6_http_fd);
+ ipv6_http_fd = -1;
+ }
+ if (ipv6_listen && screen->httpPort > 0) {
+ ipv6_http_fd = listen6(screen->httpPort);
+ rfbLog("reset_httpport: ipv6_http_fd: %d port: %d\n",
+ ipv6_http_fd, screen->httpPort);
}
}
static void reset_rfbport(int old, int new) {
int rp = new;
- if (rp < 0) {
+
+ if (inetd) {
+ rfbLog("reset_rfbport: cannot set rfbport: %d in inetd.\n", rp);
+ return;
+ } else if (!screen) {
+ rfbLog("reset_rfbport: no screen.\n");
+ return;
+ } else if (rp < 0) {
rfbLog("reset_rfbport: invalid rfbport: %d\n", rp);
+ return;
} else if (rp == old) {
rfbLog("reset_rfbport: unchanged rfbport: %d\n", rp);
- } else if (inetd) {
- rfbLog("reset_rfbport: cannot set rfbport: %d"
- " in inetd.\n", rp);
- } else if (screen) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- int maxfd;
- /* mutex */
- if (rp == 0) {
- screen->autoPort = TRUE;
+ return;
+ }
+
+ rfbLog("reset_rfbport: setting rfbport %d -> %d.\n", old == -1 ? rp : old, rp);
+
+ screen->port = rp;
+
+ if (use_openssl) {
+ openssl_port(1);
+ if (openssl_sock < 0 && openssl_sock6 < 0) {
+ rfbLog("reset_rfbport: warning could not listen on port: %d\n",
+ screen->port);
} else {
- screen->autoPort = FALSE;
+ set_vnc_desktop_name();
}
- screen->port = rp;
- screen->socketState = RFB_SOCKET_INIT;
-
- if (screen->listenSock > -1) {
- close(screen->listenSock);
+ if (https_port_num >= 0) {
+ https_port(1);
}
+ return;
+ }
- rfbLog("reset_rfbport: setting rfbport %d -> %d.\n",
- old == -1 ? rp : old, rp);
- rfbInitSockets(screen);
+ if (screen->listenSock >= 0) {
+ FD_CLR(screen->listenSock, &(screen->allFds));
+ close(screen->listenSock);
+ screen->listenSock = -1;
+ }
- maxfd = screen->maxFd;
- if (screen->udpSock > 0 && screen->udpSock > maxfd) {
- maxfd = screen->udpSock;
+ if (noipv4 || getenv("IPV4_FAILS")) {
+ if (getenv("IPV4_FAILS")) {
+ rfbLog("TESTING: IPV4_FAILS for reset_rfbport()\n");
}
- iter = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- if (cl->sock > -1) {
- FD_SET(cl->sock, &(screen->allFds));
- if (cl->sock > maxfd) {
- maxfd = cl->sock;
- }
+ } else {
+ screen->listenSock = listen_tcp(screen->port, screen->listenInterface, 0);
+ if (screen->listenSock >= 0) {
+ if (screen->listenSock > screen->maxFd) {
+ screen->maxFd = screen->listenSock;
}
+ FD_SET(screen->listenSock, &(screen->allFds));
}
- rfbReleaseClientIterator(iter);
+ }
- screen->maxFd = maxfd;
+ if (ipv6_listen_fd >= 0) {
+ close(ipv6_listen_fd);
+ ipv6_listen_fd = -1;
+ }
+ if (ipv6_listen && screen->port > 0) {
+ ipv6_listen_fd = listen6(screen->port);
+ rfbLog("reset_rfbport: ipv6_listen_fd: %d port: %d\n",
+ ipv6_listen_fd, screen->port);
+ }
+ if (screen->listenSock < 0 && ipv6_listen_fd < 0) {
+ rfbLog("reset_rfbport: warning could not listen on port: %d\n", screen->port);
+ } else {
set_vnc_desktop_name();
}
}
@@ -741,6 +825,8 @@ int remote_control_access_ok(void) {
void macosxCG_keycode_inject(int down, int keycode);
#endif
+int rc_npieces = 0;
+
/*
* Huge, ugly switch to handle all remote commands and queries
* -remote/-R and -query/-Q.
@@ -876,6 +962,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
}
free(s);
+ rc_npieces = n;
strcpy(buf, "");
for (k=0; k < n; k++) {
res = process_remote_cmd(pieces[k], 1);
@@ -898,6 +985,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
free(pieces[k]);
}
free(pieces);
+ rc_npieces = 0;
goto qry;
}
p += strlen("qry=");
@@ -1779,6 +1867,74 @@ char *process_remote_cmd(char *cmd, int stringonly) {
free(before);
goto done;
}
+ if (!strcmp(p, "noipv6")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, noipv6);
+ goto qry;
+ }
+ rfbLog("remote_cmd: enabling -noipv6 mode for future sockets.\n");
+ noipv6 = 1;
+ goto done;
+ }
+ if (!strcmp(p, "ipv6")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !noipv6);
+ goto qry;
+ }
+ rfbLog("remote_cmd: disabling -noipv6 mode for future sockets.\n");
+ noipv6 = 0;
+ goto done;
+ }
+ if (!strcmp(p, "noipv4")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, noipv4);
+ goto qry;
+ }
+ rfbLog("remote_cmd: enabling -noipv4 mode for future sockets.\n");
+ noipv4 = 1;
+ goto done;
+ }
+ if (!strcmp(p, "ipv4")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !noipv4);
+ goto qry;
+ }
+ rfbLog("remote_cmd: disabling -noipv4 mode for future sockets.\n");
+ noipv4 = 0;
+ goto done;
+ }
+ if (!strcmp(p, "no6")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !ipv6_listen);
+ goto qry;
+ }
+ if (ipv6_listen) {
+ ipv6_listen = 0;
+ rfbLog("disabling -6 IPv6 listening mode.\n");
+ reset_rfbport(-1, screen->port);
+ reset_httpport(-1, screen->httpPort);
+ if (https_port_num > 0) {
+ https_port(1);
+ }
+ }
+ goto done;
+ }
+ if (!strcmp(p, "6")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, ipv6_listen);
+ goto qry;
+ }
+ if (!ipv6_listen) {
+ ipv6_listen = 1;
+ rfbLog("enabling -6 IPv6 listening mode.\n");
+ reset_rfbport(-1, screen->port);
+ reset_httpport(-1, screen->httpPort);
+ if (https_port_num > 0) {
+ https_port(1);
+ }
+ }
+ goto done;
+ }
if (!strcmp(p, "localhost")) {
char *before, *old;
if (query) {
@@ -1818,9 +1974,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
rfbLog("listening on loopback network only.\n");
rfbLog("allow list is: '%s'\n", NONUL(allow_list));
reset_rfbport(-1, screen->port);
- if (screen->httpListenSock > -1) {
- reset_httpport(-1, screen->httpPort);
- }
+ reset_httpport(-1, screen->httpPort);
goto done;
}
if (!strcmp(p, "nolocalhost")) {
@@ -1866,9 +2020,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
rfbLog("listening on ALL network interfaces.\n");
rfbLog("allow list is: '%s'\n", NONUL(allow_list));
reset_rfbport(-1, screen->port);
- if (screen->httpListenSock > -1) {
- reset_httpport(-1, screen->httpPort);
- }
+ reset_httpport(-1, screen->httpPort);
goto done;
}
if (strstr(p, "listen") == p) {
@@ -1957,9 +2109,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
if (ok) {
rfbLog("allow list is: '%s'\n", NONUL(allow_list));
reset_rfbport(-1, screen->port);
- if (screen->httpListenSock > -1) {
- reset_httpport(-1, screen->httpPort);
- }
+ reset_httpport(-1, screen->httpPort);
free(before);
} else {
rfbLog("invalid listen string: %s\n", listen_str);
@@ -3933,6 +4083,10 @@ char *process_remote_cmd(char *cmd, int stringonly) {
}
all_input = 1;
rfbLog("enabled allinput\n");
+ if (handle_events_eagerly) {
+ rfbLog("disabled input_eagerly\n");
+ handle_events_eagerly = 0;
+ }
goto done;
}
if (!strcmp(p, "noallinput")) {
@@ -3944,6 +4098,28 @@ char *process_remote_cmd(char *cmd, int stringonly) {
rfbLog("disabled allinput\n");
goto done;
}
+ if (!strcmp(p, "input_eagerly")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, handle_events_eagerly);
+ goto qry;
+ }
+ handle_events_eagerly = 1;
+ rfbLog("enabled input_eagerly\n");
+ if (all_input) {
+ rfbLog("disabled allinput\n");
+ all_input = 0;
+ }
+ goto done;
+ }
+ if (!strcmp(p, "noinput_eagerly")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !handle_events_eagerly);
+ goto qry;
+ }
+ handle_events_eagerly = 0;
+ rfbLog("disabled input_eagerly\n");
+ goto done;
+ }
if (strstr(p, "input") == p) {
int doit = 1;
COLON_CHECK("input:")
@@ -4941,24 +5117,24 @@ char *process_remote_cmd(char *cmd, int stringonly) {
}
if (strstr(p, "uinput_reset") == p) {
COLON_CHECK("uinput_reset:")
- p += strlen("uinput_reset:");
if (query) {
snprintf(buf, bufn, "ans=%s%s%d", p, co,
get_uinput_reset());
goto qry;
}
+ p += strlen("uinput_reset:");
rfbLog("set_uinput_reset: %s\n", p);
set_uinput_reset(atoi(p));
goto done;
}
if (strstr(p, "uinput_always") == p) {
COLON_CHECK("uinput_always:")
- p += strlen("uinput_always:");
if (query) {
snprintf(buf, bufn, "ans=%s%s%d", p, co,
get_uinput_always());
goto qry;
}
+ p += strlen("uinput_always:");
rfbLog("set_uinput_always: %s\n", p);
set_uinput_always(atoi(p));
goto done;
@@ -5002,7 +5178,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
snprintf(buf, bufn, "ans=%s:%d", p, (ls > -1));
goto qry;
}
- if (screen->httpListenSock > -1) {
+ if (screen->httpListenSock > -1 || ipv6_http_fd > -1) {
rfbLog("already listening for http connections.\n");
} else {
rfbLog("turning on listening for http connections.\n");
@@ -5018,7 +5194,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
snprintf(buf, bufn, "ans=%s:%d", p, !(ls > -1));
goto qry;
}
- if (screen->httpListenSock < 0) {
+ if (screen->httpListenSock < 0 && ipv6_http_fd < 0) {
rfbLog("already not listening for http connections.\n");
} else {
rfbLog("turning off listening for http connections.\n");
@@ -5936,7 +6112,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
grab_state(&ptr_grabbed, &kbd_grabbed);
snprintf(buf, bufn, "aro=%s:%d,%d", p, ptr_grabbed, kbd_grabbed);
- if (dpy) {
+ if (dpy && rc_npieces < 10) {
rfbLog("remote_cmd: ptr,kbd: %s\n", buf);
}
goto qry;
@@ -5982,7 +6158,9 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else if (!strcmp(p, "pointer_root")) { /* skip-cmd-list */
snprintf(buf, bufn, "aro=%s:0x%x", p, (unsigned int) r);
}
- rfbLog("remote_cmd: %s: %s\n", p, buf);
+ if (rc_npieces < 10) {
+ rfbLog("remote_cmd: %s: %s\n", p, buf);
+ }
goto qry;
}
if (!strcmp(p, "bpp")) {