From 81ef0b9345dd393fea8edab879ee1fd8f0bf9e81 Mon Sep 17 00:00:00 2001 From: runge Date: Sat, 27 Oct 2007 22:45:30 +0000 Subject: x11vnc: -proxy, -ssh options. ncache bug in -8to24, Selection "targets" bugfix. --- x11vnc/connections.c | 564 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 555 insertions(+), 9 deletions(-) (limited to 'x11vnc/connections.c') diff --git a/x11vnc/connections.c b/x11vnc/connections.c index ac0723d..b7af0be 100644 --- a/x11vnc/connections.c +++ b/x11vnc/connections.c @@ -1610,6 +1610,544 @@ static void check_connect_file(char *file) { } } +static int socks5_proxy(char *host, int port, int sock) { + unsigned char buf[512], tmp[2]; + char reply[512]; + int len, n, i, j = 0; + + memset(buf, 0, 512); + memset(reply, 0, 512); + + buf[0] = 0x5; + buf[1] = 0x1; + buf[2] = 0x0; + + write(sock, buf, 3); + + n = read(sock, buf, 2); + + if (n != 2) { + rfbLog("socks5_proxy: read error: %d\n", n); + close(sock); + return 0; + } + if (buf[0] != 0x5 || buf[1] != 0x0) { + rfbLog("socks5_proxy: handshake error: %d %d\n", (int) buf[0], (int) buf[1]); + close(sock); + return 0; + } + + buf[0] = 0x5; + buf[1] = 0x1; + buf[2] = 0x0; + buf[3] = 0x3; + + buf[4] = (unsigned char) strlen(host); + strcat((char *) buf+5, host); + + len = 5 + strlen(host); + + buf[len] = (unsigned char) (port >> 8); + buf[len+1] = (unsigned char) (port & 0xff); + + write(sock, buf, len+2); + + for (i=0; i<4; i++) { + int n; + n = read(sock, tmp, 1); + j++; + if (n < 0) { + if (errno != EINTR) { + break; + } else { + i--; + if (j > 100) { + break; + } + continue; + } + } + if (n == 0) { + break; + } + reply[i] = tmp[0]; + } + if (reply[3] == 0x1) { + read(sock, reply+4, 4 + 2); + } else if (reply[3] == 0x3) { + n = read(sock, tmp, 1); + reply[4] = tmp[0]; + read(sock, reply+5, (int) reply[4] + 2); + } else if (reply[3] == 0x4) { + read(sock, reply+4, 16 + 2); + } + + if (0) { + int i; + for (i=0; i> 8); + buf[3] = (unsigned char) (port & 0xff); + + + if (strlen(host) > 256) { + rfbLog("socks_proxy: hostname too long: %s\n", host); + close(sock); + return 0; + } + + if (!strcmp(host, "localhost") || !strcmp(host, "127.0.0.1")) { + buf[4] = 127; + buf[5] = 0; + buf[6] = 0; + buf[7] = 1; + } else if (sscanf(host, "%d.%d.%d.%d", &d1, &d2, &d3, &d4) == 4) { + buf[4] = (unsigned char) d1; + buf[5] = (unsigned char) d2; + buf[6] = (unsigned char) d3; + buf[7] = (unsigned char) d4; + } else { + buf[4] = 0x0; + buf[5] = 0x0; + buf[6] = 0x0; + buf[7] = 0x3; + socks4a = 1; + } + len = 8; + + strcat((char *)buf+8, "nobody"); + len += strlen("nobody") + 1; + + if (socks4a) { + strcat((char *) buf+8+strlen("nobody") + 1, host); + len += strlen(host) + 1; + } + + write(sock, buf, len); + + for (i=0; i<8; i++) { + int n; + n = read(sock, tmp, 1); + j++; + if (n < 0) { + if (errno != EINTR) { + break; + } else { + i--; + if (j > 100) { + break; + } + continue; + } + } + if (n == 0) { + break; + } + reply[i] = tmp[0]; + } + if (0) { + int i; + for (i=0; i 0) { + rfbLog("proxy GET reconnect to: %s:%d\n", newhost, newport); + pxy_get_sock = rfbConnectToTcpAddr(newhost, newport); + } + } + free(req); + + return ok; +} + +static int proxy_connect(char *host, int port) { + char *p, *q, *str; + int i, n, pxy[PXY],pxy_p[PXY]; + int psock = -1; + char *pxy_h[PXY], *pxy_g[PXY]; + + if (! connect_proxy) { + return -1; + } + str = strdup(connect_proxy); + + for (i=0; i= PXY) { + break; + } + + if (q) { + *q = ','; + p = q + 1; + } else { + p = NULL; + } + } + free(str); + + if (!n) { + psock = -1; + goto pxy_clean; + } + + if (pxy[0] == PXY_SSH) { + int rc, len = 0; + char *cmd, *ssh; + int sport = find_free_port(7300, 8000); + if (getenv("SSH")) { + ssh = getenv("SSH"); + } else { + ssh = "ssh"; + } + len = 200 + strlen(ssh) + strlen(pxy_h[0]) + strlen(host); + cmd = (char *) malloc(len); + if (n == 1) { + if (pxy_p[0] <= 1) { + sprintf(cmd, "%s -f -L '%d:%s:%d' '%s' 'sleep 20'", ssh, sport, host, port, pxy_h[0]); + } else { + sprintf(cmd, "%s -f -p %d -L '%d:%s:%d' '%s' 'sleep 20'", ssh, pxy_p[0], sport, host, port, pxy_h[0]); + } + } else { + if (pxy_p[0] <= 1) { + sprintf(cmd, "%s -f -L '%d:%s:%d' '%s' 'sleep 20'", ssh, sport, pxy_h[1], pxy_p[1], pxy_h[0]); + } else { + sprintf(cmd, "%s -f -p %d -L '%d:%s:%d' '%s' 'sleep 20'", ssh, pxy_p[0], sport, pxy_h[1], pxy_p[1], pxy_h[0]); + } + } + if (no_external_cmds || !cmd_ok("ssh")) { + rfbLogEnable(1); + rfbLog("cannot run external commands in -nocmds mode:\n"); + rfbLog(" \"%s\"\n", cmd); + rfbLog(" exiting.\n"); + clean_up_exit(1); + } + close_exec_fds(); + fprintf(stderr, "\n"); + rfbLog("running: %s\n", cmd); + rc = system(cmd); + free(cmd); + if (rc != 0) { + psock = -1; + goto pxy_clean; + } + psock = rfbConnectToTcpAddr("localhost", sport); + + } else { + psock = rfbConnectToTcpAddr(pxy_h[0], pxy_p[0]); + } + + if (psock < 0) { + psock = -1; + goto pxy_clean; + } + rfbLog("opened socket to proxy: %s:%d\n", pxy_h[0], pxy_p[0]); + + if (n >= 2) { + if (! pconnect(psock, pxy_h[1], pxy_p[1], pxy[0], pxy_g[0], pxy_h[0], pxy_p[0])) { + close(psock); psock = -1; goto pxy_clean; + } + if (pxy_get_sock >= 0) {close(psock); psock = pxy_get_sock;} + + if (n >= 3) { + if (! pconnect(psock, pxy_h[2], pxy_p[2], pxy[1], pxy_g[1], pxy_h[1], pxy_p[1])) { + close(psock); psock = -1; goto pxy_clean; + } + if (pxy_get_sock >= 0) {close(psock); psock = pxy_get_sock;} + if (! pconnect(psock, host, port, pxy[2], pxy_g[2], pxy_h[2], pxy_p[2])) { + close(psock); psock = -1; goto pxy_clean; + } + if (pxy_get_sock >= 0) {close(psock); psock = pxy_get_sock;} + + } else { + if (! pconnect(psock, host, port, pxy[1], pxy_g[1], pxy_h[1], pxy_p[1])) { + close(psock); psock = -1; goto pxy_clean; + } + if (pxy_get_sock >= 0) {close(psock); psock = pxy_get_sock;} + } + } else { + if (! pconnect(psock, host, port, pxy[0], pxy_g[0], pxy_h[0], pxy_p[0])) { + close(psock); psock = -1; goto pxy_clean; + } + if (pxy_get_sock >= 0) {close(psock); psock = pxy_get_sock;} + } + + pxy_clean: + for (i=0; i < PXY; i++) { + if (pxy_h[i] != NULL) { + free(pxy_h[i]); + } + if (pxy_g[i] != NULL) { + free(pxy_g[i]); + } + } + + return psock; +} + /* * Do a reverse connect for a single "host" or "host:port" */ @@ -1654,15 +2192,13 @@ static int do_reverse_connect(char *str) { *p = '\0'; } -#if 0 - if (use_openssl && !getenv("X11VNC_SSL_ALLOW_REVERSE")) { - rfbLog("reverse connections disabled in -ssl mode.\n"); - return 0; - } -#endif - if (use_openssl) { - int vncsock = rfbConnectToTcpAddr(host, rport); + int vncsock; + if (connect_proxy) { + vncsock = proxy_connect(host, rport); + } else { + vncsock = rfbConnectToTcpAddr(host, rport); + } if (vncsock < 0) { rfbLog("reverse_connect: failed to connect to: %s\n", str); return 0; @@ -1702,7 +2238,17 @@ static int do_reverse_connect(char *str) { } } - cl = rfbReverseConnection(screen, host, rport); + if (connect_proxy != NULL) { + int sock = proxy_connect(host, rport); + if (sock >= 0) { + cl = rfbNewClient(screen, sock); + } else { + return 0; + } + } else { + cl = rfbReverseConnection(screen, host, rport); + } + free(host); if (cl == NULL) { -- cgit v1.2.3