x11vnc: -display WAIT:..., -users unixpw=, su_verify dpy command.

pull/1/head
runge 18 years ago
parent a60ee2ee9f
commit 1776a3a55f

@ -1,10 +1,13 @@
2006-06-08 Karl Runge <runge@karlrunge.com>
* prepare_x11vnc_dist.sh: to 0.8.2
2006-05-29 Steven Carr <scarr@jsa-usa.com> 2006-05-29 Steven Carr <scarr@jsa-usa.com>
* Identified and removed some memory leaks associated * Identified and removed some memory leaks associated
with the Encodings RRE, CoRRE, ZLIB, and Ultra. with the Encodings RRE, CoRRE, ZLIB, and Ultra.
* KeyboardLedState now has portable masks defined. * KeyboardLedState now has portable masks defined.
* rfb >= 3.7 Security Type Handler list would grow 1 * rfb >= 3.7 Security Type Handler list would grow 1
entry for each new client connection. entry for each new client connection.
2006-05-16 Steven Carr <scarr@jsa-usa.com> 2006-05-16 Steven Carr <scarr@jsa-usa.com>
* Statistics output now fits in 80-column output * Statistics output now fits in 80-column output
* Corrected Cursor Statistics reporting as messages * Corrected Cursor Statistics reporting as messages

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

@ -1,3 +1,8 @@
2006-06-08 Karl Runge <runge@karlrunge.com>
* x11vnc: XOpenDisplay wrapper for raw xauth data, -unixpw
su_verify() to run any cmd, -users unixpw= mode. -display WAIT:...
modes for delayed X display opening and dynamic choosing.
2006-06-03 Karl Runge <runge@karlrunge.com> 2006-06-03 Karl Runge <runge@karlrunge.com>
* x11vnc: -capslock and -skip_lockkeys options. map some Alt keys * x11vnc: -capslock and -skip_lockkeys options. map some Alt keys
to Latin under linuxfb. switch to new stats API. Handle more to Latin under linuxfb. switch to new stats API. Handle more

File diff suppressed because it is too large Load Diff

