Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
L
libvncserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
rasky
libvncserver
Commits
5b18d401
Commit
5b18d401
authored
Feb 09, 2005
by
runge
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
x11vnc -users, fix -solid on gnome/kde, configure.ac pwd.h wait.h and utmpx.h
parent
b04336f9
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
965 additions
and
160 deletions
+965
-160
ChangeLog
ChangeLog
+4
-0
configure.ac
configure.ac
+2
-2
ChangeLog
x11vnc/ChangeLog
+5
-0
README
x11vnc/README
+32
-13
tkx11vnc
x11vnc/tkx11vnc
+15
-0
tkx11vnc.h
x11vnc/tkx11vnc.h
+15
-0
x11vnc.1
x11vnc/x11vnc.1
+99
-20
x11vnc.c
x11vnc/x11vnc.c
+793
-125
No files found.
ChangeLog
View file @
5b18d401
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>
* configure.ac: add /usr/sfw on Solaris when XFIXES, add
--with-jpeg=DIR --with-zlib=DIR, workaround bug when
...
...
configure.ac
View file @
5b18d401
...
...
@@ -213,7 +213,7 @@ AC_SUBST(WSOCKLIB)
# Checks for header files.
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.
AC_C_CONST
...
...
@@ -234,7 +234,7 @@ AC_FUNC_VPRINTF
AC_FUNC_FORK
AC_CHECK_LIB(nsl,gethostbyname)
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
AC_CHECK_LIB(cygipc,shmget)
...
...
x11vnc/ChangeLog
View file @
5b18d401
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>
* -solid solid color background when clients are connected.
* -opts/-? to show option names only.
...
...
x11vnc/README
View file @
5b18d401
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
:
...
...
@@ -354,16 +354,34 @@ vncviewer -via $host localhost:0 # must be TightVNC vncviewer.
TightVNC
encoding
gives
very
good
compression
and
performance
,
it
even
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
/
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
at
[
36
]
ftp
://
ftp
.
uu
.
net
/
graphics
/
jpeg
/
and
zlib
at
/
usr
/
lib
).
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
[
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
locations
information
to
the
libvncserver
configuration
:
locations
information
to
the
libvncserver
configuration
via
the
CPPFLAGS
and
LDFLAGS
environmental
variables
:
#
!/bin/sh
#
Build
script
for
Solaris
,
etc
,
with
gcc
,
libjpeg
and
libz
in
...
...
@@ -511,11 +529,12 @@ ls -l ./x11vnc/x11vnc
SunRay Gotcha #1: Note that even though your SunRay X11 DISPLAY is
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
you supply to the VNC viewer) is something like sunray-server:0
(note the :0 corresponding to port 5900, it is not :137). If it cannot
get 5900, it tries for 5901, and so on. You can also try to force the
port (and thereby the VNC display) using the -rfbport NNNN option.
port if it can get it, in which case the VNC display (i.e. the
information you supply to the VNC viewer) is something like
sunray-server:0 (note the :0 corresponding to port 5900, it is not
:137). If it cannot get 5900, it tries for 5901, and so on. You can
also try to force the port (and thereby the VNC display) using the
-rfbport NNNN option.
Limitations:
...
...
@@ -530,8 +549,8 @@ ls -l ./x11vnc/x11vnc
* A rate limiting factor for x11vnc performance is that video
hardware is optimized for writing, not reading (x11vnc reads the
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
in the whole video hardware framebuffer (5MB for 1280x1024 at
be a factor of 10-
200, and it usually takes about 0.5-1 sec to
read
in the whole video hardware framebuffer (5MB for 1280x1024 at
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.
To get a sense of the read and write speeds of your video card,
...
...
@@ -540,7 +559,7 @@ ls -l ./x11vnc/x11vnc
direct graphics access the dga command (press "b" to run the
benchmark and then after a few seconds press "q" to quit).
On XFree86 it is actually possible to increase the framebuffer
read speed considerably (5-
5
0 times) by using the Shadow
read speed considerably (5-
10
0 times) by using the Shadow
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
Option "ShadowFB" "true" (and depending on video card driver,
...
...
x11vnc/tkx11vnc
View file @
5b18d401
...
...
@@ -1660,6 +1660,7 @@ proc split_query {query} {
proc set_x11_display
{
name
}
{
global x11_display
set
x11_display
"x11vnc X display:
$name
"
wm title
.
"tkx11vnc -
$name
"
}
proc set_vnc_display
{
name
}
{
global vnc_display
...
...
@@ -1671,6 +1672,7 @@ proc set_vnc_url {name} {
}
proc no_x11_display
{}
{
set_x11_display
"(*none*)"
wm title
.
"tkx11vnc"
}
proc no_vnc_display
{}
{
set_vnc_display
"(*none*)"
...
...
@@ -2391,6 +2393,7 @@ proc start_x11vnc {} {
proc run_remote_cmd {opts} {
global menu_var x11vnc_prog x11vnc_cmdline x11vnc_xdisplay
global x11vnc_auth_file
set debug [in_debug_mode]
...
...
@@ -2413,6 +2416,10 @@ proc run_remote_cmd {opts} {
lappend cmd "-display"
lappend cmd
$x11vnc_xdisplay
}
if {
$x11vnc_auth_file
!= ""} {
lappend cmd "-auth"
lappend cmd
$x11vnc_auth_file
}
lappend cmd "-sync"
foreach word
$opts
{
lappend cmd
$word
...
...
@@ -2501,6 +2508,7 @@ proc try_connect {} {
# main:
global env x11vnc_prog x11vnc_cmdline x11vnc_xdisplay x11vnc_connect;
global x11vnc_auth_file
global helpall helptext helpremote helplabel hostname;
global all_settings reply_xdisplay always_update
global max_text_height max_text_width
...
...
@@ -2585,6 +2593,13 @@ if {[info exists env(X11VNC_XDISPLAY)]} {
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]
#puts [exec env]
#puts "x11vnc_xdisplay:
$x11vnc_xdisplay
"
...
...
x11vnc/tkx11vnc.h
View file @
5b18d401
...
...
@@ -1666,6 +1666,7 @@
"proc set_x11_display {name} {
\n
"
" global x11_display
\n
"
" set x11_display
\"
x11vnc X display: $name
\"\n
"
" wm title .
\"
tkx11vnc - $name
\"\n
"
"}
\n
"
"proc set_vnc_display {name} {
\n
"
" global vnc_display
\n
"
...
...
@@ -1677,6 +1678,7 @@
"}
\n
"
"proc no_x11_display {} {
\n
"
" set_x11_display
\"
(*none*)
\"\n
"
" wm title .
\"
tkx11vnc
\"\n
"
"}
\n
"
"proc no_vnc_display {} {
\n
"
" set_vnc_display
\"
(*none*)
\"\n
"
...
...
@@ -2397,6 +2399,7 @@
"
\n
"
"proc run_remote_cmd {opts} {
\n
"
" global menu_var x11vnc_prog x11vnc_cmdline x11vnc_xdisplay
\n
"
" global x11vnc_auth_file
\n
"
"
\n
"
" set debug [in_debug_mode]
\n
"
"
\n
"
...
...
@@ -2419,6 +2422,10 @@
" lappend cmd
\"
-display
\"\n
"
" lappend cmd $x11vnc_xdisplay
\n
"
" }
\n
"
" if {$x11vnc_auth_file !=
\"\"
} {
\n
"
" lappend cmd
\"
-auth
\"\n
"
" lappend cmd $x11vnc_auth_file
\n
"
" }
\n
"
" lappend cmd
\"
-sync
\"\n
"
" foreach word $opts {
\n
"
" lappend cmd $word
\n
"
...
...
@@ -2507,6 +2514,7 @@
"# main:
\n
"
"
\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 all_settings reply_xdisplay always_update
\n
"
"global max_text_height max_text_width
\n
"
...
...
@@ -2591,6 +2599,13 @@
" set x11vnc_xdisplay
\"
:0
\"
;
\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
"
"#puts [exec env]
\n
"
"#puts
\"
x11vnc_xdisplay: $x11vnc_xdisplay
\"\n
"
...
...
x11vnc/x11vnc.1
View file @
5b18d401
...
...
@@ -2,7 +2,7 @@
.TH X11VNC "1" "February 2005" "x11vnc " "User Commands"
.SH NAME
x11vnc - allow VNC connections to real X11 displays
version: 0.7.1pre, lastmod: 2005-02-0
5
version: 0.7.1pre, lastmod: 2005-02-0
8
.SH SYNOPSIS
.B x11vnc
[OPTION]...
...
...
@@ -58,11 +58,11 @@ environment variable to \fIdisp\fR.
.IP
Set the X authority file to be \fIfile\fR, equivalent to
setting the XAUTHORITY environment variable to \fIfile\fR
before startup. See
before startup. S
ame as \fB-xauth\fR file. S
ee
.IR Xsecurity (7)
,
,
.IR xauth (1)
man pages.
man pages
for more info
.
.PP
\fB-id\fR \fIwindowid\fR
.IP
...
...
@@ -210,10 +210,17 @@ Note: if you are not redirecting stderr to a log file
For use with "vncviewer -listen" reverse connections.
If \fIstring\fR has the form "host" or "host:port"
the connection is made once at startup. Use commas
for a list of host's and host:port's. If \fIstring\fR
contains "/" it is instead interpreted as a file to
periodically check for new hosts. The first line is
read and then the file is truncated.
for a list of host's and host:port's.
.IP
If \fIstring\fR contains "/" it is instead interpreted
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
\fB-vncconnect,\fR \fB-novncconnect\fR
.IP
...
...
@@ -277,6 +284,17 @@ external command returns 0 the client is accepted,
otherwise the client is rejected. See below for an
extension to accept a client view-only.
.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
be set to the incoming client IP number and the port
in RFB_CLIENT_PORT (or -1 if unavailable). Similarly,
...
...
@@ -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
is not interpreted by x11vnc. Example: \fB-gone\fR 'xlock &'
.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
.IP
Do not use the MIT-SHM extension for the polling.
...
...
@@ -357,15 +430,22 @@ To improve performance, when VNC clients are connected
try to change the desktop background to a solid color.
The [color] is optional: the default color is "cyan4".
For a different one specify the X color (rgb.txt name,
e.g. "darkblue" or numerical "#RRGGBB"). Currently
this option only works on GNOME, KDE, and classic X
(i.e. with the background image on the root window).
The "gconftool-2" and "dcop" external commands are
run for GNOME and KDE respectively. Other desktops
won't work, e.g. XFCE (send us the corresponding
commands if you find them). If x11vnc guesses your
desktop incorrectly, you can force it by prefixing
color with "gnome:", "kde:", or "root:".
e.g. "darkblue" or numerical "#RRGGBB").
.IP
Currently this option only works on GNOME, KDE, and
classic X (i.e. with the background image on the root
window). The "gconftool-2" and "dcop" external
commands are run for GNOME and KDE respectively.
Other desktops won't work, e.g. XFCE (send us the
corresponding commands if you find them). If x11vnc
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
\fB-blackout\fR \fIstring\fR
.IP
...
...
@@ -930,8 +1010,7 @@ the gui to come back to you via your ssh redirected X
display (e.g. localhost:10).
.IP
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 <x11vnc-opts...>"
"x11vnc \fB-gui\fR :10", "x11vnc \fB-gui\fR conn,host:10",
.IP
If you do not specify a gui X display in "gui-opts"
then the DISPLAY environment variable and \fB-display\fR
...
...
@@ -1361,7 +1440,7 @@ noalwaysshared nevershared noalwaysshared dontdisconnect
nodontdisconnect desktop noremote
.IP
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
scaling_pad scaling_interpolate inetd safer unsafe
passwdfile using_shm logfile o rc norc h help V version
...
...
x11vnc/x11vnc.c
View file @
5b18d401
...
...
@@ -137,11 +137,17 @@
#define LIBVNCSERVER_HAVE_XSHM 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_XFIXES 1
#define LIBVNCSERVER_HAVE_XDAMAGE 1
*/
#endif
/* OLD_TREE */
#include <unistd.h>
...
...
@@ -215,6 +221,17 @@ extern int h_errno;
#include <arpa/inet.h>
#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
* undef SOLARIS_OVERLAY or IRIX_OVERLAY if there are problems building.
...
...
@@ -273,7 +290,7 @@ static int xdamage_base_event_type;
#endif
/* date +'lastmod: %Y-%m-%d' */
char
lastmod
[]
=
"0.7.1pre lastmod: 2005-02-0
5
"
;
char
lastmod
[]
=
"0.7.1pre lastmod: 2005-02-0
8
"
;
/* X display info */
...
...
@@ -371,6 +388,10 @@ time_t last_event, last_input, last_client = 0;
/* last client to move pointer */
rfbClientPtr
last_pointer_client
=
NULL
;
int
accepted_client
=
0
;
int
client_count
=
0
;
int
clients_served
=
0
;
/* more transient kludge variables: */
int
cursor_x
,
cursor_y
;
/* x and y from the viewer(s) */
int
got_user_input
=
0
;
...
...
@@ -433,6 +454,7 @@ void initialize_polling_images(void);
void
initialize_signals
(
void
);
void
initialize_tiles
(
void
);
void
initialize_speeds
(
void
);
void
clean_shm
(
int
);
void
free_tiles
(
void
);
void
initialize_watch_bell
(
void
);
void
initialize_xinerama
(
void
);
...
...
@@ -545,6 +567,8 @@ int shared = 0; /* share vnc display. */
int
deny_all
=
0
;
/* global locking of new clients */
int
accept_remote_cmds
=
1
;
/* -noremote */
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_once
=
NULL
;
/* one time -allow */
char
*
accept_cmd
=
NULL
;
/* for -accept */
...
...
@@ -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
)
{
if
(
sscanf
(
str
,
"0x%lx"
,
num
)
!=
1
)
{
if
(
sscanf
(
str
,
"%ld"
,
num
)
!=
1
)
{
...
...
@@ -852,6 +887,424 @@ char *bitprint(unsigned int st, int nbits) {
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.
* Up to caller to free returned string.
...
...
@@ -1318,7 +1771,7 @@ void clean_shm(int quick) {
break
;
}
}
if
(
!
quiet
&&
!
quick
)
{
if
(
!
quiet
)
{
rfbLog
(
"deleted %d tile_row polling images.
\n
"
,
cnt
);
}
}
...
...
@@ -1356,62 +1809,13 @@ void clean_up_exit (int 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 */
static
XErrorHandler
Xerror_def
;
static
XIOErrorHandler
XIOerr_def
;
XErrorEvent
*
trapped_xerror_event
;
int
trapped_xerror
=
0
;
int
trapped_xioerror
=
0
;
int
trapped_getimage_xerror
=
0
;
int
trap_xerror
(
Display
*
d
,
XErrorEvent
*
error
)
{
...
...
@@ -1420,12 +1824,19 @@ int trap_xerror(Display *d, XErrorEvent *error) {
return
0
;
}
int
trap_xioerror
(
Display
*
d
)
{
trapped_xioerror
=
1
;
return
0
;
}
int
trap_getimage_xerror
(
Display
*
d
,
XErrorEvent
*
error
)
{
trapped_getimage_xerror
=
1
;
trapped_xerror_event
=
error
;
return
0
;
}
void
interrupted
(
int
);
static
int
Xerror
(
Display
*
d
,
XErrorEvent
*
error
)
{
X_UNLOCK
;
interrupted
(
0
);
...
...
@@ -1434,7 +1845,7 @@ static int Xerror(Display *d, XErrorEvent *error) {
static
int
XIOerr
(
Display
*
d
)
{
X_UNLOCK
;
interrupted
(
0
);
interrupted
(
-
1
);
return
(
*
XIOerr_def
)(
d
);
}
...
...
@@ -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: */
int
valid_window
(
Window
win
)
{
XErrorHandler
old_handler
;
...
...
@@ -1563,10 +2031,6 @@ void initialize_signals(void) {
* 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
*/
...
...
@@ -3189,16 +3653,9 @@ void initialize_remap(char *infile) {
rewind
(
in
);
}
while
(
fgets
(
line
,
256
,
in
)
!=
NULL
)
{
int
blank
=
1
,
isbtn
=
0
;
p
=
line
;
while
(
*
p
)
{
if
(
!
isspace
(
*
p
))
{
blank
=
0
;
break
;
}
p
++
;
}
if
(
blank
)
{
int
isbtn
=
0
;
p
=
lblanks
(
line
);
if
(
*
p
==
'\0'
)
{
continue
;
}
if
(
strchr
(
line
,
'#'
))
{
...
...
@@ -7987,6 +8444,8 @@ char *process_remote_cmd(char *cmd, int stringonly) {
}
}
else
if
(
!
strcmp
(
p
,
"auth"
))
{
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"
))
{
snprintf
(
buf
,
bufn
,
"aro=%s:%d"
,
p
,
rootshift
);
}
else
if
(
!
strcmp
(
p
,
"scale_str"
))
{
...
...
@@ -9156,6 +9615,10 @@ int get_which_cursor(void) {
which
=
CURS_TERM
;
}
else
if
(
strstr
(
winfo
.
res_class
,
"text"
))
{
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) {
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
);
free_tiles
();
}
...
...
@@ -10655,13 +11119,45 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
/* -- 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
;
if
(
!
cmd
||
*
cmd
==
'\0'
)
{
return
0
;
}
rfbLog
(
"running command:
\n
%s
\n
"
,
cmd
);
usr_bin_path
(
0
);
rc
=
system
(
cmd
);
usr_bin_path
(
1
);
if
(
rc
>=
256
)
{
rc
=
rc
/
256
;
}
...
...
@@ -10674,8 +11170,14 @@ char *cmd_output(char *cmd) {
char
line
[
1024
];
int
rc
;
if
(
!
cmd
||
*
cmd
==
'\0'
)
{
return
""
;
}
rfbLog
(
"running pipe:
\n
%s
\n
"
,
cmd
);
usr_bin_path
(
0
);
p
=
popen
(
cmd
,
"r"
);
usr_bin_path
(
1
);
output
[
0
]
=
'\0'
;
...
...
@@ -10826,12 +11328,12 @@ void solid_gnome(char *color) {
cmd
=
(
char
*
)
malloc
(
strlen
(
set_option
)
-
2
+
strlen
(
orig_option
)
+
1
);
sprintf
(
cmd
,
set_option
,
orig_option
);
d
o
_cmd
(
cmd
);
d
t
_cmd
(
cmd
);
free
(
cmd
);
cmd
=
(
char
*
)
malloc
(
strlen
(
set_color
)
-
2
+
strlen
(
orig_color
)
+
1
);
sprintf
(
cmd
,
set_color
,
orig_color
);
d
o
_cmd
(
cmd
);
d
t
_cmd
(
cmd
);
free
(
cmd
);
return
;
}
...
...
@@ -10860,24 +11362,42 @@ void solid_gnome(char *color) {
rfbLog
(
"bad color: %s
\n
"
,
color
);
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
);
d
o
_cmd
(
cmd
);
d
t
_cmd
(
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"
);
d
o
_cmd
(
cmd
);
d
t
_cmd
(
cmd
);
free
(
cmd
);
}
void
solid_kde
(
char
*
color
)
{
char
set_color
[]
=
"dcop kdesktop KBackgroundIface setColor '%s' 1"
;
char
bg_off
[]
=
"dcop kdesktop KBackgroundIface setBackgroundEnabled 0"
;
char
bg_on
[]
=
"dcop kdesktop KBackgroundIface setBackgroundEnabled 1"
;
char
*
cmd
;
char
set_color
[]
=
"dcop --user '%s' kdesktop KBackgroundIface setColor '%s' 1"
;
char
bg_off
[]
=
"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
)
{
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
;
}
...
...
@@ -10886,11 +11406,18 @@ void solid_kde(char *color) {
return
;
}
cmd
=
(
char
*
)
malloc
(
strlen
(
set_color
)
-
2
+
strlen
(
color
)
+
1
)
;
sprintf
(
cmd
,
set_color
,
color
);
do_cmd
(
cmd
);
d
o_cmd
(
bg_off
);
len
=
strlen
(
set_color
)
+
strlen
(
user
)
+
strlen
(
color
)
+
1
;
cmd
=
(
char
*
)
malloc
(
len
);
sprintf
(
cmd
,
set_color
,
user
,
color
);
d
t_cmd
(
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
()
{
...
...
@@ -10912,6 +11439,11 @@ void solid_bg(int restore) {
static
char
*
prev_str
;
char
*
dtname
,
*
color
;
if
(
started_as_root
==
1
&&
users_list
)
{
/* we are still root, don't try. */
return
;
}
if
(
restore
)
{
if
(
!
solid_on
)
{
return
;
...
...
@@ -11644,6 +12176,7 @@ void shm_clean(XShmSegmentInfo *shm, XImage *xim) {
#endif
if
(
xim
!=
NULL
)
{
XDestroyImage
(
xim
);
xim
=
NULL
;
}
X_UNLOCK
;
...
...
@@ -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"
;
char
cmd
[
100
];
char
*
wish
=
NULL
,
*
orig_path
,
*
full_path
,
*
tpath
,
*
p
;
char
*
old_xauth
=
NULL
;
int
try_max
=
4
,
sleep
=
300
;
pid_t
mypid
=
getpid
();
FILE
*
pipe
,
*
tmpf
;
...
...
@@ -13687,7 +14221,14 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc, pid_t parent) {
int
rc
,
i
;
rfbLogEnable
(
0
);
if
(
!
client_connect_file
)
{
if
(
getenv
(
"XAUTHORITY"
)
!=
NULL
)
{
old_xauth
=
strdup
(
getenv
(
"XAUTHORITY"
));
}
dpy
=
XOpenDisplay
(
x11vnc_xdisplay
);
if
(
!
dpy
&&
auth_file
)
{
set_env
(
"XAUTHORITY"
,
auth_file
);
dpy
=
XOpenDisplay
(
x11vnc_xdisplay
);
}
if
(
!
dpy
&&
!
x11vnc_xdisplay
)
{
x11vnc_xdisplay
=
strdup
(
":0"
);
dpy
=
XOpenDisplay
(
x11vnc_xdisplay
);
...
...
@@ -13719,6 +14260,9 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc, pid_t parent) {
}
}
set_env
(
"X11VNC_XDISPLAY"
,
x11vnc_xdisplay
);
if
(
getenv
(
"XAUTHORITY"
)
!=
NULL
)
{
set_env
(
"X11VNC_XAUTHORITY"
,
getenv
(
"XAUTHORITY"
));
}
if
(
rc
==
0
)
{
fprintf
(
stderr
,
"gui: ping succeeded.
\n
"
);
set_env
(
"X11VNC_CONNECT"
,
"1"
);
...
...
@@ -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"
" again manually.
\n
"
,
x11vnc_xdisplay
);
}
if
(
dpy
)
{
XCloseDisplay
(
dpy
);
}
if
(
old_xauth
)
{
set_env
(
"XAUTHORITY"
,
old_xauth
);
free
(
old_xauth
);
}
}
orig_path
=
getenv
(
"PATH"
);
...
...
@@ -13768,6 +14319,9 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc, pid_t parent) {
set_env
(
"DISPLAY"
,
gui_xdisplay
);
set_env
(
"X11VNC_PROG"
,
program_name
);
set_env
(
"X11VNC_CMDLINE"
,
program_cmdline
);
if
(
auth_file
)
{
set_env
(
"X11VNC_AUTH_FILE"
,
auth_file
);
}
sprintf
(
cmd
,
"%s -"
,
wish
);
tmpf
=
tmpfile
();
...
...
@@ -13871,6 +14425,7 @@ void do_gui(char *opts) {
if
(
!
test_dpy
)
{
fprintf
(
stderr
,
"error: cannot connect to gui X DISPLAY: %s
\n
"
,
gui_xdisplay
);
exit
(
1
);
}
XCloseDisplay
(
test_dpy
);
...
...
@@ -14776,11 +15331,15 @@ static void watch_loop(void) {
check_xevents
();
check_connect_inputs
();
check_padded_fb
();
if
(
started_as_root
)
{
check_switched_user
();
}
if
(
first_conn_timeout
<
0
)
{
start
=
time
(
0
);
first_conn_timeout
=
-
first_conn_timeout
;
}
if
(
!
screen
||
!
screen
->
clientHead
)
{
/* waiting for a client */
if
(
first_conn_timeout
)
{
...
...
@@ -14788,13 +15347,15 @@ static void watch_loop(void) {
rfbLog
(
"No client after %d secs.
\n
"
,
first_conn_timeout
);
shut_down
=
1
;
continue
;
}
}
usleep
(
200
*
1000
);
continue
;
}
first_conn_timeout
=
0
;
if
(
first_conn_timeout
&&
all_clients_initialized
())
{
first_conn_timeout
=
0
;
}
if
(
nofb
)
{
/* no framebuffer polling needed */
...
...
@@ -14897,7 +15458,8 @@ static void print_help(int mode) {
" environment variable to
\"
disp
\"
.
\n
"
"-auth file Set the X authority file to be
\"
file
\"
, equivalent to
\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
"
"-id windowid Show the window corresponding to
\"
windowid
\"
not
\n
"
" the entire display. New windows like popup menus,
\n
"
...
...
@@ -14994,10 +15556,13 @@ static void print_help(int mode) {
"-connect string For use with
\"
vncviewer -listen
\"
reverse connections.
\n
"
" If
\"
string
\"
has the form
\"
host
\"
or
\"
host:port
\"\n
"
" the connection is made once at startup. Use commas
\n
"
" for a list of host's and host:port's. If
\"
string
\"\n
"
" contains
\"
/
\"
it is instead interpreted as a file to
\n
"
" periodically check for new hosts. The first line is
\n
"
" read and then the file is truncated.
\n
"
" for a list of host's and host:port's.
\n
"
"
\n
"
" If
\"
string
\"
contains
\"
/
\"
it is instead interpreted
\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
"
"-novncconnect VNC program vncconnect(1). When the property is
\n
"
" set to
\"
host
\"
or
\"
host:port
\"
establish a reverse
\n
"
...
...
@@ -15035,6 +15600,11 @@ static void print_help(int mode) {
" otherwise the client is rejected. See below for an
\n
"
" extension to accept a client view-only.
\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
"
" be set to the incoming client IP number and the port
\n
"
" in RFB_CLIENT_PORT (or -1 if unavailable). Similarly,
\n
"
...
...
@@ -15086,6 +15656,53 @@ static void print_help(int mode) {
" in -accept. Unlike -accept, the command return code
\n
"
" is not interpreted by x11vnc. Example: -gone 'xlock &'
\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
"
" Remote displays can be polled this way: be careful this
\n
"
" can use large amounts of network bandwidth. This is
\n
"
...
...
@@ -15101,15 +15718,18 @@ static void print_help(int mode) {
" try to change the desktop background to a solid color.
\n
"
" The [color] is optional: the default color is
\"
cyan4
\"
.
\n
"
" For a different one specify the X color (rgb.txt name,
\n
"
" e.g.
\"
darkblue
\"
or numerical
\"
#RRGGBB
\"
). Currently
\n
"
" this option only works on GNOME, KDE, and classic X
\n
"
" (i.e. with the background image on the root window).
\n
"
" The
\"
gconftool-2
\"
and
\"
dcop
\"
external commands are
\n
"
" run for GNOME and KDE respectively. Other desktops
\n
"
" won't work, e.g. XFCE (send us the corresponding
\n
"
" commands if you find them). If x11vnc guesses your
\n
"
" desktop incorrectly, you can force it by prefixing
\n
"
" color with
\"
gnome:
\"
,
\"
kde:
\"
, or
\"
root:
\"
.
\n
"
" e.g.
\"
darkblue
\"
or numerical
\"
#RRGGBB
\"
).
\n
"
"
\n
"
" Currently this option only works on GNOME, KDE, and
\n
"
" classic X (i.e. with the background image on the root
\n
"
" window). The
\"
gconftool-2
\"
and
\"
dcop
\"
external
\n
"
" commands are run for GNOME and KDE respectively.
\n
"
" Other desktops won't work, e.g. XFCE (send us the
\n
"
" corresponding commands if you find them). If x11vnc
\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
"
" comma separated list of WxH+X+Y type geometries for
\n
"
" each rectangle.
\n
"
...
...
@@ -15535,8 +16155,7 @@ static void print_help(int mode) {
" display (e.g. localhost:10).
\n
"
"
\n
"
" Examples:
\"
x11vnc -gui
\"
,
\"
x11vnc -gui localhost:10
\"
,
\n
"
"
\"
x11vnc -gui :10
\"
,
\"
x11vnc -gui wait,:10
\"
,
\n
"
"
\"
x11vnc -gui <x11vnc-opts...>
\"\n
"
"
\"
x11vnc -gui :10
\"
,
\"
x11vnc -gui conn,host:10
\"
,
\n
"
"
\n
"
" If you do not specify a gui X display in
\"
gui-opts
\"\n
"
" then the DISPLAY environment variable and -display
\n
"
...
...
@@ -15591,6 +16210,7 @@ static void print_help(int mode) {
"
\"
zero:x1,y1,x2,y2
\"
for a rectangle.
\n
"
" refresh send the entire fb to all clients.
\n
"
" reset recreate the fb, polling memory, etc.
\n
"
/* ext. cmd. */
" id:windowid set -id window to
\"
windowid
\"
. empty
\n
"
" or
\"
root
\"
to go back to root window
\n
"
" sid:windowid set -sid window to
\"
windowid
\"\n
"
...
...
@@ -15606,6 +16226,7 @@ static void print_help(int mode) {
" visual:vis set -visual to
\"
vis
\"\n
"
" scale:frac set -scale to
\"
frac
\"\n
"
" viewonly enable -viewonly mode.
\n
"
/* access view,share,forever */
" noviewonly disable -viewonly mode.
\n
"
" shared enable -shared mode.
\n
"
" noshared disable -shared mode.
\n
"
...
...
@@ -15616,6 +16237,7 @@ static void print_help(int mode) {
" connects in the next n secs.
\n
"
" deny deny any new connections, same as
\"
lock
\"\n
"
" nodeny allow new connections, same as
\"
unlock
\"\n
"
/* access, filename */
" connect:host do reverse connection to host,
\"
host
\"\n
"
" may be a comma separated list of hosts
\n
"
" or host:ports. See -connect.
\n
"
...
...
@@ -15625,8 +16247,10 @@ static void print_help(int mode) {
" If you know the client internal hex ID,
\n
"
" e.g. 0x3 (returned by -query clients and
\n
"
" RFB_CLIENT_ID), you can use that too.
\n
"
/* access */
" allowonce:host For the next connection only, allow
\n
"
" connection from
\"
host
\"
.
\n
"
/* access */
" allow:hostlist set -allow list to (comma separated)
\n
"
"
\"
hostlist
\"
. See -allow and -localhost.
\n
"
" Do not use with -allow /path/to/file
\n
"
...
...
@@ -15634,6 +16258,7 @@ static void print_help(int mode) {
" use
\"
-host
\"
to delete a single host
\n
"
" localhost enable -localhost mode
\n
"
" nolocalhost disable -localhost mode
\n
"
/* ext. cmd. */
" accept:cmd set -accept
\"
cmd
\"
(empty to disable).
\n
"
" gone:cmd set -gone
\"
cmd
\"
(empty to disable).
\n
"
" noshm enable -noshm mode.
\n
"
...
...
@@ -15644,6 +16269,7 @@ static void print_help(int mode) {
" onetile enable -onetile mode. (you may need to
\n
"
" set shm for this to do something)
\n
"
" noonetile disable -onetile mode.
\n
"
/* ext. cmd. */
" solid enable -solid mode
\n
"
" nosolid disable -solid mode.
\n
"
" solid_color:color set -solid color (and apply it).
\n
"
...
...
@@ -15674,6 +16300,7 @@ static void print_help(int mode) {
" noclear_mods disable -clear_mods mode.
\n
"
" clear_keys enable -clear_keys mode and clear them.
\n
"
" noclear_keys disable -clear_keys mode.
\n
"
/* filename */
" remap:str set -remap
\"
str
\"
(empty to disable).
\n
"
" See -remap for the form of
\"
str
\"\n
"
" (basically: key1-key2,key3-key4,...)
\n
"
...
...
@@ -15733,6 +16360,7 @@ static void print_help(int mode) {
" height parameter to n.
\n
"
" desktop:str set -desktop name to str for new clients.
\n
"
" rfbport:n set -rfbport to n.
\n
"
/* access */
" http enable http client connections.
\n
"
" nohttp disable http client connections.
\n
"
" httpport:n set -httpport to n.
\n
"
...
...
@@ -15817,7 +16445,7 @@ static void print_help(int mode) {
" nodontdisconnect desktop noremote
\n
"
"
\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
"
" scaling_pad scaling_interpolate inetd safer unsafe
\n
"
" passwdfile using_shm logfile o rc norc h help V version
\n
"
...
...
@@ -16097,17 +16725,22 @@ static void check_rcfile(int argc, char **argv) {
perror
(
"fopen"
);
exit
(
1
);
}
}
else
if
(
getenv
(
"HOME"
)
==
NULL
)
{
norc
=
1
;
}
else
{
strncpy
(
rcfile
,
getenv
(
"HOME"
),
500
);
strcat
(
rcfile
,
"/.x11vncrc"
);
infile
=
rcfile
;
rc
=
fopen
(
rcfile
,
"r"
);
if
(
rc
==
NULL
)
{
char
*
home
=
get_home_dir
();
if
(
!
home
)
{
norc
=
1
;
}
else
{
rc_rcfile
=
strdup
(
rcfile
);
strncpy
(
rcfile
,
home
,
500
);
free
(
home
);
strcat
(
rcfile
,
"/.x11vncrc"
);
infile
=
rcfile
;
rc
=
fopen
(
rcfile
,
"r"
);
if
(
rc
==
NULL
)
{
norc
=
1
;
}
else
{
rc_rcfile
=
strdup
(
rcfile
);
}
}
}
...
...
@@ -16161,12 +16794,7 @@ static void check_rcfile(int argc, char **argv) {
if
(
(
q
=
strchr
(
p
,
'#'
))
!=
NULL
)
{
*
q
=
'\0'
;
}
while
(
*
p
)
{
if
(
!
isspace
(
*
p
))
{
break
;
}
p
++
;
}
p
=
lblanks
(
p
);
strncat
(
buf
,
p
,
sz
-
strlen
(
buf
)
-
1
);
if
(
cont
)
{
...
...
@@ -16195,12 +16823,7 @@ static void check_rcfile(int argc, char **argv) {
p
=
buf
;
p
+=
strlen
(
parm
);
while
(
*
p
)
{
if
(
!
isspace
(
*
p
))
{
break
;
}
p
++
;
}
p
=
lblanks
(
p
);
if
(
*
p
==
'\0'
)
{
buf
[
0
]
=
'\0'
;
continue
;
...
...
@@ -16258,6 +16881,45 @@ int main(int argc, char* argv[]) {
/* if we are root limit some remote commands: */
if
(
!
getuid
()
||
!
geteuid
())
{
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
]);
...
...
@@ -16305,7 +16967,7 @@ int main(int argc, char* argv[]) {
if
(
!
strcmp
(
arg
,
"-display"
))
{
CHECK_ARGC
use_dpy
=
strdup
(
argv
[
++
i
]);
}
else
if
(
!
strcmp
(
arg
,
"-auth"
))
{
}
else
if
(
!
strcmp
(
arg
,
"-auth"
)
||
!
strcmp
(
arg
,
"-xauth"
)
)
{
CHECK_ARGC
auth_file
=
strdup
(
argv
[
++
i
]);
}
else
if
(
!
strcmp
(
arg
,
"-id"
)
||
!
strcmp
(
arg
,
"-sid"
))
{
...
...
@@ -16361,6 +17023,9 @@ int main(int argc, char* argv[]) {
}
else
if
(
!
strcmp
(
arg
,
"-timeout"
))
{
CHECK_ARGC
first_conn_timeout
=
atoi
(
argv
[
++
i
]);
}
else
if
(
!
strcmp
(
arg
,
"-users"
))
{
CHECK_ARGC
users_list
=
strdup
(
argv
[
++
i
]);
}
else
if
(
!
strcmp
(
arg
,
"-inetd"
))
{
inetd
=
1
;
}
else
if
(
!
strcmp
(
arg
,
"-connect"
))
{
...
...
@@ -16927,6 +17592,8 @@ int main(int argc, char* argv[]) {
:
"null"
);
fprintf
(
stderr
,
" gone: %s
\n
"
,
gone_cmd
?
gone_cmd
:
"null"
);
fprintf
(
stderr
,
" users: %s
\n
"
,
users_list
?
users_list
:
"null"
);
fprintf
(
stderr
,
" using_shm: %d
\n
"
,
using_shm
);
fprintf
(
stderr
,
" flipbytes: %d
\n
"
,
flip_byte_order
);
fprintf
(
stderr
,
" onetile: %d
\n
"
,
single_copytile
);
...
...
@@ -17162,7 +17829,8 @@ int main(int argc, char* argv[]) {
" cursor mode
\n
"
);
rfbLog
(
" to: '-cursor most'.
\n
"
);
rfbLog
(
" to disable this behavior use: "
"'-cursor arrow'.
\n
"
);
"'-cursor arrow'
\n
"
);
rfbLog
(
" or '-noxfixes'.
\n
"
);
}
}
if
(
!
strcmp
(
multiple_cursors_mode
,
"most"
))
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment