x11vnc: --grabkbd, -grabptr, -env, -allowedcmds, unixpw+WAIT user fred:options

pull/1/head
runge 19 years ago
parent 363ae71df0
commit 64e731a9da

@ -65,7 +65,7 @@ static unsigned int root_rgb[NCOLOR];
static void set_root_cmap(void) {
static time_t last_set = 0;
time_t now = time(0);
time_t now = time(NULL);
XWindowAttributes attr;
static XColor color[NCOLOR];
int redo = 0;

@ -1,3 +1,8 @@
2006-06-18 Karl Runge <runge@karlrunge.com>
* x11vnc: -grabkbd, -grabptr, -env options. under -unixpw +
WAIT let user add some options after his username (e.g. runge:3/4)
-allowedcmds to fine tune vs. -nocmds. general cleanup.
2006-06-12 Karl Runge <runge@karlrunge.com>
* x11vnc: word tune SSL Java viewer; fix multi-certs bug. Add
-display WAIT:cmd=FINDDISPLAY builtin script and cmd=HTTPONCE

@ -1,5 +1,5 @@
x11vnc README file Date: Mon Jun 12 22:23:23 EDT 2006
x11vnc README file Date: Sun Jun 18 19:37:38 EDT 2006
The following information is taken from these URLs:
@ -7192,7 +7192,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.2 lastmod: 2006-06-12
x11vnc: allow VNC connections to real X11 displays. 0.8.2 lastmod: 2006-06-18
x11vnc options:
-display disp -auth file -id windowid
@ -7205,19 +7205,20 @@ x11vnc options:
-inetd -nofilexfer -http
-http_ssl -connect string -vncconnect
-novncconnect -allow host1[,host2..] -localhost
-nolookup -input string -viewpasswd string
-passwdfile filename -unixpw [list] -unixpw_nis [list]
-display WAIT:... -ssl [pem] -ssldir [dir]
-sslverify [path] -sslGenCA [dir] -sslGenCert type name
-sslEncKey [pem] -sslCertInfo [pem] -sslDelCert [pem]
-stunnel [pem] -stunnel3 [pem] -https [port]
-usepw -storepasswd pass file -nopw
-accept string -afteraccept string -gone string
-users list -noshm -flipbyteorder
-onetile -solid [color] -blackout string
-xinerama -noxinerama -xtrap
-xrandr [mode] -padgeom WxH -o logfile
-flag file -rc filename -norc
-nolookup -input string -grabkbd
-grabptr -viewpasswd string -passwdfile filename
-unixpw [list] -unixpw_nis [list] -display WAIT:...
-ssl [pem] -ssldir [dir] -sslverify [path]
-sslGenCA [dir] -sslGenCert type name -sslEncKey [pem]
-sslCertInfo [pem] -sslDelCert [pem] -stunnel [pem]
-stunnel3 [pem] -https [port] -usepw
-storepasswd pass file -nopw -accept string
-afteraccept string -gone string -users list
-noshm -flipbyteorder -onetile
-solid [color] -blackout string -xinerama
-noxinerama -xtrap -xrandr [mode]
-padgeom WxH -o logfile -flag file
-rc filename -norc -env VAR=VALUE
-h, -help -?, -opts -V, -version
-dbg -q -bg
-modtweak -nomodtweak -xkb
@ -7254,7 +7255,8 @@ x11vnc options:
-remote command -query variable -QD variable
-sync -noremote -yesremote
-unsafe -safer -privremote
-nocmds -deny_all
-nocmds -allowedcmds list -deny_all
libvncserver options:
-rfbport port TCP port for RFB protocol
@ -7288,7 +7290,7 @@ libvncserver-tight-extension options:
% x11vnc -help
x11vnc: allow VNC connections to real X11 displays. 0.8.2 lastmod: 2006-06-12
x11vnc: allow VNC connections to real X11 displays. 0.8.2 lastmod: 2006-06-18
(type "x11vnc -opts" to just list the options.)
@ -7576,6 +7578,7 @@ Options:
option, otherwise the stderr goes to the viewer which
will cause it to abort. Specifying both -inetd and -q
and no -o will automatically close the stderr.
-nofilexfer Disable the TightVNC file transfer extension. (same as
-disablefiletransfer). Note that when the -viewonly
option is supplied all file transfers are disabled.
@ -7583,6 +7586,7 @@ Options:
However, if the remote control mechanism is used to
change the global or per-client viewonly state the
filetransfer permissions will NOT change.
-http Instead of using -httpdir (see below) to specify
where the Java vncviewer applet is, have x11vnc try
to *guess* where the directory is by looking relative
@ -7659,6 +7663,23 @@ Options:
a global -viewonly is in effect (all input is discarded
in that case).
-grabkbd When VNC viewers are connected, attempt to the grab the
keyboard so someone sitting at the physical display
is not able to enter keystrokes. This method uses
XGrabKeyboard(3X11) and so it is not secure and does not
rule out the person at the physical display injecting
keystrokes by flooding the server with them, grabbing
the keyboard himself, etc. Some degree of cooperation
from the person at the display is assumed.
-grabptr As -grabkbd, but for the mouse pointer using
XGrabPointer(3X11). Unfortunately due to the way the X
server works, the mouse can still be moved around by the
user at the physical display, but he will not be able to
change window focus with it. Also some window managers
that call XGrabServer(3X11) for resizes, etc, will
act on the local user's input. Again, some degree of
cooperation from the person at the display is assumed.
-viewpasswd string Supply a 2nd password for view-only logins. The -passwd
(full-access) password must also be supplied.
@ -7857,7 +7878,25 @@ Options:
as the user who just authenticated via the login and
password prompt.
Thus the combination of -display WAIT:cmd=... and
Also in the case of -unixpw, the user logging in can
place a colon at the end of his username and supply
a few options: scale=, scale_cursor=, solid, id=,
clear_mods, clear_keys, repeat, or speeds= separated
by commas if there is more than one. After the user
logs in successfully, these options will be applied to
the VNC screen. For example,
login: fred:scale=3/4,repeat
Password: ...
for convenience m/n implies scale= e.g. fred:3/4
To disable this set the environment variable
X11VNC_NO_UNIXPW_OPTS=1. To set any other options,
the user can use the gui (x11vnc -gui connect) or the
remote control method (x11vnc -R opt:val) during his
VNC session.
So the combination of -display WAIT:cmd=... and
-unixpw allows automatic pairing of an unix
authenticated VNC user with his desktop. This could
be very useful on SunRays and also any system where
@ -7890,7 +7929,7 @@ Options:
5815 stream tcp nowait root /usr/sbin/tcpd .../x11vnc \
-inetd -q -http_ssl -display WAIT:cmd=HTTPONCE
Is used in the Apache SSL-portal example (see FAQ).
It is used in the Apache SSL-portal example (see FAQ).
Finally, one can insert a geometry between colons,
e.g. WAIT:1280x1024:... to set the size of the display
@ -8672,6 +8711,12 @@ Options:
-rc filename Use "filename" instead of $HOME/.x11vncrc for rc file.
-norc Do not process any .x11vncrc file for options.
-env VAR=VALUE Set the environment variable 'VAR' to value 'VALUE'
at x11vnc startup. This is a convenience utility to
avoid shell script wrappers, etc. to set the env. var.
You may specify as many of these as needed on the
command line.
-h, -help Print this help text.
-?, -opts Only list the x11vnc options.
-V, -version Print program version and last modification date.
@ -9974,6 +10019,10 @@ n
nolookup enable -nolookup mode.
lookup disable -nolookup mode.
input:str set -input to "str", empty to disable.
grabkbd enable -grabkbd mode.
nograbkbd disable -grabkbd mode.
grabptr enable -grabptr mode.
nograbptr disable -grabptr mode.
client_input:str set the K, M, B -input on a per-client
basis. select which client as for
disconnect, e.g. client_input:host:MB
@ -10230,13 +10279,14 @@ n
scr_skip scr_inc scr_keys scr_term scr_keyrepeat
scr_parms scrollcopyrect scr noscrollcopyrect noscr
fixscreen noxrecord xrecord reset_record pointer_mode
pm input_skip input client_input speeds wmdt
debug_pointer dp nodebug_pointer nodp debug_keyboard
dk nodebug_keyboard nodk deferupdate defer wait_ui
wait_bog nowait_bog slow_fb wait readtimeout nap nonap
sb screen_blank fbpm nofbpm fs gaps grow fuzz snapfb
nosnapfb rawfb progressive rfbport http nohttp httpport
httpdir enablehttpproxy noenablehttpproxy alwaysshared
pm input_skip input grabkbd nograbkbd grabptr
nograbptr client_input speeds wmdt debug_pointer dp
nodebug_pointer nodp debug_keyboard dk nodebug_keyboard
nodk deferupdate defer wait_ui wait_bog nowait_bog
slow_fb wait readtimeout nap nonap sb screen_blank
fbpm nofbpm fs gaps grow fuzz snapfb nosnapfb rawfb
progressive rfbport http nohttp httpport httpdir
enablehttpproxy noenablehttpproxy alwaysshared
noalwaysshared nevershared noalwaysshared dontdisconnect
nodontdisconnect desktop debug_xevents nodebug_xevents
debug_xevents debug_xdamage nodebug_xdamage
@ -10323,6 +10373,17 @@ n
remote-control is disabled it cannot be turned back on.
-nocmds No external commands (e.g. system(3), popen(3), exec(3))
will be run.
-allowedcmds list "list" contains a comma separated list of the only
external commands that can be run. The full list of
associated options is:
stunnel, ssl, unixpw, WAIT, id, accept, afteraccept,
gone, pipeinput, v4l-info, rawfb-setup, dt, gui,
storepasswd, crash.
See each option's help to learn the associated external
command. Note that the -nocmds option takes precedence
and disables all external commands.
-deny_all For use with -remote nodeny: start out denying all
incoming clients until "-remote nodeny" is used to

@ -312,7 +312,7 @@ static void crash_shell(void) {
} else if (*str == 's' && *(str+1) == '\0') {
sprintf(cmd, "sh -c '(%s) &'", crash_stack_command1);
/* crash */
if (no_external_cmds) {
if (no_external_cmds || !cmd_ok("crash")) {
fprintf(stderr, "\nno_external_cmds=%d\n",
no_external_cmds);
goto crash_prompt;

@ -14,6 +14,7 @@
#include "sslcmds.h"
#include "sslhelper.h"
#include "xwrappers.h"
#include "xevents.h"
/*
* routines for handling incoming, outgoing, etc connections
@ -44,6 +45,7 @@ void check_gui_inputs(void);
enum rfbNewClientAction new_client(rfbClientPtr client);
void start_client_info_sock(char *host_port_cookie);
void send_client_info(char *str);
void adjust_grabs(int grab, int quiet);
void check_new_clients(void);
@ -328,6 +330,32 @@ void set_child_info(void) {
}
}
int cmd_ok(char *cmd) {
char *p, *str;
if (no_external_cmds) {
return 0;
}
if (! cmd || cmd[0] == '\0') {
return 0;
}
if (! allowed_external_cmds) {
/* default, allow any (overridden by -nocmds) */
return 1;
}
str = strdup(allowed_external_cmds);
p = strtok(str, ",");
while (p) {
if (!strcmp(p, cmd)) {
free(str);
return 1;
}
p = strtok(NULL, ",");
}
free(str);
return 0;
}
/*
* utility to run a user supplied command setting some RFB_ env vars.
* used by, e.g., accept_client() and client_gone()
@ -336,7 +364,7 @@ static int run_user_command(char *cmd, rfbClientPtr client, char *mode) {
char *old_display = NULL;
char *addr = client->host;
char str[100];
int rc;
int rc, ok;
ClientData *cd = (ClientData *) client->clientData;
if (addr == NULL || addr[0] == '\0') {
@ -414,11 +442,11 @@ static int run_user_command(char *cmd, rfbClientPtr client, char *mode) {
if (cd) {
sprintf(str, "%d", (int) cd->login_time);
} else {
sprintf(str, ">%d", (int) time(0));
sprintf(str, ">%d", (int) time(NULL));
}
set_env("RFB_LOGIN_TIME", str);
sprintf(str, "%d", (int) time(0));
sprintf(str, "%d", (int) time(NULL));
set_env("RFB_CURRENT_TIME", str);
if (!cd || !cd->username || cd->username[0] == '\0') {
@ -449,7 +477,17 @@ static int run_user_command(char *cmd, rfbClientPtr client, char *mode) {
set_env("RFB_CLIENT_COUNT", str);
/* gone, accept, afteraccept */
if (no_external_cmds) {
ok = 0;
if (!strcmp(mode, "accept") && cmd_ok("accept")) {
ok = 1;
}
if (!strcmp(mode, "afteraccept") && cmd_ok("afteraccept")) {
ok = 1;
}
if (!strcmp(mode, "gone") && cmd_ok("gone")) {
ok = 1;
}
if (no_external_cmds || !ok) {
rfbLogEnable(1);
rfbLog("cannot run external commands in -nocmds mode:\n");
rfbLog(" \"%s\"\n", cmd);
@ -1398,7 +1436,7 @@ static void check_connect_file(char *file) {
char line[VNC_CONNECT_MAX], host[VNC_CONNECT_MAX];
static int first_warn = 1, truncate_ok = 1;
static time_t last_time = 0;
time_t now = time(0);
time_t now = time(NULL);
if (last_time == 0) {
last_time = now;
@ -1846,7 +1884,7 @@ void check_gui_inputs(void) {
enum rfbNewClientAction new_client(rfbClientPtr client) {
ClientData *cd;
last_event = last_input = time(0);
last_event = last_input = time(NULL);
if (inetd) {
@ -1902,7 +1940,7 @@ if (getenv("NEW_CLIENT")) fprintf(stderr, "new_client: %s %d\n", client->host, c
cd->input[0] = '-';
cd->login_viewonly = -1;
cd->login_time = time(0);
cd->login_time = time(NULL);
cd->ssl_helper_pid = 0;
if (use_openssl && openssl_last_helper_pid) {
@ -1933,7 +1971,7 @@ if (0) fprintf(stderr, "SET ssl_helper_pid: %d\n", openssl_last_helper_pid);
}
client_count++;
last_keyboard_input = last_pointer_input = time(0);
last_keyboard_input = last_pointer_input = time(NULL);
if (no_autorepeat && client_count == 1 && ! view_only) {
/*
@ -1958,7 +1996,7 @@ if (0) fprintf(stderr, "SET ssl_helper_pid: %d\n", openssl_last_helper_pid);
cd->raw_bytes_sent = 0;
accepted_client = 1;
last_client = time(0);
last_client = time(NULL);
if (unixpw) {
unixpw_in_progress = 1;
@ -1968,7 +2006,7 @@ if (0) fprintf(stderr, "SET ssl_helper_pid: %d\n", openssl_last_helper_pid);
unixpw_login_viewonly = 1;
client->viewOnly = FALSE;
}
unixpw_last_try_time = time(0);
unixpw_last_try_time = time(NULL);
unixpw_screen(1);
unixpw_keystroke(0, 0, 1);
}
@ -2027,7 +2065,7 @@ void start_client_info_sock(char *host_port_cookie) {
if (sock >= 0) {
char *lst = list_clients();
icon_mode_socks[next] = sock;
start_time[next] = time(0);
start_time[next] = time(NULL);
write(sock, "COOKIE:", strlen("COOKIE:"));
write(sock, cookie, strlen(cookie));
write(sock, "\n", strlen("\n"));
@ -2105,6 +2143,40 @@ void send_client_info(char *str) {
}
}
void adjust_grabs(int grab, int quiet) {
RAWFB_RET_VOID
/* n.b. caller decides to X_LOCK or not. */
if (grab) {
if (grab_kbd) {
if (! quiet) {
rfbLog("grabbing keyboard with XGrabKeyboard\n");
}
XGrabKeyboard(dpy, window, False, GrabModeAsync,
GrabModeAsync, CurrentTime);
}
if (grab_ptr) {
if (! quiet) {
rfbLog("grabbing pointer with XGrabPointer\n");
}
XGrabPointer(dpy, window, False, 0, GrabModeAsync,
GrabModeAsync, None, None, CurrentTime);
}
} else {
if (grab_kbd) {
if (! quiet) {
rfbLog("ungrabbing keyboard with XUngrabKeyboard\n");
}
XUngrabKeyboard(dpy, CurrentTime);
}
if (grab_ptr) {
if (! quiet) {
rfbLog("ungrabbing pointer with XUngrabPointer\n");
}
XUngrabPointer(dpy, CurrentTime);
}
}
}
void check_new_clients(void) {
static int last_count = 0;
rfbClientIteratorPtr iter;
@ -2117,12 +2189,27 @@ void check_new_clients(void) {
unixpw_login_viewonly = 1;
unixpw_client->viewOnly = FALSE;
}
if (time(0) > unixpw_last_try_time + 25) {
if (time(NULL) > unixpw_last_try_time + 25) {
rfbLog("unixpw_deny: timed out waiting for reply.\n");
unixpw_deny();
}
return;
}
if (grab_kbd || grab_ptr) {
static double last_force = 0.0;
if (client_count != last_count || dnow() > last_force + 0.25) {
int q = (client_count == last_count);
last_force = dnow();
X_LOCK;
if (client_count) {
adjust_grabs(1, q);
} else {
adjust_grabs(0, q);
}
X_UNLOCK;
}
}
if (client_count == last_count) {
return;
@ -2143,6 +2230,7 @@ void check_new_clients(void) {
if (! screen) {
return;
}
if (! client_count) {
send_client_info("clients:none");
return;

@ -28,6 +28,7 @@ extern void check_gui_inputs(void);
extern enum rfbNewClientAction new_client(rfbClientPtr client);
extern void start_client_info_sock(char *host_port_cookie);
extern void send_client_info(char *str);
extern void adjust_grabs(int grab, int quiet);
extern void check_new_clients(void);
#endif /* _X11VNC_CONNECTIONS_H */

@ -1262,7 +1262,7 @@ static int get_xfixes_cursor(int init) {
oldest++;
}
oldtime = curs_times[oldest];
now = time(0);
now = time(NULL);
for (i = CURS_DYN_MIN; i <= CURS_DYN_MAX; i++) {
if (screen && screen->cursor == cursors[i]->rfb) {
;

@ -420,7 +420,7 @@ if (0) fprintf(stderr, "run_gui: %s -- %d %d\n", gui_xdisplay, connect_to_x11vnc
}
/* gui */
if (no_external_cmds) {
if (no_external_cmds || !cmd_ok("gui")) {
fprintf(stderr, "cannot run external commands in -nocmds "
"mode:\n");
fprintf(stderr, " \"%s\"\n", "gui + wish");

@ -305,6 +305,7 @@ void print_help(int mode) {
" option, otherwise the stderr goes to the viewer which\n"
" will cause it to abort. Specifying both -inetd and -q\n"
" and no -o will automatically close the stderr.\n"
"\n"
"-nofilexfer Disable the TightVNC file transfer extension. (same as\n"
" -disablefiletransfer). Note that when the -viewonly\n"
" option is supplied all file transfers are disabled.\n"
@ -312,6 +313,7 @@ void print_help(int mode) {
" However, if the remote control mechanism is used to\n"
" change the global or per-client viewonly state the\n"
" filetransfer permissions will NOT change.\n"
"\n"
"-http Instead of using -httpdir (see below) to specify\n"
" where the Java vncviewer applet is, have x11vnc try\n"
" to *guess* where the directory is by looking relative\n"
@ -388,6 +390,23 @@ void print_help(int mode) {
" a global -viewonly is in effect (all input is discarded\n"
" in that case).\n"
"\n"
"-grabkbd When VNC viewers are connected, attempt to the grab the\n"
" keyboard so someone sitting at the physical display\n"
" is not able to enter keystrokes. This method uses\n"
" XGrabKeyboard(3X11) and so it is not secure and does not\n"
" rule out the person at the physical display injecting\n"
" keystrokes by flooding the server with them, grabbing\n"
" the keyboard himself, etc. Some degree of cooperation\n"
" from the person at the display is assumed.\n"
"-grabptr As -grabkbd, but for the mouse pointer using\n"
" XGrabPointer(3X11). Unfortunately due to the way the X\n"
" server works, the mouse can still be moved around by the\n"
" user at the physical display, but he will not be able to\n"
" change window focus with it. Also some window managers\n"
" that call XGrabServer(3X11) for resizes, etc, will\n"
" act on the local user's input. Again, some degree of\n"
" cooperation from the person at the display is assumed.\n"
"\n"
"-viewpasswd string Supply a 2nd password for view-only logins. The -passwd\n"
" (full-access) password must also be supplied.\n"
"\n"
@ -587,7 +606,25 @@ void print_help(int mode) {
" as the user who just authenticated via the login and\n"
" password prompt.\n"
"\n"
" Thus the combination of -display WAIT:cmd=... and\n"
" Also in the case of -unixpw, the user logging in can\n"
" place a colon at the end of his username and supply\n"
" a few options: scale=, scale_cursor=, solid, id=,\n"
" clear_mods, clear_keys, repeat, or speeds= separated\n"
" by commas if there is more than one. After the user\n"
" logs in successfully, these options will be applied to\n"
" the VNC screen. For example,\n"
"\n"
" login: fred:scale=3/4,repeat\n"
" Password: ...\n"
"\n"
" for convenience m/n implies scale= e.g. fred:3/4\n"
" To disable this set the environment variable\n"
" X11VNC_NO_UNIXPW_OPTS=1. To set any other options,\n"
" the user can use the gui (x11vnc -gui connect) or the\n"
" remote control method (x11vnc -R opt:val) during his\n"
" VNC session.\n"
"\n"
" So the combination of -display WAIT:cmd=... and\n"
" -unixpw allows automatic pairing of an unix\n"
" authenticated VNC user with his desktop. This could\n"
" be very useful on SunRays and also any system where\n"
@ -620,7 +657,7 @@ void print_help(int mode) {
" 5815 stream tcp nowait root /usr/sbin/tcpd .../x11vnc \\\n"
" -inetd -q -http_ssl -display WAIT:cmd=HTTPONCE\n"
"\n"
" Is used in the Apache SSL-portal example (see FAQ).\n"
" It is used in the Apache SSL-portal example (see FAQ).\n"
"\n"
" Finally, one can insert a geometry between colons,\n"
" e.g. WAIT:1280x1024:... to set the size of the display\n"
@ -1404,6 +1441,12 @@ void print_help(int mode) {
"-rc filename Use \"filename\" instead of $HOME/.x11vncrc for rc file.\n"
"-norc Do not process any .x11vncrc file for options.\n"
"\n"
"-env VAR=VALUE Set the environment variable 'VAR' to value 'VALUE'\n"
" at x11vnc startup. This is a convenience utility to\n"
" avoid shell script wrappers, etc. to set the env. var.\n"
" You may specify as many of these as needed on the\n"
" command line.\n"
"\n"
"-h, -help Print this help text.\n"
"-?, -opts Only list the x11vnc options.\n"
"-V, -version Print program version and last modification date.\n"
@ -2719,6 +2762,10 @@ void print_help(int mode) {
" nolookup enable -nolookup mode.\n"
" lookup disable -nolookup mode.\n"
" input:str set -input to \"str\", empty to disable.\n"
" grabkbd enable -grabkbd mode.\n"
" nograbkbd disable -grabkbd mode.\n"
" grabptr enable -grabptr mode.\n"
" nograbptr disable -grabptr mode.\n"
" client_input:str set the K, M, B -input on a per-client\n"
" basis. select which client as for\n"
" disconnect, e.g. client_input:host:MB\n"
@ -2976,13 +3023,14 @@ void print_help(int mode) {
" scr_skip scr_inc scr_keys scr_term scr_keyrepeat\n"
" scr_parms scrollcopyrect scr noscrollcopyrect noscr\n"
" fixscreen noxrecord xrecord reset_record pointer_mode\n"
" pm input_skip input client_input speeds wmdt\n"
" debug_pointer dp nodebug_pointer nodp debug_keyboard\n"
" dk nodebug_keyboard nodk deferupdate defer wait_ui\n"
" wait_bog nowait_bog slow_fb wait readtimeout nap nonap\n"
" sb screen_blank fbpm nofbpm fs gaps grow fuzz snapfb\n"
" nosnapfb rawfb progressive rfbport http nohttp httpport\n"
" httpdir enablehttpproxy noenablehttpproxy alwaysshared\n"
" pm input_skip input grabkbd nograbkbd grabptr\n"
" nograbptr client_input speeds wmdt debug_pointer dp\n"
" nodebug_pointer nodp debug_keyboard dk nodebug_keyboard\n"
" nodk deferupdate defer wait_ui wait_bog nowait_bog\n"
" slow_fb wait readtimeout nap nonap sb screen_blank\n"
" fbpm nofbpm fs gaps grow fuzz snapfb nosnapfb rawfb\n"
" progressive rfbport http nohttp httpport httpdir\n"
" enablehttpproxy noenablehttpproxy alwaysshared\n"
" noalwaysshared nevershared noalwaysshared dontdisconnect\n"
" nodontdisconnect desktop debug_xevents nodebug_xevents\n"
" debug_xevents debug_xdamage nodebug_xdamage\n"
@ -2997,12 +3045,8 @@ void print_help(int mode) {
" scale_str scaled_x scaled_y scale_numer scale_denom\n"
" scale_fac scaling_blend scaling_nomult4 scaling_pad\n"
" scaling_interpolate inetd privremote unsafe safer nocmds\n"
#ifndef REL81
" passwdfile unixpw unixpw_nis unixpw_list ssl ssl_pem\n"
" sslverify stunnel stunnel_pem https usepw using_shm\n"
#else
" passwdfile usepw using_shm\n"
#endif
" logfile o flag rc norc h help V version lastmod bg\n"
" sigpipe threads readrate netrate netlatency pipeinput\n"
" clients client_count pid ext_xtest ext_xtrap ext_xrecord\n"
@ -3073,6 +3117,17 @@ void print_help(int mode) {
" remote-control is disabled it cannot be turned back on.\n"
"-nocmds No external commands (e.g. system(3), popen(3), exec(3))\n"
" will be run.\n"
"-allowedcmds list \"list\" contains a comma separated list of the only\n"
" external commands that can be run. The full list of\n"
" associated options is:\n"
"\n"
" stunnel, ssl, unixpw, WAIT, id, accept, afteraccept,\n"
" gone, pipeinput, v4l-info, rawfb-setup, dt, gui,\n"
" storepasswd, crash.\n"
"\n"
" See each option's help to learn the associated external\n"
" command. Note that the -nocmds option takes precedence\n"
" and disables all external commands.\n"
"\n"
"-deny_all For use with -remote nodeny: start out denying all\n"
" incoming clients until \"-remote nodeny\" is used to\n"
@ -3247,7 +3302,7 @@ void nopassword_warning_msg(int gotloc) {
"#@ YOU ARE RUNNING X11VNC WITHOUT A PASSWORD!! @#\n"
"#@ @#\n"
"#@ This means anyone with network access to this computer @#\n"
"#@ will be able to easily view and control your desktop. @#\n"
"#@ will be able to view and control your desktop. @#\n"
"#@ @#\n"
"#@ >>> If you did not mean to do this Press CTRL-C now!! <<< @#\n"
"#@ @#\n"
@ -3257,16 +3312,18 @@ void nopassword_warning_msg(int gotloc) {
"#@ @#\n"
"#@ You can create an x11vnc password file by running: @#\n"
"#@ @#\n"
"#@ x11vnc -storepasswd password /path/to/passfile @#\n"
"#@ x11vnc -storepasswd password /path/to/passfile @#\n"
"#@ or x11vnc -storepasswd /path/to/passfile @#\n"
"#@ or x11vnc -storepasswd @#\n"
"#@ @#\n"
"#@ (the last one will use ~/.vnc/passwd) @#\n"
"#@ @#\n"
"#@ and then starting x11vnc via: @#\n"
"#@ @#\n"
"#@ x11vnc -rfbauth /path/to/passfile @#\n"
"#@ @#\n"
"#@ an existing ~/.vnc/passwd file will work too. @#\n"
"#@ @#\n"
"#@ Running \"x11vnc -storepasswd\" with no arguments @#\n"
"#@ will prompt for a passwd to store in ~/.vnc/passwd. @#\n"
"#@ an existing ~/.vnc/passwd file from another VNC @#\n"
"#@ application will work fine too. @#\n"
"#@ @#\n"
"#@ You can also use the -passwdfile or -passwd options. @#\n"
"#@ (note -passwd is unsafe if local users are not trusted) @#\n"
@ -3277,7 +3334,8 @@ void nopassword_warning_msg(int gotloc) {
"#@ Use x11vnc -usepw to automatically use your @#\n"
"#@ ~/.vnc/passwd or ~/.vnc/passwdfile password files. @#\n"
"#@ (and prompt you to create ~/.vnc/passwd if neither @#\n"
"#@ file exists.) @#\n"
"#@ file exists.) Under -usepw, x11vnc will exit if it @#\n"
"#@ cannot find a password to use. @#\n"
"#@ @#\n"
"#@ @#\n"
"#@ Even with a password, the subsequent VNC traffic is @#\n"

@ -324,7 +324,7 @@ void autorepeat(int restore, int bequiet) {
void check_add_keysyms(void) {
static time_t last_check = 0;
int clear_freq = 300, quiet = 1, count;
time_t now = time(0);
time_t now = time(NULL);
if (unixpw_in_progress) return;
@ -2612,7 +2612,7 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
KeyCode k;
int idx, isbutton = 0;
allowed_input_t input;
time_t now = time(0);
time_t now = time(NULL);
double tnow;
static int skipped_last_down;
static rfbBool last_down;

@ -75,6 +75,7 @@ int no_external_cmds = 0; /* -nocmds */
#else
int no_external_cmds = 1; /* cannot be turned back on. */
#endif
char *allowed_external_cmds = NULL;
int started_as_root = 0;
int host_lookup = 1;
char *users_list = NULL; /* -users */

@ -56,6 +56,7 @@ extern int safe_remote_only;
extern int priv_remote;
extern int more_safe;
extern int no_external_cmds;
extern char *allowed_external_cmds;
extern int started_as_root;
extern int host_lookup;
extern char *users_list;

@ -51,10 +51,10 @@ static void check_fbpm(void) {
if (! client_count) {
return;
}
if (time(0) < last_fbpm + 5) {
if (time(NULL) < last_fbpm + 5) {
return;
}
last_fbpm = time(0);
last_fbpm = time(NULL);
if (FBPMInfo(dpy, &level, &enabled)) {
if (db) fprintf(stderr, "FBPMInfo level: %d enabled: %d\n", level, enabled);

@ -319,7 +319,7 @@ static void update_x11_pointer_position(int x, int y) {
rc = set_cursor(x, y, get_which_cursor());
cursor_changes += rc;
last_event = last_input = last_pointer_input = time(0);
last_event = last_input = last_pointer_input = time(NULL);
}
void do_button_mask_change(int mask, int button) {
@ -390,7 +390,7 @@ void do_button_mask_change(int mask, int button) {
static void update_x11_pointer_mask(int mask) {
int snapped = 0, xr_mouse = 1, i;
last_event = last_input = last_pointer_input = time(0);
last_event = last_input = last_pointer_input = time(NULL);
RAWFB_RET_VOID
@ -942,7 +942,7 @@ if (0) fprintf(stderr, "initialize_pipeinput: %s -- %s\n", pipeinput_str, p);
set_child_info();
/* pipeinput */
if (no_external_cmds) {
if (no_external_cmds || !cmd_ok("pipeinput")) {
rfbLogEnable(1);
rfbLog("cannot run external commands in -nocmds mode:\n");
rfbLog(" \"%s\"\n", p);

@ -296,7 +296,10 @@ int check_httpdir(void) {
p = strtok(path, ":");
while(p) {
free(prog);
if (prog) {
free(prog);
prog = NULL;
}
len = strlen(p) + 1 + strlen(base) + 1;
prog = (char *) malloc(len);
snprintf(prog, len, "%s/%s", p, base);
@ -314,6 +317,7 @@ int check_httpdir(void) {
* 12345678901234567
* /path/to/bin/../share/x11vnc/classes/ssl
* 123456789012345678901
* 21
*/
if ((q = strrchr(prog, '/')) == NULL) {
rfbLog("check_httpdir: bad program path: %s\n", prog);
@ -648,13 +652,25 @@ char *process_remote_cmd(char *cmd, int stringonly) {
/* comma separated batch mode */
char *s, *q, *res;
char tmp[512];
strcpy(buf, "");
char **pieces;
int k = 0, n = 0;
pieces = (char **) malloc(strlen(cmd) * sizeof(char *));
s = strdup(cmd + strlen("qry="));
q = strtok(s, ",");
while (q) {
strcpy(tmp, "qry=");
strncat(tmp, q, 500);
res = process_remote_cmd(tmp, 1);
pieces[n] = strdup(tmp);
n++;
q = strtok(NULL, ",");
}
free(s);
strcpy(buf, "");
for (k=0; k<n; k++) {
res = process_remote_cmd(pieces[k], 1);
if (res && strlen(buf)+strlen(res)
>= X11VNC_REMOTE_MAX - 1) {
rfbLog("overflow in process_remote_cmd:"
@ -666,12 +682,14 @@ char *process_remote_cmd(char *cmd, int stringonly) {
strcat(buf, res);
free(res);
}
q = strtok(NULL, ",");
if (q) {
if (k < n - 1) {
strcat(buf, ",");
}
}
free(s);
for (k=0; k<n; k++) {
free(pieces[k]);
}
free(pieces);
goto qry;
}
p += strlen("qry=");
@ -781,7 +799,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
if (sscanf(p, "%d", &delay) == 1) {
rfbLog("damaging client fb's for %d secs "
"(by not marking rects.)\n", delay);
damage_time = time(0);
damage_time = time(NULL);
damage_delay = delay;
}
@ -3028,6 +3046,47 @@ char *process_remote_cmd(char *cmd, int stringonly) {
if (doit) {
initialize_allowed_input();
}
} else if (!strcmp(p, "grabkbd")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, grab_kbd);
goto qry;
}
grab_kbd = 1;
rfbLog("enabled grab_kbd\n");
} else if (!strcmp(p, "nograbkbd")) {
int orig = grab_kbd;
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !grab_kbd);
goto qry;
}
grab_kbd = 0;
if (orig && dpy) {
X_LOCK;
XUngrabKeyboard(dpy, CurrentTime);
X_UNLOCK;
}
rfbLog("disabled grab_kbd\n");
} else if (!strcmp(p, "grabptr")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, grab_ptr);
goto qry;
}
grab_ptr = 1;
rfbLog("enabled grab_ptr\n");
} else if (!strcmp(p, "nograbptr")) {
int orig = grab_ptr;
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !grab_ptr);
goto qry;
}
grab_ptr = 0;
if (orig && dpy) {
X_LOCK;
XUngrabPointer(dpy, CurrentTime);
X_UNLOCK;
}
rfbLog("disabled grab_ptr\n");
} else if (strstr(p, "client_input") == p) {
NOTAPP
COLON_CHECK("client_input:")

@ -99,26 +99,26 @@ void initialize_tiles(void) {
ntiles = ntiles_x * ntiles_y;
tile_has_diff = (unsigned char *)
malloc((size_t) (ntiles * sizeof(unsigned char)));
calloc((size_t) (ntiles * sizeof(unsigned char)), 1);
tile_has_xdamage_diff = (unsigned char *)
malloc((size_t) (ntiles * sizeof(unsigned char)));
calloc((size_t) (ntiles * sizeof(unsigned char)), 1);
tile_row_has_xdamage_diff = (unsigned char *)
malloc((size_t) (ntiles_y * sizeof(unsigned char)));
calloc((size_t) (ntiles_y * sizeof(unsigned char)), 1);
tile_tried = (unsigned char *)
malloc((size_t) (ntiles * sizeof(unsigned char)));
calloc((size_t) (ntiles * sizeof(unsigned char)), 1);
tile_copied = (unsigned char *)
malloc((size_t) (ntiles * sizeof(unsigned char)));
calloc((size_t) (ntiles * sizeof(unsigned char)), 1);
tile_blackout = (tile_blackout_t *)
malloc((size_t) (ntiles * sizeof(tile_blackout_t)));
tile_region = (region_t *) malloc((size_t) (ntiles * sizeof(region_t)));
calloc((size_t) (ntiles * sizeof(tile_blackout_t)), 1);
tile_region = (region_t *) calloc((size_t) (ntiles * sizeof(region_t)), 1);
tile_row = (XImage **)
malloc((size_t) ((ntiles_x + 1) * sizeof(XImage *)));
calloc((size_t) ((ntiles_x + 1) * sizeof(XImage *)), 1);
tile_row_shm = (XShmSegmentInfo *)
malloc((size_t) ((ntiles_x + 1) * sizeof(XShmSegmentInfo)));
calloc((size_t) ((ntiles_x + 1) * sizeof(XShmSegmentInfo)), 1);
/* there will never be more hints than tiles: */
hint_list = (hint_t *) malloc((size_t) (ntiles * sizeof(hint_t)));
hint_list = (hint_t *) calloc((size_t) (ntiles * sizeof(hint_t)), 1);
}
void free_tiles(void) {
@ -240,7 +240,7 @@ static int shm_create(XShmSegmentInfo *shm, XImage **ximg_ptr, int w, int h,
}
return 0;
}
if (db) fprintf(stderr, "shm_create simple %d %d\t0x%x %s\n", w, h, xim, name);
if (db) fprintf(stderr, "shm_create simple %d %d\t%p %s\n", w, h, xim, name);
xim->data = (char *) malloc(xim->bytes_per_line * xim->height);
if (xim->data == NULL) {
rfbErr("XCreateImage(%s) data malloc failed.\n", name);
@ -349,7 +349,7 @@ void shm_delete(XShmSegmentInfo *shm) {
void shm_clean(XShmSegmentInfo *shm, XImage *xim) {
int db = 0;
if (db) fprintf(stderr, "shm_clean: called: 0x%x\n", xim);
if (db) fprintf(stderr, "shm_clean: called: %p\n", xim);
X_LOCK;
#if LIBVNCSERVER_HAVE_XSHM
if (shm != NULL && shm->shmid != -1 && dpy) {
@ -360,11 +360,11 @@ void shm_clean(XShmSegmentInfo *shm, XImage *xim) {
if (xim != NULL) {
if (! raw_fb_back_to_X) { /* raw_fb hack */
if (xim->bitmap_unit != -1) {
if (db) fprintf(stderr, "shm_clean: XDestroyImage 0x%x\n", xim);
if (db) fprintf(stderr, "shm_clean: XDestroyImage %p\n", xim);
XDestroyImage(xim);
} else {
if (xim->data) {
if (db) fprintf(stderr, "shm_clean: free xim->data 0x%x 0x%x\n", xim, xim->data);
if (db) fprintf(stderr, "shm_clean: free xim->data %p %p\n", xim, xim->data);
free(xim->data);
xim->data = NULL;
}
@ -1228,7 +1228,7 @@ void mark_rect_as_modified(int x1, int y1, int x2, int y2, int force) {
* damage_delay seconds.
*/
int debug = 0;
if (time(0) > damage_time + damage_delay) {
if (time(NULL) > damage_time + damage_delay) {
if (! quiet) {
rfbLog("damaging turned off.\n");
}
@ -2153,7 +2153,7 @@ if (db && snapcnt++ < 5) rfbLog("rawfb copy_snap took: %.5f secs\n", dnow() - st
*/
static void nap_set(int tile_cnt) {
int nap_in = nap_ok;
time_t now = time(0);
time_t now = time(NULL);
if (scan_count == 0) {
/* roll up check for all NSCAN scans */
@ -2219,7 +2219,7 @@ static void nap_check(int tile_cnt) {
return;
}
now = time(0);
now = time(NULL);
if (screen_blank > 0) {
int dt_ev, dt_fbu, ms = 2000;
@ -2254,7 +2254,7 @@ static void nap_check(int tile_cnt) {
*/
static void ping_clients(int tile_cnt) {
static time_t last_send = 0;
time_t now = time(0);
time_t now = time(NULL);
if (rfbMaxClientWait < 20000) {
rfbMaxClientWait = 20000;

@ -752,7 +752,7 @@ void check_padded_fb(void) {
}
if (unixpw_in_progress) return;
if (time(0) > pad_geometry_time+1 && all_clients_initialized()) {
if (time(NULL) > pad_geometry_time+1 && all_clients_initialized()) {
remove_fake_fb();
}
}
@ -776,7 +776,7 @@ void install_padded_fb(char *geom) {
return;
}
install_fake_fb(w, h, bpp);
pad_geometry_time = time(0);
pad_geometry_time = time(NULL);
}
static void initialize_snap_fb(void) {
@ -885,7 +885,7 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
set_child_info();
q += strlen("setup:");
/* rawfb-setup */
if (no_external_cmds) {
if (no_external_cmds || !cmd_ok("rawfb-setup")) {
rfbLogEnable(1);
rfbLog("cannot run external commands in -nocmds "
"mode:\n");
@ -1354,12 +1354,12 @@ static void initialize_clipshift(void) {
static int wait_until_mapped(Window win) {
int ms = 50, waittime = 30;
time_t start = time(0);
time_t start = time(NULL);
XWindowAttributes attr;
while (1) {
if (! valid_window(win, NULL, 0)) {
if (time(0) > start + waittime) {
if (time(NULL) > start + waittime) {
break;
}
usleep(ms * 1000);
@ -1840,7 +1840,7 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
fb_depth = (int) fb->depth;
rfbLog("initialize_screen: fb_depth/fb_bpp/fb_Bpl %d/%d/%d\n", fb_depth,
fb_depth, fb_Bpl);
fb_bpp, fb_Bpl);
main_bytes_per_line = fb->bytes_per_line;

@ -54,7 +54,7 @@ static int dt_cmd(char *cmd) {
}
/* dt */
if (no_external_cmds) {
if (no_external_cmds || !cmd_ok("dt")) {
rfbLog("cannot run external commands in -nocmds mode:\n");
rfbLog(" \"%s\"\n", cmd);
rfbLog(" dt_cmd: returning 1\n");
@ -522,7 +522,11 @@ static void solid_gnome(char *color) {
if (! orig_color) {
char *q;
orig_color = strdup(cmd_output(get_color));
if (cmd_ok("dt")) {
orig_color = strdup(cmd_output(get_color));
} else {
orig_color = "";
}
if (*orig_color == '\0') {
orig_color = strdup("#FFFFFF");
}
@ -532,7 +536,11 @@ static void solid_gnome(char *color) {
}
if (! orig_option) {
char *q;
orig_option = strdup(cmd_output(get_option));
if (cmd_ok("dt")) {
orig_option = strdup(cmd_output(get_option));
} else {
orig_color = "";
}
if (*orig_option == '\0') {
orig_option = strdup("stretched");
}

@ -32,7 +32,7 @@ static pid_t stunnel_pid = 0;
void check_stunnel(void) {
static time_t last_check = 0;
time_t now = time(0);
time_t now = time(NULL);
if (last_check + 3 >= now) {
return;
@ -72,13 +72,14 @@ int start_stunnel(int stunnel_port, int x11vnc_port) {
path = getenv("PATH");
if (! path) {
path = strdup(extra);
path = strdup(extra+1);
} else {
char *pt = path;
path = (char *) malloc(strlen(path)+strlen(extra)+1);
if (! path) {
return 0;
}
strcpy(path, getenv("PATH"));
strcpy(path, pt);
strcat(path, extra);
}
@ -106,15 +107,16 @@ int start_stunnel(int stunnel_port, int x11vnc_port) {
}
if (! stunnel_path) {
free(exe);
return 0;
}
if (stunnel_path[0] == '\0') {
free(stunnel_path);
free(exe);
return 0;
}
/* stunnel */
if (no_external_cmds) {
if (no_external_cmds || !cmd_ok("stunnel")) {
rfbLogEnable(1);
rfbLog("start_stunnel: cannot run external commands in -nocmds mode:\n");
rfbLog(" \"%s\"\n", stunnel_path);
@ -140,7 +142,7 @@ int start_stunnel(int stunnel_port, int x11vnc_port) {
if (ssl_verify) {
if (stat(ssl_verify, &verify_buf) != 0) {
rfbLog("stunnel: %s does not exist.\n", ssl_verify);
return 0;
clean_up_exit(1);
}
}
@ -148,7 +150,7 @@ int start_stunnel(int stunnel_port, int x11vnc_port) {
if (stunnel_pid < 0) {
stunnel_pid = 0;
free(stunnel_path);
free(exe);
return 0;
}
@ -162,7 +164,7 @@ int start_stunnel(int stunnel_port, int x11vnc_port) {
}
if (use_stunnel == 3) {
char sp[20], xp[20], *a = NULL;
char sp[30], xp[30], *a = NULL;
char *st = stunnel_path;
char *pm = stunnel_pem;
char *sv = ssl_verify;
@ -179,6 +181,7 @@ int start_stunnel(int stunnel_port, int x11vnc_port) {
}
if (stunnel_pem && ssl_verify) {
/* XXX double check -v 2 */
execlp(st, st, "-f", "-d", sp, "-r", xp, "-P",
"none", "-p", pm, a, sv, "-v", "2",
(char *) NULL);
@ -212,6 +215,7 @@ int start_stunnel(int stunnel_port, int x11vnc_port) {
} else {
fprintf(in, "CAfile = %s\n", ssl_verify);
}
/* XXX double check -v 2 */
fprintf(in, "verify = 2\n");
}
fprintf(in, ";debug = 7\n\n");
@ -226,7 +230,8 @@ int start_stunnel(int stunnel_port, int x11vnc_port) {
execlp(stunnel_path, stunnel_path, "-fd", fd, (char *) NULL);
exit(1);
}
free(stunnel_path);
free(exe);
usleep(500 * 1000);
waitpid(stunnel_pid, &status, WNOHANG);
@ -263,9 +268,9 @@ void stop_stunnel(void) {
void setup_stunnel(int rport, int *argc, char **argv) {
int i, xport = 0;
if (! rport) {
if (! rport && argc && argv) {
for (i=0; i< *argc; i++) {
if (!strcmp(argv[i], "-rfbport")) {
if (argv[i] && !strcmp(argv[i], "-rfbport")) {
if (i < *argc - 1) {
rport = atoi(argv[i+1]);
break;
@ -281,18 +286,21 @@ void setup_stunnel(int rport, int *argc, char **argv) {
goto stunnel_fail;
}
}
xport = find_free_port(5950, 5999);
if (! xport) {
goto stunnel_fail;
}
if (start_stunnel(rport, xport)) {
int tweaked = 0;
char tmp[20];
char tmp[30];
sprintf(tmp, "%d", xport);
if (argv) {
for (i=0; i< *argc; i++) {
if (!strcmp(argv[i], "-rfbport")) {
if (argc && argv) {
for (i=0; i < *argc; i++) {
if (argv[i] && !strcmp(argv[i], "-rfbport")) {
if (i < *argc - 1) {
/* replace orig value */
argv[i+i] = strdup(tmp);
tweaked = 1;
break;
@ -353,7 +361,7 @@ char *get_Cert_dir(char *cdir_in, char **tmp_in) {
sprintf(cdir, "%s%s", home, cases1[1]);
}
tmp = (char *) malloc(strlen(cdir) + 10);
tmp = (char *) malloc(strlen(cdir) + strlen("/tmp") + 1);
for (i=0; i<3; i++) {
int ret;
sprintf(tmp, "%s%s", cdir, cases2[i]);
@ -380,35 +388,36 @@ char *get_Cert_dir(char *cdir_in, char **tmp_in) {
return cdir;
}
void sslGenCA(char *cdir) {
static char *getsslscript(char *cdir, char *name, char *script) {
char *openssl = find_openssl_bin();
char *tmp, *cmd, *scr, *cdir_use;
char *tmp, *scr, *cdir_use;
FILE *out;
if (! openssl) {
if (! openssl || openssl[0] == '\0') {
exit(1);
}
if (!name || !script) {
exit(1);
}
cdir_use = get_Cert_dir(cdir, &tmp);
if (! cdir_use) {
if (!cdir_use || !tmp) {
exit(1);
}
cmd = (char *) malloc(strlen(tmp) + 100);
scr = (char *) malloc(strlen(tmp) + 100);
scr = (char *) malloc(strlen(tmp) + 1 + strlen(name) + 30);
sprintf(cmd, "%s/genca.%d.sh", tmp, getpid());
out = fopen(cmd, "w");
sprintf(scr, "%s/%s.%d.sh", tmp, name, getpid());
out = fopen(scr, "w");
if (! out) {
rfbLog("could not open: %s\n", cmd);
rfbLog("could not open: %s\n", scr);
rfbLogPerror("fopen");
exit(1);
}
fprintf(out, "%s", genCA);
fprintf(out, "%s", script);
fclose(out);
sprintf(scr, "/bin/sh %s", cmd);
rfbLog("Using openssl: %s\n", openssl);
rfbLog("Using certs dir: %s\n", cdir_use);
fprintf(stderr, "\n");
@ -416,45 +425,36 @@ void sslGenCA(char *cdir) {
set_env("BASE_DIR", cdir_use);
set_env("OPENSSL", openssl);
system(scr);
unlink(cmd);
return scr;
}
void sslGenCert(char *ty, char *nm) {
char *openssl = find_openssl_bin();
char *tmp, *cmd, *scr, *cdir_use;
FILE *out;
void sslGenCA(char *cdir) {
char *cmd, *scr = getsslscript(cdir, "genca", genCA);
if (! openssl) {
if (! scr) {
exit(1);
}
cdir_use = get_Cert_dir(NULL, &tmp);
if (! cdir_use) {
exit(1);
}
cmd = (char *)malloc(strlen("/bin/sh ") + strlen(scr) + 1);
sprintf(cmd, "/bin/sh %s", scr);
cmd = (char *) malloc(strlen(tmp) + 100);
scr = (char *) malloc(strlen(tmp) + 100);
system(cmd);
unlink(scr);
sprintf(cmd, "%s/gencert.%d.sh", tmp, getpid());
out = fopen(cmd, "w");
if (! out) {
rfbLog("could not open: %s\n", cmd);
rfbLogPerror("fopen");
free(cmd);
free(scr);
}
void sslGenCert(char *ty, char *nm) {
char *cmd, *scr = getsslscript(NULL, "gencert", genCert);
if (! scr) {
exit(1);
}
fprintf(out, "%s", genCert);
fclose(out);
sprintf(scr, "/bin/sh %s", cmd);
rfbLog("Using openssl: %s\n", openssl);
rfbLog("Using certs dir: %s\n", cdir_use);
fprintf(stderr, "\n");
cmd = (char *)malloc(strlen("/bin/sh ") + strlen(scr) + 1);
sprintf(cmd, "/bin/sh %s", scr);
set_env("BASE_DIR", cdir_use);
set_env("OPENSSL", openssl);
if (! ty) {
set_env("TYPE", "");
} else {
@ -474,17 +474,18 @@ void sslGenCert(char *ty, char *nm) {
}
}
system(scr);
unlink(cmd);
system(cmd);
unlink(scr);
free(cmd);
free(scr);
}
void sslEncKey(char *path, int mode) {
char *openssl = find_openssl_bin();
char *scr, *cert = NULL, *tca;
char *scr, *cert = NULL, *tca, *cdir = NULL;
char line[1024], tmp[] = "/tmp/x11vnc-tmp.XXXXXX";
char *cdir = NULL;
int tmp_fd, incert, info_only = 0, delete_only = 0;
int listlong = 0;
int tmp_fd, incert, info_only = 0, delete_only = 0, listlong = 0;
struct stat sbuf;
FILE *file;
static int depth = 0;
@ -493,6 +494,11 @@ void sslEncKey(char *path, int mode) {
/* get_saved_pem may call us back. */
return;
}
if (! path) {
return;
}
depth++;
if (mode == 1) {
@ -504,8 +510,9 @@ void sslEncKey(char *path, int mode) {
if (! openssl) {
exit(1);
}
cdir = get_Cert_dir(NULL, &tca);
if (! cdir) {
if (! cdir || ! tca) {
fprintf(stderr, "could not find Cert dir\n");
exit(1);
}
@ -518,28 +525,38 @@ void sslEncKey(char *path, int mode) {
if (strstr(path, "SAVE") == path) {
char *p = get_saved_pem(path, 0);
if (p == NULL) {
fprintf(stderr, "could not find saved pem matching: %s\n", path);
fprintf(stderr, "could not find saved pem "
"matching: %s\n", path);
exit(1);
}
path = p;
} else if (!strcmp(path, "CA") && cdir) {
tca = (char *) malloc(strlen(cdir) + strlen("/CA/cacert.pem") + 1);
} else if (!strcmp(path, "CA")) {
tca = (char *) malloc(strlen(cdir)+strlen("/CA/cacert.pem")+1);
sprintf(tca, "%s/CA/cacert.pem", cdir);
path = tca;
} else if (info_only && (!strcasecmp(path, "LIST") || !strcasecmp(path, "LS") ||
!strcasecmp(path, "ALL"))) {
if (! cdir || strchr(cdir, '\'')) {
fprintf(stderr, "bad certdir char: %s\n", cdir ? cdir : "null");
} else if (info_only && (!strcasecmp(path, "LIST") ||
!strcasecmp(path, "LS") || !strcasecmp(path, "ALL"))) {
if (! program_name || strchr(program_name, ' ')) {
fprintf(stderr, "bad program name.\n");
exit(1);
}
if (strchr(cdir, '\'')) {
fprintf(stderr, "bad certdir char: %s\n", cdir);
exit(1);
}
tca = (char *) malloc(2*strlen(cdir) + strlen(program_name) + 1000);
sprintf(tca, "find '%s' | egrep '/(CA|tmp|clients)$|\\.(crt|pem|key|req)$' "
"| grep -v CA/newcerts", cdir);
tca = (char *) malloc(2*strlen(cdir)+strlen(program_name)+1000);
sprintf(tca, "find '%s' | egrep '/(CA|tmp|clients)$|"
"\\.(crt|pem|key|req)$' | grep -v CA/newcerts", cdir);
if (!strcasecmp(path, "ALL")) {
/* ugh.. */
strcat(tca, " | egrep -v 'private/cakey.pem|(CA|tmp|clients)$' | xargs -n1 ");
strcat(tca, " | egrep -v 'private/cakey.pem|"
"(CA|tmp|clients)$' | xargs -n1 ");
strcat(tca, program_name);
strcat(tca, " -ssldir '");
strcat(tca, cdir);
@ -548,6 +565,8 @@ void sslEncKey(char *path, int mode) {
strcat(tca, " | xargs ls -ld ");
}
system(tca);
free(tca);
depth--;
return;
@ -562,7 +581,7 @@ void sslEncKey(char *path, int mode) {
write(tmp_fd, genCert, strlen(genCert));
close(tmp_fd);
scr = (char *) malloc(strlen(tmp) + 100);
scr = (char *) malloc(strlen("/bin/sh ") + strlen(tmp) + 1);
sprintf(scr, "/bin/sh %s", tmp);
set_env("BASE_DIR", cdir);
@ -575,57 +594,59 @@ void sslEncKey(char *path, int mode) {
}
system(scr);
unlink(tmp);
free(scr);
depth--;
return;
}
if (stat(path, &sbuf) != 0) {
if (strstr(path, "client") || strchr(path, '/') == NULL) {
int i;
tca = (char *) malloc(strlen(cdir) + strlen("/clients")
+ strlen(path) + 100);
for (i = 1; i <= 15; i++) {
tca[0] = '\0';
if ( i == 1) {
sprintf(tca, "%s/%s", cdir, path);
} else if (i == 2 && mode > 0) {
sprintf(tca, "%s/%s.crt", cdir, path);
} else if (i == 3) {
sprintf(tca, "%s/%s.pem", cdir, path);
} else if (i == 4 && mode > 1) {
sprintf(tca, "%s/%s.req", cdir, path);
} else if (i == 5 && mode > 1) {
sprintf(tca, "%s/%s.key", cdir, path);
} else if (i == 6) {
sprintf(tca, "%s/clients/%s", cdir, path);
} else if (i == 7 && mode > 0) {
sprintf(tca, "%s/clients/%s.crt", cdir, path);
} else if (i == 8) {
sprintf(tca, "%s/clients/%s.pem", cdir, path);
} else if (i == 9 && mode > 1) {
sprintf(tca, "%s/clients/%s.req", cdir, path);
} else if (i == 10 && mode > 1) {
sprintf(tca, "%s/clients/%s.key", cdir, path);
} else if (i == 11) {
sprintf(tca, "%s/server-%s", cdir, path);
} else if (i == 12 && mode > 0) {
sprintf(tca, "%s/server-%s.crt", cdir, path);
} else if (i == 13) {
sprintf(tca, "%s/server-%s.pem", cdir, path);
} else if (i == 14 && mode > 1) {
sprintf(tca, "%s/server-%s.req", cdir, path);
} else if (i == 15 && mode > 1) {
sprintf(tca, "%s/server-%s.key", cdir, path);
}
if (tca[0] == '\0') {
continue;
}
if (stat(tca, &sbuf) == 0) {
path = tca;
break;
}
if (strstr(path, "client") || strchr(path, '/') == NULL) {
int i;
tca = (char *) malloc(strlen(cdir) + strlen(path) + 100);
for (i = 1; i <= 15; i++) {
tca[0] = '\0';
if ( i == 1) {
sprintf(tca, "%s/%s", cdir, path);
} else if (i == 2 && mode > 0) {
sprintf(tca, "%s/%s.crt", cdir, path);
} else if (i == 3) {
sprintf(tca, "%s/%s.pem", cdir, path);
} else if (i == 4 && mode > 1) {
sprintf(tca, "%s/%s.req", cdir, path);
} else if (i == 5 && mode > 1) {
sprintf(tca, "%s/%s.key", cdir, path);
} else if (i == 6) {
sprintf(tca, "%s/clients/%s", cdir, path);
} else if (i == 7 && mode > 0) {
sprintf(tca, "%s/clients/%s.crt", cdir, path);
} else if (i == 8) {
sprintf(tca, "%s/clients/%s.pem", cdir, path);
} else if (i == 9 && mode > 1) {
sprintf(tca, "%s/clients/%s.req", cdir, path);
} else if (i == 10 && mode > 1) {
sprintf(tca, "%s/clients/%s.key", cdir, path);
} else if (i == 11) {
sprintf(tca, "%s/server-%s", cdir, path);
} else if (i == 12 && mode > 0) {
sprintf(tca, "%s/server-%s.crt", cdir, path);
} else if (i == 13) {
sprintf(tca, "%s/server-%s.pem", cdir, path);
} else if (i == 14 && mode > 1) {
sprintf(tca, "%s/server-%s.req", cdir, path);
} else if (i == 15 && mode > 1) {
sprintf(tca, "%s/server-%s.key", cdir, path);
}
if (tca[0] == '\0') {
continue;
}
if (stat(tca, &sbuf) == 0) {
path = tca;
break;
}
}
}
}
if (stat(path, &sbuf) != 0) {
@ -635,7 +656,7 @@ void sslEncKey(char *path, int mode) {
}
if (! info_only) {
cert = (char *) malloc(2*(sbuf.st_size + 100));
cert = (char *) malloc(2*(sbuf.st_size + 1024));
file = fopen(path, "r");
if (file == NULL) {
rfbLog("sslEncKey: %s\n", path);
@ -645,15 +666,17 @@ void sslEncKey(char *path, int mode) {
incert = 0;
cert[0] = '\0';
while (fgets(line, 1024, file) != NULL) {
if (strstr(line, "-----BEGIN CERTIFICATE-----") == line) {
if (strstr(line, "-----BEGIN CERTIFICATE-----")
== line) {
incert = 1;
}
if (incert) {
if (strlen(cert) + strlen(line) < 2*sbuf.st_size) {
if (strlen(cert)+strlen(line) < 2*sbuf.st_size) {
strcat(cert, line);
}
}
if (strstr(line, "-----END CERTIFICATE-----") == line) {
if (strstr(line, "-----END CERTIFICATE-----")
== line) {
incert = 0;
}
}
@ -668,7 +691,7 @@ void sslEncKey(char *path, int mode) {
write(tmp_fd, genCert, strlen(genCert));
close(tmp_fd);
scr = (char *) malloc(strlen(tmp) + 100);
scr = (char *) malloc(strlen("/bin/sh ") + strlen(tmp) + 1);
sprintf(scr, "/bin/sh %s", tmp);
set_env("BASE_DIR", "/no/such/dir");
@ -691,7 +714,7 @@ void sslEncKey(char *path, int mode) {
rfbLogPerror("fopen");
exit(1);
}
fprintf(file, cert);
fprintf(file, "%s", cert);
fclose(file);
free(cert);
}

@ -92,9 +92,9 @@ int openssl_present(void) {return 1;}
static void sslerrexit(void) {
unsigned long err = ERR_get_error();
char str[256];
if (err) {
char str[256];
ERR_error_string(err, str);
fprintf(stderr, "ssl error: %s\n", str);
}
@ -106,6 +106,11 @@ char *get_saved_pem(char *save, int create) {
int prompt = 0, len;
struct stat sbuf;
if (! save) {
rfbLog("get_saved_pem: save string is null.\n");
clean_up_exit(1);
}
if (strstr(save, "SAVE_PROMPT") == save) {
prompt = 1;
s = save + strlen("SAVE_PROMPT");
@ -121,11 +126,13 @@ char *get_saved_pem(char *save, int create) {
}
cdir = get_Cert_dir(NULL, &tmp);
if (! cdir) {
if (! cdir || ! tmp) {
rfbLog("get_saved_pem: could not find Cert dir.\n");
clean_up_exit(1);
}
len = strlen(cdir) + strlen("/server.pem") + strlen(s) + 1;
path = (char *) malloc(len);
sprintf(path, "%s/server%s.pem", cdir, s);
@ -145,6 +152,11 @@ char *get_saved_pem(char *save, int create) {
static char *get_input(char *tag, char **in) {
char line[1024], *str;
if (! tag || ! in || ! *in) {
return NULL;
}
fprintf(stderr, "%s:\n [%s] ", tag, *in);
if (fgets(line, 1024, stdin) == NULL) {
rfbLog("could not read stdin!\n");
@ -155,26 +167,28 @@ static char *get_input(char *tag, char **in) {
*str = '\0';
}
str = lblanks(line);
if (! strcmp(str, "")) {
if (!strcmp(str, "")) {
return *in;
} else {
free(*in);
return strdup(line);
}
}
char *find_openssl_bin(void) {
char *path, *exe, *p;
char *path, *exe, *p, *gp;
struct stat sbuf;
int found_openssl = 0;
char extra[] = ":/usr/bin:/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/sfw/bin";
char extra[] = ":/usr/bin:/bin:/usr/sbin:/usr/local/bin"
":/usr/local/sbin:/usr/sfw/bin";
if (! getenv("PATH")) {
gp = getenv("PATH");
if (! gp) {
fprintf(stderr, "could not find openssl(1) program in PATH.\n");
return NULL;
}
path = (char *) malloc(strlen(getenv("PATH")) + strlen(extra) + 1);
strcpy(path, getenv("PATH"));
path = (char *) malloc(strlen(gp) + strlen(extra) + 1);
strcpy(path, gp);
strcat(path, extra);
/* find openssl binary: */
@ -233,31 +247,36 @@ static char *create_tmp_pem(char *pathin, int prompt) {
;
C = strdup("AU");
L = strdup(UT.sysname);
snprintf(line, 1024, "%s-%f", UT.nodename, dnow());
L = strdup(UT.sysname ? UT.sysname : "unknown-os");
snprintf(line, 1024, "%s-%f", UT.nodename ? UT.nodename :
"unknown-node", dnow());
line[1024-1] = '\0';
OU = strdup(line);
O = strdup("x11vnc");
if (pathin) {
snprintf(line, 1024, "x11vnc-SELF-SIGNED-CERT-%d", getpid());
} else {
snprintf(line, 1024, "x11vnc-SELF-SIGNED-TEMPORARY-CERT-%d", getpid());
snprintf(line, 1024, "x11vnc-SELF-SIGNED-TEMPORARY-CERT-%d",
getpid());
}
line[1024-1] = '\0';
CN = strdup(line);
EM = strdup("x11vnc@server.nowhere");
/* ssl */
if (no_external_cmds) {
if (no_external_cmds || !cmd_ok("ssl")) {
rfbLog("create_tmp_pem: cannot run external commands.\n");
return NULL;
}
rfbLog("\n");
if (pathin) {
rfbLog("Creating a self-signed PEM certificate...\n");
} else {
rfbLog("Creating a temporary, self-signed PEM certificate...\n");
}
rfbLog("\n");
rfbLog("This will NOT prevent man-in-the-middle attacks UNLESS you\n");
rfbLog("get the certificate information to the VNC viewers SSL\n");
@ -274,9 +293,8 @@ static char *create_tmp_pem(char *pathin, int prompt) {
rfbLog("server certificate.\n");
rfbLog("\n");
exe = find_openssl_bin();
if (exe == NULL) {
if (! exe) {
return NULL;
}
@ -401,14 +419,15 @@ static char *create_tmp_pem(char *pathin, int prompt) {
rfbLogPerror("fopen");
return NULL;
}
out = fopen(pathin, "w");
chmod(pathin, 0600);
if (out == NULL) {
rfbLog("could not open: %s\n", pathin);
rfbLogPerror("fopen");
fclose(crt);
return NULL;
}
chmod(pathin, 0600);
in = fopen(pem, "r");
if (in == NULL) {
@ -461,6 +480,10 @@ static int pem_passwd_callback(char *buf, int size, int rwflag,
void *userdata) {
char *q, line[1024];
if (! buf) {
exit(1);
}
fprintf(stderr, "\nA passphrase is needed to unlock an OpenSSL "
"private key (PEM file).\n");
fprintf(stderr, "Enter passphrase> ");
@ -488,7 +511,18 @@ static int pem_passwd_callback(char *buf, int size, int rwflag,
static int appendfile(FILE *out, char *infile) {
char line[1024];
FILE *in = fopen(infile, "r");
FILE *in;
if (! infile) {
rfbLog("appendfile: null infile.\n");
return 0;
}
if (! out) {
rfbLog("appendfile: null out handle.\n");
return 0;
}
in = fopen(infile, "r");
if (in == NULL) {
rfbLog("appendfile: %s\n", infile);
@ -520,11 +554,8 @@ static char *get_ssl_verify_file(char *str_in) {
return str_in;
}
str = strdup(str_in);
p = strtok(str, ",");
cdir = get_Cert_dir(NULL, &tmp);
if (! cdir) {
if (! cdir || ! tmp) {
rfbLog("get_ssl_verify_file: invalid cert-dir.\n");
exit(1);
}
@ -535,12 +566,15 @@ static char *get_ssl_verify_file(char *str_in) {
sprintf(tfile, "%s/sslverify-load-%d.crts", tmp, getpid());
file = fopen(tfile, "w");
chmod(tfile, 0600);
if (file == NULL) {
rfbLog("get_ssl_verify_file: %s\n", tfile);
rfbLogPerror("fopen");
exit(1);
}
chmod(tfile, 0600);
str = strdup(str_in);
p = strtok(str, ",");
while (p) {
if (!strcmp(p, "CA")) {
@ -551,9 +585,11 @@ static char *get_ssl_verify_file(char *str_in) {
}
fprintf(stderr, "sslverify: loaded %s\n", tfile2);
count++;
} else if (!strcmp(p, "clients")) {
DIR *dir;
struct dirent *dp;
sprintf(tfile2, "%s/clients", cdir);
dir = opendir(tfile2);
if (! dir) {
@ -565,15 +601,21 @@ static char *get_ssl_verify_file(char *str_in) {
while ( (dp = readdir(dir)) != NULL) {
char *n = dp->d_name;
char *q = strstr(n, ".crt");
if (! q || strlen(q) != strlen(".crt")) {
continue;
}
if (strlen(n) > 512) {
continue;
}
sprintf(tfile2, "%s/clients/%s", cdir, n);
if (! appendfile(file, tfile2)) {
unlink(tfile);
exit(1);
}
fprintf(stderr, "sslverify: loaded %s\n", tfile2);
fprintf(stderr, "sslverify: loaded %s\n",
tfile2);
count++;
}
closedir(dir);
@ -599,7 +641,10 @@ static char *get_ssl_verify_file(char *str_in) {
fclose(file);
free(tfile2);
free(str);
fprintf(stderr, "sslverify: using %d client certs in %s\n", count, tfile);
fprintf(stderr, "sslverify: using %d client certs in %s\n", count,
tfile);
return tfile;
}
@ -676,6 +721,7 @@ void openssl_init(void) {
clean_up_exit(1);
}
tmp_pem = 1;
} else if (strstr(openssl_pem, "SAVE") == openssl_pem) {
openssl_pem = get_saved_pem(openssl_pem, 1);
if (! openssl_pem) {
@ -747,16 +793,19 @@ void openssl_init(void) {
}
unlink(openssl_pem);
free(openssl_pem);
openssl_pem = NULL;
}
if (ssl_verify) {
struct stat sbuf;
char *file;
int lvl;
file = get_ssl_verify_file(ssl_verify);
if (stat(file, &sbuf) != 0) {
if (!file || stat(file, &sbuf) != 0) {
rfbLog("openssl_init: -sslverify does not exists %s.\n",
file);
file ? file : "null");
rfbLogPerror("stat");
clean_up_exit(1);
}
@ -773,6 +822,7 @@ void openssl_init(void) {
sslerrexit();
}
}
lvl = SSL_VERIFY_FAIL_IF_NO_PEER_CERT|SSL_VERIFY_PEER;
SSL_CTX_set_verify(ctx, lvl, NULL);
if (strstr(file, "tmp/sslverify-load-")) {
@ -860,7 +910,9 @@ void https_port(void) {
rfbLog("https_port: could not open port %d\n", port);
clean_up_exit(1);
}
if (db) fprintf(stderr, "https_port: listen on port/sock %d/%d\n", port, sock);
if (db) fprintf(stderr, "https_port: listen on port/sock %d/%d\n",
port, sock);
https_sock = sock;
}
@ -978,6 +1030,7 @@ if (db) fprintf(stderr, "waitpid(%d) 2\n", helpers[i]);
}
}
/* AUDIT */
static int is_ssl_readable(int s_in, time_t last_https, char *last_get,
int mode) {
int nfd, db = 0;
@ -1008,7 +1061,7 @@ static int is_ssl_readable(int s_in, time_t last_https, char *last_get,
* increase the timeout if we know HTTP traffic has occurred
* recently:
*/
if (time(0) < last_https + 30) {
if (time(NULL) < last_https + 30) {
tv.tv_sec = 8;
if (strstr(last_get, "VncViewer")) {
tv.tv_sec = 4;
@ -1047,7 +1100,7 @@ static int watch_for_http_traffic(char *buf_a, int *n_a) {
db = atoi(getenv("ACCEPT_OPENSSL_DEBUG"));
}
buf = (char *) calloc(sizeof(ABSIZE+1), 1);
buf = (char *) calloc((ABSIZE+1), 1);
*n_a = 0;
n = SSL_read(ssl, buf, 2);
@ -1614,7 +1667,7 @@ if (db) fprintf(stderr, "iface: %s\n", iface);
int i;
rfbLog("SSL: but https for helper process succeeded.\n");
if (mode != OPENSSL_HTTPS) {
last_https = time(0);
last_https = time(NULL);
for (i=0; i<128; i++) {
last_get[i] = '\0';
}
@ -1856,7 +1909,7 @@ static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
if (db) fprintf(stderr, "ssl_xfer begin\n");
start = time(0);
start = time(NULL);
if (is_https) {
tv_use = tv_https_early;
} else {
@ -1967,7 +2020,7 @@ static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
}
}
if (tv_cutover && time(0) > start + tv_cutover) {
if (tv_cutover && time(NULL) > start + tv_cutover) {
tv_cutover = 0;
if (is_https) {
tv_use = tv_https_later;
@ -2176,8 +2229,8 @@ void check_openssl(void) {
}
last_check = now;
if (time(0) > last_waitall + 150) {
last_waitall = time(0);
if (time(NULL) > last_waitall + 150) {
last_waitall = time(NULL);
ssl_helper_pid(0, -2); /* waitall */
}

@ -13,6 +13,8 @@ extern int openssl_port_num;
extern int https_sock;
extern pid_t openssl_last_helper_pid;
extern void raw_xfer(int csock, int s_in, int s_out);
extern int openssl_present(void);
extern void openssl_init(void);
extern void openssl_port(void);

@ -697,9 +697,14 @@ char find_display[] =
"if [ \"X$1\" = \"X-n\" ]; then\n"
" showxauth=\"\"\n"
" shift\n"
"elif [ \"X$1\" = \"X-f\" ]; then\n"
"fi\n"
"if [ \"X$1\" = \"X-f\" ]; then\n"
" shift\n"
" showxauth=\"$1\"\n"
" if [ ! -r $1 ]; then\n"
" echo \"\"\n"
" exit 1\n"
" fi\n"
" export XAUTHORITY=\"$1\"\n"
" shift\n"
"fi\n"
"\n"
@ -724,24 +729,46 @@ char find_display[] =
"# Now try to match X DISPLAY to user:\n"
"\n"
"# who(1) output column 2:\n"
"display=`who | grep \"^${user}[ ][ ]*:[0-9]\" | head -1 | awk '{print $2}'`\n"
"display=`who | grep \"^${user}[ ][ ]*:[0-9]\" | head -1 \\\n"
" | awk '{print $2}'`\n"
"\n"
"if [ \"X$display\" = \"X\" ]; then\n"
" # who(1) output, last column:\n"
" display=`who | grep \"^${user}[ ]\" | awk '{print $NF}' | grep '(:[0-9]' | sed -e 's/[()]//g' | head -1`\n"
" if [ \"X$display\" = \"X\" ]; then\n"
" echo \"\" # failure\n"
" exit 1\n"
" fi\n"
" # who(1) output, last column:\n"
" display=`who | grep \"^${user}[ ]\" | awk '{print $NF}' \\\n"
" | grep '(:[0-9]' | sed -e 's/[()]//g' | head -1`\n"
" if [ \"X$display\" = \"X\" ]; then\n"
" if [ \"X$X11VNC_FINDDISPLAY_SKIP_XAUTH\" != \"X\" ]; then\n"
" echo \"\" # failure\n"
" exit 1\n"
" fi\n"
" # loop over xauth list items machine ^hostname/unix:N\n"
" host=`hostname | sed -e 's/\\..*$//'`\n"
" for d in `xauth list | awk '{print $1}' | grep /unix \\\n"
" | grep \"^${host}\" | sed -e 's/^.*://' | sort -n | uniq`\n"
" do\n"
" xdpyinfo -display \":$d\" >/dev/null 2>&1\n"
" if [ $? = 0 ]; then\n"
" # try again with no authority:\n"
" env XAUTHORITY=/dev/null xdpyinfo \\\n"
" -display \":$d\" >/dev/null 2>&1\n"
" # 0 means got in for free... skip it.\n"
" if [ $? != 0 ]; then\n"
" # keep it\n"
" display=\":$d\"\n"
" break\n"
" fi\n"
" fi\n"
" done\n"
" if [ \"X$display\" = \"X\" ]; then\n"
" echo \"\" # failure\n"
" exit 1\n"
" fi\n"
" fi\n"
"fi\n"
"\n"
"echo \"DISPLAY=$display\"\n"
"if [ \"X$showxauth\" != \"X\" ]; then\n"
" if [ \"X$showxauth\" = \"X1\" ]; then\n"
" xauth extract - \"$display\" 2>/dev/null\n"
" else\n"
" xauth -f \"$showxauth\" extract - \"$display\" 2>/dev/null\n"
" fi\n"
" xauth extract - \"$display\" 2>/dev/null\n"
"fi\n"
"\n"
"exit 0\n"

@ -310,6 +310,8 @@ Permissions
=0S dontdisconnect
=SQA deny_all
timeout:
grabkbd
grabptr
=GAL LOFF
Tuning

@ -321,6 +321,8 @@ char gui_code[] = "";
" =0S dontdisconnect\n"
" =SQA deny_all\n"
" timeout:\n"
" grabkbd\n"
" grabptr\n"
" =GAL LOFF\n"
"\n"
"Tuning\n"

@ -70,6 +70,7 @@ rfbClientPtr unixpw_client = NULL;
int keep_unixpw = 0;
char *keep_unixpw_user = NULL;
char *keep_unixpw_pass = NULL;
char *keep_unixpw_opts = NULL;
static int in_login = 0, in_passwd = 0, tries = 0;
static int char_row = 0, char_col = 0;
@ -398,7 +399,7 @@ int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size) {
}
}
/* unixpw */
if (no_external_cmds) {
if (no_external_cmds || !cmd_ok("unixpw")) {
rfbLog("su_verify: cannot run external commands.\n");
clean_up_exit(1);
}
@ -789,50 +790,54 @@ static void unixpw_verify(char *user, char *pass) {
int x, y;
char li[] = "Login incorrect";
char log[] = "login: ";
char *colon = NULL;
if (db) fprintf(stderr, "unixpw_verify: '%s' '%s'\n", user, db > 1 ? pass : "********");
rfbLog("unixpw_verify: %s\n", user);
colon = strchr(user, ':');
if (colon) {
*colon = '\0';
rfbLog("unixpw_verify: colon: %s\n", user);
}
if (unixpw_nis) {
if (crypt_verify(user, pass)) {
unixpw_accept(user);
if (keep_unixpw) {
keep_unixpw_user = strdup(user);
keep_unixpw_pass = strdup(pass);
if (colon) {
keep_unixpw_opts = strdup(colon+1);
} else {
keep_unixpw_opts = strdup("");
}
}
if (colon) *colon = ':';
return;
} else {
rfbLog("unixpw_verify: crypt_verify login for %s failed.\n", user);
usleep(3000*1000);
}
} else if (0) {
char buf[8192];
int n = 8000;
int res = su_verify(user, pass, "/home/runge/wallycom yegg 33", buf, &n);
fprintf(stderr, "su_verify ret: n=%d ", n);
write(2, buf, n);
if (res) {
unixpw_accept(user);
if (keep_unixpw) {
keep_unixpw_user = strdup(user);
keep_unixpw_pass = strdup(pass);
}
return;
}
rfbLog("unixpw_verify: su_verify login for %s failed.\n", user);
} else {
if (su_verify(user, pass, NULL, NULL, NULL)) {
unixpw_accept(user);
if (keep_unixpw) {
keep_unixpw_user = strdup(user);
keep_unixpw_pass = strdup(pass);
if (colon) {
keep_unixpw_opts = strdup(colon+1);
} else {
keep_unixpw_opts = strdup("");
}
}
if (colon) *colon = ':';
return;
}
rfbLog("unixpw_verify: su_verify login for %s failed.\n", user);
}
if (colon) *colon = ':';
if (tries < 2) {
char_row++;
@ -856,7 +861,7 @@ if (db) fprintf(stderr, "unixpw_verify: '%s' '%s'\n", user, db > 1 ? pass : "***
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0);
}
unixpw_last_try_time = time(0);
unixpw_last_try_time = time(NULL);
unixpw_keystroke(0, 0, 2);
tries++;
} else {
@ -902,6 +907,10 @@ void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init) {
free(keep_unixpw_pass);
keep_unixpw_pass = NULL;
}
if (keep_unixpw_opts) {
free(keep_unixpw_opts);
keep_unixpw_opts = NULL;
}
return;
}
@ -988,7 +997,12 @@ void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init) {
return;
}
#if 0
user[u_cnt++] = keystr[0];
#else
user[u_cnt++] = (char) keysym;
keystr[0] = (char) keysym;
#endif
x = text_x();
y = text_y();

@ -18,5 +18,6 @@ extern rfbClientPtr unixpw_client;
extern int keep_unixpw;
extern char *keep_unixpw_user;
extern char *keep_unixpw_pass;
extern char *keep_unixpw_opts;
#endif /* _X11VNC_UNIXPW_H */

@ -46,7 +46,7 @@ void check_switched_user(void) {
static int did_solid = 0;
static int did_dummy = 0;
int delay = 15;
time_t now = time(0);
time_t now = time(NULL);
if (unixpw_in_progress) return;
@ -675,7 +675,7 @@ static int switch_user_env(uid_t uid, char *name, char *home, int fb_mode) {
static void try_to_switch_users(void) {
static time_t last_try = 0;
time_t now = time(0);
time_t now = time(NULL);
char *users, *p;
if (getuid() && geteuid()) {
@ -934,7 +934,7 @@ void check_new_passwds(void) {
}
if (unixpw_in_progress) return;
now = time(0);
now = time(NULL);
if (now > last_check + 1) {
if (read_passwds(passwdfile)) {
install_passwds();
@ -1029,16 +1029,106 @@ static void handle_one_http_request(void) {
}
}
void user_supplied_opts(char *opts) {
char *p, *str;
char *allow[] = {
"skip-display", "skip-auth", "skip-shared",
"scale", "scale_cursor", "solid", "id", "clear_mods",
"clear_keys", "repeat", "speeds",
NULL
};
if (getenv("X11VNC_NO_UNIXPW_OPTS")) {
return;
}
str = strdup(opts);
p = strtok(str, ",");
while (p) {
char *q;
int i, n, m, ok = 0;
i = 0;
while (allow[i] != NULL) {
if (strstr(allow[i], "skip-")) {
i++;
continue;
}
if (strstr(p, allow[i]) == p) {
ok = 1;
break;
}
i++;
}
if (! ok && sscanf(p, "%d/%d", &n, &m) == 2) {
if (scale_str) free(scale_str);
scale_str = strdup(p);
} else if (ok) {
if (strstr(p, "display=") == p) {
if (use_dpy) free(use_dpy);
use_dpy = strdup(p + strlen("display="));
} else if (strstr(p, "auth=") == p) {
if (auth_file) free(auth_file);
auth_file = strdup(p + strlen("auth="));
} else if (strstr(p, "scale=") == p) {
if (scale_str) free(scale_str);
scale_str = strdup(p + strlen("scale="));
} else if (strstr(p, "scale_cursor=") == p) {
if (scale_cursor_str) free(scale_cursor_str);
scale_cursor_str = strdup(p +
strlen("scale_cursor="));
} else if (!strcmp(p, "shared")) {
shared = 1;
} else if (!strcmp(p, "solid")) {
use_solid_bg = 1;
if (!solid_str) {
solid_str = strdup(solid_default);
}
} else if (strstr(p, "solid=") == p) {
use_solid_bg = 1;
if (solid_str) free(solid_str);
solid_str = strdup(p + strlen("solid="));
} else if (strstr(p, "id=") == p) {
unsigned long win;
q = p + strlen("id=");
if (strcmp(q, "pick")) {
if (scan_hexdec(q, &win)) {
subwin = win;
}
}
} else if (!strcmp(p, "clear_mods")) {
clear_mods = 1;
} else if (!strcmp(p, "clear_keys")) {
clear_mods = 2;
} else if (!strcmp(p, "repeat")) {
no_autorepeat = 0;
} else if (strstr(p, "speeds=") == p) {
if (speeds_str) free(speeds_str);
speeds_str = strdup(p + strlen("speeds="));
q = speeds_str;
while (*q != '\0') {
if (*q == '-') {
*q = ',';
}
q++;
}
}
}
p = strtok(NULL, ",");
}
free(str);
}
extern char find_display[];
static XImage ximage_struct;
int wait_for_client(int *argc, char** argv, int http) {
static XImage ximage_struct;
XImage* fb_image;
int w = 640, h = 480, b = 32;
int w0, h0, i;
int chg_raw_fb = 0;
char *str, *q, *p;
char *cmd = NULL;
int w0, h0, i, chg_raw_fb = 0;
char *str, *q, *p, *cmd = NULL;
int db = 0;
char tmp[] = "/tmp/x11vnc-find_display.XXXXXX";
int tmp_fd = -1, dt = 0;
@ -1047,11 +1137,11 @@ int wait_for_client(int *argc, char** argv, int http) {
return 0;
}
for (i=0; i< *argc; i++) {
for (i=0; i < *argc; i++) {
if (!strcmp(argv[i], "-desktop")) {
dt = 1;
}
if (0) fprintf(stderr, "args %d %s\n", i, argv[i]);
if (1) fprintf(stderr, "args %d %s\n", i, argv[i]);
}
str = strdup(use_dpy);
@ -1085,7 +1175,7 @@ int wait_for_client(int *argc, char** argv, int http) {
if (db) fprintf(stderr, "str: %s\n", str);
if (strstr(str, "cmd=") == str) {
if (no_external_cmds) {
if (no_external_cmds || !cmd_ok("WAIT")) {
rfbLog("wait_for_client external cmds not allowed:"
" %s\n", use_dpy);
clean_up_exit(1);
@ -1127,7 +1217,7 @@ int wait_for_client(int *argc, char** argv, int http) {
if (! dt) {
char *s;
argv[*argc] = strdup("-desktop");
(*argc)++;
*argc = (*argc) + 1;
if (cmd) {
char *q;
@ -1141,18 +1231,27 @@ int wait_for_client(int *argc, char** argv, int http) {
}
rfb_desktop_name = strdup(s);
argv[*argc] = s;
(*argc)++;
*argc = (*argc) + 1;
}
initialize_allowed_input();
if (! multiple_cursors_mode) {
multiple_cursors_mode = strdup("default");
}
initialize_cursors_mode();
initialize_screen(argc, argv, fb_image);
initialize_signals();
if (!strcmp(cmd, "HTTPONCE")) {
if (! raw_fb) {
chg_raw_fb = 1;
/* kludge to get RAWFB_RET with dpy == NULL guards */
raw_fb = (char *) 0x1;
}
if (cmd && !strcmp(cmd, "HTTPONCE")) {
handle_one_http_request();
clean_up_exit(0);
}
@ -1161,12 +1260,6 @@ int wait_for_client(int *argc, char** argv, int http) {
http_connections(1);
}
if (! raw_fb) {
chg_raw_fb = 1;
/* kludge to get RAWFB_RET with dpy == NULL guards */
raw_fb = "null";
}
if (cmd && unixpw) {
keep_unixpw = 1;
}
@ -1176,12 +1269,15 @@ int wait_for_client(int *argc, char** argv, int http) {
}
while (1) {
if (! use_threads) {
rfbPE(-1);
if (shut_down) {
clean_up_exit(0);
}
if (use_openssl) {
check_openssl();
}
if (! use_threads) {
rfbPE(-1);
}
if (! screen || ! screen->clientHead) {
usleep(100 * 1000);
continue;
@ -1196,6 +1292,9 @@ int wait_for_client(int *argc, char** argv, int http) {
clean_up_exit(1);
}
while (1) {
if (shut_down) {
clean_up_exit(0);
}
if (! use_threads) {
rfbPE(-1);
}
@ -1238,7 +1337,6 @@ int wait_for_client(int *argc, char** argv, int http) {
char line[18000];
memset(line, 0, 18000);
if (0) unixpw_msg("Looking up DISPLAY", 0);
if (keep_unixpw_user && keep_unixpw_pass) {
n = 18000;
@ -1329,7 +1427,6 @@ if (db) write(2, line, n); write(2, "\n", 1);
if (*q == '\n' || *q == '\r') *q = '\0';
q++;
}
if (db) fprintf(stderr, "use_dpy: %s n: %d\n", use_dpy, n);
if (line2[0] != '\0') {
if (strstr(line2, "XAUTHORITY=") == line2) {
q = line2;
@ -1360,6 +1457,9 @@ if (db) fprintf(stderr, "xauth_raw_len: %d\n", n);
if (chg_raw_fb) {
raw_fb = NULL;
}
if (unixpw && keep_unixpw_opts && keep_unixpw_opts[0] != '\0') {
user_supplied_opts(keep_unixpw_opts);
}
return 1;
}

@ -2807,7 +2807,7 @@ static int try_copyrect(Window frame, int x, int y, int w, int h, int dx, int dy
* it for now by CopyRect-ing the *whole* on-screen
* rectangle (whether obscured or not!)
*/
if (time(0) > dt_bad_check + 5) {
if (time(NULL) > dt_bad_check + 5) {
char *dt = guess_desktop();
if (!strcmp(dt, "kde")) {
dt_bad = 1;
@ -2816,7 +2816,7 @@ static int try_copyrect(Window frame, int x, int y, int w, int h, int dx, int dy
} else {
dt_bad = 0;
}
dt_bad_check = time(0);
dt_bad_check = time(NULL);
}
if (clipshift) {
@ -3746,7 +3746,7 @@ if (db) fprintf(stderr, "send_copyrect: %d\n", sent_copyrect);
* save the stack list, perhaps the user has
* paused with button down.
*/
last_save_stacklist = time(0);
last_save_stacklist = time(NULL);
} else {
stack_list_num = 0;
}
@ -4126,7 +4126,7 @@ static void check_user_input4(double dt, double dtr, int tile_diffs) {
sscanf(p, "%lf,%lf,%lf,%lf", &dt_cut, &Tfac_r, &Tfac_v, &Tfac_n);
}
first = 0;
ssec = time(0);
ssec = time(NULL);
if (dtr) {} /* unused vars warning: */
}

@ -51,7 +51,7 @@ char *choose_title(char *display);
/*
* routine to keep 0 <= i < n, should use in more places...
* routine to keep 0 <= i < n
*/
int nfix(int i, int n) {
if (i < 0) {
@ -120,7 +120,7 @@ void uppercase(char *str) {
char *lblanks(char *str) {
char *p = str;
while (*p) {
while (*p != '\0') {
if (! isspace(*p)) {
break;
}
@ -150,6 +150,9 @@ int scan_hexdec(char *str, unsigned long *num) {
int parse_geom(char *str, int *wp, int *hp, int *xp, int *yp, int W, int H) {
int w, h, x, y;
if (! str) {
return 0;
}
/* handle +/-x and +/-y */
if (sscanf(str, "%dx%d+%d+%d", &w, &h, &x, &y) == 4) {
;
@ -176,10 +179,13 @@ int parse_geom(char *str, int *wp, int *hp, int *xp, int *yp, int W, int H) {
void set_env(char *name, char *value) {
char *str;
if (!value) {
if (! name) {
return;
}
if (! value) {
value = "";
}
str = (char *) malloc(strlen(name)+strlen(value)+2);
str = (char *) malloc(strlen(name) + 1 + strlen(value) + 1);
sprintf(str, "%s=%s", name, value);
putenv(str);
}
@ -277,6 +283,7 @@ char *this_host(void) {
char host[MAXN];
#if LIBVNCSERVER_HAVE_GETHOSTNAME
if (gethostname(host, MAXN) == 0) {
host[MAXN-1] = '\0';
return strdup(host);
}
#endif
@ -286,8 +293,8 @@ char *this_host(void) {
int match_str_list(char *str, char **list) {
int i = 0, matched = 0;
if (! list) {
return matched;
if (! str || ! list) {
return 0;
}
while (list[i] != NULL) {
if (!strcmp(list[i], "*")) {
@ -304,9 +311,14 @@ int match_str_list(char *str, char **list) {
char **create_str_list(char *cslist) {
int i, n;
char *p, *str = strdup(cslist);
char *p, *str;
char **list = NULL;
if (! cslist) {
return NULL;
}
str = strdup(cslist);
n = 1;
p = str;
while (*p != '\0') {
@ -316,7 +328,8 @@ char **create_str_list(char *cslist) {
p++;
}
list = (char **) malloc((n+1)*sizeof(char *));
/* the extra last one holds NULL */
list = (char **) malloc( (n+1)*sizeof(char *) );
for(i=0; i < n+1; i++) {
list[i] = NULL;
}
@ -427,6 +440,10 @@ double rect_overlap(int x1, int y1, int x2, int y2, int X1, int Y1,
a = nabs((x2 - x1) * (y2 - y1));
A = nabs((X2 - X1) * (Y2 - Y1));
if (a == 0 || A == 0) {
return 0.0;
}
r = sraRgnCreateRect(x1, y1, x2, y2);
R = sraRgnCreateRect(X1, Y1, X2, Y2);
@ -455,6 +472,8 @@ double rect_overlap(int x1, int y1, int x2, int y2, int X1, int Y1,
*/
char *choose_title(char *display) {
static char title[(MAXN+10)];
memset(title, 0, MAXN+10);
strcpy(title, "x11vnc");
if (display == NULL) {
@ -465,16 +484,20 @@ char *choose_title(char *display) {
}
title[0] = '\0';
if (display[0] == ':') {
if (this_host() != NULL) {
strncpy(title, this_host(), MAXN - strlen(title));
char *th = this_host();
if (th != NULL) {
strncpy(title, th, MAXN - strlen(title));
}
}
strncat(title, display, MAXN - strlen(title));
if (subwin && valid_window(subwin, NULL, 0)) {
char *name;
if (dpy && XFetchName(dpy, subwin, &name)) {
strncat(title, " ", MAXN - strlen(title));
strncat(title, name, MAXN - strlen(title));
if (subwin && dpy && valid_window(subwin, NULL, 0)) {
char *name = NULL;
if (XFetchName(dpy, subwin, &name)) {
if (name) {
strncat(title, " ", MAXN - strlen(title));
strncat(title, name, MAXN - strlen(title));
free(name);
}
}
}
return title;

@ -1090,7 +1090,7 @@ static char *guess_via_v4l_info(char *dev, int *fd) {
if (*fd) {}
/* v4l-info */
if (no_external_cmds) {
if (no_external_cmds || !cmd_ok("v4l-info")) {
rfbLog("guess_via_v4l_info: cannot run external "
"command: v4l-info\n");
return NULL;

@ -305,7 +305,7 @@ int pick_windowid(unsigned long *num) {
set_env("DISPLAY", use_dpy);
}
/* id */
if (no_external_cmds) {
if (no_external_cmds || !cmd_ok("id")) {
rfbLogEnable(1);
rfbLog("cannot run external commands in -nocmds mode:\n");
rfbLog(" \"%s\"\n", "xwininfo");

@ -2,7 +2,7 @@
.TH X11VNC "1" "June 2006" "x11vnc " "User Commands"
.SH NAME
x11vnc - allow VNC connections to real X11 displays
version: 0.8.2, lastmod: 2006-06-12
version: 0.8.2, lastmod: 2006-06-18
.SH SYNOPSIS
.B x11vnc
[OPTION]...
@ -474,6 +474,32 @@ users to move the mouse. This option is ignored when
a global \fB-viewonly\fR is in effect (all input is discarded
in that case).
.PP
\fB-grabkbd\fR
.IP
When VNC viewers are connected, attempt to the grab the
keyboard so someone sitting at the physical display
is not able to enter keystrokes. This method uses
.IR XGrabKeyboard (3X11)
and so it is not secure and does not
rule out the person at the physical display injecting
keystrokes by flooding the server with them, grabbing
the keyboard himself, etc. Some degree of cooperation
from the person at the display is assumed.
.PP
\fB-grabptr\fR
.IP
As \fB-grabkbd,\fR but for the mouse pointer using
.IR XGrabPointer (3X11).
Unfortunately due to the way the X
server works, the mouse can still be moved around by the
user at the physical display, but he will not be able to
change window focus with it. Also some window managers
that call
.IR XGrabServer (3X11)
for resizes, etc, will
act on the local user's input. Again, some degree of
cooperation from the person at the display is assumed.
.PP
\fB-viewpasswd\fR \fIstring\fR
.IP
Supply a 2nd password for view-only logins. The \fB-passwd\fR
@ -704,7 +730,25 @@ In the case of \fB-unixpw,\fR then the above command is run
as the user who just authenticated via the login and
password prompt.
.IP
Thus the combination of \fB-display\fR WAIT:cmd=... and
Also in the case of \fB-unixpw,\fR the user logging in can
place a colon at the end of his username and supply
a few options: scale=, scale_cursor=, solid, id=,
clear_mods, clear_keys, repeat, or speeds= separated
by commas if there is more than one. After the user
logs in successfully, these options will be applied to
the VNC screen. For example,
.IP
login: fred:scale=3/4,repeat
Password: ...
.IP
for convenience m/n implies scale= e.g. fred:3/4
To disable this set the environment variable
X11VNC_NO_UNIXPW_OPTS=1. To set any other options,
the user can use the gui (x11vnc \fB-gui\fR connect) or the
remote control method (x11vnc \fB-R\fR opt:val) during his
VNC session.
.IP
So the combination of \fB-display\fR WAIT:cmd=... and
\fB-unixpw\fR allows automatic pairing of an unix
authenticated VNC user with his desktop. This could
be very useful on SunRays and also any system where
@ -738,7 +782,7 @@ by client web browsers. For example:
5815 stream tcp nowait root /usr/sbin/tcpd .../x11vnc \\
\fB-inetd\fR \fB-q\fR \fB-http_ssl\fR \fB-display\fR WAIT:cmd=HTTPONCE
.IP
Is used in the Apache SSL-portal example (see FAQ).
It is used in the Apache SSL-portal example (see FAQ).
.IP
Finally, one can insert a geometry between colons,
e.g. WAIT:1280x1024:... to set the size of the display
@ -1629,6 +1673,14 @@ Use \fIfilename\fR instead of $HOME/.x11vncrc for rc file.
.IP
Do not process any .x11vncrc file for options.
.PP
\fB-env\fR \fIVAR=VALUE\fR
.IP
Set the environment variable 'VAR' to value 'VALUE'
at x11vnc startup. This is a convenience utility to
avoid shell script wrappers, etc. to set the env. var.
You may specify as many of these as needed on the
command line.
.PP
\fB-h,\fR \fB-help\fR
.IP
Print this help text.
@ -3222,6 +3274,14 @@ lookup disable \fB-nolookup\fR mode.
.IP
input:str set \fB-input\fR to "str", empty to disable.
.IP
grabkbd enable \fB-grabkbd\fR mode.
.IP
nograbkbd disable \fB-grabkbd\fR mode.
.IP
grabptr enable \fB-grabptr\fR mode.
.IP
nograbptr disable \fB-grabptr\fR mode.
.IP
client_input:str set the K, M, B \fB-input\fR on a per-client
basis. select which client as for
disconnect, e.g. client_input:host:MB
@ -3653,13 +3713,14 @@ nowf wirecopyrect wcr nowirecopyrect nowcr scr_area
scr_skip scr_inc scr_keys scr_term scr_keyrepeat
scr_parms scrollcopyrect scr noscrollcopyrect noscr
fixscreen noxrecord xrecord reset_record pointer_mode
pm input_skip input client_input speeds wmdt
debug_pointer dp nodebug_pointer nodp debug_keyboard
dk nodebug_keyboard nodk deferupdate defer wait_ui
wait_bog nowait_bog slow_fb wait readtimeout nap nonap
sb screen_blank fbpm nofbpm fs gaps grow fuzz snapfb
nosnapfb rawfb progressive rfbport http nohttp httpport
httpdir enablehttpproxy noenablehttpproxy alwaysshared
pm input_skip input grabkbd nograbkbd grabptr
nograbptr client_input speeds wmdt debug_pointer dp
nodebug_pointer nodp debug_keyboard dk nodebug_keyboard
nodk deferupdate defer wait_ui wait_bog nowait_bog
slow_fb wait readtimeout nap nonap sb screen_blank
fbpm nofbpm fs gaps grow fuzz snapfb nosnapfb rawfb
progressive rfbport http nohttp httpport httpdir
enablehttpproxy noenablehttpproxy alwaysshared
noalwaysshared nevershared noalwaysshared dontdisconnect
nodontdisconnect desktop debug_xevents nodebug_xevents
debug_xevents debug_xdamage nodebug_xdamage
@ -3770,6 +3831,20 @@ No external commands (e.g.
)
will be run.
.PP
\fB-allowedcmds\fR \fIlist\fR
.IP
\fIlist\fR contains a comma separated list of the only
external commands that can be run. The full list of
associated options is:
.IP
stunnel, ssl, unixpw, WAIT, id, accept, afteraccept,
gone, pipeinput, v4l-info, rawfb-setup, dt, gui,
storepasswd, crash.
.IP
See each option's help to learn the associated external
command. Note that the \fB-nocmds\fR option takes precedence
and disables all external commands.
.PP
\fB-deny_all\fR
.IP
For use with \fB-remote\fR nodeny: start out denying all

@ -211,7 +211,7 @@ static void check_cursor_changes(void) {
static void record_last_fb_update(void) {
static int rbs0 = -1;
static time_t last_call = 0;
time_t now = time(0);
time_t now = time(NULL);
int rbs = -1;
rfbClientIteratorPtr iter;
rfbClientPtr cl;
@ -399,7 +399,7 @@ if (0 && dt > 0.0) fprintf(stderr, "dt: %.5f %.4f\n", dt, dnow() - x11vnc_start)
static void watch_loop(void) {
int cnt = 0, tile_diffs = 0, skip_pe = 0;
double tm, dtr, dt = 0.0;
time_t start = time(0);
time_t start = time(NULL);
if (use_threads) {
rfbRunEventLoop(screen, -1, TRUE);
@ -489,7 +489,7 @@ if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret);
}
if (first_conn_timeout < 0) {
start = time(0);
start = time(NULL);
first_conn_timeout = -first_conn_timeout;
}
}
@ -497,7 +497,7 @@ if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret);
if (! screen || ! screen->clientHead) {
/* waiting for a client */
if (first_conn_timeout) {
if (time(0) - start > first_conn_timeout) {
if (time(NULL) - start > first_conn_timeout) {
rfbLog("No client after %d secs.\n",
first_conn_timeout);
shut_down = 1;
@ -1252,7 +1252,7 @@ static void store_homedir_passwd(char *file) {
str2[0] = '\0';
/* storepasswd */
if (no_external_cmds) {
if (no_external_cmds || !cmd_ok("storepasswd")) {
fprintf(stderr, "-nocmds cannot be used with -storepasswd\n");
exit(1);
}
@ -1376,6 +1376,10 @@ int main(int argc, char* argv[]) {
immediate_switch_user(argc, argv);
}
for (i=0; i < 2048; i++) {
argv_vnc[i] = NULL;
}
argv_vnc[0] = strdup(argv[0]);
program_name = strdup(argv[0]);
program_pid = (int) getpid();
@ -1431,6 +1435,30 @@ int main(int argc, char* argv[]) {
}
}
/*
* do a quick check for -env parameters
*/
for (i=1; i < argc; i++) {
char *p, *q;
arg = argv[i];
if (strstr(arg, "--") == arg) {
arg++;
}
if (!strcmp(arg, "-env")) {
CHECK_ARGC
p = strdup(argv[++i]);
q = strchr(p, '=');
if (! q) {
fprintf(stderr, "no -env '=' found: %s\n", p);
exit(1);
} else {
*q = '\0';
}
set_env(p, q+1);
free(p);
}
}
for (i=1; i < argc; i++) {
/* quick-n-dirty --option handling. */
arg = argv[i];
@ -1569,6 +1597,10 @@ int main(int argc, char* argv[]) {
} else if (!strcmp(arg, "-input")) {
CHECK_ARGC
allowed_input_str = strdup(argv[++i]);
} else if (!strcmp(arg, "-grabkbd")) {
grab_kbd = 1;
} else if (!strcmp(arg, "-grabptr")) {
grab_ptr = 1;
} else if (!strcmp(arg, "-viewpasswd")) {
vpw_loc = i;
CHECK_ARGC
@ -1781,6 +1813,8 @@ int main(int argc, char* argv[]) {
i++; /* done above */
} else if (!strcmp(arg, "-norc")) {
; /* done above */
} else if (!strcmp(arg, "-env")) {
i++; /* done above */
} else if (!strcmp(arg, "-h") || !strcmp(arg, "-help")) {
print_help(0);
} else if (!strcmp(arg, "-?") || !strcmp(arg, "-opts")) {
@ -2181,6 +2215,9 @@ int main(int argc, char* argv[]) {
more_safe = 1;
} else if (!strcmp(arg, "-nocmds")) {
no_external_cmds = 1;
} else if (!strcmp(arg, "-allowedcmds")) {
CHECK_ARGC
allowed_external_cmds = strdup(argv[++i]);
} else if (!strcmp(arg, "-deny_all")) {
deny_all = 1;
} else if (!strcmp(arg, "-httpdir")) {
@ -3157,9 +3194,14 @@ int main(int argc, char* argv[]) {
initialize_screen(&argc_vnc, argv_vnc, fb0);
if (waited_for_client && fake_fb) {
free(fake_fb);
fake_fb = NULL;
if (waited_for_client) {
if (fake_fb) {
free(fake_fb);
fake_fb = NULL;
}
if (use_solid_bg && client_count) {
solid_bg(0);
}
}
if (! waited_for_client) {

@ -366,9 +366,9 @@ extern char *http_dir;
extern char vnc_desktop_name[];
extern char *main_fb; /* our copy of the X11 fb */
extern char *rfb_fb; /* same as main_fb unless transformation */
extern char *fake_fb; /* used under -padgeom */
extern char *snap_fb; /* used under -snapfb */
extern char *cmap8to24_fb; /* used under -8to24 */
extern char *fake_fb; /* used under -padgeom */
extern char *snap_fb; /* used under -snapfb */
extern char *cmap8to24_fb; /* used under -8to24 */
extern char *raw_fb;
extern char *raw_fb_addr;
extern int raw_fb_offset;

@ -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.2 lastmod: 2006-06-12";
char lastmod[] = "0.8.2 lastmod: 2006-06-18";
/* X display info */
@ -68,11 +68,11 @@ int raw_fb_seek = 0;
int raw_fb_fd = -1;
int raw_fb_back_to_X = 0; /* kludge for testing rawfb -> X */
int rfb_bytes_per_line;
int main_bytes_per_line;
unsigned long main_red_mask, main_green_mask, main_blue_mask;
unsigned short main_red_max, main_green_max, main_blue_max;
unsigned short main_red_shift, main_green_shift, main_blue_shift;
int rfb_bytes_per_line = 0;
int main_bytes_per_line = 0;
unsigned long main_red_mask = 0, main_green_mask = 0, main_blue_mask = 0;
unsigned short main_red_max = 0, main_green_max = 0, main_blue_max = 0;
unsigned short main_red_shift = 0, main_green_shift = 0, main_blue_shift = 0;
/* scaling parameters */
char *scale_str = NULL;
@ -123,8 +123,8 @@ int client_count = 0;
int clients_served = 0;
/* more transient kludge variables: */
int cursor_x, cursor_y; /* x and y from the viewer(s) */
int button_change_x, button_change_y;
int cursor_x = 0, cursor_y = 0; /* x and y from the viewer(s) */
int button_change_x = 0, button_change_y = 0;
int got_user_input = 0;
int got_pointer_input = 0;
int got_pointer_calls = 0;

@ -369,7 +369,7 @@ if (0) XEventsQueued(dpy, QueuedAfterFlush);
"/direct %d/%d/%d/%d\n", call, dt, tm - x11vnc_start, ecount,
dcount, ccount, xdamage_direct_count);
}
now = time(0);
now = time(NULL);
if (! last_rpt) {
last_rpt = now;
}

@ -16,6 +16,8 @@
/* XXX CHECK BEFORE RELEASE */
int grab_buster = 0;
int grab_kbd = 0;
int grab_ptr = 0;
int sync_tod_delay = 3;
void initialize_vnc_connect_prop(void);
@ -187,7 +189,7 @@ static void get_prop(char *str, int len, Atom prop) {
static void bust_grab(int reset) {
static int bust_count = 0;
static time_t last_bust = 0;
time_t now = time(0);
time_t now = time(NULL);
KeyCode key;
int button, x, y, nb;
@ -272,7 +274,7 @@ static void bust_grab(int reset) {
XTestFakeKeyEvent_wr(dpy, key, False, CurrentTime);
}
XFlush_wr(dpy);
last_bust = time(0);
last_bust = time(NULL);
}
typedef struct _grabwatch {
@ -294,7 +296,7 @@ static int process_watch(char *str, int parent, int db) {
unsigned long xtime;
static grabwatch_t watches[GRABWATCH];
static int first = 1;
time_t now = time(0);
time_t now = time(NULL);
static time_t last_bust = 0;
int too_long, problems = 0;
@ -604,7 +606,7 @@ void sync_tod_with_servertime(void) {
void check_keycode_state(void) {
static time_t last_check = 0;
int delay = 10, noinput = 3;
time_t now = time(0);
time_t now = time(NULL);
if (! client_count) {
return;
@ -629,7 +631,7 @@ void check_keycode_state(void) {
void check_autorepeat(void) {
static time_t last_check = 0;
time_t now = time(0);
time_t now = time(NULL);
int autorepeat_is_on, autorepeat_initially_on, idle_timeout = 300;
static int idle_reset = 0;
@ -710,7 +712,7 @@ void check_xevents(int reset) {
static time_t last_init_check = 0;
static time_t last_sync = 0;
static time_t last_time_sync = 0;
time_t now = time(0);
time_t now = time(NULL);
static double last_request = 0.0;
XErrorHandler old_handler;

@ -4,6 +4,8 @@
/* -- xevents.h -- */
extern int grab_buster;
extern int grab_kbd;
extern int grab_ptr;
extern int sync_tod_delay;
extern void initialize_vnc_connect_prop(void);

@ -34,11 +34,11 @@ extern int known_xrandr_mode(char *s);
if (subwin) { \
static int last = 0; \
subwin_trap_count++; \
if (time(0) > last_subwin_trap + 60) { \
if (time(NULL) > last_subwin_trap + 60) { \
rfbLog("trapped GetImage xerror" \
" in SUBWIN mode. [%d]\n", \
subwin_trap_count); \
last_subwin_trap = time(0); \
last_subwin_trap = time(NULL); \
last = subwin_trap_count; \
} \
if (subwin_trap_count - last > 30) { \

@ -3,6 +3,7 @@
#include "x11vnc.h"
#include "xrecord.h"
#include "keyboard.h"
#include "xevents.h"
int xshm_present = 0;
int xtest_present = 0;
@ -601,8 +602,15 @@ void XTestFakeKeyEvent_wr(Display* dpy, KeyCode key, Bool down,
last_keyboard_keycode = key;
}
if (grab_kbd) {
XUngrabKeyboard(dpy, CurrentTime);
}
if (xtrap_input) {
XTRAP_FakeKeyEvent_wr(dpy, key, down, delay);
if (grab_kbd) {
adjust_grabs(1, 1);
}
return;
}
@ -616,6 +624,9 @@ void XTestFakeKeyEvent_wr(Display* dpy, KeyCode key, Bool down,
}
#if LIBVNCSERVER_HAVE_XTEST
XTestFakeKeyEvent(dpy, key, down, delay);
if (grab_kbd) {
adjust_grabs(1, 1);
}
if (debug_keyboard) {
upup_downdown_warning(key, down);
}
@ -648,8 +659,15 @@ void XTestFakeButtonEvent_wr(Display* dpy, unsigned int button, Bool is_press,
RAWFB_RET_VOID
if (grab_ptr) {
XUngrabPointer(dpy, CurrentTime);
}
if (xtrap_input) {
XTRAP_FakeButtonEvent_wr(dpy, button, is_press, delay);
if (grab_ptr) {
adjust_grabs(1, 1);
}
return;
}
@ -664,6 +682,9 @@ void XTestFakeButtonEvent_wr(Display* dpy, unsigned int button, Bool is_press,
#if LIBVNCSERVER_HAVE_XTEST
XTestFakeButtonEvent(dpy, button, is_press, delay);
#endif
if (grab_ptr) {
adjust_grabs(1, 1);
}
}
void XTRAP_FakeMotionEvent_wr(Display* dpy, int screen, int x, int y,
@ -690,8 +711,15 @@ void XTestFakeMotionEvent_wr(Display* dpy, int screen, int x, int y,
RAWFB_RET_VOID
if (grab_ptr) {
XUngrabPointer(dpy, CurrentTime);
}
if (xtrap_input) {
XTRAP_FakeMotionEvent_wr(dpy, screen, x, y, delay);
if (grab_ptr) {
adjust_grabs(1, 1);
}
return;
}
@ -702,6 +730,9 @@ void XTestFakeMotionEvent_wr(Display* dpy, int screen, int x, int y,
#if LIBVNCSERVER_HAVE_XTEST
XTestFakeMotionEvent(dpy, screen, x, y, delay);
#endif
if (grab_ptr) {
adjust_grabs(1, 1);
}
}
Bool XTestCompareCurrentCursorWithWindow_wr(Display* dpy, Window w) {

Loading…
Cancel
Save