@ -155,7 +155,7 @@ void clean_up_exit (int ret) {
} }
#endif #endif
/* XXX rdpy_ctrl, etc. cannot close w/o blocking */ /* XXX rdpy_ctrl, etc. cannot close w/o blocking */
XCloseDisplay(dpy); XCloseDisplay_wr(dpy);
X_UNLOCK; X_UNLOCK;
fflush(stderr); fflush(stderr);
@ -311,6 +311,7 @@ static void crash_shell(void) {
crash_shell_help(); crash_shell_help();
} else if (*str == 's' && *(str+1) == '\0') { } else if (*str == 's' && *(str+1) == '\0') {
sprintf(cmd, "sh -c '(%s) &'", crash_stack_command1); sprintf(cmd, "sh -c '(%s) &'", crash_stack_command1);
/* crash */
if (no_external_cmds) { if (no_external_cmds) {
fprintf(stderr, "\nno_external_cmds=%d\n", fprintf(stderr, "\nno_external_cmds=%d\n",
no_external_cmds); no_external_cmds);

@ -448,6 +448,7 @@ static int run_user_command(char *cmd, rfbClientPtr client, char *mode) {
sprintf(str, "%d", client_count); sprintf(str, "%d", client_count);
set_env("RFB_CLIENT_COUNT", str); set_env("RFB_CLIENT_COUNT", str);
/* gone, accept, afteraccept */
if (no_external_cmds) { if (no_external_cmds) {
rfbLogEnable(1); rfbLogEnable(1);
rfbLog("cannot run external commands in -nocmds mode:\n"); rfbLog("cannot run external commands in -nocmds mode:\n");

@ -5,6 +5,7 @@
#include "win_utils.h" #include "win_utils.h"
#include "remote.h" #include "remote.h"
#include "cleanup.h" #include "cleanup.h"
#include "xwrappers.h"
#include "tkx11vnc.h" #include "tkx11vnc.h"
@ -229,15 +230,15 @@ if (0) fprintf(stderr, "run_gui: %s -- %d %d\n", gui_xdisplay, connect_to_x11vnc
} else { } else {
old_xauth = strdup(""); old_xauth = strdup("");
} }
dpy = XOpenDisplay(x11vnc_xdisplay); dpy = XOpenDisplay_wr(x11vnc_xdisplay);
if (! dpy && auth_file) { if (! dpy && auth_file) {
set_env("XAUTHORITY", auth_file); set_env("XAUTHORITY", auth_file);
dpy = XOpenDisplay(x11vnc_xdisplay); dpy = XOpenDisplay_wr(x11vnc_xdisplay);
} }
if (! dpy && ! x11vnc_xdisplay) { if (! dpy && ! x11vnc_xdisplay) {
/* worstest case */ /* worstest case */
x11vnc_xdisplay = strdup(":0"); x11vnc_xdisplay = strdup(":0");
dpy = XOpenDisplay(x11vnc_xdisplay); dpy = XOpenDisplay_wr(x11vnc_xdisplay);
} }
if (! dpy) { if (! dpy) {
rfbLog("gui: could not open x11vnc " rfbLog("gui: could not open x11vnc "
@ -310,7 +311,7 @@ if (0) fprintf(stderr, "run_gui: %s -- %d %d\n", gui_xdisplay, connect_to_x11vnc
set_env("X11VNC_CONNECT_FILE", client_connect_file); set_env("X11VNC_CONNECT_FILE", client_connect_file);
} }
if (dpy) { if (dpy) {
XCloseDisplay(dpy); XCloseDisplay_wr(dpy);
dpy = NULL; dpy = NULL;
} }
if (old_xauth) { if (old_xauth) {
@ -418,6 +419,7 @@ if (0) fprintf(stderr, "run_gui: %s -- %d %d\n", gui_xdisplay, connect_to_x11vnc
set_env("X11VNC_ICON_FONT", icon_mode_font); set_env("X11VNC_ICON_FONT", icon_mode_font);
} }
/* gui */
if (no_external_cmds) { if (no_external_cmds) {
fprintf(stderr, "cannot run external commands in -nocmds " fprintf(stderr, "cannot run external commands in -nocmds "
"mode:\n"); "mode:\n");
@ -576,20 +578,20 @@ void do_gui(char *opts, int sleep) {
fprintf(stderr, "starting gui, trying display: %s\n", fprintf(stderr, "starting gui, trying display: %s\n",
gui_xdisplay); gui_xdisplay);
} }
test_dpy = XOpenDisplay(gui_xdisplay); test_dpy = XOpenDisplay_wr(gui_xdisplay);
if (! test_dpy && auth_file) { if (! test_dpy && auth_file) {
if (getenv("XAUTHORITY") != NULL) { if (getenv("XAUTHORITY") != NULL) {
old_xauth = strdup(getenv("XAUTHORITY")); old_xauth = strdup(getenv("XAUTHORITY"));
} }
set_env("XAUTHORITY", auth_file); set_env("XAUTHORITY", auth_file);
test_dpy = XOpenDisplay(gui_xdisplay); test_dpy = XOpenDisplay_wr(gui_xdisplay);
} }
if (! test_dpy) { if (! test_dpy) {
if (! old_xauth && getenv("XAUTHORITY") != NULL) { if (! old_xauth && getenv("XAUTHORITY") != NULL) {
old_xauth = strdup(getenv("XAUTHORITY")); old_xauth = strdup(getenv("XAUTHORITY"));
} }
set_env("XAUTHORITY", ""); set_env("XAUTHORITY", "");
test_dpy = XOpenDisplay(gui_xdisplay); test_dpy = XOpenDisplay_wr(gui_xdisplay);
} }
if (! test_dpy) { if (! test_dpy) {
fprintf(stderr, "error: cannot connect to gui X DISPLAY: %s\n", fprintf(stderr, "error: cannot connect to gui X DISPLAY: %s\n",
@ -603,7 +605,7 @@ void do_gui(char *opts, int sleep) {
tray_manager_ok = 0; tray_manager_ok = 0;
} }
} }
XCloseDisplay(test_dpy); XCloseDisplay_wr(test_dpy);
if (start_x11vnc) { if (start_x11vnc) {

@ -69,7 +69,8 @@ void print_help(int mode) {
"-display disp X11 server display to connect to, usually :0. The X\n" "-display disp X11 server display to connect to, usually :0. The X\n"
" server process must be running on same machine and\n" " server process must be running on same machine and\n"
" support MIT-SHM. Equivalent to setting the DISPLAY\n" " support MIT-SHM. Equivalent to setting the DISPLAY\n"
" environment variable to \"disp\".\n" " environment variable to \"disp\". See the description\n"
" below of the \"-display WAIT:...\" extensions.\n"
"-auth file Set the X authority file to be \"file\", equivalent to\n" "-auth file Set the X authority file to be \"file\", equivalent to\n"
" setting the XAUTHORITY environment variable to \"file\"\n" " setting the XAUTHORITY environment variable to \"file\"\n"
" before startup. Same as -xauth file. See Xsecurity(7),\n" " before startup. Same as -xauth file. See Xsecurity(7),\n"
@ -298,7 +299,7 @@ void print_help(int mode) {
" and only loop 5 times.\n" " and only loop 5 times.\n"
"-timeout n Exit unless a client connects within the first n seconds\n" "-timeout n Exit unless a client connects within the first n seconds\n"
" after startup.\n" " after startup.\n"
"-inetd Launched by inetd(1): stdio instead of listening socket.\n" "-inetd Launched by inetd(8): stdio instead of listening socket.\n"
" Note: if you are not redirecting stderr to a log file\n" " Note: if you are not redirecting stderr to a log file\n"
" (via shell 2> or -o option) you MUST also specify the -q\n" " (via shell 2> or -o option) you MUST also specify the -q\n"
" option, otherwise the stderr goes to the viewer which\n" " option, otherwise the stderr goes to the viewer which\n"
@ -554,6 +555,62 @@ void print_help(int mode) {
" for any other modern environment. All of the -unixpw\n" " for any other modern environment. All of the -unixpw\n"
" options and contraints apply.\n" " options and contraints apply.\n"
"\n" "\n"
"-display WAIT:... A special usage mode for the normal -display option.\n"
" Useful with -unixpw, but can be used independently\n"
" of it. If the display string begins with WAIT: then\n"
" x11vnc waits until a VNC client connects before opening\n"
" the X display (or -rawfb device).\n"
"\n"
" This could be useful for delaying opening the display\n"
" for certain usage modes (say if x11vnc is started at\n"
" boot time and no X server is running or users logged\n"
" in yet).\n"
"\n"
" If the string is, e.g. WAIT:0.0 or WAIT:1, i.e. \"WAIT\"\n"
" in front of a normal X display, then that indicated\n"
" display is used. A more interesting case is like this:\n"
"\n"
" WAIT:cmd=/usr/local/bin/find_display\n"
"\n"
" in which case the command after \"cmd=\" is run to\n"
" dynamically work out the DISPLAY and optionally the\n"
" XAUTHORITY data. The first line of the command output\n"
" must be of the form DISPLAY=<xdisplay>. Any remaining\n"
" output is taken as XAUTHORITY data. It can be either\n"
" of the form XAUTHORITY=<file> or raw xauthority data for\n"
" the display (e.g. \"xauth extract - $DISPLAY\" output).\n"
"\n"
" In the case of -unixpw, then the above command is run\n"
" as the user who just authenticated via the login and\n"
" password prompt.\n"
"\n"
" Thus 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"
" multiple users share a given machine. The user does\n"
" not need to remember special ports or passwords set up\n"
" for his desktop and VNC.\n"
"\n"
" A nice way to use WAIT:cmd=... is out of inetd(8)\n"
" (it automatically forks a new x11vnc for each user).\n"
" You can have the x11vnc inetd spawned process run as,\n"
" say, root or nobody. When run as root (for either\n"
" inetd or display manager), you can also supply the\n"
" option \"-users unixpw=\" to have the x11vnc process\n"
" switch to the user as well. Note: there will be a 2nd\n"
" SSL helper process that will not switch, but it is only\n"
" encoding and decoding the stream at that point.\n"
"\n"
" As a special case, WAIT:cmd=FINDDISPLAY will run a\n"
" script that works on most Unixes to determine a user's\n"
" DISPLAY variable and xauthority data. this is TBD.\n"
"\n"
" Finally, one can insert a geometry between colons,\n"
" e.g. WAIT:1280x1024:... to set the size of the display\n"
" the VNC client first attaches to since some VNC viewers\n"
" will not automatically adjust to a new framebuffer size.\n"
"\n"
"-ssl [pem] Use the openssl library (www.openssl.org) to provide a\n" "-ssl [pem] Use the openssl library (www.openssl.org) to provide a\n"
" built-in encrypted SSL tunnel between VNC viewers and\n" " built-in encrypted SSL tunnel between VNC viewers and\n"
" x11vnc. This requires libssl support to be compiled\n" " x11vnc. This requires libssl support to be compiled\n"
@ -689,24 +746,24 @@ void print_help(int mode) {
" is attempted to be loaded. As a kludge, use a token\n" " is attempted to be loaded. As a kludge, use a token\n"
" like ../server-foo to load a server cert if you find\n" " like ../server-foo to load a server cert if you find\n"
" that necessary.\n" " that necessary.\n"
" \n" "\n"
" Use -ssldir to use a directory different from the\n" " Use -ssldir to use a directory different from the\n"
" ~/.vnc/certs default.\n" " ~/.vnc/certs default.\n"
" \n" "\n"
" Note that if the \"CA\" cert is loaded you do not need\n" " Note that if the \"CA\" cert is loaded you do not need\n"
" to load any of the certs that have been signed by it.\n" " to load any of the certs that have been signed by it.\n"
" You will need to load any additional self-signed certs\n" " You will need to load any additional self-signed certs\n"
" however.\n" " however.\n"
" \n" "\n"
" Examples:\n" " Examples:\n"
" x11vnc -ssl -sslverify CA\n" " x11vnc -ssl -sslverify CA\n"
" x11vnc -ssl -sslverify self:fred,self:jim\n" " x11vnc -ssl -sslverify self:fred,self:jim\n"
" x11vnc -ssl -sslverify CA,clients\n" " x11vnc -ssl -sslverify CA,clients\n"
" \n" "\n"
" Usually \"-sslverify CA\" is the most effective.\n" " Usually \"-sslverify CA\" is the most effective.\n"
" See the -sslGenCA and -sslGenCert options below for\n" " See the -sslGenCA and -sslGenCert options below for\n"
" how to set up and manage the CA framework.\n" " how to set up and manage the CA framework.\n"
" \n" "\n"
"\n" "\n"
"\n" "\n"
" NOTE: the following utilities, -sslGenCA, -sslGenCert,\n" " NOTE: the following utilities, -sslGenCA, -sslGenCert,\n"
@ -1092,7 +1149,7 @@ void print_help(int mode) {
" otherwise the client is rejected. See below for an\n" " otherwise the client is rejected. See below for an\n"
" extension to accept a client view-only.\n" " extension to accept a client view-only.\n"
"\n" "\n"
" If x11vnc is running as root (say from inetd(1) or from\n" " If x11vnc is running as root (say from inetd(8) or from\n"
" display managers xdm(1), gdm(1), etc), think about the\n" " display managers xdm(1), gdm(1), etc), think about the\n"
" security implications carefully before supplying this\n" " security implications carefully before supplying this\n"
" option (likewise for the -gone option).\n" " option (likewise for the -gone option).\n"
@ -1163,75 +1220,84 @@ void print_help(int mode) {
" Unlike -accept, the command return code is not\n" " Unlike -accept, the command return code is not\n"
" interpreted by x11vnc. Example: -gone 'xlock &'\n" " interpreted by x11vnc. Example: -gone 'xlock &'\n"
"\n" "\n"
"-users list If x11vnc is started as root (say from inetd(1) or from\n" "-users list If x11vnc is started as root (say from inetd(8) or from\n"
" display managers xdm(1), gdm(1), etc), then as soon\n" " display managers xdm(1), gdm(1), etc), then as soon\n"
" as possible after connections to the X display are\n" " as possible after connections to the X display are\n"
" established try to switch to one of the users in the\n" " established try to switch to one of the users in the\n"
" comma separated \"list\". If x11vnc is not running as\n" " comma separated \"list\". If x11vnc is not running as\n"
" root this option is ignored.\n" " root this option is ignored.\n"
" \n" "\n"
" Why use this option? In general it is not needed since\n" " Why use this option? In general it is not needed since\n"
" x11vnc is already connected to the X display and can\n" " x11vnc is already connected to the X display and can\n"
" perform its primary functions. The option was added\n" " perform its primary functions. The option was added\n"
" to make some of the *external* utility commands x11vnc\n" " to make some of the *external* utility commands x11vnc\n"
" occasionally runs work properly. In particular under\n" " occasionally runs work properly. In particular under\n"
" GNOME and KDE to implement the \"-solid color\" feature\n" " GNOME and KDE to implement the \"-solid color\" feature\n"
" external commands (gconftool-2 and dcop) must be run\n" " external commands (gconftool-2 and dcop) unfortunately\n"
" as the user owning the desktop session. Since this\n" " must be run as the user owning the desktop session.\n"
" option switches userid it also affects the userid used\n" " Since this option switches userid it also affects the\n"
" to run the processes for the -accept and -gone options.\n" " userid used to run the processes for the -accept and\n"
" It also affects the ability to read files for options\n" " -gone options. It also affects the ability to read\n"
" such as -connect, -allow, and -remap. Note that the\n" " files for options such as -connect, -allow, and -remap.\n"
" -connect file is also sometimes written to.\n" " Note that the -connect file is also sometimes written\n"
" \n" " to.\n"
" So be careful with this option since in many situations\n" "\n"
" So be careful with this option since in some situations\n"
" its use can decrease security.\n" " its use can decrease security.\n"
" \n" "\n"
" The switch to a user will only take place if the\n" " In general the switch to a user will only take place\n"
" display can still be successfully opened as that user\n" " if the display can still be successfully opened as that\n"
" (this is primarily to try to guess the actual owner\n" " user (this is primarily to try to guess the actual owner\n"
" of the session). Example: \"-users fred,wilma,betty\".\n" " of the session). Example: \"-users fred,wilma,betty\".\n"
" Note that a malicious user \"barney\" by quickly using\n" " Note that a malicious user \"barney\" by quickly using\n"
" \"xhost +\" when logging in may get x11vnc to switch\n" " \"xhost +\" when logging in may possibly get the x11vnc\n"
" to user \"fred\". What happens next?\n" " process to switch to user \"fred\". What happens next?\n"
" \n" "\n"
" Under display managers it may be a long time before\n" " Under display managers it may be a long time before\n"
" the switch succeeds (i.e. a user logs in). To make\n" " the switch succeeds (i.e. a user logs in). To instead\n"
" it switch immediately regardless if the display\n" " make it switch immediately regardless if the display\n"
" can be reopened prefix the username with the \"+\"\n" " can be reopened prefix the username with the \"+\"\n"
" character. E.g. \"-users +bob\" or \"-users +nobody\".\n" " character. E.g. \"-users +bob\" or \"-users +nobody\".\n"
"\n"
" The latter (i.e. switching immediately to user\n" " The latter (i.e. switching immediately to user\n"
" \"nobody\") is probably the only use of this option\n" " \"nobody\") is probably the only use of this option\n"
" that increases security.\n" " that increases security.\n"
" \n" "\n"
" In -unixpw mode, if \"-users unixpw=\" is supplied\n"
" then after a user authenticates himself via the\n"
" -unixpw mechanism, x11vnc will try to switch to that\n"
" user as though \"-users +username\" had been supplied.\n"
" If you want to limit which users this will be done for,\n"
" provide them as a comma separated list after \"unixpw=\"\n"
"\n"
" To immediately switch to a user *before* connections\n" " To immediately switch to a user *before* connections\n"
" to the X display are made or any files opened use the\n" " to the X display are made or any files opened use the\n"
" \"=\" character: \"-users =bob\". That user needs to\n" " \"=\" character: \"-users =bob\". That user needs to\n"
" be able to open the X display of course.\n" " be able to open the X display and any files of course.\n"
" \n" "\n"
" The special user \"guess=\" means to examine the utmpx\n" " The special user \"guess=\" means to examine the utmpx\n"
" database (see who(1)) looking for a user attached to\n" " database (see who(1)) looking for a user attached to\n"
" the display number (from DISPLAY or -display option)\n" " the display number (from DISPLAY or -display option)\n"
" and try him/her. To limit the list of guesses, use:\n" " and try him/her. To limit the list of guesses, use:\n"
" \"-users guess=bob,betty\".\n" " \"-users guess=bob,betty\".\n"
" \n" "\n"
" Even more sinister is the special user \"lurk=\" that\n" " Even more sinister is the special user \"lurk=\"\n"
" means to try to guess the DISPLAY from the utmpx login\n" " that means to try to guess the DISPLAY from the utmpx\n"
" database as well. So it \"lurks\" waiting for anyone\n" " login database as well. So it \"lurks\" waiting for\n"
" to log into an X session and then connects to it.\n" " anyone to log into an X session and then connects to it.\n"
" Specify a list of users after the = to limit which\n" " Specify a list of users after the = to limit which users\n"
" users will be tried. To enable a different searching\n" " will be tried. To enable a different searching mode, if\n"
" mode, if the first user in the list is something like\n" " the first user in the list is something like \":0\" or\n"
" \":0\" or \":0-2\" that indicates a range of DISPLAY\n" " \":0-2\" that indicates a range of DISPLAY numbers that\n"
" numbers that will be tried (regardless of whether\n" " will be tried (regardless of whether they are in the\n"
" they are in the utmpx database) for all users that\n" " utmpx database) for all users that are logged in. Also\n"
" are logged in. Examples: \"-users lurk=\" and also\n" " see the \"-display WAIT:...\" functionality. Examples:\n"
" \"-users lurk=:0-1,bob,mary\"\n" " \"-users lurk=\" and also \"-users lurk=:0-1,bob,mary\"\n"
" \n" "\n"
" Be especially careful using the \"guess=\" and \"lurk=\"\n" " Be especially careful using the \"guess=\" and \"lurk=\"\n"
" modes. They are not recommended for use on machines\n" " modes. They are not recommended for use on machines\n"
" with untrustworthy local users.\n" " with untrustworthy local users.\n"
" \n" "\n"
"-noshm Do not use the MIT-SHM extension for the polling.\n" "-noshm Do not use the MIT-SHM extension for the polling.\n"
" Remote displays can be polled this way: be careful this\n" " Remote displays can be polled this way: be careful this\n"
" can use large amounts of network bandwidth. This is\n" " can use large amounts of network bandwidth. This is\n"
@ -1255,7 +1321,7 @@ void print_help(int mode) {
" commands are run for GNOME and KDE respectively.\n" " commands are run for GNOME and KDE respectively.\n"
" Other desktops won't work, e.g. Xfce (send us the\n" " Other desktops won't work, e.g. Xfce (send us the\n"
" corresponding commands if you find them). If x11vnc is\n" " corresponding commands if you find them). If x11vnc is\n"
" running as root (inetd(1) or gdm(1)), the -users option\n" " running as root (inetd(8) or gdm(1)), the -users option\n"
" may be needed for GNOME and KDE. If x11vnc guesses\n" " may be needed for GNOME and KDE. If x11vnc guesses\n"
" your desktop incorrectly, you can force it by prefixing\n" " your desktop incorrectly, you can force it by prefixing\n"
" color with \"gnome:\", \"kde:\", \"cde:\" or \"root:\".\n" " color with \"gnome:\", \"kde:\", \"cde:\" or \"root:\".\n"
@ -1554,7 +1620,7 @@ void print_help(int mode) {
" default (see -noxfixes below). This can be disabled\n" " default (see -noxfixes below). This can be disabled\n"
" with -nocursor, and also some values of the \"mode\"\n" " with -nocursor, and also some values of the \"mode\"\n"
" option below.\n" " option below.\n"
" \n" "\n"
" Note that under XFIXES cursors with transparency (alpha\n" " Note that under XFIXES cursors with transparency (alpha\n"
" channel) will usually not be exactly represented and one\n" " channel) will usually not be exactly represented and one\n"
" may find Overlay preferable. See also the -alphacut\n" " may find Overlay preferable. See also the -alphacut\n"
@ -1606,7 +1672,7 @@ void print_help(int mode) {
" pixel with alpha value less than n becomes completely\n" " pixel with alpha value less than n becomes completely\n"
" transparent. Otherwise the pixel is completely opaque.\n" " transparent. Otherwise the pixel is completely opaque.\n"
" Default %d\n" " Default %d\n"
" \n" "\n"
"-alphafrac fraction With the threshold in -alphacut some cursors will become\n" "-alphafrac fraction With the threshold in -alphacut some cursors will become\n"
" almost completely transparent because their alpha values\n" " almost completely transparent because their alpha values\n"
" are not high enough. For those cursors adjust the\n" " are not high enough. For those cursors adjust the\n"
@ -1872,7 +1938,7 @@ void print_help(int mode) {
" So for a short time there are two (or more) block\n" " So for a short time there are two (or more) block\n"
" cursors on the screen. There are similar scenarios,\n" " cursors on the screen. There are similar scenarios,\n"
" (e.g. an output line is duplicated).\n" " (e.g. an output line is duplicated).\n"
" \n" "\n"
" These transients are induced by the approximation of\n" " These transients are induced by the approximation of\n"
" scroll detection (e.g. it detects the scroll, but not\n" " scroll detection (e.g. it detects the scroll, but not\n"
" the fact that the block cursor was cleared just before\n" " the fact that the block cursor was cleared just before\n"
@ -2279,7 +2345,7 @@ void print_help(int mode) {
" mode if the bpp is 24.\n" " mode if the bpp is 24.\n"
"\n" "\n"
" video4linux: on Linux some attempt is made to handle\n" " video4linux: on Linux some attempt is made to handle\n"
" video devices (webcams or tv tuners) automatically.\n" " video devices (webcams or TV tuners) automatically.\n"
" The idea is the WxHxB will be extracted from the\n" " The idea is the WxHxB will be extracted from the\n"
" device itself. So if you do not supply \"@WxHxB...\n" " device itself. So if you do not supply \"@WxHxB...\n"
" parameters x11vnc will try to determine them. It first\n" " parameters x11vnc will try to determine them. It first\n"
@ -2326,7 +2392,7 @@ void print_help(int mode) {
" 24, and 32 respectively). See http://www.linuxtv.org\n" " 24, and 32 respectively). See http://www.linuxtv.org\n"
" for more info (V4L api).\n" " for more info (V4L api).\n"
"\n" "\n"
" For tv/rf tuner cards one can set the tuning mode\n" " For TV/rf tuner cards one can set the tuning mode\n"
" via tun=XXX where XXX can be one of PAL, NTSC, SECAM,\n" " via tun=XXX where XXX can be one of PAL, NTSC, SECAM,\n"
" or AUTO.\n" " or AUTO.\n"
"\n" "\n"

@ -93,7 +93,7 @@ char *allowed_input_str = NULL;
char *viewonly_passwd = NULL; /* view only passwd. */ char *viewonly_passwd = NULL; /* view only passwd. */
char **passwd_list = NULL; /* for -passwdfile */ char **passwd_list = NULL; /* for -passwdfile */
int begin_viewonly = -1; int begin_viewonly = -1;
int inetd = 0; /* spawned from inetd(1) */ int inetd = 0; /* spawned from inetd(8) */
#ifndef FILEXFER #ifndef FILEXFER
#define FILEXFER 1 #define FILEXFER 1
#endif #endif

@ -941,6 +941,7 @@ if (0) fprintf(stderr, "initialize_pipeinput: %s -- %s\n", pipeinput_str, p);
} }
set_child_info(); set_child_info();
/* pipeinput */
if (no_external_cmds) { if (no_external_cmds) {
rfbLogEnable(1); rfbLogEnable(1);
rfbLog("cannot run external commands in -nocmds mode:\n"); rfbLog("cannot run external commands in -nocmds mode:\n");

@ -585,7 +585,7 @@ int remote_control_access_ok(void) {
"XAUTHORITY\n", dpy_str); "XAUTHORITY\n", dpy_str);
fprintf(stderr, " -- (ignore any Xlib: errors that" fprintf(stderr, " -- (ignore any Xlib: errors that"
" follow) --\n"); " follow) --\n");
dpy2 = XOpenDisplay(dpy_str); dpy2 = XOpenDisplay_wr(dpy_str);
fflush(stderr); fflush(stderr);
fprintf(stderr, " -- (done checking) --\n\n"); fprintf(stderr, " -- (done checking) --\n\n");
@ -601,7 +601,7 @@ int remote_control_access_ok(void) {
if (dpy2) { if (dpy2) {
rfbLog("XAUTHORITY is not required on display.\n"); rfbLog("XAUTHORITY is not required on display.\n");
rfbLog(" %s\n", DisplayString(dpy)); rfbLog(" %s\n", DisplayString(dpy));
XCloseDisplay(dpy2); XCloseDisplay_wr(dpy2);
dpy2 = NULL; dpy2 = NULL;
return 0; return 0;
} }

@ -541,7 +541,7 @@ void set_raw_fb_params(int restore) {
multiple_cursors_mode = mc0; multiple_cursors_mode = mc0;
if (! dpy && raw_fb_orig_dpy) { if (! dpy && raw_fb_orig_dpy) {
dpy = XOpenDisplay(raw_fb_orig_dpy); dpy = XOpenDisplay_wr(raw_fb_orig_dpy);
if (dpy) { if (dpy) {
if (! quiet) rfbLog("reopened DISPLAY: %s\n", if (! quiet) rfbLog("reopened DISPLAY: %s\n",
raw_fb_orig_dpy); raw_fb_orig_dpy);
@ -881,6 +881,7 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
set_child_info(); set_child_info();
q += strlen("setup:"); q += strlen("setup:");
/* rawfb-setup */
if (no_external_cmds) { if (no_external_cmds) {
rfbLogEnable(1); rfbLogEnable(1);
rfbLog("cannot run external commands in -nocmds " rfbLog("cannot run external commands in -nocmds "
@ -988,7 +989,7 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
if (dpy) { if (dpy) {
rfbLog("closing X DISPLAY: %s in rawfb mode.\n", rfbLog("closing X DISPLAY: %s in rawfb mode.\n",
DisplayString(dpy)); DisplayString(dpy));
XCloseDisplay(dpy); /* yow! */ XCloseDisplay_wr(dpy); /* yow! */
} }
dpy = NULL; dpy = NULL;
} }
@ -1974,7 +1975,7 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
have_masks = 0; have_masks = 0;
} }
if (cmap8to24 && depth == 8) { if (cmap8to24 && depth == 8 && dpy) {
XVisualInfo vinfo; XVisualInfo vinfo;
/* more cooking up... */ /* more cooking up... */
have_masks = 2; have_masks = 2;
@ -2042,6 +2043,8 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
rfbLog("Raw fb at addr %p is %dbpp depth=%d " rfbLog("Raw fb at addr %p is %dbpp depth=%d "
"true color\n", raw_fb_addr, "true color\n", raw_fb_addr,
fb_bpp, fb_depth); fb_bpp, fb_depth);
} else if (! dpy) {
;
} else if (have_masks == 2) { } else if (have_masks == 2) {
rfbLog("\n"); rfbLog("\n");
rfbLog("X display %s is %dbpp depth=%d indexed " rfbLog("X display %s is %dbpp depth=%d indexed "
@ -2206,6 +2209,7 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
fprintf(stderr, " 8to24_fb: %p\n", cmap8to24_fb); fprintf(stderr, " 8to24_fb: %p\n", cmap8to24_fb);
fprintf(stderr, " snap_fb: %p\n", snap_fb); fprintf(stderr, " snap_fb: %p\n", snap_fb);
fprintf(stderr, " raw_fb: %p\n", raw_fb); fprintf(stderr, " raw_fb: %p\n", raw_fb);
fprintf(stderr, " fake_fb: %p\n", fake_fb);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }

@ -53,6 +53,7 @@ static int dt_cmd(char *cmd) {
return 0; return 0;
} }
/* dt */
if (no_external_cmds) { if (no_external_cmds) {
rfbLog("cannot run external commands in -nocmds mode:\n"); rfbLog("cannot run external commands in -nocmds mode:\n");
rfbLog(" \"%s\"\n", cmd); rfbLog(" \"%s\"\n", cmd);

@ -113,6 +113,7 @@ int start_stunnel(int stunnel_port, int x11vnc_port) {
return 0; return 0;
} }
/* stunnel */
if (no_external_cmds) { if (no_external_cmds) {
rfbLogEnable(1); rfbLogEnable(1);
rfbLog("start_stunnel: cannot run external commands in -nocmds mode:\n"); rfbLog("start_stunnel: cannot run external commands in -nocmds mode:\n");

@ -246,6 +246,7 @@ static char *create_tmp_pem(char *pathin, int prompt) {
CN = strdup(line); CN = strdup(line);
EM = strdup("x11vnc@server.nowhere"); EM = strdup("x11vnc@server.nowhere");
/* ssl */
if (no_external_cmds) { if (no_external_cmds) {
rfbLog("create_tmp_pem: cannot run external commands.\n"); rfbLog("create_tmp_pem: cannot run external commands.\n");
return NULL; return NULL;
@ -818,7 +819,7 @@ void openssl_port(void) {
rfbLog("openssl_port: could not reopen port %d\n", port); rfbLog("openssl_port: could not reopen port %d\n", port);
clean_up_exit(1); clean_up_exit(1);
} }
if (db) fprintf(stderr, "listen on port/sock %d/%d\n", port, sock); rfbLog("openssl_port: listen on port/sock %d/%d\n", port, sock);
openssl_sock = sock; openssl_sock = sock;
openssl_port_num = port; openssl_port_num = port;

@ -316,6 +316,12 @@ Tuning
=D-C:0,1,2,3,4 pointer_mode: =D-C:0,1,2,3,4 pointer_mode:
input_skip: input_skip:
=D nodragging =D nodragging
-- D
speeds:
=D wait:
defer:
=D nap
screen_blank:
-- --
=GAL WireFrame:: =GAL WireFrame::
wireframe wireframe
@ -337,12 +343,6 @@ Tuning
xd_area: xd_area:
xd_mem: xd_mem:
=GAL LOFF =GAL LOFF
-- D
speeds:
=D wait:
defer:
=D nap
screen_blank:
-- --
=GAL SharedMemory:: =GAL SharedMemory::
noshm noshm

@ -327,6 +327,12 @@ char gui_code[] = "";
" =D-C:0,1,2,3,4 pointer_mode:\n" " =D-C:0,1,2,3,4 pointer_mode:\n"
" input_skip:\n" " input_skip:\n"
" =D nodragging\n" " =D nodragging\n"
" -- D\n"
" speeds:\n"
" =D wait:\n"
" defer:\n"
" =D nap\n"
" screen_blank:\n"
" --\n" " --\n"
" =GAL WireFrame::\n" " =GAL WireFrame::\n"
" wireframe\n" " wireframe\n"
@ -348,12 +354,6 @@ char gui_code[] = "";
" xd_area:\n" " xd_area:\n"
" xd_mem:\n" " xd_mem:\n"
" =GAL LOFF\n" " =GAL LOFF\n"
" -- D\n"
" speeds:\n"
" =D wait:\n"
" defer:\n"
" =D nap\n"
" screen_blank:\n"
" --\n" " --\n"
" =GAL SharedMemory::\n" " =GAL SharedMemory::\n"
" noshm\n" " noshm\n"

@ -49,7 +49,7 @@ void unixpw_screen(int init);
void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init); void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init);
void unixpw_accept(char *user); void unixpw_accept(char *user);
void unixpw_deny(void); void unixpw_deny(void);
int su_verify(char *user, char *pass); int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size);
int crypt_verify(char *user, char *pass); int crypt_verify(char *user, char *pass);
static int white(void); static int white(void);
@ -63,6 +63,10 @@ int unixpw_login_viewonly = 0;
time_t unixpw_last_try_time = 0; time_t unixpw_last_try_time = 0;
rfbClientPtr unixpw_client = NULL; rfbClientPtr unixpw_client = NULL;
int keep_unixpw = 0;
char *keep_unixpw_user = NULL;
char *keep_unixpw_pass = NULL;
static int in_login = 0, in_passwd = 0, tries = 0; static int in_login = 0, in_passwd = 0, tries = 0;
static int char_row = 0, char_col = 0; static int char_row = 0, char_col = 0;
static int char_x = 0, char_y = 0, char_w = 8, char_h = 16; static int char_x = 0, char_y = 0, char_w = 8, char_h = 16;
@ -352,11 +356,11 @@ int crypt_verify(char *user, char *pass) {
#endif /* UNIXPW_CRYPT */ #endif /* UNIXPW_CRYPT */
} }
int su_verify(char *user, char *pass) { int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size) {
#ifndef UNIXPW_SU #ifndef UNIXPW_SU
return 0; return 0;
#else #else
int i, j, status, fd = -1, sfd, tfd; int i, j, status, fd = -1, sfd, tfd, drain_size = 4096, rsize;
int slow_pw = 1; int slow_pw = 1;
char *slave, *bin_true = NULL, *bin_su = NULL; char *slave, *bin_true = NULL, *bin_su = NULL;
pid_t pid, pidw; pid_t pid, pidw;
@ -389,6 +393,7 @@ int su_verify(char *user, char *pass) {
return 0; return 0;
} }
} }
/* unixpw */
if (no_external_cmds) { if (no_external_cmds) {
rfbLog("su_verify: cannot run external commands.\n"); rfbLog("su_verify: cannot run external commands.\n");
clean_up_exit(1); clean_up_exit(1);
@ -417,6 +422,10 @@ int su_verify(char *user, char *pass) {
} if (stat("/usr/bin/true", &sbuf) == 0) { } if (stat("/usr/bin/true", &sbuf) == 0) {
bin_true = "/usr/bin/true"; bin_true = "/usr/bin/true";
} }
if (cmd != NULL && cmd[0] != '\0') {
/* this is for ext. cmd su -c "my cmd" */
bin_true = cmd;
}
if (bin_true == NULL) { if (bin_true == NULL) {
rfbLogPerror("existence /bin/true"); rfbLogPerror("existence /bin/true");
return 0; return 0;
@ -617,13 +626,13 @@ if (db) fprintf(stderr, "slave is: %s fd=%d\n", slave, fd);
if (db) fprintf(stderr, "%s", buf); if (db) fprintf(stderr, "%s", buf);
if (db > 3 && n == 1 && buf[0] == ':') { if (db > 3 && n == 1 && buf[0] == ':') {
char cmd[32]; char cmd0[32];
usleep( 100 * 1000 ); usleep( 100 * 1000 );
fprintf(stderr, "\n\n"); fprintf(stderr, "\n\n");
sprintf(cmd, "ps wu %d", pid); sprintf(cmd0, "ps wu %d", pid);
system(cmd); system(cmd0);
sprintf(cmd, "stty -a < %s", slave); sprintf(cmd0, "stty -a < %s", slave);
system(cmd); system(cmd0);
fprintf(stderr, "\n\n"); fprintf(stderr, "\n\n");
} }
@ -675,7 +684,12 @@ if (db) {
* if we don't drain we may block at waitpid. If we close(fd), the * if we don't drain we may block at waitpid. If we close(fd), the
* make cause child to die by signal. * make cause child to die by signal.
*/ */
for (i = 0; i<4096; i++) { if (rbuf && *rbuf_size > 0) {
/* asked to return output of command */
drain_size = *rbuf_size;
rsize = 0;
}
for (i = 0; i< drain_size; i++) {
int n; int n;
buf[0] = '\0'; buf[0] = '\0';
@ -691,6 +705,48 @@ if (db) fprintf(stderr, "%s", buf);
if (n <= 0) { if (n <= 0) {
break; break;
} }
if (rbuf) {
rbuf[i] = buf[0];
rsize++;
}
}
if (rbuf) {
char *s = rbuf;
char *p = strdup(pass);
int n, o = 0;
n = strlen(p);
if (p[n-1] == '\n') {
p[n-1] = '\0';
}
/*
* usually is: Password: mypassword\r\n\r\n<output-of-command>
* and output will have \n -> \r\n
*/
if (rbuf[0] == ' ') {
s++;
o++;
}
if (strstr(s, p) == s) {
s += strlen(p);
o += strlen(p);
for (n = 0; n < 4; n++) {
if (s[0] == '\r' || s[0] == '\n') {
s++;
o++;
}
}
}
if (o > 0) {
int i = 0;
rsize -= o;
while (o < drain_size) {
rbuf[i++] = rbuf[o++];
}
}
*rbuf_size = rsize;
strzero(p);
} }
if (db) fprintf(stderr, "\n"); if (db) fprintf(stderr, "\n");
@ -730,14 +786,39 @@ if (db) fprintf(stderr, "unixpw_verify: '%s' '%s'\n", user, db > 1 ? pass : "***
if (unixpw_nis) { if (unixpw_nis) {
if (crypt_verify(user, pass)) { if (crypt_verify(user, pass)) {
unixpw_accept(user); unixpw_accept(user);
if (keep_unixpw) {
keep_unixpw_user = strdup(user);
keep_unixpw_pass = strdup(pass);
}
return; return;
} else { } else {
rfbLog("unixpw_verify: crypt_verify login for %s failed.\n", user); rfbLog("unixpw_verify: crypt_verify login for %s failed.\n", user);
usleep(3000*1000); 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 { } else {
if (su_verify(user, pass)) { if (su_verify(user, pass, NULL, NULL, NULL)) {
unixpw_accept(user); unixpw_accept(user);
if (keep_unixpw) {
keep_unixpw_user = strdup(user);
keep_unixpw_pass = strdup(pass);
}
return; return;
} }
rfbLog("unixpw_verify: su_verify login for %s failed.\n", user); rfbLog("unixpw_verify: su_verify login for %s failed.\n", user);
@ -803,6 +884,14 @@ void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init) {
user[i] = '\0'; user[i] = '\0';
pass[i] = '\0'; pass[i] = '\0';
} }
if (keep_unixpw_user) {
free(keep_unixpw_user);
keep_unixpw_user = NULL;
}
if (keep_unixpw_pass) {
free(keep_unixpw_pass);
keep_unixpw_pass = NULL;
}
return; return;
} }
@ -1027,6 +1116,41 @@ static void apply_opts (char *user) {
void unixpw_accept(char *user) { void unixpw_accept(char *user) {
apply_opts(user); apply_opts(user);
if (started_as_root == 1 && users_list
&& strstr(users_list, "unixpw=") == users_list) {
if (getuid() && geteuid()) {
rfbLog("unixpw_accept: unixpw= but not root\n");
started_as_root = 2;
} else {
char *u = (char *)malloc(strlen(user)+1);
u[0] = '\0';
if (!strcmp(users_list, "unixpw=")) {
sprintf(u, "+%s", user);
} else {
char *p, *str = strdup(users_list);
p = strtok(str + strlen("unixpw="), ",");
while (p) {
if (!strcmp(p, user)) {
sprintf(u, "+%s", user);
break;
}
p = strtok(NULL, ",");
}
free(str);
}
if (u[0] == '\0') {
rfbLog("unixpw_accept skipping switch to user: %s\n", user);
} else if (switch_user(u, 0)) {
rfbLog("unixpw_accept switched to user: %s\n", user);
} else {
rfbLog("unixpw_accept failed to switched to user: %s\n", user);
}
free(u);
}
}
if (unixpw_login_viewonly) { if (unixpw_login_viewonly) {
unixpw_client->viewOnly = TRUE; unixpw_client->viewOnly = TRUE;
} }

@ -7,12 +7,15 @@ extern void unixpw_screen(int init);
extern void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init); extern void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init);
extern void unixpw_accept(char *user); extern void unixpw_accept(char *user);
extern void unixpw_deny(void); extern void unixpw_deny(void);
extern int su_verify(char *user, char *pass); extern int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size);
extern int crypt_verify(char *user, char *pass); extern int crypt_verify(char *user, char *pass);
extern int unixpw_in_progress; extern int unixpw_in_progress;
extern int unixpw_login_viewonly; extern int unixpw_login_viewonly;
extern time_t unixpw_last_try_time; extern time_t unixpw_last_try_time;
extern rfbClientPtr unixpw_client; extern rfbClientPtr unixpw_client;
extern int keep_unixpw;
extern char *keep_unixpw_user;
extern char *keep_unixpw_pass;
#endif /* _X11VNC_UNIXPW_H */ #endif /* _X11VNC_UNIXPW_H */

@ -6,6 +6,8 @@
#include "scan.h" #include "scan.h"
#include "screen.h" #include "screen.h"
#include "unixpw.h" #include "unixpw.h"
#include "sslhelper.h"
#include "xwrappers.h"
void check_switched_user(void); void check_switched_user(void);
void lurk_loop(char *str); void lurk_loop(char *str);
@ -13,6 +15,7 @@ int switch_user(char *user, int fb_mode);
int read_passwds(char *passfile); int read_passwds(char *passfile);
void install_passwds(void); void install_passwds(void);
void check_new_passwds(void); void check_new_passwds(void);
int wait_for_client(int *argc, char** argv, int http);
static void switch_user_task_dummy(void); static void switch_user_task_dummy(void);
@ -574,9 +577,9 @@ static int try_user_and_display(uid_t uid, char *dpystr) {
} }
fclose(stderr); fclose(stderr);
dpy2 = XOpenDisplay(dpystr); dpy2 = XOpenDisplay_wr(dpystr);
if (dpy2) { if (dpy2) {
XCloseDisplay(dpy2); XCloseDisplay_wr(dpy2);
exit(0); /* success */ exit(0); /* success */
} else { } else {
exit(2); /* fail */ exit(2); /* fail */
@ -940,4 +943,234 @@ void check_new_passwds(void) {
} }
} }
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 db = 0;
if (! use_dpy || strstr(use_dpy, "WAIT:") != use_dpy) {
return 0;
}
rfbLog("into wait_for_client.\n");
str = strdup(use_dpy);
str += strlen("WAIT:");
q = strchr(str, ':');
/* get any leading geometry: */
if (q) *q = '\0';
if (sscanf(str, "%dx%d", &w0, &h0) == 2) {
w = w0;
h = h0;
}
if (q) *q = ':';
q = strchr(str, ':');
if (! q) {
if (strstr(str, "cmd=") != str) {
str = strdup(":0");
}
} else {
str = q;
}
if (db) fprintf(stderr, "str: %s\n", str);
if (strstr(str, "cmd=") == str) {
cmd = str + strlen("cmd=");
if (db) fprintf(stderr, "cmd: %s\n", cmd);
/* WAIT */
if (no_external_cmds) {
rfbLog("wait_for_client external cmds not allowed:"
" %s\n", use_dpy);
clean_up_exit(1);
}
}
if (fake_fb) {
free(fake_fb);
}
fake_fb = (char *) calloc(w*h*b/4, 1);
fb_image = &ximage_struct;
fb_image->data = fake_fb;
fb_image->format = ZPixmap;
fb_image->width = w;
fb_image->height = h;
fb_image->bits_per_pixel = b;
fb_image->bytes_per_line = w*b/8;
fb_image->bitmap_unit = -1;
fb_image->depth = 24;
fb_image->red_mask = 0xff0000;
fb_image->green_mask = 0x00ff00;
fb_image->blue_mask = 0x0000ff;
depth = fb_image->depth;
dpy_x = wdpy_x = w;
dpy_y = wdpy_y = h;
off_x = 0;
off_y = 0;
initialize_allowed_input();
initialize_screen(argc, argv, fb_image);
if (http && check_httpdir()) {
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;
}
if (inetd && use_openssl) {
accept_openssl(OPENSSL_INETD);
}
while (1) {
if (! use_threads) {
rfbPE(-1);
}
if (use_openssl) {
check_openssl();
}
if (! screen || ! screen->clientHead) {
usleep(100 * 1000);
continue;
}
rfbLog("wait_for_client: got client\n");
break;
}
if (unixpw) {
if (! unixpw_in_progress) {
rfbLog("unixpw but no unixpw_in_progress\n");
clean_up_exit(1);
}
while (1) {
if (! use_threads) {
rfbPE(-1);
}
if (unixpw_in_progress) {
usleep(20 * 1000);
continue;
}
rfbLog("wait_for_client: unixpw finished.\n");
break;
}
}
if (cmd) {
char line1[1024];
char line2[16384];
char *q;
int n;
memset(line1, 0, 1024);
memset(line2, 0, 16384);
if (unixpw) {
int res = 0, k, j;
char line[18000];
memset(line, 0, 18000);
if (keep_unixpw_user && keep_unixpw_pass) {
n = 18000;
res = su_verify(keep_unixpw_user, keep_unixpw_pass,
cmd, line, &n);
strzero(keep_unixpw_user);
strzero(keep_unixpw_pass);
}
keep_unixpw = 0;
if (! res) {
rfbLog("wait_for_client: cmd failed: %s\n", cmd);
clean_up_exit(1);
}
for (k = 0; k < 1024; k++) {
line1[k] = line[k];
if (line[k] == '\n') {
k++;
break;
}
}
n -= k;
while (j < 16384) {
line2[j] = line[k+j];
j++;
}
} else {
FILE *p = popen(cmd, "r");
if (! p) {
rfbLog("wait_for_client: cmd failed: %s\n", cmd);
rfbLogPerror("popen");
clean_up_exit(1);
}
if (fgets(line1, 1024, p) == NULL) {
rfbLog("wait_for_client: read failed: %s\n", cmd);
rfbLogPerror("fgets");
clean_up_exit(1);
}
n = fread(line2, 1, 16384, p);
pclose(p);
}
if (strstr(line1, "DISPLAY=") != line1) {
rfbLog("wait_for_client: bad reply %s\n", line1);
clean_up_exit(1);
}
use_dpy = strdup(line1 + strlen("DISPLAY="));
q = use_dpy;
while (*q != '\0') {
if (*q == '\n' || *q == '\r') *q = '\0';
q++;
}
if (db) fprintf(stderr, "use_dpy: %s n: %d\n", use_dpy, n);
if (0) write(2, line2, n);
if (line2[0] != '\0') {
if (strstr(line2, "XAUTHORITY=") == line2) {
q = line2;
while (*q != '\0') {
if (*q == '\n' || *q == '\r') *q = '\0';
q++;
}
if (auth_file) {
free(auth_file);
}
auth_file = strdup(line2 + strlen("XAUTHORITY="));
} else {
xauth_raw_data = (char *)malloc(n);
xauth_raw_len = n;
memcpy(xauth_raw_data, line2, n);
if (db) fprintf(stderr, "xauth_raw_len: %d\n", n);
if (0) {
write(2, xauth_raw_data, xauth_raw_len);
fprintf(stderr, "\n");
}
}
}
} else {
use_dpy = strdup(str);
}
if (chg_raw_fb) {
raw_fb = NULL;
}
return 1;
}

@ -9,5 +9,6 @@ extern int switch_user(char *, int);
extern int read_passwds(char *passfile); extern int read_passwds(char *passfile);
extern void install_passwds(void); extern void install_passwds(void);
extern void check_new_passwds(void); extern void check_new_passwds(void);
extern int wait_for_client(int *argc, char** argv, int http);
#endif /* _X11VNC_USER_H */ #endif /* _X11VNC_USER_H */

@ -1089,6 +1089,7 @@ static char *guess_via_v4l_info(char *dev, int *fd) {
if (*fd) {} if (*fd) {}
/* v4l-info */
if (no_external_cmds) { if (no_external_cmds) {
rfbLog("guess_via_v4l_info: cannot run external " rfbLog("guess_via_v4l_info: cannot run external "
"command: v4l-info\n"); "command: v4l-info\n");

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

@ -2,7 +2,7 @@
.TH X11VNC "1" "June 2006" "x11vnc " "User Commands" .TH X11VNC "1" "June 2006" "x11vnc " "User Commands"
.SH NAME .SH NAME
x11vnc - allow VNC connections to real X11 displays x11vnc - allow VNC connections to real X11 displays
version: 0.8.1, lastmod: 2006-06-03 version: 0.8.2, lastmod: 2006-06-08
.SH SYNOPSIS .SH SYNOPSIS
.B x11vnc .B x11vnc
[OPTION]... [OPTION]...
@ -60,7 +60,8 @@ becomes a space character).
X11 server display to connect to, usually :0. The X X11 server display to connect to, usually :0. The X
server process must be running on same machine and server process must be running on same machine and
support MIT-SHM. Equivalent to setting the DISPLAY support MIT-SHM. Equivalent to setting the DISPLAY
environment variable to \fIdisp\fR. environment variable to \fIdisp\fR. See the description
below of the "\fB-display\fR \fIWAIT:...\fR" extensions.
.PP .PP
\fB-auth\fR \fIfile\fR \fB-auth\fR \fIfile\fR
.IP .IP
@ -355,7 +356,7 @@ after startup.
\fB-inetd\fR \fB-inetd\fR
.IP .IP
Launched by Launched by
.IR inetd (1): .IR inetd (8):
stdio instead of listening socket. stdio instead of listening socket.
Note: if you are not redirecting stderr to a log file Note: if you are not redirecting stderr to a log file
(via shell 2> or \fB-o\fR option) you MUST also specify the \fB-q\fR (via shell 2> or \fB-o\fR option) you MUST also specify the \fB-q\fR
@ -515,6 +516,755 @@ used to have viewonly passwords. (tip: make the 3rd
and last line be "__BEGIN_VIEWONLY__" to have 2 and last line be "__BEGIN_VIEWONLY__" to have 2
full-access passwords) full-access passwords)
.PP .PP
\fB-unixpw\fR \fI[list]\fR
.IP
Use Unix username and password authentication. x11vnc
uses the
.IR su (1)
program to verify the user's password.
[list] is an optional comma separated list of allowed
Unix usernames. See below for per-user options that
can be applied.
.IP
A familiar "login:" and "Password:" dialog is
presented to the user on a black screen inside the
vncviewer. The connection is dropped if the user fails
to supply the correct password in 3 tries or does not
send one before a 25 second timeout. Existing clients
are view-only during this period.
.IP
Since the detailed behavior of
.IR su (1)
can vary from
OS to OS and for local configurations, test the mode
carefully on your systems before using it in production.
Test different combinations of valid/invalid usernames
and valid/invalid passwords to see if it behaves as
expected. x11vnc will attempt to be conservative and
reject a login if anything abnormal occurs.
.IP
On FreeBSD and the other BSD's by default it is
impossible for the user running x11vnc to validate
his *own* password via
.IR su (1)
(evidently commenting out
the pam_self.so entry in /etc/pam.d/su eliminates this
problem). So the x11vnc login will always *fail* for
this case (even when the correct password is supplied).
.IP
A possible workaround for this 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 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, one of two schemes
will be enforced: 1) the \fB-ssl\fR builtin SSL mode, or 2)
require both \fB-localhost\fR and \fB-stunnel\fR be enabled.
.IP
Method 1) ensures the traffic is encrypted between
viewer and server. A PEM file will be required, see the
discussion under \fB-ssl\fR below (under some circumstances
a temporary one can be automatically generated).
.IP
Method 2) requires the viewer connection to appear
to come from the same machine x11vnc is running on
(e.g. from a ssh \fB-L\fR port redirection). And that the
\fB-stunnel\fR SSL mode be used for encryption over the
network.(see the description of \fB-stunnel\fR below).
.IP
Note: as a convenience, if you
.IR ssh (1)
in and start
x11vnc it will check if the environment variable
SSH_CONNECTION is set and appears reasonable. If it
does, then the \fB-ssl\fR or \fB-stunnel\fR requirement will be
dropped since it is assumed you are using ssh for the
encrypted tunnelling. \fB-localhost\fR is still enforced.
Use \fB-ssl\fR or \fB-stunnel\fR to force SSL usage even if
SSH_CONNECTION is set.
.IP
To override the above restrictions you can set
environment variables before starting x11vnc:
.IP
Set UNIXPW_DISABLE_SSL=1 to disable requiring either
\fB-ssl\fR or \fB-stunnel.\fR Evidently you will be using a
different method to encrypt the data between the
vncviewer and x11vnc: perhaps
.IR ssh (1)
or an IPSEC VPN.
.IP
Note that use of \fB-localhost\fR with
.IR ssh (1)
is roughly
the same as requiring a Unix user login (since a Unix
password or the user's public key authentication is
used by sshd on the machine where x11vnc runs and only
local connections from that machine are accepted)
.IP
Set UNIXPW_DISABLE_LOCALHOST=1 to disable the \fB-localhost\fR
requirement in Method 2). One should never do this
(i.e. allow the Unix passwords to be sniffed on the
network).
.IP
Regarding reverse connections (e.g. \fB-R\fR connect:host
and \fB-connect\fR host), when the \fB-localhost\fR constraint is
in effect then 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 in \fB-ssl\fR
mode reverse connection are disabled (see below).
.IP
In \fB-inetd\fR mode the Method 1) will be enforced (not
Method 2). With \fB-ssl\fR in effect reverse connections
are disabled. If you override this via env. var, be
sure to also use encryption from the viewer to inetd.
Tip: you can also have your own stunnel spawn x11vnc
in \fB-inetd\fR mode (thereby bypassing inetd). See the FAQ
for details.
.IP
The user names in the comma separated [list] can have
per-user options after a ":", e.g. "fred:opts"
where "opts" is a "+" separated list of
"viewonly", "fullaccess", "input=XXXX", or
"deny", e.g. "karl,fred:viewonly,boss:input=M".
For "input=" it is the K,M,B,C described under \fB-input.\fR
.IP
If a user in the list is "*" that means those
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 utilities for testing password
if [list] starts with the "%" character. See the
quick_pw() function in the source for details.
.PP
\fB-unixpw_nis\fR \fI[list]\fR
.IP
As \fB-unixpw\fR above, however do not use
.IR su (1)
but rather
use the traditional
.IR getpwnam (3)
+
.IR crypt (3)
method to
verify passwords instead. This requires that the
encrypted passwords be readable. Passwords stored
in /etc/shadow will be inaccessible unless x11vnc
is run as root.
.IP
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 (only that
.IR getpwnam (3)
return the encrypted
password is required), but it is unlikely it will work
for any other modern environment. All of the \fB-unixpw\fR
options and contraints apply.
.PP
\fB-display\fR \fIWAIT:...\fR
.IP
A special usage mode for the normal \fB-display\fR option.
Useful with \fB-unixpw,\fR but can be used independently
of it. If the display string begins with WAIT: then
x11vnc waits until a VNC client connects before opening
the X display (or \fB-rawfb\fR device).
.IP
This could be useful for delaying opening the display
for certain usage modes (say if x11vnc is started at
boot time and no X server is running or users logged
in yet).
.IP
If the string is, e.g. WAIT:0.0 or WAIT:1, i.e. "WAIT"
in front of a normal X display, then that indicated
display is used. A more interesting case is like this:
.IP
WAIT:cmd=/usr/local/bin/find_display
.IP
in which case the command after "cmd=" is run to
dynamically work out the DISPLAY and optionally the
XAUTHORITY data. The first line of the command output
must be of the form DISPLAY=<xdisplay>. Any remaining
output is taken as XAUTHORITY data. It can be either
of the form XAUTHORITY=<file> or raw xauthority data for
the display (e.g. "xauth extract - $DISPLAY" output).
.IP
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
\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
multiple users share a given machine. The user does
not need to remember special ports or passwords set up
for his desktop and VNC.
.IP
A nice way to use WAIT:cmd=... is out of
.IR inetd (8)
(it automatically forks a new x11vnc for each user).
You can have the x11vnc inetd spawned process run as,
say, root or nobody. When run as root (for either
inetd or display manager), you can also supply the
option "\fB-users\fR \fIunixpw=\fR" to have the x11vnc process
switch to the user as well. Note: there will be a 2nd
SSL helper process that will not switch, but it is only
encoding and decoding the stream at that point.
.IP
As a special case, WAIT:cmd=FINDDISPLAY will run a
script that works on most Unixes to determine a user's
DISPLAY variable and xauthority data. this is TBD.
.IP
Finally, one can insert a geometry between colons,
e.g. WAIT:1280x1024:... to set the size of the display
the VNC client first attaches to since some VNC viewers
will not automatically adjust to a new framebuffer size.
.PP
\fB-ssl\fR \fI[pem]\fR
.IP
Use the openssl library (www.openssl.org) to provide a
built-in encrypted SSL tunnel between VNC viewers and
x11vnc. This requires libssl support to be compiled
into x11vnc at build time. If x11vnc is not built
with libssl support it will exit immediately when \fB-ssl\fR
is prescribed.
.IP
[pem] is optional, use "\fB-ssl\fR \fI/path/to/mycert.pem\fR"
to specify a PEM certificate file to use to identify
and provide a key for this server. See
.IR openssl (1)
for
more info about PEMs and the \fB-sslGenCert\fR option below.
.IP
The connecting VNC viewer SSL tunnel can optionally
authenticate this server if they have the public
key part of the certificate (or a common certificate
authority, CA, is a more sophisicated way to verify
this server's cert, see \fB-sslGenCA\fR below). This is
used to prevent man-in-the-middle attacks. Otherwise,
if the VNC viewer accepts this server's key without
verification, at least the traffic is protected
from passive sniffing on the network (but NOT from
man-in-the-middle attacks).
.IP
If [pem] is not supplied and the
.IR openssl (1)
utility
command exists in PATH, then a temporary, self-signed
certificate will be generated for this session (this
may take 5-30 seconds on slow machines). If
.IR openssl (1)
cannot be used to generate a temporary certificate
x11vnc exits immediately.
.IP
If successful in using
.IR openssl (1)
to generate a
temporary certificate, the public part of it will be
displayed to stderr (e.g. one could copy it to the
client-side to provide authentication of the server to
VNC viewers.) See following paragraphs for how to save
keys to reuse when x11vnc is restarted.
.IP
Set the env. var. X11VNC_SHOW_TMP_PEM=1 to have x11vnc
print out the entire certificate, including the PRIVATE
KEY part, to stderr. One could reuse this cert if saved
in a [pem] file. Similarly, set X11VNC_KEEP_TMP_PEM=1
to not delete the temporary PEM file: the file name
will be printed to stderr (so one could move it to
a safe place for reuse). You will be prompted for a
passphrase for the private key.
.IP
If [pem] is "SAVE" then the certificate will be saved
to the file ~/.vnc/certs/server.pem, or if that file
exists it will be used directly. Similarly, if [pem]
is "SAVE_PROMPT" the server.pem certificate will be
made based on your answers to its prompts for info such
as OrganizationalName, CommonName, etc.
.IP
Use "SAVE-<string>" and "SAVE_PROMPT-<string>"
to refer to the file ~/.vnc/certs/server-<string>.pem
instead. E.g. "SAVE-charlie" will store to the file
~/.vnc/certs/server-charlie.pem
.IP
See \fB-ssldir\fR below to use a directory besides the
default ~/.vnc/certs
.IP
Example: x11vnc \fB-ssl\fR SAVE \fB-display\fR :0 ...
.IP
Reverse connections are disabled in \fB-ssl\fR mode because
there is no way to ensure that data channel will
be encrypted. Set X11VNC_SSL_ALLOW_REVERSE=1 to
override this.
.IP
Your VNC viewer will also need to be able to connect
via SSL. See the discussion below under \fB-stunnel\fR and
the FAQ (ssl_vncviewer script) for how this might be
achieved. E.g. on Unix it is easy to write a shell
script that starts up stunnel and then vncviewer.
Also in the x11vnc source a SSL enabled Java VNC Viewer
applet is provided in the classes/ssl directory.
.PP
\fB-ssldir\fR \fI[dir]\fR
.IP
Use [dir] as an alternate ssl certificate and key
management toplevel directory. The default is
~/.vnc/certs
.IP
This directory is used to store server and other
certificates and keys and also other materials. E.g. in
the simplest case, "\fB-ssl\fR \fISAVE\fR" will store the x11vnc
server cert in [dir]/server.pem
.IP
Use of alternate directories via \fB-ssldir\fR allows you to
manage multiple VNC Certificate Authority (CA) keys.
Another use is if ~/.vnc/cert is on an NFS share you
might want your certificates and keys to be on a local
filesystem to prevent network snooping (for example
\fB-ssldir\fR /var/lib/x11vnc-certs).
.IP
\fB-ssldir\fR affects nearly all of the other \fB-ssl*\fR options,
e.g. \fB-ssl\fR SAVE, \fB-sslGenCert,\fR etc..
.PP
\fB-sslverify\fR \fI[path]\fR
.IP
For either of the \fB-ssl\fR or \fB-stunnel\fR modes, use [path]
to provide certificates to authenticate incoming VNC
*Client* connections (normally only the server is
authenticated in SSL.) This can be used as a method
to replace standard password authentication of clients.
.IP
If [path] is a directory it contains the client (or CA)
certificates in separate files. If [path] is a file,
it contains multiple certificates. See special tokens
below. These correspond to the "CApath = dir" and
"CAfile = file" stunnel options. See the
.IR stunnel (8)
manpage for details.
.IP
Examples:
x11vnc \fB-ssl\fR \fB-sslverify\fR ~/my.pem
x11vnc \fB-ssl\fR \fB-sslverify\fR ~/my_pem_dir/
.IP
Note that if [path] is a directory, it must contain
the certs in separate files named like <HASH>.0, where
the value of <HASH> is found by running the command
"openssl x509 \fB-hash\fR \fB-noout\fR \fB-in\fR file.crt". Evidently
one uses <HASH>.1 if there is a collision...
.IP
The the key-management utility "\fB-sslCertInfo\fR \fIHASHON\fR"
and "\fB-sslCertInfo\fR \fIHASHOFF\fR" will create/delete these
hashes for you automatically (via symlink) in the HASH
subdirs it manages. Then you can point \fB-sslverify\fR to
the HASH subdir.
.IP
Special tokens: in \fB-ssl\fR mode, if [path] is not a file or
a directory, it is taken as a comma separated list of
tokens that are interpreted as follows:
.IP
If a token is "CA" that means load the CA/cacert.pem
file from the ssl directory. If a token is "clients"
then all the files clients/*.crt in the ssl directory
are loaded. Otherwise the file clients/token.crt
is attempted to be loaded. As a kludge, use a token
like ../server-foo to load a server cert if you find
that necessary.
.IP
Use \fB-ssldir\fR to use a directory different from the
~/.vnc/certs default.
.IP
Note that if the "CA" cert is loaded you do not need
to load any of the certs that have been signed by it.
You will need to load any additional self-signed certs
however.
.IP
Examples:
x11vnc \fB-ssl\fR \fB-sslverify\fR CA
x11vnc \fB-ssl\fR \fB-sslverify\fR self:fred,self:jim
x11vnc \fB-ssl\fR \fB-sslverify\fR CA,clients
.IP
Usually "\fB-sslverify\fR \fICA\fR" is the most effective.
See the \fB-sslGenCA\fR and \fB-sslGenCert\fR options below for
how to set up and manage the CA framework.
.IP
NOTE: the following utilities, \fB-sslGenCA,\fR \fB-sslGenCert,\fR
\fB-sslEncKey,\fR and \fB-sslCertInfo\fR are provided for
completeness, but for casual usage they are overkill.
.IP
They provide VNC Certificate Authority (CA) key creation
and server / client key generation and signing. So they
provide a basic Public Key management framework for
VNC-ing with x11vnc. (note that they require
.IR openssl (1)
be installed on the system)
.IP
However, the simplest usage mode (where x11vnc
automatically generates its own, self-signed, temporary
key and the VNC viewers always accept it, e.g. accepting
via a dialog box) is probably safe enough for most
scenarios. CA management is not needed.
.IP
To protect against Man-In-The-Middle attacks the
simplest mode can be improved by using "\fB-ssl\fR \fISAVE\fR"
to have x11vnc create a longer term self-signed
certificate, and then (safely) copy the corresponding
public key cert to the desired client machines (care
must be taken the private key part is not stolen;
you will be prompted for a passphrase).
.IP
So keep in mind no CA key creation or management
(-sslGenCA and \fB-sslGenCert)\fR is needed for either of
the above two common usage modes.
.IP
One might want to use \fB-sslGenCA\fR and \fB-sslGenCert\fR
if you had a large number of VNC client and server
workstations. That way the administrator could generate
a single CA key with \fB-sslGenCA\fR and distribute its
certificate part to all of the workstations.
.IP
Next, he could create signed VNC server keys
(-sslGenCert server ...) for each workstation or user
that then x11vnc would use to authenticate itself to
any VNC client that has the CA cert.
.IP
Optionally, the admin could also make it so the
VNC clients themselves are authenticated to x11vnc
(-sslGenCert client ...) For this \fB-sslverify\fR would be
pointed to the CA cert (and/or self-signed certs).
.IP
x11vnc will be able to use all of these cert and
key files. On the VNC client side, they will need to
be "imported" somehow. Web browsers have "Manage
Certificates" actions as does the Java applet plugin
Control Panel. stunnel can also use these files (see
the ssl_vncviewer example script in the FAQ.)
.PP
\fB-sslGenCA\fR \fI[dir]\fR
.IP
Generate your own Certificate Authority private key,
certificate, and other files in directory [dir].
.IP
If [dir] is not supplied, a \fB-ssldir\fR setting is used,
or otherwise ~/.vnc/certs is used.
.IP
This command also creates directories where server and
client certs and keys will be stored. The
.IR openssl (1)
program must be installed on the system and available
in PATH.
.IP
After the CA files and directories are created the
command exits; the VNC server is not run.
.IP
You will be prompted for information to put into the CA
certificate. The info does not have to be accurate just
as long as clients accept the cert for VNC connections.
You will also need to supply a passphrase of at least
4 characters for the CA private key.
.IP
Once you have generated the CA you can distribute
its certificate part, [dir]/CA/cacert.pem, to other
workstations where VNC viewers will be run. One will
need to "import" this certicate in the applications,
e.g. Web browser, Java applet plugin, stunnel, etc.
Next, you can create and sign keys using the CA with
the \fB-sslGenCert\fR option below.
.IP
Examples:
x11vnc \fB-sslGenCA\fR
x11vnc \fB-sslGenCA\fR ~/myCAdir
x11vnc \fB-ssldir\fR ~/myCAdir \fB-sslGenCA\fR
.IP
(the last two lines are equivalent)
.PP
\fB-sslGenCert\fR \fItype\fR \fIname\fR
.IP
Generate a VNC server or client certificate and private
key pair signed by the CA created previously with
\fB-sslGenCA.\fR The
.IR openssl (1)
program must be installed
on the system and available in PATH.
.IP
After the Certificate is generated the command exits;
the VNC server is not run.
.IP
The type of key to be generated is the string \fItype\fR.
It is either "server" (i.e. for use by x11vnc) or
"client" (for a VNC viewer). Note that typically
only "server" is used: the VNC clients authenticate
themselves by a non-public-key method (e.g. VNC or
unix password). \fItype\fR is required.
.IP
An arbitrary default name you want to associate with
the key is supplied by the \fIname\fR string. You can
change it at the various prompts when creating the key.
\fIname\fR is optional.
.IP
If name is left blank for clients keys then "nobody"
is used. If left blank for server keys, then the
primary server key: "server.pem" is created (this
is the saved one referenced by "\fB-ssl\fR \fISAVE\fR" when the
server is started)
.IP
If \fIname\fR begins with the string "self:" then
a self-signed certificate is created instead of one
signed by your CA key.
.IP
If \fIname\fR begins with the string "req:" then only a
key (.key) and a certificate signing *request* (.req)
are generated. You can then send the .req file to
an external CA (even a professional one, e.g. Thawte)
and then combine the .key and the received cert into
the .pem file with the same basename.
.IP
The distinction between "server" and "client" is
simply the choice of output filenames and sub-directory.
This makes it so the \fB-ssl\fR SAVE-name option can easily
pick up the x11vnc PEM file this option generates.
And similarly makes it easy for the \fB-sslverify\fR option
to pick up your client certs.
.IP
There is nothing special about the filename or directory
location of either the "server" and "client" certs.
You can rename the files or move them to wherever
you like.
.IP
Precede this option with \fB-ssldir\fR [dir] to use a
directory other than the default ~/.vnc/certs You will
need to run \fB-sslGenCA\fR on that directory first before
doing any \fB-sslGenCert\fR key creation.
.IP
Note you cannot recreate a cert with exactly the same
distiguished name (DN) as an existing one. To do so,
you will need to edit the [dir]/CA/index.txt file to
delete the line.
.IP
Similar to \fB-sslGenCA,\fR you will be prompted to fill
in some information that will be recorded in the
certificate when it is created. Tip: if you know
the fully-quailified hostname other people will be
connecting to you can use that as the CommonName "CN"
to avoid some applications (e.g. web browsers and java
plugin) complaining it does not match the hostname.
.IP
You will also need to supply the CA private key
passphrase to unlock the private key created from
\fB-sslGenCA.\fR This private key is used to sign the server
or client certicate.
.IP
The "server" certs can be used by x11vnc directly by
pointing to them via the \fB-ssl\fR [pem] option. The default
file will be ~/.vnc/certs/server.pem. This one would
be used by simply typing \fB-ssl\fR SAVE. The pem file
contains both the certificate and the private key.
server.crt file contains the cert only.
.IP
The "client" cert + private key file will need
to be copied and imported into the VNC viewer
side applications (Web browser, Java plugin,
stunnel, etc.) Once that is done you can delete the
"client" private key file on this machine since
it is only needed on the VNC viewer side. The,
e.g. ~/.vnc/certs/clients/<name>.pem contains both
the cert and private key. The <name>.crt contains the
certificate only.
.IP
NOTE: It is very important to know one should always
generate new keys with a passphrase. Otherwise if an
untrusted user steals the key file he could use it to
masquerade as the x11vnc server (or VNC viewer client).
You will be prompted whether to encrypt the key with
a passphrase or not. It is recommended that you do.
One inconvenience to a passphrase is that it must
be suppled every time x11vnc or the client app is
started up.
.IP
Examples:
.IP
x11vnc \fB-sslGenCert\fR server
x11vnc \fB-ssl\fR SAVE \fB-display\fR :0 ...
.IP
and then on viewer using ssl_vncviewer stunnel wrapper
(see the FAQ):
ssl_vncviewer \fB-verify\fR ./cacert.crt hostname:0
.IP
(this assumes the cacert.crt cert from \fB-sslGenCA\fR
was safely copied to the VNC viewer machine where
ssl_vncviewer is run)
.IP
Example using a name:
.IP
x11vnc \fB-sslGenCert\fR server charlie
x11vnc \fB-ssl\fR SAVE-charlie \fB-display\fR :0 ...
.IP
Example for a client certificate (rarely used):
.IP
x11vnc \fB-sslGenCert\fR client roger
scp ~/.vnc/certs/clients/roger.pem somehost:.
rm ~/.vnc/certs/clients/roger.pem
.IP
x11vnc is then started with the the option \fB-sslverify\fR
~/.vnc/certs/clients/roger.crt (or simply \fB-sslverify\fR
roger), and on the viewer user on somehost could do
for example:
.IP
ssl_vncviewer \fB-mycert\fR ./roger.pem hostname:0
.PP
\fB-sslEncKey\fR \fI[pem]\fR
.IP
Utility to encrypt an existing PEM file with a
passphrase you supply when prompted. For that key to be
used (e.g. by x11vnc) the passphrase must be supplied
each time.
.IP
The "SAVE" notation described under \fB-ssl\fR applies as
well. (precede this option with \fB-ssldir\fR [dir] to refer
a directory besides the default ~/.vnc/certs)
.IP
The
.IR openssl (1)
program must be installed on the system
and available in PATH. After the Key file is encrypted
the command exits; the VNC server is not run.
.IP
Examples:
x11vnc \fB-sslEncKey\fR /path/to/foo.pem
x11vnc \fB-sslEncKey\fR SAVE
x11vnc \fB-sslEncKey\fR SAVE-charlie
.PP
\fB-sslCertInfo\fR \fI[pem]\fR
.IP
Prints out information about an existing PEM file.
In addition the public certificate is also printed.
The
.IR openssl (1)
program must be in PATH. Basically the
command "openssl x509 \fB-text"\fR is run on the pem.
.IP
The "SAVE" notation described under \fB-ssl\fR applies
as well.
.IP
Using "LIST" will give a list of all certs being
managed (in the ~/.vnc/certs dir, use \fB-ssldir\fR to refer
to another dir). "ALL" will print out the info for
every managed key (this can be very long). Giving a
client or server cert shortname will also try a lookup
(e.g. \fB-sslCertInfo\fR charlie). Use "LISTL" or "LL"
for a long (ls \fB-l\fR style) listing.
.IP
Using "HASHON" will create subdirs [dir]/HASH and
[dir]/HASH with OpenSSL hash filenames (e.g. 0d5fbbf1.0)
symlinks pointing up to the corresponding *.crt file.
([dir] is ~/.vnc/certs or one given by \fB-ssldir.)\fR
This is a useful way for other OpenSSL applications
(e.g. stunnel) to access all of the certs without
having to concatenate them. x11vnc will not use them
unless you specifically reference them. "HASHOFF"
removes these HASH subdirs.
.IP
The LIST, LISTL, LL, ALL, HASHON, HASHOFF words can
also be lowercase, e.g. "list".
.PP
\fB-sslDelCert\fR \fI[pem]\fR
.IP
Prompts you to delete all .crt .pem .key .req files
associated with [pem]. "SAVE" and lookups as in
\fB-sslCertInfo\fR apply as well.
.PP
\fB-stunnel\fR \fI[pem]\fR
.IP
Use the
.IR stunnel (8)
(www.stunnel.org) to provide an
encrypted SSL tunnel between viewers and x11vnc.
.IP
This external tunnel method was implemented prior to the
integrated \fB-ssl\fR encryption described above. It still
works well. This requires stunnel to be installed
on the system and available via PATH (n.b. stunnel is
often installed in sbin directories). Version 4.x of
stunnel is assumed (but see \fB-stunnel3\fR below.)
.IP
[pem] is optional, use "\fB-stunnel\fR \fI/path/to/stunnel.pem\fR"
to specify a PEM certificate file to pass to stunnel.
Whether one is needed or not depends on your stunnel
configuration. stunnel often generates one at install
time. See the stunnel documentation for details.
.IP
stunnel is started up as a child process of x11vnc and
any SSL connections stunnel receives are decrypted and
sent to x11vnc over a local socket. The strings
"The SSL VNC desktop is ..." and "SSLPORT=..."
are printed out at startup to indicate this.
.IP
The \fB-localhost\fR option is enforced by default
to avoid people routing around the SSL channel.
Set STUNNEL_DISABLE_LOCALHOST=1 before starting x11vnc
to disable the requirement.
.IP
Your VNC viewer will also need to be able to connect via
SSL. Unfortunately not too many do this. UltraVNC has
an encryption plugin but it does not seem to be SSL.
.IP
Also, in the x11vnc distribution, a patched TightVNC
Java applet is provided in classes/ssl that does SSL
connections (only).
.IP
It is also not too difficult to set up an stunnel or
other SSL tunnel on the viewer side. A simple example
on Unix using stunnel 3.x is:
.IP
% stunnel \fB-c\fR \fB-d\fR localhost:5901 \fB-r\fR remotehost:5900
% vncviewer localhost:1
.IP
For Windows, stunnel has been ported to it and there
are probably other such tools available. See the FAQ
for more examples.
.PP
\fB-stunnel3\fR \fI[pem]\fR
.IP
Use version 3.x stunnel command line syntax instead of
version 4.x
.PP
\fB-https\fR \fI[port]\fR
.IP
Choose a separate HTTPS port (-ssl mode only).
.IP
In \fB-ssl\fR mode, it turns out you can use the
single VNC port (e.g. 5900) for both VNC and HTTPS
connections. (HTTPS is used to retrieve a SSL-aware
VncViewer.jar applet that is provided with x11vnc).
Since both use SSL the implementation was extended to
detect if HTTP traffic (i.e. GET) is taking place and
handle it accordingly. The URL would be, e.g.:
.IP
https://mymachine.org:5900/
.IP
This is convenient for firewalls, etc, because only one
port needs to be allowed in. However, this heuristic
adds a few seconds delay to each connection and can be
unreliable (especially if the user takes much time to
ponder the Certificate dialogs in his browser, Java VM,
or VNC Viewer applet. That's right 3 separate "Are
you sure you want to connect" dialogs!)
.IP
So use the \fB-https\fR option to provide a separate, more
reliable HTTPS port that x11vnc will listen on. If
[port] is not provided (or is 0), one is autoselected.
The URL to use is printed out at startup.
.IP
The SSL Java applet directory is specified via the
\fB-httpdir\fR option. If not supplied it will try to guess
the directory as though the \fB-http\fR option was supplied.
.PP
\fB-usepw\fR \fB-usepw\fR
.IP .IP
If no other password method was supplied on the command If no other password method was supplied on the command
@ -524,6 +1274,9 @@ use it with \fB-passwdfile;\fR otherwise, prompt the user
for a password to create ~/.vnc/passwd and use it with for a password to create ~/.vnc/passwd and use it with
the \fB-rfbauth\fR option. If none of these succeed x11vnc the \fB-rfbauth\fR option. If none of these succeed x11vnc
exits immediately. exits immediately.
.IP
Note: \fB-unixpw\fR currently does not count as a password
method by this option.
.PP .PP
\fB-storepasswd\fR \fIpass\fR \fIfile\fR \fB-storepasswd\fR \fIpass\fR \fIfile\fR
.IP .IP
@ -556,7 +1309,7 @@ otherwise the client is rejected. See below for an
extension to accept a client view-only. extension to accept a client view-only.
.IP .IP
If x11vnc is running as root (say from If x11vnc is running as root (say from
.IR inetd (1) .IR inetd (8)
or from or from
display managers display managers
.IR xdm (1) .IR xdm (1)
@ -642,7 +1395,7 @@ interpreted by x11vnc. Example: \fB-gone\fR 'xlock &'
\fB-users\fR \fIlist\fR \fB-users\fR \fIlist\fR
.IP .IP
If x11vnc is started as root (say from If x11vnc is started as root (say from
.IR inetd (1) .IR inetd (8)
or from or from
display managers display managers
.IR xdm (1) .IR xdm (1)
@ -660,38 +1413,47 @@ perform its primary functions. The option was added
to make some of the *external* utility commands x11vnc to make some of the *external* utility commands x11vnc
occasionally runs work properly. In particular under occasionally runs work properly. In particular under
GNOME and KDE to implement the "\fB-solid\fR \fIcolor\fR" feature GNOME and KDE to implement the "\fB-solid\fR \fIcolor\fR" feature
external commands (gconftool-2 and dcop) must be run external commands (gconftool-2 and dcop) unfortunately
as the user owning the desktop session. Since this must be run as the user owning the desktop session.
option switches userid it also affects the userid used Since this option switches userid it also affects the
to run the processes for the \fB-accept\fR and \fB-gone\fR options. userid used to run the processes for the \fB-accept\fR and
It also affects the ability to read files for options \fB-gone\fR options. It also affects the ability to read
such as \fB-connect,\fR \fB-allow,\fR and \fB-remap.\fR Note that the files for options such as \fB-connect,\fR \fB-allow,\fR and \fB-remap.\fR
\fB-connect\fR file is also sometimes written to. Note that the \fB-connect\fR file is also sometimes written
.IP to.
So be careful with this option since in many situations .IP
So be careful with this option since in some situations
its use can decrease security. its use can decrease security.
.IP .IP
The switch to a user will only take place if the In general the switch to a user will only take place
display can still be successfully opened as that user if the display can still be successfully opened as that
(this is primarily to try to guess the actual owner user (this is primarily to try to guess the actual owner
of the session). Example: "\fB-users\fR \fIfred,wilma,betty\fR". of the session). Example: "\fB-users\fR \fIfred,wilma,betty\fR".
Note that a malicious user "barney" by quickly using Note that a malicious user "barney" by quickly using
"xhost +" when logging in may get x11vnc to switch "xhost +" when logging in may possibly get the x11vnc
to user "fred". What happens next? process to switch to user "fred". What happens next?
.IP .IP
Under display managers it may be a long time before Under display managers it may be a long time before
the switch succeeds (i.e. a user logs in). To make the switch succeeds (i.e. a user logs in). To instead
it switch immediately regardless if the display make it switch immediately regardless if the display
can be reopened prefix the username with the "+" can be reopened prefix the username with the "+"
character. E.g. "\fB-users\fR \fI+bob\fR" or "\fB-users\fR \fI+nobody\fR". character. E.g. "\fB-users\fR \fI+bob\fR" or "\fB-users\fR \fI+nobody\fR".
.IP
The latter (i.e. switching immediately to user The latter (i.e. switching immediately to user
"nobody") is probably the only use of this option "nobody") is probably the only use of this option
that increases security. that increases security.
.IP .IP
In \fB-unixpw\fR mode, if "\fB-users\fR \fIunixpw=\fR" is supplied
then after a user authenticates himself via the
\fB-unixpw\fR mechanism, x11vnc will try to switch to that
user as though "\fB-users\fR \fI+username\fR" had been supplied.
If you want to limit which users this will be done for,
provide them as a comma separated list after "unixpw="
.IP
To immediately switch to a user *before* connections To immediately switch to a user *before* connections
to the X display are made or any files opened use the to the X display are made or any files opened use the
"=" character: "\fB-users\fR \fI=bob\fR". That user needs to "=" character: "\fB-users\fR \fI=bob\fR". That user needs to
be able to open the X display of course. be able to open the X display and any files of course.
.IP .IP
The special user "guess=" means to examine the utmpx The special user "guess=" means to examine the utmpx
database (see database (see
@ -701,18 +1463,18 @@ the display number (from DISPLAY or \fB-display\fR option)
and try him/her. To limit the list of guesses, use: and try him/her. To limit the list of guesses, use:
"\fB-users\fR \fIguess=bob,betty\fR". "\fB-users\fR \fIguess=bob,betty\fR".
.IP .IP
Even more sinister is the special user "lurk=" that Even more sinister is the special user "lurk="
means to try to guess the DISPLAY from the utmpx login that means to try to guess the DISPLAY from the utmpx
database as well. So it "lurks" waiting for anyone login database as well. So it "lurks" waiting for
to log into an X session and then connects to it. anyone to log into an X session and then connects to it.
Specify a list of users after the = to limit which Specify a list of users after the = to limit which users
users will be tried. To enable a different searching will be tried. To enable a different searching mode, if
mode, if the first user in the list is something like the first user in the list is something like ":0" or
":0" or ":0-2" that indicates a range of DISPLAY ":0-2" that indicates a range of DISPLAY numbers that
numbers that will be tried (regardless of whether will be tried (regardless of whether they are in the
they are in the utmpx database) for all users that utmpx database) for all users that are logged in. Also
are logged in. Examples: "\fB-users\fR \fIlurk=\fR" and also see the "\fB-display\fR \fIWAIT:...\fR" functionality. Examples:
"\fB-users\fR \fIlurk=:0-1,bob,mary\fR" "\fB-users\fR \fIlurk=\fR" and also "\fB-users\fR \fIlurk=:0-1,bob,mary\fR"
.IP .IP
Be especially careful using the "guess=" and "lurk=" Be especially careful using the "guess=" and "lurk="
modes. They are not recommended for use on machines modes. They are not recommended for use on machines
@ -752,7 +1514,7 @@ commands are run for GNOME and KDE respectively.
Other desktops won't work, e.g. Xfce (send us the Other desktops won't work, e.g. Xfce (send us the
corresponding commands if you find them). If x11vnc is corresponding commands if you find them). If x11vnc is
running as root ( running as root (
.IR inetd (1) .IR inetd (8)
or or
.IR gdm (1) .IR gdm (1)
), the \fB-users\fR option ), the \fB-users\fR option
@ -2025,7 +2787,7 @@ for a video camera that delivers the pixel data as
mode if the bpp is 24. mode if the bpp is 24.
.IP .IP
video4linux: on Linux some attempt is made to handle video4linux: on Linux some attempt is made to handle
video devices (webcams or tv tuners) automatically. video devices (webcams or TV tuners) automatically.
The idea is the WxHxB will be extracted from the The idea is the WxHxB will be extracted from the
device itself. So if you do not supply "@WxHxB... device itself. So if you do not supply "@WxHxB...
parameters x11vnc will try to determine them. It first parameters x11vnc will try to determine them. It first
@ -2074,7 +2836,7 @@ RGB555, RGB565, RGB24, and RGB32 (with bpp 8, 8, 16, 16,
24, and 32 respectively). See http://www.linuxtv.org 24, and 32 respectively). See http://www.linuxtv.org
for more info (V4L api). for more info (V4L api).
.IP .IP
For tv/rf tuner cards one can set the tuning mode For TV/rf tuner cards one can set the tuning mode
via tun=XXX where XXX can be one of PAL, NTSC, SECAM, via tun=XXX where XXX can be one of PAL, NTSC, SECAM,
or AUTO. or AUTO.
.IP .IP
@ -2897,7 +3659,8 @@ http_url auth xauth users rootshift clipshift
scale_str scaled_x scaled_y scale_numer scale_denom scale_str scaled_x scaled_y scale_numer scale_denom
scale_fac scaling_blend scaling_nomult4 scaling_pad scale_fac scaling_blend scaling_nomult4 scaling_pad
scaling_interpolate inetd privremote unsafe safer nocmds scaling_interpolate inetd privremote unsafe safer nocmds
passwdfile usepw using_shm passwdfile unixpw unixpw_nis unixpw_list ssl ssl_pem
sslverify stunnel stunnel_pem https usepw using_shm
logfile o flag rc norc h help V version lastmod bg logfile o flag rc norc h help V version lastmod bg
sigpipe threads readrate netrate netlatency pipeinput sigpipe threads readrate netrate netlatency pipeinput
clients client_count pid ext_xtest ext_xtrap ext_xrecord clients client_count pid ext_xtest ext_xtrap ext_xrecord

@ -960,7 +960,7 @@ static void quick_pw(char *str) {
} }
fprintf(stdout, "password: "); fprintf(stdout, "password: ");
/* no_external_cmds does not apply */ /* test mode: no_external_cmds does not apply */
system("stty -echo"); system("stty -echo");
if(fgets(tmp, 128, stdin) == NULL) { if(fgets(tmp, 128, stdin) == NULL) {
fprintf(stdout, "\n"); fprintf(stdout, "\n");
@ -1003,7 +1003,7 @@ static void quick_pw(char *str) {
exit(1); exit(1);
} }
} else { } else {
if (su_verify(p, q+1)) { if (su_verify(p, q+1, NULL, NULL, NULL)) {
fprintf(stdout, "Y %s\n", p); fprintf(stdout, "Y %s\n", p);
exit(0); exit(0);
} else { } else {
@ -1254,7 +1254,7 @@ static void check_loop_mode(int argc, char* argv[]) {
perror("fork"); perror("fork");
exit(1); exit(1);
} else { } else {
/* no_external_cmds does not apply */ /* loop mode: no_external_cmds does not apply */
execvp(argv[0], argv2); execvp(argv[0], argv2);
exit(1); exit(1);
} }
@ -1283,6 +1283,7 @@ static void store_homedir_passwd(char *file) {
str1[0] = '\0'; str1[0] = '\0';
str2[0] = '\0'; str2[0] = '\0';
/* storepasswd */
if (no_external_cmds) { if (no_external_cmds) {
fprintf(stderr, "-nocmds cannot be used with -storepasswd\n"); fprintf(stderr, "-nocmds cannot be used with -storepasswd\n");
exit(1); exit(1);
@ -1388,6 +1389,7 @@ int main(int argc, char* argv[]) {
int dt = 0, bg = 0; int dt = 0, bg = 0;
int got_rfbwait = 0; int got_rfbwait = 0;
int got_httpdir = 0, try_http = 0; int got_httpdir = 0, try_http = 0;
int waited_for_client = 0;
XImage *fb0 = NULL; XImage *fb0 = NULL;
/* used to pass args we do not know about to rfbGetScreen(): */ /* used to pass args we do not know about to rfbGetScreen(): */
@ -2728,20 +2730,33 @@ int main(int argc, char* argv[]) {
use_xkb_modtweak = 0; use_xkb_modtweak = 0;
#endif #endif
#ifdef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER
if (filexfer) {
rfbRegisterTightVNCFileTransferExtension();
} else {
rfbUnregisterTightVNCFileTransferExtension();
}
#endif
initialize_allowed_input();
if (users_list && strstr(users_list, "lurk=")) { if (users_list && strstr(users_list, "lurk=")) {
if (use_dpy) { if (use_dpy) {
rfbLog("warning: -display does not make sense in " rfbLog("warning: -display does not make sense in "
"\"lurk=\" mode...\n"); "\"lurk=\" mode...\n");
} }
lurk_loop(users_list); lurk_loop(users_list);
} else if (use_dpy && strstr(use_dpy, "WAIT:") == use_dpy) {
waited_for_client = wait_for_client(&argc_vnc, argv_vnc,
try_http && ! got_httpdir);
} }
if (use_dpy) { if (use_dpy) {
dpy = XOpenDisplay(use_dpy); dpy = XOpenDisplay_wr(use_dpy);
} else if ( (use_dpy = getenv("DISPLAY")) ) { } else if ( (use_dpy = getenv("DISPLAY")) ) {
dpy = XOpenDisplay(use_dpy); dpy = XOpenDisplay_wr(use_dpy);
} else { } else {
dpy = XOpenDisplay(""); dpy = XOpenDisplay_wr("");
} }
if (! dpy && raw_fb_str) { if (! dpy && raw_fb_str) {
@ -2764,7 +2779,7 @@ int main(int argc, char* argv[]) {
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");
use_dpy = ":0"; use_dpy = ":0";
dpy = XOpenDisplay(use_dpy); dpy = XOpenDisplay_wr(use_dpy);
if (dpy) { if (dpy) {
rfbLog("*** XOpenDisplay of \":0\" successful.\n"); rfbLog("*** XOpenDisplay of \":0\" successful.\n");
} }
@ -2803,7 +2818,7 @@ int main(int argc, char* argv[]) {
fflush(stderr); fflush(stderr);
fflush(stdout); fflush(stdout);
usleep(30 * 1000); /* still needed? */ usleep(30 * 1000); /* still needed? */
XCloseDisplay(dpy); XCloseDisplay_wr(dpy);
exit(rc); exit(rc);
} }
@ -3133,13 +3148,6 @@ int main(int argc, char* argv[]) {
raw_fb_pass_go_and_collect_200_dollars: raw_fb_pass_go_and_collect_200_dollars:
#ifdef LIBVNCSERVER_WITH_TIGHTVNC_FILETRANSFER
if (filexfer) {
rfbRegisterTightVNCFileTransferExtension();
} else {
rfbUnregisterTightVNCFileTransferExtension();
}
#endif
if (! dt) { if (! dt) {
static char str[] = "-desktop"; static char str[] = "-desktop";
argv_vnc[argc_vnc++] = str; argv_vnc[argc_vnc++] = str;
@ -3162,8 +3170,15 @@ int main(int argc, char* argv[]) {
initialize_screen(&argc_vnc, argv_vnc, fb0); initialize_screen(&argc_vnc, argv_vnc, fb0);
if (try_http && ! got_httpdir && check_httpdir()) { if (waited_for_client && fake_fb) {
http_connections(1); free(fake_fb);
fake_fb = NULL;
}
if (! waited_for_client) {
if (try_http && ! got_httpdir && check_httpdir()) {
http_connections(1);
}
} }
initialize_tiles(); initialize_tiles();
@ -3180,10 +3195,10 @@ int main(int argc, char* argv[]) {
initialize_keyboard_and_pointer(); initialize_keyboard_and_pointer();
initialize_allowed_input();
if (inetd && use_openssl) { if (inetd && use_openssl) {
accept_openssl(OPENSSL_INETD); if (! waited_for_client) {
accept_openssl(OPENSSL_INETD);
}
} }
if (! inetd && ! use_openssl) { if (! inetd && ! use_openssl) {
if (! screen->port || screen->listenSock < 0) { if (! screen->port || screen->listenSock < 0) {

@ -114,7 +114,7 @@
#define PASSWD_UNLESS_NOPW 0 #define PASSWD_UNLESS_NOPW 0
#endif #endif
#define REL81 #define noREL81
/* /*
* Beginning of support for small binary footprint build for embedded * Beginning of support for small binary footprint build for embedded
@ -320,6 +320,8 @@ extern char lastmod[];
extern Display *dpy; /* the single display screen we connect to */ extern Display *dpy; /* the single display screen we connect to */
extern int scr; extern int scr;
extern char *xauth_raw_data;
extern int xauth_raw_len;
extern Window window, rootwin; /* polled window, root window (usu. same) */ extern Window window, rootwin; /* polled window, root window (usu. same) */
extern Visual *default_visual; /* the default visual (unless -visual) */ extern Visual *default_visual; /* the default visual (unless -visual) */
extern int bpp, depth; extern int bpp, depth;

@ -15,12 +15,14 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0; int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */ /* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.8.1 lastmod: 2006-06-03"; char lastmod[] = "0.8.2 lastmod: 2006-06-08";
/* X display info */ /* X display info */
Display *dpy = NULL; /* the single display screen we connect to */ Display *dpy = NULL; /* the single display screen we connect to */
int scr = 0; int scr = 0;
char *xauth_raw_data = NULL;
int xauth_raw_len = 0;
Window window = None, rootwin = None; /* polled window, root window (usu. same) */ Window window = None, rootwin = None; /* polled window, root window (usu. same) */
Visual *default_visual = NULL; /* the default visual (unless -visual) */ Visual *default_visual = NULL; /* the default visual (unless -visual) */
int bpp = 0, depth = 0; int bpp = 0, depth = 0;

@ -454,7 +454,7 @@ static void grab_buster_watch(int parent, char *dstr) {
} }
/* overwrite original dpy, we let orig connection sit unused. */ /* overwrite original dpy, we let orig connection sit unused. */
dpy = XOpenDisplay(dstr); dpy = XOpenDisplay_wr(dstr);
if (!dpy) { if (!dpy) {
fprintf(stderr, "grab_buster_watch: could not reopen: %s\n", fprintf(stderr, "grab_buster_watch: could not reopen: %s\n",
dstr); dstr);
@ -518,7 +518,7 @@ void spawn_grab_buster(void) {
RAWFB_RET_VOID RAWFB_RET_VOID
XCloseDisplay(dpy); XCloseDisplay_wr(dpy);
dpy = NULL; dpy = NULL;
if ((pid = fork()) > 0) { if ((pid = fork()) > 0) {
@ -539,7 +539,7 @@ void spawn_grab_buster(void) {
exit(0); exit(0);
} }
dpy = XOpenDisplay(dstr); dpy = XOpenDisplay_wr(dstr);
if (!dpy) { if (!dpy) {
rfbLog("failed to reopen display %s in spawn_grab_buster\n", rfbLog("failed to reopen display %s in spawn_grab_buster\n",
dstr); dstr);

@ -40,6 +40,10 @@ void initialize_xkb(void) {
return; return;
} }
if (! xauth_raw(1)) {
return;
}
if (! XkbOpenDisplay(DisplayString(dpy), &xkb_base_event_type, &ir, if (! XkbOpenDisplay(DisplayString(dpy), &xkb_base_event_type, &ir,
NULL, NULL, &reason) ) { NULL, NULL, &reason) ) {
if (! quiet) { if (! quiet) {
@ -49,6 +53,7 @@ void initialize_xkb(void) {
xkb_base_event_type = 0; xkb_base_event_type = 0;
xkb_present = 0; xkb_present = 0;
} }
xauth_raw(0);
} }
void initialize_watch_bell(void) { void initialize_watch_bell(void) {

@ -118,8 +118,8 @@ static void xrecord_grabserver(int start) {
XSync(gdpy_ctrl, True); XSync(gdpy_ctrl, True);
if (! rc_grab || trapped_record_xerror) { if (! rc_grab || trapped_record_xerror) {
XCloseDisplay(gdpy_ctrl); XCloseDisplay_wr(gdpy_ctrl);
XCloseDisplay(gdpy_data); XCloseDisplay_wr(gdpy_data);
gdpy_ctrl = NULL; gdpy_ctrl = NULL;
gdpy_data = NULL; gdpy_data = NULL;
XSetErrorHandler(old_handler); XSetErrorHandler(old_handler);
@ -127,8 +127,8 @@ static void xrecord_grabserver(int start) {
} }
rc = XRecordEnableContextAsync(gdpy_data, rc_grab, record_grab, NULL); rc = XRecordEnableContextAsync(gdpy_data, rc_grab, record_grab, NULL);
if (!rc || trapped_record_xerror) { if (!rc || trapped_record_xerror) {
XCloseDisplay(gdpy_ctrl); XCloseDisplay_wr(gdpy_ctrl);
XCloseDisplay(gdpy_data); XCloseDisplay_wr(gdpy_data);
gdpy_ctrl = NULL; gdpy_ctrl = NULL;
gdpy_data = NULL; gdpy_data = NULL;
XSetErrorHandler(old_handler); XSetErrorHandler(old_handler);
@ -179,18 +179,18 @@ void initialize_xrecord(void) {
X_LOCK; X_LOCK;
/* open a 2nd control connection to DISPLAY: */ /* open a 2nd control connection to DISPLAY: */
if (rdpy_data) { if (rdpy_data) {
XCloseDisplay(rdpy_data); XCloseDisplay_wr(rdpy_data);
rdpy_data = NULL; rdpy_data = NULL;
} }
if (rdpy_ctrl) { if (rdpy_ctrl) {
XCloseDisplay(rdpy_ctrl); XCloseDisplay_wr(rdpy_ctrl);
rdpy_ctrl = NULL; rdpy_ctrl = NULL;
} }
rdpy_ctrl = XOpenDisplay(DisplayString(dpy)); rdpy_ctrl = XOpenDisplay_wr(DisplayString(dpy));
XSync(dpy, True); XSync(dpy, True);
XSync(rdpy_ctrl, True); XSync(rdpy_ctrl, True);
/* open datalink connection to DISPLAY: */ /* open datalink connection to DISPLAY: */
rdpy_data = XOpenDisplay(DisplayString(dpy)); rdpy_data = XOpenDisplay_wr(DisplayString(dpy));
if (!rdpy_ctrl || ! rdpy_data) { if (!rdpy_ctrl || ! rdpy_data) {
X_UNLOCK; X_UNLOCK;
return; return;
@ -206,19 +206,19 @@ void initialize_xrecord(void) {
* in place, why? Not sure, so we manually watch for grabs... * in place, why? Not sure, so we manually watch for grabs...
*/ */
if (gdpy_data) { if (gdpy_data) {
XCloseDisplay(gdpy_data); XCloseDisplay_wr(gdpy_data);
gdpy_data = NULL; gdpy_data = NULL;
} }
if (gdpy_ctrl) { if (gdpy_ctrl) {
XCloseDisplay(gdpy_ctrl); XCloseDisplay_wr(gdpy_ctrl);
gdpy_ctrl = NULL; gdpy_ctrl = NULL;
} }
xserver_grabbed = 0; xserver_grabbed = 0;
gdpy_ctrl = XOpenDisplay(DisplayString(dpy)); gdpy_ctrl = XOpenDisplay_wr(DisplayString(dpy));
XSync(dpy, True); XSync(dpy, True);
XSync(gdpy_ctrl, True); XSync(gdpy_ctrl, True);
gdpy_data = XOpenDisplay(DisplayString(dpy)); gdpy_data = XOpenDisplay_wr(DisplayString(dpy));
if (gdpy_ctrl && gdpy_data) { if (gdpy_ctrl && gdpy_data) {
disable_grabserver(gdpy_ctrl, 0); disable_grabserver(gdpy_ctrl, 0);
disable_grabserver(gdpy_data, 0); disable_grabserver(gdpy_data, 0);
@ -260,19 +260,19 @@ void shutdown_xrecord(void) {
} }
if (rdpy_data) { if (rdpy_data) {
XCloseDisplay(rdpy_data); XCloseDisplay_wr(rdpy_data);
rdpy_data = NULL; rdpy_data = NULL;
} }
if (rdpy_ctrl) { if (rdpy_ctrl) {
XCloseDisplay(rdpy_ctrl); XCloseDisplay_wr(rdpy_ctrl);
rdpy_ctrl = NULL; rdpy_ctrl = NULL;
} }
if (gdpy_data) { if (gdpy_data) {
XCloseDisplay(gdpy_data); XCloseDisplay_wr(gdpy_data);
gdpy_data = NULL; gdpy_data = NULL;
} }
if (gdpy_ctrl) { if (gdpy_ctrl) {
XCloseDisplay(gdpy_ctrl); XCloseDisplay_wr(gdpy_ctrl);
gdpy_ctrl = NULL; gdpy_ctrl = NULL;
} }
xserver_grabbed = 0; xserver_grabbed = 0;
@ -1367,16 +1367,16 @@ static void shutdown_record_context(XRecordContext rc, int bequiet, int reopen)
if (debug_scroll) { if (debug_scroll) {
rfbLog("closing RECORD data connection.\n"); rfbLog("closing RECORD data connection.\n");
} }
XCloseDisplay(rdpy_data); XCloseDisplay_wr(rdpy_data);
rdpy_data = NULL; rdpy_data = NULL;
if (debug_scroll) { if (debug_scroll) {
rfbLog("closing RECORD control connection.\n"); rfbLog("closing RECORD control connection.\n");
} }
XCloseDisplay(rdpy_ctrl); XCloseDisplay_wr(rdpy_ctrl);
rdpy_ctrl = NULL; rdpy_ctrl = NULL;
rdpy_ctrl = XOpenDisplay(dpystr); rdpy_ctrl = XOpenDisplay_wr(dpystr);
if (! rdpy_ctrl) { if (! rdpy_ctrl) {
rfbLog("Failed to reopen RECORD control connection:" rfbLog("Failed to reopen RECORD control connection:"
@ -1390,13 +1390,13 @@ static void shutdown_record_context(XRecordContext rc, int bequiet, int reopen)
disable_grabserver(rdpy_ctrl, 0); disable_grabserver(rdpy_ctrl, 0);
XSync(rdpy_ctrl, True); XSync(rdpy_ctrl, True);
rdpy_data = XOpenDisplay(dpystr); rdpy_data = XOpenDisplay_wr(dpystr);
if (! rdpy_data) { if (! rdpy_data) {
rfbLog("Failed to reopen RECORD data connection:" rfbLog("Failed to reopen RECORD data connection:"
"%s\n", dpystr); "%s\n", dpystr);
rfbLog(" disabling RECORD scroll detection.\n"); rfbLog(" disabling RECORD scroll detection.\n");
XCloseDisplay(rdpy_ctrl); XCloseDisplay_wr(rdpy_ctrl);
rdpy_ctrl = NULL; rdpy_ctrl = NULL;
use_xrecord = 0; use_xrecord = 0;
return; return;

@ -68,6 +68,10 @@ void disable_grabserver(Display *in_dpy, int change);
Bool XRecordQueryVersion_wr(Display *dpy, int *maj, int *min); Bool XRecordQueryVersion_wr(Display *dpy, int *maj, int *min);
int xauth_raw(int on);
Display *XOpenDisplay_wr(char *display_name);
int XCloseDisplay_wr(Display *display);
void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h); void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h);
static void upup_downdown_warning(KeyCode key, Bool down); static void upup_downdown_warning(KeyCode key, Bool down);
@ -879,4 +883,74 @@ Bool XRecordQueryVersion_wr(Display *dpy, int *maj, int *min) {
#endif #endif
} }
int xauth_raw(int on) {
char tmp[] = "/tmp/x11vnc-xauth.XXXXXX";
int tmp_fd = -1;
static char *old_xauthority = NULL;
static char *old_tmp = NULL;
int db = 0;
if (on) {
if (old_xauthority) {
free(old_xauthority);
old_xauthority = NULL;
}
if (old_tmp) {
free(old_tmp);
old_tmp = NULL;
}
if (xauth_raw_data) {
tmp_fd = mkstemp(tmp);
if (tmp_fd < 0) {
rfbLog("could not create tmp xauth file: %s\n", tmp);
return 0;
}
if (db) fprintf(stderr, "tmp: %s\n", tmp);
write(tmp_fd, xauth_raw_data, xauth_raw_len);
close(tmp_fd);
if (getenv("XAUTHORITY")) {
old_xauthority = strdup(getenv("XAUTHORITY"));
} else {
old_xauthority = strdup("");
}
set_env("XAUTHORITY", tmp);
old_tmp = strdup(tmp);
}
return 1;
} else {
if (old_xauthority) {
set_env("XAUTHORITY", old_xauthority);
free(old_xauthority);
old_xauthority = NULL;
}
if (old_tmp) {
unlink(old_tmp);
free(old_tmp);
old_tmp = NULL;
}
return 1;
}
}
Display *XOpenDisplay_wr(char *display_name) {
Display *d;
int db = 0;
if (! xauth_raw(1)) {
return NULL;
}
d = XOpenDisplay(display_name);
if (db) fprintf(stderr, "XOpenDisplay_wr: %s 0x%x\n", display_name, d);
xauth_raw(0);
return d;
}
int XCloseDisplay_wr(Display *display) {
int db = 0;
if (db) fprintf(stderr, "XCloseDisplay_wr: 0x%x\n", display);
return XCloseDisplay(display);
}

@ -68,4 +68,8 @@ extern void disable_grabserver(Display *in_dpy, int change);
extern Bool XRecordQueryVersion_wr(Display *dpy, int *maj, int *min); extern Bool XRecordQueryVersion_wr(Display *dpy, int *maj, int *min);
extern int xauth_raw(int on);
extern Display *XOpenDisplay_wr(char *display_name);
extern int XCloseDisplay_wr(Display *display);
#endif /* _X11VNC_XWRAPPERS_H */ #endif /* _X11VNC_XWRAPPERS_H */

Loading…
Cancel
Save