x11vnc: gui speedup and fixes. -unixpw and -inetd

pull/1/head
runge 18 years ago
parent a9a9c812f7
commit c997e901c4

@ -1,3 +1,10 @@
2006-03-06 Karl Runge <runge@karlrunge.com>
* x11vnc: switch remote control to X11VNC_REMOTE property. Put
in -unixpw constraints for reverse connections under -inetd.
-inetd won't quit when reverse conn client leaves. Allow keyboard
input for viewonly -unixpw logins. "%*" utils for testing
-unixpw. improve start time fix bugs, small screen in gui.
2006-03-04 Karl Runge <runge@karlrunge.com>
* x11vnc: -unixpw on *bsd, hpux and tru64. Add -unixpw_nis for
non-shadow systems. check stunnel dying. check SSH_CONNECTION

@ -1,5 +1,5 @@
x11vnc README file Date: Sat Mar 4 17:57:40 EST 2006
x11vnc README file Date: Mon Mar 6 10:24:41 EST 2006
The following information is taken from these URLs:
@ -5382,7 +5382,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.8.1 lastmod: 2006-03-04
x11vnc: allow VNC connections to real X11 displays. 0.8.1 lastmod: 2006-03-06
x11vnc options:
-display disp -auth file
@ -5495,7 +5495,7 @@ libvncserver-tight-extension options:
% x11vnc -help
x11vnc: allow VNC connections to real X11 displays. 0.8.1 lastmod: 2006-03-04
x11vnc: allow VNC connections to real X11 displays. 0.8.1 lastmod: 2006-03-06
Typical usage is:
@ -5793,8 +5793,9 @@ Options:
-novncconnect VNC program vncconnect(1). When the property is
set to "host" or "host:port" establish a reverse
connection. Using xprop(1) instead of vncconnect may
work (see the FAQ). The -remote control mechanism also
uses this VNC_CONNECT channel. Default: -vncconnect
work (see the FAQ). The -remote control mechanism uses
X11VNC_REMOTE channel, and this option disables/enables
it as well. Default: -vncconnect
-allow host1[,host2..] Only allow client connections from hosts matching
the comma separated list of hostnames or IP addresses.
@ -5909,8 +5910,8 @@ Options:
x11vnc as root with the "-users +nobody" option to
immediately switch to user nobody. Another source of
problems are PAM modules that prompt for extra info,
e.g. password aging modules. These logins will always
fail as well.
e.g. password aging modules. These logins will fail
as well even when the correct password is supplied.
*IMPORTANT*: to prevent the Unix password being sent in
*clear text* over the network, two x11vnc options are
@ -5937,17 +5938,28 @@ Options:
is set and appears reasonable. If it does, then the
stunnel requirement is dropped since it is assumed
you are using ssh for the encrypted tunnelling.
Use -stunnel to force stunnel usage.
Use -stunnel to force stunnel usage for this case.
Set UNIXPW_DISABLE_LOCALHOST=1 to disable the -localhost
requirement. One should never do this (i.e. allow the
Unix passwords to be sniffed on the network).
NOTE: in -inetd mode the two settings are not enforced
since x11vnc does not make network connections in
that case. Be sure to use encryption from the viewer
to inetd. One can also have your own stunnel spawn
x11vnc in -inetd mode. See the FAQ.
Regarding reverse connections (e.g. -R connect:host),
the -localhost constraint is in effect and the reverse
connections can only be used to connect to the same
machine x11vnc is running on (default port 5500).
Please use a ssh or stunnel port redirection to the
viewer machine to tunnel the reverse connection over
an encrypted channel. Note that Unix username and
password *will* be prompted for (unlike VNC passwords
that are skipped for reverse connections).
NOTE: in -inetd mode the two settings are attempted
to be enforced for reverse connections. Be sure to
use encryption from the viewer to inetd since x11vnc
cannot guess easily if it is encrpyted. Note: you can
also have your own stunnel spawn x11vnc in -inetd mode
(i.e. bypassing inetd). See the FAQ.
The user names in the comma separated [list] can have
per-user options after a ":", e.g. "fred:opts"
@ -5962,16 +5974,21 @@ Options:
Use "deny" to explicitly deny some users if you use
"*" to set a global option.
-unixpw_nis [list] As -unixpw above, however do not run su(1) but rather
use the traditional getpwnam() + crypt() method instead.
This requires that the encrpyted passwords be readable.
Passwords stored in /etc/shadow will be inaccessible
unless run as root. This is called "NIS" mode
simply because in most NIS setups the user encrypted
passwords are accessible (e.g. "ypcat passwd").
NIS is not required for this mode to work, but it
is unlikely it will work for any other environment.
All of the -unixpw options and contraints apply.
There are also some tools for testing password if [list]
starts with the "%" character. See the quick_pw()
function for details.
-unixpw_nis [list] As -unixpw above, however do not use su(1) but rather
use the traditional getpwnam(3) + crypt(3) method
instead. This requires that the encrpyted passwords
be readable. Passwords stored in /etc/shadow will
be inaccessible unless run as root. This is called
"NIS" mode simply because in most NIS setups the
user encrypted passwords are accessible (e.g. "ypcat
passwd"). NIS is not required for this mode to
work, but it is unlikely it will work for any other
environment. All of the -unixpw options and contraints
apply.
-stunnel [pem] Use the stunnel(1) (www.stunnel.org) to provide
an encrypted SSL tunnel between viewers and x11vnc.
@ -7238,7 +7255,7 @@ n
-remote command.
The default communication channel is that of X
properties (specifically VNC_CONNECT), and so this
properties (specifically X11VNC_REMOTE), and so this
command must be run with correct settings for DISPLAY
and possibly XAUTHORITY to connect to the X server
and set the property. Alternatively, use the -display
@ -7520,9 +7537,9 @@ n
it comes back with prefix "aro=" instead of "ans=".
Some -remote commands are pure actions that do not make
sense as variables, e.g. "stop" or "disconnect",
in these cases the value returned is "N/A". To direct
a query straight to the VNC_CONNECT property or connect
sense as variables, e.g. "stop" or "disconnect", in
these cases the value returned is "N/A". To direct a
query straight to the X11VNC_REMOTE property or connect
file use "qry=..." instead of "cmd=..."
Here is the current list of "variables" that can
@ -7621,9 +7638,9 @@ n
A note about security wrt remote control commands.
If someone can connect to the X display and change
the property VNC_CONNECT, then they can remotely
the property X11VNC_REMOTE, then they can remotely
control x11vnc. Normally access to the X display is
protected. Note that if they can modify VNC_CONNECT
protected. Note that if they can modify X11VNC_REMOTE
on the X server, they have enough permissions to also
run their own x11vnc and thus have complete control
of the desktop. If the "-connect /path/to/file"
@ -7633,9 +7650,9 @@ n
permissions. See -privremote below.
If you are paranoid and do not think -noremote is
enough, to disable the VNC_CONNECT property channel
completely use -novncconnect, or use the -safer
option that shuts many things off.
enough, to disable the X11VNC_REMOTE property channel
completely use -novncconnect, or use the -safer option
that shuts many things off.
-unsafe A few remote commands are disabled by default
(currently: id:pick, accept:<cmd>, gone:<cmd>, and

@ -19,6 +19,9 @@
/* string for the VNC_CONNECT property */
char vnc_connect_str[VNC_CONNECT_MAX+1];
Atom vnc_connect_prop = None;
char x11vnc_remote_str[X11VNC_REMOTE_MAX+1];
Atom x11vnc_remote_prop = None;
rfbClientPtr inetd_client = NULL;
int all_clients_initialized(void);
char *list_clients(void);
@ -29,7 +32,9 @@ void set_client_input(char *str);
void set_child_info(void);
void reverse_connect(char *str);
void set_vnc_connect_prop(char *str);
void read_vnc_connect_prop(void);
void read_vnc_connect_prop(int);
void set_x11vnc_remote_prop(char *str);
void read_x11vnc_remote_prop(int);
void check_connect_inputs(void);
void check_gui_inputs(void);
enum rfbNewClientAction new_client(rfbClientPtr client);
@ -604,8 +609,8 @@ static void client_gone(rfbClientPtr client) {
free_client_data(client);
if (inetd) {
rfbLog("viewer exited.\n");
if (inetd && client == inetd_client) {
rfbLog("inetd viewer exited.\n");
clean_up_exit(0);
}
if (connect_once) {
@ -1463,6 +1468,21 @@ static int do_reverse_connect(char *str) {
*p = '\0';
}
if (inetd && unixpw) {
if(strcmp(host, "localhost") && strcmp(host, "127.0.0.1")) {
if (! getenv("UNIXPW_DISABLE_LOCALHOST")) {
rfbLog("reverse_connect: in -inetd only localhost\n");
rfbLog("connections allowed under -unixpw\n");
return 0;
}
}
if (! getenv("UNIXPW_DISABLE_STUNNEL") && ! have_ssh_env()) {
rfbLog("reverse_connect: in -inetd stunnel/ssh\n");
rfbLog("required under -unixpw\n");
return 0;
}
}
cl = rfbReverseConnection(screen, host, rport);
free(host);
@ -1529,15 +1549,20 @@ void reverse_connect(char *str) {
}
/*
* Routines for monitoring the VNC_CONNECT property for changes.
* The vncconnect(1) will set it on our X display.
* Routines for monitoring the VNC_CONNECT and X11VNC_REMOTE properties
* for changes. The vncconnect(1) will set it on our X display.
*/
void set_vnc_connect_prop(char *str) {
XChangeProperty(dpy, rootwin, vnc_connect_prop, XA_STRING, 8,
PropModeReplace, (unsigned char *)str, strlen(str));
}
void read_vnc_connect_prop(void) {
void set_x11vnc_remote_prop(char *str) {
XChangeProperty(dpy, rootwin, x11vnc_remote_prop, XA_STRING, 8,
PropModeReplace, (unsigned char *)str, strlen(str));
}
void read_vnc_connect_prop(int nomsg) {
Atom type;
int format, slen, dlen;
unsigned long nitems = 0, bytes_after = 0;
@ -1575,28 +1600,73 @@ void read_vnc_connect_prop(void) {
} while (bytes_after > 0);
vnc_connect_str[VNC_CONNECT_MAX] = '\0';
if (! db) {
if (! db || nomsg) {
;
} else if (strstr(vnc_connect_str, "ans=stop:N/A,ans=quit:N/A,ans=")) {
} else {
rfbLog("read VNC_CONNECT: %s\n", vnc_connect_str);
}
}
void read_x11vnc_remote_prop(int nomsg) {
Atom type;
int format, slen, dlen;
unsigned long nitems = 0, bytes_after = 0;
unsigned char* data = NULL;
int db = 1;
x11vnc_remote_str[0] = '\0';
slen = 0;
if (! vnc_connect || x11vnc_remote_prop == None) {
/* not active or problem with X11VNC_REMOTE atom */
return;
}
/* read the property value into x11vnc_remote_str: */
do {
if (XGetWindowProperty(dpy, DefaultRootWindow(dpy),
x11vnc_remote_prop, nitems/4, X11VNC_REMOTE_MAX/16, False,
AnyPropertyType, &type, &format, &nitems, &bytes_after,
&data) == Success) {
dlen = nitems * (format/8);
if (slen + dlen > X11VNC_REMOTE_MAX) {
/* too big */
rfbLog("warning: truncating large X11VNC_REMOTE"
" string > %d bytes.\n", X11VNC_REMOTE_MAX);
XFree(data);
break;
}
memcpy(x11vnc_remote_str+slen, data, dlen);
slen += dlen;
x11vnc_remote_str[slen] = '\0';
XFree(data);
}
} while (bytes_after > 0);
x11vnc_remote_str[X11VNC_REMOTE_MAX] = '\0';
if (! db || nomsg) {
;
} else if (strstr(vnc_connect_str, "qry=stop,quit,exit")) {
} else if (strstr(x11vnc_remote_str, "ans=stop:N/A,ans=quit:N/A,ans=")) {
;
} else if (strstr(vnc_connect_str, "ack=") == vnc_connect_str) {
} else if (strstr(x11vnc_remote_str, "qry=stop,quit,exit")) {
;
} else if (quiet && strstr(vnc_connect_str, "qry=ping") ==
vnc_connect_str) {
} else if (strstr(x11vnc_remote_str, "ack=") == x11vnc_remote_str) {
;
} else if (strstr(vnc_connect_str, "cmd=") &&
strstr(vnc_connect_str, "passwd")) {
rfbLog("read VNC_CONNECT: *\n");
} else if (strlen(vnc_connect_str) > 38) {
} else if (quiet && strstr(x11vnc_remote_str, "qry=ping") ==
x11vnc_remote_str) {
;
} else if (strstr(x11vnc_remote_str, "cmd=") &&
strstr(x11vnc_remote_str, "passwd")) {
rfbLog("read X11VNC_REMOTE: *\n");
} else if (strlen(x11vnc_remote_str) > 38) {
char trim[100];
trim[0] = '\0';
strncat(trim, vnc_connect_str, 38);
rfbLog("read VNC_CONNECT: %s ...\n", trim);
strncat(trim, x11vnc_remote_str, 38);
rfbLog("read X11VNC_REMOTE: %s ...\n", trim);
} else {
rfbLog("read VNC_CONNECT: %s\n", vnc_connect_str);
rfbLog("read X11VNC_REMOTE: %s\n", x11vnc_remote_str);
}
}
@ -1643,6 +1713,13 @@ void check_connect_inputs(void) {
vnc_connect_str[0] = '\0';
}
send_client_connect();
/* X11VNC_REMOTE property */
if (vnc_connect && *x11vnc_remote_str != '\0') {
client_connect = strdup(x11vnc_remote_str);
x11vnc_remote_str[0] = '\0';
}
send_client_connect();
}
void check_gui_inputs(void) {
@ -1650,7 +1727,7 @@ void check_gui_inputs(void) {
int socks[ICON_MODE_SOCKS];
fd_set fds;
struct timeval tv;
char buf[VNC_CONNECT_MAX+1];
char buf[X11VNC_REMOTE_MAX+1];
ssize_t nbytes;
if (unixpw_in_progress) return;
@ -1686,10 +1763,10 @@ void check_gui_inputs(void) {
if (! FD_ISSET(fd, &fds)) {
continue;
}
for (k=0; k<=VNC_CONNECT_MAX; k++) {
for (k=0; k<=X11VNC_REMOTE_MAX; k++) {
buf[k] = '\0';
}
nbytes = read(fd, buf, VNC_CONNECT_MAX);
nbytes = read(fd, buf, X11VNC_REMOTE_MAX);
if (nbytes <= 0) {
close(fd);
icon_mode_socks[socks[i]] = -1;
@ -1726,15 +1803,20 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
last_event = last_input = time(0);
if (inetd) {
/*
* Set this so we exit as soon as connection closes,
* otherwise client_gone is only called after RFB_CLIENT_ACCEPT
*/
client->clientGoneHook = client_gone;
if (inetd_client == NULL) {
inetd_client = client;
client->clientGoneHook = client_gone;
}
}
clients_served++;
if (0) fprintf(stderr, "new_client: %s %d\n", client->host, clients_served);
if (unixpw && unixpw_in_progress) {
rfbLog("denying additional client: %s during -unixpw login.\n",
@ -1822,6 +1904,11 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
if (unixpw) {
unixpw_in_progress = 1;
unixpw_client = client;
unixpw_login_viewonly = 0;
if (client->viewOnly) {
unixpw_login_viewonly = 1;
client->viewOnly = FALSE;
}
unixpw_last_try_time = time(0);
unixpw_screen(1);
unixpw_keystroke(0, 0, 1);
@ -1926,6 +2013,7 @@ void send_client_info(char *str) {
strcat(pstr, "\n");
if (icon_mode_fh) {
if (0) fprintf(icon_mode_fh, "\n");
fprintf(icon_mode_fh, "%s", pstr);
fflush(icon_mode_fh);
}
@ -1940,6 +2028,7 @@ void send_client_info(char *str) {
len = strlen(pstr);
while (len > 0) {
if (0) write(sock, "\n", 1);
n = write(sock, buf, len);
if (n > 0) {
buf += n;
@ -1965,7 +2054,11 @@ void check_new_clients(void) {
int run_after_accept = 0;
if (unixpw_in_progress) {
if (time(0) > unixpw_last_try_time + 30) {
if (unixpw_client && unixpw_client->viewOnly) {
unixpw_login_viewonly = 1;
unixpw_client->viewOnly = FALSE;
}
if (time(0) > unixpw_last_try_time + 25) {
rfbLog("unixpw_deny: timed out waiting for reply.\n");
unixpw_deny();
}
@ -1992,7 +2085,7 @@ void check_new_clients(void) {
return;
}
if (! client_count) {
send_client_info("none");
send_client_info("clients:none");
return;
}
@ -2037,9 +2130,12 @@ void check_new_clients(void) {
}
}
if (send_info) {
char *str = list_clients();
char *str, *s = list_clients();
str = (char *) malloc(strlen("clients:") + strlen(s) + 1);
sprintf(str, "clients:%s", s);
send_client_info(str);
free(str);
free(s);
}
}

@ -5,6 +5,10 @@
extern char vnc_connect_str[];
extern Atom vnc_connect_prop;
extern char x11vnc_remote_str[];
extern Atom x11vnc_remote_prop;
extern rfbClientPtr inetd_client;
extern int all_clients_initialized(void);
extern char *list_clients(void);
@ -15,7 +19,9 @@ extern void set_client_input(char *str);
extern void set_child_info(void);
extern void reverse_connect(char *str);
extern void set_vnc_connect_prop(char *str);
extern void read_vnc_connect_prop(void);
extern void read_vnc_connect_prop(int);
extern void set_x11vnc_remote_prop(char *str);
extern void read_x11vnc_remote_prop(int);
extern void check_connect_inputs(void);
extern void check_gui_inputs(void);
extern enum rfbNewClientAction new_client(rfbClientPtr client);

@ -22,6 +22,7 @@ int tray_manager_ok = 0;
Window tray_request = None;
Window tray_window = None;
int tray_unembed = 0;
pid_t run_gui_pid = 0;
char *get_gui_code(void);
@ -183,6 +184,12 @@ static char *icon_mode_embed_id = NULL;
static char *icon_mode_font = NULL;
static char *icon_mode_params = NULL;
static int got_sigusr1 = 0;
static void sigusr1 (int sig) {
got_sigusr1 = 1;
}
static void run_gui(char *gui_xdisplay, int connect_to_x11vnc, int start_x11vnc,
int simple_gui, pid_t parent, char *gui_opts) {
char *x11vnc_xdisplay = NULL;
@ -191,10 +198,11 @@ static void run_gui(char *gui_xdisplay, int connect_to_x11vnc, int start_x11vnc,
char cmd[100];
char *wish = NULL, *orig_path, *full_path, *tpath, *p;
char *old_xauth = NULL;
int try_max = 4, sleep = 300;
int try_max = 4, sleep = 300, totms;
pid_t mypid = getpid();
FILE *pipe, *tmpf;
if (0) fprintf(stderr, "run_gui: %s -- %d %d\n", gui_xdisplay, connect_to_x11vnc, (int) parent);
if (*gui_code == '\0') {
rfbLog("gui: gui not compiled into this program.\n");
exit(0);
@ -234,21 +242,44 @@ static void run_gui(char *gui_xdisplay, int connect_to_x11vnc, int start_x11vnc,
scr = DefaultScreen(dpy);
rootwin = RootWindow(dpy, scr);
initialize_vnc_connect_prop();
initialize_x11vnc_remote_prop();
}
signal(SIGUSR1, sigusr1);
got_sigusr1 = 0;
totms = 0;
while (totms < 3500) {
usleep(50*1000);
totms += 50;
if (got_sigusr1) {
fprintf(stderr, "\n");
if (! quiet) rfbLog("gui: got SIGUSR1\n");
break;
}
if (! start_x11vnc && totms >= 150) {
break;
}
}
usleep(2200*1000);
fprintf(stderr, "\n");
if (!quiet) {
signal(SIGUSR1, SIG_DFL);
if (! got_sigusr1) fprintf(stderr, "\n");
if (!quiet && ! got_sigusr1) {
rfbLog("gui: trying to contact a x11vnc server at X"
" display %s ...\n", NONUL(x11vnc_xdisplay));
}
for (i=0; i<try_max; i++) {
usleep(sleep*1000);
if (!quiet) {
rfbLog("gui: pinging %s try=%d ...\n",
NONUL(x11vnc_xdisplay), i+1);
}
rc = send_remote_cmd("qry=ping", 1, 1);
if (rc == 0) {
if (! got_sigusr1) {
if (!quiet) {
rfbLog("gui: pinging %s try=%d ...\n",
NONUL(x11vnc_xdisplay), i+1);
}
rc = send_remote_cmd("qry=ping", 1, 1);
if (rc == 0) {
break;
}
} else {
rc = 0;
break;
}
if (parent && mypid != parent && kill(parent, 0) != 0) {
@ -257,6 +288,7 @@ static void run_gui(char *gui_xdisplay, int connect_to_x11vnc, int start_x11vnc,
rc = 1;
break;
}
usleep(sleep*1000);
}
set_env("X11VNC_XDISPLAY", x11vnc_xdisplay);
if (getenv("XAUTHORITY") != NULL) {
@ -619,6 +651,9 @@ void do_gui(char *opts, int sleep) {
simple_gui, parent, opts);
exit(1);
}
if (connect_to_x11vnc) {
run_gui_pid = p;
}
#else
fprintf(stderr, "system does not support fork: start "
"x11vnc in the gui.\n");

@ -11,6 +11,7 @@ extern int tray_manager_ok;
extern Window tray_request;
extern Window tray_window;
extern int tray_unembed;
extern pid_t run_gui_pid;
extern char *get_gui_code(void);
extern int tray_embed(Window iconwin, int remove);

@ -315,8 +315,9 @@ void print_help(int mode) {
"-novncconnect VNC program vncconnect(1). When the property is\n"
" set to \"host\" or \"host:port\" establish a reverse\n"
" connection. Using xprop(1) instead of vncconnect may\n"
" work (see the FAQ). The -remote control mechanism also\n"
" uses this VNC_CONNECT channel. Default: %s\n"
" work (see the FAQ). The -remote control mechanism uses\n"
" X11VNC_REMOTE channel, and this option disables/enables\n"
" it as well. Default: %s\n"
"\n"
"-allow host1[,host2..] Only allow client connections from hosts matching\n"
" the comma separated list of hostnames or IP addresses.\n"
@ -431,8 +432,8 @@ void print_help(int mode) {
" x11vnc as root with the \"-users +nobody\" option to\n"
" immediately switch to user nobody. Another source of\n"
" problems are PAM modules that prompt for extra info,\n"
" e.g. password aging modules. These logins will always\n"
" fail as well.\n"
" e.g. password aging modules. These logins will fail\n"
" as well even when the correct password is supplied.\n"
"\n"
" *IMPORTANT*: to prevent the Unix password being sent in\n"
" *clear text* over the network, two x11vnc options are\n"
@ -459,17 +460,28 @@ void print_help(int mode) {
" is set and appears reasonable. If it does, then the\n"
" stunnel requirement is dropped since it is assumed\n"
" you are using ssh for the encrypted tunnelling.\n"
" Use -stunnel to force stunnel usage.\n"
" Use -stunnel to force stunnel usage for this case.\n"
"\n"
" Set UNIXPW_DISABLE_LOCALHOST=1 to disable the -localhost\n"
" requirement. One should never do this (i.e. allow the\n"
" Unix passwords to be sniffed on the network).\n"
"\n"
" NOTE: in -inetd mode the two settings are not enforced\n"
" since x11vnc does not make network connections in\n"
" that case. Be sure to use encryption from the viewer\n"
" to inetd. One can also have your own stunnel spawn\n"
" x11vnc in -inetd mode. See the FAQ.\n"
" Regarding reverse connections (e.g. -R connect:host),\n"
" the -localhost constraint is in effect and the reverse\n"
" connections can only be used to connect to the same\n"
" machine x11vnc is running on (default port 5500).\n"
" Please use a ssh or stunnel port redirection to the\n"
" viewer machine to tunnel the reverse connection over\n"
" an encrypted channel. Note that Unix username and\n"
" password *will* be prompted for (unlike VNC passwords\n"
" that are skipped for reverse connections).\n"
"\n"
" NOTE: in -inetd mode the two settings are attempted\n"
" to be enforced for reverse connections. Be sure to\n"
" use encryption from the viewer to inetd since x11vnc\n"
" cannot guess easily if it is encrpyted. Note: you can\n"
" also have your own stunnel spawn x11vnc in -inetd mode\n"
" (i.e. bypassing inetd). See the FAQ.\n"
"\n"
" The user names in the comma separated [list] can have\n"
" per-user options after a \":\", e.g. \"fred:opts\"\n"
@ -484,16 +496,21 @@ void print_help(int mode) {
" Use \"deny\" to explicitly deny some users if you use\n"
" \"*\" to set a global option.\n"
"\n"
"-unixpw_nis [list] As -unixpw above, however do not run su(1) but rather\n"
" use the traditional getpwnam() + crypt() method instead.\n"
" This requires that the encrpyted passwords be readable.\n"
" Passwords stored in /etc/shadow will be inaccessible\n"
" unless run as root. This is called \"NIS\" mode\n"
" simply because in most NIS setups the user encrypted\n"
" passwords are accessible (e.g. \"ypcat passwd\").\n"
" NIS is not required for this mode to work, but it\n"
" is unlikely it will work for any other environment.\n"
" All of the -unixpw options and contraints apply.\n"
" There are also some tools for testing password if [list]\n"
" starts with the \"%\" character. See the quick_pw()\n"
" function for details.\n"
"\n"
"-unixpw_nis [list] As -unixpw above, however do not use su(1) but rather\n"
" use the traditional getpwnam(3) + crypt(3) method\n"
" instead. This requires that the encrpyted passwords\n"
" be readable. Passwords stored in /etc/shadow will\n"
" be inaccessible unless run as root. This is called\n"
" \"NIS\" mode simply because in most NIS setups the\n"
" user encrypted passwords are accessible (e.g. \"ypcat\n"
" passwd\"). NIS is not required for this mode to\n"
" work, but it is unlikely it will work for any other\n"
" environment. All of the -unixpw options and contraints\n"
" apply.\n"
"\n"
"-stunnel [pem] Use the stunnel(1) (www.stunnel.org) to provide\n"
" an encrypted SSL tunnel between viewers and x11vnc.\n"
@ -1767,7 +1784,7 @@ void print_help(int mode) {
" -remote command.\n"
"\n"
" The default communication channel is that of X\n"
" properties (specifically VNC_CONNECT), and so this\n"
" properties (specifically X11VNC_REMOTE), and so this\n"
" command must be run with correct settings for DISPLAY\n"
" and possibly XAUTHORITY to connect to the X server\n"
" and set the property. Alternatively, use the -display\n"
@ -2056,9 +2073,9 @@ void print_help(int mode) {
" it comes back with prefix \"aro=\" instead of \"ans=\".\n"
"\n"
" Some -remote commands are pure actions that do not make\n"
" sense as variables, e.g. \"stop\" or \"disconnect\",\n"
" in these cases the value returned is \"N/A\". To direct\n"
" a query straight to the VNC_CONNECT property or connect\n"
" sense as variables, e.g. \"stop\" or \"disconnect\", in\n"
" these cases the value returned is \"N/A\". To direct a\n"
" query straight to the X11VNC_REMOTE property or connect\n"
" file use \"qry=...\" instead of \"cmd=...\"\n"
"\n"
" Here is the current list of \"variables\" that can\n"
@ -2157,9 +2174,9 @@ void print_help(int mode) {
"\n"
" A note about security wrt remote control commands.\n"
" If someone can connect to the X display and change\n"
" the property VNC_CONNECT, then they can remotely\n"
" the property X11VNC_REMOTE, then they can remotely\n"
" control x11vnc. Normally access to the X display is\n"
" protected. Note that if they can modify VNC_CONNECT\n"
" protected. Note that if they can modify X11VNC_REMOTE\n"
" on the X server, they have enough permissions to also\n"
" run their own x11vnc and thus have complete control\n"
" of the desktop. If the \"-connect /path/to/file\"\n"
@ -2169,9 +2186,9 @@ void print_help(int mode) {
" permissions. See -privremote below.\n"
"\n"
" If you are paranoid and do not think -noremote is\n"
" enough, to disable the VNC_CONNECT property channel\n"
" completely use -novncconnect, or use the -safer\n"
" option that shuts many things off.\n"
" enough, to disable the X11VNC_REMOTE property channel\n"
" completely use -novncconnect, or use the -safer option\n"
" that shuts many things off.\n"
"\n"
"-unsafe A few remote commands are disabled by default\n"
" (currently: id:pick, accept:<cmd>, gone:<cmd>, and\n"

@ -30,6 +30,7 @@
#define FB_REQ 0x4
#define VNC_CONNECT_MAX 16384
#define X11VNC_REMOTE_MAX 16384
#define PROP_MAX (131072L)
#define MAXN 256

@ -55,11 +55,11 @@ int send_remote_cmd(char *cmd, int query, int wait) {
perror("fopen");
return 1;
}
} else if (vnc_connect_prop == None) {
initialize_vnc_connect_prop();
if (vnc_connect_prop == None) {
} else if (x11vnc_remote_prop == None) {
initialize_x11vnc_remote_prop();
if (x11vnc_remote_prop == None) {
fprintf(stderr, "send_remote_cmd: could not obtain "
"VNC_CONNECT X property\n");
"X11VNC_REMOTE X property\n");
return 1;
}
}
@ -71,13 +71,13 @@ int send_remote_cmd(char *cmd, int query, int wait) {
fclose(in);
} else {
fprintf(stderr, ">>> sending remote command: \"%s\" via"
" VNC_CONNECT X property.\n", cmd);
set_vnc_connect_prop(cmd);
" X11VNC_REMOTE X property.\n", cmd);
set_x11vnc_remote_prop(cmd);
XFlush(dpy);
}
if (query || wait) {
char line[VNC_CONNECT_MAX];
char line[X11VNC_REMOTE_MAX];
int rc=1, i=0, max=70, ms_sl=50;
if (!strcmp(cmd, "cmd=stop")) {
@ -95,7 +95,7 @@ int send_remote_cmd(char *cmd, int query, int wait) {
perror("fopen");
return 1;
}
fgets(line, VNC_CONNECT_MAX, in);
fgets(line, X11VNC_REMOTE_MAX, in);
fclose(in);
q = line;
while (*q != '\0') {
@ -103,8 +103,9 @@ int send_remote_cmd(char *cmd, int query, int wait) {
q++;
}
} else {
read_vnc_connect_prop();
strncpy(line, vnc_connect_str, VNC_CONNECT_MAX);
read_x11vnc_remote_prop(1);
strncpy(line, x11vnc_remote_str,
X11VNC_REMOTE_MAX);
}
if (strcmp(cmd, line)){
if (query) {
@ -581,8 +582,8 @@ char *process_remote_cmd(char *cmd, int stringonly) {
#if REMOTE_CONTROL
char *p = cmd;
char *co = "";
char buf[VNC_CONNECT_MAX];
int bufn = VNC_CONNECT_MAX;
char buf[X11VNC_REMOTE_MAX];
int bufn = X11VNC_REMOTE_MAX;
int query = 0;
static char *prev_cursors_mode = NULL;
@ -617,7 +618,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
strncat(tmp, q, 500);
res = process_remote_cmd(tmp, 1);
if (res && strlen(buf)+strlen(res)
>= VNC_CONNECT_MAX - 1) {
>= X11VNC_REMOTE_MAX - 1) {
rfbLog("overflow in process_remote_cmd:"
" %s -- %s\n", buf, res);
free(res);
@ -3848,7 +3849,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
}
} else {
if (dpy) { /* raw_fb hack */
set_vnc_connect_prop(buf);
set_x11vnc_remote_prop(buf);
XFlush(dpy);
}
}

@ -13,6 +13,7 @@
#endif
void check_stunnel(void);
int start_stunnel(int stunnel_port, int x11vnc_port);
void stop_stunnel(void);
void setup_stunnel(int rport, int *argc, char **argv);

@ -56,6 +56,30 @@ catch {rename send {}}
# -- means add a separator
#
global env started time_count
set started ""
proc dtime {{msg ""}} {
global started time_count
if {$started == ""} {
return
}
set diff [expr "[exec gtod.bin] - $started"]
set diff [format "%.2f" $diff]
incr time_count
if {$msg == ""} {
set msg $time_count
}
puts -nonewline stderr "$msg $diff "
puts stderr [clock format [clock seconds]]
}
if [info exists env(X11VNC_GUI_TIME)] {
global started time_count
set started [exec gtod.bin]
set time_count 0
dtime "S"
}
proc set_template {} {
global template
set template "
@ -1746,7 +1770,6 @@ proc entry_delete {} {
proc push_new_value {item name new {query 1}} {
global menu_var always_update remote_output query_output
global delay_sleep extra_sleep extra_sleep_split
global query_result_list
set debug [in_debug_mode]
@ -2985,7 +3008,6 @@ proc do_var {item} {
set debug [in_debug_mode]
set string 0
if {[is_action $item] || $item == "WindowView"} {
# Menu item is action:
@ -3409,9 +3431,9 @@ proc update_clients_menu {list} {
set count 0
foreach client [split $list ","] {
if {![regexp {^[a-z0-9]*[a-z0-9]:} $client]} {
append_text "Skipping client line: "
append_text $client
append_text "\n"
#append_text "Skipping client line: "
#append_text $client
#append_text "\n"
continue
}
regsub -all {[{}()~!$&*|;'"`{}<>\[\]]} $client "" client
@ -3978,9 +4000,15 @@ proc do_props {{msg ""}} {
global have_labelframes ffont bfont
global props_buttons icon_noadvanced
global icon_mode icon_mode_at_startup
global screen_height screen_width
check_update_vars
set pady 1m
if {$screen_height <= 360} {
set pady 0m
}
if [info exists menu_var(deny)] {
if {$menu_var(deny) == $unset_str || $menu_var(deny) == 0} {
set props_accept 1
@ -4087,7 +4115,7 @@ proc do_props {{msg ""}} {
pack $vp.l -fill x -expand 1 -padx 1m -pady 0m -side top
}
entry $vp.e -show "*" -textvariable props_viewpasswd -font $bfont
pack $vp.e -fill x -expand 1 -padx 1m -pady 1m -side top
pack $vp.e -fill x -expand 1 -padx 1m -pady $pady -side top
lappend props_buttons $vp.e
@ -4102,7 +4130,7 @@ proc do_props {{msg ""}} {
pack $pw.l -fill x -expand 1 -padx 1m -pady 0m -side top
}
entry $pw.e -show "*" -textvariable props_passwd -font $bfont
pack $pw.e -fill x -expand 1 -padx 1m -pady 1m -side top
pack $pw.e -fill x -expand 1 -padx 1m -pady $pady -side top
if {! $icon_mode_at_startup} {
$vp.e configure -state disabled
@ -4121,31 +4149,31 @@ proc do_props {{msg ""}} {
frame $sh
checkbutton $sh.button -text "Shared" \
-variable props_shared -anchor w -font $bfont
pack $sh.button -fill x -expand 1 -padx 1m -pady 1m
pack $sh.button -fill x -expand 1 -padx 1m -pady $pady
set vo "$w.viewonly"
frame $vo
checkbutton $vo.button -text "All Clients ViewOnly" \
-variable props_viewonly -anchor w -font $bfont
pack $vo.button -fill x -expand 1 -padx 1m -pady 1m
pack $vo.button -fill x -expand 1 -padx 1m -pady $pady
set cf "$w.confirm"
frame $cf
checkbutton $cf.button -text "Ask for Confirmation" \
-variable props_confirm -anchor w -font $bfont
pack $cf.button -fill x -expand 1 -padx 1m -pady 1m
pack $cf.button -fill x -expand 1 -padx 1m -pady $pady
set ac "$w.accept"
frame $ac
checkbutton $ac.button -text "Accept Connections" \
-variable props_accept -anchor w -font $bfont
pack $ac.button -fill x -expand 1 -padx 1m -pady 1m
pack $ac.button -fill x -expand 1 -padx 1m -pady $pady
set px "6m"
pack $b1 -side bottom -fill x -pady 1m -padx $px
pack $b2 -side bottom -fill x -pady 1m -padx $px
pack $vp -side bottom -fill x -pady 1m -padx $px
pack $pw -side bottom -fill x -pady 1m -padx $px
pack $b1 -side bottom -fill x -pady $pady -padx $px
pack $b2 -side bottom -fill x -pady $pady -padx $px
pack $vp -side bottom -fill x -pady $pady -padx $px
pack $pw -side bottom -fill x -pady $pady -padx $px
pack $sh -side bottom -fill x -pady 0m -padx $px
pack $vo -side bottom -fill x -pady 0m -padx $px
pack $cf -side bottom -fill x -pady 0m -padx $px
@ -4158,7 +4186,8 @@ proc do_props {{msg ""}} {
set ms "$w.msg"
text $ms -font $ffont -relief ridge -width $tw -height $th
$ms insert 1.0 $msg
pack $ms -side bottom -fill x -pady 1m -padx $px
pack $ms -side bottom -fill x -pady $pady -padx $px
update
}
lappend props_buttons $ac.button $cf.button $vo.button $sh.button
@ -4346,7 +4375,10 @@ proc read_client_info {channel} {
catch {file delete $x11vnc_client_file}
set read_client_info_lock 0
clean_icon_exit
} elseif {$str != "skip"} {
} elseif {$str == "skip"} {
;
} elseif [regexp {^clients:} $str] {
regsub {^clients:} $str "" str
if {$str == "none"} {
set str ""
}
@ -4487,6 +4519,7 @@ proc try_client_info_sock {} {
global x11vnc_xdisplay0 menu_var
set db 0
#dtime t1
set start 13037
set tries 100
set socket_got_callback 0
@ -4537,8 +4570,12 @@ proc try_client_info_sock {} {
append_text "try_client_info_sock: server socket failed.\n"
return
}
run_remote_cmd [list "-nosync" "-R" "noop"]
after 500
if {! $x11vnc_started} {
run_remote_cmd [list "-nosync" "-R" "noop"]
if {$db} {dtime A}
after 250
if {$db} {dtime A}
}
# set the cookie to some obscured randomness
set socket_cookie [clock clicks]
@ -4557,8 +4594,18 @@ proc try_client_info_sock {} {
}
run_remote_cmd [list "-nosync" "-R" \
"client_info_sock:$myaddr:$port:$socket_cookie"]
#dtime t2
if {$db} {puts "client_info_sock:$myaddr:$port:$socket_cookie"}
after 500
for {set i 0} {$i < 10} {incr i} {
after 50
update; update idletasks
#dtime aa
if {$socket_got_callback != 0} {
#puts "break-"
break
}
}
#dtime t3
set aftid ""
if {$socket_got_callback == 0} {
@ -4576,6 +4623,7 @@ proc try_client_info_sock {} {
} else {
setup_client_sock 1
}
#dtime t4
}
proc set_icon_label {} {
@ -5022,10 +5070,14 @@ proc make_widgets {top} {
global helptext helpremote helplabel
global icon_mode icon_win props_win full_win
global top_widget_names
global screen_height screen_width
# Make the top label
set label_width 80
if {$screen_width <= 400} {
set label_width 64
}
set info_label "$top.info"
label $info_label -textvariable info_str -bd 2 -relief groove \
-anchor w -width $label_width -font $ffont
@ -5124,8 +5176,14 @@ proc make_widgets {top} {
pack $df -side top -fill x
# text area
global text_height
set text_area "$top.text"
text $text_area -height 12 -relief ridge -font $ffont
if {$screen_width <= 400} {
text $text_area -height $text_height -width $label_width \
-relief ridge -font $ffont
} else {
text $text_area -height $text_height -relief ridge -font $ffont
}
pack $text_area -side top -fill both -expand 1
set top_widget_names(text) $text_area
@ -5694,6 +5752,24 @@ proc run_remote_cmd_via_sock {opts} {
if {$db} {puts stderr "run_remote_cmd_via_sock: \"$res\""}
set res [string trim $res]
if [regexp {^clients:} $res] {
regsub {^clients:} $res "" tmp
if {$tmp == "none"} {
set tmp ""
}
update_clients_menu $tmp
set client_str $tmp
set_client_balloon $tmp
if ![regexp {^clients} $opt] {
# we could block here...
if {$db} {puts stderr "run_remote_cmd_via_sock: gets"}
gets $client_sock res
if {$db} {puts stderr "run_remote_cmd_via_sock: \"$res\""}
set res [string trim $res]
}
}
set docmd ""
if {$res != ""} {
@ -5806,6 +5882,7 @@ proc try_connect {} {
global menu_var unset_str
set db 0
#dtime c1
if {! $connected_to_x11vnc} {
if {[info exists menu_var(display)]} {
@ -5820,6 +5897,7 @@ proc try_connect {} {
set_info "Pinging $x11vnc_xdisplay ..."
set rargs [list "-Q" "ping"]
set result [run_remote_cmd $rargs]
#dtime c2a
if {$db} {puts "try_connect: \"$result\""}
@ -5831,10 +5909,12 @@ proc try_connect {} {
set_connected yes
setup_client_channel
#dtime c2b
setup_client_sock 1
setup_client_tail
fetch_displays
#dtime c3a
return 1
} else {
set str "x11vnc server."
@ -6007,6 +6087,10 @@ proc undo_tray_embed {} {
############################################################################
# main:
if [info exists env(X11VNC_GUI_TIME)] {
dtime M
}
wm withdraw .
global env x11vnc_prog x11vnc_cmdline x11vnc_xdisplay x11vnc_connect;
@ -6017,10 +6101,10 @@ global x11vnc_auth_file x11vnc_connect_file beginner_mode simple_gui_created
global helpall helptext helpremote helplabel hostname osname
global all_settings reply_xdisplay always_update
global max_text_height max_text_width
global text_height
global menu_var unset_str menus_disabled
global bfont ffont sfont snfont old_labels have_labelframes
global connected_to_x11vnc
global delay_sleep extra_sleep extra_sleep_split
global cache_all_query_vars
global last_query_all_time query_all_freq client_tail client_sock client_info_read
global icon_mode icon_mode_at_startup
@ -6028,6 +6112,7 @@ global tray_embed tray_running icon_setpasswd icon_embed_id
global icon_noadvanced icon_minimal
global make_gui_count text_area_str
global gui_argv0 gui_start_mode
global screen_height screen_width
set unset_str "(unset)"
set vnc_url $unset_str
@ -6035,6 +6120,7 @@ set connected_to_x11vnc 0
set menus_disabled 0
set max_text_height 40
set max_text_width 90
set text_height 14
set bfont "-adobe-helvetica-bold-r-*-*-*-120-*-*-*-*-*-*"
set sfont "-adobe-helvetica-bold-r-*-*-*-100-*-*-*-*-*-*"
set snfont "-adobe-helvetica-medium-r-*-*-*-100-*-*-*-*-*-*"
@ -6054,11 +6140,6 @@ set text_area_str ""
set gui_argv0 $argv0
set gui_start_mode ""
# these are no longer used under x11vnc -sync:
set delay_sleep 350
set extra_sleep 1000
set extra_sleep_split 4
if {$tk_version < 8.0} {
puts stderr ""
puts stderr "*** tkx11vnc: tk version is old $tk_version, please use 8.0 or higher."
@ -6075,6 +6156,19 @@ if {$tk_version < 8.4} {
set have_labelframes 0
}
set screen_height [winfo screenheight .]
set screen_width [winfo screenwidth .]
if {$screen_height < 500} {
# short screen, PDA?
set max_text_height 22
set text_height 13
if {$screen_height <= 360} {
# very short.
set max_text_height 16
set max_text_width 60
set text_height 11
}
}
if {[info exists env(X11VNC_GUI_TEXT_HEIGHT)]} {
set max_text_height $env(X11VNC_GUI_TEXT_HEIGHT)
}
@ -6130,7 +6224,7 @@ if {[info exists env(X11VNC_CLIENT_FILE)]} {
if {$client_tail != ""} {
gets $client_tail tmp
if [eof $client_tail] {
puts "eof $client_tail"
#puts "eof $client_tail"
clean_client_tail
set client_tail ""
}
@ -6299,25 +6393,29 @@ key_bindings;
get_default_vars
dtime D
if {$icon_mode} {
if {$tray_embed} {
make_gui "tray"
} else {
make_gui "icon"
}
dtime G
old_balloon
if {$icon_setpasswd} {
set m "You must specify a Session\n"
set m "${m}Password before VNC clients can\n"
set m "${m}connect. Enter one in the Password\n"
set m "${m}field and then Press \"OK\". This\n"
set m "${m}password is not stored, it is only\n"
set m "${m}used for this x11vnc session.\n"
set m "You must specify a Session Password\n"
set m "${m}before VNC clients can connect.\n"
set m "${m}Enter one in the Password field\n"
set m "${m}and Press \"OK\". The password(s) is\n"
set m "${m}only for this x11vnc session.\n"
do_props $m
push_new_value "unlock" "unlock" 1 0
#push_new_value "unlock" "unlock" 1 0
}
} else {
make_gui "full"
dtime G
}
# main loop.

@ -67,6 +67,30 @@ char gui_code[] = "";
"# -- means add a separator\n"
"#\n"
"\n"
"global env started time_count\n"
"set started \"\"\n"
"proc dtime {{msg \"\"}} {\n"
" global started time_count\n"
" if {$started == \"\"} {\n"
" return\n"
" }\n"
" set diff [expr \"[exec gtod.bin] - $started\"]\n"
" set diff [format \"%.2f\" $diff]\n"
" incr time_count\n"
" if {$msg == \"\"} {\n"
" set msg $time_count\n"
" }\n"
" puts -nonewline stderr \"$msg $diff \" \n"
" puts stderr [clock format [clock seconds]]\n"
"}\n"
"\n"
"if [info exists env(X11VNC_GUI_TIME)] {\n"
" global started time_count\n"
" set started [exec gtod.bin]\n"
" set time_count 0\n"
" dtime \"S\"\n"
"}\n"
"\n"
"proc set_template {} {\n"
" global template\n"
" set template \"\n"
@ -1757,7 +1781,6 @@ char gui_code[] = "";
"\n"
"proc push_new_value {item name new {query 1}} {\n"
" global menu_var always_update remote_output query_output\n"
" global delay_sleep extra_sleep extra_sleep_split\n"
" global query_result_list\n"
"\n"
" set debug [in_debug_mode]\n"
@ -2996,7 +3019,6 @@ char gui_code[] = "";
"\n"
" set debug [in_debug_mode]\n"
"\n"
"\n"
" set string 0\n"
" if {[is_action $item] || $item == \"WindowView\"} {\n"
" # Menu item is action:\n"
@ -3420,9 +3442,9 @@ char gui_code[] = "";
" set count 0\n"
" foreach client [split $list \",\"] {\n"
" if {![regexp {^[a-z0-9]*[a-z0-9]:} $client]} {\n"
" append_text \"Skipping client line: \"\n"
" append_text $client\n"
" append_text \"\\n\"\n"
" #append_text \"Skipping client line: \"\n"
" #append_text $client\n"
" #append_text \"\\n\"\n"
" continue\n"
" }\n"
" regsub -all {[{}()~!$&*|;'\"`{}<>\\[\\]]} $client \"\" client\n"
@ -3989,9 +4011,15 @@ char gui_code[] = "";
" global have_labelframes ffont bfont\n"
" global props_buttons icon_noadvanced\n"
" global icon_mode icon_mode_at_startup\n"
" global screen_height screen_width\n"
"\n"
" check_update_vars\n"
"\n"
" set pady 1m\n"
" if {$screen_height <= 360} {\n"
" set pady 0m\n"
" }\n"
"\n"
" if [info exists menu_var(deny)] {\n"
" if {$menu_var(deny) == $unset_str || $menu_var(deny) == 0} {\n"
" set props_accept 1\n"
@ -4098,7 +4126,7 @@ char gui_code[] = "";
" pack $vp.l -fill x -expand 1 -padx 1m -pady 0m -side top\n"
" }\n"
" entry $vp.e -show \"*\" -textvariable props_viewpasswd -font $bfont\n"
" pack $vp.e -fill x -expand 1 -padx 1m -pady 1m -side top\n"
" pack $vp.e -fill x -expand 1 -padx 1m -pady $pady -side top\n"
"\n"
"\n"
" lappend props_buttons $vp.e\n"
@ -4113,7 +4141,7 @@ char gui_code[] = "";
" pack $pw.l -fill x -expand 1 -padx 1m -pady 0m -side top\n"
" }\n"
" entry $pw.e -show \"*\" -textvariable props_passwd -font $bfont\n"
" pack $pw.e -fill x -expand 1 -padx 1m -pady 1m -side top\n"
" pack $pw.e -fill x -expand 1 -padx 1m -pady $pady -side top\n"
"\n"
" if {! $icon_mode_at_startup} {\n"
" $vp.e configure -state disabled\n"
@ -4132,31 +4160,31 @@ char gui_code[] = "";
" frame $sh\n"
" checkbutton $sh.button -text \"Shared\" \\\n"
" -variable props_shared -anchor w -font $bfont\n"
" pack $sh.button -fill x -expand 1 -padx 1m -pady 1m\n"
" pack $sh.button -fill x -expand 1 -padx 1m -pady $pady\n"
"\n"
" set vo \"$w.viewonly\"\n"
" frame $vo\n"
" checkbutton $vo.button -text \"All Clients ViewOnly\" \\\n"
" -variable props_viewonly -anchor w -font $bfont\n"
" pack $vo.button -fill x -expand 1 -padx 1m -pady 1m\n"
" pack $vo.button -fill x -expand 1 -padx 1m -pady $pady\n"
"\n"
" set cf \"$w.confirm\"\n"
" frame $cf\n"
" checkbutton $cf.button -text \"Ask for Confirmation\" \\\n"
" -variable props_confirm -anchor w -font $bfont\n"
" pack $cf.button -fill x -expand 1 -padx 1m -pady 1m\n"
" pack $cf.button -fill x -expand 1 -padx 1m -pady $pady\n"
"\n"
" set ac \"$w.accept\"\n"
" frame $ac\n"
" checkbutton $ac.button -text \"Accept Connections\" \\\n"
" -variable props_accept -anchor w -font $bfont\n"
" pack $ac.button -fill x -expand 1 -padx 1m -pady 1m\n"
" pack $ac.button -fill x -expand 1 -padx 1m -pady $pady\n"
"\n"
" set px \"6m\"\n"
" pack $b1 -side bottom -fill x -pady 1m -padx $px\n"
" pack $b2 -side bottom -fill x -pady 1m -padx $px\n"
" pack $vp -side bottom -fill x -pady 1m -padx $px\n"
" pack $pw -side bottom -fill x -pady 1m -padx $px\n"
" pack $b1 -side bottom -fill x -pady $pady -padx $px\n"
" pack $b2 -side bottom -fill x -pady $pady -padx $px\n"
" pack $vp -side bottom -fill x -pady $pady -padx $px\n"
" pack $pw -side bottom -fill x -pady $pady -padx $px\n"
" pack $sh -side bottom -fill x -pady 0m -padx $px\n"
" pack $vo -side bottom -fill x -pady 0m -padx $px\n"
" pack $cf -side bottom -fill x -pady 0m -padx $px\n"
@ -4169,7 +4197,8 @@ char gui_code[] = "";
" set ms \"$w.msg\"\n"
" text $ms -font $ffont -relief ridge -width $tw -height $th\n"
" $ms insert 1.0 $msg\n"
" pack $ms -side bottom -fill x -pady 1m -padx $px\n"
" pack $ms -side bottom -fill x -pady $pady -padx $px\n"
" update\n"
" }\n"
"\n"
" lappend props_buttons $ac.button $cf.button $vo.button $sh.button\n"
@ -4357,7 +4386,10 @@ char gui_code[] = "";
" catch {file delete $x11vnc_client_file}\n"
" set read_client_info_lock 0\n"
" clean_icon_exit\n"
" } elseif {$str != \"skip\"} {\n"
" } elseif {$str == \"skip\"} {\n"
" ;\n"
" } elseif [regexp {^clients:} $str] {\n"
" regsub {^clients:} $str \"\" str\n"
" if {$str == \"none\"} {\n"
" set str \"\"\n"
" }\n"
@ -4498,6 +4530,7 @@ char gui_code[] = "";
" global x11vnc_xdisplay0 menu_var\n"
"\n"
" set db 0\n"
"#dtime t1\n"
" set start 13037\n"
" set tries 100\n"
" set socket_got_callback 0\n"
@ -4548,8 +4581,12 @@ char gui_code[] = "";
" append_text \"try_client_info_sock: server socket failed.\\n\"\n"
" return\n"
" }\n"
" run_remote_cmd [list \"-nosync\" \"-R\" \"noop\"]\n"
" after 500\n"
" if {! $x11vnc_started} {\n"
" run_remote_cmd [list \"-nosync\" \"-R\" \"noop\"]\n"
" if {$db} {dtime A}\n"
" after 250\n"
" if {$db} {dtime A}\n"
" }\n"
"\n"
" # set the cookie to some obscured randomness\n"
" set socket_cookie [clock clicks]\n"
@ -4568,8 +4605,18 @@ char gui_code[] = "";
" }\n"
" run_remote_cmd [list \"-nosync\" \"-R\" \\\n"
" \"client_info_sock:$myaddr:$port:$socket_cookie\"]\n"
"#dtime t2\n"
" if {$db} {puts \"client_info_sock:$myaddr:$port:$socket_cookie\"}\n"
" after 500\n"
" for {set i 0} {$i < 10} {incr i} {\n"
" after 50\n"
" update; update idletasks\n"
"#dtime aa\n"
" if {$socket_got_callback != 0} {\n"
"#puts \"break-\"\n"
" break\n"
" }\n"
" }\n"
"#dtime t3\n"
"\n"
" set aftid \"\"\n"
" if {$socket_got_callback == 0} {\n"
@ -4587,6 +4634,7 @@ char gui_code[] = "";
" } else {\n"
" setup_client_sock 1\n"
" }\n"
"#dtime t4\n"
"}\n"
"\n"
"proc set_icon_label {} {\n"
@ -5033,10 +5081,14 @@ char gui_code[] = "";
" global helptext helpremote helplabel\n"
" global icon_mode icon_win props_win full_win\n"
" global top_widget_names\n"
" global screen_height screen_width\n"
"\n"
"\n"
" # Make the top label\n"
" set label_width 80\n"
" if {$screen_width <= 400} {\n"
" set label_width 64\n"
" }\n"
" set info_label \"$top.info\"\n"
" label $info_label -textvariable info_str -bd 2 -relief groove \\\n"
" -anchor w -width $label_width -font $ffont\n"
@ -5135,8 +5187,14 @@ char gui_code[] = "";
" pack $df -side top -fill x\n"
"\n"
" # text area\n"
" global text_height\n"
" set text_area \"$top.text\"\n"
" text $text_area -height 12 -relief ridge -font $ffont\n"
" if {$screen_width <= 400} {\n"
" text $text_area -height $text_height -width $label_width \\\n"
" -relief ridge -font $ffont\n"
" } else {\n"
" text $text_area -height $text_height -relief ridge -font $ffont\n"
" }\n"
" pack $text_area -side top -fill both -expand 1\n"
" set top_widget_names(text) $text_area\n"
"\n"
@ -5705,6 +5763,24 @@ char gui_code[] = "";
" if {$db} {puts stderr \"run_remote_cmd_via_sock: \\\"$res\\\"\"}\n"
" set res [string trim $res]\n"
"\n"
" if [regexp {^clients:} $res] {\n"
" regsub {^clients:} $res \"\" tmp\n"
" if {$tmp == \"none\"} {\n"
" set tmp \"\"\n"
" }\n"
" update_clients_menu $tmp\n"
" set client_str $tmp\n"
" set_client_balloon $tmp\n"
"\n"
" if ![regexp {^clients} $opt] {\n"
" # we could block here...\n"
" if {$db} {puts stderr \"run_remote_cmd_via_sock: gets\"}\n"
" gets $client_sock res\n"
" if {$db} {puts stderr \"run_remote_cmd_via_sock: \\\"$res\\\"\"}\n"
" set res [string trim $res]\n"
" }\n"
" }\n"
"\n"
" set docmd \"\"\n"
"\n"
" if {$res != \"\"} {\n"
@ -5817,6 +5893,7 @@ char gui_code[] = "";
" global menu_var unset_str\n"
"\n"
" set db 0\n"
"#dtime c1\n"
"\n"
" if {! $connected_to_x11vnc} {\n"
" if {[info exists menu_var(display)]} {\n"
@ -5831,6 +5908,7 @@ char gui_code[] = "";
" set_info \"Pinging $x11vnc_xdisplay ...\"\n"
" set rargs [list \"-Q\" \"ping\"]\n"
" set result [run_remote_cmd $rargs]\n"
"#dtime c2a\n"
"\n"
" if {$db} {puts \"try_connect: \\\"$result\\\"\"}\n"
"\n"
@ -5842,10 +5920,12 @@ char gui_code[] = "";
" set_connected yes\n"
"\n"
" setup_client_channel\n"
"#dtime c2b\n"
" setup_client_sock 1\n"
" setup_client_tail\n"
"\n"
" fetch_displays\n"
"#dtime c3a\n"
" return 1\n"
" } else {\n"
" set str \"x11vnc server.\"\n"
@ -6018,6 +6098,10 @@ char gui_code[] = "";
"############################################################################\n"
"# main:\n"
"\n"
"if [info exists env(X11VNC_GUI_TIME)] {\n"
" dtime M\n"
"}\n"
"\n"
"wm withdraw .\n"
"\n"
"global env x11vnc_prog x11vnc_cmdline x11vnc_xdisplay x11vnc_connect;\n"
@ -6028,10 +6112,10 @@ char gui_code[] = "";
"global helpall helptext helpremote helplabel hostname osname\n"
"global all_settings reply_xdisplay always_update\n"
"global max_text_height max_text_width\n"
"global text_height\n"
"global menu_var unset_str menus_disabled\n"
"global bfont ffont sfont snfont old_labels have_labelframes\n"
"global connected_to_x11vnc\n"
"global delay_sleep extra_sleep extra_sleep_split\n"
"global cache_all_query_vars\n"
"global last_query_all_time query_all_freq client_tail client_sock client_info_read\n"
"global icon_mode icon_mode_at_startup\n"
@ -6039,6 +6123,7 @@ char gui_code[] = "";
"global icon_noadvanced icon_minimal\n"
"global make_gui_count text_area_str\n"
"global gui_argv0 gui_start_mode\n"
"global screen_height screen_width\n"
"\n"
"set unset_str \"(unset)\"\n"
"set vnc_url $unset_str\n"
@ -6046,6 +6131,7 @@ char gui_code[] = "";
"set menus_disabled 0\n"
"set max_text_height 40\n"
"set max_text_width 90\n"
"set text_height 14\n"
"set bfont \"-adobe-helvetica-bold-r-*-*-*-120-*-*-*-*-*-*\"\n"
"set sfont \"-adobe-helvetica-bold-r-*-*-*-100-*-*-*-*-*-*\"\n"
"set snfont \"-adobe-helvetica-medium-r-*-*-*-100-*-*-*-*-*-*\"\n"
@ -6065,11 +6151,6 @@ char gui_code[] = "";
"set gui_argv0 $argv0\n"
"set gui_start_mode \"\"\n"
"\n"
"# these are no longer used under x11vnc -sync:\n"
"set delay_sleep 350\n"
"set extra_sleep 1000\n"
"set extra_sleep_split 4\n"
"\n"
"if {$tk_version < 8.0} {\n"
" puts stderr \"\"\n"
" puts stderr \"*** tkx11vnc: tk version is old $tk_version, please use 8.0 or higher.\"\n"
@ -6086,6 +6167,19 @@ char gui_code[] = "";
" set have_labelframes 0\n"
"}\n"
"\n"
"set screen_height [winfo screenheight .]\n"
"set screen_width [winfo screenwidth .]\n"
"if {$screen_height < 500} {\n"
" # short screen, PDA?\n"
" set max_text_height 22\n"
" set text_height 13\n"
" if {$screen_height <= 360} {\n"
" # very short.\n"
" set max_text_height 16\n"
" set max_text_width 60\n"
" set text_height 11\n"
" }\n"
"}\n"
"if {[info exists env(X11VNC_GUI_TEXT_HEIGHT)]} {\n"
" set max_text_height $env(X11VNC_GUI_TEXT_HEIGHT)\n"
"}\n"
@ -6141,7 +6235,7 @@ char gui_code[] = "";
" if {$client_tail != \"\"} {\n"
" gets $client_tail tmp\n"
" if [eof $client_tail] {\n"
"puts \"eof $client_tail\"\n"
"#puts \"eof $client_tail\"\n"
" clean_client_tail\n"
" set client_tail \"\"\n"
" }\n"
@ -6310,27 +6404,31 @@ char gui_code[] = "";
"\n"
"get_default_vars\n"
"\n"
"dtime D\n"
"\n"
"if {$icon_mode} {\n"
" if {$tray_embed} {\n"
" make_gui \"tray\"\n"
" } else {\n"
" make_gui \"icon\"\n"
" }\n"
" dtime G\n"
" old_balloon\n"
" if {$icon_setpasswd} {\n"
" set m \"You must specify a Session\\n\" \n"
" set m \"${m}Password before VNC clients can\\n\" \n"
" set m \"${m}connect. Enter one in the Password\\n\" \n"
" set m \"${m}field and then Press \\\"OK\\\". This\\n\" \n"
" set m \"${m}password is not stored, it is only\\n\" \n"
" set m \"${m}used for this x11vnc session.\\n\" \n"
" set m \"You must specify a Session Password\\n\" \n"
" set m \"${m}before VNC clients can connect.\\n\" \n"
" set m \"${m}Enter one in the Password field\\n\" \n"
" set m \"${m}and Press \\\"OK\\\". The password(s) is\\n\" \n"
" set m \"${m}only for this x11vnc session.\\n\" \n"
" do_props $m\n"
" push_new_value \"unlock\" \"unlock\" 1 0\n"
" #push_new_value \"unlock\" \"unlock\" 1 0\n"
" }\n"
"} else {\n"
" make_gui \"full\"\n"
" dtime G\n"
"}\n"
"\n"
"\n"
"# main loop.\n"
#endif
/* ifdef NOGUI */

@ -54,6 +54,7 @@ static void set_db(void);
static void unixpw_verify(char *user, char *pass);
int unixpw_in_progress = 0;
int unixpw_login_viewonly = 0;
time_t unixpw_last_try_time = 0;
rfbClientPtr unixpw_client = NULL;
@ -975,6 +976,9 @@ static void apply_opts (char *user) {
void unixpw_accept(char *user) {
apply_opts(user);
if (unixpw_login_viewonly) {
unixpw_client->viewOnly = TRUE;
}
unixpw_in_progress = 0;
unixpw_client = NULL;
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);

@ -11,6 +11,7 @@ extern int su_verify(char *user, char *pass);
extern int crypt_verify(char *user, char *pass);
extern int unixpw_in_progress;
extern int unixpw_login_viewonly;
extern time_t unixpw_last_try_time;
extern rfbClientPtr unixpw_client;

@ -2,7 +2,7 @@
.TH X11VNC "1" "March 2006" "x11vnc " "User Commands"
.SH NAME
x11vnc - allow VNC connections to real X11 displays
version: 0.8.1, lastmod: 2006-03-04
version: 0.8.1, lastmod: 2006-03-06
.SH SYNOPSIS
.B x11vnc
[OPTION]...
@ -391,8 +391,9 @@ set to "host" or "host:port" establish a reverse
connection. Using
.IR xprop (1)
instead of vncconnect may
work (see the FAQ). The \fB-remote\fR control mechanism also
uses this VNC_CONNECT channel. Default: \fB-vncconnect\fR
work (see the FAQ). The \fB-remote\fR control mechanism uses
X11VNC_REMOTE channel, and this option disables/enables
it as well. Default: \fB-vncconnect\fR
.PP
\fB-allow\fR \fIhost1[,host2..]\fR
.IP
@ -530,8 +531,8 @@ this case. A possible workaround would be to start
x11vnc as root with the "\fB-users\fR \fI+nobody\fR" option to
immediately switch to user nobody. Another source of
problems are PAM modules that prompt for extra info,
e.g. password aging modules. These logins will always
fail as well.
e.g. password aging modules. These logins will fail
as well even when the correct password is supplied.
.IP
*IMPORTANT*: to prevent the Unix password being sent in
*clear text* over the network, two x11vnc options are
@ -564,17 +565,28 @@ will check if the environment variable SSH_CONNECTION
is set and appears reasonable. If it does, then the
stunnel requirement is dropped since it is assumed
you are using ssh for the encrypted tunnelling.
Use \fB-stunnel\fR to force stunnel usage.
Use \fB-stunnel\fR to force stunnel usage for this case.
.IP
Set UNIXPW_DISABLE_LOCALHOST=1 to disable the \fB-localhost\fR
requirement. One should never do this (i.e. allow the
Unix passwords to be sniffed on the network).
.IP
NOTE: in \fB-inetd\fR mode the two settings are not enforced
since x11vnc does not make network connections in
that case. Be sure to use encryption from the viewer
to inetd. One can also have your own stunnel spawn
x11vnc in \fB-inetd\fR mode. See the FAQ.
Regarding reverse connections (e.g. \fB-R\fR connect:host),
the \fB-localhost\fR constraint is in effect and the reverse
connections can only be used to connect to the same
machine x11vnc is running on (default port 5500).
Please use a ssh or stunnel port redirection to the
viewer machine to tunnel the reverse connection over
an encrypted channel. Note that Unix username and
password *will* be prompted for (unlike VNC passwords
that are skipped for reverse connections).
.IP
NOTE: in \fB-inetd\fR mode the two settings are attempted
to be enforced for reverse connections. Be sure to
use encryption from the viewer to inetd since x11vnc
cannot guess easily if it is encrpyted. Note: you can
also have your own stunnel spawn x11vnc in \fB-inetd\fR mode
(i.e. bypassing inetd). See the FAQ.
.IP
The user names in the comma separated [list] can have
per-user options after a ":", e.g. "fred:opts"
@ -588,21 +600,30 @@ options apply to all users. It also means all users
are allowed to log in after supplying a valid password.
Use "deny" to explicitly deny some users if you use
"*" to set a global option.
.IP
There are also some tools for testing password if [list]
starts with the "%" character. See the quick_pw()
function for details.
.PP
\fB-unixpw_nis\fR \fI[list]\fR
.IP
As \fB-unixpw\fR above, however do not run
As \fB-unixpw\fR above, however do not use
.IR su (1)
but rather
use the traditional getpwnam() + crypt() method instead.
This requires that the encrpyted passwords be readable.
Passwords stored in /etc/shadow will be inaccessible
unless run as root. This is called "NIS" mode
simply because in most NIS setups the user encrypted
passwords are accessible (e.g. "ypcat passwd").
NIS is not required for this mode to work, but it
is unlikely it will work for any other environment.
All of the \fB-unixpw\fR options and contraints apply.
use the traditional
.IR getpwnam (3)
+
.IR crypt (3)
method
instead. This requires that the encrpyted passwords
be readable. Passwords stored in /etc/shadow will
be inaccessible unless run as root. This is called
"NIS" mode simply because in most NIS setups the
user encrypted passwords are accessible (e.g. "ypcat
passwd"). NIS is not required for this mode to
work, but it is unlikely it will work for any other
environment. All of the \fB-unixpw\fR options and contraints
apply.
.PP
\fB-stunnel\fR \fI[pem]\fR
.IP
@ -2163,7 +2184,7 @@ command exits. You can often use the \fB-query\fR command
\fB-remote\fR command.
.IP
The default communication channel is that of X
properties (specifically VNC_CONNECT), and so this
properties (specifically X11VNC_REMOTE), and so this
command must be run with correct settings for DISPLAY
and possibly XAUTHORITY to connect to the X server
and set the property. Alternatively, use the \fB-display\fR
@ -2655,9 +2676,9 @@ to the standard output. If a variable is read-only,
it comes back with prefix "aro=" instead of "ans=".
.IP
Some \fB-remote\fR commands are pure actions that do not make
sense as variables, e.g. "stop" or "disconnect",
in these cases the value returned is "N/A". To direct
a query straight to the VNC_CONNECT property or connect
sense as variables, e.g. "stop" or "disconnect", in
these cases the value returned is "N/A". To direct a
query straight to the X11VNC_REMOTE property or connect
file use "qry=..." instead of "cmd=..."
.IP
Here is the current list of "variables" that can
@ -2762,9 +2783,9 @@ Default: \fB-yesremote\fR
.IP
A note about security wrt remote control commands.
If someone can connect to the X display and change
the property VNC_CONNECT, then they can remotely
the property X11VNC_REMOTE, then they can remotely
control x11vnc. Normally access to the X display is
protected. Note that if they can modify VNC_CONNECT
protected. Note that if they can modify X11VNC_REMOTE
on the X server, they have enough permissions to also
run their own x11vnc and thus have complete control
of the desktop. If the "\fB-connect\fR \fI/path/to/file\fR"
@ -2774,9 +2795,9 @@ sure to protect the X display and that file's write
permissions. See \fB-privremote\fR below.
.IP
If you are paranoid and do not think \fB-noremote\fR is
enough, to disable the VNC_CONNECT property channel
completely use \fB-novncconnect,\fR or use the \fB-safer\fR
option that shuts many things off.
enough, to disable the X11VNC_REMOTE property channel
completely use \fB-novncconnect,\fR or use the \fB-safer\fR option
that shuts many things off.
.PP
\fB-unsafe\fR
.IP

@ -139,6 +139,7 @@
#include "rates.h"
#include "unixpw.h"
#include "inet.h"
#include "sslcmds.h"
/*
* main routine for the x11vnc program
@ -920,6 +921,8 @@ static void quick_pw(char *str) {
*
* starting "%/" or "%." means read the first line from that file.
*
* "%%" or "%" means prompt user.
*
* otherwise: %user:pass
*/
if (!strcmp(str, "%-") || !strcmp(str, "%stdin")) {
@ -932,6 +935,31 @@ static void quick_pw(char *str) {
exit(1);
}
q = strdup(getenv("UNIXPW"));
} else if (!strcmp(str, "%%") || !strcmp(str, "%")) {
char *t, inp[1024];
fprintf(stdout, "username: ");
if(fgets(tmp, 128, stdin) == NULL) {
exit(1);
}
strcpy(inp, tmp);
t = strchr(inp, '\n');
if (t) {
*t = ':';
} else {
strcat(inp, ":");
}
fprintf(stdout, "password: ");
system("stty -echo");
if(fgets(tmp, 128, stdin) == NULL) {
fprintf(stdout, "\n");
system("stty echo");
exit(1);
}
system("stty echo");
fprintf(stdout, "\n");
strcat(inp, tmp);
q = strdup(inp);
} else if (str[1] == '/' || str[1] == '.') {
FILE *in = fopen(str+1, "r");
if (in == NULL) {
@ -1235,6 +1263,10 @@ static void check_loop_mode(int argc, char* argv[]) {
}
}
#define SHOW_NO_PASSWORD_WARNING \
(!got_passwd && !got_rfbauth && (!got_passwdfile || !passwd_list) \
&& !query_cmd && !remote_cmd && !unixpw && !got_gui_pw)
int main(int argc, char* argv[]) {
int i, len, tmpi;
@ -1244,6 +1276,7 @@ int main(int argc, char* argv[]) {
char *remote_cmd = NULL;
char *query_cmd = NULL;
char *gui_str = NULL;
int got_gui_pw = 0;
int pw_loc = -1, got_passwd = 0, got_rfbauth = 0, nopw = NOPW;
int got_viewpasswd = 0, got_localhost = 0, got_passwdfile = 0;
int got_stunnel = 0;
@ -1448,7 +1481,7 @@ int main(int argc, char* argv[]) {
unixpw_nis = 1;
}
if (i < argc-1) {
char *p, *q, *s = argv[i+1];
char *s = argv[i+1];
if (s[0] != '-') {
unixpw_list = strdup(s);
i++;
@ -1875,6 +1908,9 @@ int main(int argc, char* argv[]) {
char *s = argv[i+1];
if (*s != '-') {
gui_str = strdup(s);
if (strstr(gui_str, "setp")) {
got_gui_pw = 1;
}
i++;
}
}
@ -2005,8 +2041,8 @@ int main(int argc, char* argv[]) {
}
if (launch_gui) {
int sleep = 0;
if (!got_passwd && !got_rfbauth && !got_passwdfile && !nopw) {
sleep = 3;
if (SHOW_NO_PASSWORD_WARNING && !nopw) {
sleep = 2;
}
do_gui(gui_str, sleep);
}
@ -2132,8 +2168,7 @@ int main(int argc, char* argv[]) {
exit(1);
}
if (!got_passwd && !got_rfbauth && (!got_passwdfile || !passwd_list)
&& !query_cmd && !remote_cmd && !unixpw) {
if (SHOW_NO_PASSWORD_WARNING) {
char message[] = "-rfbauth, -passwdfile, -passwd password, "
"or -unixpw required.";
if (! nopw) {
@ -2834,8 +2869,7 @@ int main(int argc, char* argv[]) {
}
if (! quiet) {
rfbLog("screen setup finished.\n");
if (!got_passwd && !got_rfbauth && !got_passwdfile && !unixpw
&& !nopw) {
if (SHOW_NO_PASSWORD_WARNING && !nopw) {
rfbLog("\n");
rfbLog("WARNING: You are running x11vnc WITHOUT"
" a password. See\n");

@ -15,7 +15,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.8.1 lastmod: 2006-03-04";
char lastmod[] = "0.8.1 lastmod: 2006-03-06";
/* X display info */

@ -18,6 +18,7 @@ int grab_buster = 0;
int sync_tod_delay = 3;
void initialize_vnc_connect_prop(void);
void initialize_x11vnc_remote_prop(void);
void spawn_grab_buster(void);
void sync_tod_with_servertime(void);
void check_keycode_state(void);
@ -39,10 +40,16 @@ void initialize_vnc_connect_prop(void) {
vnc_connect_prop = XInternAtom(dpy, "VNC_CONNECT", False);
}
void initialize_x11vnc_remote_prop(void) {
x11vnc_remote_str[0] = '\0';
x11vnc_remote_prop = XInternAtom(dpy, "X11VNC_REMOTE", False);
}
static void initialize_xevents(void) {
static int did_xselect_input = 0;
static int did_xcreate_simple_window = 0;
static int did_vnc_connect_prop = 0;
static int did_x11vnc_remote_prop = 0;
static int did_xfixes = 0;
static int did_xdamage = 0;
static int did_xrandr = 0;
@ -75,6 +82,14 @@ static void initialize_xevents(void) {
initialize_vnc_connect_prop();
did_vnc_connect_prop = 1;
}
if (vnc_connect && !did_x11vnc_remote_prop) {
initialize_x11vnc_remote_prop();
did_x11vnc_remote_prop = 1;
}
if (run_gui_pid > 0) {
kill(run_gui_pid, SIGUSR1);
run_gui_pid = 0;
}
if (xfixes_present && use_xfixes && !did_xfixes) {
initialize_xfixes();
did_xfixes = 1;
@ -744,11 +759,16 @@ void check_xevents(void) {
set_cutbuffer = 0;
} else if (vnc_connect && vnc_connect_prop != None
&& xev.xproperty.atom == vnc_connect_prop) {
/*
* Go retrieve VNC_CONNECT string.
*/
read_vnc_connect_prop();
read_vnc_connect_prop(0);
} else if (vnc_connect && x11vnc_remote_prop != None
&& xev.xproperty.atom == x11vnc_remote_prop) {
/*
* Go retrieve X11VNC_REMOTE string.
*/
read_x11vnc_remote_prop(0);
}
}
}

@ -7,6 +7,7 @@ extern int grab_buster;
extern int sync_tod_delay;
extern void initialize_vnc_connect_prop(void);
extern void initialize_x11vnc_remote_prop(void);
extern void spawn_grab_buster(void);
extern void sync_tod_with_servertime(void);
extern void check_keycode_state(void);

Loading…
Cancel
Save