x11vnc: -proxy, -ssh options. ncache bug in -8to24, Selection "targets" bugfix.

pull/1/head
runge 16 years ago
parent be9dc49025
commit 81ef0b9345

@ -1,6 +1,6 @@
#!/bin/bash
VERSION="0.9.3"
VERSION="0.9.4"
cd "$(dirname "$0")"

@ -1721,10 +1721,12 @@ if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, dno
call_count++;
/* clip to display just in case: */
x1 = nfix(x1, dpy_x);
y1 = nfix(y1, dpy_y);
x2 = nfix(x2, dpy_x+1);
y2 = nfix(y2, dpy_y+1);
if (!ncache) {
x1 = nfix(x1, dpy_x);
y1 = nfix(y1, dpy_y);
x2 = nfix(x2, dpy_x+1);
y2 = nfix(y2, dpy_y+1);
}
if (wireframe_in_progress) {
/*
@ -1765,6 +1767,7 @@ if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, dno
idx = (int) (*uc);
if (0 && line % 100 == 0 && j % 32 == 0) fprintf(stderr, "%d %d %u x1=%d y1=%d\n", line, j, root_rgb[idx], x1, y1);
#if 0
if (do_hibits) {
hi = idx << 24;

@ -1,3 +1,9 @@
2007-10-27 Karl Runge <runge@karlrunge.com>
* x11vnc: fix ncache bug and others under -8to24, -ssh
option, socks and other proxies in -proxy option.
compiler warnings. fix TARGETS selection request bug
(java, konsole).
2007-10-03 Karl Runge <runge@karlrunge.com>
* x11vnc: add xfce to createdisplay

File diff suppressed because it is too large Load Diff

@ -133,6 +133,10 @@ void clean_up_exit (int ret) {
if (avahi) {
avahi_cleanup();
}
if (ssh_pid > 0) {
kill(ssh_pid, SIGTERM);
ssh_pid = 0;
}
#ifdef MACOSX
if (client_connect_file) {

@ -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<len+2; i++) {
fprintf(stderr, "b[%d]: %d\n", i, (int) buf[i]);
}
for (i=0; i<len+2; i++) {
fprintf(stderr, "r[%d]: %d\n", i, (int) reply[i]);
}
}
if (reply[0] == 0x5 && reply[1] == 0x0 && reply[2] == 0x0) {
rfbLog("SOCKS5 connect OK to %s:%d sock=%d\n", host, port, sock);
return 1;
} else {
rfbLog("SOCKS5 error to %s:%d sock=%d\n", host, port, sock);
close(sock);
return 0;
}
}
static int socks_proxy(char *host, int port, int sock) {
unsigned char buf[512], tmp[2];
char reply[16];
int socks4a = 0, len, i, j = 0, d1, d2, d3, d4;
memset(buf, 0, 512);
buf[0] = 0x4;
buf[1] = 0x1;
buf[2] = (unsigned char) (port >> 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<len; i++) {
fprintf(stderr, "b[%d]: %d\n", i, (int) buf[i]);
}
for (i=0; i<8; i++) {
fprintf(stderr, "r[%d]: %d\n", i, (int) reply[i]);
}
}
if (reply[0] == 0x0 && reply[1] == 0x5a) {
if (socks4a) {
rfbLog("SOCKS4a connect OK to %s:%d sock=%d\n", host, port, sock);
} else {
rfbLog("SOCKS4 connect OK to %s:%d sock=%d\n", host, port, sock);
}
return 1;
} else {
if (socks4a) {
rfbLog("SOCKS4a error to %s:%d sock=%d\n", host, port, sock);
} else {
rfbLog("SOCKS4 error to %s:%d sock=%d\n", host, port, sock);
}
close(sock);
return 0;
}
}
#define PXY_HTTP 1
#define PXY_GET 2
#define PXY_SOCKS 3
#define PXY_SOCKS5 4
#define PXY_SSH 5
#define PXY 3
static int pxy_get_sock;
static int pconnect(int psock, char *host, int port, int type, char *http_path, char *gethost, int getport) {
char reply[4096];
int i, ok, len;
char *req;
pxy_get_sock = -1;
if (type == PXY_SOCKS) {
return socks_proxy(host, port, psock);
}
if (type == PXY_SOCKS5) {
return socks5_proxy(host, port, psock);
}
if (type == PXY_SSH) {
return 1;
}
len = strlen("CONNECT ") + strlen(host);
if (type == PXY_GET) {
len += strlen(http_path) + strlen(gethost);
len += strlen("host=") + 1 + strlen("port=") + 1 + 1;
}
len += 1 + 20 + strlen("HTTP/1.1\r\n") + 1;
req = (char *)malloc(len);
if (type == PXY_GET) {
int noquery = 0;
char *t = strstr(http_path, "__END__");
if (t) {
noquery = 1;
*t = '\0';
}
if (noquery) {
sprintf(req, "GET %s HTTP/1.1\r\n", http_path);
} else {
sprintf(req, "GET %shost=%s&port=%d HTTP/1.1\r\n", http_path, host, port);
}
} else {
sprintf(req, "CONNECT %s:%d HTTP/1.1\r\n", host, port);
}
rfbLog("http proxy: %s", req);
write(psock, req, strlen(req));
if (type == PXY_GET) {
char *t = "Connection: close\r\n";
write(psock, t, strlen(t));
}
if (type == PXY_GET) {
sprintf(req, "Host: %s:%d\r\n", gethost, getport);
rfbLog("http proxy: %s", req);
sprintf(req, "Host: %s:%d\r\n\r\n", gethost, getport);
} else {
sprintf(req, "Host: %s:%d\r\n", host, port);
rfbLog("http proxy: %s", req);
sprintf(req, "Host: %s:%d\r\n\r\n", host, port);
}
write(psock, req, strlen(req));
ok = 0;
reply[0] = '\0';
for (i=0; i<4096; i++) {
int n;
req[0] = req[1] = '\0';
n = read(psock, req, 1);
if (n < 0) {
if (errno != EINTR) {
break;
} else {
continue;
}
}
if (n == 0) {
break;
}
strcat(reply, req);
if (strstr(reply, "\r\n\r\n")) {
if (strstr(reply, "HTTP/") == reply) {
char *q = strchr(reply, ' ');
if (q) {
q++;
if (q[0] == '2' && q[1] == '0' && q[2] == '0' && q[3] == ' ') {
ok = 1;
}
}
}
break;
}
}
if (type == PXY_GET) {
char *t1 = strstr(reply, "VNC-IP-Port: ");
char *t2 = strstr(reply, "VNC-Host-Port: ");
char *s, *newhost = NULL;
int newport = 0;
fprintf(stderr, "%s\n", reply);
if (t1) {
t1 += strlen("VNC-IP-Port: ");
s = strstr(t1, ":");
if (s) {
*s = '\0';
newhost = strdup(t1);
newport = atoi(s+1);
}
} else if (t2) {
t2 += strlen("VNC-Host-Port: ");
s = strstr(t2, ":");
if (s) {
*s = '\0';
newhost = strdup(t2);
newport = atoi(s+1);
}
}
if (newhost && newport > 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; i++) {
pxy[i] = 0;
pxy_p[i] = 0;
pxy_h[i] = NULL;
pxy_g[i] = NULL;
}
n = 0;
p = str;
while (p) {
char *hp, *c, *s = NULL;
q = strchr(p, ',');
if (q) {
*q = '\0';
}
if (n==0) fprintf(stderr, "\n");
rfbLog("proxy_connect[%d]: %s\n", n+1, p);
pxy[n] = 0;
pxy_p[n] = 0;
pxy_h[n] = NULL;
pxy_g[n] = NULL;
if (strstr(p, "socks://") == p) {
hp = strstr(p, "://") + 3;
pxy[n] = PXY_SOCKS;
} else if (strstr(p, "socks4://") == p) {
hp = strstr(p, "://") + 3;
pxy[n] = PXY_SOCKS;
} else if (strstr(p, "socks5://") == p) {
hp = strstr(p, "://") + 3;
pxy[n] = PXY_SOCKS5;
} else if (strstr(p, "ssh://") == p) {
if (n != 0) {
rfbLog("ssh:// proxy must be the first one\n");
clean_up_exit(1);
}
hp = strstr(p, "://") + 3;
pxy[n] = PXY_SSH;
} else if (strstr(p, "http://") == p) {
hp = strstr(p, "://") + 3;
pxy[n] = PXY_HTTP;
} else if (strstr(p, "https://") == p) {
hp = strstr(p, "://") + 3;
pxy[n] = PXY_HTTP;
} else {
hp = p;
pxy[n] = PXY_HTTP;
}
c = strstr(hp, ":");
if (!c && pxy[n] == PXY_SSH) {
char *hp2 = (char *) malloc(strlen(hp) + 5);
sprintf(hp2, "%s:1", hp);
hp = hp2;
c = strstr(hp, ":");
}
if (!c) {
pxy[n] = 0;
if (q) {
*q = ',';
p = q + 1;
} else {
p = NULL;
}
continue;
}
if (pxy[n] == PXY_HTTP) {
s = strstr(c, "/");
if (s) {
pxy[n] = PXY_GET;
pxy_g[n] = strdup(s);
*s = '\0';
}
}
pxy_p[n] = atoi(c+1);
if (pxy_p[n] <= 0) {
pxy[n] = 0;
pxy_p[n] = 0;
if (q) {
*q = ',';
p = q + 1;
} else {
p = NULL;
}
continue;
}
*c = '\0';
pxy_h[n] = strdup(hp);
if (++n >= 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) {

@ -400,7 +400,7 @@ void print_help(int mode) {
"-http_ssl As -http, but force lookup for ssl classes subdir.\n"
#endif
"\n"
"-avahi Use the Avahi/mDNS ZeroConf protocol to advertize\n"
"-avahi Use the Avahi/mDNS ZeroConf protocol to advertise\n"
" this VNC server to the local network. (Related terms:\n"
" Rendezvous, Bonjour). Depending on your setup, you\n"
" may need to start avahi-daemon and open udp port 5353\n"
@ -432,8 +432,67 @@ void print_help(int mode) {
"-connect_or_exit str As with -connect, except if none of the reverse\n"
" connections succeed, then x11vnc shutdowns immediately.\n"
"\n"
" If you do not want x11vnc to listen on ANY interface\n"
" use -rfbport 0\n"
" By the way, if you do not want x11vnc to listen on\n"
" ANY interface use -rfbport 0 which is handy for the\n"
" -connect_or_exit mode.\n"
"\n"
"-proxy string Use proxy in string (e.g. host:port) as a proxy for\n"
" making reverse connections (-connect or -connect_or_exit\n"
" options).\n"
"\n"
" Web proxies are supported, but note by default most of\n"
" them only support destination connections to ports 443\n"
" or 563, so this might not be very useful (the viewer\n"
" would need to listen on that port or the router would\n"
" have to do a port redirection).\n"
"\n"
" A web proxy may be specified by either \"host:port\"\n"
" or \"http://host:port\" (the port is required even if\n"
" it is the common choices 80 or 8080)\n"
"\n"
" SOCKS4, SOCKS4a, and SOCKS5 are also supported.\n"
" SOCKS proxies normally do not have restrictions on the\n"
" destination port number.\n"
"\n"
" Use a format like this: socks://host:port or\n"
" socks5://host:port. Note that ssh -D does not support\n"
" SOCKS4a, so use socks5://. For socks:// SOCKS4 is used\n"
" on a numerical IP and \"localhost\", otherwise SOCKS4a\n"
" is used (and so the proxy tries to do the DNS lookup).\n"
"\n"
" An experimental mode is \"-proxy http://host:port/...\"\n"
" Note the \"/\" after the port that distinguishes it from\n"
" a normal web proxy. The port must be supplied even if\n"
" it is the default 80. For this mode a GET is done to\n"
" the supplied URL with the string host=H&port=P appended.\n"
" H and P will be the -connect reverse connect host\n"
" and port. Use the string \"__END__\" to disable the\n"
" appending. The basic idea here is that maybe some cgi\n"
" script provides the actual viewer hookup and tunnelling.\n"
" How to actually achieve this within cgi, php, etc. is\n"
" not clear... A custom web server or apache module\n"
" would be straight-forward.\n"
"\n"
" Another experimental mode is \"-proxy ssh://user@host\"\n"
" in which case a SSH tunnel is used for the proxying.\n"
" \"user@\" is not needed unless your unix username is\n"
" different on \"host\". For a non-standard SSH port\n"
" use ssh://user@host:port. If proxies are chained (see\n"
" next paragraph) then the ssh one must be the first one.\n"
" If ssh-agent is not active, then the ssh password needs\n"
" to be entered in the terminal where x11vnc is running.\n"
" Examples:\n"
"\n"
" -connect localhost:0 -proxy ssh://me@friends-pc:2222\n"
"\n"
" -connect snoopy:0 -proxy ssh://ssh.company.com\n"
"\n"
" Multiple proxies may be chained together in case one\n"
" needs to ricochet off of a number of hosts to finally\n"
" reach the VNC viewer. Up to 3 may be chained, separate\n"
" them by commas in the order they are to be connected to.\n"
" E.g.: http://host1:port1,socks5://host2:port2 or three\n"
" like: first,second,third\n"
"\n"
"-vncconnect Monitor the VNC_CONNECT X property set by the standard\n"
"-novncconnect VNC program vncconnect(1). When the property is\n"
@ -578,7 +637,7 @@ void print_help(int mode) {
" If multiple non-blank lines exist in the file they are\n"
" all taken as valid passwords. Blank lines are ignored.\n"
" Password lines may be \"commented out\" (ignored) if\n"
" they begin with the charactor \"#\" or the line contains\n"
" they begin with the character \"#\" or the line contains\n"
" the string \"__SKIP__\". Lines may be annotated by use\n"
" of the \"__COMM__\" string: from it to the end of the\n"
" line is ignored. An empty password may be specified\n"
@ -721,7 +780,7 @@ void print_help(int mode) {
"-unixpw_nis [list] As -unixpw above, however do not use su(1) but rather\n"
" use the traditional getpwnam(3) + crypt(3) method to\n"
" verify passwords. All of the above -unixpw options and\n"
" contraints apply.\n"
" constraints apply.\n"
"\n"
" This mode requires that the encrypted passwords be\n"
" readable. Encrypted passwords stored in /etc/shadow\n"
@ -1090,6 +1149,11 @@ void print_help(int mode) {
" with libssl support it will exit immediately when -ssl\n"
" is prescribed.\n"
"\n"
" The VNC Viewer-side needs support SSL as well.\n"
" See this URL and also the discussion below for ideas\n"
" on how to enable SSL support for the viewer:\n"
" http://www.karlrunge.com/x11vnc/#faq-ssl-tunnel-viewers\n"
"\n"
" [pem] is optional, use \"-ssl /path/to/mycert.pem\"\n"
" to specify a PEM certificate file to use to identify\n"
" and provide a key for this server. See openssl(1) for\n"
@ -1098,12 +1162,12 @@ void print_help(int mode) {
" The connecting VNC viewer SSL tunnel can optionally\n"
" authenticate this server if they have the public\n"
" key part of the certificate (or a common certificate\n"
" authority, CA, is a more sophisicated way to verify\n"
" authority, CA, is a more sophisticated way to verify\n"
" this server's cert, see -sslGenCA below). This is\n"
" used to prevent man-in-the-middle attacks. Otherwise,\n"
" if the VNC viewer accepts this server's key without\n"
" verification, at least the traffic is protected\n"
" from passive sniffing on the network (but NOT from\n"
" from passive sniffing on the network (but *NOT* from\n"
" man-in-the-middle attacks).\n"
"\n"
" If [pem] is not supplied and the openssl(1) utility\n"
@ -1136,6 +1200,8 @@ void print_help(int mode) {
" made based on your answers to its prompts for info such\n"
" as OrganizationalName, CommonName, etc.\n"
"\n"
" We expect most users to use \"-ssl SAVE\".\n"
"\n"
" Use \"SAVE-<string>\" and \"SAVE_PROMPT-<string>\"\n"
" to refer to the file ~/.vnc/certs/server-<string>.pem\n"
" instead. E.g. \"SAVE-charlie\" will store to the file\n"
@ -1146,20 +1212,14 @@ void print_help(int mode) {
"\n"
" Example: x11vnc -ssl SAVE -display :0 ...\n"
"\n"
#if 0
" Reverse connections are disabled in -ssl mode because\n"
" there is no way to ensure that data channel will\n"
" be encrypted. Set X11VNC_SSL_ALLOW_REVERSE=1 to\n"
" override this.\n"
"\n"
#endif
" Your VNC viewer will also need to be able to connect\n"
" Your VNC viewer will need to be able to connect\n"
" via SSL. See the discussion below under -stunnel and\n"
" the FAQ (ss_vncviewer script) for how this might be\n"
" achieved. E.g. on Unix it is easy to write a shell\n"
" script that starts up stunnel and then vncviewer.\n"
" Also in the x11vnc source a SSL enabled Java VNC Viewer\n"
" applet is provided in the classes/ssl directory.\n"
" http://www.karlrunge.com/x11vnc/#faq-ssl-tunnel-viewers\n"
" for how this might be achieved. E.g. on Unix it is\n"
" easy to write a shell script that starts up stunnel\n"
" and then vncviewer. Also in the x11vnc source a SSL\n"
" enabled Java VNC Viewer applet is provided in the\n"
" classes/ssl directory.\n"
"\n"
"-ssltimeout n Set SSL read timeout to n seconds. In some situations\n"
" (i.e. an iconified viewer in Windows) the viewer stops\n"
@ -1326,7 +1386,7 @@ void print_help(int mode) {
" Once you have generated the CA you can distribute\n"
" its certificate part, [dir]/CA/cacert.pem, to other\n"
" workstations where VNC viewers will be run. One will\n"
" need to \"import\" this certicate in the applications,\n"
" need to \"import\" this certificate in the applications,\n"
" e.g. Web browser, Java applet plugin, stunnel, etc.\n"
" Next, you can create and sign keys using the CA with\n"
" the -sslGenCert option below.\n"
@ -1400,7 +1460,7 @@ void print_help(int mode) {
" Similar to -sslGenCA, you will be prompted to fill\n"
" in some information that will be recorded in the\n"
" certificate when it is created. Tip: if you know\n"
" the fully-quailified hostname other people will be\n"
" the fully-qualified hostname other people will be\n"
" connecting to you can use that as the CommonName \"CN\"\n"
" to avoid some applications (e.g. web browsers and java\n"
" plugin) complaining it does not match the hostname.\n"
@ -1408,7 +1468,7 @@ void print_help(int mode) {
" You will also need to supply the CA private key\n"
" passphrase to unlock the private key created from\n"
" -sslGenCA. This private key is used to sign the server\n"
" or client certicate.\n"
" or client certificate.\n"
"\n"
" The \"server\" certs can be used by x11vnc directly by\n"
" pointing to them via the -ssl [pem] option. The default\n"
@ -1621,13 +1681,51 @@ void print_help(int mode) {
"\n"
" This spares the user from having to type in\n"
" https://mygateway.com/?PORT=443 into their web\n"
" browser. Note taht port 443 is the default https port;\n"
" other ports must be explicity indicated, for example:\n"
" browser. Note that port 443 is the default https port;\n"
" other ports must be explicitly indicated, for example:\n"
" https://mygateway.com:8000/?PORT=8000. To avoid having\n"
" to include the PORT= in the browser URL, simply supply\n"
" \"-httpsredir\" to x11vnc.\n"
"\n"
#endif
"-ssh user@host:disp Create a remote listening port on machine \"host\"\n"
" via a SSH tunnel using the -R rport:localhost:lport\n"
" method. lport will be the local x11vnc listening port,\n"
" so a connection to rport (5900+disp) on \"host\"\n"
" will reach x11vnc. E.g. fred@snoopy.com:0\n"
"\n"
" This could be useful if a firewall/router prevents\n"
" incoming connections to the x11vnc machine, but\n"
" the ssh machine \"host\" can be reached by the VNC\n"
" viewer. \"user@\" is not needed unless the remote unix\n"
" username differs from the current one.\n"
"\n"
" By default the remote sshd is usually configured to\n"
" only listen on localhost for rport, so the viewer may\n"
" need to ssh -L redir to \"host\" as well (See SSVNC to\n"
" automate this). The sshd setting GatewayPorts enables\n"
" listening on all interfaces for rport; viewers can\n"
" reach it more easily.\n"
"\n"
" \"disp\" is the VNC display for the remote SSH side,\n"
" e.g. 0 corresponds to port 5900, etc. If disp is\n"
" greater than 200 the value is used as the port. Use a\n"
" negative value to force a low port, e.g. host:-80 will\n"
" use port 80.\n"
"\n"
" If ssh-agent is not active, then the ssh password needs\n"
" to be entered in the terminal where x11vnc is running.\n"
"\n"
" By default the remote ssh will issue a 'sleep 300' to\n"
" wait for the incoming connection for 5 mins. To modify\n"
" this use user@host:disp+secs.\n"
"\n"
" If the remote SSH server is on a non-standard port\n"
" (i.e. not 22) use user@host:port:disp+secs.\n"
"\n"
" Note that the ssh process may NOT be killed when\n"
" x11vnc exits. It tries by looking at ps(1) output.\n"
"\n"
"-usepw If no other password method was supplied on the command\n"
" line, first look for ~/.vnc/passwd and if found use it\n"
" with -rfbauth; next, look for ~/.vnc/passwdfile and\n"
@ -1674,7 +1772,7 @@ void print_help(int mode) {
" in RFB_CLIENT_COUNT. RFB_MODE will be \"accept\".\n"
" RFB_STATE will be PROTOCOL_VERSION, SECURITY_TYPE,\n"
" AUTHENTICATION, INITIALISATION, NORMAL, or UNKNOWN\n"
" indicating up to which state the client has acheived.\n"
" indicating up to which state the client has achieved.\n"
" RFB_LOGIN_VIEWONLY will be 0, 1, or -1 (unknown).\n"
" RFB_USERNAME, RFB_LOGIN_TIME, and RFB_CURRENT_TIME may\n"
" also be set.\n"
@ -2913,7 +3011,7 @@ void print_help(int mode) {
"-nowait_bog Do not detect if the screen polling is \"bogging down\"\n"
" and sleep more. Some activities with no user input can\n"
" slow things down a lot: consider a large terminal window\n"
" with a long build running in it continously streaming\n"
" with a long build running in it continuously streaming\n"
" text output. By default x11vnc will try to detect this\n"
" (3 screen polls in a row each longer than 0.25 sec with\n"
" no user input), and sleep up to 1.5 secs to let things\n"
@ -3110,7 +3208,7 @@ void print_help(int mode) {
" so take care.\n"
"\n"
" If the string begins with \"video\", see the VIDEO4LINUX\n"
" discusion below where the device may be queried for\n"
" discussion below where the device may be queried for\n"
" (and possibly set) the framebuffer parameters.\n"
"\n"
" If the string begins with \"console\", \"/dev/fb\", or\n"
@ -3668,10 +3766,10 @@ void print_help(int mode) {
" nohttp disable http client connections.\n"
" deny deny any new connections, same as \"lock\"\n"
" nodeny allow new connections, same as \"unlock\"\n"
" avahi enable avahi service advertizing.\n"
" noavahi disable avahi service advertizing.\n"
" mdns enable avahi service advertizing.\n"
" nomdns disable avahi service advertizing.\n"
" avahi enable avahi service advertising.\n"
" noavahi disable avahi service advertising.\n"
" mdns enable avahi service advertising.\n"
" nomdns disable avahi service advertising.\n"
/* access, filename */
" connect:host do reverse connection to host, \"host\"\n"
" may be a comma separated list of hosts\n"
@ -3684,6 +3782,8 @@ void print_help(int mode) {
" If you know the client internal hex ID,\n"
" e.g. 0x3 (returned by \"-query clients\"\n"
" and RFB_CLIENT_ID) you can use that too.\n"
" proxy:host:port set reverse connection proxy (empty to\n"
" disable).\n"
/* access */
" allowonce:host For the next connection only, allow\n"
" connection from \"host\".\n"
@ -3819,11 +3919,14 @@ void print_help(int mode) {
" noncache_no_moveraise disable no_moveraise mode.\n"
" ncache_no_dtchange enable ncache_no_dtchange mode.\n"
" noncache_no_dtchange disable ncache_no_dtchange mode.\n"
" ncache_old_wm enable ncache_old_wm mode.\n"
" noncache_old_wm disable ncache_old_wm mode.\n"
" ncache_no_rootpixmap enable ncache_no_rootpixmap.\n"
" noncache_no_rootpixmap disable ncache_no_rootpixmap.\n"
" ncache_reset_rootpixmap recheck the root pixmap, ncrp\n"
" ncache_keep_anims enable ncache_keep_anims.\n"
" noncache_keep_anims disable ncache_keep_anims.\n"
" ncache_pad:n set -ncache_pad to n.\n"
" wireframe enable -wireframe mode. same as \"wf\"\n"
" nowireframe disable -wireframe mode. same as \"nowf\"\n"
" wireframe:str enable -wireframe mode string.\n"
@ -3981,8 +4084,8 @@ void print_help(int mode) {
" 8to24_opts 24to32 no24to32 visual scale scale_cursor\n"
" viewonly noviewonly shared noshared forever noforever\n"
" once timeout tightfilexfer notightfilexfer ultrafilexfer\n"
" noultrafilexfer rfbversion deny lock nodeny unlock\n"
" avahi mdns noavahi nomdns connect allowonce allow\n"
" noultrafilexfer rfbversion deny lock nodeny unlock avahi\n"
" mdns noavahi nomdns connect proxy allowonce allow\n"
" localhost nolocalhost listen lookup nolookup accept\n"
" afteraccept gone shm noshm flipbyteorder noflipbyteorder\n"
" onetile noonetile solid_color solid nosolid blackout\n"
@ -4004,12 +4107,12 @@ void print_help(int mode) {
" nodragging ncache_cr noncache_cr ncache_no_moveraise\n"
" noncache_no_moveraise ncache_no_dtchange\n"
" noncache_no_dtchange ncache_no_rootpixmap\n"
" noncache_no_rootpixmap ncache_reset_rootpixmap\n"
" noncache_no_rootpixmap ncache_reset_rootpixmap ncrp\n"
" ncache_keep_anims noncache_keep_anims ncache_old_wm\n"
" noncache_old_wm ncache noncache ncache_size debug_ncache\n"
" nodebug_ncache wireframe_mode wireframe wf nowireframe\n"
" nowf wireframelocal wfl nowireframelocal nowfl\n"
" wirecopyrect wcr nowirecopyrect nowcr scr_area\n"
" noncache_old_wm ncache_pad ncache noncache ncache_size\n"
" debug_ncache nodebug_ncache wireframe_mode wireframe wf\n"
" nowireframe nowf wireframelocal wfl nowireframelocal\n"
" nowfl wirecopyrect wcr nowirecopyrect nowcr scr_area\n"
" scr_skip scr_inc scr_keys scr_term scr_keyrepeat\n"
" scr_parms scrollcopyrect scr noscrollcopyrect noscr\n"
" fixscreen noxrecord xrecord reset_record pointer_mode\n"
@ -4074,7 +4177,7 @@ void print_help(int mode) {
" command was processed by querying for any new settings.\n"
" Note however that there is timeout of a few seconds so\n"
" if the x11vnc takes longer than that to process the\n"
" requests the requestor will think that a failure has\n"
" requests the requester will think that a failure has\n"
" taken place.\n"
"\n"
"-noremote Do not process any remote control commands or queries.\n"
@ -4120,7 +4223,7 @@ void print_help(int mode) {
" associated options is:\n"
"\n"
" stunnel, ssl, unixpw, WAIT, id, accept, afteraccept,\n"
" gone, pipeinput, v4l-info, rawfb-setup, dt, gui,\n"
" gone, pipeinput, v4l-info, rawfb-setup, dt, gui, ssh,\n"
" storepasswd, passwdfile, custom_passwd, crash.\n"
"\n"
" See each option's help to learn the associated external\n"
@ -4257,7 +4360,7 @@ void xopen_display_fail_message(char *disp) {
" the secret key that\n");
fprintf(stderr, " allows x11vnc to connect to the desired"
" X DISPLAY.\n");
fprintf(stderr, " - You can explicity indicate which MIT-MAGIC-COOKIE"
fprintf(stderr, " - You can explicitly indicate which MIT-MAGIC-COOKIE"
" file should be used\n");
fprintf(stderr, " by the -auth option, e.g.:\n");
fprintf(stderr, " x11vnc -auth /home/someuser/.Xauthority"

@ -1755,7 +1755,7 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
if (khints && keysym < 0x100) {
/* low keysyms, ascii, only */
int ks = (int) keysym;
int ok = 1, lbest, l;
int ok = 1, lbest = 0, l;
short sbest = -1;
for (l=0; l < found; l++) {
if (kc_f[l] < 0x100) {
@ -1820,7 +1820,7 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
/* next just check for "best" one that is down */
if (Kc_f == -1 && anydown) {
int l;
int best = -1, lbest;
int best = -1, lbest = 0;
/*
* If it is already down, that is
* a great hint. Use it.

@ -1,5 +1,7 @@
/* -- macosxCGP.c -- */
void macosxCGP_unused(void) {}
#if (defined(__MACH__) && defined(__APPLE__))
#include <ApplicationServices/ApplicationServices.h>

@ -5,6 +5,7 @@
* and the other stuff, otherwise it does not work properly, mouse drags
* will not work!!
*/
void macosxCGS_unused(void) {}
#if (defined(__MACH__) && defined(__APPLE__))

@ -35,6 +35,8 @@ int https_port_redir = 0;
char *ssl_verify = NULL;
int ssl_initialized = 0;
int ssl_timeout_secs = -1;
char *ssh_str = NULL;
pid_t ssh_pid = 0;
int usepw = USEPW;
char *blackout_str = NULL; /* -blackout */
int blackout_ptr = 0;
@ -176,6 +178,7 @@ char *client_connect = NULL; /* strings for -connect option */
char *client_connect_file = NULL;
int connect_or_exit = 0;
int vnc_connect = 1; /* -vncconnect option */
char *connect_proxy = NULL;
int show_cursor = 1; /* show cursor shapes */
int show_multiple_cursors = 0; /* show X when on root background, etc */

@ -35,6 +35,8 @@ extern int https_port_redir;
extern char *ssl_verify;
extern int ssl_initialized;
extern int ssl_timeout_secs;
extern char *ssh_str;
extern pid_t ssh_pid;
extern int usepw;
extern char *blackout_str;
extern int blackout_ptr;
@ -148,6 +150,7 @@ extern char *client_connect;
extern char *client_connect_file;
extern int connect_or_exit;
extern int vnc_connect;
extern char *connect_proxy;
extern int show_cursor;
extern int show_multiple_cursors;

@ -1380,6 +1380,25 @@ char *process_remote_cmd(char *cmd, int stringonly) {
/* this is a reverse connection */
reverse_connect(p);
} else if (strstr(p, "proxy") == p) {
COLON_CHECK("proxy:")
if (query) {
snprintf(buf, bufn, "ans=%s%s%s", p, co,
NONUL(connect_proxy));
goto qry;
}
p += strlen("proxy:");
if (connect_proxy) {
free(connect_proxy);
connect_proxy = NULL;
}
if (!strcmp(p, "") || !strcasecmp(p, "none")) {
rfbLog("remote_cmd: disabled -proxy\n");
} else {
connect_proxy = strdup(p);
rfbLog("remote_cmd: set -proxy %s\n", connect_proxy);
}
} else if (strstr(p, "allowonce") == p) {
COLON_CHECK("allowonce:")
if (query) {
@ -2910,6 +2929,18 @@ char *process_remote_cmd(char *cmd, int stringonly) {
ncache_old_wm = 0;
rfbLog("remote_cmd: disabled -ncache_old_wm\n");
} else if (strstr(p, "ncache_pad") == p) {
int orig = ncache_pad, n;
COLON_CHECK("ncache_pad:")
if (query) {
snprintf(buf, bufn, "ans=%s%s%d", p, co, ncache_pad);
goto qry;
}
p += strlen("ncache_pad:");
n = atoi(p);
rfbLog("remote_cmd: setting ncache_pad %d to: %d\n", orig, n);
} else if (!strcmp(p, "ncache")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !!ncache);

@ -25,6 +25,7 @@
#include "macosxCG.h"
#include "avahi.h"
#include "solid.h"
#include "inet.h"
#include <rfb/rfbclient.h>
@ -1242,7 +1243,7 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
unsigned int vals[1024], val;
int x, y, fd, w = 1024, h = 768;
if (strstr(n, "0x")) {
if (sscanf(n, "0x%lx", &val) != 1) {
if (sscanf(n, "0x%x", &val) != 1) {
val = 0;
}
}

@ -62,6 +62,7 @@ void selection_request(XEvent *ev, char *type) {
char *str;
unsigned int length;
unsigned char *data;
static Atom xa_targets = None;
# ifndef XA_LENGTH
unsigned long XA_LENGTH;
# endif
@ -103,34 +104,69 @@ void selection_request(XEvent *ev, char *type) {
req_event->target, req_event->property);
}
if (xa_targets == None) {
xa_targets = XInternAtom(dpy, "TARGETS", False);
}
/* the window may have gone away, so trap errors */
trapped_xerror = 0;
old_handler = XSetErrorHandler(trap_xerror);
if (ev->xselectionrequest.target == XA_LENGTH) {
/* length request */
int ret;
long llength = (long) length;
XChangeProperty(ev->xselectionrequest.display,
ret = XChangeProperty(ev->xselectionrequest.display,
ev->xselectionrequest.requestor,
ev->xselectionrequest.property,
ev->xselectionrequest.target, 32, PropModeReplace,
(unsigned char *) &length, sizeof(unsigned int));
(unsigned char *) &llength, 1); /* had sizeof(unsigned int) = 4 before... */
if (debug_sel) {
rfbLog("LENGTH: XChangeProperty() -> %d\n", ret);
}
} else if (xa_targets != None && ev->xselectionrequest.target == xa_targets) {
/* targets request */
int ret;
Atom targets[2];
targets[0] = (Atom) xa_targets;
targets[1] = (Atom) XA_STRING;
data = (unsigned char *)str;
ret = XChangeProperty(ev->xselectionrequest.display,
ev->xselectionrequest.requestor,
ev->xselectionrequest.property,
ev->xselectionrequest.target, 32, PropModeReplace,
(unsigned char *) targets, 2);
if (debug_sel) {
rfbLog("TARGETS: XChangeProperty() -> %d -- sz1: %d sz2: %d\n",
ret, sizeof(targets[0]), sizeof(targets)/sizeof(targets[0]));
}
} else {
/* data request */
int ret;
data = (unsigned char *)str;
XChangeProperty(ev->xselectionrequest.display,
ret = XChangeProperty(ev->xselectionrequest.display,
ev->xselectionrequest.requestor,
ev->xselectionrequest.property,
ev->xselectionrequest.target, 8, PropModeReplace,
data, length);
if (debug_sel) {
rfbLog("DATA: XChangeProperty() -> %d\n", ret);
}
}
if (! trapped_xerror) {
XSendEvent(req_event->display, req_event->requestor, False, 0,
int ret = XSendEvent(req_event->display, req_event->requestor, False, 0,
(XEvent *)&notify_event);
if (debug_sel) {
rfbLog("XSendEvent() -> %d\n", ret);
}
}
if (trapped_xerror) {
rfbLog("selection_request: ignored XError while sending "

@ -382,8 +382,10 @@ Tuning
ncache_cr
ncache_no_moveraise
ncache_no_dtchange
ncache_old_wm
ncache_no_rootpixmap
ncache_keep_anims
ncache_pad:
=RA ncache_reset_rootpixmap
=GAL LOFF
--

@ -393,8 +393,10 @@ char gui_code[] = "";
" ncache_cr\n"
" ncache_no_moveraise\n"
" ncache_no_dtchange\n"
" ncache_old_wm\n"
" ncache_no_rootpixmap\n"
" ncache_keep_anims\n"
" ncache_pad:\n"
" =RA ncache_reset_rootpixmap\n"
" =GAL LOFF\n"
" --\n"

@ -1314,6 +1314,7 @@ void user_supplied_opts(char *opts) {
static void vnc_redirect_timeout (int sig) {
write(2, "timeout: no clients connected.\n", 31);
if (sig) {};
exit(0);
}
@ -1513,6 +1514,10 @@ int wait_for_client(int *argc, char** argv, int http) {
initialize_signals();
if (ssh_str != NULL) {
ssh_remote_tunnel(ssh_str, screen->port);
}
if (! raw_fb) {
chg_raw_fb = 1;
/* kludge to get RAWFB_RET with dpy == NULL guards */
@ -1600,7 +1605,6 @@ int wait_for_client(int *argc, char** argv, int http) {