diff options
author | runge <runge> | 2008-09-07 04:17:33 +0000 |
---|---|---|
committer | runge <runge> | 2008-09-07 04:17:33 +0000 |
commit | d5cba7a574a667f5321194cb05d0b4adcb995866 (patch) | |
tree | 2748fd38612cc63256ee864284cd8dab19f4eba1 /x11vnc/misc/enhanced_tightvnc_viewer | |
parent | dbfa4ad1f78f6133bc5f50e766f7f3bfdb8fa049 (diff) | |
download | libtdevnc-d5cba7a574a667f5321194cb05d0b4adcb995866.tar.gz libtdevnc-d5cba7a574a667f5321194cb05d0b4adcb995866.zip |
x11vnc: kill gui_pid on exit in -connect/-connect_or_exit mode.
-grablocal n experiment (not compiled by default). -macuskbd
option for macosx for orig uskdb code. keycode=N remote contol
cmd. Find dpy look at non-NFS cookies in /tmp. Fix gui tray
insertion on recent gnome dt. Fix connect_file bug. Sync SSVNC
Diffstat (limited to 'x11vnc/misc/enhanced_tightvnc_viewer')
14 files changed, 4022 insertions, 1075 deletions
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/README b/x11vnc/misc/enhanced_tightvnc_viewer/README index 69f1d12..a6b138d 100644 --- a/x11vnc/misc/enhanced_tightvnc_viewer/README +++ b/x11vnc/misc/enhanced_tightvnc_viewer/README @@ -29,7 +29,7 @@ survey http://rechten.uvt.nl/koops/cryptolaw/index.htm for useful information. All work done by Karl J. Runge in this project is -Copyright (c) 2006-2007 Karl J. Runge and is licensed under the GPL as +Copyright (c) 2006-2008 Karl J. Runge and is licensed under the GPL as described in the file COPYING in this directory. All the files and information in this project are provided "AS IS" @@ -66,23 +66,30 @@ The enhanced TightVNC viewer features are: - Create or Import SSL Certificates and Private Keys. + - Reverse (viewer listening) VNC connections via SSL and SSH. + + - Support for Web Proxies, SOCKS Proxies, and the UltraVNC + repeater proxy (e.g. repeater://host:port+ID:1234). Multiple + proxies may be chained together (3 max). + + - Support for SSH Gateway connections and non-standard SSH ports. + + - You can also use your own VNC Viewer, e.g. UltraVNC or RealVNC, + with the front-end GUI or scripts if you like. + - Automatic Service tunnelling via SSH for CUPS and SMB Printing, ESD/ARTSD Audio, and SMB (Windows/Samba) filesystem mounting. + - Sets up any additional SSH port redirections that you want. + - Port Knocking for "closed port" SSH/SSL connections. In addition to a simple fixed port sequence and one-time-pad implementation, a hook is also provided to run any port knocking client before a connecting. - - You can also use your own VNC Viewer, e.g. UltraVNC or RealVNC, - with the front-end GUI or scripts if you like. - - - Sets up any additional SSH port redirections that you want. - - Support for native MacOS X usage with bundled Chicken of the - VNC viewer. - - - Reverse (viewer listening) VNC connections via SSL and SSH. + VNC viewer (the Unix X11 viewer is also provided for MacOS X, + and is better IMHO). - Dynamic VNC Server Port determination and redirection (using ssh's builtin SOCKS proxy, -D) for servers like x11vnc that @@ -116,6 +123,16 @@ The enhanced TightVNC viewer features are: (java must be in $PATH). Note that x11vnc supports UltraVNC file transfer. + - Connection support for the UltraVNC repeater proxy (-repeater + option). + + - Support for UltraVNC Single Click operation. (both unencrypted: + SC I, and SSL encrypted: SC III) + + - Instead of hostname:display one can also supply "exec=command args..." + to connect the viewer to the stdio of an external command + (e.g. stunnel or socat) rather than using a TCP/IP socket. + - Extremely low color modes: 64 and 8 colors in 8bpp (-use64/-bgr222, -use8/-bgr111) @@ -391,7 +408,7 @@ If you need to Build: If your OS/arch is not included or the provided binary has the wrong library dependencies, etc. the script "build.unix" may be able to successfully build on for you and deposit the binaries down in ./bin/... -using the included source code. +using the included source code. It is a hack but usually works. You MUST run the build.unix script from this directory (that this toplevel README is in, i.e "ssvnc") and like this: @@ -401,9 +418,30 @@ README is in, i.e "ssvnc") and like this: To use custom locations for libraries see the LDFLAGS_OS and CPPFLAGS_OS description at the top of the build.unix script. +You can set these env. vars to customize the build: + + SSVNC_BUILD_NO_STATIC=1 do not try to statically link libs + SSVNC_BUILD_FORCE_OVERWRITE=1 do not prompt about existing binaries + SSVNC_BUILD_SKIP_VIEWER=1 do not build vncviewer + SSVNC_BUILD_SKIP_STUNNEL=1 do not build stunnel + SSVNC_BUILD_ULTRAFTP=1 only build the file xfer helper jar + +here is an example to build only the vncviewer and with normal library +linking (and in a more or less automated way): + + env SSVNC_BUILD_NO_STATIC=1 SSVNC_BUILD_FORCE_OVERWRITE=1 SSVNC_BUILD_SKIP_STUNNEL=1 ./build.unix + Feel free to ask us if you need help running ./build.unix +Convential Build: + +A more conventional source tarball is provided in ssvnc-x.y.z.src.tar.gz. +It uses a more or less familiar 'make config; make all; make install' +method. It does not include stunnel, so that must be installed on the +system separately. + + The programs: ------------ @@ -519,6 +557,86 @@ as long as you install external vncviewer and stunnel packages: ssvnc_unix_minimal-1.x.y.tar.gz +Untrusted Local Users: +--------------------- + + *IMPORTANT WARNING*: If you run SSVNC on a workstation or computer + that other users can log into and you DO NOT TRUST these users + (it is a shame but sometimes one has to work in an environment like + this), then please note the following warning. + + By 'do not trust' we mean they might try to gain access to remote + machines you connect to via SSVNC. Note that an untrusted local + user can often obtain root access in a short amount of time; if a + user has acheived that, then all bets are off for ANYTHING that you + do on the workstation. It is best to get rid of Untrusted Local + Users as soon as possible. + + Both the SSL and SSH tunnels set up by SSVNC listen on certain ports + on the 'localhost' address and redirect TCP connections to the remote + machine; usually the VNC server running there (but it could also be + another service, e.g. CUPS printing). These are the stunnel(8) SSL + redirection and the ssh(1) '-L' port redirection. Because 'localhost' + is used only users or programs on the same workstation that is + running SSVNC can connect to these ports, however this includes any + local users (not just the user running SSVNC.) + + If the untrusted local user tries to connect to these ports, he may + succeed in varying degrees to gain access to the remote machine. + We now list some safeguards one can put in place to try to make this + more difficult to acheive. + + It probably pays to have the VNC server require a password, even + though there has already been SSL or SSH authentication (via + certificates or passwords). In general if the VNC Server requires + SSL authentication of the viewer that helps, unless the untrusted + local user has gained access to your SSVNC certificate keys. + + If the VNC server is configured to only allow one viewer connection + at a time, then the window of opportunity that the untrusted local + user can use is greatly reduced: he might only have a second or two + between the tunnel being set up and the SSVNC vncviewer connecting + to it (i.e. if the VNC server only allows a single connection, the + untrusted local user cannot connect once your session is established). + Similarly, when you disconnect the tunnel is torn down quickly and + there is little or no window of opportunity to connect (e.g. x11vnc + in its default mode exits after the first client disconnects). + + Also for SSL tunnelling with stunnel(8) on Unix using one of the SSVNC + prebuilt 'bundles', a patched stunnel is provided that denies all + connections after the first one, and exits when the first one closes. + This is not true if the system installed stunnel(8) is used and is + not true when using SSVNC on Windows. + + The following are two experimental features that are added to SSVNC + to improve the situation for the SSL/stunnel case. Set them via + Options -> Advanced -> "STUNNEL Local Port Protections". + + 1) For SSL tunnelling with stunnel(8) on Unix there is a setting + 'Use stunnel EXEC mode' (experimental) that will try to exec(2) + stunnel instead of using a listening socket. This will require + using the specially modified vncviewer unix viewer provided + by SSVNC. If this mode proves stable it will become the default. + + 2) For SSL tunnelling with stunnel(8) on Unix there is a setting + 'Use stunnel IDENT check' (experimental) to limit socket + connections to be from you (this assumes the untrusted local + user has not become root on your workstation and has modified + your local IDENT check service; if he has you have much bigger + problems to worry about...) + + There is also one simple LD_PRELOAD trick for SSH to limit the number + of accepted port redirection connections. This makes the window of + time the untrusted local user can connect to the tunnel much smaller. + Enable it via Options -> Advanced -> "SSH Local Port Protections". + You will need to have the lim_accept.so file in your SSVNC package. + + The main message is to 'Watch your Back' when you connect via the + SSVNC tunnels and there are users you don't trust on your workstation. + The same applies to ANY use of SSH '-L' port redirections or outgoing + stunnel SSL redirection services. + + Help and Info: ------------- diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/sshvnc.bat b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/sshvnc.bat new file mode 100644 index 0000000..9cd2d9e --- /dev/null +++ b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/sshvnc.bat @@ -0,0 +1 @@ +start ssvnc.exe -ssh %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/tsvnc.bat b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/tsvnc.bat new file mode 100644 index 0000000..1331d02 --- /dev/null +++ b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/tsvnc.bat @@ -0,0 +1 @@ +start ssvnc.exe -ts %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/sshvnc b/x11vnc/misc/enhanced_tightvnc_viewer/bin/sshvnc new file mode 100755 index 0000000..a427b42 --- /dev/null +++ b/x11vnc/misc/enhanced_tightvnc_viewer/bin/sshvnc @@ -0,0 +1,7 @@ +#!/bin/sh +# +# wrapper for SSH_ONLY mode +# +PATH=`dirname "$0"`:$PATH; export PATH +SSVNC_SSH_ONLY=1; export SSVNC_SSH_ONLY +exec ssvnc -ssh "$@" diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc b/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc index a9753ce..69dbf6b 100755 --- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc +++ b/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc @@ -79,7 +79,11 @@ nearby=0 if [ -x "$dir/vncviewer" -a -x "$dir/stunnel" ]; then nearby=1 fi -if [ ! -d "$dir/$name" -a $nearby = 0 ]; then +if [ "X$name" = "X." ]; then + : + #type vncviewer + #type stunnel +elif [ ! -d "$dir/$name" -a $nearby = 0 ]; then echo echo "Cannot find platform dir for your OS `uname -sm`:" echo diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd b/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd index 7f01a22..3d355d3 100755 --- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd +++ b/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2006 by Karl J. Runge <runge@karlrunge.com> +# Copyright (c) 2006-2008 by Karl J. Runge <runge@karlrunge.com> # # ssvnc_cmd: # @@ -23,9 +23,15 @@ # # Usage: # -# ssvnc_cmd [ss_vncviewer-args] hostname:N [tightvncviewer-args] +# ssvnc_cmd [ss_vncviewer-args] hostname:N [vncviewer-args] # -# "hostname:N" is the host and VNC display to connect to, e.g. snoopy:0 +# if, instead, this script is named "tightvncviewer" it calls the +# vncviewer directly and must be invoked as: +# +# tightvncviewer [vncviewer-args] hostname:N +# +# In both cases, "hostname:N" is the host and VNC display to connect to, +# e.g. snoopy:0 # # See the script util/ss_vncviewer for details about its arguments: # @@ -35,6 +41,8 @@ # -alpha # -grab # +# N.B. if this script is named "tightvncviewer" the vncviewer is called +# directly, and there won't be any SSL or SSH encryption tunnels. # # If the *very first* argument is "-cotvnc" then it is assumed you are on # Darwin and want to run the Chicken of the VNC viewer via our wrapper. @@ -75,9 +83,12 @@ # Option names may be abbreviated, e.g. -bgr instead of -bgr233. # See the manual page for more information. # +# Note: the enhanced tightvnc viewer (SSVNC) has many more options, run +# this script as "ssvnc_cmd Vnc://a:0 -help" or "tightvncviewer -help" +# to seem them. -if [ "X$1" = "X-h" -o "X$1" = "X-help" -o "X$1" = "X--help" ]; then - head -76 "$0" | grep -v bin/sh +if [ "X$1" = "X-h" -o "X$1" = "X-helpxxx" -o "X$1" = "X--help" ]; then + tail -n +2 "$0" | sed -e '/^$/ q' -e 's/^#//' exit fi @@ -145,12 +156,20 @@ do done dir=`dirname "$f"` PATH="$dir:$PATH" +SSVNC_BASEDIR="$dir" +export SSVNC_BASEDIR +SSVNC_UNAME="$name" +export SSVNC_UNAME nearby=0 if [ -x "$dir/vncviewer" -a -x "$dir/stunnel" ]; then nearby=1 fi -if [ ! -d "$dir/$name" -a $nearby = 0 ]; then +if [ "X$name" = "X." ]; then + : + #type vncviewer + #type stunnel +elif [ ! -d "$dir/$name" -a $nearby = 0 ]; then echo echo "Cannot find platform dir for your OS `uname -sm`:" echo @@ -223,6 +242,9 @@ fi # # if [ $use_ours = 1 ]; then + # avoid system vncviewer app-defaults + #XFILESEARCHPATH="/tmp/path/nowhere"; export XFILESEARCHPATH + if [ "X$base" = "Xtightvncviewer" ]; then $VNCVIEWERCMD -encodings 'copyrect tight zrle zlib hextile' "$@" else diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/tsvnc b/x11vnc/misc/enhanced_tightvnc_viewer/bin/tsvnc new file mode 100755 index 0000000..acf55c6 --- /dev/null +++ b/x11vnc/misc/enhanced_tightvnc_viewer/bin/tsvnc @@ -0,0 +1,7 @@ +#!/bin/sh +# +# wrapper for TS_ONLY mode +# +PATH=`dirname "$0"`:$PATH; export PATH +SSVNC_TS_ONLY=1; export SSVNC_TS_ONLY +exec ssvnc -ts "$@" diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer b/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer index 6becd63..d12f5ce 100755 --- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer +++ b/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer @@ -447,6 +447,9 @@ findfree() { # removes files, etc. final() { echo "" + if [ "X$tmp_cfg" != "X" ]; then + rm -f $tmp_cfg + fi if [ "X$SS_VNCVIEWER_RM" != "X" ]; then rm -f $SS_VNCVIEWER_RM 2>/dev/null fi @@ -1012,6 +1015,24 @@ if [ "X$use_ssh" = "X1" ]; then # let user override ssh via $SSH ssh=${SSH:-"ssh -x"} + if [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" ]; then + SSVNC_LIM_ACCEPT_PRELOAD="$SSVNC_BASEDIR/$SSVNC_UNAME/$SSVNC_LIM_ACCEPT_PRELOAD" + fi + if [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" ]; then + echo "" + echo "SSVNC_LIM_ACCEPT_PRELOAD=$SSVNC_LIM_ACCEPT_PRELOAD" + fi + + if [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" -a -f "$SSVNC_LIM_ACCEPT_PRELOAD" ]; then + plvar=LD_PRELOAD + if uname | grep Darwin >/dev/null; then + plvar="DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES" + fi + ssh="env $plvar=$SSVNC_LIM_ACCEPT_PRELOAD $ssh" + else + SSVNC_LIM_ACCEPT_PRELOAD="" + fi + if echo "$proxy" | egrep '(http|https|socks|socks4|socks5)://' > /dev/null; then # Handle Web or SOCKS proxy(ies) for the initial connect. Kecho host=$host @@ -1328,10 +1349,11 @@ Kecho proxy=$proxy c=0 pssh="" + mssh=`echo "$ssh" | sed -e 's/^env.*ssh/ssh/'` while [ $c -lt 30 ] do p=`expr $pmark + $c` - if ps -p "$p" 2>&1 | grep "$ssh" > /dev/null; then + if ps -p "$p" 2>&1 | grep "$mssh" > /dev/null; then pssh=$p break fi @@ -1339,6 +1361,8 @@ Kecho proxy=$proxy done if [ "X$getport" != "X" ]; then : + elif [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" ] ; then + sleep 2 elif [ "X$ssh_cmd" = "Xsleep $ssh_sleep" ] ; then #echo T sleep 1 sleep 1 @@ -1523,9 +1547,11 @@ if [ "X$direct_connect" != "X" ]; then exit $? fi -tmp=/tmp/ss_vncviewer${RANDOM}.$$ -mytmp "$tmp" +tmp_cfg=/tmp/ss_vncviewer${RANDOM}.$$ +mytmp "$tmp_cfg" +# make_tcert is no longer invoked via the ssvnc gui (Listen mode). +# make_tcert is for testing only now via -mycert BUILTIN make_tcert() { tcert="/tmp/tcert${RANDOM}.$$" cat > $tcert <<END @@ -1584,37 +1610,50 @@ END echo "$tcert" } +stunnel_exec="" +if echo $STUNNEL_EXTRA_SVC_OPTS | grep '#stunnel-exec' > /dev/null; then + stunnel_exec="#" +fi + if [ "X$reverse" = "X" ]; then if echo "$proxy" | grep repeater:// > /dev/null; then - if [ "X$cert" = "X" ]; then + if [ "X$cert" = "XBUILTIN" ]; then ttcert=`make_tcert` cert="cert = $ttcert" fi + # Note for listen mode, an empty cert will cause stunnel to fail. + # The ssvnc gui will have already taken care of this. fi - cat > "$tmp" <<END + cat > "$tmp_cfg" <<END foreground = yes pid = client = yes debug = 6 $STUNNEL_EXTRA_OPTS +$STUNNEL_EXTRA_OPTS_USER $verify $cert -[vnc_stunnel] -accept = localhost:$use +${stunnel_exec}[vnc_stunnel] +${stunnel_exec}accept = localhost:$use $connect +$STUNNEL_EXTRA_SVC_OPTS +$STUNNEL_EXTRA_SVC_OPTS_USER END else + stunnel_exec="" # doesn't work for listening. p2=`expr 5500 + $N` connect="connect = localhost:$p2" - if [ "X$cert" = "X" ]; then + if [ "X$cert" = "XBUILTIN" ]; then ttcert=`make_tcert` cert="cert = $ttcert" fi + # Note for listen mode, an empty cert will cause stunnel to fail. + # The ssvnc gui will have already taken care of this. STUNNEL_EXTRA_OPTS=`echo "$STUNNEL_EXTRA_OPTS" | sed -e 's/maxconn/#maxconn/'` @@ -1622,18 +1661,21 @@ else if [ "X$use_ssh" = "X1" ]; then hloc="localhost:" fi - cat > "$tmp" <<END + cat > "$tmp_cfg" <<END foreground = yes pid = client = no debug = 6 $STUNNEL_EXTRA_OPTS +$STUNNEL_EXTRA_OPTS_USER $verify $cert [vnc_stunnel] accept = $hloc$port $connect +$STUNNEL_EXTRA_SVC_OPTS +$STUNNEL_EXTRA_SVC_OPTS_USER END fi @@ -1641,31 +1683,33 @@ fi echo "" echo "Using this stunnel configuration:" echo "" -cat "$tmp" | uniq +cat "$tmp_cfg" | uniq echo "" sleep 1 -echo "" -echo "Running stunnel:" -echo "$STUNNEL $tmp" -st=`echo "$STUNNEL" | awk '{print $1}'` -$st -help > /dev/null 2>&1 -$STUNNEL "$tmp" < /dev/tty > /dev/tty & -stunnel_pid=$! -echo "" - -# pause here to let the user supply a possible passphrase for the -# mycert key: -if [ "X$mycert" != "X" ]; then - sleep 1 +if [ "X$stunnel_exec" = "X" ]; then echo "" - echo "(pausing for possible certificate passphrase dialog)" + echo "Running stunnel:" + echo "$STUNNEL $tmp_cfg" + st=`echo "$STUNNEL" | awk '{print $1}'` + $st -help > /dev/null 2>&1 + $STUNNEL "$tmp_cfg" < /dev/tty > /dev/tty & + stunnel_pid=$! echo "" - sleep 4 + + # pause here to let the user supply a possible passphrase for the + # mycert key: + if [ "X$mycert" != "X" ]; then + sleep 1 + echo "" + echo "(pausing for possible certificate passphrase dialog)" + echo "" + sleep 4 + fi + #echo T sleep 1 + sleep 1 + rm -f "$tmp_cfg" fi -#echo T sleep 1 -sleep 1 -rm -f "$tmp" echo "" @@ -1675,15 +1719,19 @@ if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then fi echo "Running viewer:" if [ "X$reverse" = "X" ]; then - echo "$VNCVIEWERCMD" "$@" localhost:$N + vnc_hp=localhost:$N + if [ "X$stunnel_exec" != "X" ]; then + vnc_hp="exec=$STUNNEL $tmp_cfg" + fi + echo "$VNCVIEWERCMD" "$@" "$vnc_hp" trap "final" 0 2 15 echo "" - $VNCVIEWERCMD "$@" localhost:$N + $VNCVIEWERCMD "$@" "$vnc_hp" if [ $? != 0 ]; then echo "vncviewer command failed: $?" if [ "X$secondtry" = "X1" ]; then sleep 2 - $VNCVIEWERCMD "$@" localhost:$N + $VNCVIEWERCMD "$@" "$vnc_hp" fi fi else diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl b/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl index d99763e..3e296c6 100755 --- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl +++ b/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl @@ -3,7 +3,7 @@ exec wish "$0" "$@" # -# Copyright (c) 2006-2007 by Karl J. Runge <runge@karlrunge.com> +# Copyright (c) 2006-2008 by Karl J. Runge <runge@karlrunge.com> # # ssvnc.tcl: gui wrapper to the programs in this # package. Also sets up service port forwarding. @@ -382,8 +382,8 @@ proc help {} { SSL Certificate Verification: - *IMPORTANT*: If you do not take the steps to VERIFY the VNC Server's SSL - Certificate, you are theoretically vulnerable to a Man-In-The-Middle + ***IMPORTANT***: If you do not take the steps to VERIFY the VNC Server's + SSL Certificate, you are in principle vulnerable to a Man-In-The-Middle attack. Without SSL Certificate verification, only passive network sniffing attacks will be guaranteed to be prevented. @@ -400,7 +400,8 @@ proc help {} { However, "Fetch Cert" and "Verify All Certs" are currently disabled in the rare "SSH + SSL" usage mode (e.g. SSH is used to enter a firewall gateway, and then SSL is tunneled through that to reach - the workstation). + the workstation). You are always free to use a "ServerCert" (under + "Certs...") to authenticate SSL Servers against. Windows STUNNEL: @@ -414,7 +415,7 @@ proc help {} { its Log file (useful for debugging connections). SSVNC will kill the STUNNEL process for you, but you may still need - to move the mouse over the icon to make it go away. + to move the mouse over the icon to make the picture go away! In some cases you may need to terminate STUNNEL manually from the System Tray (right click on dark green icon) and selecting "Exit". @@ -422,13 +423,14 @@ proc help {} { VNC Password: - On Unix or MacOSX if there is a VNC password for the server you + On Unix or MacOSX IF there is a VNC password for the server you can enter it in the "VNC Password:" entry box. This is *REQUIRED* on MacOSX when Chicken of the VNC is used. - On Unix if you choose not to enter the password you will be prompted - for it in the terminal window running TightVNC viewer if one is required. + On Unix (including MacOSX using the X11 viewer) if you choose not + to enter the password you will simply be prompted for it in the + terminal window running TightVNC viewer if one is required. On Windows TightVNC viewer should prompt you when a password is required. @@ -436,6 +438,85 @@ proc help {} { need to enter it each time). + Untrusted Local Users: + + *IMPORTANT WARNING*: If you run SSVNC on a workstation or computer + that other users can log into and you DO NOT TRUST these users + (it is a shame but sometimes one has to work in an environment like + this), then please note the following warning. + + By 'do not trust' we mean they might try to gain access to remote + machines you connect to via SSVNC. Note that an untrusted local + user can often obtain root access in a short amount of time; if a + user has acheived that, then all bets are off for ANYTHING that you + do on the workstation. It is best to get rid of Untrusted Local + Users as soon as possible. + + Both the SSL and SSH tunnels set up by SSVNC listen on certain ports + on the 'localhost' address and redirect TCP connections to the remote + machine; usually the VNC server running there (but it could also be + another service, e.g. CUPS printing). These are the stunnel(8) SSL + redirection and the ssh(1) '-L' port redirection. Because 'localhost' + is used only users or programs on the same workstation that is + running SSVNC can connect to these ports, however this includes any + local users (not just the user running SSVNC.) + + If the untrusted local user tries to connect to these ports, he may + succeed in varying degrees to gain access to the remote machine. + We now list some safeguards one can put in place to try to make this + more difficult to acheive. + + It probably pays to have the VNC server require a password, even + though there has already been SSL or SSH authentication (via + certificates or passwords). In general if the VNC Server requires + SSL authentication of the viewer that helps, unless the untrusted + local user has gained access to your SSVNC certificate keys. + + If the VNC server is configured to only allow one viewer connection + at a time, then the window of opportunity that the untrusted local + user can use is greatly reduced: he might only have a second or two + between the tunnel being set up and the SSVNC vncviewer connecting + to it (i.e. if the VNC server only allows a single connection, the + untrusted local user cannot connect once your session is established). + Similarly, when you disconnect the tunnel is torn down quickly and + there is little or no window of opportunity to connect (e.g. x11vnc + in its default mode exits after the first client disconnects). + + Also for SSL tunnelling with stunnel(8) on Unix using one of the SSVNC + prebuilt 'bundles', a patched stunnel is provided that denies all + connections after the first one, and exits when the first one closes. + This is not true if the system installed stunnel(8) is used and is + not true when using SSVNC on Windows. + + The following are two experimental features that are added to SSVNC + to improve the situation for the SSL/stunnel case. Set them via + Options -> Advanced -> "STUNNEL Local Port Protections". + + 1) For SSL tunnelling with stunnel(8) on Unix there is a setting + 'Use stunnel EXEC mode' (experimental) that will try to exec(2) + stunnel instead of using a listening socket. This will require + using the specially modified vncviewer unix viewer provided + by SSVNC. If this mode proves stable it will become the default. + + 2) For SSL tunnelling with stunnel(8) on Unix there is a setting + 'Use stunnel IDENT check' (experimental) to limit socket + connections to be from you (this assumes the untrusted local + user has not become root on your workstation and has modified + your local IDENT check service; if he has you have much bigger + problems to worry about...) + + There is also one simple LD_PRELOAD trick for SSH to limit the number + of accepted port redirection connections. This makes the window of + time the untrusted local user can connect to the tunnel much smaller. + Enable it via Options -> Advanced -> "SSH Local Port Protections". + You will need to have the lim_accept.so file in your SSVNC package. + + The main message is to 'Watch your Back' when you connect via the + SSVNC tunnels and there are users you don't trust on your workstation. + The same applies to ANY use of SSH '-L' port redirections or outgoing + stunnel SSL redirection services. + + SSH: Click on "Use SSH" if you want to use an *SSH* tunnel instead of SSL @@ -479,7 +560,7 @@ proc help {} { VNC Host:Display username@somehost.com:2 Remote SSH Command: x11vnc -find -rfbport 5902 -nopw - See the the Tip below (11) for using x11vnc PORT=NNNN feature (or + See the Tip below (11) for using x11vnc PORT=NNNN feature (or vncserver(1) output) to not need to specify the VNC display number or the x11vnc -rfbport option. @@ -665,6 +746,9 @@ proc help {} { the VNC server acts as a SSL *client* and so requires the Viewer end to have an SSL cert, etc. + Note that in Listening mode you must supply a MyCert or use the + "listen.pem" one you are prompted to create. + Set REPEATER_FORCE=1 in the Host:Display (hit Enter, and then clear it) to force SSVNC to try to a forward connection in this situation. @@ -694,6 +778,48 @@ proc help {} { x11vnc -ssl SAVE + UltraVNC Single Click: + + UltraVNC has Single Click (SC) Windows VNC servers that allow naive + users to get them running very easily (a EXE download and a few + mouse clicks). See http://sc.uvnc.com/ for details on how to create + these binaries. + + One important point for SC III binary creation: do NOT include + "-id N" in the helpdesk.txt config file. This is because the Ultra + VNC repeater is not used. Use something like: + + [HOST] + Internet Support XYZ + -sslproxy -connect xx.xx.xx.xx:5500 -noregistry + + + The Unix SSVNC vncviewer supports the both the unencrypted "SC I" + mode and the SSL encrypted "SC III" mode. For both cases SSVNC + must be run in Listening mode (Options -> Reverse VNC Connection) + + For SC I, enable Reverse VNC Connection and put Vnc://0 in the + VNC Host:Display (use a different number if you are not using + the default listening port 5500). Then click on the "Listen" + button and finally have the user run your Single Click I EXE. + + For SC III, enable Reverse VNC Connection and then UNSET "Verify + All Certs" (this is required). Let the VNC Host:Display be ":0" + (use a different number if you are not using the default listening + port 5500). Then click on the "Listen" button and finally have the + user run your Single Click III EXE. + + For SC III, you will also need to enable the setting in the + Options menu "UltraVNC Single Click III Bug", otherwise the + STUNNEL connection may drop after 2-15 minutes. + + Note that in Listening mode you MUST supply a MyCert or use the + "listen.pem" one you are prompted to create. + + Single Click II using the UltraVNC repeater should also work, but + has not been tested. + + SSL Certificates: If you want to use a SSL Certificate (PEM) file to authenticate @@ -766,7 +892,7 @@ proc help {} { A ShortCut for this is Ctrl-S as long as user@hostname is present in the entry box. - 3) If you use "KNOCK" for the "Remote SSH Command" (or int he display + 3) If you use "KNOCK" for the "Remote SSH Command" (or in the display line "user@hostname cmd=KNOCK") then only the port-knocking is performed. @@ -796,7 +922,7 @@ proc help {} { info. 7) On Unix to have SSVNC act as a general STUNNEL redirector (i.e. no - VNC), put the the desired host:port in VNC Host:Display (use a + VNC), put the desired host:port in VNC Host:Display (use a negative port value if it is to be less than 200), then go to Options -> Advanced -> Change VNC Viewer. Change the "viewer" command to be "xmessage OK" or "xmessage <port>" (or sleep) where @@ -885,7 +1011,7 @@ proc help {} { before starting the viewer. The env. var. SSVNC_EXTRA_SLEEP also does this (and also Sleep: Option setting) On Mac, you can set DYLD_LIBRARY_PATH=... too. It should propagate down - the the viewer. + the viewer. 13) If you want this application to be SSH only, then supply the command line option "-ssh" or set the env. var SSVNC_SSH_ONLY=1. @@ -970,9 +1096,9 @@ proc help_certs {} { set msg { Description: - *IMPORTANT*: Only with SSL Certificate verification (either manually or via a - Certificate Authority certificate) can Man-In-The-Middle attacks be prevented. - Otherwise, only passive network sniffing attacks are prevented. + ***IMPORTANT***: Only with SSL Certificate verification (either manually or + via a Certificate Authority certificate) can Man-In-The-Middle attacks be + prevented. Otherwise, only passive network sniffing attacks are prevented. The SSL Certificate files described below may have been created externally (e.g. by x11vnc or openssl): you can import them via "Import Certificate". @@ -984,6 +1110,13 @@ proc help_certs {} { box description below, and then Connect. You will usually want to Save this association in a VNC Server profile for the next time you connect. + Expiration: + + SSL Certificates will Expire after a certain period (usually 1-2 years; + if you create a cert with this tool you can set it to any length you want). + So if for a particular Cert you find you can no longer connect, check the + STUNNEL log output to see if the cert has expired. Then create a new one. + Fetch Cert: You can also retrieve and view the VNC Server's Cert via the "Fetch Cert" @@ -1081,7 +1214,17 @@ proc help_certs {} { This is because of the way OpenSSL must use hash-based filenames in Cert dirs. The file will have a "full filename:" line indicating the fingerprint and - hostname associated with it. Be sure to remove both files. + hostname associated with it. Be sure to remove both files. The Delete Certs + dialog should automatically find the matching one for you and prompt you to + remove it as well. + + + Deleting Certificates: + + To delete a Certificate+private_key pair click on "Delete Certificate" + and select one in the menu. You will be prompted to remove it, + and also any corresponding .pem or .crt file. For "ACCEPTED_CERTS" + it will find the matching "HASH" file and prompt you to remove that too. Notes: @@ -1273,7 +1416,7 @@ set msg { x11vnc has an experiment Client-Side caching scheme "-ncache n" that can give nice speedups. But there are some drawbacks - because the the cache-region is visible and uses much RAM. + because the cache-region is visible and uses much RAM. http://www.karlrunge.com/x11vnc/#faq-client-caching X11VNC Options: @@ -1550,11 +1693,24 @@ set msg { Then a VNC server should establish a reverse connection to that port on this machine (e.g. -connect this-machine:5500) - SSL certificates will be verified, however you won't be - prompted about unrecognized ones; rather, you must set - up the correct Server certificate (e.g. by importing). + Server SSL certificates will be verified, however you WILL + NOTE be prompted about unrecognized ones; rather, you MUST + set up the correct Server certificate (e.g. by importing). prior to any connections. + If the connection is failing in Reverse VNC (listening) mode, + check the STUNNEL log output to see if STUNNEL is unable to + authenticate the VNC Server. If you want to allow in a + reverse connection with NO Server authentication, unset the + 'Verify All Certs' option. + + When listening in SSL, you will ALSO need to specify YOUR + OWN SSL cert, "MyCert", or otherwise let the GUI prompt you + to create a "listen.pem" and use that. + + The "listen.pem" will be reused in later SSL Listening + connections unless you specify a different one with MyCert. + For reverse connections in SSH or SSH + SSL modes it is a little trickier. The SSH tunnel (with -R tunnel) must be established and remain up waiting for reverse connections. @@ -1590,6 +1746,32 @@ set msg { unless it is a double proxy where the 2nd host is the machine with the VNC server. + UltraVNC Single Click III Bug: + + The UltraVNC Single Click III (SSL) server works with SSVNC; + it makes a reverse connection to it via an SSL tunnel: + + http://www.uvnc.com/pchelpware/SCIII/index.html + + Unfortunately the SSL implementation used by UltraVNC SC III + is incompatible with OpenSSL in that the connection will be + dropped after 2-15 minutes due to an unexpected packet. + + However this can be worked around in STUNNEL by setting + configution item 'options = ALL'. Enabling 'UltraVNC Single + Click III Bug' passes this setting to STUNNEL. + + On Windows 'options = ALL' is used by default for stunnel. + On Unix and MacOSX you will need to select this option. + + Setting this option may provide a workaround for other SSL + VNC servers. + + BTW, you can set the environment variable STUNNEL_EXTRA_OPTS_USER + to add any lines to the STUNNEL global config that you want to. + See the stunnel(8) man page for more details. + + View Only: Have VNC Viewer ignore mouse and keyboard input. @@ -2041,16 +2223,19 @@ proc set_defaults {} { global choose_ncache ts_ncache choose_multisession ts_multisession global ts_mode ts_desktop_size ts_desktop_depth choose_desktop_geom global additional_port_redirs additional_port_redirs_list + global stunnel_local_protection stunnel_local_protection_type ssh_local_protection multiple_listen global sound_daemon_remote_cmd sound_daemon_remote_port sound_daemon_kill sound_daemon_restart global sound_daemon_local_cmd sound_daemon_local_port sound_daemon_local_kill sound_daemon_x11vnc sound_daemon_local_start global smb_su_mode smb_mount_list global use_port_knocking port_knocking_list global ycrop_string extra_sleep use_listen use_unixpw use_x11vnc_find unixpw_username + global use_uvnc_ssl_bug global include_list set defs(use_viewonly) 0 set defs(use_listen) 0 + set defs(use_uvnc_ssl_bug) 0 set defs(use_unixpw) 0 set defs(unixpw_username) "" set defs(use_x11vnc_find) 0 @@ -2107,6 +2292,11 @@ proc set_defaults {} { set defs(additional_port_redirs) 0 set defs(additional_port_redirs_list) "" + set defs(stunnel_local_protection) 0 + set defs(stunnel_local_protection_type) "none" + set defs(ssh_local_protection) 0 + set defs(multiple_listen) 0 + set defs(cups_local_server) "" set defs(cups_remote_port) "" set defs(cups_local_smb_server) "" @@ -2168,7 +2358,7 @@ proc do_viewer_windows {n} { global use_alpha use_grab use_ssh use_sshssl use_viewonly use_fullscreen use_bgr233 global use_nojpeg use_raise_on_beep use_compresslevel use_quality global change_vncviewer change_vncviewer_path vncviewer_realvnc4 - global use_listen env + global use_listen use_uvnc_ssl_bug env set cmd "vncviewer" if {$change_vncviewer && $change_vncviewer_path != ""} { @@ -2297,7 +2487,8 @@ proc do_viewer_windows {n} { } } else { if [regexp {^[0-9][0-9]*$} $n] { - append cmd " localhost:$n" + global win_localhost + append cmd " $win_localhost:$n" } else { append cmd " $n" } @@ -2358,6 +2549,21 @@ proc get_ipconfig {} { return $ip } +proc read_file {file} { + set str "" + if [file exists $file] { + set fh "" + catch {set fh [open $file "r"]} + if {$fh != ""} { + while {[gets $fh line] > -1} { + append str "$line\n" + } + close $fh + } + } + return $str +} + proc guess_nat_ip {} { global save_nat last_save_nat set s "" @@ -2465,8 +2671,22 @@ proc windows_start_sound_daemon {file} { after 1500 } -proc windows_stop_sound_daemon {} { +proc winkill {pid} { global is_win9x + + if {$pid == ""} { + return + } + if {! $is_win9x} { + catch {exec tskill.exe $pid} + after 100 + catch {exec taskkill.exe /PID $pid} + after 100 + } + catch {exec w98/kill.exe /f $pid} +} + +proc windows_stop_sound_daemon {} { global use_sound sound_daemon_local_cmd sound_daemon_local_start set cmd [string trim $sound_daemon_local_cmd] @@ -2492,11 +2712,7 @@ proc windows_stop_sound_daemon {} { set count 0 foreach pid [array names pids] { mesg "Stopping SOUND pid: $pid" - if {$is_win9x} { - catch {exec w98/kill.exe /f $pid} - } else { - catch {exec tskill.exe $pid} - } + winkill $pid if {$count == 0} { after 1200 } else { @@ -2578,7 +2794,7 @@ proc launch_windows_ssh {hp file n} { global is_win9x env global use_sshssl use_ssh putty_pw global port_knocking_list - global use_listen listening_name + global use_listen use_uvnc_ssl_bug listening_name global ts_only global debug_netstat @@ -2586,7 +2802,9 @@ proc launch_windows_ssh {hp file n} { set proxy [get_ssh_proxy $hp] set sshcmd [get_ssh_cmd $hp] - set vnc_host "localhost" + global win_localhost + + set vnc_host $win_localhost set vnc_disp $hpnew regsub {^.*:} $vnc_disp "" vnc_disp @@ -2595,13 +2813,13 @@ proc launch_windows_ssh {hp file n} { if {$proxy == ""} { if {[regexp {^([^:]*):([0-9][0-9]*)$} $hpnew mv sshhst sshpt]} { set proxy "$sshhst:$sshpt" - set hpnew "localhost" + set hpnew $win_localhost } } else { if {![regexp {,} $proxy]} { - if {$hpnew != "localhost"} { + if {$hpnew != $win_localhost} { set proxy "$proxy,$hpnew" - set hpnew "localhost" + set hpnew $win_localhost } } } @@ -2718,12 +2936,12 @@ proc launch_windows_ssh {hp file n} { unset -nocomplain env(SSVNC_DEST) if {$sproxy1 == ""} { - set proxy "localhost:$port2" + set proxy "$win_localhost:$port2" if [regexp {^(.*)@} $ssh_host mv u] { set proxy "$u@$proxy" } } else { - set proxy "${sproxy1_user}localhost:$port2" + set proxy "${sproxy1_user}$win_localhost:$port2" } if {$sproxy_rest != ""} { set proxy "$proxy,$sproxy_rest" @@ -2767,7 +2985,7 @@ proc launch_windows_ssh {hp file n} { } set double_ssh "-L $p_port:$ssh_host2:$ssh_port2 -P $ssh_port1 $u1$ssh_host1" - set proxy_use "${u2}localhost:$p_port" + set proxy_use "${u2}$win_localhost:$p_port" } else { # user1@gateway:port1 @@ -2785,7 +3003,7 @@ proc launch_windows_ssh {hp file n} { set vnc_host $hpnew regsub {:.*$} $vnc_host "" vnc_host if {$vnc_host == ""} { - set vnc_host "localhost" + set vnc_host $win_localhost } } @@ -2985,7 +3203,7 @@ proc launch_windows_ssh {hp file n} { } if {$vnc_host == ""} { - set vnc_host "localhost" + set vnc_host $win_localhost } regsub {^.*@} $vnc_host "" vnc_host @@ -3460,15 +3678,15 @@ proc unix_terminal_cmd {{geometry "+100+100"} {title "xterm-command"} {cmd "echo } if {$bg} { if {$xrm1 == ""} { - exec xterm -geometry "$geometry" -title "$title" -e sh -c "$cmd" 2>@stdout & + exec xterm -sb -sl 2000 -geometry "$geometry" -title "$title" -e sh -c "$cmd" 2>@stdout & } else { - exec xterm -geometry "$geometry" -title "$title" -xrm "$xrm1" -xrm "$xrm2" -xrm "$xrm3" -e sh -c "$cmd" 2>@stdout & + exec xterm -sb -sl 2000 -geometry "$geometry" -title "$title" -xrm "$xrm1" -xrm "$xrm2" -xrm "$xrm3" -e sh -c "$cmd" 2>@stdout & } } else { if {$xrm1 == ""} { - exec xterm -geometry "$geometry" -title "$title" -e sh -c "$cmd" 2>@stdout + exec xterm -sb -sl 2000 -geometry "$geometry" -title "$title" -e sh -c "$cmd" 2>@stdout } else { - exec xterm -geometry "$geometry" -title "$title" -xrm "$xrm1" -xrm "$xrm2" -xrm "$xrm3" -e sh -c "$cmd" 2>@stdout + exec xterm -sb -sl 2000 -geometry "$geometry" -title "$title" -xrm "$xrm1" -xrm "$xrm2" -xrm "$xrm3" -e sh -c "$cmd" 2>@stdout } } } @@ -3848,9 +4066,11 @@ proc fetch_cert_windows {hp} { set list [split $hpnew ":"] + global win_localhost + set host [lindex $list 0] if {$host == ""} { - set host "localhost" + set host $win_localhost } if [regexp {^.*@} $host match] { @@ -3897,7 +4117,7 @@ proc fetch_cert_windows {hp} { set env(SSVNC_LISTEN) $port2 set env(SSVNC_DEST) "$host:$port" - set host localhost + set host $win_localhost set port $port2 mesg "Starting TCP helper on port $port2 ..." after 600 @@ -3956,14 +4176,7 @@ proc fetch_cert_windows {hp} { } } foreach pid $pids { - global is_win9x - if {$pid == ""} { - ; - } elseif {$is_win9x} { - catch {exec w98/kill.exe /f $pid} - } else { - catch {exec tskill.exe $pid} - } + winkill $pid } catch {close $ph} catch {file delete $tin $tou} @@ -4001,15 +4214,8 @@ if {1} { break } } - global is_win9x foreach pid $pids { - if {$pid == ""} { - ; - } elseif {$is_win9x} { - catch {exec w98/kill.exe /f $pid} - } else { - catch {exec tskill.exe $pid} - } + winkill $pid } after 500 set ph "" @@ -4183,14 +4389,15 @@ proc check_accepted_certs {} { sent to you by the server administrator). - Should this certificate be saved in the accepted certs directory and - then used to SSL authenticate VNC servers? + Do you want this certificate to be saved in the accepted certs directory + and then used to SSL authenticate VNC servers? By clicking 'Inspect and maybe Save Cert' you will be given the opportunity to inspect the certificate before deciding to save it or not. - Choose 'Ignore Cert for One Connection' to connect one time to the - server and not require ANY certificate verification. + Choose 'Ignore Cert for One Connection' to connect a single time to the + server with NO certificate verification. You will see this dialog again + the next time you connect to the same server. " if {$oth == 0} { @@ -4450,6 +4657,59 @@ proc init_unixpw {hp} { } } +proc check_for_listen_ssl_cert {} { + global mycert use_listen use_ssh + if {! $use_listen} { + return 1 + } + if {$use_ssh} { + return 1 + } + if {$mycert != ""} { + return 1 + } + + set name [get_idir_certs ""] + set name "$name/listen.pem" + if {[file exists $name]} { + set mycert $name + mesg "Using Listen Cert: $name" + after 1000 + return 1 + } + + set title "SSL Listen requires MyCert"; + set msg "In SSL Listen mode a cert+key is required, but you have not specified 'MyCert'.\n\nCreate a cert+key 'listen' now?" + set reply [tk_messageBox -type okcancel -icon warning -message $msg -title $msg] + if {$reply == "cancel"} { + return 0 + } + create_cert $name + tkwait window .ccrt + if {[file exists $name]} { + set mycert $name + mesg "Using Listen Cert: $name" + after 1000 + return 1 + } + return 0 +} + +proc reset_stunnel_extra_opts {} { + global stunnel_extra_opts0 stunnel_extra_svc_opts0 env + global ssvnc_multiple_listen0 + if {$stunnel_extra_opts0 != "none"} { + set env(STUNNEL_EXTRA_OPTS) $stunnel_extra_opts0 + } + if {$stunnel_extra_svc_opts0 != "none"} { + set env(STUNNEL_EXTRA_SVC_OPTS) $stunnel_extra_svc_opts0 + } + set env(SSVNC_LIM_ACCEPT_PRELOAD) "" + if {$ssvnc_multiple_listen0 != "none"} { + set env(SSVNC_MULTIPLE_LISTEN) $ssvnc_multiple_listen0 + } +} + proc launch_unix {hp} { global smb_redir_0 smb_mounts env global vncauth_passwd use_unixpw unixpw_username unixpw_passwd @@ -4493,6 +4753,69 @@ proc launch_unix {hp} { } } + if {! $do_direct} { + if {! [check_for_listen_ssl_cert]} { + return + } + } + + global stunnel_extra_opts0 stunnel_extra_svc_opts0 + set stunnel_extra_opts0 "" + set stunnel_extra_svc_opts0 "" + global ssvnc_multiple_listen0 + set ssvnc_multiple_listen0 "" + + if {$use_uvnc_ssl_bug && ! $use_ssh} { + if [info exists env(STUNNEL_EXTRA_OPTS)] { + set stunnel_extra_opts0 $env(STUNNEL_EXTRA_OPTS) + set env(STUNNEL_EXTRA_OPTS) "$env(STUNNEL_EXTRA_OPTS)\noptions = ALL" + } else { + set env(STUNNEL_EXTRA_OPTS) "options = ALL" + } + } + if {$stunnel_local_protection && ! $use_listen} { + if {$stunnel_local_protection_type == "ident"} { + set user "" + if {[info exists env(USER)]} { + set user $env(USER) + } elseif {[info exists env(LOGNAME)]} { + set user $env(USER) + } + if {$user != ""} { + if [info exists env(STUNNEL_EXTRA_SVC_OPTS)] { + set stunnel_extra_svc_opts0 $env(STUNNEL_EXTRA_SVC_OPTS) + set env(STUNNEL_EXTRA_SVC_OPTS) "$env(STUNNEL_EXTRA_SVC_OPTS)\nident = $user" + } else { + set env(STUNNEL_EXTRA_SVC_OPTS) "ident = $user" + } + } + } elseif {$stunnel_local_protection_type == "exec"} { + if [info exists env(STUNNEL_EXTRA_SVC_OPTS)] { + set stunnel_extra_svc_opts0 $env(STUNNEL_EXTRA_SVC_OPTS) + set env(STUNNEL_EXTRA_SVC_OPTS) "$env(STUNNEL_EXTRA_SVC_OPTS)\n#stunnel-exec" + } else { + set env(STUNNEL_EXTRA_SVC_OPTS) "#stunnel-exec" + } + } + } + if {$ssh_local_protection} { + if {![info exists env(LIM_ACCEPT)]} { + set env(LIM_ACCEPT) 1 + } + if {![info exists env(LIM_ACCEPT_TIME)]} { + set env(LIM_ACCEPT_TIME) 15 + } + set env(SSVNC_LIM_ACCEPT_PRELOAD) "lim_accept.so" + mesg "SSH LIM_ACCEPT($env(LIM_ACCEPT),$env(LIM_ACCEPT_TIME)): lim_accept.so" + after 1000 + } + if {$multiple_listen && $use_listen} { + if [info exists env(SSVNC_MULTIPLE_LISTEN)] { + set ssvnc_multiple_listen0 $env(SSVNC_MULTIPLE_LISTEN) + } + set env(SSVNC_MULTIPLE_LISTEN) "1" + } + if {$use_ssh || $use_sshssl} { if {$skip_ssh} { set cmd "ss_vncviewer" @@ -4512,6 +4835,9 @@ proc launch_unix {hp} { if {$use_listen} { set cmd "$cmd -listen" } + if {$ssh_local_protection} { + regsub {ss_vncviewer} $cmd "ssvnc_cmd" cmd + } set hpnew [get_ssh_hp $hp] set proxy [get_ssh_proxy $hp] set sshcmd [get_ssh_cmd $hp] @@ -4653,6 +4979,7 @@ proc launch_unix {hp} { } if {! $did_port_knock} { if {! [do_port_knock $pk_hp start]} { + reset_stunnel_extra_opts return } set did_port_knock 1 @@ -4671,6 +4998,7 @@ proc launch_unix {hp} { set env(SS_VNCVIEWER_SSH_CMD) "" set env(SS_VNCVIEWER_SSH_ONLY) "" set env(SS_VNCVIEWER_USE_C) "" + reset_stunnel_extra_opts return } } else { @@ -4679,6 +5007,7 @@ proc launch_unix {hp} { set proxy [get_ssh_proxy $hp] if {! [repeater_proxy_check $proxy]} { + reset_stunnel_extra_opts return } @@ -4693,6 +5022,7 @@ proc launch_unix {hp} { global skip_verify_accepted_certs set skip_verify_accepted_certs 0 if {! [check_accepted_certs]} { + reset_stunnel_extra_opts return } if {! $skip_verify_accepted_certs} { @@ -4763,6 +5093,7 @@ proc launch_unix {hp} { catch {destroy .c} mesg "file still exists: $tmp" bell + reset_stunnel_extra_opts return } catch {set fh [open $tmp "w"]} @@ -4771,6 +5102,7 @@ proc launch_unix {hp} { catch {destroy .c} mesg "cannot create: $tmp" bell + reset_stunnel_extra_opts return } puts $fh "#!/bin/sh" @@ -4953,6 +5285,7 @@ proc launch_unix {hp} { if {! [do_port_knock $pk_hp start]} { wm deiconify . update + reset_stunnel_extra_opts return } set did_port_knock 1 @@ -5034,20 +5367,16 @@ proc launch_unix {hp} { do_port_knock $pk_hp finish } + reset_stunnel_extra_opts + fini_unixpw } proc kill_stunnel {pids} { - global is_win9x - set count 0 foreach pid $pids { mesg "killing STUNNEL pid: $pid" - if {$is_win9x} { - catch {exec w98/kill.exe /f $pid} - } else { - catch {exec tskill.exe $pid} - } + winkill $pid if {$count == 0} { after 1200 } else { @@ -5259,7 +5588,7 @@ proc launch {{hp ""}} { global mycert svcert crtdir global pids_before pids_after pids_new global env - global use_ssl use_ssh use_sshssl use_listen + global use_ssl use_ssh use_sshssl use_listen use_uvnc_ssl_bug global vncdisplay set debug 0 @@ -5553,9 +5882,11 @@ proc launch {{hp ""}} { set list [split $hp ":"] + global win_localhost + set host [lindex $list 0] if {$host == ""} { - set host "localhost" + set host $win_localhost } if [regexp {^.*@} $host match] { @@ -5594,7 +5925,7 @@ proc launch {{hp ""}} { after 2000 } if {$use_listen} { - set env(SSVNC_REVERSE) "localhost:$port" + set env(SSVNC_REVERSE) "$win_localhost:$port" } else { set env(SSVNC_LISTEN) [expr "$n2 + 5900"] } @@ -5607,6 +5938,12 @@ proc launch {{hp ""}} { after 1000 } + if {$use_listen && $mycert == ""} { + if {! [check_for_listen_ssl_cert]} { + return; + } + } + set fail 0 set fh [open $file "w"] @@ -5616,7 +5953,11 @@ proc launch {{hp ""}} { } else { puts $fh "client = yes" } + # WRT, UltraVNC Single Click III Bug: + # Wow, on Windows we've been using 'options = ALL' + # all along! Duh. OK keep it... puts $fh "options = ALL" + puts $fh "taskbar = yes" puts $fh "RNDbytes = 2048" puts $fh "RNDfile = bananarand.bin" @@ -5631,12 +5972,10 @@ proc launch {{hp ""}} { } puts $fh "cert = $mycert" } elseif {$use_listen} { - set dummy "dummy.pem" - set dh [open $dummy "w"] - puts $dh [dummy_cert] - close $dh - puts $fh "cert = $dummy" + # see above, this should not happen. + puts $fh "cert = _nocert_" } + if {$svcert != ""} { if {! [file exists $svcert]} { mesg "ServerCert does not exist: $svcert" @@ -5680,11 +6019,11 @@ proc launch {{hp ""}} { set port2 "" if {! $use_listen} { set port2 [expr "$n + 5900"] - puts $fh "accept = localhost:$port2" + puts $fh "accept = $win_localhost:$port2" if {$use_sshssl || $proxy != ""} { set port [expr "$n2 + 5900"] - puts $fh "connect = localhost:$port" + puts $fh "connect = $win_localhost:$port" } else { puts $fh "connect = $host:$port" } @@ -5692,8 +6031,8 @@ proc launch {{hp ""}} { set port2 [expr "$n + 5500"] set hloc "" if {$use_ssh} { - set hloc "localhost:" - set listening_name "localhost:$port (on remote SSH side)" + set hloc "$win_localhost:" + set listening_name "$win_localhost:$port (on remote SSH side)" } else { set hn [get_hostname] if {$hn == ""} { @@ -5702,7 +6041,7 @@ proc launch {{hp ""}} { set listening_name "$hn:$port (or nn.nn.nn.nn:$port, etc.)" } puts $fh "accept = $hloc$port" - puts $fh "connect = localhost:$port2" + puts $fh "connect = $win_localhost:$port2" } puts $fh "delay = no" @@ -5805,9 +6144,11 @@ proc direct_connect_windows {{hp ""}} { set list [split $hp ":"] + global win_localhost + set host [lindex $list 0] if {$host == ""} { - set host "localhost" + set host $win_localhost } if [regexp {^.*@} $host match] { @@ -5852,7 +6193,7 @@ proc direct_connect_windows {{hp ""}} { set env(SSVNC_DEST) "$host:$port" set port [expr $n2 + 5900] - set host "localhost" + set host $win_localhost } set fail 0 @@ -5974,6 +6315,60 @@ proc get_idir_certs {str} { return $idir } +proc delete_cert {{parent "."}} { + set idir [get_idir_certs ""] + set f "" + unix_dialog_resize $parent + if {$idir != ""} { + set f [tk_getOpenFile -parent $parent -initialdir $idir] + } else { + set f [tk_getOpenFile -parent $parent] + } + if {$f != "" && [file exists $f]} { + set reply [tk_messageBox -parent $parent -type yesno -icon question -title "Delete Cert" -message "Delete $f"] + if {$reply == "yes"} { + global mycert svcert + set f_text [read_file $f] + set f2 "" + catch {file delete $f} + if {$f == $mycert} { set mycert "" } + if {$f == $svcert} { set svcert "" } + if [regexp {\.crt$} $f] { + regsub {\.crt$} $f ".pem" f2 + } elseif [regexp {\.pem$} $f] { + regsub {\.pem$} $f ".crt" f2 + } + if {$f2 != "" && [file exists $f2]} { + set reply [tk_messageBox -parent $parent -type yesno -icon question -title "Delete Cert" -message "Delete $f2"] + if {$reply == "yes"} { + catch {file delete $f2} + if {$f2 == $mycert} { set mycert "" } + if {$f2 == $svcert} { set svcert "" } + } + } + set dir [file dirname $f] + if {$f_text != "" && [regexp {accepted$} $dir]} { + foreach crt [glob -nocomplain -directory $dir {*.crt} {*.pem} {*.[0-9]}] { + #puts "try $crt" + set c_text [read_file $crt] + if {$c_text == ""} { + continue + } + if {$c_text != $f_text} { + continue + } + set reply [tk_messageBox -parent $parent -type yesno -icon question -title "Delete Identical Cert" -message "Delete Identical $crt"] + if {$reply == "yes"} { + catch {file delete $crt} + } + } + } + } + } + catch {wm deiconify .c} + update +} + proc set_mycert {{parent "."}} { global mycert set idir [get_idir_certs $mycert] @@ -5989,10 +6384,9 @@ proc set_mycert {{parent "."}} { } catch {wm deiconify .c} v_mycert - update + update } - proc show_cert {crt} { if {$crt == ""} { bell @@ -6445,7 +6839,7 @@ emailAddress_max = 64 } } -proc create_cert {} { +proc create_cert {{name ""}} { toplev .ccrt wm title .ccrt "Create SSL Certificate" @@ -6545,7 +6939,7 @@ proc create_cert {} { set ccert(OUN) "Product Development" set ccert(CN) "www.nowhere.none" set ccert(EM) "admin@nowhere.none" - set ccert(DAYS) "365" + set ccert(DAYS) "730" set ccert(FILE) "" } @@ -6561,8 +6955,14 @@ proc create_cert {} { set tcert(EM) "Email Address:" set tcert(DAYS) "Days until expiration:" - if {$ccert(FILE) == ""} { - set idir [get_idir_certs ""] + set idir [get_idir_certs ""] + if {$name != ""} { + if {[regexp {/} $name] || [regexp {\.pem$} $name] || [regexp {\.crt$} $name]} { + set ccert(FILE) $name + } else { + set ccert(FILE) "$idir/$name.pem" + } + } elseif {$ccert(FILE) == ""} { set ccert(FILE) "$idir/vnccert.pem" } @@ -6594,6 +6994,9 @@ proc create_cert {} { entry $w.e -width $ew -textvariable ccert(FILE) button $w.b -text "Browse..." -command {set_createcert_file; catch {raise .ccrt}} + if {$name != ""} { + $w.b configure -state disabled + } pack $w.e -side right pack $w.b -side right @@ -7129,6 +7532,7 @@ proc getcerts {} { button .c.create -text "Create Certificate ..." -command {create_cert} button .c.import -text "Import Certificate ..." -command {import_cert} + button .c.delete -text "Delete Certificate ..." -command {delete_cert} frame .c.b button .c.b.done -text "Done" -command {catch {destroy .c}} @@ -7156,7 +7560,7 @@ proc getcerts {} { v_svcert } - pack .c.mycert .c.svcert .c.crtdir .c.create .c.import .c.b -side top -fill x + pack .c.mycert .c.svcert .c.crtdir .c.create .c.import .c.delete .c.b -side top -fill x center_win .c wm resizable .c 1 0 @@ -7531,62 +7935,6 @@ proc sync_use_ssl_ssh {} { } } -proc dummy_cert {} { - set str { ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAvkfXxb0wcxgrjV2ziFikjII+ze8iKcTBt47L0GM/c21efelN -+zZpJUUXLu4zz8Ryq8Q+sQgfNy7uTOpN9bUUaOk1TnD7gaDQnQWiNHmqbW2kL+DS -OKngJVPo9dETAS8hf7+D1e1DBZxjTc1a4RQqWJixwpYj99ixWzu8VC2m/xXsjvOs -jp4+DLBB490nbkwvstmhmiWm1CmI5O5xOkgioVNQqHvQMdVKOSz9PpbjvZiRX1Uo -qoMrk+2NOqwP90TB35yPASXb9zXKpO7DLhkube+yYGf+yk46aD707L07Eb7cosFP -S84vNZ9gX7rQ0UOwm5rYA/oZTBskgaqhtIzkLwIDAQABAoIBAD4ot/sXt5kRn0Ca -CIkU9AQWlC+v28grR2EQW9JiaZrqcoDNUzUqbCTJsi4ZkIFh2lf0TsqELbZYNW6Y -6AjJM7al4E0UqYSKJTv2WCuuRxdiRs2BMwthqyBmjeanev7bB6V0ybt7u3Y8xU/o -MrTuYnr4vrEjXPKdLirwk7AoDbKsRXHSIiHEIBOq1+dUQ32t36ukdnnza4wKDLZc -PKHiCdCk/wOGhuDlxD6RspqUAlRnJ8/aEhrgWxadFXw1hRhRsf/v1shtB0T3DmTe -Jchjwyiw9mryb9JZAcKxW+fUc4EVvj6VdQGqYInQJY5Yxm5JAlVQUJicuuJEvn6A -rj5osQECgYEA552CaHpUiFlB4HGkjaH00kL+f0+gRF4PANCPk6X3UPDVYzKnzmuu -yDvIdEETGFWBwoztUrOOKqVvPEQ+kBa2+DWWYaERZLtg2cI5byfDJxQ3ldzilS3J -1S3WgCojqcsG/hlxoQJ1dZFanUy/QhUZ0B+wlC+Zp1Q8AyuGQvhHp68CgYEA0lBI -eqq2GGCdJuNHMPFbi8Q0BnX55LW5C1hWjhuYiEkb3hOaIJuJrqvayBlhcQa2cGqp -uP34e9UCfoeLgmoCQ0b4KpL2NGov/mL4i8bMgog4hcoYuIi3qxN18vVR14VKEh4U -RLk0igAYPU+IK2QByaQlBo9OSaKkcfm7U1/pK4ECgYAxr6VpGk0GDvfF2Tsusv6d -GIgV8ZP09qSLTTJvvxvF/lQYeqZq7sjI5aJD5i3de4JhpO/IXQJzfZfWOuGc8XKA -3qYK/Y2IqXXGYRcHFGWV/Y1LFd55mCADHlk0l1WdOBOg8P5iRu/Br9PbiLpCx9oI -vrOXpnp03eod1/luZmqguwKBgQCWFRSj9Q7ddpSvG6HCG3ro0qsNsUMTI1tZ7UBX -SPogx4tLf1GN03D9ZUZLZVFUByZKMtPLX/Hi7K9K/A9ikaPrvsl6GEX6QYzeTGJx -3Pw0amFrmDzr8ySewNR6/PXahxPEuhJcuI31rPufRRI3ZLah3rFNbRbBFX+klkJH -zTnoAQKBgDbUK/aQFGduSy7WUT7LlM3UlGxJ2sA90TQh4JRQwzur0ACN5GdYZkqM -YBts4sBJVwwJoxD9OpbvKu3uKCt41BSj0/KyoBzjT44S2io2tj1syujtlVUsyyBy -/ca0A7WBB8lD1D7QMIhYUm2O9kYtSCLlUTHt5leqGaRG38DqlX36 ------END RSA PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIIDzDCCArQCCQDSzxzxqhyqLzANBgkqhkiG9w0BAQQFADCBpzELMAkGA1UEBhMC -VVMxFjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxDzANBgNVBAcTBkJvc3RvbjETMBEG -A1UEChMKTXkgQ29tcGFueTEcMBoGA1UECxMTUHJvZHVjdCBEZXZlbG9wbWVudDEZ -MBcGA1UEAxMQd3d3Lm5vd2hlcmUubm9uZTEhMB8GCSqGSIb3DQEJARYSYWRtaW5A -bm93aGVyZS5ub25lMB4XDTA3MDMyMzE4MDc0NVoXDTI2MDUyMjE4MDc0NVowgacx -CzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNldHRzMQ8wDQYDVQQHEwZC -b3N0b24xEzARBgNVBAoTCk15IENvbXBhbnkxHDAaBgNVBAsTE1Byb2R1Y3QgRGV2 -ZWxvcG1lbnQxGTAXBgNVBAMTEHd3dy5ub3doZXJlLm5vbmUxITAfBgkqhkiG9w0B -CQEWEmFkbWluQG5vd2hlcmUubm9uZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBAL5H18W9MHMYK41ds4hYpIyCPs3vIinEwbeOy9BjP3NtXn3pTfs2aSVF -Fy7uM8/EcqvEPrEIHzcu7kzqTfW1FGjpNU5w+4Gg0J0FojR5qm1tpC/g0jip4CVT -6PXREwEvIX+/g9XtQwWcY03NWuEUKliYscKWI/fYsVs7vFQtpv8V7I7zrI6ePgyw -QePdJ25ML7LZoZolptQpiOTucTpIIqFTUKh70DHVSjks/T6W472YkV9VKKqDK5Pt -jTqsD/dEwd+cjwEl2/c1yqTuwy4ZLm3vsmBn/spOOmg+9Oy9OxG+3KLBT0vOLzWf -YF+60NFDsJua2AP6GUwbJIGqobSM5C8CAwEAATANBgkqhkiG9w0BAQQFAAOCAQEA -vGomHEp6TVU83X2EBUgnbOhzKJ9u3fOI/Uf5L7p//Vxqow7OR1cguzh/YEzmXOIL -ilMVnzX9nj/bvcLAuqEP7MR1A8f4+E807p/L/Sf49BiCcwQq5I966sGKYXjkve+T -2GTBNwMSq+5kLSf6QY8VZI+qnrAudEQMeJByQhTZZ0dH8Njeq8EGl9KUio+VWaiW -CQK6xJuAvAHqa06OjLmwu1fYD4GLGSrOIiRVkSXV8qLIUmzxdJaIRznkFWsrCEKR -wAH966SAOvd2s6yOHMvyDRIL7WHxfESB6rDHsdIW/yny1fBePjv473KrxyXtbz7I -dMw1yW09l+eEo4A7GzwOdw== ------END CERTIFICATE----- -} - return $str -} - proc save_profile {{parent "."}} { global is_windows uname global profdone @@ -7824,7 +8172,13 @@ proc get_sound_redir {} { if {$uname == "Darwin"} { set loc "127.0.0.1:$loc" } else { - set loc "localhost:$loc" + global is_windows + if {$is_windows} { + global win_localhost + set loc "$win_localhost:$loc" + } else { + set loc "localhost:$loc" + } } } set redir "$sound_daemon_remote_port:$loc" @@ -7899,7 +8253,11 @@ proc get_smb_redir {} { set lport 139 } } else { - set lhost localhost + global is_windows win_localhost + set lhost "localhost" + if {$is_windows} { + set lhost $win_localhost + } set lport 139 } } @@ -10172,13 +10530,26 @@ proc help_advanced_opts {} { server and through that mount SMB file shares from your local server. The remote machine must be Linux with smbmount installed. - Change vncviewer: specify a non-bundled VNC Viewer (e.g. - UltraVNC or RealVNC) to run instead of the bundled TightVNC Viewer. - - Extra Redirs: specify additional -L port:host:port and + Additional Port Redirs: specify additional -L port:host:port and -R port:host:port cmdline options for SSH to enable additional services. + SSH Local Port Protections: and LD_PRELOAD hack to limit the + number of SSH port redirections to 1 and within the first + 15 seconds. So there is a smaller window when the user can try + to use your tunnel compared to the duration of your session. + + STUNNEL Local Port Protections: Try to prevent Untrusted Local + Users (see the main Help panel) from using your STUNNEL tunnel + to connect to the remote VNC Server. + + Multiple LISTEN Connections: allow multiple VNC servers to + reverse connect at the same time and so display each of their + desktops on your screen at the same time. + + Change VNC Viewer: specify a non-bundled VNC Viewer (e.g. + UltraVNC or RealVNC) to run instead of the bundled TightVNC Viewer. + Port Knocking: for "closed port" services, first "knock" on the firewall ports in a certain way to open the door for SSH or SSL. The port can also be closed when the encrypted VNC connection @@ -10387,6 +10758,184 @@ proc port_redir_dialog {} { focus .redirs.path.e } +proc stunnel_sec_dialog {} { + global stunnel_local_protection + + toplev .stlsec + wm title .stlsec "STUNNEL Local Port Protections" + + global help_font uname + if {$uname == "Darwin"} { + scroll_text .stlsec.f 82 36 + } else { + scroll_text .stlsec.f 82 36 + } + + apply_bg .stlsec.f + + set msg { + See the discussion of "Untrusted Local Users" in the main 'Help' + panel for info about users who are able to log into the workstation + you run SSVNC on and might try to use your encrypted tunnel to gain + access to the remote VNC machine. + + For STUNNEL SSL tunnels (not SSH tunnels) we provide two options as extra + safeguards against untrusted local users. Both only apply to Unix/MacOSX. + Note that Both options are ignored in reverse connection (Listen) mode. + + 1) The first one 'Use stunnel EXEC mode' (it is mutually exclusive with + option 2). For this case the modified SSVNC Unix viewer must be + used: it execs the stunnel program instead of connecting to it via + TCP/IP. Thus there is no localhost listening port involved at all. + + This is the best solution for SSL stunnel tunnels, but is currently + experimental. If it works well it will become the default mechanism. + + 2) The second one 'Use stunnel IDENT check', uses the stunnel(8) + 'ident = username' to use the local identd daemon (IDENT RFC 1413 + http://www.ietf.org/rfc/rfc1413.txt) to check that the locally + connecting program (the SSVNC vncviewer) is being run by your userid. + See the stunnel(8) man page for details. + + Normally the IDENT check service cannot be trusted much when used + *remotely* (the remote host may be have installed a modified daemon). + However when using the IDENT check service *locally* it should be + reliable. If not, it means the local machine (where you run SSVNC) + has already been root compromised and you have a serious problem. + + Enabling 'Use stunnel IDENT check' requires a working identd on the + local machine. Often it is not installed or enabled (because it is not + deemed to be useful, etc). identd is usually run out of the inetd(8) + super-server. Even when installed and running it is often configured + incorrectly. On a Debian/lenny system we actually found that the + kernel module 'tcp_diag' needed to be loaded! ('modprobe tcp_diag') +} + .stlsec.f.t insert end $msg + + radiobutton .stlsec.ident -relief ridge -anchor w -variable stunnel_local_protection_type -value "ident" -text "Use stunnel IDENT check" + radiobutton .stlsec.exec -relief ridge -anchor w -variable stunnel_local_protection_type -value "exec" -text "Use stunnel EXEC mode" + + button .stlsec.cancel -text "Cancel" -command {set stunnel_local_protection 0; destroy .stlsec} + bind .stlsec <Escape> {set stunnel_local_protection 0; destroy .stlsec} + wm protocol .stlsec WM_DELETE_WINDOW {set stunnel_local_protection 0; destroy .stlsec} + button .stlsec.done -text "Done" -command {if {$stunnel_local_protection_type == "none"} {set stunnel_local_protection 0}; destroy .stlsec} + + pack .stlsec.f .stlsec.exec .stlsec.ident .stlsec.cancel .stlsec.done -side top -fill x + + center_win .stlsec + wm resizable .stlsec 1 0 +} + +proc ssh_sec_dialog {} { + global ssh_local_protection + + toplev .sshsec + wm title .sshsec "SSH Local Port Protections" + + global help_font + eval text .sshsec.t -width 80 -height 28 $help_font + + apply_bg .sshsec.t + + set msg { + See the discussion of "Untrusted Local Users" in the main 'Help' + panel for info about users who are able to log into the workstation + you run SSVNC on and might try to use your encrypted tunnel to gain + access to the remote VNC machine. + + For SSH tunnels we have an LD_PRELOAD hack (lim_accept.so) that + will limit ssh from accepting any local redirection connections + after the first one or after 15 seconds, whichever comes first. + The first SSH port redirection connection is intended to be the + one that tunnels your VNC Viewer to reach the remote server. + + You can adjust these defaults LIM_ACCEPT=1 LIM_ACCEPT_TIME=15 by + setting those env. vars. to different values. + + Note that there is still a window of a few seconds the Untrusted + Local User can try to connect before your VNC Viewer does. So this + method is far from perfect. But once your VNC session is established, + he should be blocked out. Test to make sure blocking is taking place. + + Do not use this option if you are doing SSH Service redirections + 'Additional Port Redirections' that redirect a local port to the + remote server via ssh -L. + + Note that if the shared object "lim_accept.so" cannot be found, + this option has no effect. Watch the output in the terminal for + the "SSVNC_LIM_ACCEPT_PRELOAD" setting. +} + .sshsec.t insert end $msg + + button .sshsec.cancel -text "Cancel" -command {set ssh_local_protection 0; destroy .sshsec} + bind .sshsec <Escape> {set ssh_local_protection 0; destroy .sshsec} + wm protocol .sshsec WM_DELETE_WINDOW {set ssh_local_protection 0; destroy .sshsec} + button .sshsec.done -text "Done" -command {destroy .sshsec} + + pack .sshsec.t .sshsec.cancel .sshsec.done -side top -fill x + + center_win .sshsec + wm resizable .sshsec 1 0 +} + +proc multilisten_dialog {} { + global multiple_listen + + toplev .multil + wm title .multil "Multiple LISTEN Connections" + + global help_font + eval text .multil.t -width 84 -height 33 $help_font + + apply_bg .multil.t + + set msg { + Set this option to allow SSVNC (when in LISTEN / Reverse connections + mode) to allow multiple VNC servers to connect at the same time and + so display each of their desktops on your screen at the same time. + + This option only applies on Unix or MaOSX when using the supplied + SSVNC vncviewer. If you specify your own VNC Viewer it has no effect. + + On Windows (only the stock TightVNC viewer is provided) it has no + effect. On MacOSX if the COTVNC viewer is used it has no effect. + + It only applies to LISTEN mode, not for forward connections. + + Rationale: To play it safe, the Unix vncviewer provided by SSVNC + (ssvncviewer) only allows one LISTEN reverse connection at a time. + This is to prohibit malicious people on the network from depositing + as many desktops on your screen as he likes, even if you are already + connected to VNC server you desire. + + For example, perhaps the malicious user could trick you into typing + a password into the desktop he displays on your screen. + + This protection is not perfect, because the malicious user could + try to reverse connect to you before the correct VNC server reverse + connects to you. This is even more of a problem if you keep your + SSVNC viewer in LISTEN mode but unconnected for long periods of time. + Pay careful attention in this case if you are to supplying sensitive + information to the remote desktop. + + Enable 'Multiple LISTEN Connections' if you want to disable the default + protection in the Unix SSVNC vncviewer; i.e. allow multiple reverse + connections simultaneously (all vnc viewers we know of do this by default) +} + .multil.t insert end $msg + + button .multil.cancel -text "Cancel" -command {set multiple_listen 0; destroy .multil} + bind .multil <Escape> {set multiple_listen 0; destroy .multil} + wm protocol .multil WM_DELETE_WINDOW {set multiple_listen 0; destroy .multil} + button .multil.done -text "Done" -command {destroy .multil} + + pack .multil.t .multil.cancel .multil.done -side top -fill x + + center_win .multil + wm resizable .multil 1 0 +} + + proc find_netcat {} { global is_windows @@ -11296,6 +11845,8 @@ proc set_advanced_options {} { global change_vncviewer global use_port_knocking port_knocking_list global is_windows darwin_cotvnc + global use_ssh use_sshssl + global adv_ssh catch {destroy .o} toplev .oa @@ -11306,29 +11857,65 @@ proc set_advanced_options {} { checkbutton .oa.b$i -anchor w -variable use_cups -text \ "Enable CUPS Print tunnelling" \ -command {if {$use_cups} {cups_dialog}} + if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled} + set adv_ssh(cups) .oa.b$i incr i checkbutton .oa.b$i -anchor w -variable use_sound -text \ "Enable ESD/ARTSD Audio tunnelling" \ -command {if {$use_sound} {sound_dialog}} + if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled} + set adv_ssh(snd) .oa.b$i incr i checkbutton .oa.b$i -anchor w -variable use_smbmnt -text \ "Enable SMB mount tunnelling" \ -command {if {$use_smbmnt} {smb_dialog}} + if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled} + set adv_ssh(smb) .oa.b$i + incr i + + checkbutton .oa.b$i -anchor w -variable additional_port_redirs -text \ + "Additional Port Redirs" \ + -command {if {$additional_port_redirs} {port_redir_dialog}} + if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled} + set adv_ssh(redirs) .oa.b$i incr i + global use_ssl use_ssh use_sshssl + + checkbutton .oa.b$i -anchor w -variable ssh_local_protection -text \ + "SSH Local Port Protections" \ + -command {if {$ssh_local_protection} {ssh_sec_dialog}} + global ssh_local_protection_button + set ssh_local_protection_button .oa.b$i + if {$use_ssl} {.oa.b$i configure -state disabled} + if {$is_windows} {.oa.b$i configure -state disabled} + incr i + + checkbutton .oa.b$i -anchor w -variable stunnel_local_protection -text \ + "STUNNEL Local Port Protections" \ + -command {if {$stunnel_local_protection} {stunnel_sec_dialog}} + global stunnel_local_protection_button + set stunnel_local_protection_button .oa.b$i + if {$use_ssh} {.oa.b$i configure -state disabled} + if {$is_windows} {.oa.b$i configure -state disabled} + incr i + + checkbutton .oa.b$i -anchor w -variable multiple_listen -text \ + "Multiple LISTEN Connections" \ + -command {if {$multiple_listen} {multilisten_dialog}} + global multiple_listen_button use_listen + set multiple_listen_button .oa.b$i + if {$is_windows} {.oa.b$i configure -state disabled} + if {!$use_listen} {.oa.b$i configure -state disabled} + incr i checkbutton .oa.b$i -anchor w -variable change_vncviewer -text \ "Change VNC Viewer" \ -command {if {$change_vncviewer} {change_vncviewer_dialog}} incr i - checkbutton .oa.b$i -anchor w -variable additional_port_redirs -text \ - "Additional Port Redirs" \ - -command {if {$additional_port_redirs} {port_redir_dialog}} - incr i - checkbutton .oa.b$i -anchor w -variable use_port_knocking -text \ "Port Knocking" \ -command {if {$use_port_knocking} {port_knocking_dialog}} @@ -11518,11 +12105,45 @@ proc putty_pw_entry {mode} { catch {.o.pw.e configure -state normal} } } +proc adv_ssh_tog {on} { + global adv_ssh + foreach b {cups snd smb redirs} { + if [info exists adv_ssh($b)] { + if {$on} { + catch {$adv_ssh($b) configure -state normal} + } else { + catch {$adv_ssh($b) configure -state disabled} + } + } + } +} + +proc adv_listen_ssl_tog {on} { + global stunnel_local_protection_button + if [info exists stunnel_local_protection_button] { + if {$on} { + catch {$stunnel_local_protection_button configure -state normal} + } else { + catch {$stunnel_local_protection_button configure -state disabled} + } + } +} + +proc adv_listen_ssh_tog {on} { + global ssh_local_protection_button + if [info exists ssh_local_protection_button] { + if {$on} { + catch {$ssh_local_protection_button configure -state normal} + } else { + catch {$ssh_local_protection_button configure -state disabled} + } + } +} proc ssl_ssh_adjust {which} { global use_ssl use_ssh use_sshssl sshssl_sw global remote_ssh_cmd_list - global x11vnc_find_widget x11vnc_xlogin_widget + global x11vnc_find_widget x11vnc_xlogin_widget uvnc_bug_widget if {$which == "ssl"} { set use_ssl 1 @@ -11537,6 +12158,12 @@ proc ssl_ssh_adjust {which} { if [info exists x11vnc_xlogin_widget] { catch {$x11vnc_xlogin_widget configure -state disabled} } + if [info exists uvnc_bug_widget] { + catch {$uvnc_bug_widget configure -state normal} + } + adv_ssh_tog 0 + adv_listen_ssl_tog 1 + adv_listen_ssh_tog 0 } elseif {$which == "ssh"} { set use_ssl 0 set use_ssh 1 @@ -11550,6 +12177,12 @@ proc ssl_ssh_adjust {which} { if [info exists x11vnc_xlogin_widget] { catch {$x11vnc_xlogin_widget configure -state normal} } + if [info exists uvnc_bug_widget] { + catch {$uvnc_bug_widget configure -state disabled} + } + adv_ssh_tog 1 + adv_listen_ssl_tog 0 + adv_listen_ssh_tog 1 } elseif {$which == "sshssl"} { set use_ssl 0 set use_ssh 0 @@ -11563,6 +12196,12 @@ proc ssl_ssh_adjust {which} { if [info exists x11vnc_xlogin_widget] { catch {$x11vnc_xlogin_widget configure -state normal} } + if [info exists uvnc_bug_widget] { + catch {$uvnc_bug_widget configure -state normal} + } + adv_ssh_tog 1 + adv_listen_ssl_tog 1 + adv_listen_ssh_tog 1 } if [info exists remote_ssh_cmd_list] { @@ -11594,13 +12233,18 @@ proc ssl_ssh_adjust {which} { } proc listen_adjust {} { - global use_listen revs_button + global use_listen revs_button multiple_listen_button + if {![info exists multiple_listen_button]} { + set multiple_listen_button "none" + } if {$use_listen} { catch {.b.conn configure -text "Listen"} catch {.o.b.connect configure -text "Listen"} + catch {$multiple_listen_button configure -state normal} } else { catch {.b.conn configure -text "Connect"} catch {.o.b.connect configure -text "Connect"} + catch {$multiple_listen_button configure -state disabled} } } @@ -11661,7 +12305,7 @@ proc set_options {} { global env is_windows darwin_cotvnc uname global use_listen global use_x11vnc_find x11vnc_find_widget - global use_x11vnc_xlogin x11vnc_xlogin_widget + global use_x11vnc_xlogin x11vnc_xlogin_widget uvnc_bug_widget global ts_only if {$ts_only} { set_ts_options @@ -11705,11 +12349,18 @@ proc set_options {} { incr i checkbutton .o.b$i -anchor w -variable use_listen -text \ - "Reverse VNC Connection (-LISTEN)" -command {listen_adjust; if {$vncdisplay == ""} {set vncdisplay ":0"}} + "Reverse VNC Connection (-LISTEN)" -command {listen_adjust; if {$vncdisplay == ""} {set vncdisplay ":0"}; if {$use_listen} {destroy .o}} #if {$is_windows} {.o.b$i configure -state disabled} if {$darwin_cotvnc} {.o.b$i configure -state disabled} incr i + checkbutton .o.b$i -anchor w -variable use_uvnc_ssl_bug -text \ + "UltraVNC Single Click III Bug" + if {$is_windows} {.o.b$i configure -state disabled} + if {$use_ssh && !$use_sshssl} {.o.b$i configure -state disabled} + set uvnc_bug_widget ".o.b$i" + incr i + checkbutton .o.b$i -anchor w -variable use_viewonly -text \ "View Only" incr i @@ -12002,6 +12653,9 @@ set ts_desktop_depth_def "" set ts_desktop_type_def "" set ts_xserver_type_def "" +global win_localhost +set win_localhost "127.0.0.1" + if [file exists $ssvncrc] { set fh "" catch {set fh [open $ssvncrc "r"]} diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/build.unix b/x11vnc/misc/enhanced_tightvnc_viewer/build.unix index 9dd28d2..2740f0e 100755 --- a/x11vnc/misc/enhanced_tightvnc_viewer/build.unix +++ b/x11vnc/misc/enhanced_tightvnc_viewer/build.unix @@ -1,6 +1,10 @@ #!/bin/sh -# Notes: to customize locations, e.g. for libjpeg, set LDFLAGS_OS and/or CPPFLAGS_OS +# See the README in this directory for more info on using this script +# (build.unix). Search for SSVNC_BUILD. +# +# Notes: to customize locations, e.g. for libjpeg, set LDFLAGS_OS and/or +# CPPFLAGS_OS # # e.g. on Darwin we did: # @@ -45,6 +49,10 @@ if [ ! -d ./bin -o ! -d src/patches -o ! -f ./build.unix ]; then exit $? fi +pline() { + echo "------------------------------------------------------------------" +} + # Try to find osname.arch # name=$UNAME @@ -62,35 +70,73 @@ if [ `uname` = "Darwin" ]; then LDD="otool -L" fi +# Create a tmp dir for this build: +# +tmp=./src/tmp/$name.$$ +if [ "X$TMPDIR" != "X" ]; then + tmp="$TMPDIR/$tmp" +fi +mkdir -p $tmp || exit 1 + +# Do ultraftp Java viewer (only): +# +if [ "X$SSVNC_BUILD_ULTRAFTP" != "X" ]; then + ultraftp_tar=`ls -td ./src/zips/ultraftp.tar* | head -1` + if [ ! -f $ultraftp_tar ]; then + echo "could not locate ultraftp java vnc viewer source" + exit 1 + fi + echo "" + pline + echo "BUILDING THE ULTRAFTP HELPER JAR" + echo "" + sleep 1 + + cat $ultraftp_tar | (cd $tmp; tar xvf -) || exit 1 + cd $tmp/ultraftp || exit 1 + pwd + echo + make install + + exit 0 # DONE +fi + # Work out main destination: # dest=./bin/$name if [ -d $dest ]; then - printf "$dest exists. overwrite it? [y]/n " - read x - if [ "X$x" = "Xn" ]; then - exit + if [ "X$SSVNC_BUILD_FORCE_OVERWRITE" = "X" ]; then + printf "$dest exists. overwrite in it? [y]/n " + read x + if [ "X$x" = "Xn" ]; then + exit + fi + else + echo "$dest exists. overwriting in it." + fi + if [ "X$SSVNC_BUILD_SKIP_VIEWER" = "X" ]; then + if [ `uname` = "Darwin" ]; then + rm -f $dest/vncviewer.x11* + else + rm -f $dest/vncviewer* + fi + fi + if [ "X$SSVNC_BUILD_SKIP_STUNNEL" = "X" ]; then + rm -f $dest/stunnel* fi - rm -f $dest/*stunnel* - rm -f $dest/*vncviewer* fi mkdir -p $dest || exit 1 -# Create a tmp dir for this build: -# -tmp=./src/tmp/$name.$$ -if [ "X$TMPDIR" != "X" ]; then - tmp="$TMPDIR/$tmp" -fi -mkdir -p $tmp || exit 1 # Try to find some static archives of various libraries: # libs="$tmp/libs" mkdir -p $libs || exit 1 for liba in libz.a libjpeg.a libssl.a libcrypto.a -#for liba in libz.a libjpeg.a do + if [ "X$SSVNC_BUILD_NO_STATIC" != "X" ]; then + break + fi for dir in /usr/lib /lib /usr/local/lib /usr/pkg/lib /usr/sfw/lib /usr/openwin/lib do if [ "$name" = "Linux.x86_64" -o "$name" = "Linux.ppc64" ] ; then @@ -105,10 +151,12 @@ do fi done done -echo "Found these static archive libraries, will try to use them..." -ls -ld $libs -ls -l $libs -echo +if [ "X$SSVNC_BUILD_NO_STATIC" = "X" ]; then + echo "Found these static archive libraries, will try to use them..." + ls -ld $libs + ls -l $libs + echo +fi have_gcc="" if type gcc > /dev/null; then @@ -132,7 +180,7 @@ END fi fi -if [ -d /var/tmp/LIBS ]; then +if [ -d /var/tmp/LIBS -a "X$SSVNC_BUILD_NO_STATIC" = "X" ]; then LDFLAGS_OS="$LDFLAGS_OS -L/var/tmp/LIBS" fi @@ -150,176 +198,262 @@ if [ $cnt -lt 1 ]; then exit 1 fi +pline() { + echo "------------------------------------------------------------------" +} + # Do tightvnc viewer: # -tight_src=`ls -td ./src/vnc_unixsrc* | head -1` -if [ ! -d $tight_src ]; then - echo "could not locate tight vnc viewer source" - exit 1 -fi +if [ "X$SSVNC_BUILD_SKIP_VIEWER" = "X" ]; then + tight_src=`ls -td ./src/vnc_unixsrc* | head -1` + if [ ! -d $tight_src ]; then + echo "could not locate tight vnc viewer source" + exit 1 + fi + echo "" + pline + echo "BUILDING THE VNCVIEWER" + echo "" + sleep 1 -cp -pR "$tight_src" "$tmp/vnc_unixsrc" || exit 1 + cp -pR "$tight_src" "$tmp/vnc_unixsrc" || exit 1 -echo "applying tight vnc patches:" -start=`pwd` -cd $tmp; -failed=0 -count=0 -patches="../../patches/tight-vncviewer-full.patch" -if [ ! -f "$patches" ]; then - patches=`ls ../../patches/tight* | grep -v 'tight-vncviewer-full.patch'` -fi -for patch in $patches -do - if [ ! -f "$patch" ]; then - continue - fi - if [ "X$PATCH_FAIL" != "X" ]; then - failed=1 - break + echo "applying tight vnc patches:" + start=`pwd` + cd $tmp; + failed=0 + count=0 + patches="../../patches/tight-vncviewer-full.patch" + if [ ! -f "$patches" ]; then + patches=`ls ../../patches/tight* | grep -v 'tight-vncviewer-full.patch'` fi - echo PATCHING WITH: "$patch" - ls -l "$patch" + for patch in $patches + do + if [ ! -f "$patch" ]; then + continue + fi + if [ "X$PATCH_FAIL" != "X" ]; then + failed=1 + break + fi + echo PATCHING WITH: "$patch" + ls -l "$patch" + sleep 1 + patch -p0 < "$patch" + if [ $? != 0 ]; then + failed=`expr $failed + 1` + else + count=`expr $count + 1` + fi + done sleep 1 - patch -p0 < "$patch" - if [ $? != 0 ]; then - failed=`expr $failed + 1` - else - count=`expr $count + 1` + cd "$start" + if [ $failed != 0 -o $count = 0 ]; then + ball=src/zips/vnc_unixsrc_vncviewer.patched.tar + echo "patches failed, trying to use backup tarball:" + ls -l $ball + sleep 2 + cat $ball | (cd $tmp; tar -xvf -) fi -done -sleep 1 -cd "$start" -if [ $failed != 0 -o $count = 0 ]; then - ball=src/zips/vnc_unixsrc_vncviewer.patched.tar - echo "patches failed, trying to use backup tarball:" - ls -l $ball - sleep 2 - cat $ball | (cd $tmp; tar -xvf -) -fi -echo + echo -cd $tmp/vnc_unixsrc -xmkmf -make Makefiles -mv vncviewer/Makefile vncviewer/Makefile.orig -sed -e "s,EXTRA_LDOPTIONS =,EXTRA_LDOPTIONS = -L$start/$libs $LDFLAGS_OS," \ - -e "s,CCOPTIONS =,CCOPTIONS = $CPPFLAGS_OS," \ - vncviewer/Makefile.orig > vncviewer/Makefile + cd $tmp/vnc_unixsrc + xmkmf + make Makefiles + mv vncviewer/Makefile vncviewer/Makefile.orig + sed -e "s,EXTRA_LDOPTIONS =,EXTRA_LDOPTIONS = -L$start/$libs $LDFLAGS_OS," \ + -e "s,CCOPTIONS =,CCOPTIONS = $CPPFLAGS_OS," \ + vncviewer/Makefile.orig > vncviewer/Makefile -if [ `uname` = "SunOS" ]; then - for d in vncviewer libvncauth vncconnect vncpasswd - do - mv $d/Makefile $d/Makefile.orig - sed -e "s,CCOPTIONS =.*\$,CCOPTIONS = $CPPFLAGS_OS," \ - $d/Makefile.orig > $d/Makefile - done -fi + if [ `uname` = "SunOS" ]; then + for d in vncviewer libvncauth vncconnect vncpasswd + do + mv $d/Makefile $d/Makefile.orig + sed -e "s,CCOPTIONS =.*\$,CCOPTIONS = $CPPFLAGS_OS," \ + $d/Makefile.orig > $d/Makefile + done + fi -make depend -echo $PATH -make all -ls -l vncviewer/vncviewer -cd "$start" -src=$tmp/vnc_unixsrc/vncviewer/vncviewer -sync -sleep 2 -sync -strip $src -sync -sleep 2 -sync -wc $src -sum $src -sleep 2 - -suff="" -if [ `uname` = "Darwin" ]; then - suff=".x11" + make depend + echo $PATH + make all + ls -l vncviewer/vncviewer + cd "$start" + src=$tmp/vnc_unixsrc/vncviewer/vncviewer + sync + sleep 2 + sync + strip $src + sync + sleep 2 + sync + wc $src + sum $src + sleep 2 + + suff="" + if [ `uname` = "Darwin" ]; then + suff=".x11" + fi + echo cp -p $src $dest/vncviewer$suff + sleep 1 + cp -p $src $dest/vncviewer$suff || exit 1 + + echo + pline + echo "LISTING, HELP, and LDD THE VNCVIEWER:" + echo + sleep 1 + + ls -l $src $dest/vncviewer$suff + echo + echo $dest/vncviewer$suff -h + echo + $dest/vncviewer$suff -h + echo + echo $LDD $dest/vncviewer$suff + echo + $LDD $dest/vncviewer$suff + echo "" fi -echo cp -p $src $dest/vncviewer$suff -sleep 1 -cp -p $src $dest/vncviewer$suff || exit 1 -ls -l $src $dest/vncviewer$suff -$dest/vncviewer$suff -h -$LDD $dest/vncviewer$suff -echo "" # Do stunnel: # -stunnel_src=`ls -td ./src/stunnel* | head -1` -if [ ! -d $stunnel_src ]; then - echo "could not locate stunnel source" - exit 1 -fi +if [ "X$SSVNC_BUILD_SKIP_STUNNEL" = "X" ]; then + stunnel_src=`ls -td ./src/stunnel* | head -1` + if [ ! -d $stunnel_src ]; then + echo "could not locate stunnel source" + exit 1 + fi + echo "" + pline + echo "BUILDING THE STUNNEL" + echo "" + sleep 1 -cp -pR "$stunnel_src" "$tmp/stunnel" || exit 1 + cp -pR "$stunnel_src" "$tmp/stunnel" || exit 1 -echo "applying stunnel patches:" -start=`pwd` -cd $tmp; -failed=0 -count=0 -for patch in ../../patches/stunnel* -do - if [ ! -f "$patch" ]; then - continue + echo "applying stunnel patches:" + start=`pwd` + cd $tmp; + failed=0 + count=0 + for patch in ../../patches/stunnel* + do + if [ ! -f "$patch" ]; then + continue + fi + if [ "X$PATCH_FAIL" != "X" ]; then + failed=1 + break + fi + echo PATCHING WITH: "$patch" + ls -l "$patch" + sleep 1 + patch -p0 < $patch + if [ $? != 0 ]; then + failed=`expr $failed + 1` + else + count=`expr $count + 1` + fi + done + sleep 1 + cd "$start" + if [ $failed != 0 -o $count = 0 ]; then + ball=src/zips/stunnel.patched.tar + echo "patches failed, trying to use backup tarball:" + ls -l $ball + sleep 2 + cat $ball | (cd $tmp; tar -xvf -) fi - if [ "X$PATCH_FAIL" != "X" ]; then - failed=1 - break + echo + + + cd $tmp/stunnel + if [ `uname` = "SunOS" ]; then + cp configure configure.orig + sed -e "s,/var/ssl,/var/ssl /usr/sfw," configure.orig > configure fi - echo PATCHING WITH: "$patch" - ls -l "$patch" + env LDFLAGS="-L$start/$libs $LDFLAGS_OS" CPPFLAGS="$CPPFLAGS_OS" ./configure --disable-libwrap + make + ls -l src/stunnel + cd "$start" + src=$tmp/stunnel/src/stunnel + sync + sleep 2 + sync + strip $src + sync + sleep 2 + sync + wc $src + sum $src + sleep 2 + echo cp -p $src $dest/stunnel + cp -p $src $dest/stunnel || exit 1 sleep 1 - patch -p0 < $patch - if [ $? != 0 ]; then - failed=`expr $failed + 1` - else - count=`expr $count + 1` + cp -p $src $dest/stunnel || exit 1 + + echo + pline + echo "LISTING, HELP, and LDD THE STUNNEL:" + echo + sleep 1 + + ls -l $src $dest/stunnel + echo + echo $dest/stunnel -help + echo + $dest/stunnel -help + echo + echo $LDD $dest/stunnel + echo + $LDD $dest/stunnel + echo "" +fi + +# Do vncstorepw and ld preload friends: +# +if [ "X$SSVNC_BUILD_SKIP_VNCSTOREPW" = "X" ]; then + vncpw_tar=`ls -td ./src/zips/vncstorepw* | head -1` + if [ ! -f $vncpw_tar ]; then + echo "could not locate vncstorepw source" + exit 1 fi -done -sleep 1 -cd "$start" -if [ $failed != 0 -o $count = 0 ]; then - ball=src/zips/stunnel.patched.tar - echo "patches failed, trying to use backup tarball:" - ls -l $ball - sleep 2 - cat $ball | (cd $tmp; tar -xvf -) + echo "" + pline + echo "BUILDING THE VNCSTOREPW AND FRIENDS" + echo "" + sleep 1 + + cat "$vncpw_tar" | (cd $tmp; tar xvf -) + + cd $tmp/vncstorepw + make + + cd "$start" + cp -p $tmp/vncstorepw/vncstorepw $tmp/vncstorepw/lim_accept.so $dest + echo "" fi -echo -cd $tmp/stunnel -if [ `uname` = "SunOS" ]; then - cp configure configure.orig - sed -e "s,/var/ssl,/var/ssl /usr/sfw," configure.orig > configure +if [ "X$SSVNC_BUILD_SKIP_VIEWER" = "X" -a "X$SSVNC_BUILD_SKIP_STUNNEL" = "X" ]; then + # list the viewer again. + + echo + pline + echo "LISTING, HELP, and LDD THE VNCVIEWER (again):" + echo + sleep 1 + + ls -l $dest/vncviewer$suff + echo + echo $dest/vncviewer$suff -h + echo + $dest/vncviewer$suff -h + echo + echo $LDD $dest/vncviewer$suff + echo + $LDD $dest/vncviewer$suff fi -env LDFLAGS="-L$start/$libs $LDFLAGS_OS" CPPFLAGS="$CPPFLAGS_OS" ./configure --disable-libwrap -make -ls -l src/stunnel -cd "$start" -src=$tmp/stunnel/src/stunnel -sync -sleep 2 -sync -strip $src -sync -sleep 2 -sync -wc $src -sum $src -sleep 2 -echo cp -p $src $dest/stunnel -cp -p $src $dest/stunnel || exit 1 -sleep 1 -cp -p $src $dest/stunnel || exit 1 -ls -l $src $dest/stunnel -$dest/stunnel -help -$LDD $dest/stunnel -echo "" - -$dest/vncviewer$suff -h -$LDD $dest/vncviewer$suff diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvnc.1 b/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvnc.1 new file mode 100644 index 0000000..661c32a --- /dev/null +++ b/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvnc.1 @@ -0,0 +1,148 @@ +'\" t +.\" ** The above line should force tbl to be a preprocessor ** +.\" Man page for the SSVNC vncviewer +.\" +.\" Copyright (C) 2006-2008 Karl J. Runge <runge@karlrunge.com> +.\" +.\" You may distribute under the terms of the GNU General Public +.\" License as specified in the file LICENCE.TXT that comes with the +.\" TightVNC distribution. +.\" +.TH ssvnc 1 "September 2008" "" "SSVNC" +.SH NAME +ssvnc \- a GUI wrapper for SSL and SSH VNC connections. +.SH SYNOPSIS +.B ssvnc +.br +.B ssvnc +.RI [\| host \|][\| :display \|] +.br +.B ssvnc +.RI [\| saved-profile-name \|] +.br +.B ssvnc +.RI [\| options \|][\| host-or-profile \] +.br +.B ssvnc +.IR \--help +.br +.SH DESCRIPTION +.B ssvnc +is a tcl/tk gui wrapper that runs on Unix, MacOSX, and Windows. +It sets up an SSL or SSH tunnel to the remote VNC Server and then launches +the VNC viewer (either the one provided or another one that you have +specified) to use that encrypted tunnel to connect to the VNC Server. +The use of Proxies and Gateways to make the connections is implemented. + +Once you have started the SSVNC gui, you can click on the buttons +"Help", "Options -> Help", "Certs -> Help", etc. for much information +on how to use and configure the tool. + +In short, you supply a VNC server "hostname:display" in the +"VNC Host:Display" entry box and then press the "Connect" button to +connect to the server via SSL (stunnel). E.g. "far-away.east:0". +Port numbers are also allowed, e.g. far-away.east:5905. + +Or supply user@hostname:display and click on the "Use SSH" option, then +press the "Connect" button to connect to the server via an SSH tunnel. +E.g. "fred@far-away.east:0". + +As an easter egg, we note it is also possible to disable the use of SSL/SSH +encryption tunnels by using a vnc:// or Vnc:// prefix before +host:display. + +Normally you do not specify any command line options. You simply +run \fBssvnc\fR and use the GUI that starts up. + +However, as shortcuts you can supply a VNC host:display (or host:port) +on the command line. to connect to immediately (the GUI is started +and the connection is initiated). For example, "\fBssvnc far-away.east:0\fR" +Instead of a host:display, you can specify the name of a saved profile to +automatically load that profile and then connect to its server. +For example "\fBssvnc far\fR", if you name the profile "far". +You can use the \fB-profiles\fR option to list the profiles you have saved. + +The related commands \fBsshvnc\fR and \fBtsvnc\fR start up the GUI in +simplified modes: SSH Only Mode, and Terminal Services Mode, respectively. +See below and the application Help for more information on the modes. + +There are also some command line options described as follows. +.SH OPTIONS +.TP +\fB\--help\fR +Starts up the GUI as though the 'Help' button was pressed to show the +main Help panel. +.TP +\fB\-profiles\fR +List the saved SSVNC profiles you have created. A profile +is a destination host with specific parameter settings. +.TP +\fB\-list\fR +Same as \fB\-profiles\fR +.TP +\fB\-ssh\fR +Start in "SSH Only Mode". No SSL aspects are shown. +Same as running the command \fBsshvnc\fR +.TP +\fB\-ts\fR +Start in "Terminal Services Mode". This is like "SSH Only Mode", but +simpler and assumes \fBx11vnc\fR is available on the remote side +to start and manage X and VNC sessions. +Same as running the command \fBtsvnc\fR +.TP +\fB\-tso\fR +Same as \fB-ts\fR "Terminal Services Mode", however never let the +user leave this mode (no button to switch modes is provided.) +Same as SSVNC_TS_ALWAYS=1. +.TP +\fB\-ssl\fR +Force the full GUI Mode: both SSL and SSH. This is the default. +.TP +\fB\-nv\fR +Toggle the "Verify All Certs" button to be off at startup. +.TP +\fB\-nvb\fR +Never show the "Verify All Certs" button. +Same as SSVNC_NO_VERIFY_ALL_BUTTON=1. +.TP +\fB\-bigger\fR +Make the Profile Selection Dialog window bigger. +Same as SSVNC_BIGGER_DIALOG=1. +.SH URL NOTATION +Here are all of our URL-like prefixes that you can put in front of +host:display (or host:port): + +For SSL: vncs:// vncssl:// and vnc+ssl:// + +For SSH: vncssh:// and vnc+ssh:// + +For No Encryption Tunnel: vnc:// and Vnc:// + +Examples: + +To quickly make an SSL connection: \fBssvnc vncs://snoopy.com:0\fR + +To quickly make an SSH connection: \fBssvnc vnc+ssh://fred@snoopy.com:0\fR + +To quickly make a direct connection: \fBssvnc Vnc://snoopy.com:0\fR + +The above will also work in the "VNC Host:Display" entry box in the GUI. +Press the "Connect" button after entering them. +.SH FILES +Your SSVNC vnc profiles are stored in the \fB$HOME/.vnc/profiles\fR +directory. They end in suffix \fB.vnc\fR + +Your SSVNC vnc certificates and keys are stored in the \fB$HOME/.vnc/certs\fR +directory. They typically end in \fB.pem\fR (both certificate and +private key) or \fB.crt\fR (certificate only). + +You can put a few global parameters (e.g. mode=sshvnc) in your +\fB$HOME/.ssvncrc\fR file (\fBssvnc_rc\fR on Windows); see the +application Help for more information. + +.SH SEE ALSO +\fBssvncviewer\fB(1), \fBvncviewer\fR(1), \fBstunnel\fR(8), \fBssh\fR(1), \fBx11vnc\fR(1), \fBvncserver\fR(1) +http://www.karlrunge.com/x11vnc http://www.karlrunge.com/x11vnc/ssvnc.html +.SH AUTHORS +Karl J. Runge <runge@karlrunge.com> wrote the SSVNC gui (tcl/tk) and +associated wrapper scripts. diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1 b/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1 new file mode 100644 index 0000000..e451ec8 --- /dev/null +++ b/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1 @@ -0,0 +1,586 @@ +'\" t +.\" ** The above line should force tbl to be a preprocessor ** +.\" Man page for X vncviewer +.\" +.\" Copyright (C) 1998 Marcus.Brinkmann@ruhr-uni-bochum.de +.\" Copyright (C) 2000,2001 Red Hat, Inc. +.\" Copyright (C) 2001-2003 Constantin Kaplinsky <const@ce.cctpu.edu.ru> +.\" Copyright (C) 2006-2008 Karl J. Runge <runge@karlrunge.com> +.\" +.\" You may distribute under the terms of the GNU General Public +.\" License as specified in the file LICENCE.TXT that comes with the +.\" TightVNC distribution. +.\" +.TH ssvncviewer 1 "August 2008" "" "SSVNC" +.SH NAME +ssvncviewer \- an X viewer client for VNC +.SH SYNOPSIS +.B ssvncviewer +.RI [\| options \|] +.RI [\| host \|][\| :display \|] +.br +.B ssvncviewer +.RI [\| options \|] +.RI [\| host \|][\| ::port \|] +.br +.B ssvncviewer +.RI [\| options \|] +.RI exec=[\| cmd+args... \|] +.br +.B ssvncviewer +.RI [\| options \|] +.RI /path/to/unix/socket +.br +.B ssvncviewer +.RI [\| options \|] +.IR \-listen +.RI [\| display \|] +.br +.B ssvncviewer +.IR \-help +.br +.SH DESCRIPTION +.B ssvncviewer +is an Xt\-based client application for the VNC (Virtual Network +Computing) system. It can connect to any VNC\-compatible server such +as \fBXvnc\fR, WinVNC, or \fBx11vnc\fR, allowing you to control desktop environment +of a different machine. + +ssvncviewer is an enhanced version of the tightvnc unix viewer that can +take advantage of features in the \fBx11vnc\fR and UltraVNC VNC servers. +See below for the description of these features. + +You can use F8 to display a pop\-up utility menu. Press F8 twice to +pass single F8 to the remote side. +.SH OPTIONS +.TP +\fB\-help\fR +Prints a short usage notice to stderr. +.TP +\fB\-listen\fR +Make the viewer listen on port 5500+\fIdisplay\fR for reverse +connections from a server. WinVNC supports reverse connections using +the "Add New Client" menu option, or the \-connect command line +option. \fBXvnc\fR requires the use of the helper program +\fBvncconnect\fR. +.TP +\fB\-via\fR \fIgateway\fR +Automatically create encrypted TCP tunnel to the \fIgateway\fR machine +before connection, connect to the \fIhost\fR through that tunnel +(TightVNC\-specific). By default, this option invokes SSH local port +forwarding, assuming that SSH client binary can be accessed as +/usr/bin/ssh. Note that when using the \fB\-via\fR option, the host +machine name should be specified as known to the gateway machine, e.g. +"localhost" denotes the \fIgateway\fR, not the machine where vncviewer +was launched. See the ENVIRONMENT section below for the information on +configuring the \fB\-via\fR option. +.TP +\fB\-shared\fR +When connecting, specify that a shared connection is requested. In +TightVNC, this is the default mode, allowing you to share the desktop +with other clients already using it. +.TP +\fB\-noshared\fR +When connecting, specify that the session may not be shared. This +would either disconnect other connected clients or refuse your +connection, depending on the server configuration. +.TP +\fB\-viewonly\fR +Disable transfer of mouse and keyboard events from the client to the +server. +.TP +\fB\-fullscreen\fR +Start in full\-screen mode. Please be aware that operating in +full\-screen mode may confuse X window managers. Typically, such +conflicts cause incorrect handling of input focus or make the viewer +window disappear mysteriously. See the grabKeyboard setting in the +RESOURCES section below for a method to solve input focus problem. +.TP +\fB\-noraiseonbeep\fR +By default, the viewer shows and raises its window on remote beep +(bell) event. This option disables such behaviour +(TightVNC\-specific). +.TP +\fB\-user\fR \fIusername\fR +User name for Unix login authentication. Default is to use current +Unix user name. If this option was given, the viewer will prefer Unix +login authentication over the standard VNC authentication. +.TP +\fB\-passwd\fR \fIpasswd\-file\fR +File from which to get the password (as generated by the +\fBvncpasswd\fR(1) program). This option affects only the standard VNC +authentication. +.TP +\fB\-encodings\fR \fIencoding\-list\fR +TightVNC supports several different compression methods to encode +screen updates; this option specifies a set of them to use in order of +preference. Encodings are specified separated with spaces, and must +thus be enclosed in quotes if more than one is specified. Available +encodings, in default order for a remote connection, are "copyrect +tight hextile zlib corre rre raw". For a local connection (to the same +machine), the default order to try is "raw copyrect tight hextile zlib +corre rre". Raw encoding is always assumed as a last option if no +other encoding can be used for some reason. For more information on +encodings, see the section ENCODINGS below. +.TP +\fB\-bgr233\fR +Always use the BGR233 format to encode pixel data. This reduces +network traffic, but colors may be represented inaccurately. The +bgr233 format is an 8\-bit "true color" format, with 2 bits blue, 3 +bits green, and 3 bits red. +.TP +\fB\-owncmap\fR +Try to use a PseudoColor visual and a private colormap. This allows +the VNC server to control the colormap. +.TP +\fB\-truecolour\fR, \fB\-truecolor\fR +Try to use a TrueColor visual. +.TP +\fB\-depth\fR \fIdepth\fR +On an X server which supports multiple TrueColor visuals of different +depths, attempt to use the specified one (in bits per pixel); if +successful, this depth will be requested from the VNC server. +.TP +\fB\-compresslevel \fIlevel\fR +Use specified compression \fIlevel\fR (0..9) for "tight" and "zlib" +encodings (TightVNC\-specific). Level 1 uses minimum of CPU time and +achieves weak compression ratios, while level 9 offers best +compression but is slow in terms of CPU time consumption on the server +side. Use high levels with very slow network connections, and low +levels when working over high\-speed LANs. It's not recommended to use +compression level 0, reasonable choices start from the level 1. +.TP +\fB\-quality \fIlevel\fR +Use the specified JPEG quality \fIlevel\fR (0..9) for the "tight" +encoding (TightVNC\-specific). Quality level 0 denotes bad image +quality but very impressive compression ratios, while level 9 offers +very good image quality at lower compression ratios. Note that the +"tight" encoder uses JPEG to encode only those screen areas that look +suitable for lossy compression, so quality level 0 does not always +mean unacceptable image quality. +.TP +\fB\-nojpeg\fR +Disable lossy JPEG compression in Tight encoding (TightVNC\-specific). +Disabling JPEG compression is not a good idea in typical cases, as +that makes the Tight encoder less efficient. You might want to use +this option if it's absolutely necessary to achieve perfect image +quality (see also the \fB\-quality\fR option). +.TP +\fB\-nocursorshape\fR +Disable cursor shape updates, protocol extensions used to handle +remote cursor movements locally on the client side +(TightVNC\-specific). Using cursor shape updates decreases delays with +remote cursor movements, and can improve bandwidth usage dramatically. +.TP +\fB\-x11cursor\fR +Use a real X11 cursor with X-style cursor shape updates, instead of +drawing the remote cursor on the framebuffer. This option also +disables the dot cursor, and disables cursor position updates in +non-fullscreen mode. +.TP +\fB\-autopass\fR +Read a plain-text password from stdin. This option affects only the +standard VNC authentication. + +.SH Enhanced TightVNC Viewer (SSVNC) OPTIONS +.TP +Enhanced TightVNC Viewer (SSVNC) web page is located at: +.TP +http://www.karlrunge.com/x11vnc/ssvnc.html +.TP +Note: ZRLE and ZYWRLE encodings are now supported. +.TP +Note: F9 is shortcut to Toggle FullScreen mode. +.TP +Note: In -listen mode set the env var. SSVNC_MULTIPLE_LISTEN=1 +to allow more than one incoming VNC server at a time. +.TP +Note: If the host:port is specified as "exec=command args..." +then instead of making a TCP/IP socket connection to the +remote VNC server, "command args..." is executed and the +viewer is attached to its stdio. This enables tunnelling +established via an external command, e.g. an stunnel(8) +that does not involve a listening socket. +This mode does not work for -listen reverse connections. +.TP +Note: If the host:port contains a '/' it is interpreted as a +unix-domain socket (AF_LOCAL insead of AF_INET) +.TP +\fB\-use64\fR +In \fB\-bgr233\fR mode, use 64 colors instead of 256. +.TP +\fB\-bgr222\fR +Same as \fB\-use64\fR. +.TP +\fB\-use8\fR +In \fB\-bgr233\fR mode, use 8 colors instead of 256. +.TP +\fB\-bgr111\fR +Same as \fB\-use8\fR. +.TP +\fB\-16bpp\fR +If the vnc viewer X display is depth 24 at 32bpp +request a 16bpp format from the VNC server to cut +network traffic by up to 2X, then tranlate the +pixels to 32bpp locally. +.TP +\fB\-bgr565\fR +Same as \fB\-16bpp\fR. +.TP +\fB\-grey\fR +Use a grey scale for the 16- and 8\fB\-bpp\fR modes. +.TP +\fB\-alpha\fR +Use alphablending transparency for local cursors +requires: x11vnc server, both client and server +must be 32bpp and same endianness. +.TP +\fB\-ycrop\fR n +Only show the top n rows of the framebuffer. For +use with x11vnc \fB\-ncache\fR client caching option +to help "hide" the pixel cache region. +Use a negative value (e.g. \fB\-1\fR) for autodetection. +Autodetection will always take place if the remote +fb height is more than 2 times the width. +.TP +\fB\-sbwidth\fR n +Scrollbar width for x11vnc \fB\-ncache\fR mode (\fB\-ycrop\fR), +default is very narrow: 2 pixels, it is narrow to +avoid distraction in \fB\-ycrop\fR mode. +.TP +\fB\-nobell\fR +Disable bell. +.TP +\fB\-rawlocal\fR +Prefer raw encoding for localhost, default is +no, i.e. assumes you have a SSH tunnel instead. +.TP +\fB\-graball\fR +Grab the entire X server when in fullscreen mode, +needed by some old window managers like fvwm2. +.TP +\fB\-popupfix\fR +Warp the popup back to the pointer position, +needed by some old window managers like fvwm2. +.TP +\fB\-grabkbd\fR +Grab the X keyboard when in fullscreen mode, +needed by some window managers. Same as \fB\-grabkeyboard\fR. +\fB\-grabkbd\fR is the default, use \fB\-nograbkbd\fR to disable. +.TP +\fB\-bs\fR, \fB\-nobs\fR +Whether or not to use X server Backingstore for the +main viewer window. The default is to not, mainly +because most Linux, etc, systems X servers disable +*all* Backingstore by default. To re\fB\-enable\fR it put +Option "Backingstore" +in the Device section of /etc/X11/xorg.conf. +In \fB\-bs\fR mode with no X server backingstore, whenever an +area of the screen is re\fB\-exposed\fR it must go out to the +VNC server to retrieve the pixels. This is too slow. +In \fB\-nobs\fR mode, memory is allocated by the viewer to +provide its own backing of the main viewer window. This +actually makes some activities faster (changes in large +regions) but can appear to "flash" too much. +.TP +\fB\-noshm\fR +Disable use of MIT shared memory extension (not recommended) +.TP +\fB\-termchat\fR +Do the UltraVNC chat in the terminal vncviewer is in +instead of in an independent window. +.TP +\fB\-unixpw\fR +str Useful for logging into x11vnc in \fB\-unixpw\fR mode. "str" is a +string that allows many ways to enter the Unix Username +and Unix Password. These characters: username, newline, +password, newline are sent to the VNC server after any VNC +authentication has taken place. Under x11vnc they are +used for the \fB\-unixpw\fR login. Other VNC servers could do +something similar. +You can also indicate "str" via the environment +variable SSVNC_UNIXPW. +Note that the Escape key is actually sent first to tell +x11vnc to not echo the Unix Username back to the VNC +viewer. Set SSVNC_UNIXPW_NOESC=1 to override this. +If str is ".", then you are prompted at the command line +for the username and password in the normal way. If str is +"-" the stdin is read via getpass(3) for username@password. +Otherwise if str is a file, it is opened and the first line +read is taken as the Unix username and the 2nd as the +password. If str prefixed by "rm:" the file is removed +after reading. Otherwise, if str has a "@" character, +it is taken as username@password. Otherwise, the program +exits with an error. Got all that? +.TP +\fB-repeater\fR str This is for use with UltraVNC repeater proxy described +here: http://www.uvnc.com/addons/repeater.html. The "str" +is the ID string to be sent to the repeater. E.g. ID:1234 +It can also be the hostname and port or display of the VNC +server, e.g. 12.34.56.78:0 or snoopy.com:1. Note that when +using -repeater, the host:dpy on the cmdline is the repeater +server, NOT the VNC server. The repeater will connect you. +Example: vncviewer ... -repeater ID:3333 repeat.host:5900 +Example: vncviewer ... -repeater vhost:0 repeat.host:5900 +.TP +\fB\-printres\fR Print out the Ssvnc X resources (appdefaults) and +then exit. You can save them to a file and customize them (e.g. the +keybindings and Popup menu) Then point to the file via +XENVIRONMENT or XAPPLRESDIR. +.TP +\fB New Popup actions:\fR + + ViewOnly: ~ -viewonly + Disable Bell: ~ -nobell + Cursor Shape: ~ -nocursorshape + X11 Cursor: ~ -x11cursor + Cursor Alphablend: ~ -alpha + Toggle Tight/ZRLE: ~ -encodings ... + Toggle ZRLE/ZYWRLE: ~ -encodings zywrle... + Quality Level ~ -quality (both Tight and ZYWRLE) + Compress Level ~ -compresslevel + Disable JPEG: ~ -nojpeg (Tight) + Full Color ~ as many colors as local screen allows. + Grey scale (16 & 8-bpp) ~ -grey, for low colors 16/8bpp modes. + 16 bit color (BGR565) ~ -16bpp / -bgr565 + 8 bit color (BGR233) ~ -bgr233 + 256 colors ~ -bgr233 default # of colors. + 64 colors ~ -bgr222 / -use64 + 8 colors ~ -bgr111 / -use8 + Set Y Crop (y-max) ~ -ycrop + Set Scrollbar Width ~ -sbwidth + + UltraVNC Extensions: + + Set 1/n Server Scale Ultravnc ext. Scale desktop by 1/n. + Text Chat Ultravnc ext. Do Text Chat. + File Transfer Ultravnc ext. File xfer via Java helper. + Single Window Ultravnc ext. Grab a single window. + (click on the window you want). + Disable Remote Input Ultravnc ext. Try to prevent input and + viewing of monitor at physical display. + + Note: the Ultravnc extensions only apply to servers that + support them. x11vnc/libvncserver supports some of them. + +.SH ENCODINGS +The server supplies information in whatever format is desired by the +client, in order to make the client as easy as possible to implement. +If the client represents itself as able to use multiple formats, the +server will choose one. + +.I Pixel format +refers to the representation of an individual pixel. The most common +formats are 24 and 16 bit "true\-color" values, and 8\-bit "color map" +representations, where an arbitrary map converts the color number to +RGB values. + +.I Encoding +refers to how a rectangle of pixels are sent (all pixel information in +VNC is sent as rectangles). All rectangles come with a header giving +the location and size of the rectangle and an encoding type used by +the data which follows. These types are listed below. +.TP +.B Raw +The raw encoding simply sends width*height pixel values. All clients +are required to support this encoding type. Raw is also the fastest +when the server and viewer are on the same machine, as the connection +speed is essentially infinite and raw encoding minimizes processing +time. +.TP +.B CopyRect +The Copy Rectangle encoding is efficient when something is being +moved; the only data sent is the location of a rectangle from which +data should be copied to the current location. Copyrect could also be +used to efficiently transmit a repeated pattern. +.TP +.B RRE +The Rise\-and\-Run\-length\-Encoding is basically a 2D version of +run\-length encoding (RLE). In this encoding, a sequence of identical +pixels are compressed to a single value and repeat count. In VNC, this +is implemented with a background color, and then specifications of an +arbitrary number of subrectangles and color for each. This is an +efficient encoding for large blocks of constant color. +.TP +.B CoRRE +This is a minor variation on RRE, using a maximum of 255x255 pixel +rectangles. This allows for single\-byte values to be used, reducing +packet size. This is in general more efficient, because the savings +from sending 1\-byte values generally outweighs the losses from the +(relatively rare) cases where very large regions are painted the same +color. +.TP +.B Hextile +Here, rectangles are split up in to 16x16 tiles, which are sent in a +predetermined order. The data within the tiles is sent either raw or +as a variant on RRE. Hextile encoding is usually the best choice for +using in high\-speed network environments (e.g. Ethernet local\-area +networks). +.TP +.B Zlib +Zlib is a very simple encoding that uses zlib library to compress raw +pixel data. This encoding achieves good compression, but consumes a +lot of CPU time. Support for this encoding is provided for +compatibility with VNC servers that might not understand Tight +encoding which is more efficient than Zlib in nearly all real\-life +situations. +.TP +.B Tight +Like Zlib encoding, Tight encoding uses zlib library to compress the +pixel data, but it pre\-processes data to maximize compression ratios, +and to minimize CPU usage on compression. Also, JPEG compression may +be used to encode color\-rich screen areas (see the description of +\-quality and \-nojpeg options above). Tight encoding is usually the +best choice for low\-bandwidth network environments (e.g. slow modem +connections). +.TP +.B ZRLE +The SSVNC viewer has ported the RealVNC (www.realvnc.com) ZRLE encoding +to the unix tightvnc viewer. +.TP +.B ZYWRLE +The SSVNC viewer has ported the Hitachi lossy wavelet based ZRLE +encoding from http://mobile.hitachi-system.co.jp/publications/ZYWRLE/ +to the unix tightvnc viewer. +.SH RESOURCES +X resources that \fBvncviewer\fR knows about, aside from the +normal Xt resources, are as follows: +.TP +.B shareDesktop +Equivalent of \fB\-shared\fR/\fB\-noshared\fR options. Default true. +.TP +.B viewOnly +Equivalent of \fB\-viewonly\fR option. Default false. +.TP +.B fullScreen +Equivalent of \fB\-fullscreen\fR option. Default false. +.TP +.B grabKeyboard +Grab keyboard in full-screen mode. This can help to solve problems +with losing keyboard focus. Default false. +.TP +.B raiseOnBeep +Equivalent of \fB\-noraiseonbeep\fR option, when set to false. Default +true. +.TP +.B passwordFile +Equivalent of \fB\-passwd\fR option. +.TP +.B userLogin +Equivalent of \fB\-user\fR option. +.TP +.B passwordDialog +Whether to use a dialog box to get the password (true) or get it from +the tty (false). Irrelevant if \fBpasswordFile\fR is set. Default +false. +.TP +.B encodings +Equivalent of \fB\-encodings\fR option. +.TP +.B compressLevel +Equivalent of \fB\-compresslevel\fR option (TightVNC\-specific). +.TP +.B qualityLevel +Equivalent of \fB\-quality\fR option (TightVNC\-specific). +.TP +.B enableJPEG +Equivalent of \fB\-nojpeg\fR option, when set to false. Default true. +.TP +.B useRemoteCursor +Equivalent of \fB\-nocursorshape\fR option, when set to false +(TightVNC\-specific). Default true. +.TP +.B useBGR233 +Equivalent of \fB\-bgr233\fR option. Default false. +.TP +.B nColours +When using BGR233, try to allocate this many "exact" colors from the +BGR233 color cube. When using a shared colormap, setting this resource +lower leaves more colors for other X clients. Irrelevant when using +truecolor. Default is 256 (i.e. all of them). +.TP +.B useSharedColours +If the number of "exact" BGR233 colors successfully allocated is less +than 256 then the rest are filled in using the "nearest" colors +available. This resource says whether to only use the "exact" BGR233 +colors for this purpose, or whether to use other clients' "shared" +colors as well. Default true (i.e. use other clients' colors). +.TP +.B forceOwnCmap +Equivalent of \fB\-owncmap\fR option. Default false. +.TP +.B forceTrueColour +Equivalent of \fB\-truecolour\fR option. Default false. +.TP +.B requestedDepth +Equivalent of \fB\-depth\fR option. +.TP +.B useSharedMemory +Use MIT shared memory extension if on the same machine as the X +server. Default true. +.TP +.B wmDecorationWidth, wmDecorationHeight +The total width and height taken up by window manager decorations. +This is used to calculate the maximum size of the VNC viewer window. +Default is width 4, height 24. +.TP +.B bumpScrollTime, bumpScrollPixels +When in full screen mode and the VNC desktop is bigger than the X +display, scrolling happens whenever the mouse hits the edge of the +screen. The maximum speed of scrolling is bumpScrollPixels pixels +every bumpScrollTime milliseconds. The actual speed of scrolling will +be slower than this, of course, depending on how fast your machine is. +Default 20 pixels every 25 milliseconds. +.TP +.B popupButtonCount +The number of buttons in the popup window. See the README file for +more information on how to customize the buttons. +.TP +.B debug +For debugging. Default false. +.TP +.B rawDelay, copyRectDelay +For debugging, see the README file for details. Default 0 (off). +.SH ENVIRONMENT +When started with the \fB\-via\fR option, vncviewer reads the +\fBVNC_VIA_CMD\fR environment variable, expands patterns beginning +with the "%" character, and executes result as a command assuming that +it would create TCP tunnel that should be used for VNC connection. If +not set, this environment variable defaults to "/usr/bin/ssh -f -L +%L:%H:%R %G sleep 20". + +The following patterns are recognized in the \fBVNC_VIA_CMD\fR (note +that all the patterns %G, %H, %L and %R must be present in the command +template): +.TP +.B %% +A literal "%"; +.TP +.B %G +gateway host name; +.TP +.B %H +remote VNC host name, as known to the gateway; +.TP +.B %L +local TCP port number; +.TP +.B %R +remote TCP port number. +.SH SEE ALSO +\fBvncserver\fR(1), \fBXvnc\fR(1), \fBvncpasswd\fR(1), +\fBvncconnect\fR(1), \fBssh\fR(1) +.SH AUTHORS +Original VNC was developed in AT&T Laboratories Cambridge. TightVNC +additions was implemented by Constantin Kaplinsky. Many other people +participated in development, testing and support. + +\fBMan page authors:\fR +.br +Marcus Brinkmann <Marcus.Brinkmann@ruhr-uni-bochum.de>, +.br +Terran Melconian <terran@consistent.org>, +.br +Tim Waugh <twaugh@redhat.com>, +.br +Constantin Kaplinsky <const@ce.cctpu.edu.ru> diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_getpatches b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_getpatches index 38e66c9..8e1ddcc 100755 --- a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_getpatches +++ b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_getpatches @@ -3,3 +3,7 @@ cp -p /dist/src/apps/VNC/tight_vnc_1.3dev5/tight-vncviewer*patch . cp -p /dist/src/apps/VNC/tight_vnc_1.3dev5/vnc_unixsrc_vncviewer.patched.tar ../zips/ +cp -p /dist/src/apps/VNC/etc/libvncserver_cvs/expts/java_ssl/ultra/ultraftp.tar ../zips/ +cp -p /dist/src/apps/VNC/etc/libvncserver_cvs/expts/vncstorepw.tar ../zips/ + +cp -p /dist/src/apps/VNC/tight_vnc_1.3dev5/vnc_unixsrc/vncviewer/vncviewer.man ../../man/man1/ssvncviewer.1 diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-full.patch b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-full.patch index 2120959..cf7ce30 100644 --- a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-full.patch +++ b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-full.patch @@ -1,7 +1,14 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/Vncviewer vnc_unixsrc/vncviewer/Vncviewer --- vnc_unixsrc.orig/vncviewer/Vncviewer 2003-02-07 05:30:57.000000000 -0500 -+++ vnc_unixsrc/vncviewer/Vncviewer 2008-02-17 13:34:03.000000000 -0500 -@@ -5,9 +5,9 @@ ++++ vnc_unixsrc/vncviewer/Vncviewer 2008-08-24 16:26:01.000000000 -0400 +@@ -1,20 +1,22 @@ + ! +-! Application defaults file for vncviewer. ++! Application defaults file for SSVNC vncviewer. ++! ++! N.B.: You will need to rename this file to be "Ssvnc" instead of "Vncviewer" + ! + ! ! The title of the main window. "%s" will be replaced by the desktop name. @@ -9,11 +16,38 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/Vncviewer vnc_unixsrc/vncview +! -Vncviewer.title: TightVNC: %s -+Vncviewer.title: SSVNC: %s Press F8 for Menu ++Ssvnc.title: SSVNC: %s Press F8 for Menu + + + ! + ! Translations on the main window. + ! + +-Vncviewer.translations:\ ++Ssvnc.translations:\ + <Enter>: SelectionToVNC()\n\ + <Leave>: SelectionFromVNC() + +@@ -23,7 +25,7 @@ + ! Uncomment to grab the keyboard in full-screen mode. + ! + +-! Vncviewer.grabKeyboard: True ++! Ssvnc.grabKeyboard: True ! -@@ -50,6 +50,7 @@ +@@ -43,6 +45,9 @@ + *viewport.useRight: True + *viewport*Scrollbar*thumb: None + ++*viewport.horizontal.height: 6 ++*viewport.vertical.width: 6 ++ + + ! + ! Default translations on desktop window. +@@ -50,89 +55,591 @@ *desktop.baseTranslations:\ <Key>F8: ShowPopup()\n\ @@ -21,25 +55,97 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/Vncviewer vnc_unixsrc/vncview <ButtonPress>: SendRFBEvent()\n\ <ButtonRelease>: SendRFBEvent()\n\ <Motion>: SendRFBEvent()\n\ -@@ -72,17 +73,51 @@ - *passwordDialog.dialog.value.translations: #override\n\ - <Key>Return: PasswordDialogDone() + <KeyPress>: SendRFBEvent()\n\ + <KeyRelease>: SendRFBEvent() + ++*viewport.horizontal.translations: #override\n\ ++ <KeyPress>Right: StartScroll(Forward)\n\ ++ <KeyRelease>Right: NotifyScroll(FullLength) EndScroll()\n\ ++ <KeyPress>Left: StartScroll(Backward)\n\ ++ <KeyRelease>Left: NotifyScroll(FullLength) EndScroll()\n\ ++ <KeyPress>Next: StartScroll(Forward)\n\ ++ <KeyRelease>Next: NotifyScroll(FullLength) EndScroll()\n\ ++ <KeyPress>Prior: StartScroll(Backward)\n\ ++ <KeyRelease>Prior: NotifyScroll(FullLength) EndScroll()\n\ ++ <KeyPress>z: StartScroll(Forward)\n\ ++ <KeyRelease>z: NotifyScroll(FullLength) EndScroll()\n\ ++ <KeyPress>a: StartScroll(Backward)\n\ ++ <KeyRelease>a: NotifyScroll(FullLength) EndScroll()\n\ ++ <KeyPress>f: StartScroll(Forward)\n\ ++ <KeyRelease>f: NotifyScroll(FullLength) EndScroll()\n\ ++ <KeyPress>b: StartScroll(Backward)\n\ ++ <KeyRelease>b: NotifyScroll(FullLength) EndScroll()\n\ ++ <KeyPress>Down: StartScroll(Forward)\n\ ++ <KeyRelease>Down: NotifyScroll(FullLength) EndScroll()\n\ ++ <KeyPress>Up: StartScroll(Backward)\n\ ++ <KeyRelease>Up: NotifyScroll(FullLength) EndScroll() ++ ++*viewport.vertical.translations: #override\n\ ++ <KeyPress>Down: StartScroll(Forward)\n\ ++ <KeyRelease>Down: NotifyScroll(FullLength) EndScroll()\n\ ++ <KeyPress>Up: StartScroll(Backward)\n\ ++ <KeyRelease>Up: NotifyScroll(FullLength) EndScroll()\n\ ++ <KeyPress>Next: StartScroll(Forward)\n\ ++ <KeyRelease>Next: NotifyScroll(FullLength) EndScroll()\n\ ++ <KeyPress>Prior: StartScroll(Backward)\n\ ++ <KeyRelease>Prior: NotifyScroll(FullLength) EndScroll()\n\ ++ <KeyPress>z: StartScroll(Forward)\n\ ++ <KeyRelease>z: NotifyScroll(FullLength) EndScroll()\n\ ++ <KeyPress>a: StartScroll(Backward)\n\ ++ <KeyRelease>a: NotifyScroll(FullLength) EndScroll()\n\ ++ <KeyPress>f: StartScroll(Forward)\n\ ++ <KeyRelease>f: NotifyScroll(FullLength) EndScroll()\n\ ++ <KeyPress>b: StartScroll(Backward)\n\ ++ <KeyRelease>b: NotifyScroll(FullLength) EndScroll()\n\ ++ <KeyPress>Right: StartScroll(Forward)\n\ ++ <KeyRelease>Right: NotifyScroll(FullLength) EndScroll()\n\ ++ <KeyPress>Left: StartScroll(Backward)\n\ ++ <KeyRelease>Left: NotifyScroll(FullLength) EndScroll() ++ + ! + ! Dialog boxes + ! + + *serverDialog.dialog.label: VNC server: ++ + *serverDialog.dialog.value: ++ + *serverDialog.dialog.value.translations: #override\n\ +- <Key>Return: ServerDialogDone() ++ <Key>Return: ServerDialogDone() ++ +*ycropDialog.dialog.label: Y Crop (max-height in pixels): ++ +*ycropDialog.dialog.value: -+*ycropDialog.dialog.value.translations: #override\\n\ ++ ++*ycropDialog.dialog.value.translations: #override\n\ + <Key>Return: YCropDialogDone() + +*scbarDialog.dialog.label: Scroll Bars width: ++ +*scbarDialog.dialog.value: -+*scbarDialog.dialog.value.translations: #override\\n\ ++ ++*scbarDialog.dialog.value.translations: #override\n\ + <Key>Return: ScbarDialogDone() + +*scaleDialog.dialog.label: Integer n for 1/n server scaling: ++ +*scaleDialog.dialog.value: -+*scaleDialog.dialog.value.translations: #override\\n\ ++ ++*scaleDialog.dialog.value.translations: #override\n\ + <Key>Return: ScaleDialogDone() + + *passwordDialog.dialog.label: Password: ++ + *passwordDialog.dialog.value: + + *passwordDialog.dialog.value.AsciiSink.echo: False ++ + *passwordDialog.dialog.value.translations: #override\n\ +- <Key>Return: PasswordDialogDone() ++ <Key>Return: PasswordDialogDone() + ! ! Popup window appearance @@ -47,423 +153,538 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/Vncviewer vnc_unixsrc/vncview -*popup.title: TightVNC popup +*popup.title: SSVNC popup ++ *popup*background: grey -*popup*font: -*-helvetica-bold-r-*-*-16-*-*-*-*-*-*-* +-*popup.buttonForm.Command.borderWidth: 0 +-*popup.buttonForm.Toggle.borderWidth: 0 ++ +*popup*font_old: -*-helvetica-bold-r-*-*-16-*-*-*-*-*-*-* ++ +*popup*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-* - *popup.buttonForm.Command.borderWidth: 0 - *popup.buttonForm.Toggle.borderWidth: 0 - ++ ++*popup.buttonForm*.Command.borderWidth: 0 ++ ++*popup.buttonForm*.Toggle.borderWidth: 0 ++ +*scaleN.title: 1/n scale ++ +*scaleN*background: grey ++ +*scaleN*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-* ++ +*scaleN.buttonForm.Command.borderWidth: 0 ++ +*scaleN.buttonForm.Toggle.borderWidth: 0 + +*quality.title: quality ++ +*quality*background: grey ++ +*quality*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-* ++ +*quality.buttonForm.Command.borderWidth: 0 ++ +*quality.buttonForm.Toggle.borderWidth: 0 + +*compress.title: compress ++ +*compress*background: grey ++ +*compress*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-* ++ +*compress.buttonForm.Command.borderWidth: 0 ++ +*compress.buttonForm.Toggle.borderWidth: 0 + + ! ! Translations on popup window - send key presses through ! -@@ -96,43 +131,344 @@ + + *popup.translations: #override <Message>WM_PROTOCOLS: HidePopup() ++ + *popup.buttonForm.translations: #override\n\ +- <KeyPress>: SendRFBEvent() HidePopup() ++ <KeyPress>: SendRFBEvent() HidePopup() + + + ! ! Popup buttons ! -*popupButtonCount: 8 +*popupButtonCount: 38 ++ +*popupButtonBreak: 19 *popup*button1.label: Dismiss popup --*popup*button1.translations: #override\n\ ++ + *popup*button1.translations: #override\n\ - <Btn1Down>,<Btn1Up>: HidePopup() -+*popup*button1.translations: #override\\n\ + <Btn1Down>,<Btn1Up>: HidePopup() *popup*button2.label: Quit viewer --*popup*button2.translations: #override\n\ ++ + *popup*button2.translations: #override\n\ - <Btn1Down>,<Btn1Up>: Quit() -+*popup*button2.translations: #override\\n\ + <Btn1Down>,<Btn1Up>: Quit() ++ ++*popup*button3.label: Full screen (also F9) -*popup*button3.label: Full screen -+*popup*button3.label: Full screen (also F9) *popup*button3.type: toggle --*popup*button3.translations: #override\n\ ++ + *popup*button3.translations: #override\n\ - <Visible>: SetFullScreenState()\n\ - <Btn1Down>,<Btn1Up>: toggle() HidePopup() ToggleFullScreen() -+*popup*button3.translations: #override\\n\ -+ <Visible>: SetFullScreenState()\\n\ ++ <Visible>: SetFullScreenState()\n\ + <Btn1Down>,<Btn1Up>: toggle() ToggleFullScreen() HidePopup() *popup*button4.label: Clipboard: local -> remote --*popup*button4.translations: #override\n\ ++ + *popup*button4.translations: #override\n\ - <Btn1Down>,<Btn1Up>: SelectionToVNC(always) HidePopup() -+*popup*button4.translations: #override\\n\ + <Btn1Down>,<Btn1Up>: SelectionToVNC(always) HidePopup() *popup*button5.label: Clipboard: local <- remote --*popup*button5.translations: #override\n\ ++ + *popup*button5.translations: #override\n\ - <Btn1Down>,<Btn1Up>: SelectionFromVNC(always) HidePopup() -+*popup*button5.translations: #override\\n\ + <Btn1Down>,<Btn1Up>: SelectionFromVNC(always) HidePopup() *popup*button6.label: Request refresh --*popup*button6.translations: #override\n\ ++ + *popup*button6.translations: #override\n\ - <Btn1Down>,<Btn1Up>: SendRFBEvent(fbupdate) HidePopup() -+*popup*button6.translations: #override\\n\ + <Btn1Down>,<Btn1Up>: SendRFBEvent(fbupdate) HidePopup() *popup*button7.label: Send ctrl-alt-del --*popup*button7.translations: #override\n\ ++ + *popup*button7.translations: #override\n\ - <Btn1Down>,<Btn1Up>: SendRFBEvent(keydown,Control_L)\ - SendRFBEvent(keydown,Alt_L)\ - SendRFBEvent(key,Delete)\ - SendRFBEvent(keyup,Alt_L)\ - SendRFBEvent(keyup,Control_L)\ - HidePopup() -+*popup*button7.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: SendRFBEvent(keydown,Control_L)\ -+ SendRFBEvent(keydown,Alt_L)\ -+ SendRFBEvent(key,Delete)\ -+ SendRFBEvent(keyup,Alt_L)\ -+ SendRFBEvent(keyup,Control_L)\ -+ HidePopup() ++ <Btn1Down>,<Btn1Up>: SendRFBEvent(keydown,Control_L) SendRFBEvent(keydown,Alt_L) SendRFBEvent(key,Delete) SendRFBEvent(keyup,Alt_L) SendRFBEvent(keyup,Control_L) HidePopup() *popup*button8.label: Send F8 --*popup*button8.translations: #override\n\ ++ + *popup*button8.translations: #override\n\ - <Btn1Down>,<Btn1Up>: SendRFBEvent(key,F8) HidePopup() -+*popup*button8.translations: #override\\n\ + <Btn1Down>,<Btn1Up>: SendRFBEvent(key,F8) HidePopup() + +*popup*button9.label: Send F9 -+*popup*button9.translations: #override\\n\ ++ ++*popup*button9.translations: #override\n\ + <Btn1Down>,<Btn1Up>: SendRFBEvent(key,F9) HidePopup() + +*popup*button10.label: ViewOnly ++ +*popup*button10.type: toggle -+*popup*button10.translations: #override\\n\ -+ <Visible>: SetViewOnlyState()\\n\ ++ ++*popup*button10.translations: #override\n\ ++ <Visible>: SetViewOnlyState()\n\ + <Btn1Down>,<Btn1Up>: toggle() ToggleViewOnly() HidePopup() + +*popup*button11.label: Disable Bell ++ +*popup*button11.type: toggle -+*popup*button11.translations: #override\\n\ -+ <Visible>: SetBellState()\\n\ ++ ++*popup*button11.translations: #override\n\ ++ <Visible>: SetBellState()\n\ + <Btn1Down>,<Btn1Up>: toggle() ToggleBell() HidePopup() + +*popup*button12.label: Cursor Shape ++ +*popup*button12.type: toggle -+*popup*button12.translations: #override\\n\ -+ <Visible>: SetCursorShapeState()\\n\ ++ ++*popup*button12.translations: #override\n\ ++ <Visible>: SetCursorShapeState()\n\ + <Btn1Down>,<Btn1Up>: toggle() ToggleCursorShape() HidePopup() + +*popup*button13.label: X11 Cursor ++ +*popup*button13.type: toggle -+*popup*button13.translations: #override\\n\ -+ <Visible>: SetX11CursorState()\\n\ ++ ++*popup*button13.translations: #override\n\ ++ <Visible>: SetX11CursorState()\n\ + <Btn1Down>,<Btn1Up>: toggle() ToggleX11Cursor() HidePopup() + +*popup*button14.label: Cursor Alphablend ++ +*popup*button14.type: toggle -+*popup*button14.translations: #override\\n\ -+ <Visible>: SetCursorAlphaState()\\n\ ++ ++*popup*button14.translations: #override\n\ ++ <Visible>: SetCursorAlphaState()\n\ + <Btn1Down>,<Btn1Up>: toggle() ToggleCursorAlpha() HidePopup() + +*popup*button15.label: Toggle Tight/ZRLE ++ +*popup*button15.type: toggle -+*popup*button15.translations: #override\\n\ -+ <Visible>: SetZRLEState()\\n\ ++ ++*popup*button15.translations: #override\n\ ++ <Visible>: SetZRLEState()\n\ + <Btn1Down>,<Btn1Up>: toggle() ToggleTightZRLE() HidePopup() + +*popup*button16.label: Toggle ZRLE/ZYWRLE ++ +*popup*button16.type: toggle -+*popup*button16.translations: #override\\n\ -+ <Visible>: SetZYWRLEState()\\n\ ++ ++*popup*button16.translations: #override\n\ ++ <Visible>: SetZYWRLEState()\n\ + <Btn1Down>,<Btn1Up>: toggle() ToggleZRLEZYWRLE() HidePopup() + +*popup*button17.label: Quality Level -+*popup*button17.translations: #override\\n\ ++ ++*popup*button17.translations: #override\n\ + <Btn1Down>,<Btn1Up>: HidePopup() ShowQuality() + +*popup*button18.label: Compress Level -+*popup*button18.translations: #override\\n\ ++ ++*popup*button18.translations: #override\n\ + <Btn1Down>,<Btn1Up>: HidePopup() ShowCompress() + +*popup*button19.label: Disable JPEG ++ +*popup*button19.type: toggle -+*popup*button19.translations: #override\\n\ -+ <Visible>: SetNOJPEGState()\\n\ ++ ++*popup*button19.translations: #override\n\ ++ <Visible>: SetNOJPEGState()\n\ + <Btn1Down>,<Btn1Up>: toggle() ToggleJPEG() HidePopup() + +*popup*button20.label: Full Color ++ +*popup*button20.type: toggle -+*popup*button20.translations: #override\\n\ -+ <Visible>: SetFullColorState()\\n\ ++ ++*popup*button20.translations: #override\n\ ++ <Visible>: SetFullColorState()\n\ + <Btn1Down>,<Btn1Up>: toggle() ToggleFullColor() HidePopup() + +*popup*button21.label: Grey Scale (16 & 8-bpp) ++ +*popup*button21.type: toggle -+*popup*button21.translations: #override\\n\ -+ <Visible>: SetGreyScaleState()\\n\ ++ ++*popup*button21.translations: #override\n\ ++ <Visible>: SetGreyScaleState()\n\ + <Btn1Down>,<Btn1Up>: toggle() ToggleGreyScale() HidePopup() + +*popup*button22.label: 16 bit color (BGR565) ++ +*popup*button22.type: toggle -+*popup*button22.translations: #override\\n\ -+ <Visible>: Set16bppState()\\n\ ++ ++*popup*button22.translations: #override\n\ ++ <Visible>: Set16bppState()\n\ + <Btn1Down>,<Btn1Up>: toggle() Toggle16bpp() HidePopup() + +*popup*button23.label: 8 bit color (BGR233) ++ +*popup*button23.type: toggle -+*popup*button23.translations: #override\\n\ -+ <Visible>: Set8bppState()\\n\ ++ ++*popup*button23.translations: #override\n\ ++ <Visible>: Set8bppState()\n\ + <Btn1Down>,<Btn1Up>: toggle() Toggle8bpp() HidePopup() + +*popup*button24.label: - 256 colors ++ +*popup*button24.type: toggle -+*popup*button24.translations: #override\\n\ -+ <Visible>: Set256ColorsState()\\n\ ++ ++*popup*button24.translations: #override\n\ ++ <Visible>: Set256ColorsState()\n\ + <Btn1Down>,<Btn1Up>: toggle() Toggle256Colors() HidePopup() + +*popup*button25.label: - 64 colors ++ +*popup*button25.type: toggle -+*popup*button25.translations: #override\\n\ -+ <Visible>: Set64ColorsState()\\n\ ++ ++*popup*button25.translations: #override\n\ ++ <Visible>: Set64ColorsState()\n\ + <Btn1Down>,<Btn1Up>: toggle() Toggle64Colors() HidePopup() + +*popup*button26.label: - 8 colors ++ +*popup*button26.type: toggle -+*popup*button26.translations: #override\\n\ -+ <Visible>: Set8ColorsState()\\n\ ++ ++*popup*button26.translations: #override\n\ ++ <Visible>: Set8ColorsState()\n\ + <Btn1Down>,<Btn1Up>: toggle() Toggle8Colors() HidePopup() + +*popup*button27.label: Set Y Crop (y-max) -+*popup*button27.translations: #override\\n\ ++ ++*popup*button27.translations: #override\n\ + <Btn1Down>,<Btn1Up>: HidePopup() SetYCrop() + +*popup*button28.label: Set Scrollbar Width -+*popup*button28.translations: #override\\n\ ++ ++*popup*button28.translations: #override\n\ + <Btn1Down>,<Btn1Up>: HidePopup() SetScbar() + +*popup*button29.label: UltraVNC Extensions: -+*popup*button29.translations: #override\\n\ ++ ++*popup*button29.translations: #override\n\ + <Btn1Down>,<Btn1Up>: HidePopup() + +*popup*button30.label: - Set 1/n Server Scale -+*popup*button30.translations: #override\\n\ ++ ++*popup*button30.translations: #override\n\ + <Btn1Down>,<Btn1Up>: HidePopup() ShowScaleN() + +*popup*button31.label: - Text Chat ++ +*popup*button31.type: toggle -+*popup*button31.translations: #override\\n\ -+ <Visible>: SetTextChatState()\\n\ ++ ++*popup*button31.translations: #override\n\ ++ <Visible>: SetTextChatState()\n\ + <Btn1Down>,<Btn1Up>: toggle() ToggleTextChat() HidePopup() + +*popup*button32.label: - File Transfer ++ +*popup*button32.type: toggle -+*popup*button32.translations: #override\\n\ -+ <Visible>: SetFileXferState()\\n\ ++ ++*popup*button32.translations: #override\n\ ++ <Visible>: SetFileXferState()\n\ + <Btn1Down>,<Btn1Up>: toggle() ToggleFileXfer() HidePopup() + +*popup*button33.label: - Single Window ++ +*popup*button33.type: toggle -+*popup*button33.translations: #override\\n\ -+ <Visible>: SetSingleWindowState()\\n\ ++ ++*popup*button33.translations: #override\n\ ++ <Visible>: SetSingleWindowState()\n\ + <Btn1Down>,<Btn1Up>: toggle() ToggleSingleWindow() HidePopup() + +*popup*button34.label: - Disable Remote Input ++ +*popup*button34.type: toggle -+*popup*button34.translations: #override\\n\ -+ <Visible>: SetServerInputState()\\n\ ++ ++*popup*button34.translations: #override\n\ ++ <Visible>: SetServerInputState()\n\ + <Btn1Down>,<Btn1Up>: toggle() ToggleServerInput() HidePopup() + +*popup*button35.label: ++ +*popup*button36.label: ++ +*popup*button37.label: ++ +*popup*button38.label: + +*scaleN*button0.label: Dismiss -+*scaleN*button0.translations: #override\\n\ ++ ++*scaleN*button0.translations: #override\n\ + <Btn1Down>,<Btn1Up>: HideScaleN() + +*scaleN*button1.label: 1/1 -+*scaleN*button1.translations: #override\\n\ -+ <Visible>: SetScaleNState(1)\\n\ ++ ++*scaleN*button1.translations: #override\n\ ++ <Visible>: SetScaleNState(1)\n\ + <Btn1Down>,<Btn1Up>: SetScaleN(1) HideScaleN() + +*scaleN*button2.label: 1/2 -+*scaleN*button2.translations: #override\\n\ -+ <Visible>: SetScaleNState(2)\\n\ ++ ++*scaleN*button2.translations: #override\n\ ++ <Visible>: SetScaleNState(2)\n\ + <Btn1Down>,<Btn1Up>: SetScaleN(2) HideScaleN() + +*scaleN*button3.label: 1/3 -+*scaleN*button3.translations: #override\\n\ -+ <Visible>: SetScaleNState(3)\\n\ ++ ++*scaleN*button3.translations: #override\n\ ++ <Visible>: SetScaleNState(3)\n\ + <Btn1Down>,<Btn1Up>: SetScaleN(3) HideScaleN() + +*scaleN*button4.label: 1/4 -+*scaleN*button4.translations: #override\\n\ -+ <Visible>: SetScaleNState(4)\\n\ ++ ++*scaleN*button4.translations: #override\n\ ++ <Visible>: SetScaleNState(4)\n\ + <Btn1Down>,<Btn1Up>: SetScaleN(4) HideScaleN() + +*scaleN*button5.label: 1/5 -+*scaleN*button5.translations: #override\\n\ -+ <Visible>: SetScaleNState(5)\\n\ ++ ++*scaleN*button5.translations: #override\n\ ++ <Visible>: SetScaleNState(5)\n\ + <Btn1Down>,<Btn1Up>: SetScaleN(5) HideScaleN() + +*scaleN*button6.label: Other -+*scaleN*button6.translations: #override\\n\ -+ <Visible>: SetScaleNState(6)\\n\ ++ ++*scaleN*button6.translations: #override\n\ ++ <Visible>: SetScaleNState(6)\n\ + <Btn1Down>,<Btn1Up>: HideScaleN() DoServerScale() + +*quality*buttonD.label: Dismiss -+*quality*buttonD.translations: #override\\n\ ++ ++*quality*buttonD.translations: #override\n\ + <Btn1Down>,<Btn1Up>: HideQuality() + +*quality*button0.label: 0 ++ +*quality*button0.type: toggle -+*quality*button0.translations: #override\\n\ -+ <Visible>: SetQualityState(0)\\n\ ++ ++*quality*button0.translations: #override\n\ ++ <Visible>: SetQualityState(0)\n\ + <Btn1Down>,<Btn1Up>: SetQuality(0) HideQuality() + +*quality*button1.label: 1 ++ +*quality*button1.type: toggle -+*quality*button1.translations: #override\\n\ -+ <Visible>: SetQualityState(1)\\n\ ++ ++*quality*button1.translations: #override\n\ ++ <Visible>: SetQualityState(1)\n\ + <Btn1Down>,<Btn1Up>: SetQuality(1) HideQuality() + +*quality*button2.label: 2 ++ +*quality*button2.type: toggle -+*quality*button2.translations: #override\\n\ -+ <Visible>: SetQualityState(2)\\n\ ++ ++*quality*button2.translations: #override\n\ ++ <Visible>: SetQualityState(2)\n\ + <Btn1Down>,<Btn1Up>: SetQuality(2) HideQuality() + +*quality*button3.label: 3 ++ +*quality*button3.type: toggle -+*quality*button3.translations: #override\\n\ -+ <Visible>: SetQualityState(3)\\n\ ++ ++*quality*button3.translations: #override\n\ ++ <Visible>: SetQualityState(3)\n\ + <Btn1Down>,<Btn1Up>: SetQuality(3) HideQuality() + +*quality*button4.label: 4 ++ +*quality*button4.type: toggle -+*quality*button4.translations: #override\\n\ -+ <Visible>: SetQualityState(4)\\n\ ++ ++*quality*button4.translations: #override\n\ ++ <Visible>: SetQualityState(4)\n\ + <Btn1Down>,<Btn1Up>: SetQuality(4) HideQuality() + +*quality*button5.label: 5 ++ +*quality*button5.type: toggle -+*quality*button5.translations: #override\\n\ -+ <Visible>: SetQualityState(5)\\n\ ++ ++*quality*button5.translations: #override\n\ ++ <Visible>: SetQualityState(5)\n\ + <Btn1Down>,<Btn1Up>: SetQuality(5) HideQuality() + +*quality*button6.label: 6 ++ +*quality*button6.type: toggle -+*quality*button6.translations: #override\\n\ -+ <Visible>: SetQualityState(6)\\n\ ++ ++*quality*button6.translations: #override\n\ ++ <Visible>: SetQualityState(6)\n\ + <Btn1Down>,<Btn1Up>: SetQuality(6) HideQuality() + +*quality*button7.label: 7 ++ +*quality*button7.type: toggle -+*quality*button7.translations: #override\\n\ -+ <Visible>: SetQualityState(7)\\n\ ++ ++*quality*button7.translations: #override\n\ ++ <Visible>: SetQualityState(7)\n\ + <Btn1Down>,<Btn1Up>: SetQuality(7) HideQuality() + +*quality*button8.label: 8 ++ +*quality*button8.type: toggle -+*quality*button8.translations: #override\\n\ -+ <Visible>: SetQualityState(8)\\n\ ++ ++*quality*button8.translations: #override\n\ ++ <Visible>: SetQualityState(8)\n\ + <Btn1Down>,<Btn1Up>: SetQuality(8) HideQuality() + +*quality*button9.label: 9 ++ +*quality*button9.type: toggle -+*quality*button9.translations: #override\\n\ -+ <Visible>: SetQualityState(9)\\n\ ++ ++*quality*button9.translations: #override\n\ ++ <Visible>: SetQualityState(9)\n\ + <Btn1Down>,<Btn1Up>: SetQuality(9) HideQuality() + +*compress*buttonD.label: Dismiss -+*compress*buttonD.translations: #override\\n\ ++ ++*compress*buttonD.translations: #override\n\ + <Btn1Down>,<Btn1Up>: HideCompress() + +*compress*button0.label: 0 -+*compress*button0.translations: #override\\n\ -+ <Visible>: SetCompressState(0)\\n\ ++ ++*compress*button0.translations: #override\n\ ++ <Visible>: SetCompressState(0)\n\ + <Btn1Down>,<Btn1Up>: SetCompress(0) HideCompress() + +*compress*button1.label: 1 -+*compress*button1.translations: #override\\n\ -+ <Visible>: SetCompressState(1)\\n\ ++ ++*compress*button1.translations: #override\n\ ++ <Visible>: SetCompressState(1)\n\ + <Btn1Down>,<Btn1Up>: SetCompress(1) HideCompress() + +*compress*button2.label: 2 -+*compress*button2.translations: #override\\n\ -+ <Visible>: SetCompressState(2)\\n\ ++ ++*compress*button2.translations: #override\n\ ++ <Visible>: SetCompressState(2)\n\ + <Btn1Down>,<Btn1Up>: SetCompress(2) HideCompress() + +*compress*button3.label: 3 -+*compress*button3.translations: #override\\n\ -+ <Visible>: SetCompressState(3)\\n\ ++ ++*compress*button3.translations: #override\n\ ++ <Visible>: SetCompressState(3)\n\ + <Btn1Down>,<Btn1Up>: SetCompress(3) HideCompress() + +*compress*button4.label: 4 -+*compress*button4.translations: #override\\n\ -+ <Visible>: SetCompressState(4)\\n\ ++ ++*compress*button4.translations: #override\n\ ++ <Visible>: SetCompressState(4)\n\ + <Btn1Down>,<Btn1Up>: SetCompress(4) HideCompress() + +*compress*button5.label: 5 -+*compress*button5.translations: #override\\n\ -+ <Visible>: SetCompressState(5)\\n\ ++ ++*compress*button5.translations: #override\n\ ++ <Visible>: SetCompressState(5)\n\ + <Btn1Down>,<Btn1Up>: SetCompress(5) HideCompress() + +*compress*button6.label: 6 -+*compress*button6.translations: #override\\n\ -+ <Visible>: SetCompressState(6)\\n\ ++ ++*compress*button6.translations: #override\n\ ++ <Visible>: SetCompressState(6)\n\ + <Btn1Down>,<Btn1Up>: SetCompress(6) HideCompress() + +*compress*button7.label: 7 -+*compress*button7.translations: #override\\n\ -+ <Visible>: SetCompressState(7)\\n\ ++ ++*compress*button7.translations: #override\n\ ++ <Visible>: SetCompressState(7)\n\ + <Btn1Down>,<Btn1Up>: SetCompress(7) HideCompress() + +*compress*button8.label: 8 -+*compress*button8.translations: #override\\n\ -+ <Visible>: SetCompressState(8)\\n\ ++ ++*compress*button8.translations: #override\n\ ++ <Visible>: SetCompressState(8)\n\ + <Btn1Down>,<Btn1Up>: SetCompress(8) HideCompress() + +*compress*button9.label: 9 -+*compress*button9.translations: #override\\n\ -+ <Visible>: SetCompressState(9)\\n\ ++ ++*compress*button9.translations: #override\n\ ++ <Visible>: SetCompressState(9)\n\ + <Btn1Down>,<Btn1Up>: SetCompress(9) HideCompress() + diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/vncviewer/argsresources.c --- vnc_unixsrc.orig/vncviewer/argsresources.c 2007-02-04 17:10:31.000000000 -0500 -+++ vnc_unixsrc/vncviewer/argsresources.c 2008-04-28 21:30:05.000000000 -0400 -@@ -31,7 +31,7 @@ ++++ vnc_unixsrc/vncviewer/argsresources.c 2008-09-06 21:48:37.000000000 -0400 +@@ -31,9 +31,9 @@ char *fallback_resources[] = { - "Vncviewer.title: TightVNC: %s", -+ "Vncviewer.title: SSVNC: %s - Press F8 for Menu", ++ "Ssvnc.title: SSVNC: %s - Press F8 for Menu", - "Vncviewer.translations:\ +- "Vncviewer.translations:\ ++ "Ssvnc.translations:\ <Enter>: SelectionToVNC()\\n\ + <Leave>: SelectionFromVNC()", + @@ -45,8 +45,58 @@ "*viewport.useRight: True", "*viewport*Scrollbar*thumb: None", + "*viewport.horizontal.height: 6 ", + "*viewport.vertical.width: 6 ", -+ "vncviewer*viewport.horizontal.height: 6 ", -+ "vncviewer*viewport.vertical.width: 6 ", ++ "ssvnc*viewport.horizontal.height: 6 ", ++ "ssvnc*viewport.vertical.width: 6 ", + + "*viewport.horizontal.translations: #override\\n\ + <KeyPress>Right: StartScroll(Forward)\\n\ @@ -589,7 +810,22 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v "*popup*button3.type: toggle", "*popup*button3.translations: #override\\n\ <Visible>: SetFullScreenState()\\n\ -@@ -115,6 +200,305 @@ +@@ -105,16 +190,315 @@ + "*popup*button7.label: Send ctrl-alt-del", + "*popup*button7.translations: #override\\n\ + <Btn1Down>,<Btn1Up>: SendRFBEvent(keydown,Control_L)\ +- SendRFBEvent(keydown,Alt_L)\ +- SendRFBEvent(key,Delete)\ +- SendRFBEvent(keyup,Alt_L)\ +- SendRFBEvent(keyup,Control_L)\ +- HidePopup()", ++ SendRFBEvent(keydown,Alt_L)\ ++ SendRFBEvent(key,Delete)\ ++ SendRFBEvent(keyup,Alt_L)\ ++ SendRFBEvent(keyup,Control_L)\ ++ HidePopup()", + + "*popup*button8.label: Send F8", "*popup*button8.translations: #override\\n\ <Btn1Down>,<Btn1Up>: SendRFBEvent(key,F8) HidePopup()", @@ -895,6 +1131,15 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v NULL }; +@@ -124,7 +508,7 @@ + * from a dialog box. + */ + +-char vncServerHost[256]; ++char vncServerHost[1024]; + int vncServerPort = 0; + + @@ -135,6 +519,7 @@ */ @@ -1158,22 +1403,28 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v }; -@@ -302,8 +846,8 @@ +@@ -302,11 +846,13 @@ void usage(void) { - fprintf(stderr, - "TightVNC viewer version 1.3dev7\n" + fprintf(stdout, -+ "TightVNC viewer version 1.3.9 (SSVNC)\n" ++ "SSVNC Viewer (based on TightVNC viewer version 1.3.9)\n" "\n" "Usage: %s [<OPTIONS>] [<HOST>][:<DISPLAY#>]\n" " %s [<OPTIONS>] [<HOST>][::<PORT#>]\n" -@@ -332,10 +876,154 @@ ++ " %s [<OPTIONS>] exec=[CMD ARGS...]\n" ++ " %s [<OPTIONS>] /path/to/unix/socket\n" + " %s [<OPTIONS>] -listen [<DISPLAY#>]\n" + " %s -help\n" + "\n" +@@ -332,10 +878,185 @@ " -autopass\n" "\n" "Option names may be abbreviated, e.g. -bgr instead of -bgr233.\n" - "See the manual page for more information." +- "\n", programName, programName, programName, programName); + "See the manual page for more information.\n" + "\n" + "\n" @@ -1185,6 +1436,28 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v + "\n" + " Note: F9 is shortcut to Toggle FullScreen mode.\n" + "\n" ++ " Note: In -listen mode set the env var. SSVNC_MULTIPLE_LISTEN=1\n" ++ " to allow more than one incoming VNC server at a time.\n" ++ " This is the same as -multilisten described below.\n" ++ "\n" ++ " Note: If the host:port is specified as \"exec=command args...\"\n" ++ " then instead of making a TCP/IP socket connection to the\n" ++ " remote VNC server, \"command args...\" is executed and the\n" ++ " viewer is attached to its stdio. This enables tunnelling\n" ++ " established via an external command, e.g. an stunnel(8)\n" ++ " that does not involve a listening socket. This mode does\n" ++ " not work for -listen reverse connections.\n" ++ "\n" ++ " Note: If the host:port contains a '/' it is interpreted as a\n" ++ " unix-domain socket (AF_LOCAL insead of AF_INET)\n" ++ "\n" ++ " -multilisten As in -listen (reverse connection listening)\n" ++ " except allow more than one incoming VNC server to\n" ++ " be connected at a time. The default of only one\n" ++ " at a time tries to play it safe by not allowing\n" ++ " anyone on the network to put (many) desktops on\n" ++ " your screen during a long window of time.\n" ++ "\n" + " -use64 In -bgr233 mode, use 64 colors instead of 256.\n" + " -bgr222 Same as -use64.\n" + "\n" @@ -1278,8 +1551,17 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v + " -repeater str This is for use with UltraVNC repeater proxy described\n" + " here: http://www.uvnc.com/addons/repeater.html. The \"str\"\n" + " is the ID string to be sent to the repeater. E.g. ID:1234\n" -+ " In this case host:dpy on the command line is the repeater\n" -+ " server, not the VNC server. The repeater will connect you.\n" ++ " It can also be the hostname and port or display of the VNC\n" ++ " server, e.g. 12.34.56.78:0 or snoopy.com:1. Note that when\n" ++ " using -repeater, the host:dpy on the cmdline is the repeater\n" ++ " server, NOT the VNC server. The repeater will connect you.\n" ++ " Example: vncviewer ... -repeater ID:3333 repeat.host:5900\n" ++ " Example: vncviewer ... -repeater vhost:0 repeat.host:5900\n" ++ "\n" ++ " -printres Print out the Ssvnc X resources (appdefaults) and then exit\n" ++ " You can save them to a file and customize them (e.g. the\n" ++ " keybindings and Popup menu) Then point to the file via\n" ++ " XENVIRONMENT or XAPPLRESDIR.\n" + "\n" + " New Popup actions:\n" + "\n" @@ -1316,7 +1598,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v + " Note: the Ultravnc extensions only apply to servers that support\n" + " them. x11vnc/libvncserver supports some of them.\n" + "\n" - "\n", programName, programName, programName, programName); ++ "\n", programName, programName, programName, programName, programName, programName); exit(1); } +#if 0 @@ -1325,7 +1607,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v /* -@@ -350,6 +1038,7 @@ +@@ -350,6 +1071,7 @@ int i; char *vncServerName, *colonPos; int len, portOffset; @@ -1333,7 +1615,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v /* Turn app resource specs into our appData structure for the rest of the program to use */ -@@ -357,6 +1046,23 @@ +@@ -357,6 +1079,23 @@ XtGetApplicationResources(toplevel, &appData, appDataResourceList, XtNumber(appDataResourceList), 0, 0); @@ -1357,7 +1639,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v /* Add our actions to the actions table so they can be used in widget resource specs */ -@@ -376,6 +1082,10 @@ +@@ -376,6 +1115,10 @@ return; } @@ -1368,7 +1650,20 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v if (argc == 1) { vncServerName = DoServerDialog(); appData.passwordDialog = True; -@@ -414,6 +1124,13 @@ +@@ -396,7 +1139,11 @@ + } + + colonPos = strchr(vncServerName, ':'); +- if (colonPos == NULL) { ++ if (strstr(vncServerName, "exec=") == vncServerName) { ++ /* special exec-external-command case */ ++ strcpy(vncServerHost, vncServerName); ++ vncServerPort = SERVER_PORT_OFFSET; ++ } else if (colonPos == NULL) { + /* No colon -- use default port number */ + strcpy(vncServerHost, vncServerName); + vncServerPort = SERVER_PORT_OFFSET; +@@ -414,6 +1161,13 @@ if (!len || strspn(colonPos + 1, "0123456789") != len) { usage(); } @@ -2147,11 +2442,22 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/cursor.c vnc_unixsrc/vncviewe - diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncviewer/desktop.c --- vnc_unixsrc.orig/vncviewer/desktop.c 2004-05-28 13:29:29.000000000 -0400 -+++ vnc_unixsrc/vncviewer/desktop.c 2008-02-02 18:48:22.000000000 -0500 -@@ -28,21 +28,29 @@ ++++ vnc_unixsrc/vncviewer/desktop.c 2008-09-05 19:12:25.000000000 -0400 +@@ -28,21 +28,40 @@ #include <X11/extensions/XShm.h> #endif ++/* we don't have Xvlib working yet... not all cards supply RGB @ 32bpp */ ++#define XVLIB__dont ++#ifdef XVLIB ++#include <X11/extensions/Xvlib.h> ++XvImage *xv_image; ++XvPortID xv_port = None; ++int xv_width = 640; ++int xv_height = 480; ++#endif ++ ++ +#include <X11/cursorfont.h> + GC gc; @@ -2180,16 +2486,68 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview static XtResource desktopBackingStoreResources[] = { { XtNbackingStore, XtCBackingStore, XtRBackingStore, sizeof(int), 0, -@@ -50,6 +58,86 @@ +@@ -50,6 +69,138 @@ }, }; ++#ifdef XVLIB ++void setup_xv(void) { ++ int a, p, f; ++ int num_adaptors; ++ XvAdaptorInfo *adaptor_info; ++ XvImageFormatValues *formats, *format = NULL; ++ int nformats; ++ ++ if (xv_port != None) { ++ return; ++ } ++ XvQueryAdaptors (dpy, RootWindow(dpy, DefaultScreen(dpy)), &num_adaptors, &adaptor_info); ++ for (a = 0; a < num_adaptors; a++) { ++ fprintf(stderr, "Adapator \"%s\" has %d ports\n", ++ adaptor_info[a].name, ++ adaptor_info[a].num_ports); ++ } ++ for (a = 0; a < num_adaptors; a++) { ++ for (p = 0; a < adaptor_info[a].num_ports; p++) { ++ if (XvGrabPort(dpy, adaptor_info[a].base_id + p, CurrentTime) == Success) { ++ xv_port = adaptor_info[a].base_id + p; ++ break; ++ } ++ } ++ } ++ formats = XvListImageFormats (dpy, xv_port, &nformats); ++ for (f=0; f < nformats; f++) { ++fprintf(stderr, "f=%d\n", f); ++fprintf(stderr, "formats[f].type: %d\n", formats[f].type); ++fprintf(stderr, "formats[f].format: %d\n", formats[f].format); ++fprintf(stderr, "formats[f].bits_per_pixel: %d\n", formats[f].bits_per_pixel); ++fprintf(stderr, "formats[f].num_planes: %d\n", formats[f].num_planes); ++fprintf(stderr, "formats[f].scanline_order: %d\n", formats[f].scanline_order); ++fprintf(stderr, "formats[f].component_order: %s\n", formats[f].component_order); ++ if (formats[f].type != XvRGB) continue; ++ if (formats[f].format != XvPacked) continue; ++ if (formats[f].bits_per_pixel != 32) continue; ++ if (formats[f].num_planes != 1) continue; ++ if (formats[f].scanline_order != XvTopToBottom) continue; ++ if (strcmp (formats[f].component_order, "BGRX") != 0) continue; ++ format = &formats[f]; ++ break; ++ } ++// fprintf(stderr, "y_sample_bits %d u_sample_bits %d v_sample_bits %d\n", ++// format->y_sample_bits, format->u_sample_bits, format->v_sample_bits); ++// fprintf(stderr, "component_order: %s\n", format->component_order); ++ ++ xv_image = XvCreateImage (dpy, xv_port, format->id, NULL, si.framebufferWidth, si.framebufferHeight); ++} ++#endif ++ +void create_image() { + image = NULL; + image_ycrop = NULL; + +//fprintf(stderr, "useShm: %d\n", appData.useShm); + ++ +#ifdef MITSHM + if (appData.useShm) { + image = CreateShmImage(0); @@ -2267,31 +2625,28 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview /* * DesktopInitBeforeRealization creates the "desktop" widget and the viewport -@@ -59,89 +147,303 @@ +@@ -59,89 +210,320 @@ void DesktopInitBeforeRealization() { - int i; -- ++ int i; + - form = XtVaCreateManagedWidget("form", formWidgetClass, toplevel, - XtNborderWidth, 0, - XtNdefaultDistance, 0, NULL); -+ int i; ++ form = XtVaCreateManagedWidget("form", formWidgetClass, toplevel, ++ XtNborderWidth, 0, XtNdefaultDistance, 0, NULL); - viewport = XtVaCreateManagedWidget("viewport", viewportWidgetClass, form, - XtNborderWidth, 0, - NULL); -+ form = XtVaCreateManagedWidget("form", formWidgetClass, toplevel, -+ XtNborderWidth, 0, XtNdefaultDistance, 0, NULL); ++ viewport = XtVaCreateManagedWidget("viewport", viewportWidgetClass, form, ++ XtNborderWidth, 0, NULL); - desktop = XtVaCreateManagedWidget("desktop", coreWidgetClass, viewport, - XtNborderWidth, 0, - NULL); -+ viewport = XtVaCreateManagedWidget("viewport", viewportWidgetClass, form, -+ XtNborderWidth, 0, NULL); - -- XtVaSetValues(desktop, XtNwidth, si.framebufferWidth, -- XtNheight, si.framebufferHeight, NULL); + desktop = XtVaCreateManagedWidget("desktop", coreWidgetClass, viewport, + XtNborderWidth, 0, NULL); + @@ -2321,20 +2676,25 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview + old_width = si.framebufferWidth; + old_height = si.framebufferHeight; -- XtAddEventHandler(desktop, LeaveWindowMask|ExposureMask, -- True, HandleBasicDesktopEvent, NULL); +- XtVaSetValues(desktop, XtNwidth, si.framebufferWidth, +- XtNheight, si.framebufferHeight, NULL); + for (i = 0; i < 256; i++) { + modifierPressed[i] = False; + } -- for (i = 0; i < 256; i++) -- modifierPressed[i] = False; +- XtAddEventHandler(desktop, LeaveWindowMask|ExposureMask, +- True, HandleBasicDesktopEvent, NULL); + create_image(); +} -- image = NULL; +- for (i = 0; i < 256; i++) +- modifierPressed[i] = False; +static Widget scrollbar_y = NULL; +- image = NULL; ++static int xsst = 2; ++#include <X11/Xaw/Scrollbar.h> + -#ifdef MITSHM - if (appData.useShm) { - image = CreateShmImage(); @@ -2342,9 +2702,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview - appData.useShm = False; - } -#endif -+static int xsst = 2; -+#include <X11/Xaw/Scrollbar.h> - +- - if (!image) { - image = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL, - si.framebufferWidth, si.framebufferHeight, @@ -2370,7 +2728,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview + float t = 0.0; + XtVaSetValues(w, XtNtopOfThumb, &t, NULL); + } -+} + } +static XtCallbackProc Jumped(Widget w, XtPointer closure, XtPointer call_data) { + float top = *((float *) call_data); + Position x, y; @@ -2388,9 +2746,9 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview + XtVaSetValues(w, XtNtopOfThumb, *(XtArgVal*)&t, XtNshown, *(XtArgVal*)&s, NULL); + } + } - } - - ++} ++ ++ +extern double dnow(void); + +void check_things() { @@ -2452,13 +2810,13 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview + if (now <= last + 1.0) { + return; + } -+ + + dpyWidth = WidthOfScreen(DefaultScreenOfDisplay(dpy)); + dpyHeight = HeightOfScreen(DefaultScreenOfDisplay(dpy)); + + last = dnow(); +} -+ + /* * DesktopInitAfterRealization does things which require the X windows to * exist. It creates some GCs and sets the dot cursor. @@ -2541,8 +2899,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview + appData.useBackingstore = False; + } + } - -- XChangeWindowAttributes(dpy, desktopWin, valuemask, &attr); ++ + if (appData.useBackingstore) { + XtVaGetApplicationResources(desktop, (XtPointer)&attr.backing_store, + desktopBackingStoreResources, 1, NULL); @@ -2594,10 +2951,28 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview + FreeX11Cursor(); + FreeSoftCursor(); +} -+ + +- XChangeWindowAttributes(dpy, desktopWin, valuemask, &attr); +void put_image(int src_x, int src_y, int dst_x, int dst_y, int width, + int height) { + ++#ifdef XVLIB ++ if (xv_width > 0) { ++ if (xv_port == None) { ++ setup_xv(); ++ } ++ if (xv_port != None) { ++ double ratw = (double) xv_width / si.framebufferWidth; ++ double rath = (double) xv_height / si.framebufferHeight; ++ XvPutImage(dpy, xv_port, desktopWin, gc, xv_image, ++ src_x, src_y, width, height, ++ (int) ratw * dst_x, (int) rath * dst_y, ++ (int) ratw * width, (int) rath * height); ++ return; ++ } ++ } ++#endif ++ +#ifdef MITSHM + if (appData.useShm) { + if (image_ycrop == NULL) { @@ -2634,7 +3009,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview } -@@ -152,39 +454,53 @@ +@@ -152,39 +534,53 @@ static void HandleBasicDesktopEvent(Widget w, XtPointer ptr, XEvent *ev, Boolean *cont) { @@ -2709,7 +3084,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview } -@@ -201,6 +517,13 @@ +@@ -201,6 +597,13 @@ * button2 down, 3 for both, etc). */ @@ -2723,7 +3098,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview void SendRFBEvent(Widget w, XEvent *ev, String *params, Cardinal *num_params) { -@@ -208,12 +531,62 @@ +@@ -208,12 +611,62 @@ char keyname[256]; int buttonMask, x, y; @@ -2736,8 +3111,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview + return; + } + } - -- if (appData.viewOnly) return; ++ + if (selectingSingleWindow && ev->type == ButtonPress) { + selectingSingleWindow = False; + SendSingleWindow(ev->xbutton.x, ev->xbutton.y); @@ -2748,7 +3122,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview + } + return; + } -+ + +- if (appData.viewOnly) return; + if (appData.viewOnly) { + int W = si.framebufferWidth; + int H = si.framebufferHeight; @@ -2791,7 +3166,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview if (*num_params != 0) { if (strncasecmp(params[0],"key",3) == 0) { -@@ -329,26 +702,161 @@ +@@ -329,26 +782,161 @@ * CreateDotCursor. */ @@ -2969,7 +3344,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview } -@@ -359,38 +867,35 @@ +@@ -359,38 +947,35 @@ void CopyDataToScreen(char *buf, int x, int y, int width, int height) { @@ -3035,7 +3410,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview } -@@ -401,62 +906,228 @@ +@@ -401,62 +986,228 @@ static void CopyBGR233ToScreen(CARD8 *buf, int x, int y, int width, int height) { @@ -3853,6 +4228,20 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/fullscreen.c vnc_unixsrc/vncv +} + + +diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/h2html.pl vnc_unixsrc/vncviewer/h2html.pl +--- vnc_unixsrc.orig/vncviewer/h2html.pl 1969-12-31 19:00:00.000000000 -0500 ++++ vnc_unixsrc/vncviewer/h2html.pl 2008-08-30 20:34:45.000000000 -0400 +@@ -0,0 +1,10 @@ ++#!/usr/bin/perl ++ ++open(HELP, "./vncviewer -help|"); ++ ++while (<HELP>) { ++ $_ =~ s/&/&/g; ++ $_ =~ s/</</g; ++ $_ =~ s/>/>/g; ++ print; ++} diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/hextile.c vnc_unixsrc/vncviewer/hextile.c --- vnc_unixsrc.orig/vncviewer/hextile.c 2007-02-17 22:33:46.000000000 -0500 +++ vnc_unixsrc/vncviewer/hextile.c 2007-02-17 22:48:39.000000000 -0500 @@ -3980,8 +4369,17 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/hextile.c vnc_unixsrc/vncview +#undef FillRectangle diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/listen.c vnc_unixsrc/vncviewer/listen.c --- vnc_unixsrc.orig/vncviewer/listen.c 2001-01-16 03:07:57.000000000 -0500 -+++ vnc_unixsrc/vncviewer/listen.c 2007-03-23 22:30:46.000000000 -0400 -@@ -111,13 +111,14 @@ ++++ vnc_unixsrc/vncviewer/listen.c 2008-09-06 18:17:58.000000000 -0400 +@@ -58,6 +58,8 @@ + int n; + int i; + char *displayname = NULL; ++ int children = 0; ++ int totalconn = 0, maxconn = 0; + + listenSpecified = True; + +@@ -111,20 +113,36 @@ getFlashFont(d); listenSocket = ListenAtTcpPort(listenPort); @@ -3999,8 +4397,31 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/listen.c vnc_unixsrc/vncviewe + fprintf(stderr,"%s -listen: Cmdline errors are not reported until " "a connection comes in.\n", programName); ++ /* this will only work if X events drives this loop -- they don't */ ++ if (getenv("SSVNC_MAX_LISTEN")) { ++ maxconn = atoi(getenv("SSVNC_MAX_LISTEN")); ++ } ++ while (True) { -@@ -132,12 +133,13 @@ + + /* reap any zombies */ + int status, pid; +- while ((pid= wait3(&status, WNOHANG, (struct rusage *)0))>0); ++ while ((pid = wait3(&status, WNOHANG, (struct rusage *)0))>0) { ++ if (pid > 0 && children > 0) { ++ children--; ++ /* this will only work if X events drives this loop -- they don't */ ++ if (maxconn > 0 && totalconn >= maxconn) { ++ fprintf(stderr,"%s -listen: Finished final connection %d\n", ++ programName, maxconn); ++ exit(0); ++ } ++ } ++ } + + /* discard any X events */ + while (XCheckIfEvent(d, &ev, AllXEventsPredicate, NULL)) +@@ -132,12 +150,24 @@ FD_ZERO(&fds); @@ -4011,19 +4432,69 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/listen.c vnc_unixsrc/vncviewe select(FD_SETSIZE, &fds, NULL, NULL, NULL); ++ while ((pid = wait3(&status, WNOHANG, (struct rusage *)0))>0) { ++ if (pid > 0 && children > 0) { ++ children--; ++ if (maxconn > 0 && totalconn >= maxconn) { ++ fprintf(stderr,"%s -listen: Finished final connection %d\n", ++ programName, maxconn); ++ exit(0); ++ } ++ } ++ } ++ +#if 0 if (FD_ISSET(flashSocket, &fds)) { sock = AcceptTcpConnection(flashSocket); -@@ -151,6 +153,7 @@ +@@ -151,11 +181,35 @@ } close(sock); } +#endif if (FD_ISSET(listenSocket, &fds)) { - rfbsock = AcceptTcpConnection(listenSocket); -@@ -182,6 +185,10 @@ +- rfbsock = AcceptTcpConnection(listenSocket); +- if (rfbsock < 0) exit(1); +- if (!SetNonBlocking(rfbsock)) exit(1); ++ int multi_ok = 0; ++ char *sml = getenv("SSVNC_MULTIPLE_LISTEN"); ++ ++ rfbsock = AcceptTcpConnection(listenSocket); ++ ++ if (sml != NULL) { ++ if (strcmp(sml, "") && strcmp(sml, "0")) { ++ multi_ok = 1; ++ } ++ } ++ ++ if (rfbsock < 0) exit(1); ++ if (!SetNonBlocking(rfbsock)) exit(1); ++ ++ if (children > 0 && !multi_ok) { ++ fprintf(stderr,"\n"); ++ fprintf(stderr,"%s: denying extra incoming connection (%d already)\n", ++ programName, children); ++ fprintf(stderr,"%s: to override: use '-multilisten' or set SSVNC_MULTIPLE_LISTEN=1\n", ++ programName); ++ fprintf(stderr,"\n"); ++ close(rfbsock); ++ rfbsock = -1; ++ continue; ++ } ++ totalconn++; + + XCloseDisplay(d); + +@@ -175,6 +229,7 @@ + + default: + /* parent - go round and listen again */ ++ children++; + close(rfbsock); + if (!(d = XOpenDisplay(displayname))) { + fprintf(stderr,"%s: unable to open display %s\n", +@@ -182,6 +237,10 @@ exit(1); } getFlashFont(d); @@ -4047,7 +4518,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/misc.c vnc_unixsrc/vncviewer/ static int diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/popup.c vnc_unixsrc/vncviewer/popup.c --- vnc_unixsrc.orig/vncviewer/popup.c 2000-06-11 08:00:53.000000000 -0400 -+++ vnc_unixsrc/vncviewer/popup.c 2008-02-17 12:50:06.000000000 -0500 ++++ vnc_unixsrc/vncviewer/popup.c 2008-09-05 21:59:15.000000000 -0400 @@ -25,15 +25,44 @@ #include <X11/Xaw/Form.h> @@ -4095,7 +4566,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/popup.c vnc_unixsrc/vncviewer XSetWMProtocols(dpy, XtWindow(popup), &wmDeleteWindow, 1); } -@@ -52,42 +81,448 @@ +@@ -52,42 +81,453 @@ }; void @@ -4342,6 +4813,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/popup.c vnc_unixsrc/vncviewer + +extern int use_loopback; +time_t start_listen = 0; ++pid_t java_helper = 0; + +void ShowFile(Widget w, XEvent *event, String *params, Cardinal *num_params) { + int i, port0 = 7200, port, sock = -1; @@ -4355,6 +4827,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/popup.c vnc_unixsrc/vncviewer + fprintf(stderr, "Cannot find UltraVNC FTP jar file.\n"); + return; + } ++ + use_loopback = 1; + for (i = 0; i < 100; i++) { + port = port0 + i; @@ -4365,6 +4838,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/popup.c vnc_unixsrc/vncviewer + } + } + use_loopback = 0; ++ + if (sock >= 0) { + int st; + pid_t pid = fork(); @@ -4381,7 +4855,9 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/popup.c vnc_unixsrc/vncviewer + system(cmd); + exit(0); + } ++ fprintf(stderr, "java helper pid is: %d\n", (int) pid); + waitpid(pid, &st, 0); ++ java_helper = pid; + start_listen = time(NULL); + } + free(cmd); @@ -4550,7 +5026,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/popup.c vnc_unixsrc/vncviewer + entry = XtVaCreateManagedWidget("entry", asciiTextWidgetClass, myform, + XtNresize, XawtextResizeWidth, XtNresizable, True, XtNwrap, XawtextWrapWord, + XtNscrollHorizontal, XawtextScrollNever, XtNscrollVertical, XawtextScrollNever, -+ XtNheight, 20, XtNwidth, 400, XtNfromVert, text, ++ XtNheight, 20, XtNwidth, 400, XtNfromVert, text, XtNeditType, XawtextEdit, + XtNdisplayCaret, True, XtNeditType, XawtextEdit, NULL); + + dismiss = XtVaCreateManagedWidget("dismiss", commandWidgetClass, myform, XtNlabel, "Close Chat", XtNfromVert, entry, NULL); @@ -4586,9 +5062,17 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/popup_ad vnc_unixsrc/vncviewe + print; +} diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncviewer/rfbproto.c ---- vnc_unixsrc.orig/vncviewer/rfbproto.c 2004-03-11 13:14:39.000000000 -0500 -+++ vnc_unixsrc/vncviewer/rfbproto.c 2008-05-11 11:20:45.000000000 -0400 -@@ -57,6 +57,44 @@ +--- vnc_unixsrc.orig/vncviewer/rfbproto.c 2008-09-05 19:51:24.000000000 -0400 ++++ vnc_unixsrc/vncviewer/rfbproto.c 2008-09-05 21:51:53.000000000 -0400 +@@ -23,6 +23,7 @@ + * rfbproto.c - functions to deal with client side of RFB protocol. + */ + ++#include <sys/stat.h> + #include <unistd.h> + #include <errno.h> + #include <pwd.h> +@@ -57,6 +58,44 @@ static Bool HandleTight16(int rx, int ry, int rw, int rh); static Bool HandleTight32(int rx, int ry, int rw, int rh); @@ -4633,7 +5117,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie static void ReadConnFailedReason(void); static long ReadCompactLen (void); -@@ -68,6 +106,10 @@ +@@ -68,6 +107,10 @@ int compressedLen); @@ -4644,7 +5128,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie int rfbsock; char *desktopName; rfbPixelFormat myFormat; -@@ -177,6 +219,9 @@ +@@ -177,6 +220,9 @@ sig_rfbEncodingPointerPos, "Pointer position update"); CapsAdd(encodingCaps, rfbEncodingLastRect, rfbTightVncVendor, sig_rfbEncodingLastRect, "LastRect protocol extension"); @@ -4654,40 +5138,125 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } -@@ -187,21 +232,21 @@ +@@ -187,21 +233,104 @@ Bool ConnectToRFBServer(const char *hostname, int port) { - unsigned int host; -+ unsigned int host; - +- - if (!StringToIPAddr(hostname, &host)) { - fprintf(stderr,"Couldn't convert '%s' to host address\n", hostname); - return False; - } -+ if (!StringToIPAddr(hostname, &host)) { -+ fprintf(stderr,"Couldn't convert '%s' to host address\n", hostname); -+ return False; -+ } - +- - rfbsock = ConnectToTcpAddr(host, port); -+ rfbsock = ConnectToTcpAddr(host, port); ++ unsigned int host; ++ char *q, *cmd = NULL; ++ Bool setnb; ++ struct stat sb; ++ ++ if (strstr(hostname, "exec=") == hostname) { ++ cmd = strdup(hostname); ++ q = strchr(cmd, '='); ++ *q = ' '; ++ if (getenv("SSVNC_BASEDIR")) { ++ char *base = getenv("SSVNC_BASEDIR"); ++ char *newcmd = (char *)malloc(strlen(base) + strlen(cmd) + 1000); ++ sprintf(newcmd, "%s/unwrap.so", base); ++ if (stat(newcmd, &sb) == 0) { ++#if (defined(__MACH__) && defined(__APPLE__)) ++ sprintf(newcmd, "DYLD_FORCE_FLAT_NAMESPACE=1; export DYLD_FORCE_FLAT_NAMESPACE; DYLD_INSERT_LIBRARIES='%s/unwrap.so'; export DYLD_INSERT_LIBRARIES; %s", base, cmd); ++#else ++ sprintf(newcmd, "LD_PRELOAD='%s/unwrap.so'; export LD_PRELOAD; %s", base, cmd); ++#endif ++ cmd = newcmd; ++ } ++ } ++ } - if (rfbsock < 0) { - fprintf(stderr,"Unable to connect to VNC server\n"); - return False; - } -+ if (rfbsock < 0) { -+ fprintf(stderr,"Unable to connect to VNC server\n"); -+ return False; ++ if (cmd != NULL) { ++ int sfd[2]; ++ pid_t pid; ++ ++ fprintf(stderr, "exec-cmd: %s\n", cmd); ++ ++ if (! SocketPair(sfd)) { ++ return False; ++ } ++ if (0) { ++ fprintf(stderr, "sfd: %d %d\n", sfd[0], sfd[1]); ++ fflush(stderr); ++ } ++ ++ pid = fork(); ++ if (pid == -1) { ++ perror("fork"); ++ return False; ++ } ++ if (pid == 0) { ++ char *args[4]; ++ int d; ++ args[0] = "/bin/sh"; ++ args[1] = "-c"; ++ args[2] = cmd; ++ args[3] = NULL; ++ ++ close(sfd[1]); ++ dup2(sfd[0], 0); ++ dup2(sfd[0], 1); ++ for (d=3; d < 256; d++) { ++ if (d != sfd[0]) { ++ close(d); ++ } ++ } ++ execvp(args[0], args); ++ perror("exec"); ++ exit(1); ++ } else { ++ close(sfd[0]); ++ rfbsock = sfd[1]; ++ } ++ if (rfbsock < 0) { ++ fprintf(stderr,"Unable to connect to exec'd command: %s\n", cmd); ++ return False; ++ } ++ } else if (strchr(hostname, '/') && stat(hostname, &sb) == 0) { ++ /* assume unix domain socket */ ++ char *thost = strdup(hostname); ++ ++ rfbsock = ConnectToUnixSocket(thost); ++ free(thost); ++ ++ if (rfbsock < 0) { ++ fprintf(stderr,"Unable to connect to VNC server (unix-domain socket: %s)\n", hostname); ++ return False; ++ } ++ ++ } else { ++ if (!StringToIPAddr(hostname, &host)) { ++ fprintf(stderr,"Couldn't convert '%s' to host address\n", hostname); ++ return False; ++ } ++ ++ rfbsock = ConnectToTcpAddr(host, port); ++ ++ if (rfbsock < 0) { ++ fprintf(stderr,"Unable to connect to VNC server (%s:%d)\n", hostname, port); ++ return False; ++ } + } - return SetNonBlocking(rfbsock); -+ return SetNonBlocking(rfbsock); ++ setnb = SetNonBlocking(rfbsock); ++ return setnb; } -@@ -212,211 +257,228 @@ +@@ -212,211 +341,299 @@ Bool InitialiseRFBConnection(void) { @@ -4730,8 +5299,54 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie - fprintf(stderr,"Not a valid VNC server\n"); - return False; - } -+ if (sscanf(pv, rfbProtocolVersionFormat, &server_major, &server_minor) != 2) { -+ fprintf(stderr,"Not a valid VNC server\n"); ++ if (strstr(pv, "ID:") == pv) { ++ ; ++ } else if (sscanf(pv, rfbProtocolVersionFormat, &server_major, &server_minor) != 2) { ++ if (strstr(pv, "test") == pv) { ++ /* now some hacks for ultraVNC SC III (SSL) ... testA, etc */ ++ int i; ++ char *se = NULL; ++ ++ fprintf(stderr,"Trying UltraVNC Single Click III workaround: %s\n", pv); ++ for (i=0; i < 7 ; i++) { ++ pv[i] = pv[i+5]; ++ } ++ if (!ReadFromRFBServer(pv+7, 5)) { ++ return False; ++ } ++ ++ se = getenv("STUNNEL_EXTRA_OPTS"); ++ if (se == NULL) { ++ se = getenv("STUNNEL_EXTRA_OPTS_USER"); ++ } ++ if (se != NULL) { ++ if (strstr(se, "options")) { ++ if (strstr(se, "ALL") || strstr(se, "DONT_INSERT_EMPTY_FRAGMENTS")) { ++ ; /* good */ ++ } else { ++ se = NULL; ++ } ++ } else { ++ se = NULL; ++ } ++ } ++ if (se == NULL) { ++ fprintf(stderr, "\n"); ++ fprintf(stderr, "***************************************************************\n"); ++ fprintf(stderr, "To work around UltraVNC SC III SSL dropping after a few minutes\n"); ++ fprintf(stderr, "you may need to set STUNNEL_EXTRA_OPTS_USER='options = ALL'.\n"); ++ fprintf(stderr, "Or select 'UltraVNC Single Click III Bug' in the SSVNC GUI.\n"); ++ fprintf(stderr, "***************************************************************\n"); ++ fprintf(stderr, "\n"); ++ } ++ if (strstr(pv, "ID:") == pv) { ++ goto check_ID_string; ++ } ++ if (sscanf(pv, rfbProtocolVersionFormat, &server_major, &server_minor) == 2) { ++ goto ultra_vnc_nonsense; ++ } ++ } ++ fprintf(stderr,"Not a valid VNC server: '%s'\n", pv); + return False; + } @@ -4743,26 +5358,43 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie - /* any other server version, request the standard 3.3 */ - viewer_minor = rfbProtocolFallbackMinorVersion; - } -+ viewer_major = rfbProtocolMajorVersion; -+ if (server_major == 3 && server_minor >= rfbProtocolMinorVersion) { -+ /* the server supports at least the standard protocol 3.7 */ -+ viewer_minor = rfbProtocolMinorVersion; -+ } else { -+ /* any other server version, request the standard 3.3 */ -+ viewer_minor = rfbProtocolFallbackMinorVersion; ++ check_ID_string: ++ if (strstr(pv, "ID:") == pv) { ++ char tmp[256]; ++ fprintf(stderr, "UltraVNC Repeater string detected: %s\n", pv); ++ fprintf(stderr, "Pretending to be UltraVNC repeater: reading 250 bytes...\n\n"); ++ if (!ReadFromRFBServer(tmp, 250 - 12)) { ++ return False; ++ } ++ if (!ReadFromRFBServer(pv, 12)) { ++ return False; ++ } ++ if (sscanf(pv, rfbProtocolVersionFormat, &server_major, &server_minor) != 2) { ++ fprintf(stderr,"Not a valid VNC server: '%s'\n", pv); ++ return False; ++ } + } - fprintf(stderr, "Connected to RFB server, using protocol version %d.%d\n", - viewer_major, viewer_minor); -+ fprintf(stderr, "\nConnected to RFB server, using protocol version %d.%d\n", viewer_major, viewer_minor); ++ ultra_vnc_nonsense: ++ fprintf(stderr,"Proto: %s\n", pv); - sprintf(pv, rfbProtocolVersionFormat, viewer_major, viewer_minor); -+ sprintf(pv, rfbProtocolVersionFormat, viewer_major, viewer_minor); ++ viewer_major = rfbProtocolMajorVersion; - if (!WriteExact(rfbsock, pv, sz_rfbProtocolVersionMsg)) - return False; -+ if (!WriteExact(rfbsock, pv, sz_rfbProtocolVersionMsg)) { -+ return False; ++ if (server_major == 3 && (server_minor == 14 || server_minor == 16)) { ++ /* hack for UltraVNC Single Click. They misuse rfb proto version */ ++ fprintf(stderr,"Setting RFB version to 3.3 for UltraVNC Single Click.\n"); ++ viewer_minor = rfbProtocolFallbackMinorVersion; ++ } else if (server_major == 3 && server_minor >= rfbProtocolMinorVersion) { ++ /* the server supports at least the standard protocol 3.7 */ ++ viewer_minor = rfbProtocolMinorVersion; ++ } else { ++ /* any other server version, request the standard 3.3 */ ++ viewer_minor = rfbProtocolFallbackMinorVersion; + } - /* Read or select the security type. */ @@ -4773,15 +5405,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie - } - if (secType == rfbSecTypeInvalid) - return False; -+ /* Read or select the security type. */ -+ if (viewer_minor == rfbProtocolMinorVersion) { -+ secType = SelectSecurityType(); -+ } else { -+ secType = ReadSecurityType(); -+ } -+ if (secType == rfbSecTypeInvalid) { -+ return False; -+ } ++ fprintf(stderr, "\nConnected to RFB server, using protocol version %d.%d\n", viewer_major, viewer_minor); - switch (secType) { - case rfbSecTypeNone: @@ -4803,6 +5427,27 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie - fprintf(stderr, "Internal error: Invalid security type\n"); - return False; - } ++ sprintf(pv, rfbProtocolVersionFormat, viewer_major, viewer_minor); + +- ci.shared = (appData.shareDesktop ? 1 : 0); ++ if (!WriteExact(rfbsock, pv, sz_rfbProtocolVersionMsg)) { ++ return False; ++ } + +- if (!WriteExact(rfbsock, (char *)&ci, sz_rfbClientInitMsg)) +- return False; ++ /* Read or select the security type. */ ++ if (viewer_minor == rfbProtocolMinorVersion) { ++ secType = SelectSecurityType(); ++ } else { ++ secType = ReadSecurityType(); ++ } ++ if (secType == rfbSecTypeInvalid) { ++ return False; ++ } + +- if (!ReadFromRFBServer((char *)&si, sz_rfbServerInitMsg)) +- return False; + switch (secType) { + case rfbSecTypeNone: + fprintf(stderr, "No authentication needed\n\n"); @@ -4827,21 +5472,6 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + return False; + } -- ci.shared = (appData.shareDesktop ? 1 : 0); -+ ci.shared = (appData.shareDesktop ? 1 : 0); - -- if (!WriteExact(rfbsock, (char *)&ci, sz_rfbClientInitMsg)) -- return False; -+ if (!WriteExact(rfbsock, (char *)&ci, sz_rfbClientInitMsg)) { -+ return False; -+ } - -- if (!ReadFromRFBServer((char *)&si, sz_rfbServerInitMsg)) -- return False; -+ if (!ReadFromRFBServer((char *)&si, sz_rfbServerInitMsg)) { -+ return False; -+ } - - si.framebufferWidth = Swap16IfLE(si.framebufferWidth); - si.framebufferHeight = Swap16IfLE(si.framebufferHeight); - si.format.redMax = Swap16IfLE(si.format.redMax); @@ -4856,6 +5486,19 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie - (unsigned long)si.nameLength); - return False; - } ++ ci.shared = (appData.shareDesktop ? 1 : 0); + +- if (!ReadFromRFBServer(desktopName, si.nameLength)) return False; ++ if (!WriteExact(rfbsock, (char *)&ci, sz_rfbClientInitMsg)) { ++ return False; ++ } + +- desktopName[si.nameLength] = 0; ++ if (!ReadFromRFBServer((char *)&si, sz_rfbServerInitMsg)) { ++ return False; ++ } + +- fprintf(stderr,"Desktop name \"%s\"\n",desktopName); + si.framebufferWidth = Swap16IfLE(si.framebufferWidth); + si.framebufferHeight = Swap16IfLE(si.framebufferHeight); + si.format.redMax = Swap16IfLE(si.format.redMax); @@ -4871,35 +5514,32 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + return False; + } -- if (!ReadFromRFBServer(desktopName, si.nameLength)) return False; +- fprintf(stderr,"VNC server default format:\n"); +- PrintPixelFormat(&si.format); + if (!ReadFromRFBServer(desktopName, si.nameLength)) { + return False; + } -- desktopName[si.nameLength] = 0; -+ desktopName[si.nameLength] = 0; - -- fprintf(stderr,"Desktop name \"%s\"\n",desktopName); -+ fprintf(stderr,"Desktop name \"%s\"\n\n", desktopName); - -- fprintf(stderr,"VNC server default format:\n"); -- PrintPixelFormat(&si.format); -+ fprintf(stderr,"VNC server default format:\n"); -+ PrintPixelFormat(&si.format); - - if (tightVncProtocol) { - /* Read interaction capabilities (protocol 3.7t) */ - if (!ReadInteractionCaps()) - return False; - } ++ desktopName[si.nameLength] = 0; + +- return True; ++ fprintf(stderr,"Desktop name \"%s\"\n\n", desktopName); ++ ++ fprintf(stderr,"VNC server default format:\n"); ++ PrintPixelFormat(&si.format); ++ + if (tightVncProtocol) { + /* Read interaction capabilities (protocol 3.7t) */ + if (!ReadInteractionCaps()) { + return False; + } + } - -- return True; ++ + return True; } @@ -5026,8 +5666,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + if (!ReadFromRFBServer((char *)secTypes, nSecTypes)) { + return rfbSecTypeInvalid; + } - -- free(secTypes); ++ + /* Find out if the server supports TightVNC protocol extensions */ + for (j = 0; j < (int)nSecTypes; j++) { + if (secTypes[j] == rfbSecTypeTight) { @@ -5041,8 +5680,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + } + } -- if (secType == rfbSecTypeInvalid) -- fprintf(stderr, "Server did not offer supported security type\n"); +- free(secTypes); + /* Find first supported security type */ + for (j = 0; j < (int)nSecTypes; j++) { + for (i = 0; i < nKnownSecTypes; i++) { @@ -5060,9 +5698,11 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + } + } -- return (int)secType; +- if (secType == rfbSecTypeInvalid) +- fprintf(stderr, "Server did not offer supported security type\n"); + free(secTypes); -+ + +- return (int)secType; + if (secType == rfbSecTypeInvalid) { + fprintf(stderr, "Server did not offer supported security type\n"); + } @@ -5071,7 +5711,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } -@@ -451,6 +513,9 @@ +@@ -451,6 +668,9 @@ return True; } @@ -5081,7 +5721,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie /* * Negotiate authentication scheme (protocol version 3.7t) -@@ -459,56 +524,61 @@ +@@ -459,56 +679,61 @@ static Bool PerformAuthenticationTight(void) { @@ -5185,7 +5825,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } -@@ -519,80 +589,97 @@ +@@ -519,80 +744,97 @@ static Bool AuthenticateVNC(void) { @@ -5346,7 +5986,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } /* -@@ -602,68 +689,71 @@ +@@ -602,68 +844,71 @@ static Bool AuthenticateUnixLogin(void) { @@ -5470,7 +6110,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } -@@ -675,19 +765,20 @@ +@@ -675,19 +920,20 @@ static Bool ReadInteractionCaps(void) { @@ -5503,7 +6143,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } -@@ -700,17 +791,18 @@ +@@ -700,17 +946,18 @@ static Bool ReadCapabilityList(CapsContainer *caps, int count) { @@ -5531,7 +6171,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } -@@ -729,6 +821,10 @@ +@@ -729,6 +976,10 @@ Bool requestCompressLevel = False; Bool requestQualityLevel = False; Bool requestLastRectEncoding = False; @@ -5542,7 +6182,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie spf.type = rfbSetPixelFormat; spf.format = myFormat; -@@ -736,6 +832,7 @@ +@@ -736,6 +987,7 @@ spf.format.greenMax = Swap16IfLE(spf.format.greenMax); spf.format.blueMax = Swap16IfLE(spf.format.blueMax); @@ -5550,7 +6190,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie if (!WriteExact(rfbsock, (char *)&spf, sz_rfbSetPixelFormatMsg)) return False; -@@ -754,6 +851,12 @@ +@@ -754,6 +1006,12 @@ encStrLen = strlen(encStr); } @@ -5563,7 +6203,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie if (strncasecmp(encStr,"raw",encStrLen) == 0) { encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw); } else if (strncasecmp(encStr,"copyrect",encStrLen) == 0) { -@@ -775,6 +878,20 @@ +@@ -775,6 +1033,20 @@ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCoRRE); } else if (strncasecmp(encStr,"rre",encStrLen) == 0) { encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRRE); @@ -5584,7 +6224,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } else { fprintf(stderr,"Unknown encoding '%.*s'\n",encStrLen,encStr); } -@@ -797,7 +914,7 @@ +@@ -797,7 +1069,7 @@ if (appData.useRemoteCursor) { if (se->nEncodings < MAX_ENCODINGS) encs[se->nEncodings++] = Swap32IfLE(rfbEncodingXCursor); @@ -5593,7 +6233,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor); if (se->nEncodings < MAX_ENCODINGS) encs[se->nEncodings++] = Swap32IfLE(rfbEncodingPointerPos); -@@ -806,10 +923,14 @@ +@@ -806,10 +1078,14 @@ if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding) { encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect); } @@ -5609,7 +6249,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie fprintf(stderr,"Same machine: preferring raw encoding\n"); encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw); } else { -@@ -819,6 +940,8 @@ +@@ -819,6 +1095,8 @@ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect); encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight); @@ -5618,7 +6258,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile); encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib); encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCoRRE); -@@ -844,11 +967,14 @@ +@@ -844,11 +1122,14 @@ if (appData.useRemoteCursor) { encs[se->nEncodings++] = Swap32IfLE(rfbEncodingXCursor); @@ -5634,7 +6274,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } len = sz_rfbSetEncodingsMsg + se->nEncodings * 4; -@@ -868,10 +994,11 @@ +@@ -868,31 +1149,109 @@ Bool SendIncrementalFramebufferUpdateRequest() { @@ -5645,24 +6285,49 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } +time_t last_filexfer = 0; ++int delay_filexfer = 3; ++extern void CheckFileXfer(void); ++extern int rfbsock_is_ready(void); ++ ++ ++// fprintf(stderr, "skip SendFramebufferUpdateRequest: %d - %d\n", last_filexfer, time(NULL)); ++#if 0 ++int ready; ++if (0) { ++ ready = rfbsock_is_ready(); ++ if (db) fprintf(stderr, "rsir: %d\n", ready); ++ if (ready) { ++ int r = (int) HandleRFBServerMessage(); ++ if (db) fprintf(stderr, "hrsm: %d\n", r); ++ ++ } ++ if (db) fprintf(stderr, "CFX: C ****\n"); ++ CheckFileXfer(); ++ return True; ++} ++if (db) { ++ ready = rfbsock_is_ready(); ++ fprintf(stderr, "rsir: %d\n", ready); ++} ++#endif ++// x = y = 0; ++// w = h = 1; ++ ++ ++static int dyn = -1; ++extern int filexfer_sock; ++extern int filexfer_listen; /* * SendFramebufferUpdateRequest. -@@ -880,19 +1007,35 @@ + */ +- Bool SendFramebufferUpdateRequest(int x, int y, int w, int h, Bool incremental) { - rfbFramebufferUpdateRequestMsg fur; + rfbFramebufferUpdateRequestMsg fur; -+ -+ if (appData.fileActive) { -+ if (time(NULL) < last_filexfer + 2) { -+// fprintf(stderr, "skip SendFramebufferUpdateRequest: %d - %d\n", last_filexfer, time(NULL)); -+// return True; -+ x = y = 0; -+ w = h = 1; -+ } -+ } ++ static int db = -1; - fur.type = rfbFramebufferUpdateRequest; - fur.incremental = incremental ? 1 : 0; @@ -5670,6 +6335,47 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie - fur.y = Swap16IfLE(y); - fur.w = Swap16IfLE(w); - fur.h = Swap16IfLE(h); ++ if (db < 0) { ++ if (getenv("SSVNC_DEBUG_RECTS")) { ++ db = atoi(getenv("SSVNC_DEBUG_RECTS")); ++ } else { ++ db = 0; ++ } ++ } + +- if (!WriteExact(rfbsock, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg)) +- return False; ++ if (db) fprintf(stderr, "SendFramebufferUpdateRequest(%d, %d, %d, %d, incremental=%d)\n", x, y, w, h, (int) incremental); + +- return True; ++ if (dyn < 0) { ++ struct stat sb; ++ if (getenv("USER") && !strcmp(getenv("USER"), "runge")) { ++ if (stat("/tmp/nodyn", &sb) == 0) { ++ putenv("NOFTFBUPDATES=1"); ++ unlink("/tmp/nodyn"); ++ } ++ } ++ if (getenv("NOFTFBUPDATES")) { ++ dyn = 0; ++ } else { ++ dyn = 1; ++ } ++ } ++ ++ if (appData.fileActive && filexfer_sock >= 0) { ++ static int first = 1; ++ if (first) { ++ fprintf(stderr, "SFU: dynamic fb updates during filexfer: %d\n", dyn); ++ first = 0; ++ } ++if (db > 2 || 0) fprintf(stderr, "A sfur: %d %d %d %d d_last: %d\n", x, y, w, h, (int) (time(NULL) - last_filexfer)); ++ if (!dyn || time(NULL) < last_filexfer + delay_filexfer) { ++ return True; ++ } ++ } ++if (db > 1) fprintf(stderr, "B sfur: %d %d %d %d\n", x, y, w, h); ++ + fur.type = rfbFramebufferUpdateRequest; + fur.incremental = incremental ? 1 : 0; + fur.x = Swap16IfLE(x); @@ -5682,24 +6388,33 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + } else { + sent_FBU = 2; + } - -- if (!WriteExact(rfbsock, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg)) -- return False; ++ + if (!WriteExact(rfbsock, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg)) { + return False; + } - -- return True; ++ + return True; } -@@ -903,19 +1046,27 @@ +@@ -903,19 +1262,27 @@ Bool SendPointerEvent(int x, int y, int buttonMask) { - rfbPointerEventMsg pe; + rfbPointerEventMsg pe; ++ ++ if (appData.fileActive) { ++ if (!dyn || time(NULL) < last_filexfer + delay_filexfer) { ++ //fprintf(stderr, "skip SendPointerEvent: %d - %d\n", last_filexfer, time(NULL)); ++ return True; ++ } ++ } ++ ++ pe.type = rfbPointerEvent; ++ pe.buttonMask = buttonMask; ++ if (x < 0) x = 0; ++ if (y < 0) y = 0; - pe.type = rfbPointerEvent; - pe.buttonMask = buttonMask; @@ -5712,18 +6427,6 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie - pe.x = Swap16IfLE(x); - pe.y = Swap16IfLE(y); - return WriteExact(rfbsock, (char *)&pe, sz_rfbPointerEventMsg); -+ if (appData.fileActive) { -+ if (time(NULL) < last_filexfer + 2) { -+ //fprintf(stderr, "skip SendPointerEvent: %d - %d\n", last_filexfer, time(NULL)); -+ return True; -+ } -+ } -+ -+ pe.type = rfbPointerEvent; -+ pe.buttonMask = buttonMask; -+ if (x < 0) x = 0; -+ if (y < 0) y = 0; -+ + if (!appData.useX11Cursor) { + SoftCursorMove(x, y); + } @@ -5734,7 +6437,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } -@@ -926,12 +1077,12 @@ +@@ -926,12 +1293,19 @@ Bool SendKeyEvent(CARD32 key, Bool down) { @@ -5745,6 +6448,13 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie - ke.down = down ? 1 : 0; - ke.key = Swap32IfLE(key); - return WriteExact(rfbsock, (char *)&ke, sz_rfbKeyEventMsg); ++ if (appData.fileActive) { ++ if (!dyn || time(NULL) < last_filexfer + delay_filexfer) { ++ //fprintf(stderr, "skip SendPointerEvent: %d - %d\n", last_filexfer, time(NULL)); ++ return True; ++ } ++ } ++ + ke.type = rfbKeyEvent; + ke.down = down ? 1 : 0; + ke.key = Swap32IfLE(key); @@ -5752,7 +6462,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } -@@ -942,281 +1093,716 @@ +@@ -942,281 +1316,818 @@ Bool SendClientCutText(char *str, int len) { @@ -5767,95 +6477,102 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie - cct.length = Swap32IfLE(len); - return (WriteExact(rfbsock, (char *)&cct, sz_rfbClientCutTextMsg) && - WriteExact(rfbsock, str, len)); --} + if (serverCutText) { + free(serverCutText); + } + serverCutText = NULL; - ++ ++ if (appData.fileActive) { ++ if (!dyn || time(NULL) < last_filexfer + delay_filexfer) { ++ // ultravnc java viewer lets this one through. ++ return True; ++ } ++ } ++ + if (appData.viewOnly) { + return True; + } - --/* -- * HandleRFBServerMessage. -- */ ++ + cct.type = rfbClientCutText; + cct.length = Swap32IfLE(len); + return (WriteExact(rfbsock, (char *)&cct, sz_rfbClientCutTextMsg) && + WriteExact(rfbsock, str, len)); -+} + } - Bool --HandleRFBServerMessage() ++static int ultra_scale = 0; + +-/* +- * HandleRFBServerMessage. +- */ ++Bool +SendServerScale(int nfac) - { -- rfbServerToClientMsg msg; ++{ + rfbSetScaleMsg ssc; + if (nfac < 0 || nfac > 100) { + return True; + } - -- if (!ReadFromRFBServer((char *)&msg, 1)) -- return False; ++ ++ ultra_scale = nfac; + ssc.type = rfbSetScale; + ssc.scale = nfac; + return WriteExact(rfbsock, (char *)&ssc, sz_rfbSetScaleMsg); +} -- switch (msg.type) { -+Bool + Bool +-HandleRFBServerMessage() +SendServerInput(Bool enabled) -+{ + { +- rfbServerToClientMsg msg; + rfbSetServerInputMsg sim; -- case rfbSetColourMapEntries: -- { -- int i; -- CARD16 rgb[3]; -- XColor xc; +- if (!ReadFromRFBServer((char *)&msg, 1)) +- return False; + sim.type = rfbSetServerInput; + sim.status = enabled; + return WriteExact(rfbsock, (char *)&sim, sz_rfbSetServerInputMsg); +} -- if (!ReadFromRFBServer(((char *)&msg) + 1, -- sz_rfbSetColourMapEntriesMsg - 1)) -- return False; +- switch (msg.type) { +Bool +SendSingleWindow(int x, int y) +{ ++ static int w_old = -1, h_old = -1; + rfbSetSWMsg sw; -- msg.scme.firstColour = Swap16IfLE(msg.scme.firstColour); -- msg.scme.nColours = Swap16IfLE(msg.scme.nColours); +- case rfbSetColourMapEntries: +- { +- int i; +- CARD16 rgb[3]; +- XColor xc; + fprintf(stderr, "SendSingleWindow: %d %d\n", x, y); -- for (i = 0; i < msg.scme.nColours; i++) { -- if (!ReadFromRFBServer((char *)rgb, 6)) -- return False; -- xc.pixel = msg.scme.firstColour + i; -- xc.red = Swap16IfLE(rgb[0]); -- xc.green = Swap16IfLE(rgb[1]); -- xc.blue = Swap16IfLE(rgb[2]); -- xc.flags = DoRed|DoGreen|DoBlue; -- XStoreColor(dpy, cmap, &xc); -- } +- if (!ReadFromRFBServer(((char *)&msg) + 1, +- sz_rfbSetColourMapEntriesMsg - 1)) +- return False; + if (x == -1 && y == -1) { + sw.type = rfbSetSW; + sw.x = Swap16IfLE(1); + sw.y = Swap16IfLE(1); ++ if (w_old > 0) { ++ si.framebufferWidth = w_old; ++ si.framebufferHeight = h_old; ++ ReDoDesktop(); ++ } ++ w_old = h_old = -1; + } else { + sw.type = rfbSetSW; + sw.x = Swap16IfLE(x); + sw.y = Swap16IfLE(y); ++ w_old = si.framebufferWidth; ++ h_old = si.framebufferHeight; ++ + } + sw.status = True; + return WriteExact(rfbsock, (char *)&sw, sz_rfbSetSWMsg); +} -- break; -- } +- msg.scme.firstColour = Swap16IfLE(msg.scme.firstColour); +- msg.scme.nColours = Swap16IfLE(msg.scme.nColours); +Bool +SendTextChat(char *str) +{ @@ -5872,18 +6589,20 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + return WriteExact(rfbsock, str, strlen(str)); +} -- case rfbFramebufferUpdate: -- { -- rfbFramebufferUpdateRectHeader rect; -- int linesToRead; -- int bytesPerLine; -- int i; -- int usecs; +- for (i = 0; i < msg.scme.nColours; i++) { +- if (!ReadFromRFBServer((char *)rgb, 6)) +- return False; +- xc.pixel = msg.scme.firstColour + i; +- xc.red = Swap16IfLE(rgb[0]); +- xc.green = Swap16IfLE(rgb[1]); +- xc.blue = Swap16IfLE(rgb[2]); +- xc.flags = DoRed|DoGreen|DoBlue; +- XStoreColor(dpy, cmap, &xc); +- } +extern void raiseme(int force); -- if (!ReadFromRFBServer(((char *)&msg.fu) + 1, -- sz_rfbFramebufferUpdateMsg - 1)) -- return False; +- break; +- } +Bool +SendTextChatOpen(void) +{ @@ -5896,7 +6615,13 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + return WriteExact(rfbsock, (char *)&chat, sz_rfbTextChatMsg); +} -- msg.fu.nRects = Swap16IfLE(msg.fu.nRects); +- case rfbFramebufferUpdate: +- { +- rfbFramebufferUpdateRectHeader rect; +- int linesToRead; +- int bytesPerLine; +- int i; +- int usecs; +Bool +SendTextChatClose(void) +{ @@ -5908,9 +6633,9 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + return WriteExact(rfbsock, (char *)&chat, sz_rfbTextChatMsg); +} -- for (i = 0; i < msg.fu.nRects; i++) { -- if (!ReadFromRFBServer((char *)&rect, sz_rfbFramebufferUpdateRectHeader)) -- return False; +- if (!ReadFromRFBServer(((char *)&msg.fu) + 1, +- sz_rfbFramebufferUpdateMsg - 1)) +- return False; +Bool +SendTextChatFinished(void) +{ @@ -5957,11 +6682,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + return dtime0(&t); +} + -+extern int filexfer_sock; -+extern int filexfer_listen; -+ +static char fxfer[65536]; -+extern void CheckFileXfer(void); + +Bool HandleFileXfer(void) { + unsigned char hdr[12]; @@ -5998,11 +6719,30 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + + int rfbRErrorUnknownCmd = 1; // Unknown FileTransfer command. + int rfbRErrorCmd = 0xFFFFFFFF; ++ ++ int db = 0; ++ ++#if 0 ++ if (filexfer_sock < 0) { ++ return True; ++ } ++ // instead, we read and discard the ft msg data. ++#endif + +- msg.fu.nRects = Swap16IfLE(msg.fu.nRects); ++//fprintf(stderr, "In HandleFileXfer\n"); + +- for (i = 0; i < msg.fu.nRects; i++) { +- if (!ReadFromRFBServer((char *)&rect, sz_rfbFramebufferUpdateRectHeader)) +- return False; ++ last_filexfer = time(NULL); ++ //fprintf(stderr, "last_filexfer-1: %d\n", last_filexfer); - rect.encoding = Swap32IfLE(rect.encoding); - if (rect.encoding == rfbEncodingLastRect) - break; -+ int db = 0; ++ // load first byte to send to Java be the FT msg number: ++ hdr[0] = rfbFileTransfer; - rect.r.x = Swap16IfLE(rect.r.x); - rect.r.y = Swap16IfLE(rect.r.y); @@ -6014,17 +6754,39 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie - if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h, - rect.encoding)) { - return False; -- } ++ // this is to avoid XtAppProcessEvent() calls induce by our ReadFromRFBServer calls below: ++ skip_XtUpdateAll = 1; ++ if (!ReadFromRFBServer(&hdr[1], 11)) { ++ skip_XtUpdateAll = 0; ++ return False; ++ } ++ if (filexfer_sock >= 0) { ++ write(filexfer_sock, hdr, 12); ++ } else { ++ fprintf(stderr, "filexfer_sock closed, discarding 12 bytes\n"); ++ } ++ if (db) fprintf(stderr, "\n"); ++ if (db) fprintf(stderr, "Got rfbFileTransfer hdr\n"); ++ if (db > 1) write(2, hdr, 12); ++ ++ if (db) { ++ int i; ++ fprintf(stderr, "HFX HDR:"); ++ for (i=0; i < 12; i++) { ++ fprintf(stderr, " %d", (int) hdr[i]); ++ } ++ fprintf(stderr, "\n"); + } - continue; - } -+ last_filexfer = time(NULL); -+ //fprintf(stderr, "last_filexfer-1: %d\n", last_filexfer); - if (rect.encoding == rfbEncodingPointerPos) { - if (!HandleCursorPos(rect.r.x, rect.r.y)) { - return False; -+ if (filexfer_sock < 0) { -+ return True; ++ if (hdr[1] == rfbEndOfFile) { ++ goto read_no_more; ++ } else if (hdr[1] == rfbAbortFileTransfer) { ++ goto read_no_more; } - continue; - } @@ -6035,29 +6797,30 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie - fprintf(stderr,"Rect too large: %dx%d at (%d, %d)\n", - rect.r.w, rect.r.h, rect.r.x, rect.r.y); - return False; -+ hdr[0] = rfbFileTransfer; -+ skip_XtUpdateAll = 1; -+ if (!ReadFromRFBServer(&hdr[1], 11)) { -+ skip_XtUpdateAll = 0; -+ return False; -+ } -+ write(filexfer_sock, hdr, 12); -+ if (db) fprintf(stderr, "Got rfbFileTransfer hdr\n"); -+ if (db) write(2, hdr, 12); -+ if (db) fprintf(stderr, "\n"); -+ + len = (hdr[8] << 24) | (hdr[9] << 16) | (hdr[10] << 8) | hdr[11]; -+ if (db) fprintf(stderr, "Got rfbFileTransfer: len %d\n", len); ++ if (db) fprintf(stderr, "Got rfbFileTransfer: len1 %u\n", len); + if (len > 0) { + if (!ReadFromRFBServer(fxfer, len)) { + skip_XtUpdateAll = 0; + return False; + } -+ if (db) write(2, fxfer, len); -+ if (db) fprintf(stderr, "\n"); -+ write(filexfer_sock, fxfer, len); -+ } ++ if (db > 1) write(2, fxfer, len); ++ if (db && 0) fprintf(stderr, "\n"); ++ if (filexfer_sock >= 0) { ++ write(filexfer_sock, fxfer, len); ++ } else { ++ fprintf(stderr, "filexfer_sock closed, discarding %d bytes\n", len); ++ } + } + +- if (rect.r.h * rect.r.w == 0) { +- fprintf(stderr,"Zero size rect - ignoring\n"); +- continue; +- } ++ /* not used! */ + len = (hdr[4] << 24) | (hdr[5] << 16) | (hdr[6] << 8) | hdr[7]; ++ if (db) fprintf(stderr, "Got rfbFileTransfer: len2 %u\n", len); ++ + if (hdr[1] == rfbFileHeader && len != rfbRErrorCmd) { + if (db) fprintf(stderr, "Got rfbFileTransfer: rfbFileHeader\n"); + len = 4; @@ -6065,39 +6828,76 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + skip_XtUpdateAll = 0; + return False; + } -+ if (db) write(2, fxfer, len); -+ if (db) fprintf(stderr, "\n"); -+ write(filexfer_sock, fxfer, len); - } ++ if (db > 1) write(2, fxfer, len); ++ if (db && 0) fprintf(stderr, "\n"); ++ if (filexfer_sock >= 0) { ++ write(filexfer_sock, fxfer, len); ++ } else { ++ fprintf(stderr, "filexfer_sock closed, discarding %d bytes\n", len); ++ } ++ } + +- /* If RichCursor encoding is used, we should prevent collisions +- between framebuffer updates and cursor drawing operations. */ +- SoftCursorLockArea(rect.r.x, rect.r.y, rect.r.w, rect.r.h); ++ read_no_more: + +- switch (rect.encoding) { ++ if (filexfer_sock < 0) { ++ int stop = 0; ++ static time_t last_stop = 0; ++#if 0 ++ // this isn't working ++ if (hdr[1] == rfbFilePacket || hdr[1] == rfbFileHeader) { ++ fprintf(stderr, "filexfer_sock closed, trying to abort receive\n"); ++ stop = 1; ++ } ++#endif ++ if (stop && time(NULL) > last_stop+1) { ++ unsigned char rpl[12]; ++ int k; ++ rpl[0] = rfbFileTransfer; ++ rpl[1] = rfbAbortFileTransfer; ++ for (k=2; k < 12; k++) { ++ rpl[k] = 0; ++ } ++ WriteExact(rfbsock, rpl, 12); ++ last_stop = time(NULL); ++ } ++ } + +- case rfbEncodingRaw: + if (db) fprintf(stderr, "Got rfbFileTransfer done.\n"); + skip_XtUpdateAll = 0; -- if (rect.r.h * rect.r.w == 0) { -- fprintf(stderr,"Zero size rect - ignoring\n"); -- continue; -- } +- bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8; +- linesToRead = BUFFER_SIZE / bytesPerLine; ++ if (db) fprintf(stderr, "CFX: B\n"); + CheckFileXfer(); ++//fprintf(stderr, "Out HandleFileXfer\n"); + return True; +} -- /* If RichCursor encoding is used, we should prevent collisions -- between framebuffer updates and cursor drawing operations. */ -- SoftCursorLockArea(rect.r.x, rect.r.y, rect.r.w, rect.r.h); +- while (rect.r.h > 0) { +- if (linesToRead > rect.r.h) +- linesToRead = rect.r.h; +/* + * HandleRFBServerMessage. + */ -- switch (rect.encoding) { +- if (!ReadFromRFBServer(buffer,bytesPerLine * linesToRead)) +- return False; -- case rfbEncodingRaw: +- CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w, +- linesToRead); +Bool +HandleRFBServerMessage() +{ + static int db = -1; + rfbServerToClientMsg msg; -- bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8; -- linesToRead = BUFFER_SIZE / bytesPerLine; +- rect.r.h -= linesToRead; +- rect.r.y += linesToRead; + if (db < 0) { + if (getenv("DEBUG_RFB_SMSG")) { + db = 1; @@ -6106,33 +6906,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + } + } -- while (rect.r.h > 0) { -- if (linesToRead > rect.r.h) -- linesToRead = rect.r.h; + if (!ReadFromRFBServer((char *)&msg, 1)) { + return False; -+ } - -- if (!ReadFromRFBServer(buffer,bytesPerLine * linesToRead)) -- return False; -+ if (msg.type == rfbFileTransfer) { -+ return HandleFileXfer(); -+ } - -- CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w, -- linesToRead); -+ switch (msg.type) { - -- rect.r.h -= linesToRead; -- rect.r.y += linesToRead; -+ case rfbSetColourMapEntries: -+ { -+ int i; -+ CARD16 rgb[3]; -+ XColor xc; - -+ if (!ReadFromRFBServer(((char *)&msg) + 1, sz_rfbSetColourMapEntriesMsg - 1)) { -+ return False; } - break; @@ -6162,33 +6937,21 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie - rect.r.w, rect.r.h); - XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY, - rect.r.w, rect.r.h); -- } -+ msg.scme.firstColour = Swap16IfLE(msg.scme.firstColour); -+ msg.scme.nColours = Swap16IfLE(msg.scme.nColours); ++ if (msg.type == rfbFileTransfer) { ++ return HandleFileXfer(); + } - XCopyArea(dpy, desktopWin, desktopWin, gc, cr.srcX, cr.srcY, - rect.r.w, rect.r.h, rect.r.x, rect.r.y); -+ for (i = 0; i < msg.scme.nColours; i++) { -+ if (!ReadFromRFBServer((char *)rgb, 6)) { -+ return False; -+ } -+ xc.pixel = msg.scme.firstColour + i; -+ xc.red = Swap16IfLE(rgb[0]); -+ xc.green = Swap16IfLE(rgb[1]); -+ xc.blue = Swap16IfLE(rgb[2]); -+ if (appData.useGreyScale) { -+ int ave = (xc.red + xc.green + xc.blue)/3; -+ xc.red = ave; -+ xc.green = ave; -+ xc.blue = ave; -+ } -+ xc.flags = DoRed|DoGreen|DoBlue; -+ XStoreColor(dpy, cmap, &xc); -+ } ++ switch (msg.type) { - break; +- break; - } -+ } ++ case rfbSetColourMapEntries: ++ { ++ int i; ++ CARD16 rgb[3]; ++ XColor xc; - case rfbEncodingRRE: - { @@ -6205,22 +6968,11 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie - if (!HandleRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) - return False; - break; -- } ++ if (!ReadFromRFBServer(((char *)&msg) + 1, sz_rfbSetColourMapEntriesMsg - 1)) { ++ return False; + } - break; - } -+ case rfbFramebufferUpdate: -+ { -+ rfbFramebufferUpdateRectHeader rect; -+ int linesToRead; -+ int bytesPerLine; -+ int i; -+ int usecs; -+ -+ int area_copyrect = 0; -+ int area_tight = 0; -+ int area_zrle = 0; -+ int area_raw = 0; -+ if (db) fprintf(stderr, "FBU-0: %.6f\n", dnow()); - case rfbEncodingCoRRE: - { @@ -6240,8 +6992,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie - } - break; - } -+ int skip_incFBU = 0; -+ sent_FBU = -1; ++ msg.scme.firstColour = Swap16IfLE(msg.scme.firstColour); ++ msg.scme.nColours = Swap16IfLE(msg.scme.nColours); - case rfbEncodingHextile: - { @@ -6258,11 +7010,27 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie - if (!HandleHextile32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) - return False; - break; -+ if (!ReadFromRFBServer(((char *)&msg.fu) + 1, sz_rfbFramebufferUpdateMsg - 1)) { -+ return False; ++ for (i = 0; i < msg.scme.nColours; i++) { ++ if (!ReadFromRFBServer((char *)rgb, 6)) { ++ return False; ++ } ++ xc.pixel = msg.scme.firstColour + i; ++ xc.red = Swap16IfLE(rgb[0]); ++ xc.green = Swap16IfLE(rgb[1]); ++ xc.blue = Swap16IfLE(rgb[2]); ++ if (appData.useGreyScale) { ++ int ave = (xc.red + xc.green + xc.blue)/3; ++ xc.red = ave; ++ xc.green = ave; ++ xc.blue = ave; ++ } ++ xc.flags = DoRed|DoGreen|DoBlue; ++ XStoreColor(dpy, cmap, &xc); } -- break; ++ + break; - } ++ } - case rfbEncodingZlib: - { @@ -6279,10 +7047,30 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie - if (!HandleZlib32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) - return False; - break; -- } ++ case rfbFramebufferUpdate: ++ { ++ rfbFramebufferUpdateRectHeader rect; ++ int linesToRead; ++ int bytesPerLine; ++ int i; ++ int usecs; ++ ++ int area_copyrect = 0; ++ int area_tight = 0; ++ int area_zrle = 0; ++ int area_raw = 0; ++ static int rdb = -1; ++ ++ if (db) fprintf(stderr, "FBU-0: %.6f\n", dnow()); ++ if (rdb < 0) { ++ if (getenv("SSVNC_DEBUG_RECTS")) { ++ rdb = atoi(getenv("SSVNC_DEBUG_RECTS")); ++ } else { ++ rdb = 0; ++ } + } - break; - } -+ msg.fu.nRects = Swap16IfLE(msg.fu.nRects); - case rfbEncodingTight: - { @@ -6299,9 +7087,25 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie - if (!HandleTight32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) - return False; - break; -- } ++ int skip_incFBU = 0; ++ sent_FBU = -1; ++ ++ if (!ReadFromRFBServer(((char *)&msg.fu) + 1, sz_rfbFramebufferUpdateMsg - 1)) { ++ return False; + } - break; - } + +- default: +- fprintf(stderr,"Unknown rect encoding %d\n", +- (int)rect.encoding); +- return False; +- } ++ msg.fu.nRects = Swap16IfLE(msg.fu.nRects); + +- /* Now we may discard "soft cursor locks". */ +- SoftCursorUnlockScreen(); +- } + for (i = 0; i < msg.fu.nRects; i++) { + if (!ReadFromRFBServer((char *)&rect, sz_rfbFramebufferUpdateRectHeader)) { + return False; @@ -6328,8 +7132,16 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + + if (rect.encoding == rfbEncodingPointerPos) { + if (db) fprintf(stderr, "FBU-Pos1 %.6f\n", dnow()); -+ if (!HandleCursorPos(rect.r.x, rect.r.y)) { -+ return False; ++ if (0) fprintf(stderr, "CursorPos: %d %d / %d %d\n", rect.r.x, rect.r.y, rect.r.w, rect.r.h); ++ if (ultra_scale > 0) { ++ int f = ultra_scale; ++ if (!HandleCursorPos(rect.r.x/f, rect.r.y/f)) { ++ return False; ++ } ++ } else { ++ if (!HandleCursorPos(rect.r.x, rect.r.y)) { ++ return False; ++ } + } + if (db) fprintf(stderr, "FBU-Pos2 %.6f\n", dnow()); + continue; @@ -6342,17 +7154,19 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + ReDoDesktop(); + continue; + } ++ if (rdb) fprintf(stderr,"Rect: %dx%d at (%d, %d)\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y); + + if ((rect.r.x + rect.r.w > si.framebufferWidth) || + (rect.r.y + rect.r.h > si.framebufferHeight)) { -+ fprintf(stderr,"Rect too large: %dx%d at (%d, %d)\n", -+ rect.r.w, rect.r.h, rect.r.x, rect.r.y); ++ fprintf(stderr,"Rect too large: %dx%d at (%d, %d) encoding=%d\n", ++ rect.r.w, rect.r.h, rect.r.x, rect.r.y, rect.encoding); + return False; + } + + if (rect.r.h * rect.r.w == 0) { -+ fprintf(stderr,"Zero size rect - ignoring\n"); -+ continue; ++ fprintf(stderr,"*** Warning *** Zero size rect: %dx%d+%d+%d encoding=%d\n", ++ rect.r.w, rect.r.h, rect.r.x, rect.r.y, rect.encoding); ++ if (0) continue; + } + + /* If RichCursor encoding is used, we should prevent collisions @@ -6644,18 +7458,10 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + fprintf(stderr,"Unknown rect encoding %d\n", (int)rect.encoding); + return False; + } - -- default: -- fprintf(stderr,"Unknown rect encoding %d\n", -- (int)rect.encoding); -- return False; -- } ++ + /* Now we may discard "soft cursor locks". */ + if (db) fprintf(stderr, "FBU-SUL1 %.6f\n", dnow()); - -- /* Now we may discard "soft cursor locks". */ -- SoftCursorUnlockScreen(); -- } ++ + SoftCursorUnlockScreen(); + + if (db) fprintf(stderr, "FBU-SUL2 %.6f\n", dnow()); @@ -6698,7 +7504,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie #ifdef MITSHM /* if using shared memory PutImage, make sure that the X server has -@@ -1224,59 +1810,149 @@ +@@ -1224,59 +2135,165 @@ mainly to avoid copyrect using invalid screen contents - not sure if we'd need it otherwise. */ @@ -6830,6 +7636,20 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie - fprintf(stderr,"Unknown message type %d from VNC server\n",msg.type); - return False; - } ++ case rfbResizeFrameBuffer: ++ { ++ rfbResizeFrameBufferMsg rsmsg; ++ if (!ReadFromRFBServer(((char *)&rsmsg) + 1, sz_rfbResizeFrameBufferMsg - 1)) { ++ return False; ++ } ++ si.framebufferWidth = Swap16IfLE(rsmsg.framebufferWidth); ++ si.framebufferHeight = Swap16IfLE(rsmsg.framebufferHeight); ++ fprintf(stderr,"UltraVNC ReSize: %dx%d\n", si.framebufferWidth, si.framebufferHeight); ++ ReDoDesktop(); ++ break; ++ } + +- return True; + case rfbRestartConnection: + { + rfbRestartConnectionMsg rc; @@ -6860,8 +7680,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + SetFormatAndEncodings(); + DesktopCursorOff(); + SendFramebufferUpdateRequest(0, 0, si.framebufferWidth, si.framebufferHeight, False); - -- return True; ++ + break; + } + @@ -6869,10 +7688,13 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + fprintf(stderr,"Unknown message type %d from VNC server\n",msg.type); + return False; + } ++ + if (appData.fileActive) { + if (filexfer_sock < 0 && filexfer_listen < 0) { + appData.fileActive = False; ++ SendFramebufferUpdateRequest(0, 0, 1, 1, False); + } else { ++//fprintf(stderr, "CFX: A\n"); + CheckFileXfer(); + } + } @@ -6881,7 +7703,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } -@@ -1296,26 +1972,47 @@ +@@ -1296,26 +2313,47 @@ #define CONCAT2(a,b) a##b #define CONCAT2E(a,b) CONCAT2(a,b) @@ -6929,7 +7751,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie #undef BPP /* -@@ -1358,9 +2055,9 @@ +@@ -1358,9 +2396,9 @@ " %s significant bit in each byte is leftmost on the screen.\n", (format->bigEndian ? "Most" : "Least")); } else { @@ -6941,7 +7763,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie (format->bigEndian ? "Most" : "Least")); } if (format->trueColour) { -@@ -1462,4 +2159,3 @@ +@@ -1462,4 +2500,3 @@ cinfo->src = &jpegSrcManager; } @@ -7165,11 +7987,49 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/smake vnc_unixsrc/vncviewer/s +fi diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/sockets.c vnc_unixsrc/vncviewer/sockets.c --- vnc_unixsrc.orig/vncviewer/sockets.c 2001-01-14 22:54:18.000000000 -0500 -+++ vnc_unixsrc/vncviewer/sockets.c 2007-12-15 21:08:14.000000000 -0500 -@@ -63,15 +63,216 @@ - XtRemoveInput(*id); - } ++++ vnc_unixsrc/vncviewer/sockets.c 2008-09-03 14:33:59.000000000 -0400 +@@ -27,6 +27,7 @@ + #include <netinet/in.h> + #include <netinet/tcp.h> + #include <arpa/inet.h> ++#include <sys/un.h> + #include <netdb.h> + #include <fcntl.h> + #include <assert.h> +@@ -56,22 +57,327 @@ + */ + static Bool rfbsockReady = False; ++static Bool xfrsockReady = False; ++static XtInputId rfbsockId = 0; ++static XtInputId xfrsockId = 0; ++static int do_rfbsockId = 0; ++static int do_xfrsockId = 0; ++ + static void + rfbsockReadyCallback(XtPointer clientData, int *fd, XtInputId *id) + { +- rfbsockReady = True; +- XtRemoveInput(*id); ++ rfbsockReady = True; ++// XtRemoveInput(*id); ++ XtRemoveInput(rfbsockId); ++ if (do_xfrsockId) { ++ XtRemoveInput(xfrsockId); ++ } ++} ++ ++static void ++xfrsockReadyCallback(XtPointer clientData, int *fd, XtInputId *id) ++{ ++ xfrsockReady = True; ++ XtRemoveInput(xfrsockId); ++ if (do_rfbsockId) { ++ XtRemoveInput(rfbsockId); ++ } ++} ++ ++ +extern int skip_XtUpdate; +extern int skip_XtUpdateAll; +extern int filexfer_sock, filexfer_listen; @@ -7180,6 +8040,27 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/sockets.c vnc_unixsrc/vncview +static char fxfer[65536]; +int fxfer_size = 65536; + ++int rfbsock_is_ready(void) { ++ fd_set fds; ++ struct timeval tv; ++ ++ if (rfbsock < 0) { ++ return 0; ++ } ++ FD_ZERO(&fds); ++ FD_SET(rfbsock,&fds); ++ tv.tv_sec = 0; ++ tv.tv_usec = 0; ++ if (select(rfbsock+1, &fds, NULL, NULL, &tv) > 0) { ++ if (FD_ISSET(rfbsock, &fds)) { ++ return 1; ++ } ++ } ++ return 0; ++} ++ ++time_t filexfer_start = 0; ++ +void CheckFileXfer() { + fd_set fds; + struct timeval tv; @@ -7190,13 +8071,13 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/sockets.c vnc_unixsrc/vncview + return; + } + -+ if (filexfer_listen >= 0 && time(NULL) > start_listen + 10) { ++ if (filexfer_listen >= 0 && time(NULL) > start_listen + 30) { + fprintf(stderr, "filexfer closing aging listen socket.\n"); + close(filexfer_listen); + filexfer_listen = -1; + return; + } -+//fprintf(stderr, "In CheckFileXfer\n"); ++//fprintf(stderr, "In CheckFileXfer\n"); + + if (filexfer_listen >=0) { + n = filexfer_listen; @@ -7212,84 +8093,95 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/sockets.c vnc_unixsrc/vncview + tv.tv_sec = 0; + tv.tv_usec = 0; + if (select(n+1, &fds, NULL, NULL, &tv) > 0) { -+ if (FD_ISSET(n, &fds)) { -+ if (list) { -+ if (filexfer_sock >= 0) { -+ fprintf(stderr, "filexfer close stale(?) filexfer_sock.\n"); -+ close(filexfer_sock); -+ filexfer_sock = -1; -+ } -+ filexfer_sock = AcceptTcpConnection(filexfer_listen); -+ if (filexfer_listen >= 0) { -+ fprintf(stderr, "filexfer accept OK.\n"); -+ close(filexfer_listen); -+ filexfer_listen = -1; -+ } else { -+ fprintf(stderr, "filexfer accept failed.\n"); -+ } -+ break; ++ if (FD_ISSET(n, &fds)) { ++ if (list) { ++ if (filexfer_sock >= 0) { ++ fprintf(stderr, "filexfer close stale(?) filexfer_sock.\n"); ++ close(filexfer_sock); ++ filexfer_sock = -1; ++ } ++ filexfer_sock = AcceptTcpConnection(filexfer_listen); ++ if (filexfer_sock >= 0) { ++ fprintf(stderr, "filexfer accept OK.\n"); ++ close(filexfer_listen); ++ filexfer_listen = -1; ++ filexfer_start = last_filexfer = time(NULL); + } else { -+ ssize_t rn; -+ unsigned char hdr[12]; -+ unsigned int len; -+ if (db) fprintf(stderr, "try read filexfer...\n"); ++ fprintf(stderr, "filexfer accept failed.\n"); ++ } ++ break; ++ } else { ++ ssize_t rn; ++ unsigned char hdr[12]; ++ unsigned int len; ++ if (db) fprintf(stderr, "try read filexfer...\n"); +#if 1 -+ rn = read(n, fxfer, 1*8192); -+ if (0 || db) fprintf(stderr, "filexfer read[%d] %d.\n", icnt, rn); -+ if (rn < 0) { -+ fprintf(stderr, "filexfer bad read: %d\n", errno); -+ break; -+ } else if (rn == 0) { -+ fprintf(stderr, "filexfer gone.\n"); -+ close(n); -+ filexfer_sock = -1; -+ last_filexfer = time(NULL); -+ //fprintf(stderr, "last_filexfer-2a: %d\n", last_filexfer); ++ rn = read(n, fxfer, 1*8192); ++if (db) { ++ int i; ++ fprintf(stderr, "CFX HDR:"); ++ for (i=0; i < 12; i++) { ++ fprintf(stderr, " %d", (int) fxfer[i]); ++ } ++ fprintf(stderr, " ?\n"); ++} ++ if (0 || db) fprintf(stderr, "filexfer read[%d] %d.\n", icnt, rn); ++ if (rn < 0) { ++ fprintf(stderr, "filexfer bad read: %d\n", errno); ++ break; ++ } else if (rn == 0) { ++ fprintf(stderr, "filexfer gone.\n"); ++ close(n); ++ filexfer_sock = -1; ++ last_filexfer = time(NULL); ++ //fprintf(stderr, "last_filexfer-2a: %d\n", last_filexfer); ++ appData.fileActive = False; ++ SendFramebufferUpdateRequest(0, 0, 1, 1, False); ++ return; ++ } else if (rn > 0) { ++ if (db > 1) write(2, fxfer, rn); ++ if (db) fprintf(stderr, "\n"); ++ bytes += rn; ++ last_filexfer = time(NULL); ++ //fprintf(stderr, "last_filexfer-2b: %d\n", last_filexfer); ++ if (!WriteExact(rfbsock, fxfer, rn)) { + return; -+ } else if (rn > 0) { -+ if (db) write(2, fxfer, rn); -+ if (db) fprintf(stderr, "\n"); -+ bytes += rn; -+ last_filexfer = time(NULL); -+ //fprintf(stderr, "last_filexfer-2b: %d\n", last_filexfer); -+ if (!WriteExact(rfbsock, fxfer, rn)) { -+ return; -+ } -+ igot = 1; + } ++ igot = 1; ++ } +#else -+ // not working, not always 7 msg type. -+ rn = read(n, hdr, 12); -+ if (db) fprintf(stderr, "filexfer read %d.\n", rn); -+ if (rn == 0) { -+ fprintf(stderr, "filexfer gone.\n"); -+ close(n); -+ filexfer_sock = -1; -+ last_filexfer = time(NULL); -+ return; -+ } -+ if (rn == 12) { -+ len = (hdr[8] << 24) | (hdr[9] << 16) | (hdr[10] << 8) | hdr[11]; -+ if (db) fprintf(stderr, "n=%d len=%d\n", rn, len); -+ if (db) write(2, hdr, rn); -+ if (db) fprintf(stderr, "\n"); -+ WriteExact(rfbsock, hdr, rn); -+ if (len > 0) { -+ rn = read(len, fxfer, len); -+ if (!WriteExact(rfbsock, fxfer, len)) { -+ last_filexfer = time(NULL); -+ return; -+ } -+ if (db) write(2, fxfer, len); ++ // not working, not always 7 msg type. ++ rn = read(n, hdr, 12); ++ if (db) fprintf(stderr, "filexfer read %d.\n", rn); ++ if (rn == 0) { ++ fprintf(stderr, "filexfer gone.\n"); ++ close(n); ++ filexfer_sock = -1; ++ last_filexfer = time(NULL); ++ return; ++ } ++ if (rn == 12) { ++ len = (hdr[8] << 24) | (hdr[9] << 16) | (hdr[10] << 8) | hdr[11]; ++ if (db) fprintf(stderr, "n=%d len=%d\n", rn, len); ++ if (db > 1) write(2, hdr, rn); ++ if (db) fprintf(stderr, "\n"); ++ WriteExact(rfbsock, hdr, rn); ++ if (len > 0) { ++ rn = read(len, fxfer, len); ++ if (!WriteExact(rfbsock, fxfer, len)) { ++ last_filexfer = time(NULL); ++ return; + } -+ if (db) fprintf(stderr, "\n"); -+ } else { -+ if (db) fprintf(stderr, "bad rn: %d\n", rn); ++ if (db > 1) write(2, fxfer, len); + } -+ igot = 1; -+#endif ++ if (db) fprintf(stderr, "\n"); ++ } else { ++ if (db) fprintf(stderr, "bad rn: %d\n", rn); + } ++ igot = 1; ++#endif + } ++ } + } else { + if (bytes >= 8192) { + int ok = 0; @@ -7304,6 +8196,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/sockets.c vnc_unixsrc/vncview + grace++; + bytes0 = bytes; + //fprintf(stderr, "grace: %d\n", grace); ++ // forgot that this is about... + usleep(10 * 1000); + continue; + } @@ -7315,8 +8208,13 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/sockets.c vnc_unixsrc/vncview + last_filexfer = time(NULL); + //fprintf(stderr, "last_filexfer-2c: %d\n", last_filexfer); + } ++//fprintf(stderr, "Out CheckFileXfer\n"); + return; -+} + } + ++static time_t time_mark; ++extern int delay_filexfer; ++#include <sys/stat.h> + static void ProcessXtEvents() @@ -7327,7 +8225,24 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/sockets.c vnc_unixsrc/vncview - while (!rfbsockReady) { - XtAppProcessEvent(appContext, XtIMAll); - } -+ int y; ++ int y, db = 0; ++ static int dyn = -1; ++ ++ if (dyn < 0) { ++ struct stat sb; ++ if (getenv("USER") && !strcmp(getenv("USER"), "runge")) { ++ if (stat("/tmp/nodyn", &sb) == 0) { ++ putenv("NOFTFBUPDATES=1"); ++ unlink("/tmp/nodyn"); ++ } ++ } ++ if (getenv("NOFTFBUPDATES")) { ++ dyn = 0; ++ } else { ++ dyn = 1; ++ } ++ } ++ + if (skip_XtUpdateAll) { + return; + } @@ -7376,20 +8291,89 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/sockets.c vnc_unixsrc/vncview + return; + } + -+//fprintf(stderr, "XtAppAddInput: "); + rfbsockReady = False; -+ XtAppAddInput(appContext, rfbsock, (XtPointer)XtInputReadMask, ++ xfrsockReady = False; ++ do_rfbsockId = 1; ++ rfbsockId = XtAppAddInput(appContext, rfbsock, (XtPointer)XtInputReadMask, + rfbsockReadyCallback, NULL); + -+ while (!rfbsockReady) { -+//fprintf(stderr, "."); ++ do_xfrsockId = 0; ++ if (filexfer_sock >= 0) { ++ do_xfrsockId = 1; ++ xfrsockId = XtAppAddInput(appContext, filexfer_sock, (XtPointer)XtInputReadMask, ++ xfrsockReadyCallback, NULL); ++ } ++ ++ time_mark = time(NULL); ++ ++ if (appData.fileActive) { ++ static int first = 1; ++ if (first) { ++ fprintf(stderr, "PXT: dynamic fb updates during filexfer: %d\n", dyn); ++ first = 0; ++ } ++ } ++ ++ if (db) fprintf(stderr, "XtAppAddInput: "); ++ while (!rfbsockReady && !xfrsockReady) { ++ int w = si.framebufferWidth; ++ int h = si.framebufferHeight; ++ if (db) fprintf(stderr, "."); ++ if (dyn && filexfer_sock >= 0 && time(NULL) > time_mark + delay_filexfer) { ++ SendFramebufferUpdateRequest(0, 0, w, h, False); ++ } + XtAppProcessEvent(appContext, XtIMAll); + } -+//fprintf(stderr, " done.\n"); ++ if (db) fprintf(stderr, " done. r: %d x: %d\n", rfbsockReady, xfrsockReady); ++ ++ if (xfrsockReady) { ++ CheckFileXfer(); ++ } } Bool -@@ -203,6 +404,8 @@ +@@ -191,6 +497,40 @@ + return True; + } + ++int ++ConnectToUnixSocket(char *file) { ++ int sock; ++ struct sockaddr_un addr; ++ int i; ++ ++ memset(&addr, 0, sizeof(struct sockaddr_un)); ++ ++ addr.sun_family = AF_UNIX; ++ ++ for (i=0; i < 108; i++) { ++ addr.sun_path[i] = file[i]; ++ if (file[i] == '\0') { ++ break; ++ } ++ } ++ ++ sock = socket(AF_UNIX, SOCK_STREAM, 0); ++ if (sock < 0) { ++ fprintf(stderr,programName); ++ perror(": ConnectToUnixSocket: socket"); ++ return -1; ++ } ++ ++ if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { ++ fprintf(stderr, programName); ++ perror(": ConnectToUnixSocket: connect"); ++ close(sock); ++ return -1; ++ } ++ ++ return sock; ++} ++ + + /* + * ConnectToTcpAddr connects to the given TCP port. +@@ -203,6 +543,8 @@ struct sockaddr_in addr; int one = 1; @@ -7398,7 +8382,30 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/sockets.c vnc_unixsrc/vncview addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = host; -@@ -245,6 +448,8 @@ +@@ -232,7 +574,22 @@ + return sock; + } + ++Bool SocketPair(int fd[2]) { ++ if (socketpair(PF_UNIX, SOCK_STREAM, AF_UNIX, fd) == -1) { ++ perror("socketpair"); ++ return False; ++ } ++ return True; ++} + ++Bool SetNoDelay(int sock) { ++ const int one = 1; ++ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)) < 0) { ++ perror("setsockopt"); ++ return False; ++ } ++ return True; ++} + + /* + * FindFreeTcpPort tries to find unused TCP port in the range +@@ -245,6 +602,8 @@ int sock, port; struct sockaddr_in addr; @@ -7407,7 +8414,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/sockets.c vnc_unixsrc/vncview addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; -@@ -272,6 +477,8 @@ +@@ -272,6 +631,8 @@ * ListenAtTcpPort starts listening at the given TCP port. */ @@ -7416,7 +8423,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/sockets.c vnc_unixsrc/vncview int ListenAtTcpPort(int port) { -@@ -279,10 +486,16 @@ +@@ -279,10 +640,16 @@ struct sockaddr_in addr; int one = 1; @@ -7490,8 +8497,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/tunnel.c vnc_unixsrc/vncviewe sprintf(lastArgv, "localhost::%d", localPort); diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer._man vnc_unixsrc/vncviewer/vncviewer._man --- vnc_unixsrc.orig/vncviewer/vncviewer._man 1969-12-31 19:00:00.000000000 -0500 -+++ vnc_unixsrc/vncviewer/vncviewer._man 2008-02-17 13:52:41.000000000 -0500 -@@ -0,0 +1,544 @@ ++++ vnc_unixsrc/vncviewer/vncviewer._man 2008-09-02 13:31:57.000000000 -0400 +@@ -0,0 +1,586 @@ +'\" t +.\" ** The above line should force tbl to be a preprocessor ** +.\" Man page for X vncviewer @@ -7499,38 +8506,51 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer._man vnc_unixsrc/vn +.\" Copyright (C) 1998 Marcus.Brinkmann@ruhr-uni-bochum.de +.\" Copyright (C) 2000,2001 Red Hat, Inc. +.\" Copyright (C) 2001-2003 Constantin Kaplinsky <const@ce.cctpu.edu.ru> ++.\" Copyright (C) 2006-2008 Karl J. Runge <runge@karlrunge.com> +.\" +.\" You may distribute under the terms of the GNU General Public +.\" License as specified in the file LICENCE.TXT that comes with the +.\" TightVNC distribution. +.\" -+.TH vncviewer 1 "January 2003" "" "TightVNC" ++.TH ssvncviewer 1 "August 2008" "" "SSVNC" +.SH NAME -+vncviewer \- an X viewer client for VNC ++ssvncviewer \- an X viewer client for VNC +.SH SYNOPSIS -+.B vncviewer ++.B ssvncviewer +.RI [\| options \|] +.RI [\| host \|][\| :display \|] +.br -+.B vncviewer ++.B ssvncviewer +.RI [\| options \|] +.RI [\| host \|][\| ::port \|] +.br -+.B vncviewer ++.B ssvncviewer ++.RI [\| options \|] ++.RI exec=[\| cmd+args... \|] ++.br ++.B ssvncviewer ++.RI [\| options \|] ++.RI /path/to/unix/socket ++.br ++.B ssvncviewer +.RI [\| options \|] +.IR \-listen +.RI [\| display \|] +.br -+.B vncviewer ++.B ssvncviewer +.IR \-help +.br +.SH DESCRIPTION -+.B vncviewer ++.B ssvncviewer +is an Xt\-based client application for the VNC (Virtual Network +Computing) system. It can connect to any VNC\-compatible server such -+as \fBXvnc\fR or WinVNC, allowing you to control desktop environment ++as \fBXvnc\fR, WinVNC, or \fBx11vnc\fR, allowing you to control desktop environment +of a different machine. + ++ssvncviewer is an enhanced version of the tightvnc unix viewer that can ++take advantage of features in the \fBx11vnc\fR and UltraVNC VNC servers. ++See below for the description of these features. ++ +You can use F8 to display a pop\-up utility menu. Press F8 twice to +pass single F8 to the remote side. +.SH OPTIONS @@ -7673,6 +8693,20 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer._man vnc_unixsrc/vn +.TP +Note: F9 is shortcut to Toggle FullScreen mode. +.TP ++Note: In -listen mode set the env var. SSVNC_MULTIPLE_LISTEN=1 ++to allow more than one incoming VNC server at a time. ++.TP ++Note: If the host:port is specified as "exec=command args..." ++then instead of making a TCP/IP socket connection to the ++remote VNC server, "command args..." is executed and the ++viewer is attached to its stdio. This enables tunnelling ++established via an external command, e.g. an stunnel(8) ++that does not involve a listening socket. ++This mode does not work for -listen reverse connections. ++.TP ++Note: If the host:port contains a '/' it is interpreted as a ++unix-domain socket (AF_LOCAL insead of AF_INET) ++.TP +\fB\-use64\fR +In \fB\-bgr233\fR mode, use 64 colors instead of 256. +.TP @@ -7780,40 +8814,55 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer._man vnc_unixsrc/vn +it is taken as username@password. Otherwise, the program +exits with an error. Got all that? +.TP ++\fB-repeater\fR str This is for use with UltraVNC repeater proxy described ++here: http://www.uvnc.com/addons/repeater.html. The "str" ++is the ID string to be sent to the repeater. E.g. ID:1234 ++It can also be the hostname and port or display of the VNC ++server, e.g. 12.34.56.78:0 or snoopy.com:1. Note that when ++using -repeater, the host:dpy on the cmdline is the repeater ++server, NOT the VNC server. The repeater will connect you. ++Example: vncviewer ... -repeater ID:3333 repeat.host:5900 ++Example: vncviewer ... -repeater vhost:0 repeat.host:5900 ++.TP ++\fB\-printres\fR Print out the Ssvnc X resources (appdefaults) and ++then exit. You can save them to a file and customize them (e.g. the ++keybindings and Popup menu) Then point to the file via ++XENVIRONMENT or XAPPLRESDIR. ++.TP +\fB New Popup actions:\fR + -+ ViewOnly: ~ -viewonly -+ Disable Bell: ~ -nobell -+ Cursor Shape: ~ -nocursorshape -+ X11 Cursor: ~ -x11cursor -+ Cursor Alphablend: ~ -alpha -+ Toggle Tight/ZRLE: ~ -encodings ... -+ Toggle ZRLE/ZYWRLE: ~ -encodings zywrle... -+ Quality Level ~ -quality (both Tight and ZYWRLE) -+ Compress Level ~ -compresslevel -+ Disable JPEG: ~ -nojpeg (Tight) -+ Full Color as many colors as local screen allows. -+ Grey scale (16 & 8-bpp) ~ -grey, for low colors 16/8bpp modes only. -+ 16 bit color (BGR565) ~ -16bpp / -bgr565 -+ 8 bit color (BGR233) ~ -bgr233 -+ 256 colors ~ -bgr233 default # of colors. -+ 64 colors ~ -bgr222 / -use64 -+ 8 colors ~ -bgr111 / -use8 -+ Set Y Crop (y-max) ~ -ycrop -+ Set Scrollbar Width ~ -sbwidth -+ -+ UltraVNC Extensions: -+ -+ Set 1/n Server Scale Ultravnc ext. Scale desktop by 1/n. -+ Text Chat Ultravnc ext. Do Text Chat. -+ File Transfer Ultravnc ext. File xfer via Java helper. -+ Single Window Ultravnc ext. Grab and view a single window. -+ (select then click on the window you want). -+ Disable Remote Input Ultravnc ext. Try to prevent input and -+ viewing of monitor at physical display. -+ -+ Note: the Ultravnc extensions only apply to servers that support -+ them. x11vnc/libvncserver supports some of them. ++ ViewOnly: ~ -viewonly ++ Disable Bell: ~ -nobell ++ Cursor Shape: ~ -nocursorshape ++ X11 Cursor: ~ -x11cursor ++ Cursor Alphablend: ~ -alpha ++ Toggle Tight/ZRLE: ~ -encodings ... ++ Toggle ZRLE/ZYWRLE: ~ -encodings zywrle... ++ Quality Level ~ -quality (both Tight and ZYWRLE) ++ Compress Level ~ -compresslevel ++ Disable JPEG: ~ -nojpeg (Tight) ++ Full Color ~ as many colors as local screen allows. ++ Grey scale (16 & 8-bpp) ~ -grey, for low colors 16/8bpp modes. ++ 16 bit color (BGR565) ~ -16bpp / -bgr565 ++ 8 bit color (BGR233) ~ -bgr233 ++ 256 colors ~ -bgr233 default # of colors. ++ 64 colors ~ -bgr222 / -use64 ++ 8 colors ~ -bgr111 / -use8 ++ Set Y Crop (y-max) ~ -ycrop ++ Set Scrollbar Width ~ -sbwidth ++ ++ UltraVNC Extensions: ++ ++ Set 1/n Server Scale Ultravnc ext. Scale desktop by 1/n. ++ Text Chat Ultravnc ext. Do Text Chat. ++ File Transfer Ultravnc ext. File xfer via Java helper. ++ Single Window Ultravnc ext. Grab a single window. ++ (click on the window you want). ++ Disable Remote Input Ultravnc ext. Try to prevent input and ++ viewing of monitor at physical display. ++ ++ Note: the Ultravnc extensions only apply to servers that ++ support them. x11vnc/libvncserver supports some of them. + +.SH ENCODINGS +The server supplies information in whatever format is desired by the @@ -8038,7 +9087,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer._man vnc_unixsrc/vn +Constantin Kaplinsky <const@ce.cctpu.edu.ru> diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncviewer/vncviewer.c --- vnc_unixsrc.orig/vncviewer/vncviewer.c 2004-01-13 09:22:05.000000000 -0500 -+++ vnc_unixsrc/vncviewer/vncviewer.c 2008-04-28 21:20:06.000000000 -0400 ++++ vnc_unixsrc/vncviewer/vncviewer.c 2008-09-06 16:54:58.000000000 -0400 @@ -22,6 +22,7 @@ */ @@ -8080,7 +9129,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi + *(q+i) = t[i]; + } + fallback_resources[k] = p; -+ if (db) fprintf(stderr, "res: %s\n", p); ++ if (db) fprintf(stderr, "res: %s\n\n", p); + } + } + k++; @@ -8218,7 +9267,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi /* The -listen option is used to make us a daemon process which listens for incoming connections from servers, rather than actively connecting to a -@@ -45,89 +203,1172 @@ +@@ -45,89 +203,1219 @@ listenForIncomingConnections() returns, setting the listenSpecified flag. */ @@ -8238,12 +9287,35 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi + listenForIncomingConnections(&argc, argv, i); + break; + } ++ if (strcmp(argv[i], "-multilisten") == 0) { ++ putenv("SSVNC_MULTIPLE_LISTEN=1"); ++ listenForIncomingConnections(&argc, argv, i); ++ break; ++ } + if (strcmp(argv[i], "-tunnel") == 0 || strcmp(argv[i], "-via") == 0) { + if (!createTunnel(&argc, argv, i)) { + exit(1); + } + break; + } ++ if (strcmp(argv[i], "-printres") == 0 || strcmp(argv[i], "-res") == 0) { ++ int j = 0; ++ fprintf(stdout, "\n! Ssvnc fallback X resources:\n\n"); ++ while (1) { ++ char *p = fallback_resources[j++]; ++ int k = 0; ++ if (p == NULL) break; ++ while (*p != '\0') { ++ fprintf(stdout, "%c", *p); ++ if (k > 0 && *p == 'n' && *(p-1) == '\\') { ++ fprintf(stdout, "\\\n"); ++ } ++ p++; k++; ++ } ++ fprintf(stdout, "\n\n"); ++ } ++ exit(0); ++ } + } + + if (argc > 1 && strstr(argv[1], "-h") == argv[1]) { @@ -8284,7 +9356,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi + set_sbwidth(6); + } + -+ toplevel = XtVaAppInitialize(&appContext, "Vncviewer", cmdLineOptions, ++ toplevel = XtVaAppInitialize(&appContext, "Ssvnc", cmdLineOptions, + numCmdLineOptions, &argc, argv, fallback_resources, + XtNborderWidth, 0, NULL); @@ -8524,7 +9596,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi + } + schedule_format_change(); +} -+ + +- Cleanup(); +/* + * ToggleNColors + */ @@ -8856,12 +9929,36 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi + } +} + ++extern int filexfer_sock; ++extern pid_t java_helper; ++#define KILLJAVA ++#ifdef KILLJAVA ++#include <signal.h> ++#endif ++ +void +ToggleFileXfer(Widget w, XEvent *ev, String *params, Cardinal *num_params) +{ + if (appData.fileActive) { -+ HideFile(w, ev, params, num_params); -+ appData.fileActive= False; ++ //HideFile(w, ev, params, num_params); ++ //appData.fileActive = False; ++#ifndef KILLJAVA ++ if (filexfer_sock >= 0) { ++ close(filexfer_sock); ++ } ++#else ++ if (java_helper != 0) { ++ int i; ++ for (i=1; i<=5; i++) { ++ pid_t p = java_helper + i; ++ fprintf(stderr, "trying to kill java helper: %d\n", p); ++ if (kill(p, SIGTERM) == 0) { ++ java_helper = 0; ++ break; ++ } ++ } ++ } ++#endif + } else { + ShowFile(w, ev, params, num_params); + appData.fileActive = True; @@ -8897,7 +9994,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi + int h = si.framebufferHeight; + appData.serverScale = n; + SendServerScale(n); -+ SendFramebufferUpdateRequest(0, 0, w, h, False); ++ if (0) SendFramebufferUpdateRequest(0, 0, w, h, False); + schedule_fb_update(); + } +} @@ -8923,7 +10020,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi + set_server_scale(n); + } +} -+ + +- return 0; +void set_server_quality(int n) { + fprintf(stderr, "set_quality: %d\n", n); + if (n >= 0 && n <= 9) { @@ -9344,8 +10442,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi + else + XtVaSetValues(w, XtNstate, False, NULL); +} - -- Cleanup(); ++ +void +SetCursorShapeState(Widget w, XEvent *ev, String *params, Cardinal *num_params) +{ @@ -9354,8 +10451,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi + else + XtVaSetValues(w, XtNstate, False, NULL); +} - -- return 0; ++ +void +SetCursorAlphaState(Widget w, XEvent *ev, String *params, Cardinal *num_params) +{ @@ -9429,7 +10525,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi } diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncviewer/vncviewer.h --- vnc_unixsrc.orig/vncviewer/vncviewer.h 2004-03-11 13:14:40.000000000 -0500 -+++ vnc_unixsrc/vncviewer/vncviewer.h 2008-04-28 21:08:16.000000000 -0400 ++++ vnc_unixsrc/vncviewer/vncviewer.h 2008-09-02 12:21:52.000000000 -0400 @@ -51,7 +51,7 @@ (((l) & 0x0000ff00) << 8) | \ (((l) & 0x000000ff) << 24)) : (l)) @@ -9668,7 +10764,19 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncvi /* sockets.c */ -@@ -271,3 +350,63 @@ +@@ -253,8 +332,11 @@ + extern int FindFreeTcpPort(void); + extern int ListenAtTcpPort(int port); + extern int ConnectToTcpAddr(unsigned int host, int port); ++extern int ConnectToUnixSocket(char *file); + extern int AcceptTcpConnection(int listenSock); + extern Bool SetNonBlocking(int sock); ++extern Bool SetNoDelay(int sock); ++extern Bool SocketPair(int fd[2]); + + extern int StringToIPAddr(const char *str, unsigned int *addr); + extern Bool SameMachine(int sock); +@@ -271,3 +353,63 @@ extern XtAppContext appContext; extern Display* dpy; extern Widget toplevel; @@ -9734,8 +10842,68 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncvi +extern void SetFileXferState(Widget w, XEvent *ev, String *params, Cardinal *num_params); diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.man vnc_unixsrc/vncviewer/vncviewer.man --- vnc_unixsrc.orig/vncviewer/vncviewer.man 2004-03-11 13:14:40.000000000 -0500 -+++ vnc_unixsrc/vncviewer/vncviewer.man 2008-02-17 13:52:41.000000000 -0500 -@@ -168,6 +168,159 @@ ++++ vnc_unixsrc/vncviewer/vncviewer.man 2008-09-02 13:31:57.000000000 -0400 +@@ -5,38 +5,51 @@ + .\" Copyright (C) 1998 Marcus.Brinkmann@ruhr-uni-bochum.de + .\" Copyright (C) 2000,2001 Red Hat, Inc. + .\" Copyright (C) 2001-2003 Constantin Kaplinsky <const@ce.cctpu.edu.ru> ++.\" Copyright (C) 2006-2008 Karl J. Runge <runge@karlrunge.com> + .\" + .\" You may distribute under the terms of the GNU General Public + .\" License as specified in the file LICENCE.TXT that comes with the + .\" TightVNC distribution. + .\" +-.TH vncviewer 1 "January 2003" "" "TightVNC" ++.TH ssvncviewer 1 "August 2008" "" "SSVNC" + .SH NAME +-vncviewer \- an X viewer client for VNC ++ssvncviewer \- an X viewer client for VNC + .SH SYNOPSIS +-.B vncviewer ++.B ssvncviewer + .RI [\| options \|] + .RI [\| host \|][\| :display \|] + .br +-.B vncviewer ++.B ssvncviewer + .RI [\| options \|] + .RI [\| host \|][\| ::port \|] + .br +-.B vncviewer ++.B ssvncviewer ++.RI [\| options \|] ++.RI exec=[\| cmd+args... \|] ++.br ++.B ssvncviewer ++.RI [\| options \|] ++.RI /path/to/unix/socket ++.br ++.B ssvncviewer + .RI [\| options \|] + .IR \-listen + .RI [\| display \|] + .br +-.B vncviewer ++.B ssvncviewer + .IR \-help + .br + .SH DESCRIPTION +-.B vncviewer ++.B ssvncviewer + is an Xt\-based client application for the VNC (Virtual Network + Computing) system. It can connect to any VNC\-compatible server such +-as \fBXvnc\fR or WinVNC, allowing you to control desktop environment ++as \fBXvnc\fR, WinVNC, or \fBx11vnc\fR, allowing you to control desktop environment + of a different machine. + ++ssvncviewer is an enhanced version of the tightvnc unix viewer that can ++take advantage of features in the \fBx11vnc\fR and UltraVNC VNC servers. ++See below for the description of these features. ++ + You can use F8 to display a pop\-up utility menu. Press F8 twice to + pass single F8 to the remote side. + .SH OPTIONS +@@ -168,6 +181,188 @@ \fB\-autopass\fR Read a plain-text password from stdin. This option affects only the standard VNC authentication. @@ -9750,6 +10918,20 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.man vnc_unixsrc/vnc +.TP +Note: F9 is shortcut to Toggle FullScreen mode. +.TP ++Note: In -listen mode set the env var. SSVNC_MULTIPLE_LISTEN=1 ++to allow more than one incoming VNC server at a time. ++.TP ++Note: If the host:port is specified as "exec=command args..." ++then instead of making a TCP/IP socket connection to the ++remote VNC server, "command args..." is executed and the ++viewer is attached to its stdio. This enables tunnelling ++established via an external command, e.g. an stunnel(8) ++that does not involve a listening socket. ++This mode does not work for -listen reverse connections. ++.TP ++Note: If the host:port contains a '/' it is interpreted as a ++unix-domain socket (AF_LOCAL insead of AF_INET) ++.TP +\fB\-use64\fR +In \fB\-bgr233\fR mode, use 64 colors instead of 256. +.TP @@ -9857,45 +11039,60 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.man vnc_unixsrc/vnc +it is taken as username@password. Otherwise, the program +exits with an error. Got all that? +.TP ++\fB-repeater\fR str This is for use with UltraVNC repeater proxy described ++here: http://www.uvnc.com/addons/repeater.html. The "str" ++is the ID string to be sent to the repeater. E.g. ID:1234 ++It can also be the hostname and port or display of the VNC ++server, e.g. 12.34.56.78:0 or snoopy.com:1. Note that when ++using -repeater, the host:dpy on the cmdline is the repeater ++server, NOT the VNC server. The repeater will connect you. ++Example: vncviewer ... -repeater ID:3333 repeat.host:5900 ++Example: vncviewer ... -repeater vhost:0 repeat.host:5900 ++.TP ++\fB\-printres\fR Print out the Ssvnc X resources (appdefaults) and ++then exit. You can save them to a file and customize them (e.g. the ++keybindings and Popup menu) Then point to the file via ++XENVIRONMENT or XAPPLRESDIR. ++.TP +\fB New Popup actions:\fR + -+ ViewOnly: ~ -viewonly -+ Disable Bell: ~ -nobell -+ Cursor Shape: ~ -nocursorshape -+ X11 Cursor: ~ -x11cursor -+ Cursor Alphablend: ~ -alpha -+ Toggle Tight/ZRLE: ~ -encodings ... -+ Toggle ZRLE/ZYWRLE: ~ -encodings zywrle... -+ Quality Level ~ -quality (both Tight and ZYWRLE) -+ Compress Level ~ -compresslevel -+ Disable JPEG: ~ -nojpeg (Tight) -+ Full Color as many colors as local screen allows. -+ Grey scale (16 & 8-bpp) ~ -grey, for low colors 16/8bpp modes only. -+ 16 bit color (BGR565) ~ -16bpp / -bgr565 -+ 8 bit color (BGR233) ~ -bgr233 -+ 256 colors ~ -bgr233 default # of colors. -+ 64 colors ~ -bgr222 / -use64 -+ 8 colors ~ -bgr111 / -use8 -+ Set Y Crop (y-max) ~ -ycrop -+ Set Scrollbar Width ~ -sbwidth -+ -+ UltraVNC Extensions: -+ -+ Set 1/n Server Scale Ultravnc ext. Scale desktop by 1/n. -+ Text Chat Ultravnc ext. Do Text Chat. -+ File Transfer Ultravnc ext. File xfer via Java helper. -+ Single Window Ultravnc ext. Grab and view a single window. -+ (select then click on the window you want). -+ Disable Remote Input Ultravnc ext. Try to prevent input and -+ viewing of monitor at physical display. -+ -+ Note: the Ultravnc extensions only apply to servers that support -+ them. x11vnc/libvncserver supports some of them. ++ ViewOnly: ~ -viewonly ++ Disable Bell: ~ -nobell ++ Cursor Shape: ~ -nocursorshape ++ X11 Cursor: ~ -x11cursor ++ Cursor Alphablend: ~ -alpha ++ Toggle Tight/ZRLE: ~ -encodings ... ++ Toggle ZRLE/ZYWRLE: ~ -encodings zywrle... ++ Quality Level ~ -quality (both Tight and ZYWRLE) ++ Compress Level ~ -compresslevel ++ Disable JPEG: ~ -nojpeg (Tight) ++ Full Color ~ as many colors as local screen allows. ++ Grey scale (16 & 8-bpp) ~ -grey, for low colors 16/8bpp modes. ++ 16 bit color (BGR565) ~ -16bpp / -bgr565 ++ 8 bit color (BGR233) ~ -bgr233 ++ 256 colors ~ -bgr233 default # of colors. ++ 64 colors ~ -bgr222 / -use64 ++ 8 colors ~ -bgr111 / -use8 ++ Set Y Crop (y-max) ~ -ycrop ++ Set Scrollbar Width ~ -sbwidth ++ ++ UltraVNC Extensions: ++ ++ Set 1/n Server Scale Ultravnc ext. Scale desktop by 1/n. ++ Text Chat Ultravnc ext. Do Text Chat. ++ File Transfer Ultravnc ext. File xfer via Java helper. ++ Single Window Ultravnc ext. Grab a single window. ++ (click on the window you want). ++ Disable Remote Input Ultravnc ext. Try to prevent input and ++ viewing of monitor at physical display. ++ ++ Note: the Ultravnc extensions only apply to servers that ++ support them. x11vnc/libvncserver supports some of them. + .SH ENCODINGS The server supplies information in whatever format is desired by the client, in order to make the client as easy as possible to implement. -@@ -238,6 +391,15 @@ +@@ -238,6 +433,15 @@ \-quality and \-nojpeg options above). Tight encoding is usually the best choice for low\-bandwidth network environments (e.g. slow modem connections). @@ -12177,11 +13374,12 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zywrletemplate.c vnc_unixsrc/ +#undef ZYWRLE_SAVE_PIXEL diff -Naur vnc_unixsrc.orig/include/rfbproto.h vnc_unixsrc/include/rfbproto.h --- vnc_unixsrc.orig/include/rfbproto.h 2004-05-27 03:02:02.000000000 -0400 -+++ vnc_unixsrc/include/rfbproto.h 2007-02-18 13:04:35.000000000 -0500 -@@ -381,6 +381,10 @@ ++++ vnc_unixsrc/include/rfbproto.h 2008-09-05 17:01:18.000000000 -0400 +@@ -381,6 +381,11 @@ #define rfbBell 2 #define rfbServerCutText 3 ++#define rfbResizeFrameBuffer 4 // Modif sf@2002 + +/* http://sourceforge.net/projects/vncsessmgr */ +#define rfbRestartConnection 82 @@ -12189,7 +13387,7 @@ diff -Naur vnc_unixsrc.orig/include/rfbproto.h vnc_unixsrc/include/rfbproto.h #define rfbFileListData 130 #define rfbFileDownloadData 131 #define rfbFileUploadCancel 132 -@@ -403,6 +407,18 @@ +@@ -403,6 +408,18 @@ #define rfbPointerEvent 5 #define rfbClientCutText 6 @@ -12208,7 +13406,7 @@ diff -Naur vnc_unixsrc.orig/include/rfbproto.h vnc_unixsrc/include/rfbproto.h #define rfbFileListRequest 130 #define rfbFileDownloadRequest 131 #define rfbFileUploadRequest 132 -@@ -435,6 +451,11 @@ +@@ -435,6 +452,11 @@ #define rfbEncodingTight 7 #define rfbEncodingZlibHex 8 @@ -12220,7 +13418,7 @@ diff -Naur vnc_unixsrc.orig/include/rfbproto.h vnc_unixsrc/include/rfbproto.h /* signatures for basic encoding types */ #define sig_rfbEncodingRaw "RAW_____" #define sig_rfbEncodingCopyRect "COPYRECT" -@@ -955,6 +976,36 @@ +@@ -955,6 +977,51 @@ #define sz_rfbFileDownloadFailedMsg 4 /*----------------------------------------------------------------------------- @@ -12254,10 +13452,25 @@ diff -Naur vnc_unixsrc.orig/include/rfbproto.h vnc_unixsrc/include/rfbproto.h +#define rfbTextChatFinished 0xFFFFFFFD + +/*----------------------------------------------------------------------------- ++ * Modif sf@2002 ++ * ResizeFrameBuffer - The Client must change the size of its framebuffer ++ */ ++ ++typedef struct _rfbResizeFrameBufferMsg { ++ CARD8 type; /* always rfbResizeFrameBuffer */ ++ CARD8 pad1; ++ CARD16 framebufferWidth; // FrameBuffer width ++ CARD16 framebufferHeight; // FrameBuffer height ++} rfbResizeFrameBufferMsg; ++ ++#define sz_rfbResizeFrameBufferMsg 6 ++ ++ ++/*----------------------------------------------------------------------------- * Union of all server->client messages. */ -@@ -968,6 +1019,8 @@ +@@ -968,6 +1035,8 @@ rfbFileDownloadDataMsg fdd; rfbFileUploadCancelMsg fuc; rfbFileDownloadFailedMsg fdf; @@ -12266,7 +13479,7 @@ diff -Naur vnc_unixsrc.orig/include/rfbproto.h vnc_unixsrc/include/rfbproto.h } rfbServerToClientMsg; -@@ -1221,6 +1274,41 @@ +@@ -1221,6 +1290,41 @@ #define sz_rfbFileCreateDirRequestMsg 4 @@ -12308,7 +13521,7 @@ diff -Naur vnc_unixsrc.orig/include/rfbproto.h vnc_unixsrc/include/rfbproto.h /*----------------------------------------------------------------------------- * Union of all client->server messages. */ -@@ -1241,4 +1329,9 @@ +@@ -1241,4 +1345,9 @@ rfbFileDownloadCancelMsg fdc; rfbFileUploadFailedMsg fuf; rfbFileCreateDirRequestMsg fcdr; |