Commit 5b18d401 authored by runge's avatar runge

x11vnc -users, fix -solid on gnome/kde, configure.ac pwd.h wait.h and utmpx.h

parent b04336f9
2005-02-09 Karl Runge <runge@karlrunge.com>
* x11vnc: -users, fix -solid on gnome and kde.
* configure.ac: add pwd.h, wait.h, and utmpx.h checks.
2005-02-06 Karl Runge <runge@karlrunge.com> 2005-02-06 Karl Runge <runge@karlrunge.com>
* configure.ac: add /usr/sfw on Solaris when XFIXES, add * configure.ac: add /usr/sfw on Solaris when XFIXES, add
--with-jpeg=DIR --with-zlib=DIR, workaround bug when --with-jpeg=DIR --with-zlib=DIR, workaround bug when
......
...@@ -213,7 +213,7 @@ AC_SUBST(WSOCKLIB) ...@@ -213,7 +213,7 @@ AC_SUBST(WSOCKLIB)
# Checks for header files. # Checks for header files.
AC_HEADER_STDC AC_HEADER_STDC
AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h sys/time.h sys/timeb.h syslog.h unistd.h]) AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h sys/time.h sys/timeb.h syslog.h unistd.h pwd.h sys/wait.h utmpx.h])
# Checks for typedefs, structures, and compiler characteristics. # Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST AC_C_CONST
...@@ -234,7 +234,7 @@ AC_FUNC_VPRINTF ...@@ -234,7 +234,7 @@ AC_FUNC_VPRINTF
AC_FUNC_FORK AC_FUNC_FORK
AC_CHECK_LIB(nsl,gethostbyname) AC_CHECK_LIB(nsl,gethostbyname)
AC_CHECK_LIB(socket,socket) AC_CHECK_LIB(socket,socket)
AC_CHECK_FUNCS([ftime gethostbyname gethostname gettimeofday inet_ntoa memmove memset mkfifo select socket strchr strcspn strdup strerror strstr setsid]) AC_CHECK_FUNCS([ftime gethostbyname gethostname gettimeofday inet_ntoa memmove memset mkfifo select socket strchr strcspn strdup strerror strstr setsid getpwuid getpwnam getuid geteuid setuid waitpid setutxent])
# check, if shmget is in cygipc.a # check, if shmget is in cygipc.a
AC_CHECK_LIB(cygipc,shmget) AC_CHECK_LIB(cygipc,shmget)
......
2005-02-09 Karl Runge <runge@karlrunge.com>
* Add -users switch user mechanism and related utilities.
* fix -solid for gnome and kde.
* exit earlier on trapped XIO errors.
2005-02-05 Karl Runge <runge@karlrunge.com> 2005-02-05 Karl Runge <runge@karlrunge.com>
* -solid solid color background when clients are connected. * -solid solid color background when clients are connected.
* -opts/-? to show option names only. * -opts/-? to show option names only.
......
x11vnc README file Date: Sat Feb 5 12:56:36 EST 2005 x11vnc README file Date: Wed Feb 9 00:21:28 EST 2005
The following information is taken from these URLs: The following information is taken from these URLs:
...@@ -354,16 +354,34 @@ vncviewer -via $host localhost:0 # must be TightVNC vncviewer. ...@@ -354,16 +354,34 @@ vncviewer -via $host localhost:0 # must be TightVNC vncviewer.
TightVNC encoding gives very good compression and performance, it even TightVNC encoding gives very good compression and performance, it even
makes a noticeable difference over a fast LAN) makes a noticeable difference over a fast LAN)
Shortcut: On Solaris 10 you can pick up everything just by insuring
that your PATH has /usr/sfw/bin (for gcc) and /usr/ccs/bin (for other
build tools), e.g.:
env PATH=/usr/sfw/bin:/usr/ccs/bin:$PATH sh -c './configure; make'
libjpeg is included in Solaris 9 and later (/usr/sfw/include and libjpeg is included in Solaris 9 and later (/usr/sfw/include and
/usr/sfw/lib), and zlib in Solaris 8 and later (/usr/include and /usr/sfw/lib), and zlib in Solaris 8 and later (/usr/include and
/usr/lib). To get the source for these libraries: libjpeg is available /usr/lib).
at [36]ftp://ftp.uu.net/graphics/jpeg/ and zlib at
So on Solaris 9 you can pick up everything with something like this:
env PATH=/usr/local/bin:/usr/ccs/bin:$PATH CPPFLAGS='-I /usr/sfw/include' LDF
LAGS='-L/usr/sfw/lib -R/usr/sfw/lib' sh -c './configure; make'
assuming your gcc is in /usr/local/bin. That is getting pretty long,
see those assignments split up in the build script below.
If your system does not have these libraries you can get the source
for these libraries to build them: libjpeg is available at
[36]ftp://ftp.uu.net/graphics/jpeg/ and zlib at
[37]http://www.gzip.org/zlib/. See also [37]http://www.gzip.org/zlib/. See also
[38]http://www.sunfreeware.com/ for Solaris binary packages of these [38]http://www.sunfreeware.com/ for Solaris binary packages of these
libraries. libraries as well as for gcc. Normally they will install into
/usr/local.
Here is a build script that indicates one way to pass the library Here is a build script that indicates one way to pass the library
locations information to the libvncserver configuration: locations information to the libvncserver configuration via the
CPPFLAGS and LDFLAGS environmental variables:
#!/bin/sh #!/bin/sh
# Build script for Solaris, etc, with gcc, libjpeg and libz in # Build script for Solaris, etc, with gcc, libjpeg and libz in
...@@ -511,11 +529,12 @@ ls -l ./x11vnc/x11vnc ...@@ -511,11 +529,12 @@ ls -l ./x11vnc/x11vnc
SunRay Gotcha #1: Note that even though your SunRay X11 DISPLAY is SunRay Gotcha #1: Note that even though your SunRay X11 DISPLAY is
something like :137, x11vnc still tries for port 5900 as its listening something like :137, x11vnc still tries for port 5900 as its listening
if it can get it, in which case the VNC display (i.e. the information port if it can get it, in which case the VNC display (i.e. the
you supply to the VNC viewer) is something like sunray-server:0 information you supply to the VNC viewer) is something like
(note the :0 corresponding to port 5900, it is not :137). If it cannot sunray-server:0 (note the :0 corresponding to port 5900, it is not
get 5900, it tries for 5901, and so on. You can also try to force the :137). If it cannot get 5900, it tries for 5901, and so on. You can
port (and thereby the VNC display) using the -rfbport NNNN option. also try to force the port (and thereby the VNC display) using the
-rfbport NNNN option.
Limitations: Limitations:
...@@ -530,8 +549,8 @@ ls -l ./x11vnc/x11vnc ...@@ -530,8 +549,8 @@ ls -l ./x11vnc/x11vnc
* A rate limiting factor for x11vnc performance is that video * A rate limiting factor for x11vnc performance is that video
hardware is optimized for writing, not reading (x11vnc reads the hardware is optimized for writing, not reading (x11vnc reads the
video framebuffer for the screen image data). The difference can video framebuffer for the screen image data). The difference can
be a factor of 10-50, and it usually takes about 0.5-1 sec to read be a factor of 10-200, and it usually takes about 0.5-1 sec to
in the whole video hardware framebuffer (5MB for 1280x1024 at read in the whole video hardware framebuffer (5MB for 1280x1024 at
depth 24). So whenever activity changes most of the screen there depth 24). So whenever activity changes most of the screen there
is a delay of 0.5-1 sec while x11vnc reads the changed regions in. is a delay of 0.5-1 sec while x11vnc reads the changed regions in.
To get a sense of the read and write speeds of your video card, To get a sense of the read and write speeds of your video card,
...@@ -540,7 +559,7 @@ ls -l ./x11vnc/x11vnc ...@@ -540,7 +559,7 @@ ls -l ./x11vnc/x11vnc
direct graphics access the dga command (press "b" to run the direct graphics access the dga command (press "b" to run the
benchmark and then after a few seconds press "q" to quit). benchmark and then after a few seconds press "q" to quit).
On XFree86 it is actually possible to increase the framebuffer On XFree86 it is actually possible to increase the framebuffer
read speed considerably (5-50 times) by using the Shadow read speed considerably (5-100 times) by using the Shadow
Framebuffer (a copy of the framebuffer is kept in main memory and Framebuffer (a copy of the framebuffer is kept in main memory and
this can be read much more quickly). To do this one puts the line this can be read much more quickly). To do this one puts the line
Option "ShadowFB" "true" (and depending on video card driver, Option "ShadowFB" "true" (and depending on video card driver,
......
...@@ -1660,6 +1660,7 @@ proc split_query {query} { ...@@ -1660,6 +1660,7 @@ proc split_query {query} {
proc set_x11_display {name} { proc set_x11_display {name} {
global x11_display global x11_display
set x11_display "x11vnc X display: $name" set x11_display "x11vnc X display: $name"
wm title . "tkx11vnc - $name"
} }
proc set_vnc_display {name} { proc set_vnc_display {name} {
global vnc_display global vnc_display
...@@ -1671,6 +1672,7 @@ proc set_vnc_url {name} { ...@@ -1671,6 +1672,7 @@ proc set_vnc_url {name} {
} }
proc no_x11_display {} { proc no_x11_display {} {
set_x11_display "(*none*)" set_x11_display "(*none*)"
wm title . "tkx11vnc"
} }
proc no_vnc_display {} { proc no_vnc_display {} {
set_vnc_display "(*none*)" set_vnc_display "(*none*)"
...@@ -2391,6 +2393,7 @@ proc start_x11vnc {} { ...@@ -2391,6 +2393,7 @@ proc start_x11vnc {} {
proc run_remote_cmd {opts} { proc run_remote_cmd {opts} {
global menu_var x11vnc_prog x11vnc_cmdline x11vnc_xdisplay global menu_var x11vnc_prog x11vnc_cmdline x11vnc_xdisplay
global x11vnc_auth_file
set debug [in_debug_mode] set debug [in_debug_mode]
...@@ -2413,6 +2416,10 @@ proc run_remote_cmd {opts} { ...@@ -2413,6 +2416,10 @@ proc run_remote_cmd {opts} {
lappend cmd "-display" lappend cmd "-display"
lappend cmd $x11vnc_xdisplay lappend cmd $x11vnc_xdisplay
} }
if {$x11vnc_auth_file != ""} {
lappend cmd "-auth"
lappend cmd $x11vnc_auth_file
}
lappend cmd "-sync" lappend cmd "-sync"
foreach word $opts { foreach word $opts {
lappend cmd $word lappend cmd $word
...@@ -2501,6 +2508,7 @@ proc try_connect {} { ...@@ -2501,6 +2508,7 @@ proc try_connect {} {
# main: # main:
global env x11vnc_prog x11vnc_cmdline x11vnc_xdisplay x11vnc_connect; global env x11vnc_prog x11vnc_cmdline x11vnc_xdisplay x11vnc_connect;
global x11vnc_auth_file
global helpall helptext helpremote helplabel hostname; global helpall helptext helpremote helplabel hostname;
global all_settings reply_xdisplay always_update global all_settings reply_xdisplay always_update
global max_text_height max_text_width global max_text_height max_text_width
...@@ -2585,6 +2593,13 @@ if {[info exists env(X11VNC_XDISPLAY)]} { ...@@ -2585,6 +2593,13 @@ if {[info exists env(X11VNC_XDISPLAY)]} {
set x11vnc_xdisplay ":0"; set x11vnc_xdisplay ":0";
} }
if {[info exists env(X11VNC_AUTH_FILE)]} {
set x11vnc_auth_file $env(X11VNC_AUTH_FILE)
} else {
set x11vnc_auth_file ""
}
set hostname [exec uname -n] set hostname [exec uname -n]
#puts [exec env] #puts [exec env]
#puts "x11vnc_xdisplay: $x11vnc_xdisplay" #puts "x11vnc_xdisplay: $x11vnc_xdisplay"
......
...@@ -1666,6 +1666,7 @@ ...@@ -1666,6 +1666,7 @@
"proc set_x11_display {name} {\n" "proc set_x11_display {name} {\n"
" global x11_display\n" " global x11_display\n"
" set x11_display \"x11vnc X display: $name\"\n" " set x11_display \"x11vnc X display: $name\"\n"
" wm title . \"tkx11vnc - $name\"\n"
"}\n" "}\n"
"proc set_vnc_display {name} {\n" "proc set_vnc_display {name} {\n"
" global vnc_display\n" " global vnc_display\n"
...@@ -1677,6 +1678,7 @@ ...@@ -1677,6 +1678,7 @@
"}\n" "}\n"
"proc no_x11_display {} {\n" "proc no_x11_display {} {\n"
" set_x11_display \"(*none*)\"\n" " set_x11_display \"(*none*)\"\n"
" wm title . \"tkx11vnc\"\n"
"}\n" "}\n"
"proc no_vnc_display {} {\n" "proc no_vnc_display {} {\n"
" set_vnc_display \"(*none*)\"\n" " set_vnc_display \"(*none*)\"\n"
...@@ -2397,6 +2399,7 @@ ...@@ -2397,6 +2399,7 @@
"\n" "\n"
"proc run_remote_cmd {opts} {\n" "proc run_remote_cmd {opts} {\n"
" global menu_var x11vnc_prog x11vnc_cmdline x11vnc_xdisplay\n" " global menu_var x11vnc_prog x11vnc_cmdline x11vnc_xdisplay\n"
" global x11vnc_auth_file\n"
"\n" "\n"
" set debug [in_debug_mode]\n" " set debug [in_debug_mode]\n"
"\n" "\n"
...@@ -2419,6 +2422,10 @@ ...@@ -2419,6 +2422,10 @@
" lappend cmd \"-display\"\n" " lappend cmd \"-display\"\n"
" lappend cmd $x11vnc_xdisplay\n" " lappend cmd $x11vnc_xdisplay\n"
" }\n" " }\n"
" if {$x11vnc_auth_file != \"\"} {\n"
" lappend cmd \"-auth\"\n"
" lappend cmd $x11vnc_auth_file\n"
" }\n"
" lappend cmd \"-sync\"\n" " lappend cmd \"-sync\"\n"
" foreach word $opts {\n" " foreach word $opts {\n"
" lappend cmd $word\n" " lappend cmd $word\n"
...@@ -2507,6 +2514,7 @@ ...@@ -2507,6 +2514,7 @@
"# main:\n" "# main:\n"
"\n" "\n"
"global env x11vnc_prog x11vnc_cmdline x11vnc_xdisplay x11vnc_connect;\n" "global env x11vnc_prog x11vnc_cmdline x11vnc_xdisplay x11vnc_connect;\n"
"global x11vnc_auth_file\n"
"global helpall helptext helpremote helplabel hostname;\n" "global helpall helptext helpremote helplabel hostname;\n"
"global all_settings reply_xdisplay always_update\n" "global all_settings reply_xdisplay always_update\n"
"global max_text_height max_text_width\n" "global max_text_height max_text_width\n"
...@@ -2591,6 +2599,13 @@ ...@@ -2591,6 +2599,13 @@
" set x11vnc_xdisplay \":0\";\n" " set x11vnc_xdisplay \":0\";\n"
"}\n" "}\n"
"\n" "\n"
"if {[info exists env(X11VNC_AUTH_FILE)]} {\n"
" set x11vnc_auth_file $env(X11VNC_AUTH_FILE)\n"
"} else {\n"
" set x11vnc_auth_file \"\"\n"
"}\n"
"\n"
"\n"
"set hostname [exec uname -n]\n" "set hostname [exec uname -n]\n"
"#puts [exec env]\n" "#puts [exec env]\n"
"#puts \"x11vnc_xdisplay: $x11vnc_xdisplay\"\n" "#puts \"x11vnc_xdisplay: $x11vnc_xdisplay\"\n"
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
.TH X11VNC "1" "February 2005" "x11vnc " "User Commands" .TH X11VNC "1" "February 2005" "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.7.1pre, lastmod: 2005-02-05 version: 0.7.1pre, lastmod: 2005-02-08
.SH SYNOPSIS .SH SYNOPSIS
.B x11vnc .B x11vnc
[OPTION]... [OPTION]...
...@@ -58,11 +58,11 @@ environment variable to \fIdisp\fR. ...@@ -58,11 +58,11 @@ environment variable to \fIdisp\fR.
.IP .IP
Set the X authority file to be \fIfile\fR, equivalent to Set the X authority file to be \fIfile\fR, equivalent to
setting the XAUTHORITY environment variable to \fIfile\fR setting the XAUTHORITY environment variable to \fIfile\fR
before startup. See before startup. Same as \fB-xauth\fR file. See
.IR Xsecurity (7) .IR Xsecurity (7)
, ,
.IR xauth (1) .IR xauth (1)
man pages. man pages for more info.
.PP .PP
\fB-id\fR \fIwindowid\fR \fB-id\fR \fIwindowid\fR
.IP .IP
...@@ -210,10 +210,17 @@ Note: if you are not redirecting stderr to a log file ...@@ -210,10 +210,17 @@ Note: if you are not redirecting stderr to a log file
For use with "vncviewer -listen" reverse connections. For use with "vncviewer -listen" reverse connections.
If \fIstring\fR has the form "host" or "host:port" If \fIstring\fR has the form "host" or "host:port"
the connection is made once at startup. Use commas the connection is made once at startup. Use commas
for a list of host's and host:port's. If \fIstring\fR for a list of host's and host:port's.
contains "/" it is instead interpreted as a file to .IP
periodically check for new hosts. The first line is If \fIstring\fR contains "/" it is instead interpreted
read and then the file is truncated. as a file to periodically check for new hosts.
The first line is read and then the file is truncated.
Be careful for this usage mode if x11vnc is running as
root (e.g. via
.IR inetd (1)
or
.IR gdm (1)
).
.PP .PP
\fB-vncconnect,\fR \fB-novncconnect\fR \fB-vncconnect,\fR \fB-novncconnect\fR
.IP .IP
...@@ -277,6 +284,17 @@ external command returns 0 the client is accepted, ...@@ -277,6 +284,17 @@ external command returns 0 the client is accepted,
otherwise the client is rejected. See below for an 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
.IR inetd (1)
or from
display managers
.IR xdm (1)
,
.IR gdm (1)
, etc), think about the
security implications carefully before supplying this
option (likewise for the \fB-gone\fR option).
.IP
Environment: The RFB_CLIENT_IP environment variable will Environment: The RFB_CLIENT_IP environment variable will
be set to the incoming client IP number and the port be set to the incoming client IP number and the port
in RFB_CLIENT_PORT (or -1 if unavailable). Similarly, in RFB_CLIENT_PORT (or -1 if unavailable). Similarly,
...@@ -332,6 +350,61 @@ set to "gone" and the other RFB_* variables are as ...@@ -332,6 +350,61 @@ set to "gone" and the other RFB_* variables are as
in \fB-accept.\fR Unlike \fB-accept,\fR the command return code in \fB-accept.\fR Unlike \fB-accept,\fR the command return code
is not interpreted by x11vnc. Example: \fB-gone\fR 'xlock &' is not interpreted by x11vnc. Example: \fB-gone\fR 'xlock &'
.PP .PP
\fB-users\fR \fIlist\fR
.IP
If x11vnc is started as root (say from
.IR inetd (1)
or
from display managers
.IR xdm (1)
,
.IR gdm (1)
, etc), then as
soon as possible after connections to the display are
established try to switch to one of the users in the
comma separated \fIlist\fR. If x11vnc is not running as
root this option is ignored.
.IP
Why use this option? In general it is not needed
since x11vnc is already connected to the display and
can perform its primary functions. It was added to
make some of the *external* utility commands x11vnc
occasionally runs work properly. In particular under
GNOME and KDE to implement the "\fB-solid\fR \fIcolor\fR" feature
external commands (gconftool-2 and dcop) must be run as
the user owning the desktop session. This option also
affects the userid used to run the processes for the
\fB-accept\fR and \fB-gone\fR options. It also affects the ability
to read files for options such as \fB-connect,\fR \fB-allow,\fR and
\fB-remap.\fR Note that the \fB-connect\fR file is also written to.
.IP
So be careful with this option since in many situations
its use can decrease security.
.IP
The switch to a user will only take place if the display
can still be opened as that user (this is primarily to
try to guess the actual owner of the session). Example:
"\fB-users\fR \fIfred,wilma,betty\fR". Note that a malicious
user "barney" by quickly using "xhost +" when
logging in can get x11vnc to switch to user "fred".
What happens next?
.IP
Under display managers it may be a long time before
the switch succeeds (i.e. a user logs in). To make
it switch immediately regardless if the display can
be reopened or not prefix the username with the +
character. E.g. "\fB-users\fR \fI+bob\fR" or "\fB-users\fR \fI+nobody\fR".
The latter is probably the only use of this option
that increases security. To switch to a user *before*
connections to the display are made or any files opened
use the "=" character: "\fB-users\fR \fI=username\fR".
.IP
The special user "guess" means to examine the utmpx
database looking for a user attached to the display
number and try him/her. To limit the list of guesses,
use: "\fB-users\fR \fIguess=bob,fred\fR". Be especially careful
using this mode.
.PP
\fB-noshm\fR \fB-noshm\fR
.IP .IP
Do not use the MIT-SHM extension for the polling. Do not use the MIT-SHM extension for the polling.
...@@ -357,15 +430,22 @@ To improve performance, when VNC clients are connected ...@@ -357,15 +430,22 @@ To improve performance, when VNC clients are connected
try to change the desktop background to a solid color. try to change the desktop background to a solid color.
The [color] is optional: the default color is "cyan4". The [color] is optional: the default color is "cyan4".
For a different one specify the X color (rgb.txt name, For a different one specify the X color (rgb.txt name,
e.g. "darkblue" or numerical "#RRGGBB"). Currently e.g. "darkblue" or numerical "#RRGGBB").
this option only works on GNOME, KDE, and classic X .IP
(i.e. with the background image on the root window). Currently this option only works on GNOME, KDE, and
The "gconftool-2" and "dcop" external commands are classic X (i.e. with the background image on the root
run for GNOME and KDE respectively. Other desktops window). The "gconftool-2" and "dcop" external
won't work, e.g. XFCE (send us the corresponding commands are run for GNOME and KDE respectively.
commands if you find them). If x11vnc guesses your Other desktops won't work, e.g. XFCE (send us the
desktop incorrectly, you can force it by prefixing corresponding commands if you find them). If x11vnc
color with "gnome:", "kde:", or "root:". is running as root (
.IR inetd (1)
or
.IR gdm (1)
), the \fB-users\fR
option may be needed for GNOME and KDE. If x11vnc
guesses your desktop incorrectly, you can force it by
prefixing color with "gnome:", "kde:", or "root:".
.PP .PP
\fB-blackout\fR \fIstring\fR \fB-blackout\fR \fIstring\fR
.IP .IP
...@@ -930,8 +1010,7 @@ the gui to come back to you via your ssh redirected X ...@@ -930,8 +1010,7 @@ the gui to come back to you via your ssh redirected X
display (e.g. localhost:10). display (e.g. localhost:10).
.IP .IP
Examples: "x11vnc \fB-gui",\fR "x11vnc \fB-gui\fR localhost:10", Examples: "x11vnc \fB-gui",\fR "x11vnc \fB-gui\fR localhost:10",
"x11vnc \fB-gui\fR :10", "x11vnc \fB-gui\fR wait,:10", "x11vnc \fB-gui\fR :10", "x11vnc \fB-gui\fR conn,host:10",
"x11vnc \fB-gui\fR <x11vnc-opts...>"
.IP .IP
If you do not specify a gui X display in "gui-opts" If you do not specify a gui X display in "gui-opts"
then the DISPLAY environment variable and \fB-display\fR then the DISPLAY environment variable and \fB-display\fR
...@@ -1361,7 +1440,7 @@ noalwaysshared nevershared noalwaysshared dontdisconnect ...@@ -1361,7 +1440,7 @@ noalwaysshared nevershared noalwaysshared dontdisconnect
nodontdisconnect desktop noremote nodontdisconnect desktop noremote
.IP .IP
aro= display vncdisplay desktopname http_url auth aro= display vncdisplay desktopname http_url auth
rootshift scale_str scaled_x scaled_y scale_numer users rootshift scale_str scaled_x scaled_y scale_numer
scale_denom scale_fac scaling_noblend scaling_nomult4 scale_denom scale_fac scaling_noblend scaling_nomult4
scaling_pad scaling_interpolate inetd safer unsafe scaling_pad scaling_interpolate inetd safer unsafe
passwdfile using_shm logfile o rc norc h help V version passwdfile using_shm logfile o rc norc h help V version
......
...@@ -137,11 +137,17 @@ ...@@ -137,11 +137,17 @@
#define LIBVNCSERVER_HAVE_XSHM 1 #define LIBVNCSERVER_HAVE_XSHM 1
#define LIBVNCSERVER_HAVE_XTEST 1 #define LIBVNCSERVER_HAVE_XTEST 1
#define LIBVNCSERVER_HAVE_PWD_H 1
#define LIBVNCSERVER_HAVE_SYS_WAIT_H 1
#define LIBVNCSERVER_HAVE_UTMPX_H 1
/* /*
#define LIBVNCSERVER_HAVE_LIBXINERAMA 1 #define LIBVNCSERVER_HAVE_LIBXINERAMA 1
#define LIBVNCSERVER_HAVE_XFIXES 1 #define LIBVNCSERVER_HAVE_XFIXES 1
#define LIBVNCSERVER_HAVE_XDAMAGE 1 #define LIBVNCSERVER_HAVE_XDAMAGE 1
*/ */
#endif /* OLD_TREE */ #endif /* OLD_TREE */
#include <unistd.h> #include <unistd.h>
...@@ -215,6 +221,17 @@ extern int h_errno; ...@@ -215,6 +221,17 @@ extern int h_errno;
#include <arpa/inet.h> #include <arpa/inet.h>
#endif #endif
/* XXX autoconf */
#if LIBVNCSERVER_HAVE_PWD_H
#include <pwd.h>
#endif
#if LIBVNCSERVER_HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#if LIBVNCSERVER_HAVE_UTMPX_H
#include <utmpx.h>
#endif
/* /*
* overlay/multi-depth screen reading support * overlay/multi-depth screen reading support
* undef SOLARIS_OVERLAY or IRIX_OVERLAY if there are problems building. * undef SOLARIS_OVERLAY or IRIX_OVERLAY if there are problems building.
...@@ -273,7 +290,7 @@ static int xdamage_base_event_type; ...@@ -273,7 +290,7 @@ static int xdamage_base_event_type;
#endif #endif
/* date +'lastmod: %Y-%m-%d' */ /* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.7.1pre lastmod: 2005-02-05"; char lastmod[] = "0.7.1pre lastmod: 2005-02-08";
/* X display info */ /* X display info */
...@@ -371,6 +388,10 @@ time_t last_event, last_input, last_client = 0; ...@@ -371,6 +388,10 @@ time_t last_event, last_input, last_client = 0;
/* last client to move pointer */ /* last client to move pointer */
rfbClientPtr last_pointer_client = NULL; rfbClientPtr last_pointer_client = NULL;
int accepted_client = 0;
int client_count = 0;
int clients_served = 0;
/* more transient kludge variables: */ /* more transient kludge variables: */
int cursor_x, cursor_y; /* x and y from the viewer(s) */ int cursor_x, cursor_y; /* x and y from the viewer(s) */
int got_user_input = 0; int got_user_input = 0;
...@@ -433,6 +454,7 @@ void initialize_polling_images(void); ...@@ -433,6 +454,7 @@ void initialize_polling_images(void);
void initialize_signals(void); void initialize_signals(void);
void initialize_tiles(void); void initialize_tiles(void);
void initialize_speeds(void); void initialize_speeds(void);
void clean_shm(int);
void free_tiles(void); void free_tiles(void);
void initialize_watch_bell(void); void initialize_watch_bell(void);
void initialize_xinerama(void); void initialize_xinerama(void);
...@@ -545,6 +567,8 @@ int shared = 0; /* share vnc display. */ ...@@ -545,6 +567,8 @@ int shared = 0; /* share vnc display. */
int deny_all = 0; /* global locking of new clients */ int deny_all = 0; /* global locking of new clients */
int accept_remote_cmds = 1; /* -noremote */ int accept_remote_cmds = 1; /* -noremote */
int safe_remote_only = 0; /* -safer, -unsafe */ int safe_remote_only = 0; /* -safer, -unsafe */
int started_as_root = 0;
char *users_list = NULL; /* -users */
char *allow_list = NULL; /* for -allow and -localhost */ char *allow_list = NULL; /* for -allow and -localhost */
char *allow_once = NULL; /* one time -allow */ char *allow_once = NULL; /* one time -allow */
char *accept_cmd = NULL; /* for -accept */ char *accept_cmd = NULL; /* for -accept */
...@@ -752,6 +776,17 @@ void lowercase(char *str) { ...@@ -752,6 +776,17 @@ void lowercase(char *str) {
} }
} }
char *lblanks(char *str) {
char *p = str;
while (*p) {
if (! isspace(*p)) {
break;
}
p++;
}
return p;
}
int scan_hexdec(char *str, unsigned long *num) { int scan_hexdec(char *str, unsigned long *num) {
if (sscanf(str, "0x%lx", num) != 1) { if (sscanf(str, "0x%lx", num) != 1) {
if (sscanf(str, "%ld", num) != 1) { if (sscanf(str, "%ld", num) != 1) {
...@@ -852,6 +887,424 @@ char *bitprint(unsigned int st, int nbits) { ...@@ -852,6 +887,424 @@ char *bitprint(unsigned int st, int nbits) {
return str; /* take care to use or copy immediately */ return str; /* take care to use or copy immediately */
} }
char *get_user_name(void) {
char *user = NULL;
user = getenv("USER");
if (user == NULL) {
user = getenv("LOGNAME");
}
#if LIBVNCSERVER_HAVE_PWD_H
if (user == NULL) {
struct passwd *pw = getpwuid(getuid());
if (pw) {
user = pw->pw_name;
}
}
#endif
if (user) {
return(strdup(user));
} else {
return(strdup("unknown-user"));
}
}
char *get_home_dir(void) {
char *home = NULL;
home = getenv("HOME");
#if LIBVNCSERVER_HAVE_PWD_H
if (home == NULL) {
struct passwd *pw = getpwuid(getuid());
if (pw) {
home = pw->pw_dir;
}
}
#endif
if (home) {
return(strdup(home));
} else {
return(strdup("/"));
}
}
char *get_shell(void) {
char *shell = NULL;
shell = getenv("SHELL");
#if LIBVNCSERVER_HAVE_PWD_H
if (shell == NULL) {
struct passwd *pw = getpwuid(getuid());
if (pw) {
shell = pw->pw_shell;
}
}
#endif
if (shell) {
return(strdup(shell));
} else {
return(strdup("/bin/sh"));
}
}
int switch_user(char *);
void try_to_switch_users(void);
char *guess_desktop(void);
void switch_user_dummy(void) {
; /* dummy does nothing */
}
void switch_user_solid_bg(void) {
/* we have switched users, some things to do. */
if (use_solid_bg && client_count) {
solid_bg(0);
}
}
void check_switched_user (void) {
static time_t sched_switched_user = 0;
static int did_solid = 0;
static int did_dummy = 0;
int delay = 15;
time_t now = time(0);
if (started_as_root == 1 && users_list) {
try_to_switch_users();
if (started_as_root == 2) {
/*
* schedule the switch_user_tasks() call
* 15 secs is for piggy desktops to start up.
* might not be enough for slow machines...
*/
sched_switched_user = now;
did_dummy = 0;
did_solid = 0;
/* add other activities */
}
}
if (! sched_switched_user) {
return;
}
if (! did_dummy) {
switch_user_dummy();
did_dummy = 1;
}
if (! did_solid) {
int doit = 0;
char *ss = solid_str;
if (now >= sched_switched_user + delay) {
doit = 1;
} else if (ss && strstr(ss, "root:") == ss) {
if (now >= sched_switched_user + 3) {
doit = 1;
}
} else if (strcmp("root", guess_desktop())) {
usleep(1000 * 1000);
doit = 1;
}
if (doit) {
switch_user_solid_bg();
did_solid = 1;
}
}
if (did_dummy && did_solid) {
sched_switched_user = 0;
}
}
int guess_user_and_switch(char *str) {
#if LIBVNCSERVER_HAVE_UTMPX_H
char *q, *dstr, *d = DisplayString(dpy);
char *allowed = NULL;
int i, ret = 0, max = 300;
if (strstr(str, "guess=") == str) {
char *allowed = strchr(str, '=');
allowed++;
}
/* pick out ":N" */
dstr = strchr(d, ':');
if (! dstr) {
return 0;
}
q = strchr(dstr, '.');
if (q) {
*q = '\0';
}
/* look over the utmpx entries looking for this display */
setutxent();
for (i=0; i<max; i++) {
char *str;
struct utmpx *utx = getutxent();
if (! utx) {
break;
}
str = lblanks(utx->ut_user);
if (*str == '\0') {
continue; /* blank user */
}
if (allowed) {
char *p, *t = strdup(allowed);
int ok = 0;
p = strtok(t, ",");
while (p) {
if (!strcmp(p, utx->ut_user)) {
ok = 1;
}
p = strtok(NULL, ",");
}
free(t);
if (! ok) {
continue;
}
}
if (!strcmp(utx->ut_user, "guess")) {
continue; /* never... */
}
/* try the line for leading :N */
str = lblanks(utx->ut_line);
if (strstr(str, dstr) == str) {
int n = strlen(dstr);
if (isdigit(*(str+n))) {
continue; /* :1 vs. :10 */
} else if (switch_user(utx->ut_user)) {
rfbLog("switched to guessed user: %s\n",
utx->ut_user);
ret = 1;
break;
} else {
continue;
}
}
/* try the host for leading :N */
str = lblanks(utx->ut_host);
if (strstr(str, dstr) == str) {
int n = strlen(dstr);
if (isdigit(*(str+n))) {
continue; /* :1 vs. :10 */
} else if (switch_user(utx->ut_user)) {
rfbLog("switched to guessed user: %s\n",
utx->ut_user);
ret = 1;
break;
} else {
continue;
}
}
}
endutxent();
return ret;
#else
return 0;
#endif
}
int switch_user(char *user) {
int force = 0, numerical = 1;
uid_t uid = 0;
char *q, *name, *home;
if (*user == '+') {
force = 1;
user++;
}
if (!strcmp(user, "guess") || strstr(user, "guess=") == user) {
return guess_user_and_switch(user);
}
q = user;
while (*q) {
if (! isdigit(*q)) {
numerical = 0;
break;
}
q++;
}
#if LIBVNCSERVER_HAVE_PWD_H
if (numerical) {
int u = atoi(user);
struct passwd *pw;
if (u > 0) {
uid = (uid_t) u;
} else {
return 0;
}
pw = getpwuid(uid);
if (pw) {
name = pw->pw_name;
home = pw->pw_dir;
} else {
return 0;
}
} else {
struct passwd *pw = getpwnam(user);
if (pw) {
uid = pw->pw_uid;
name = pw->pw_name;
home = pw->pw_dir;
} else {
return 0;
}
}
#else
return 0;
#endif
if (! uid) {
return 0;
}
if (! force) {
#if LIBVNCSERVER_HAVE_FORK && LIBVNCSERVER_HAVE_SYS_WAIT_H
pid_t pid, pidw;
int st;
/*
* We fork here and try to open the display again as the
* new user. Unreadable XAUTHORITY could be a problem...
* This is not really needed since we have DISPLAY open
* but: 1) is a good indicator this user owns the session
* and 2) some activities do spawn new X apps, e.g.
* xmessage(1), etc.
*/
if ((pid = fork()) > 0) {
;
} else if (pid == -1) {
fprintf(stderr, "could not fork\n");
rfbLogPerror("fork");
return 0;
} else {
Display *dpy2 = 0;
char *xauth = getenv("XAUTHORITY");
#if LIBVNCSERVER_HAVE_SETUID
if (setuid(uid) != 0) {
exit(1); /* fail */
}
#else
exit(1);
#endif
if (xauth && access(xauth, R_OK) != 0) {
*(xauth-2) = '_'; /* yow */
}
set_env("USER", name);
set_env("LOGNAME", name);
set_env("HOME", home);
fclose(stderr);
dpy2 = XOpenDisplay(DisplayString(dpy));
if (dpy2) {
XCloseDisplay(dpy2);
exit(0); /* success */
} else {
exit(2); /* fail */
}
}
/* see what the child says: */
pidw = waitpid(pid, &st, 0);
if (pidw == pid && WIFEXITED(st) && WEXITSTATUS(st) == 0) {
force = 1;
}
#else
force = 1;
#endif
}
if (force) {
char *xauth = getenv("XAUTHORITY");
/*
* OK tricky here, we need to free the shm... otherwise
* we won't be able to delete it as the other user...
*/
#if !LIBVNCSERVER_HAVE_SETUID
return 0;
#else
if (using_shm) {
clean_shm(0);
free_tiles();
}
if (setuid(uid) != 0) {
if (using_shm) {
/* 2 means we did clean_shm and free_tiles */
do_new_fb(2);
}
return 0;
}
#endif
if (using_shm) {
do_new_fb(2);
}
if (xauth && access(xauth, R_OK) != 0) {
*(xauth-2) = '_'; /* yow */
}
set_env("USER", name);
set_env("LOGNAME", name);
set_env("HOME", home);
return 1;
} else {
return 0;
}
}
void try_to_switch_users(void) {
static time_t last_try = 0;
time_t now = time(0);
char *users, *p;
if (getuid() && geteuid()) {
rfbLog("try_to_switch_users: not root\n");
started_as_root = 2;
return;
}
if (!last_try) {
last_try = now;
} else if (now <= last_try + 2) {
/* try every 3 secs or so */
return;
}
last_try = now;
users = strdup(users_list);
if (strstr(users, "guess=") == users) {
if (switch_user(users)) {
started_as_root = 2;
rfbLog("try_to_switch_users: now %s\n", p);
}
free(users);
return;
}
p = strtok(users, ",");
while (p) {
if (switch_user(p)) {
started_as_root = 2;
rfbLog("try_to_switch_users: now %s\n", p);
break;
}
p = strtok(NULL, ",");
}
free(users);
}
/* /*
* Simple utility to map host name to dotted IP address. Ignores aliases. * Simple utility to map host name to dotted IP address. Ignores aliases.
* Up to caller to free returned string. * Up to caller to free returned string.
...@@ -1318,7 +1771,7 @@ void clean_shm(int quick) { ...@@ -1318,7 +1771,7 @@ void clean_shm(int quick) {
break; break;
} }
} }
if (!quiet && !quick) { if (!quiet) {
rfbLog("deleted %d tile_row polling images.\n", cnt); rfbLog("deleted %d tile_row polling images.\n", cnt);
} }
} }
...@@ -1356,62 +1809,13 @@ void clean_up_exit (int ret) { ...@@ -1356,62 +1809,13 @@ void clean_up_exit (int ret) {
exit(ret); exit(ret);
} }
/*
* General problem handler
*/
static void interrupted (int sig) {
exit_sig = sig;
if (exit_flag) {
exit_flag++;
if (use_threads) {
usleep2(250 * 1000);
} else if (exit_flag <= 2) {
return;
}
exit(4);
}
exit_flag++;
if (sig == 0) {
fprintf(stderr, "caught X11 error:\n");
} else {
fprintf(stderr, "caught signal: %d\n", sig);
}
if (sig == SIGINT) {
shut_down = 1;
return;
}
X_UNLOCK;
/* remove the shm areas with quick=1: */
clean_shm(1);
/* X keyboard cleanups */
delete_added_keycodes();
if (clear_mods == 1) {
clear_modifiers(0);
} else if (clear_mods == 2) {
clear_keys();
}
if (no_autorepeat) {
autorepeat(1);
}
if (use_solid_bg) {
solid_bg(1);
}
if (sig) {
exit(2);
}
}
/* X11 error handlers */ /* X11 error handlers */
static XErrorHandler Xerror_def; static XErrorHandler Xerror_def;
static XIOErrorHandler XIOerr_def; static XIOErrorHandler XIOerr_def;
XErrorEvent *trapped_xerror_event; XErrorEvent *trapped_xerror_event;
int trapped_xerror = 0; int trapped_xerror = 0;
int trapped_xioerror = 0;
int trapped_getimage_xerror = 0; int trapped_getimage_xerror = 0;
int trap_xerror(Display *d, XErrorEvent *error) { int trap_xerror(Display *d, XErrorEvent *error) {
...@@ -1420,12 +1824,19 @@ int trap_xerror(Display *d, XErrorEvent *error) { ...@@ -1420,12 +1824,19 @@ int trap_xerror(Display *d, XErrorEvent *error) {
return 0; return 0;
} }
int trap_xioerror(Display *d) {
trapped_xioerror = 1;
return 0;
}
int trap_getimage_xerror(Display *d, XErrorEvent *error) { int trap_getimage_xerror(Display *d, XErrorEvent *error) {
trapped_getimage_xerror = 1; trapped_getimage_xerror = 1;
trapped_xerror_event = error; trapped_xerror_event = error;
return 0; return 0;
} }
void interrupted(int);
static int Xerror(Display *d, XErrorEvent *error) { static int Xerror(Display *d, XErrorEvent *error) {
X_UNLOCK; X_UNLOCK;
interrupted(0); interrupted(0);
...@@ -1434,7 +1845,7 @@ static int Xerror(Display *d, XErrorEvent *error) { ...@@ -1434,7 +1845,7 @@ static int Xerror(Display *d, XErrorEvent *error) {
static int XIOerr(Display *d) { static int XIOerr(Display *d) {
X_UNLOCK; X_UNLOCK;
interrupted(0); interrupted(-1);
return (*XIOerr_def)(d); return (*XIOerr_def)(d);
} }
...@@ -1473,6 +1884,63 @@ char *xerror_string(XErrorEvent *error) { ...@@ -1473,6 +1884,63 @@ char *xerror_string(XErrorEvent *error) {
} }
} }
/*
* General problem handler
*/
void interrupted (int sig) {
exit_sig = sig;
if (exit_flag) {
exit_flag++;
if (use_threads) {
usleep2(250 * 1000);
} else if (exit_flag <= 2) {
return;
}
exit(4);
}
exit_flag++;
if (sig == 0) {
fprintf(stderr, "caught X11 error:\n");
} else if (sig == -1) {
fprintf(stderr, "caught XIO error:\n");
} else {
fprintf(stderr, "caught signal: %d\n", sig);
}
if (sig == SIGINT) {
shut_down = 1;
return;
}
X_UNLOCK;
/* remove the shm areas with quick=1: */
clean_shm(1);
if (sig == -1) {
/* not worth trying any more cleanup, X server probably gone */
exit(3);
}
/* X keyboard cleanups */
delete_added_keycodes();
if (clear_mods == 1) {
clear_modifiers(0);
} else if (clear_mods == 2) {
clear_keys();
}
if (no_autorepeat) {
autorepeat(1);
}
if (use_solid_bg) {
solid_bg(1);
}
if (sig) {
exit(2);
}
}
/* trapping utility to check for a valid window: */ /* trapping utility to check for a valid window: */
int valid_window(Window win) { int valid_window(Window win) {
XErrorHandler old_handler; XErrorHandler old_handler;
...@@ -1563,10 +2031,6 @@ void initialize_signals(void) { ...@@ -1563,10 +2031,6 @@ void initialize_signals(void) {
* routines for handling incoming, outgoing, etc connections * routines for handling incoming, outgoing, etc connections
*/ */
static int accepted_client = 0;
static int client_count = 0;
static int clients_served = 0;
/* /*
* check that all clients are in RFB_NORMAL state * check that all clients are in RFB_NORMAL state
*/ */
...@@ -3189,16 +3653,9 @@ void initialize_remap(char *infile) { ...@@ -3189,16 +3653,9 @@ void initialize_remap(char *infile) {
rewind(in); rewind(in);
} }
while (fgets(line, 256, in) != NULL) { while (fgets(line, 256, in) != NULL) {
int blank = 1, isbtn = 0; int isbtn = 0;
p = line; p = lblanks(line);
while (*p) { if (*p == '\0') {
if (! isspace(*p)) {
blank = 0;
break;
}
p++;
}
if (blank) {
continue; continue;
} }
if (strchr(line, '#')) { if (strchr(line, '#')) {
...@@ -7987,6 +8444,8 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -7987,6 +8444,8 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} }
} else if (!strcmp(p, "auth")) { } else if (!strcmp(p, "auth")) {
snprintf(buf, bufn, "aro=%s:%s", p, NONUL(auth_file)); snprintf(buf, bufn, "aro=%s:%s", p, NONUL(auth_file));
} else if (!strcmp(p, "users")) {
snprintf(buf, bufn, "aro=%s:%s", p, NONUL(users_list));
} else if (!strcmp(p, "rootshift")) { } else if (!strcmp(p, "rootshift")) {
snprintf(buf, bufn, "aro=%s:%d", p, rootshift); snprintf(buf, bufn, "aro=%s:%d", p, rootshift);
} else if (!strcmp(p, "scale_str")) { } else if (!strcmp(p, "scale_str")) {
...@@ -9156,6 +9615,10 @@ int get_which_cursor(void) { ...@@ -9156,6 +9615,10 @@ int get_which_cursor(void) {
which = CURS_TERM; which = CURS_TERM;
} else if (strstr(winfo.res_class, "text")) { } else if (strstr(winfo.res_class, "text")) {
which = CURS_TERM; which = CURS_TERM;
} else if (strstr(winfo.res_name, "onsole")) {
which = CURS_TERM;
} else if (strstr(winfo.res_class, "onsole")) {
which = CURS_TERM;
} }
} }
} }
...@@ -9796,7 +10259,8 @@ void do_new_fb(int reset_mem) { ...@@ -9796,7 +10259,8 @@ void do_new_fb(int reset_mem) {
rfbLog(" not work, do not use -threads if problems arise.\n"); rfbLog(" not work, do not use -threads if problems arise.\n");
} }
if (reset_mem) { if (reset_mem == 1) {
/* reset_mem == 2 is a hack for changing users... */
clean_shm(0); clean_shm(0);
free_tiles(); free_tiles();
} }
...@@ -10655,13 +11119,45 @@ void initialize_screen(int *argc, char **argv, XImage *fb) { ...@@ -10655,13 +11119,45 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
/* -- solid.c -- */ /* -- solid.c -- */
int do_cmd(char *cmd) { void usr_bin_path(int restore) {
static char *oldpath = NULL;
char *newpath;
char addpath[] = "/usr/bin:/bin:";
if (restore) {
if (oldpath) {
set_env("PATH", oldpath);
free(oldpath);
oldpath = NULL;
}
return;
}
if (getenv("PATH")) {
oldpath = strdup(getenv("PATH"));
} else {
oldpath = strdup("/usr/bin");
}
newpath = (char *) malloc(strlen(oldpath) + strlen(addpath) + 1);
newpath[0] = '\0';
strcat(newpath, addpath);
strcat(newpath, oldpath);
set_env("PATH", newpath);
free(newpath);
}
int dt_cmd(char *cmd) {
int rc; int rc;
if (!cmd || *cmd == '\0') { if (!cmd || *cmd == '\0') {
return 0; return 0;
} }
rfbLog("running command:\n %s\n", cmd); rfbLog("running command:\n %s\n", cmd);
usr_bin_path(0);
rc = system(cmd); rc = system(cmd);
usr_bin_path(1);
if (rc >= 256) { if (rc >= 256) {
rc = rc/256; rc = rc/256;
} }
...@@ -10674,8 +11170,14 @@ char *cmd_output(char *cmd) { ...@@ -10674,8 +11170,14 @@ char *cmd_output(char *cmd) {
char line[1024]; char line[1024];
int rc; int rc;
if (!cmd || *cmd == '\0') {
return "";
}
rfbLog("running pipe:\n %s\n", cmd); rfbLog("running pipe:\n %s\n", cmd);
usr_bin_path(0);
p = popen(cmd, "r"); p = popen(cmd, "r");
usr_bin_path(1);
output[0] = '\0'; output[0] = '\0';
...@@ -10826,12 +11328,12 @@ void solid_gnome(char *color) { ...@@ -10826,12 +11328,12 @@ void solid_gnome(char *color) {
cmd = (char *)malloc(strlen(set_option) - 2 + cmd = (char *)malloc(strlen(set_option) - 2 +
strlen(orig_option) + 1); strlen(orig_option) + 1);
sprintf(cmd, set_option, orig_option); sprintf(cmd, set_option, orig_option);
do_cmd(cmd); dt_cmd(cmd);
free(cmd); free(cmd);
cmd = (char *)malloc(strlen(set_color) - 2 + cmd = (char *)malloc(strlen(set_color) - 2 +
strlen(orig_color) + 1); strlen(orig_color) + 1);
sprintf(cmd, set_color, orig_color); sprintf(cmd, set_color, orig_color);
do_cmd(cmd); dt_cmd(cmd);
free(cmd); free(cmd);
return; return;
} }
...@@ -10860,24 +11362,42 @@ void solid_gnome(char *color) { ...@@ -10860,24 +11362,42 @@ void solid_gnome(char *color) {
rfbLog("bad color: %s\n", color); rfbLog("bad color: %s\n", color);
return; return;
} }
cmd = (char *)malloc(strlen(set_color) - 2 + strlen(color) + 1); cmd = (char *)malloc(strlen(set_color) + strlen(color) + 1);
sprintf(cmd, set_color, color); sprintf(cmd, set_color, color);
do_cmd(cmd); dt_cmd(cmd);
free(cmd); free(cmd);
cmd = (char *)malloc(strlen(set_option) - 2 + strlen("none") + 1);
cmd = (char *)malloc(strlen(set_option) + strlen("none") + 1);
sprintf(cmd, set_option, "none"); sprintf(cmd, set_option, "none");
do_cmd(cmd); dt_cmd(cmd);
free(cmd); free(cmd);
} }
void solid_kde(char *color) { void solid_kde(char *color) {
char set_color[] = "dcop kdesktop KBackgroundIface setColor '%s' 1"; char set_color[] =
char bg_off[] = "dcop kdesktop KBackgroundIface setBackgroundEnabled 0"; "dcop --user '%s' kdesktop KBackgroundIface setColor '%s' 1";
char bg_on[] = "dcop kdesktop KBackgroundIface setBackgroundEnabled 1"; char bg_off[] =
char *cmd; "dcop --user '%s' kdesktop KBackgroundIface setBackgroundEnabled 0";
char bg_on[] =
"dcop --user '%s' kdesktop KBackgroundIface setBackgroundEnabled 1";
char *cmd, *user = NULL;
int len;
user = get_user_name();
if (strstr(user, "'") != NULL) {
rfbLog("bad user: %s\n", user);
free(user);
return;
}
if (! color) { if (! color) {
do_cmd(bg_on); len = strlen(bg_on) + strlen(user) + 1;
cmd = (char *)malloc(len);
sprintf(cmd, bg_on, user);
dt_cmd(cmd);
free(cmd);
free(user);
return; return;
} }
...@@ -10886,11 +11406,18 @@ void solid_kde(char *color) { ...@@ -10886,11 +11406,18 @@ void solid_kde(char *color) {
return; return;
} }
cmd = (char *)malloc(strlen(set_color) - 2 + strlen(color) + 1); len = strlen(set_color) + strlen(user) + strlen(color) + 1;
sprintf(cmd, set_color, color); cmd = (char *)malloc(len);
do_cmd(cmd); sprintf(cmd, set_color, user, color);
do_cmd(bg_off); dt_cmd(cmd);
free(cmd); free(cmd);
len = strlen(bg_off) + strlen(user) + 1;
cmd = (char *)malloc(len);
sprintf(cmd, bg_off, user);
dt_cmd(cmd);
free(cmd);
free(user);
} }
char *guess_desktop() { char *guess_desktop() {
...@@ -10912,6 +11439,11 @@ void solid_bg(int restore) { ...@@ -10912,6 +11439,11 @@ void solid_bg(int restore) {
static char *prev_str; static char *prev_str;
char *dtname, *color; char *dtname, *color;
if (started_as_root == 1 && users_list) {
/* we are still root, don't try. */
return;
}
if (restore) { if (restore) {
if (! solid_on) { if (! solid_on) {
return; return;
...@@ -11644,6 +12176,7 @@ void shm_clean(XShmSegmentInfo *shm, XImage *xim) { ...@@ -11644,6 +12176,7 @@ void shm_clean(XShmSegmentInfo *shm, XImage *xim) {
#endif #endif
if (xim != NULL) { if (xim != NULL) {
XDestroyImage(xim); XDestroyImage(xim);
xim = NULL;
} }
X_UNLOCK; X_UNLOCK;
...@@ -13669,6 +14202,7 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc, pid_t parent) { ...@@ -13669,6 +14202,7 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc, pid_t parent) {
":/usr/X11R6/bin:/usr/openwin/bin:/usr/dt/bin"; ":/usr/X11R6/bin:/usr/openwin/bin:/usr/dt/bin";
char cmd[100]; char cmd[100];
char *wish = NULL, *orig_path, *full_path, *tpath, *p; char *wish = NULL, *orig_path, *full_path, *tpath, *p;
char *old_xauth = NULL;
int try_max = 4, sleep = 300; int try_max = 4, sleep = 300;
pid_t mypid = getpid(); pid_t mypid = getpid();
FILE *pipe, *tmpf; FILE *pipe, *tmpf;
...@@ -13687,7 +14221,14 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc, pid_t parent) { ...@@ -13687,7 +14221,14 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc, pid_t parent) {
int rc, i; int rc, i;
rfbLogEnable(0); rfbLogEnable(0);
if (! client_connect_file) { if (! client_connect_file) {
if (getenv("XAUTHORITY") != NULL) {
old_xauth = strdup(getenv("XAUTHORITY"));
}
dpy = XOpenDisplay(x11vnc_xdisplay); dpy = XOpenDisplay(x11vnc_xdisplay);
if (! dpy && auth_file) {
set_env("XAUTHORITY", auth_file);
dpy = XOpenDisplay(x11vnc_xdisplay);
}
if (! dpy && ! x11vnc_xdisplay) { if (! dpy && ! x11vnc_xdisplay) {
x11vnc_xdisplay = strdup(":0"); x11vnc_xdisplay = strdup(":0");
dpy = XOpenDisplay(x11vnc_xdisplay); dpy = XOpenDisplay(x11vnc_xdisplay);
...@@ -13719,6 +14260,9 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc, pid_t parent) { ...@@ -13719,6 +14260,9 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc, pid_t parent) {
} }
} }
set_env("X11VNC_XDISPLAY", x11vnc_xdisplay); set_env("X11VNC_XDISPLAY", x11vnc_xdisplay);
if (getenv("XAUTHORITY") != NULL) {
set_env("X11VNC_XAUTHORITY", getenv("XAUTHORITY"));
}
if (rc == 0) { if (rc == 0) {
fprintf(stderr, "gui: ping succeeded.\n"); fprintf(stderr, "gui: ping succeeded.\n");
set_env("X11VNC_CONNECT", "1"); set_env("X11VNC_CONNECT", "1");
...@@ -13726,6 +14270,13 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc, pid_t parent) { ...@@ -13726,6 +14270,13 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc, pid_t parent) {
fprintf(stderr, "gui: could not connect to: '%s', try" fprintf(stderr, "gui: could not connect to: '%s', try"
" again manually.\n", x11vnc_xdisplay); " again manually.\n", x11vnc_xdisplay);
} }
if (dpy) {
XCloseDisplay(dpy);
}
if (old_xauth) {
set_env("XAUTHORITY", old_xauth);
free(old_xauth);
}
} }
orig_path = getenv("PATH"); orig_path = getenv("PATH");
...@@ -13768,6 +14319,9 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc, pid_t parent) { ...@@ -13768,6 +14319,9 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc, pid_t parent) {
set_env("DISPLAY", gui_xdisplay); set_env("DISPLAY", gui_xdisplay);
set_env("X11VNC_PROG", program_name); set_env("X11VNC_PROG", program_name);
set_env("X11VNC_CMDLINE", program_cmdline); set_env("X11VNC_CMDLINE", program_cmdline);
if (auth_file) {
set_env("X11VNC_AUTH_FILE", auth_file);
}
sprintf(cmd, "%s -", wish); sprintf(cmd, "%s -", wish);
tmpf = tmpfile(); tmpf = tmpfile();
...@@ -13871,6 +14425,7 @@ void do_gui(char *opts) { ...@@ -13871,6 +14425,7 @@ void do_gui(char *opts) {
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",
gui_xdisplay); gui_xdisplay);
exit(1);
} }
XCloseDisplay(test_dpy); XCloseDisplay(test_dpy);
...@@ -14776,11 +15331,15 @@ static void watch_loop(void) { ...@@ -14776,11 +15331,15 @@ static void watch_loop(void) {
check_xevents(); check_xevents();
check_connect_inputs(); check_connect_inputs();
check_padded_fb(); check_padded_fb();
if (started_as_root) {
check_switched_user();
}
if (first_conn_timeout < 0) { if (first_conn_timeout < 0) {
start = time(0); start = time(0);
first_conn_timeout = -first_conn_timeout; first_conn_timeout = -first_conn_timeout;
} }
if (! screen || ! screen->clientHead) { if (! screen || ! screen->clientHead) {
/* waiting for a client */ /* waiting for a client */
if (first_conn_timeout) { if (first_conn_timeout) {
...@@ -14788,13 +15347,15 @@ static void watch_loop(void) { ...@@ -14788,13 +15347,15 @@ static void watch_loop(void) {
rfbLog("No client after %d secs.\n", rfbLog("No client after %d secs.\n",
first_conn_timeout); first_conn_timeout);
shut_down = 1; shut_down = 1;
continue;
} }
} }
usleep(200 * 1000); usleep(200 * 1000);
continue; continue;
} }
if (first_conn_timeout && all_clients_initialized()) {
first_conn_timeout = 0; first_conn_timeout = 0;
}
if (nofb) { if (nofb) {
/* no framebuffer polling needed */ /* no framebuffer polling needed */
...@@ -14897,7 +15458,8 @@ static void print_help(int mode) { ...@@ -14897,7 +15458,8 @@ static void print_help(int mode) {
" environment variable to \"disp\".\n" " environment variable to \"disp\".\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. See Xsecurity(7), xauth(1) man pages.\n" " before startup. Same as -xauth file. See Xsecurity(7),\n"
" xauth(1) man pages for more info.\n"
"\n" "\n"
"-id windowid Show the window corresponding to \"windowid\" not\n" "-id windowid Show the window corresponding to \"windowid\" not\n"
" the entire display. New windows like popup menus,\n" " the entire display. New windows like popup menus,\n"
...@@ -14994,10 +15556,13 @@ static void print_help(int mode) { ...@@ -14994,10 +15556,13 @@ static void print_help(int mode) {
"-connect string For use with \"vncviewer -listen\" reverse connections.\n" "-connect string For use with \"vncviewer -listen\" reverse connections.\n"
" If \"string\" has the form \"host\" or \"host:port\"\n" " If \"string\" has the form \"host\" or \"host:port\"\n"
" the connection is made once at startup. Use commas\n" " the connection is made once at startup. Use commas\n"
" for a list of host's and host:port's. If \"string\"\n" " for a list of host's and host:port's.\n"
" contains \"/\" it is instead interpreted as a file to\n" "\n"
" periodically check for new hosts. The first line is\n" " If \"string\" contains \"/\" it is instead interpreted\n"
" read and then the file is truncated.\n" " as a file to periodically check for new hosts.\n"
" The first line is read and then the file is truncated.\n"
" Be careful for this usage mode if x11vnc is running as\n"
" root (e.g. via inetd(1) or gdm(1)).\n"
"-vncconnect Monitor the VNC_CONNECT X property set by the standard\n" "-vncconnect Monitor the VNC_CONNECT X property set by the standard\n"
"-novncconnect VNC program vncconnect(1). When the property is\n" "-novncconnect VNC program vncconnect(1). When the property is\n"
" set to \"host\" or \"host:port\" establish a reverse\n" " set to \"host\" or \"host:port\" establish a reverse\n"
...@@ -15035,6 +15600,11 @@ static void print_help(int mode) { ...@@ -15035,6 +15600,11 @@ static 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"
" display managers xdm(1), gdm(1), etc), think about the\n"
" security implications carefully before supplying this\n"
" option (likewise for the -gone option).\n"
"\n"
" Environment: The RFB_CLIENT_IP environment variable will\n" " Environment: The RFB_CLIENT_IP environment variable will\n"
" be set to the incoming client IP number and the port\n" " be set to the incoming client IP number and the port\n"
" in RFB_CLIENT_PORT (or -1 if unavailable). Similarly,\n" " in RFB_CLIENT_PORT (or -1 if unavailable). Similarly,\n"
...@@ -15086,6 +15656,53 @@ static void print_help(int mode) { ...@@ -15086,6 +15656,53 @@ static void print_help(int mode) {
" in -accept. Unlike -accept, the command return code\n" " in -accept. Unlike -accept, the command return code\n"
" is not interpreted by x11vnc. Example: -gone 'xlock &'\n" " is not interpreted by x11vnc. Example: -gone 'xlock &'\n"
"\n" "\n"
"-users list If x11vnc is started as root (say from inetd(1) or\n"
" from display managers xdm(1), gdm(1), etc), then as\n"
" soon as possible after connections to the display are\n"
" established try to switch to one of the users in the\n"
" comma separated \"list\". If x11vnc is not running as\n"
" root this option is ignored.\n"
" \n"
" Why use this option? In general it is not needed\n"
" since x11vnc is already connected to the display and\n"
" can perform its primary functions. It was added to\n"
" make some of the *external* utility commands x11vnc\n"
" occasionally runs work properly. In particular under\n"
" GNOME and KDE to implement the \"-solid color\" feature\n"
" external commands (gconftool-2 and dcop) must be run as\n"
" the user owning the desktop session. This option also\n"
" affects the userid used to run the processes for the\n"
" -accept and -gone options. It also affects the ability\n"
" to read files for options such as -connect, -allow, and\n"
" -remap. Note that the -connect file is also written to.\n"
" \n"
" So be careful with this option since in many situations\n"
" its use can decrease security.\n"
" \n"
" The switch to a user will only take place if the display\n"
" can still be opened as that user (this is primarily to\n"
" try to guess the actual owner of the session). Example:\n"
" \"-users fred,wilma,betty\". Note that a malicious\n"
" user \"barney\" by quickly using \"xhost +\" when\n"
" logging in can get x11vnc to switch to user \"fred\".\n"
" What happens next?\n"
" \n"
" Under display managers it may be a long time before\n"
" the switch succeeds (i.e. a user logs in). To make\n"
" it switch immediately regardless if the display can\n"
" be reopened or not prefix the username with the +\n"
" character. E.g. \"-users +bob\" or \"-users +nobody\".\n"
" The latter is probably the only use of this option\n"
" that increases security. To switch to a user *before*\n"
" connections to the display are made or any files opened\n"
" use the \"=\" character: \"-users =username\".\n"
" \n"
" The special user \"guess\" means to examine the utmpx\n"
" database looking for a user attached to the display\n"
" number and try him/her. To limit the list of guesses,\n"
" use: \"-users guess=bob,fred\". Be especially careful\n"
" using this mode.\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"
...@@ -15101,15 +15718,18 @@ static void print_help(int mode) { ...@@ -15101,15 +15718,18 @@ static void print_help(int mode) {
" try to change the desktop background to a solid color.\n" " try to change the desktop background to a solid color.\n"
" The [color] is optional: the default color is \"cyan4\".\n" " The [color] is optional: the default color is \"cyan4\".\n"
" For a different one specify the X color (rgb.txt name,\n" " For a different one specify the X color (rgb.txt name,\n"
" e.g. \"darkblue\" or numerical \"#RRGGBB\"). Currently\n" " e.g. \"darkblue\" or numerical \"#RRGGBB\").\n"
" this option only works on GNOME, KDE, and classic X\n" "\n"
" (i.e. with the background image on the root window).\n" " Currently this option only works on GNOME, KDE, and\n"
" The \"gconftool-2\" and \"dcop\" external commands are\n" " classic X (i.e. with the background image on the root\n"
" run for GNOME and KDE respectively. Other desktops\n" " window). The \"gconftool-2\" and \"dcop\" external\n"
" won't work, e.g. XFCE (send us the corresponding\n" " commands are run for GNOME and KDE respectively.\n"
" commands if you find them). If x11vnc guesses your\n" " Other desktops won't work, e.g. XFCE (send us the\n"
" desktop incorrectly, you can force it by prefixing\n" " corresponding commands if you find them). If x11vnc\n"
" color with \"gnome:\", \"kde:\", or \"root:\".\n" " is running as root (inetd(1) or gdm(1)), the -users\n"
" option may be needed for GNOME and KDE. If x11vnc\n"
" guesses your desktop incorrectly, you can force it by\n"
" prefixing color with \"gnome:\", \"kde:\", or \"root:\".\n"
"-blackout string Black out rectangles on the screen. \"string\" is a\n" "-blackout string Black out rectangles on the screen. \"string\" is a\n"
" comma separated list of WxH+X+Y type geometries for\n" " comma separated list of WxH+X+Y type geometries for\n"
" each rectangle.\n" " each rectangle.\n"
...@@ -15535,8 +16155,7 @@ static void print_help(int mode) { ...@@ -15535,8 +16155,7 @@ static void print_help(int mode) {
" display (e.g. localhost:10).\n" " display (e.g. localhost:10).\n"
"\n" "\n"
" Examples: \"x11vnc -gui\", \"x11vnc -gui localhost:10\",\n" " Examples: \"x11vnc -gui\", \"x11vnc -gui localhost:10\",\n"
" \"x11vnc -gui :10\", \"x11vnc -gui wait,:10\",\n" " \"x11vnc -gui :10\", \"x11vnc -gui conn,host:10\",\n"
" \"x11vnc -gui <x11vnc-opts...>\"\n"
"\n" "\n"
" If you do not specify a gui X display in \"gui-opts\"\n" " If you do not specify a gui X display in \"gui-opts\"\n"
" then the DISPLAY environment variable and -display\n" " then the DISPLAY environment variable and -display\n"
...@@ -15591,6 +16210,7 @@ static void print_help(int mode) { ...@@ -15591,6 +16210,7 @@ static void print_help(int mode) {
" \"zero:x1,y1,x2,y2\" for a rectangle.\n" " \"zero:x1,y1,x2,y2\" for a rectangle.\n"
" refresh send the entire fb to all clients.\n" " refresh send the entire fb to all clients.\n"
" reset recreate the fb, polling memory, etc.\n" " reset recreate the fb, polling memory, etc.\n"
/* ext. cmd. */
" id:windowid set -id window to \"windowid\". empty\n" " id:windowid set -id window to \"windowid\". empty\n"
" or \"root\" to go back to root window\n" " or \"root\" to go back to root window\n"
" sid:windowid set -sid window to \"windowid\"\n" " sid:windowid set -sid window to \"windowid\"\n"
...@@ -15606,6 +16226,7 @@ static void print_help(int mode) { ...@@ -15606,6 +16226,7 @@ static void print_help(int mode) {
" visual:vis set -visual to \"vis\"\n" " visual:vis set -visual to \"vis\"\n"
" scale:frac set -scale to \"frac\"\n" " scale:frac set -scale to \"frac\"\n"
" viewonly enable -viewonly mode.\n" " viewonly enable -viewonly mode.\n"
/* access view,share,forever */
" noviewonly disable -viewonly mode.\n" " noviewonly disable -viewonly mode.\n"
" shared enable -shared mode.\n" " shared enable -shared mode.\n"
" noshared disable -shared mode.\n" " noshared disable -shared mode.\n"
...@@ -15616,6 +16237,7 @@ static void print_help(int mode) { ...@@ -15616,6 +16237,7 @@ static void print_help(int mode) {
" connects in the next n secs.\n" " connects in the next n secs.\n"
" deny deny any new connections, same as \"lock\"\n" " deny deny any new connections, same as \"lock\"\n"
" nodeny allow new connections, same as \"unlock\"\n" " nodeny allow new connections, same as \"unlock\"\n"
/* access, filename */
" connect:host do reverse connection to host, \"host\"\n" " connect:host do reverse connection to host, \"host\"\n"
" may be a comma separated list of hosts\n" " may be a comma separated list of hosts\n"
" or host:ports. See -connect.\n" " or host:ports. See -connect.\n"
...@@ -15625,8 +16247,10 @@ static void print_help(int mode) { ...@@ -15625,8 +16247,10 @@ static void print_help(int mode) {
" If you know the client internal hex ID,\n" " If you know the client internal hex ID,\n"
" e.g. 0x3 (returned by -query clients and\n" " e.g. 0x3 (returned by -query clients and\n"
" RFB_CLIENT_ID), you can use that too.\n" " RFB_CLIENT_ID), you can use that too.\n"
/* access */
" allowonce:host For the next connection only, allow\n" " allowonce:host For the next connection only, allow\n"
" connection from \"host\".\n" " connection from \"host\".\n"
/* access */
" allow:hostlist set -allow list to (comma separated)\n" " allow:hostlist set -allow list to (comma separated)\n"
" \"hostlist\". See -allow and -localhost.\n" " \"hostlist\". See -allow and -localhost.\n"
" Do not use with -allow /path/to/file\n" " Do not use with -allow /path/to/file\n"
...@@ -15634,6 +16258,7 @@ static void print_help(int mode) { ...@@ -15634,6 +16258,7 @@ static void print_help(int mode) {
" use \"-host\" to delete a single host\n" " use \"-host\" to delete a single host\n"
" localhost enable -localhost mode\n" " localhost enable -localhost mode\n"
" nolocalhost disable -localhost mode\n" " nolocalhost disable -localhost mode\n"
/* ext. cmd. */
" accept:cmd set -accept \"cmd\" (empty to disable).\n" " accept:cmd set -accept \"cmd\" (empty to disable).\n"
" gone:cmd set -gone \"cmd\" (empty to disable).\n" " gone:cmd set -gone \"cmd\" (empty to disable).\n"
" noshm enable -noshm mode.\n" " noshm enable -noshm mode.\n"
...@@ -15644,6 +16269,7 @@ static void print_help(int mode) { ...@@ -15644,6 +16269,7 @@ static void print_help(int mode) {
" onetile enable -onetile mode. (you may need to\n" " onetile enable -onetile mode. (you may need to\n"
" set shm for this to do something)\n" " set shm for this to do something)\n"
" noonetile disable -onetile mode.\n" " noonetile disable -onetile mode.\n"
/* ext. cmd. */
" solid enable -solid mode\n" " solid enable -solid mode\n"
" nosolid disable -solid mode.\n" " nosolid disable -solid mode.\n"
" solid_color:color set -solid color (and apply it).\n" " solid_color:color set -solid color (and apply it).\n"
...@@ -15674,6 +16300,7 @@ static void print_help(int mode) { ...@@ -15674,6 +16300,7 @@ static void print_help(int mode) {
" noclear_mods disable -clear_mods mode.\n" " noclear_mods disable -clear_mods mode.\n"
" clear_keys enable -clear_keys mode and clear them.\n" " clear_keys enable -clear_keys mode and clear them.\n"
" noclear_keys disable -clear_keys mode.\n" " noclear_keys disable -clear_keys mode.\n"
/* filename */
" remap:str set -remap \"str\" (empty to disable).\n" " remap:str set -remap \"str\" (empty to disable).\n"
" See -remap for the form of \"str\"\n" " See -remap for the form of \"str\"\n"
" (basically: key1-key2,key3-key4,...)\n" " (basically: key1-key2,key3-key4,...)\n"
...@@ -15733,6 +16360,7 @@ static void print_help(int mode) { ...@@ -15733,6 +16360,7 @@ static void print_help(int mode) {
" height parameter to n.\n" " height parameter to n.\n"
" desktop:str set -desktop name to str for new clients.\n" " desktop:str set -desktop name to str for new clients.\n"
" rfbport:n set -rfbport to n.\n" " rfbport:n set -rfbport to n.\n"
/* access */
" http enable http client connections.\n" " http enable http client connections.\n"
" nohttp disable http client connections.\n" " nohttp disable http client connections.\n"
" httpport:n set -httpport to n.\n" " httpport:n set -httpport to n.\n"
...@@ -15817,7 +16445,7 @@ static void print_help(int mode) { ...@@ -15817,7 +16445,7 @@ static void print_help(int mode) {
" nodontdisconnect desktop noremote\n" " nodontdisconnect desktop noremote\n"
"\n" "\n"
" aro= display vncdisplay desktopname http_url auth\n" " aro= display vncdisplay desktopname http_url auth\n"
" rootshift scale_str scaled_x scaled_y scale_numer\n" " users rootshift scale_str scaled_x scaled_y scale_numer\n"
" scale_denom scale_fac scaling_noblend scaling_nomult4\n" " scale_denom scale_fac scaling_noblend scaling_nomult4\n"
" scaling_pad scaling_interpolate inetd safer unsafe\n" " scaling_pad scaling_interpolate inetd safer unsafe\n"
" passwdfile using_shm logfile o rc norc h help V version\n" " passwdfile using_shm logfile o rc norc h help V version\n"
...@@ -16097,10 +16725,14 @@ static void check_rcfile(int argc, char **argv) { ...@@ -16097,10 +16725,14 @@ static void check_rcfile(int argc, char **argv) {
perror("fopen"); perror("fopen");
exit(1); exit(1);
} }
} else if (getenv("HOME") == NULL) { } else {
char *home = get_home_dir();
if (! home) {
norc = 1; norc = 1;
} else { } else {
strncpy(rcfile, getenv("HOME"), 500); strncpy(rcfile, home, 500);
free(home);
strcat(rcfile, "/.x11vncrc"); strcat(rcfile, "/.x11vncrc");
infile = rcfile; infile = rcfile;
rc = fopen(rcfile, "r"); rc = fopen(rcfile, "r");
...@@ -16110,6 +16742,7 @@ static void check_rcfile(int argc, char **argv) { ...@@ -16110,6 +16742,7 @@ static void check_rcfile(int argc, char **argv) {
rc_rcfile = strdup(rcfile); rc_rcfile = strdup(rcfile);
} }
} }
}
argv2 = (char **) malloc(argmax * sizeof(char *)); argv2 = (char **) malloc(argmax * sizeof(char *));
argv2[argc2++] = strdup(argv[0]); argv2[argc2++] = strdup(argv[0]);
...@@ -16161,12 +16794,7 @@ static void check_rcfile(int argc, char **argv) { ...@@ -16161,12 +16794,7 @@ static void check_rcfile(int argc, char **argv) {
if ( (q = strchr(p, '#')) != NULL) { if ( (q = strchr(p, '#')) != NULL) {
*q = '\0'; *q = '\0';
} }
while (*p) { p = lblanks(p);
if (! isspace(*p)) {
break;
}
p++;
}
strncat(buf, p, sz - strlen(buf) - 1); strncat(buf, p, sz - strlen(buf) - 1);
if (cont) { if (cont) {
...@@ -16195,12 +16823,7 @@ static void check_rcfile(int argc, char **argv) { ...@@ -16195,12 +16823,7 @@ static void check_rcfile(int argc, char **argv) {
p = buf; p = buf;
p += strlen(parm); p += strlen(parm);
while (*p) { p = lblanks(p);
if (! isspace(*p)) {
break;
}
p++;
}
if (*p == '\0') { if (*p == '\0') {
buf[0] = '\0'; buf[0] = '\0';
continue; continue;
...@@ -16258,6 +16881,45 @@ int main(int argc, char* argv[]) { ...@@ -16258,6 +16881,45 @@ int main(int argc, char* argv[]) {
/* if we are root limit some remote commands: */ /* if we are root limit some remote commands: */
if (!getuid() || !geteuid()) { if (!getuid() || !geteuid()) {
safe_remote_only = 1; safe_remote_only = 1;
started_as_root = 1;
/* check for '-users =fred' */
for (i=1; i < argc; i++) {
char *u;
int saved;
if (strcmp(argv[i], "-users")) {
continue;
}
if (i == argc - 1) {
fprintf(stderr, "not enough arguments for: "
"-users\n");
exit(1);
}
if (*(argv[i+1]) != '=') {
break;
}
u = strdup(argv[i+1]);
*u = '+';
if (strstr(u, "+guess") == u) {
fprintf(stderr, "invalid user: %s\n", u);
exit(1);
}
/* kludge... */
saved = using_shm;
using_shm = 0;
if (!switch_user(u)) {
fprintf(stderr, "Could not switch to user: "
"%s\n", u+1);
exit(1);
} else {
fprintf(stderr, "Switched to user: %s\n", u+1);
started_as_root = 2;
}
using_shm = saved;
free(u);
break;
}
} }
argv_vnc[0] = strdup(argv[0]); argv_vnc[0] = strdup(argv[0]);
...@@ -16305,7 +16967,7 @@ int main(int argc, char* argv[]) { ...@@ -16305,7 +16967,7 @@ int main(int argc, char* argv[]) {
if (!strcmp(arg, "-display")) { if (!strcmp(arg, "-display")) {
CHECK_ARGC CHECK_ARGC
use_dpy = strdup(argv[++i]); use_dpy = strdup(argv[++i]);
} else if (!strcmp(arg, "-auth")) { } else if (!strcmp(arg, "-auth") || !strcmp(arg, "-xauth")) {
CHECK_ARGC CHECK_ARGC
auth_file = strdup(argv[++i]); auth_file = strdup(argv[++i]);
} else if (!strcmp(arg, "-id") || !strcmp(arg, "-sid")) { } else if (!strcmp(arg, "-id") || !strcmp(arg, "-sid")) {
...@@ -16361,6 +17023,9 @@ int main(int argc, char* argv[]) { ...@@ -16361,6 +17023,9 @@ int main(int argc, char* argv[]) {
} else if (!strcmp(arg, "-timeout")) { } else if (!strcmp(arg, "-timeout")) {
CHECK_ARGC CHECK_ARGC
first_conn_timeout = atoi(argv[++i]); first_conn_timeout = atoi(argv[++i]);
} else if (!strcmp(arg, "-users")) {
CHECK_ARGC
users_list = strdup(argv[++i]);
} else if (!strcmp(arg, "-inetd")) { } else if (!strcmp(arg, "-inetd")) {
inetd = 1; inetd = 1;
} else if (!strcmp(arg, "-connect")) { } else if (!strcmp(arg, "-connect")) {
...@@ -16927,6 +17592,8 @@ int main(int argc, char* argv[]) { ...@@ -16927,6 +17592,8 @@ int main(int argc, char* argv[]) {
: "null"); : "null");
fprintf(stderr, " gone: %s\n", gone_cmd ? gone_cmd fprintf(stderr, " gone: %s\n", gone_cmd ? gone_cmd
: "null"); : "null");
fprintf(stderr, " users: %s\n", users_list ? users_list
: "null");
fprintf(stderr, " using_shm: %d\n", using_shm); fprintf(stderr, " using_shm: %d\n", using_shm);
fprintf(stderr, " flipbytes: %d\n", flip_byte_order); fprintf(stderr, " flipbytes: %d\n", flip_byte_order);
fprintf(stderr, " onetile: %d\n", single_copytile); fprintf(stderr, " onetile: %d\n", single_copytile);
...@@ -17162,7 +17829,8 @@ int main(int argc, char* argv[]) { ...@@ -17162,7 +17829,8 @@ int main(int argc, char* argv[]) {
" cursor mode\n"); " cursor mode\n");
rfbLog(" to: '-cursor most'.\n"); rfbLog(" to: '-cursor most'.\n");
rfbLog(" to disable this behavior use: " rfbLog(" to disable this behavior use: "
"'-cursor arrow'.\n"); "'-cursor arrow'\n");
rfbLog(" or '-noxfixes'.\n");
} }
} }
if(!strcmp(multiple_cursors_mode, "most")) { if(!strcmp(multiple_cursors_mode, "most")) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment