incorporate new ultravnc_dsm_helper.c.

pull/1/head
runge 14 years ago
parent 6de3f0bed7
commit 8d79a63d3c

@ -1,3 +1,7 @@
2010-04-25 Karl Runge <runge@karlrunge.com>
* x11vnc: incorporate new ultravnc_dsm_helper.c, add pointer_mask
remote control query. Cut openssl default -ping delay.
2010-04-18 Karl Runge <runge@karlrunge.com>
* x11vnc/misc: improvements to demo scripts
* x11vnc: Alias -coe for -connect_or_exit. more accurate

@ -2,7 +2,7 @@
Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
All rights reserved.
x11vnc README file Date: Sun Apr 18 17:09:43 EDT 2010
x11vnc README file Date: Fri Apr 23 00:36:17 EDT 2010
The following information is taken from these URLs:
@ -11183,6 +11183,8 @@ Enhanced TightVNC Viewer (SSVNC: SSL/SSH VNC viewer)
(-grab/-graball option).
* Fix for Popup menu positioning for old window managers (-popupfix
option).
* The VNC Viewer ssvncviewer supports IPv6 natively (no helpers
needed.)
The list of 3rd party software bundled in the archive files:
* TightVNC Viewer (windows, unix, macosx)
@ -12076,7 +12078,7 @@ x11vnc: a VNC server for real X displays
Here are all of x11vnc command line options:
% x11vnc -opts (see below for -help long descriptions)
x11vnc: allow VNC connections to real X11 displays. 0.9.10 lastmod: 2010-04-18
x11vnc: allow VNC connections to real X11 displays. 0.9.10 lastmod: 2010-04-22
x11vnc options:
-display disp -auth file -N
@ -12206,7 +12208,7 @@ libvncserver-tight-extension options:
% x11vnc -help
x11vnc: allow VNC connections to real X11 displays. 0.9.10 lastmod: 2010-04-18
x11vnc: allow VNC connections to real X11 displays. 0.9.10 lastmod: 2010-04-22
(type "x11vnc -opts" to just list the options.)
@ -12299,7 +12301,7 @@ Options:
-6 IPv6 listening support. In addition to IPv4, the
IPv6 address is listened on for incoming connections.
The same port as IPv4 is used.
The same port number as IPv4 is used.
NOTE: This x11vnc binary was compiled to have the
"-6" IPv6 listening mode ENABLED by default (CPPFLAGS
@ -17258,6 +17260,7 @@ n
pointer_y print XQueryPointer y cursor position.
pointer_same print XQueryPointer ptr on same screen.
pointer_root print XQueryPointer curr ptr rootwin.
pointer_mask print XQueryPointer button and mods mask
mouse_x print x11vnc's idea of cursor position.
mouse_y print x11vnc's idea of cursor position.
noop do nothing.
@ -17567,9 +17570,11 @@ n
ext_xrecord ext_xkb ext_xshm ext_xinerama ext_overlay
ext_xfixes ext_xdamage ext_xrandr rootwin num_buttons
button_mask mouse_x mouse_y grab_state pointer_pos
pointer_x pointer_y pointer_same pointer_root bpp depth
indexed_color dpy_x dpy_y wdpy_x wdpy_y off_x off_y
cdpy_x cdpy_y coff_x coff_y rfbauth passwd viewpasswd
pointer_x pointer_y pointer_same pointer_root
pointer_mask bpp depth indexed_color dpy_x dpy_y wdpy_x
wdpy_y off_x off_y cdpy_x cdpy_y coff_x coff_y rfbauth
passwd viewpasswd
-QD variable Just like -query variable, but returns the default
value for that parameter (no running x11vnc server
is consulted)

@ -42,11 +42,12 @@ so, delete this exception statement from your version.
/*
* ultravnc_dsm_helper.c unix/openssl UltraVNC encryption encoder/decoder.
* (also a generic symmetric encryption tunnel)
* (also a generic TCP relay and supports IPv6)
*
* compile via:
cc -O -o ultravnc_dsm_helper ultravnc_dsm_helper.c -lcrypto
cc -DDBG -O -o ultravnc_dsm_helper ultravnc_dsm_helper.c -lcrypto
cc -O -o ultravnc_dsm_helper ultravnc_dsm_helper.c -lssl -lcrypto
cc -DDBG -O -o ultravnc_dsm_helper ultravnc_dsm_helper.c -lssl -lcrypto
*
* See usage below for how to run it.
@ -65,6 +66,10 @@ so, delete this exception statement from your version.
* e.g. to connect a non-ultra-dsm-vnc viewer to a non-ultra-dsm-vnc server
* without using SSH or SSL.
*
* It can also be used as a general TCP relay (no encryption.)
*
* It supports IPv6 and so can also be used as a IPv6 gateway.
*
* -----------------------------------------------------------------------
* Copyright (C) 2008-2010 Karl J. Runge <runge@karlrunge.com>
* All rights reserved.
@ -98,13 +103,28 @@ so, delete this exception statement from your version.
static char *usage =
"\n"
"usage: ultravnc_dsm_helper cipher keyfile listenport remotehost:port\n"
"ultravnc_dsm_helper: a symmetric encryption tunnel. version 0.2\n"
"\n"
" Created to enable encrypted VNC connections to UltraVNC, it can act as\n"
" a general encrypted tunnel between any two applications. It can also\n"
" be used as a general TCP relay (i.e. no encryption) or an IPv6 gateway.\n"
"\n"
"Usage: ultravnc_dsm_helper cipher keyfile listenport remotehost:port\n"
" ultravnc_dsm_helper relay listenport remotehost:port\n"
" ultravnc_dsm_helper showcert remotehost:port\n"
"\n"
"e.g.: ultravnc_dsm_helper arc4 ./arc4.key 5901 snoopy.net:5900\n"
"\n"
" cipher: specify 'msrc4', 'msrc4_sc', 'arc4', 'aesv2',\n"
" 'aes-cfb', 'aes256', 'blowfish', '3des',\n"
" 'securevnc'.\n"
" IPv6 is supported: both IPv4 and IPv6 are attempted to listen on (port\n"
" 'listenport'.) For connections to remotehost, if IPv4 fails\n"
" then IPv6 is tried. Set the env. var ULTRAVNC_DSM_HELPER_NOIPV6\n"
" to completely disable the use of IPv6.\n"
"\n"
"\n"
" cipher: specify 'msrc4', 'msrc4_sc', 'arc4', 'aesv2', 'aes-cfb',\n"
" 'aes256', 'blowfish', '3des', 'securevnc'.\n"
"\n"
" Also 'none', 'relay', or 'showcert'. See below for details.\n"
"\n"
" 'msrc4_sc' enables a workaround for UVNC SC -plugin use.\n"
" (it might not be required in SC circa 2009 and later; try 'msrc4'.)\n"
@ -127,19 +147,22 @@ static char *usage =
" use 'rev:arc4', etc. to reverse the roles of encrypter and decrypter.\n"
" (i.e. if you want to use it for a vnc server, not vnc viewer)\n"
"\n"
" use 'noultra:...' to skip steps involving salt and IV to be compatible\n"
" to be compatible with UltraVNC DSM, i.e. assume a normal symmetric\n"
" cipher at the other end.\n"
" use 'noultra:...' to skip steps involving salt and IV to try to be\n"
" compatible with UltraVNC DSM, i.e. assume a normal symmetric cipher\n"
" at the other end.\n"
"\n"
" use 'noultra:rev:...' if both are to be supplied.\n"
"\n"
"\n"
" keyfile: file holding the key (16 bytes for arc4 and aesv2, 87 for msrc4)\n"
" E.g. dd if=/dev/random of=./my.key bs=16 count=1\n"
" keyfile can also be pw=<string> to use \"string\" for the key.\n"
" Or for 'securevnc' the RSA keystore and/or ClientAuth file.\n"
"\n"
"\n"
" listenport: port to listen for incoming connection on. (use 0 to connect\n"
" to stdio, use a negative value to force localhost)\n"
" to stdio, use a negative value to force localhost listening)\n"
"\n"
"\n"
" remotehost:port: host and port to connect to. (e.g. ultravnc server)\n"
"\n"
@ -150,6 +173,39 @@ static char *usage =
"\n"
" Use cipher@md+n,m to change the message digest. E.g. arc4@sha+8,16\n"
" Supported: 'md5', 'sha', 'sha1', 'ripemd160'.\n"
"\n"
"\n"
" TCP Relay mode: to connect without any encryption use a cipher type of\n"
" either 'relay' or 'none' (both are the equivalent):\n"
"\n"
" ultravnc_dsm_helper relay listenport remotehost:port\n"
" ultravnc_dsm_helper none listenport remotehost:port\n"
"\n"
" where 'relay' or 'none' is a literal string.\n"
" Note that for this mode no keyfile is suppled.\n"
" Note that this mode can act as an IPv4 to IPv6 gateway.\n"
"\n"
" ultravnc_dsm_helper relay 8080 ipv6.beijing2008.cn:80\n"
"\n"
"\n"
" SSL Show Certificate mode: Set the cipher to 'showcert' to fetch\n"
" the SSL certificate from remotehost:port and print it to the stdout.\n"
" No certificate authentication or verification is performed. E.g.\n"
"\n"
" ultravnc_dsm_helper showcert www.verisign.com:443\n"
"\n"
" (the output resembles that of 'openssl s_client ...') Set the env var\n"
" ULTRAVNC_DSM_HELPER_SHOWCERT_ADH=1 for Anonymous Diffie Hellman mode.\n"
"\n"
"\n"
" Looping Mode: Set the env. var. ULTRAVNC_DSM_HELPER_LOOP=1 to have it\n"
" restart itself after every disconnection in an endless loop. It pauses\n"
" 500 msec before restarting. Use ULTRAVNC_DSM_HELPER_LOOP=N to set the\n"
" pause to N msec.\n"
"\n"
" You can also set the env. var. ULTRAVNC_DSM_HELPER_BG to have the\n"
" program fork into the background for each connection, thereby acting\n"
" as a simple daemon.\n"
;
/*
@ -200,6 +256,8 @@ static char *prog = "ultravnc_dsm_helper";
#include <openssl/rand.h>
#include <openssl/rsa.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/rsa.h>
static const EVP_CIPHER *Cipher;
static const EVP_MD *Digest;
#endif
@ -291,7 +349,7 @@ extern void enc_do(char *ciph, char *keyfile, char *lport, char *rhp) {
struct stat sb;
char *q, *p, *connect_host;
char tmp[16];
int fd, len = 0, listen_port, connect_port, mbits;
int fd, len = 0, listen_port = 0, connect_port, mbits;
q = ciph;
@ -337,6 +395,12 @@ extern void enc_do(char *ciph, char *keyfile, char *lport, char *rhp) {
Cipher = EVP_aes_128_ofb(); cipher = "securevnc";
securevnc = 1;
} else if (strstr(q, "none") == q || strstr(q, "relay") == q) {
cipher = "none";
} else if (strstr(q, "showcert") == q) {
cipher = "showcert";
} else if (strstr(q, ".") == q) {
/* otherwise, try to guess cipher from key filename: */
if (strstr(keyfile, "arc4.key")) {
@ -433,7 +497,9 @@ extern void enc_do(char *ciph, char *keyfile, char *lport, char *rhp) {
}
/* port to listen on (0 => stdio, negative => localhost) */
listen_port = atoi(lport);
if (lport != NULL) {
listen_port = atoi(lport);
}
/* extract remote hostname and port */
q = strrchr(rhp, ':');
@ -449,6 +515,13 @@ extern void enc_do(char *ciph, char *keyfile, char *lport, char *rhp) {
/* check for and read in the key file */
memset(keydata, 0, sizeof(keydata));
if (!strcmp(cipher, "none")) {
goto readed_in;
}
if (!strcmp(cipher, "showcert")) {
goto readed_in;
}
if (securevnc) {
/* note the keyfile for rsa verification later */
if (keyfile != NULL && strcasecmp(keyfile, "none")) {
@ -536,6 +609,81 @@ extern void enc_do(char *ciph, char *keyfile, char *lport, char *rhp) {
}
#endif
static void enc_raw_xfer(int sock_fr, int sock_to) {
unsigned char buf[BSIZE];
unsigned char *psrc = NULL;
int len, m, n = 0;
/* zero the buffers */
memset(buf, 0, BSIZE);
/* now loop forever processing the data stream */
while (1) {
errno = 0;
/* general case of loop, read some in: */
n = read(sock_fr, buf, BSIZE);
if (n == 0 || (n < 0 && errno != EINTR)) {
/* failure to read any data, it is EOF or fatal error */
int err = errno;
/* debug output: */
fprintf(stderr, "%s: input stream finished: n=%d, err=%d", prog, n, err);
/* EOF or fatal error */
break;
} else if (n > 0) {
/* write data to the other end: */
len = n;
psrc = buf;
while (len > 0) {
errno = 0;
m = write(sock_to, psrc, len);
if (m > 0) {
/* scoot them by how much was written: */
psrc += m;
len -= m;
}
if (m < 0 && (errno == EINTR || errno == EAGAIN)) {
/* interrupted or blocked */
continue;
}
/* EOF or fatal error */
break;
}
} else {
/* this is EINTR */
}
}
/* transfer done (viewer exited or some error) */
fprintf(stderr, "\n%s: close sock_to\n", prog);
close(sock_to);
fprintf(stderr, "%s: close sock_fr\n", prog);
close(sock_fr);
/* kill our partner after 1 secs. */
sleep(1);
if (child) {
if (kill(child, SIGTERM) == 0) {
fprintf(stderr, "%s[%d]: killed my partner: %d\n",
prog, (int) getpid(), (int) child);
}
} else {
if (kill(parent, SIGTERM) == 0) {
fprintf(stderr, "%s[%d]: killed my partner: %d\n",
prog, (int) getpid(), (int) parent);
}
}
}
#if ENC_HAVE_OPENSSL
/*
* Initialize cipher context and then loop till EOF doing transfer &
@ -1368,16 +1516,163 @@ static void securevnc_setup(int conn1, int conn2) {
write(viewer, to_viewer, to_viewer_len);
}
}
#ifndef ENC_DISABLE_SHOW_CERT
static void enc_sslerrexit(void) {
unsigned long err = ERR_get_error();
if (err) {
char str[256];
ERR_error_string(err, str);
fprintf(stdout, "ssl error: %s\n", str);
}
exit(1);
}
#endif
static void show_cert(int sock) {
#ifndef ENC_DISABLE_SHOW_CERT
SSL_CTX *ctx;
SSL *ssl = NULL;
STACK_OF(X509) *sk = NULL;
X509 *peer = NULL;
SSL_CIPHER *c;
BIO *bio;
unsigned char *sid = (unsigned char *) "ultravnc_dsm_helper SID";
long mode;
int i;
fprintf(stdout, "CONNECTED(%08X)\n",sock);
SSL_library_init();
SSL_load_error_strings();
if (!RAND_status()) {
RAND_poll();
}
/* this is not for a secured connection. */
for (i=0; i < 100; i++) {
if (!RAND_status()) {
char tmp[32];
sprintf(tmp, "%d", getpid() * (17 + i));
RAND_add(tmp, strlen(tmp), 5);
} else {
break;
}
}
ctx = SSL_CTX_new( SSLv23_client_method() );
if (ctx == NULL) {
fprintf(stdout, "show_cert: SSL_CTX_new failed.\n");
close(sock);
enc_sslerrexit();
}
mode = 0;
mode |= SSL_MODE_ENABLE_PARTIAL_WRITE;
mode |= SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER;
SSL_CTX_set_mode(ctx, mode);
if (getenv("ULTRAVNC_DSM_HELPER_SHOWCERT_ADH")) {
SSL_CTX_set_cipher_list(ctx, "ADH:@STRENGTH");
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
}
ssl = SSL_new(ctx);
if (ssl == NULL) {
fprintf(stdout, "show_cert: SSL_new failed.\n");
close(sock);
enc_sslerrexit();
}
SSL_set_session_id_context(ssl, sid, strlen((char *)sid));
if (! SSL_set_fd(ssl, sock)) {
fprintf(stdout, "show_cert: SSL_set_fd failed.\n");
close(sock);
enc_sslerrexit();
}
SSL_set_connect_state(ssl);
if (SSL_connect(ssl) <= 0) {
unsigned long err = ERR_get_error();
fprintf(stdout, "show_cert: SSL_connect failed.\n");
if (err) {
char str[256];
ERR_error_string(err, str);
fprintf(stdout, "ssl error: %s\n", str);
}
}
SSL_get_verify_result(ssl);
sk = SSL_get_peer_cert_chain(ssl);
if (sk != NULL) {
fprintf(stdout, "---\nCertificate chain\n");
for (i=0; i < sk_X509_num(sk); i++) {
char buf[2048];
X509_NAME_oneline(X509_get_subject_name(sk_X509_value(sk,i)), buf, sizeof buf);
fprintf(stdout, "%2d s:%s\n", i, buf);
X509_NAME_oneline(X509_get_issuer_name(sk_X509_value(sk,i)), buf, sizeof buf);
fprintf(stdout, " i:%s\n", buf);
}
} else {
fprintf(stdout, "show_cert: SSL_get_peer_cert_chain failed.\n");
}
fprintf(stdout, "---\n");
peer = SSL_get_peer_certificate(ssl);
bio = BIO_new_fp(stdout, BIO_NOCLOSE);
if (peer != NULL) {
char buf[2048];
BIO_printf(bio,"Server certificate\n");
PEM_write_bio_X509(bio, peer);
X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof buf);
BIO_printf(bio,"subject=%s\n",buf);
X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof buf);
BIO_printf(bio,"issuer=%s\n",buf);
} else {
fprintf(stdout, "show_cert: SSL_get_peer_certificate failed.\n");
}
c = SSL_get_current_cipher(ssl);
BIO_printf(bio,"---\nNew, %s, Cipher is %s\n", SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
if (peer != NULL) {
EVP_PKEY *pktmp;
pktmp = X509_get_pubkey(peer);
BIO_printf(bio,"Server public key is %d bit\n", EVP_PKEY_bits(pktmp));
EVP_PKEY_free(pktmp);
}
BIO_printf(bio,"---\nDONE\n---\n");
fflush(stdout);
#endif
close(sock);
exit(0);
}
#ifndef SOL_IPV6
#ifdef IPPROTO_IPV6
#define SOL_IPV6 IPPROTO_IPV6
#endif
#endif
/*
* Listens on incoming port for a client, then connects to remote server.
* Then forks into two processes one is the encrypter the other the
* decrypter.
*/
static void enc_connections(int listen_port, char *connect_host, int connect_port) {
int listen_fd, conn1, conn2, ret, one = 1;
int listen_fd = -1, listen_fd6 = -1, conn1 = -1, conn2 = -1, ret, one = 1;
socklen_t clen;
struct hostent *hp;
struct sockaddr_in client, server;
fd_set fds;
int maxfd = -1;
/* zero means use stdio (preferably from socketpair()) */
if (listen_port == 0) {
@ -1385,6 +1680,10 @@ static void enc_connections(int listen_port, char *connect_host, int connect_por
goto use_stdio;
}
if (!strcmp(cipher, "showcert")) {
goto use_stdio;
}
/* fd=n,m means use the supplied already established sockets */
if (sscanf(connect_host, "fd=%d,%d", &conn1, &conn2) == 2) {
goto use_input_fds;
@ -1405,25 +1704,95 @@ static void enc_connections(int listen_port, char *connect_host, int connect_por
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_fd < 0) {
perror("socket");
exit(1);
goto try6;
}
ret = setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR,
(char *)&one, sizeof(one));
if (ret < 0) {
perror("setsockopt");
exit(1);
close(listen_fd);
listen_fd = -1;
goto try6;
}
ret = bind(listen_fd, (struct sockaddr *) &client, sizeof(client));
if (ret < 0) {
perror("bind");
exit(1);
close(listen_fd);
listen_fd = -1;
goto try6;
}
ret = listen(listen_fd, 2);
if (ret < 0) {
perror("listen");
close(listen_fd);
listen_fd = -1;
goto try6;
}
try6:
#ifdef AF_INET6
if (!getenv("ULTRAVNC_DSM_HELPER_NOIPV6")) {
struct sockaddr_in6 sin;
int one = 1, sock = -1;
sock = socket(AF_INET6, SOCK_STREAM, 0);
if (sock < 0) {
perror("socket6");
goto fail;
}
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) {
perror("setsockopt6 SO_REUSEADDR");
close(sock);
sock = -1;
goto fail;
}
#if defined(SOL_IPV6) && defined(IPV6_V6ONLY)
if (setsockopt(sock, SOL_IPV6, IPV6_V6ONLY, (char *)&one, sizeof(one)) < 0) {
perror("setsockopt6 IPV6_V6ONLY");
close(sock);
sock = -1;
goto fail;
}
#endif
memset((char *)&sin, 0, sizeof(sin));
sin.sin6_family = AF_INET6;
if (listen_port < 0) {
sin.sin6_addr = in6addr_loopback;
sin.sin6_port = htons(-listen_port);
} else {
sin.sin6_addr = in6addr_any;
sin.sin6_port = htons(listen_port);
}
if (bind(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
perror("bind6");
close(sock);
sock = -1;
goto fail;
}
if (listen(sock, 2) < 0) {
perror("listen6");
close(sock);
sock = -1;
goto fail;
}
fail:
listen_fd6 = sock;
}
#endif
if (listen_fd < 0 && listen_fd6 < 0) {
fprintf(stderr, "%s: could not listen on port: %d\n",
prog, listen_port);
exit(1);
}
@ -1431,15 +1800,85 @@ static void enc_connections(int listen_port, char *connect_host, int connect_por
prog, listen_port);
/* wait for a connection: */
clen = sizeof(client);
conn1 = accept(listen_fd, (struct sockaddr *) &client, &clen);
if (conn1 < 0) {
perror("accept");
FD_ZERO(&fds);
if (listen_fd >= 0) {
FD_SET(listen_fd, &fds);
if (listen_fd > maxfd) {
maxfd = listen_fd;
}
}
if (listen_fd6 >= 0) {
FD_SET(listen_fd6, &fds);
if (listen_fd6 > maxfd) {
maxfd = listen_fd6;
}
}
if (select(maxfd+1, &fds, NULL, NULL, NULL) <= 0) {
perror("select");
exit(1);
}
if (FD_ISSET(listen_fd, &fds)) {
clen = sizeof(client);
conn1 = accept(listen_fd, (struct sockaddr *) &client, &clen);
if (conn1 < 0) {
perror("accept");
exit(1);
}
} else if (FD_ISSET(listen_fd6, &fds)) {
#ifdef AF_INET6
struct sockaddr_in6 addr;
socklen_t addrlen = sizeof(addr);
conn1 = accept(listen_fd6, (struct sockaddr *) &addr, &addrlen);
if (conn1 < 0) {
perror("accept6");
exit(1);
}
#else
fprintf(stderr, "No IPv6 / AF_INET6 support.\n");
exit(1);
#endif
}
if (setsockopt(conn1, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)) < 0) {
perror("setsockopt TCP_NODELAY");
exit(1);
}
/* done with the listening socket: */
close(listen_fd);
/* done with the listening socket(s): */
if (listen_fd >= 0) {
close(listen_fd);
}
if (listen_fd6 >= 0) {
close(listen_fd6);
}
if (getenv("ULTRAVNC_DSM_HELPER_BG")) {
int p, n;
if ((p = fork()) > 0) {
fprintf(stderr, "%s: putting child %d in background.\n",
prog, p);
exit(0);
} else if (p == -1) {
fprintf(stderr, "%s: could not fork\n", prog);
perror("fork");
exit(1);
}
if (setsid() == -1) {
fprintf(stderr, "%s: setsid failed\n", prog);
perror("setsid");
exit(1);
}
/* adjust our stdio */
n = open("/dev/null", O_RDONLY);
dup2(n, 0);
dup2(n, 1);
dup2(n, 2);
if (n > 2) {
close(n);
}
}
use_stdio:
@ -1453,8 +1892,7 @@ static void enc_connections(int listen_port, char *connect_host, int connect_por
if ((server.sin_addr.s_addr = inet_addr(connect_host)) == htonl(INADDR_NONE)) {
if (!(hp = gethostbyname(connect_host))) {
perror("gethostbyname");
close(conn1);
exit(1);
goto tryconn6;
}
server.sin_addr.s_addr = *(unsigned long *)hp->h_addr;
}
@ -1462,18 +1900,92 @@ static void enc_connections(int listen_port, char *connect_host, int connect_por
conn2 = socket(AF_INET, SOCK_STREAM, 0);
if (conn2 < 0) {
perror("socket");
close(conn1);
exit(1);
goto tryconn6;
}
if (connect(conn2, (struct sockaddr *)&server, (sizeof(server))) < 0) {
perror("connect");
close(conn1);
goto tryconn6;
}
tryconn6:
#ifdef AF_INET6
if (conn2 < 0 && !getenv("ULTRAVNC_DSM_HELPER_NOIPV6")) {
int err;
struct addrinfo *ai;
struct addrinfo hints;
char service[32];
fprintf(stderr, "connect[ipv6]: trying to connect via IPv6 to %s\n", connect_host);
conn2 = -1;
memset(&hints, 0, sizeof(hints));
sprintf(service, "%d", connect_port);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
#ifdef AI_ADDRCONFIG
hints.ai_flags |= AI_ADDRCONFIG;
#endif
#ifdef AI_NUMERICSERV
hints.ai_flags |= AI_NUMERICSERV;
#endif
err = getaddrinfo(connect_host, service, &hints, &ai);
if (err != 0) {
fprintf(stderr, "getaddrinfo[%d]: %s\n", err, gai_strerror(err));
} else {
struct addrinfo *ap = ai;
while (ap != NULL) {
int fd = -1;
fd = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol);
if (fd == -1) {
perror("socket6");
} else {
int dmsg = 0;
int res = connect(fd, ap->ai_addr, ap->ai_addrlen);
#if defined(SOL_IPV6) && defined(IPV6_V6ONLY)
if (res != 0) {
int zero = 0;
perror("connect6");
dmsg = 1;
if (setsockopt(fd, SOL_IPV6, IPV6_V6ONLY, (char *)&zero, sizeof(zero)) == 0) {
fprintf(stderr, "connect[ipv6]: trying again with IPV6_V6ONLY=0\n");
res = connect(fd, ap->ai_addr, ap->ai_addrlen);
dmsg = 0;
}
}
#endif
if (res == 0) {
conn2 = fd;
break;
} else {
if (!dmsg) perror("connect6");
close(fd);
}
}
ap = ap->ai_next;
}
freeaddrinfo(ai);
}
}
#endif
if (conn2 < 0) {
fprintf(stderr, "could not connect to %s\n", connect_host);
exit(1);
}
if (conn2 >= 0 && setsockopt(conn2, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)) < 0) {
perror("setsockopt TCP_NODELAY");
}
use_input_fds:
if (!strcmp(cipher, "showcert")) {
show_cert(conn2);
close(conn2);
exit(0);
}
if (securevnc) {
securevnc_setup(conn1, conn2);
}
@ -1495,18 +2007,74 @@ static void enc_connections(int listen_port, char *connect_host, int connect_por
if (child == 0) {
/* encrypter: local-viewer -> remote-server */
enc_xfer(conn1, conn2, 1);
if (!strcmp(cipher, "none") || !strcmp(cipher, "relay")) {
enc_raw_xfer(conn1, conn2);
} else {
enc_xfer(conn1, conn2, 1);
}
} else {
/* decrypter: remote-server -> local-viewer */
enc_xfer(conn2, conn1, 0);
if (!strcmp(cipher, "none") || !strcmp(cipher, "relay")) {
enc_raw_xfer(conn2, conn1);
} else {
enc_xfer(conn2, conn1, 0);
}
}
}
#endif /* ENC_HAVE_OPENSSL */
static void doloop (int argc, char *argv[]) {
int ms = atoi(getenv("ULTRAVNC_DSM_HELPER_LOOP"));
if (ms > 0) {
char *cmd;
int i, len = 0;
for (i = 0; i < argc; i++) {
len += strlen(argv[i]) + 2;
}
cmd = (char *)malloc(len);
cmd[0] = '\0';
for (i = 0; i < argc; i++) {
strcat(cmd, argv[i]);
if (i < argc - 1) {
strcat(cmd, " ");
}
}
putenv("ULTRAVNC_DSM_HELPER_LOOP_SET=1");
if (ms == 1) {
ms = 500;
}
i = 0;
while (1) {
fprintf(stderr, "loop running[%d]: %s\n", ++i, cmd);
system(cmd);
usleep(1000 * ms);
}
}
}
extern int main (int argc, char *argv[]) {
char *kf, *q;
if (argc < 4) {
if (getenv("ULTRAVNC_DSM_HELPER_LOOP")) {
if (!getenv("ULTRAVNC_DSM_HELPER_LOOP_SET")) {
doloop(argc, argv);
}
}
if (argc == 3) {
if (!strcmp(argv[1], "showcert")) {
enc_do(argv[1], NULL, NULL, argv[2]);
return 0;
}
}
if (argc == 4) {
if (!strcmp(argv[1], "none") || !strcmp(argv[1], "relay")) {
enc_do(argv[1], NULL, argv[2], argv[3]);
return 0;
}
}
if (argc < 5) {
fprintf(stdout, "%s\n", usage);
exit(1);
}

@ -144,7 +144,7 @@ void print_help(int mode) {
#if X11VNC_IPV6
"-6 IPv6 listening support. In addition to IPv4, the\n"
" IPv6 address is listened on for incoming connections.\n"
" The same port as IPv4 is used.\n"
" The same port number as IPv4 is used.\n"
"\n"
#if X11VNC_LISTEN6
" NOTE: This x11vnc binary was compiled to have the\n"
@ -5131,6 +5131,7 @@ void print_help(int mode) {
" pointer_y print XQueryPointer y cursor position.\n"
" pointer_same print XQueryPointer ptr on same screen.\n"
" pointer_root print XQueryPointer curr ptr rootwin.\n"
" pointer_mask print XQueryPointer button and mods mask\n"
" mouse_x print x11vnc's idea of cursor position.\n"
" mouse_y print x11vnc's idea of cursor position.\n"
" noop do nothing.\n"
@ -5440,9 +5441,11 @@ void print_help(int mode) {
" ext_xrecord ext_xkb ext_xshm ext_xinerama ext_overlay\n"
" ext_xfixes ext_xdamage ext_xrandr rootwin num_buttons\n"
" button_mask mouse_x mouse_y grab_state pointer_pos\n"
" pointer_x pointer_y pointer_same pointer_root bpp depth\n"
" indexed_color dpy_x dpy_y wdpy_x wdpy_y off_x off_y\n"
" cdpy_x cdpy_y coff_x coff_y rfbauth passwd viewpasswd\n"
" pointer_x pointer_y pointer_same pointer_root\n"
" pointer_mask bpp depth indexed_color dpy_x dpy_y wdpy_x\n"
" wdpy_y off_x off_y cdpy_x cdpy_y coff_x coff_y rfbauth\n"
" passwd viewpasswd\n"
"\n"
"-QD variable Just like -query variable, but returns the default\n"
" value for that parameter (no running x11vnc server\n"
" is consulted)\n"

@ -6126,10 +6126,10 @@ char *process_remote_cmd(char *cmd, int stringonly) {
}
goto qry;
}
if (!strcmp(p, "pointer_pos") || !strcmp(p, "pointer_x") || !strcmp(p, "pointer_y") || !strcmp(p, "pointer_same") || !strcmp(p, "pointer_root")) {
if (!strcmp(p, "pointer_pos") || !strcmp(p, "pointer_x") || !strcmp(p, "pointer_y") || !strcmp(p, "pointer_same") || !strcmp(p, "pointer_root") || !strcmp(p, "pointer_mask")) {
int px = -1, py = -1;
int wx, wy;
unsigned int m;
unsigned int m = 0;
Window r, c;
Bool same_screen = True;
@ -6144,6 +6144,8 @@ char *process_remote_cmd(char *cmd, int stringonly) {
snprintf(buf, bufn, "aro=%s:%d", p, same_screen);
} else if (!strcmp(p, "pointer_root")) { /* skip-cmd-list */
snprintf(buf, bufn, "aro=%s:0x%x", p, (unsigned int) rootwin);
} else if (!strcmp(p, "pointer_mask")) { /* skip-cmd-list */
snprintf(buf, bufn, "aro=%s:0x%x", p, m);
}
if (!dpy) {
goto qry;
@ -6166,6 +6168,8 @@ char *process_remote_cmd(char *cmd, int stringonly) {
snprintf(buf, bufn, "aro=%s:%d", p, same_screen);
} else if (!strcmp(p, "pointer_root")) { /* skip-cmd-list */
snprintf(buf, bufn, "aro=%s:0x%x", p, (unsigned int) r);
} else if (!strcmp(p, "pointer_mask")) { /* skip-cmd-list */
snprintf(buf, bufn, "aro=%s:0x%x", p, m);
}
if (rc_npieces < 10) {
rfbLog("remote_cmd: %s: %s\n", p, buf);

@ -3014,11 +3014,12 @@ static void ping_clients(int tile_cnt) {
if (tile_cnt > 0) {
last_send = now;
} else if (tile_cnt < 0) {
/* negative tile_cnt is -ping case */
if (now >= last_send - tile_cnt) {
mark_rect_as_modified(0, 0, 1, 1, 1);
last_send = now;
}
} else if (now - last_send > 2) {
} else if (now - last_send > 5) {
/* Send small heartbeat to client */
mark_rect_as_modified(0, 0, 1, 1, 1);
last_send = now;

@ -2717,6 +2717,19 @@ void openssl_port(int restart) {
return;
}
if (ipv6_listen && screen->port <= 0) {
if (got_rfbport) {
screen->port = got_rfbport_val;
} else {
int ap = 5900;
if (auto_port > 0) {
ap = auto_port;
}
screen->port = find_free_port6(ap, ap+200);
}
rfbLog("openssl_port: reset port from 0 => %d\n", screen->port);
}
if (restart) {
port = screen->port;
} else if (screen->listenSock > -1 && screen->port > 0) {
@ -4279,6 +4292,8 @@ if (db) rfbLog("raw_xfer bad write: %d -> %d | %d/%d errno=%d\n", csock, s_out
#define ENC_HAVE_OPENSSL 0
#endif
#define ENC_DISABLE_SHOW_CERT
#include "enc.h"
static void symmetric_encryption_xfer(int csock, int s_in, int s_out) {

@ -2,7 +2,7 @@
.TH X11VNC "1" "April 2010" "x11vnc " "User Commands"
.SH NAME
x11vnc - allow VNC connections to real X11 displays
version: 0.9.10, lastmod: 2010-04-18
version: 0.9.10, lastmod: 2010-04-22
.SH SYNOPSIS
.B x11vnc
[OPTION]...
@ -114,7 +114,7 @@ enter the port number.
.IP
IPv6 listening support. In addition to IPv4, the
IPv6 address is listened on for incoming connections.
The same port as IPv4 is used.
The same port number as IPv4 is used.
.IP
NOTE: This x11vnc binary was compiled to have the
"-6" IPv6 listening mode ENABLED by default (CPPFLAGS
@ -6004,6 +6004,8 @@ pointer_same print XQueryPointer ptr on same screen.
.IP
pointer_root print XQueryPointer curr ptr rootwin.
.IP
pointer_mask print XQueryPointer button and mods mask
.IP
mouse_x print x11vnc's idea of cursor position.
.IP
mouse_y print x11vnc's idea of cursor position.
@ -6411,9 +6413,10 @@ pipeinput clients client_count pid ext_xtest ext_xtrap
ext_xrecord ext_xkb ext_xshm ext_xinerama ext_overlay
ext_xfixes ext_xdamage ext_xrandr rootwin num_buttons
button_mask mouse_x mouse_y grab_state pointer_pos
pointer_x pointer_y pointer_same pointer_root bpp depth
indexed_color dpy_x dpy_y wdpy_x wdpy_y off_x off_y
cdpy_x cdpy_y coff_x coff_y rfbauth passwd viewpasswd
pointer_x pointer_y pointer_same pointer_root
pointer_mask bpp depth indexed_color dpy_x dpy_y wdpy_x
wdpy_y off_x off_y cdpy_x cdpy_y coff_x coff_y rfbauth
passwd viewpasswd
.PP
\fB-QD\fR \fIvariable\fR
.IP

@ -47,7 +47,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.9.10 lastmod: 2010-04-18";
char lastmod[] = "0.9.10 lastmod: 2010-04-22";
/* X display info */

Loading…
Cancel
Save