From a8453eea8b0f0e5a2754582f369044fc01ef2d79 Mon Sep 17 00:00:00 2001 From: runge Date: Wed, 18 Nov 2009 18:32:08 -0500 Subject: [PATCH] ssvnc/enhanced_tightvnc_viewer update. --- x11vnc/misc/enhanced_tightvnc_viewer/README | 49 +- .../Windows/util/connect_br.tcl | 835 +++++- .../misc/enhanced_tightvnc_viewer/bin/ssvnc | 46 +- .../enhanced_tightvnc_viewer/bin/ssvnc_cmd | 11 +- .../bin/util/ss_vncviewer | 911 ++++++- .../bin/util/ssvnc.tcl | 2292 +++++++++++++---- .../man/man1/ssvncviewer.1 | 22 +- .../src/patches/_bundle | 2 +- .../src/patches/tight-vncviewer-full.patch | 1308 ++++++---- 9 files changed, 4226 insertions(+), 1250 deletions(-) diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/README b/x11vnc/misc/enhanced_tightvnc_viewer/README index 5251637..8992aea 100644 --- a/x11vnc/misc/enhanced_tightvnc_viewer/README +++ b/x11vnc/misc/enhanced_tightvnc_viewer/README @@ -64,19 +64,29 @@ The enhanced TightVNC viewer features are: - Ability to Save and Load VNC profiles for different hosts. + - You can also use your own VNC Viewer, e.g. UltraVNC or RealVNC, + with the front-end GUI or scripts if you like. + - Create or Import SSL Certificates and Private Keys. - Reverse (viewer listening) VNC connections via SSL and SSH. + - VeNCrypt SSL/TLS VNC encryption support (used by VeNCrypt, + QEMU, ggi, libvirt/virt-manager/xen, vinagre/gvncviewer/gtk-vnc) + + - ANONTLS SSL/TLS VNC encryption support (used by Vino) + + - VeNCrypt and ANONTLS are also enabled for any 3rd party VNC + Viewer (e.g. RealVNC, TightVNC, UltraVNC ...) on Unix, MacOSX, + and Windows via the provided SSVNC VeNCrypt Viewer Bridge tool + (use 'Change VNC Viewer' to select the one you want.) + - 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. @@ -131,11 +141,6 @@ The enhanced TightVNC viewer features are: - Option "-unixpw ..." for use with "x11vnc -unixpw" login dialogs. - - VeNCrypt SSL/TLS VNC encryption support (used by VeNCrypt, - QEMU, ggi, libvirt/virt-manager/xen, vinagre/gvncviewer/gtk-vnc) - - - ANONTLS SSL/TLS VNC encryption support (used by vino) - - Support for UltraVNC extensions: Single Window, Disable Server-side Input, 1/n Server side scaling, Text Chat (shell terminal UI). Both UltraVNC and x11vnc servers support these @@ -152,12 +157,13 @@ The enhanced TightVNC viewer features are: SC I, and SSL encrypted: SC III) - Support for UltraVNC DSM Encryption Plugin mode. (ARC4 and - AESV2, and MSRC4) + AESV2, MSRC4, and SecureVNC) - - Support for UltraVNC MS-Logon authentication (NOTE: the UltraVNC - MS-Logon key exchange implementation is very weak; an eavesdropper - on the network can recover your Windows password easily; you - need to use an additional encrypted tunnel with MS-Logon.) + - Support for UltraVNC MS-Logon authentication (NOTE: the + UltraVNC MS-Logon key exchange implementation is very weak; an + eavesdropper on the network can recover your Windows password + easily in a few seconds; you need to use an additional encrypted + tunnel with MS-Logon.) - Support for symmetric encryption (including blowfish and 3des ciphers) to Non-UltraVNC Servers. Any server using the same @@ -173,6 +179,11 @@ The enhanced TightVNC viewer features are: long periods of time a listening port on the the local (VNC viewer) side that redirects to the remote side. + - Reverse (viewer listening) VNC connections can show a + Popup dialog asking whether to accept the connection or not + (-acceptpopup.) The extra info provided by UltraVNC Single Click + reverse connections is also supported (-acceptpopupsc) + - Extremely low color modes: 64 and 8 colors in 8bpp (-use64/-bgr222, -use8/-bgr111) @@ -244,7 +255,7 @@ Unix and Mac OS X: Unpack the archive: - % gzip -dc ssvnc-1.0.24.tar.gz | tar xvf - + % gzip -dc ssvnc-1.0.25.tar.gz | tar xvf - Run the GUI: @@ -252,7 +263,7 @@ Unix and Mac OS X: % ./ssvnc/MacOSX/ssvnc (for Mac OS X) - The smaller file "ssvnc_no_windows-1.0.24.tar.gz" + The smaller file "ssvnc_no_windows-1.0.25.tar.gz" could have been used as well. On MacOSX you could also click on the SSVNC app icon in the Finder. @@ -298,8 +309,8 @@ Unix/MacOSX Install: For the conventional source tarball it will compile and install, e.g.: - gzip -dc ssvnc-1.0.24.src.tar.gz | tar xvf - - cd ssvnc-1.0.24 + gzip -dc ssvnc-1.0.25.src.tar.gz | tar xvf - + cd ssvnc-1.0.25 make config make all make PREFIX=/my/install/dir install @@ -311,7 +322,7 @@ Windows: Unzip, using WinZip or a similar utility, the zip file: - ssvnc-1.0.24.zip + ssvnc-1.0.25.zip Run the GUI, e.g.: @@ -323,7 +334,7 @@ Windows: select Open, and then OK to launch it. - The smaller file "ssvnc_windows_only-1.0.24.zip" + The smaller file "ssvnc_windows_only-1.0.25.zip" could have been used as well. You can make a Windows shortcut to this program if you want to. diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl index fcf140d..c363764 100755 --- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl +++ b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl @@ -11,15 +11,17 @@ proc check_callback {} { proc getout {} { global client_fh server_fh - + set delay 50 catch {flush $client_fh} after $delay catch {close $client_fh} + set client_fh "" after $delay catch {flush $server_fh} after $delay catch {close $server_fh} + set server_fh "" after $delay global bmesg_cnt @@ -37,54 +39,78 @@ proc check_closed {} { if {! $got_connection} { return } - if {$client_fh != "" && [eof $client_fh]} { - if {$debug} { - puts stderr "client_fh EOF" + if {$client_fh != ""} { + set ef "" + catch {set ef [eof $client_fh]} + if {$ef == 1} { + if {$debug} { + puts stderr "client_fh EOF" + } + getout } - getout } - if {$server_fh != "" && [eof $server_fh]} { - if {$debug} { - puts stderr "server_fh EOF" + if {$server_fh != ""} { + set ef "" + catch {set ef [eof $server_fh]} + if {$ef == 1} { + if {$debug} { + puts stderr "server_fh EOF" + } + getout } - getout } } proc xfer_in_to_out {} { - global client_fh server_fh debug + global client_fh server_fh debug do_bridge if {$client_fh != "" && ![eof $client_fh]} { - set str "" - catch {set str [read $client_fh 4096]} - if {$debug} { - puts stderr "xfer_in_to_out: $str" - } - if {$server_fh != "" && $str != ""} { - puts -nonewline $server_fh $str - flush $server_fh + set ef "" + catch {set ef [eof $client_fh]} + if {$ef == 0} { + set str "" + catch {set str [read $client_fh 4096]} + if {$debug} { + #puts stderr "xfer_in_to_out: $str" + puts stderr "xfer_in_to_out: [string length $str]" + } + if {$server_fh != "" && $str != ""} { + catch {puts -nonewline $server_fh $str} + catch {flush $server_fh} + } } } check_closed } proc xfer_out_to_in {} { - global client_fh server_fh debug - if {$server_fh != "" && ![eof $server_fh]} { - set str "" - catch {set str [read $server_fh 4096]} - if {$debug} { - puts stderr "xfer_out_to_in: $str" - } - if {$client_fh != "" && $str != ""} { - puts -nonewline $client_fh $str - flush $client_fh + global client_fh server_fh debug do_bridge + if {$server_fh != ""} { + set ef "" + catch {set ef [eof $server_fh]} + if {$ef == 0} { + set str "" + catch {set str [read $server_fh 4096]} + if {$debug} { + #puts stderr "xfer_out_to_in: $str" + puts stderr "xfer_out_to_in: [string length $str]" + } + if {$client_fh != "" && $str != ""} { + catch {puts -nonewline $client_fh $str} + catch {flush $client_fh} + } } } check_closed } proc bmesg {msg} { - return + global env + if {! [info exists env(BMESG)]} { + return + } + if {$env(BMESG) == 0} { + return + } global bmesg_cnt if {! [info exists bmesg_cnt]} { @@ -380,6 +406,560 @@ proc do_connect_repeater {sock hostport which repeater} { } } +proc vread {n sock} { + set str "" + set max 3000 + set dt 10 + set i 0 + set cnt 0 + while {$cnt < $max && $i < $n} { + incr cnt + set c [read $sock 1] + if {$c == ""} { + check_closed + after $dt + continue + } + incr i + append str $c + } + if {$i != $n} { + puts stderr "vread failure $n $i" + destroy .; exit 1 + } + return $str +} + +proc append_handshake {str} { + global env + if [info exists env(SSVNC_PREDIGESTED_HANDSHAKE)] { + set file $env(SSVNC_PREDIGESTED_HANDSHAKE) + set fh "" + catch {set fh [open $file a]} + if {$fh != ""} { + puts $fh $str + catch {close $fh} + } + } +} + +proc vencrypt_bridge_connection {fh host port} { + puts stderr "vencrypt_bridge_connection: got connection $fh $host $port" + bmesg "vencrypt_bridge_connection: got connection $fh $host $port" + global viewer_sock + set viewer_sock $fh +} + +proc center_win {w} { + update + set W [winfo screenwidth $w] + set W [expr $W + 1] + wm geometry $w +$W+0 + update + set x [expr [winfo screenwidth $w]/2 - [winfo width $w]/2] + set y [expr [winfo screenheight $w]/2 - [winfo height $w]/2] + + wm geometry $w +$x+$y + wm deiconify $w + update +} + + +proc get_user_pass {} { + global env + set up "" + if [info exists env(SSVNC_UNIXPW)] { + set rm 0 + set up $env(SSVNC_UNIXPW) + if [regexp {^rm:} $up] { + set rm 1 + regsub {^rm:} $up "" up + } + if [file exists $up] { + set fh "" + set f $up + catch {set fh [open $up r]} + if {$fh != ""} { + gets $fh u + gets $fh p + catch {close $fh} + set up "$u@$p" + } + if {$rm} { + catch {file delete $f} + } + } + } elseif [info exists env(SSVNC_VENCRYPT_USERPASS)] { + set up $env(SSVNC_VENCRYPT_USERPASS) + } + if {$up != ""} { + return $up + } + + toplevel .t + wm title .t {VeNCrypt Viewer Bridge User/Pass} + + global user pass + set user "" + set pass "" + label .t.l -text {SSVNC VeNCrypt Viewer Bridge} + + frame .t.f0 + frame .t.f0.fL + label .t.f0.fL.la -text {Username: } + label .t.f0.fL.lb -text {Password: } + + pack .t.f0.fL.la .t.f0.fL.lb -side top + + frame .t.f0.fR + entry .t.f0.fR.ea -width 24 -textvariable user + entry .t.f0.fR.eb -width 24 -textvariable pass -show * + + pack .t.f0.fR.ea .t.f0.fR.eb -side top -fill x + + pack .t.f0.fL -side left + pack .t.f0.fR -side right -expand 1 -fill x + + button .t.no -text Cancel -command {set user ""; set pass ""; destroy .t} + button .t.ok -text Done -command {destroy .t} + + center_win .t + pack .t.l .t.f0 .t.no .t.ok -side top -fill x + update + wm deiconify .t + + bind .t.f0.fR.ea {focus .t.f0.fR.eb} + bind .t.f0.fR.eb {destroy .t} + focus .t.f0.fR.ea + + wm resizable .t 1 0 + wm minsize .t [winfo reqwidth .t] [winfo reqheight .t] + + tkwait window .t + if {$user == "" || $pass == ""} { + return "" + } else { + return "$user@$pass" + } +} + +proc do_vencrypt_viewer_bridge {listen connect} { + global env + + #set env(BMESG) 1 + + vencrypt_constants + + set backwards 0 + + if {! [info exists env(SSVNC_PREDIGESTED_HANDSHAKE)]} { + puts stderr "no SSVNC_PREDIGESTED_HANDSHAKE filename in environment." + destroy .; exit 1 + } + set handshake $env(SSVNC_PREDIGESTED_HANDSHAKE) + bmesg $handshake + + if {$listen < 0} { + set backwards 1 + set listen [expr -$listen] + } + + # listen on $listen + global viewer_sock + set viewer_sock "" + set lsock "" + set rc [catch {set lsock [socket -myaddr 127.0.0.1 -server vencrypt_bridge_connection $listen]}] + if {$rc != 0} { + puts stderr "error listening on 127.0.0.1:$listen" + destroy .; exit 1 + } + bmesg "listen on $listen OK" + + # accept + vwait viewer_sock + catch {close $lsock} + fconfigure $viewer_sock -translation binary -blocking 0 + + global got_connection + set got_connection 1 + + # connect to $connect + set server_sock "" + set rc [catch {set server_sock [socket 127.0.0.1 $connect]}] + if {$rc != 0} { + puts stderr "error connecting to 127.0.0.1:$connect" + destroy .; exit 1 + } + bmesg "made connection to $connect" + fconfigure $server_sock -translation binary -blocking 0 + + if {$backwards} { + puts stderr "reversing roles of viewer and server" + set t $viewer_sock + set viewer_sock $server_sock + set server_sock $t + } + + # wait for SSVNC_PREDIGESTED_HANDSHAKE "done", put in hash. + set dt 200 + set slept 0 + set maxwait 20000 + set hs(mode) init + while {$slept < $maxwait} { + after $dt + set slept [expr $slept + $dt] + set done 0 + set fh "" + catch {set fh [open $handshake r]} + set str "" + if {$fh != ""} { + array unset hs + while {[gets $fh line] > -1} { + set line [string trim $line] + set str "$str$line\n"; + if {$line == "done"} { + set done 1 + } elseif [regexp {=} $line] { + set s [split $line "="] + set key [lindex $s 0] + set val [lindex $s 1] + set hs($key) $val + } + } + catch {close $fh} + } + if {$done} { + puts stderr $str + bmesg "$str" + break + } + } + + catch [file delete $handshake] + + if {! [info exists hs(sectype)]} { + puts stderr "no hs(sectype) found" + destroy .; exit 1 + } + + # read viewer RFB + if {! [info exists hs(server)]} { + set hs(server) "RFB 003.008" + } + puts -nonewline $viewer_sock "$hs(server)\n" + flush $viewer_sock + puts stderr "sent $hs(server) to viewer sock." + + set viewer_rfb [vread 12 $viewer_sock] + puts stderr "read viewer_rfb $viewer_rfb" + + set viewer_major 3 + set viewer_minor 8 + if [regexp {^RFB 003\.0*([0-9][0-9]*)} $viewer_rfb m v] { + set viewer_minor $v + } + + if {$hs(sectype) == $rfbSecTypeAnonTls} { + puts stderr "handling rfbSecTypeAnonTls" + if {$viewer_major > 3 || $viewer_minor >= 7} { + puts stderr "viewer >= 3.7, nothing to set up." + } else { + puts stderr "viewer <= 3.3, faking things up." + set t [vread 1 $server_sock] + binary scan $t c nsectypes + puts stderr "nsectypes=$nsectypes" + for {set i 0} {$i < $nsectypes} {incr i} { + set t [vread 1 $server_sock] + binary scan $t c st + puts stderr " $i: $st" + set types($st) $i + } + set use 1 + if [info exists types(1)] { + set use 1 + } elseif [info exists types(2)] { + set use 2 + } else { + puts stderr "no valid sectypes" + destroy .; exit 1 + } + # this should be MSB: + vsend_uchar $viewer_sock 0 + vsend_uchar $viewer_sock 0 + vsend_uchar $viewer_sock 0 + vsend_uchar $viewer_sock $use + + vsend_uchar $server_sock $use + if {$use == 1} { + set t [vread 4 $server_sock] + } + } + } elseif {$hs(sectype) == $rfbSecTypeVencrypt} { + puts stderr "handling rfbSecTypeVencrypt" + if {! [info exists hs(subtype)]} { + puts stderr "no subtype" + destroy .; exit 1 + } + set fake_type "None" + set plain 0 + + set sub_type $hs(subtype) + + + if {$sub_type == $rfbVencryptTlsNone} { + set fake_type "None" + } elseif {$sub_type == $rfbVencryptTlsVnc} { + set fake_type "VncAuth" + } elseif {$sub_type == $rfbVencryptTlsPlain} { + set fake_type "None" + set plain 1 + } elseif {$sub_type == $rfbVencryptX509None} { + set fake_type "None" + } elseif {$sub_type == $rfbVencryptX509Vnc} { + set fake_type "VncAuth" + } elseif {$sub_type == $rfbVencryptX509Plain} { + set fake_type "None" + set plain 1 + } + + if {$plain} { + set up [get_user_pass] + if [regexp {@} $up] { + set user $up + set pass $up + regsub {@.*$} $user "" user + regsub {^[^@]*@} $pass "" pass + vsend_uchar $server_sock 0 + vsend_uchar $server_sock 0 + vsend_uchar $server_sock 0 + vsend_uchar $server_sock [string length $user] + vsend_uchar $server_sock 0 + vsend_uchar $server_sock 0 + vsend_uchar $server_sock 0 + vsend_uchar $server_sock [string length $pass] + puts stderr "sending VencryptPlain user and pass." + puts -nonewline $server_sock $user + puts -nonewline $server_sock $pass + flush $server_sock + } + } + set ft 0 + if {$fake_type == "None"} { + set ft 1 + } elseif {$fake_type == "VncAuth"} { + set ft 2 + } else { + puts stderr "no valid fake_type" + destroy .; exit 1 + } + + if {$viewer_major > 3 || $viewer_minor >= 7} { + vsend_uchar $viewer_sock 1 + vsend_uchar $viewer_sock $ft + set t [vread 1 $viewer_sock] + binary scan $t c cr + if {$cr != $ft} { + puts stderr "client selected wront type $cr $ft" + destroy .; exit 1 + } + } else { + puts stderr "viewer <= 3.3, faking things up." + # this should be MSB: + vsend_uchar $viewer_sock 0 + vsend_uchar $viewer_sock 0 + vsend_uchar $viewer_sock 0 + vsend_uchar $viewer_sock $ft + + if {$ft == 1} { + set t [vread 4 $server_sock] + } + } + } + + global client_fh server_fh + set client_fh $viewer_sock + set server_fh $server_sock + + fileevent $client_fh readable xfer_in_to_out + fileevent $server_fh readable xfer_out_to_in +} + +proc vsend_uchar {sock n} { + set s [binary format c $n] + puts -nonewline $sock $s + flush $sock +} + +proc vencrypt_constants {} { + uplevel { + set rfbSecTypeAnonTls 18 + set rfbSecTypeVencrypt 19 + + set rfbVencryptPlain 256 + set rfbVencryptTlsNone 257 + set rfbVencryptTlsVnc 258 + set rfbVencryptTlsPlain 259 + set rfbVencryptX509None 260 + set rfbVencryptX509Vnc 261 + set rfbVencryptX509Plain 262 + } +} + +proc do_vencrypt {sock which} { + + vencrypt_constants + + set t [vread 1 $sock] + binary scan $t c vs_major + set t [vread 1 $sock] + binary scan $t c vs_minor + + if {$vs_minor == "" || $vs_major == "" || $vs_major != 0 || $vs_minor < 2} { + puts stderr "vencrypt failure bad vs version major=$major minor=$minor" + destroy .; exit 1 + } + puts stderr "server vencrypt version $vs_major.$vs_minor" + bmesg "server vencrypt version $vs_major.$vs_minor" + + append_handshake "subversion=0.2" + vsend_uchar $sock 0 + vsend_uchar $sock 2 + + set t [vread 1 $sock] + binary scan $t c result + if {$result != 0} { + puts stderr "vencrypt failed result: $result" + bmesg "vencrypt failed result: $result" + destroy .; exit 1 + } + + set t [vread 1 $sock] + binary scan $t c nsubtypes + puts stderr "nsubtypes: $nsubtypes" + bmesg "nsubtypes: $nsubtypes" + + for {set i 0} {$i < $nsubtypes} {incr i} { + set t [vread 4 $sock] + binary scan $t I stype + puts stderr "subtypes: $i: $stype" + append_handshake "sst$i=$stype" + set subtypes($stype) $i + } + + set subtype 0 + if [info exists subtypes($rfbVencryptX509None)] { + set subtype $rfbVencryptX509None + puts stderr "selected rfbVencryptX509None" + } elseif [info exists subtypes($rfbVencryptX509Vnc)] { + set subtype $rfbVencryptX509Vnc + puts stderr "selected rfbVencryptX509Vnc" + } elseif [info exists subtypes($rfbVencryptX509Plain)] { + set subtype $rfbVencryptX509Plain + puts stderr "selected rfbVencryptX509Plain" + } elseif [info exists subtypes($rfbVencryptTlsNone)] { + set subtype $rfbVencryptTlsNone + puts stderr "selected rfbVencryptTlsNone" + } elseif [info exists subtypes($rfbVencryptTlsVnc)] { + set subtype $rfbVencryptTlsVnc + puts stderr "selected rfbVencryptTlsVnc" + } elseif [info exists subtypes($rfbVencryptTlsPlain)] { + set subtype $rfbVencryptTlsPlain + puts stderr "selected rfbVencryptTlsPlain" + } + append_handshake "subtype=$subtype" + set st [binary format I $subtype] + puts -nonewline $sock $st + flush $sock + + if {$subtype == 0} { + puts stderr "vencrypt could not find an acceptable subtype: $subtype" + destroy .; exit 1 + } + + set t [vread 1 $sock] + binary scan $t c result + puts stderr "result=$result" + + append_handshake "done" + + if {$result == 0} { + puts stderr "vencrypt failure result: $result" + destroy .; exit 1 + } + +} + +proc do_connect_vencrypt {sock hostport which} { + global debug cur_proxy + + vencrypt_constants + + puts stderr "pxy=$which vencrypt $hostport via $cur_proxy" + bmesg "V: $which vencrypt $hostport via $cur_proxy" + + append_handshake "mode=connect" + + set srfb [vread 12 $sock] + puts stderr "srfb: $srfb" + bmesg "srfb: $srfb" + set srfb [string trim $srfb] + append_handshake "server=$srfb" + + set minor "" + if [regexp {^RFB 00[456]\.} $srfb] { + set minor 8 + } elseif [regexp {^RFB 003\.0*([0-9][0-9]*)} $srfb mvar minor] { + ; + } + if {$minor == "" || $minor < 7} { + puts stderr "vencrypt failure bad minor=$minor" + destroy .; exit 1 + } + + set vrfb "RFB 003.008\n" + if {$minor == 7} { + set vrfb "RFB 003.007\n" + } + puts -nonewline $sock $vrfb + flush $sock + + set vrfb [string trim $vrfb] + append_handshake "viewer=$vrfb" + append_handshake "latency=0.10" + + set str [vread 1 $sock] + binary scan $str c nsec + puts stderr "nsec: $nsec" + bmesg "nsec: $nsec" + for {set i 0} {$i < $nsec} {incr i} { + set str [vread 1 $sock] + binary scan $str c sec + puts stderr "sec: $sec" + bmesg "sec: $sec" + set sectypes($i) $sec + } + for {set i 0} {$i < $nsec} {incr i} { + if {$sectypes($i) == $rfbSecTypeVencrypt} { + append_handshake "sectype=$rfbSecTypeVencrypt" + vsend_uchar $sock $rfbSecTypeVencrypt + after 500 + bmesg "do_vencrypt $sock $which" + do_vencrypt $sock $which + return + } + } + for {set i 0} {$i < $nsec} {incr i} { + if {$sectypes($i) == $rfbSecTypeAnonTls} { + append_handshake "sectype=$rfbSecTypeAnonTls" + vsend_uchar $sock $rfbSecTypeAnonTls + bmesg "rfbSecTypeAnonTls" + after 500 + append_handshake "done" + return + } + } +} + proc do_connect {sock type hostport which} { if {$type == "http"} { do_connect_http $sock $hostport $which @@ -390,6 +970,8 @@ proc do_connect {sock type hostport which} { } elseif [regexp -nocase {^repeater:} $type] { regsub -nocase {^repeater:} $type "" repeater do_connect_repeater $sock $hostport $which $repeater + } elseif {$type == "vencrypt"} { + do_connect_vencrypt $sock $hostport $which } } @@ -431,9 +1013,6 @@ proc handle_connection {fh host port} { fconfigure $fh -translation binary -blocking 0 fconfigure $sock -translation binary -blocking 0 - fileevent $fh readable xfer_in_to_out - fileevent $sock readable xfer_out_to_in - set cur_proxy $proxy1 if {$proxy2 != ""} { do_connect $sock $proxy1_type "$proxy2_host:$proxy2_port" 1 @@ -451,6 +1030,9 @@ proc handle_connection {fh host port} { } else { do_connect $sock $proxy1_type $dest 1 } + + fileevent $fh readable xfer_in_to_out + fileevent $sock readable xfer_out_to_in } proc proxy_type {proxy} { @@ -468,6 +1050,8 @@ proc proxy_type {proxy} { return "http" } elseif [regexp -nocase {^repeater://.*\+(.*)$} $proxy mat idstr] { return "repeater:$idstr" + } elseif [regexp -nocase {^vencrypt://} $proxy] { + return "vencrypt" } else { return "http" } @@ -482,111 +1066,132 @@ proc proxy_hostport {proxy} { return $hp } +proc setb {} { + wm withdraw . + button .b -text "CONNECT_BR" -command {destroy .} + pack .b + after 1000 check_callback +} + global env +set got_connection 0 set proxy1 "" set proxy2 "" set proxy3 "" set client_fh "" set server_fh "" - +set do_bridge 0 set debug 0 -if {$debug} { - if {! [info exists env(SSVNC_DEST)]} { - set env(SSVNC_DEST) "haystack:2037" - } - if {! [info exists env(SSVNC_PROXY)]} { - set env(SSVNC_PROXY) "haystack:2037" - } - if {! [info exists env(SSVNC_LISTEN)]} { - set env(SSVNC_LISTEN) "6789" - } -} else { - if {! [info exists env(SSVNC_DEST)]} { - destroy .; exit; - } - if {! [info exists env(SSVNC_PROXY)]} { - destroy .; exit; - } - if {! [info exists env(SSVNC_LISTEN)] && ! [info exists env(SSVNC_REVERSE)]} { - destroy .; exit; - } + +if [info exists env(CONNECT_BR_DEBUG)] { + set debug 1 } -set dest $env(SSVNC_DEST) +if [info exists env(SSVNC_VENCRYPT_VIEWER_BRIDGE)] { + set s [split $env(SSVNC_VENCRYPT_VIEWER_BRIDGE) ","] + set listen [lindex $s 0] + set connect [lindex $s 1] -if [regexp {,} $env(SSVNC_PROXY)] { - set s [split $env(SSVNC_PROXY) ","] - set proxy1 [lindex $s 0] - set proxy2 [lindex $s 1] - set proxy3 [lindex $s 2] -} else { - set proxy1 $env(SSVNC_PROXY) + setb + + do_vencrypt_viewer_bridge $listen $connect + set do_bridge 1 } -set proxy1_type [proxy_type $proxy1] -set proxy1_hp [proxy_hostport $proxy1] +if {$do_bridge} { + ; +} else { + if {$debug && 0} { + if {! [info exists env(SSVNC_DEST)]} { + set env(SSVNC_DEST) "haystack:2037" + } + if {! [info exists env(SSVNC_PROXY)]} { + set env(SSVNC_PROXY) "haystack:2037" + } + if {! [info exists env(SSVNC_LISTEN)]} { + set env(SSVNC_LISTEN) "6789" + } + } else { + if {! [info exists env(SSVNC_DEST)]} { + destroy .; exit; + } + if {! [info exists env(SSVNC_PROXY)]} { + destroy .; exit; + } + if {! [info exists env(SSVNC_LISTEN)] && ! [info exists env(SSVNC_REVERSE)]} { + destroy .; exit; + } + } -set s [split $proxy1_hp ":"] -set proxy1_host [lindex $s 0] -set proxy1_port [lindex $s 1] + #set env(BMESG) 1 -set proxy2_type "" -set proxy2_host "" -set proxy2_port "" + set dest $env(SSVNC_DEST) -if {$proxy2 != ""} { - set proxy2_type [proxy_type $proxy2] - set proxy2_hp [proxy_hostport $proxy2] - set s [split $proxy2_hp ":"] - set proxy2_host [lindex $s 0] - set proxy2_port [lindex $s 1] -} + if [regexp {,} $env(SSVNC_PROXY)] { + set s [split $env(SSVNC_PROXY) ","] + set proxy1 [lindex $s 0] + set proxy2 [lindex $s 1] + set proxy3 [lindex $s 2] + } else { + set proxy1 $env(SSVNC_PROXY) + } -set proxy3_type "" -set proxy3_host "" -set proxy3_port "" + set proxy1_type [proxy_type $proxy1] + set proxy1_hp [proxy_hostport $proxy1] -if {$proxy3 != ""} { - set proxy3_type [proxy_type $proxy3] - set proxy3_hp [proxy_hostport $proxy3] - set s [split $proxy3_hp ":"] - set proxy3_host [lindex $s 0] - set proxy3_port [lindex $s 1] -} + set s [split $proxy1_hp ":"] + set proxy1_host [lindex $s 0] + set proxy1_port [lindex $s 1] -bmesg "1: '$proxy1_host' '$proxy1_port' '$proxy1_type'"; -bmesg "2: '$proxy2_host' '$proxy2_port' '$proxy2_type'"; -bmesg "3: '$proxy3_host' '$proxy3_port' '$proxy3_type'"; + set proxy2_type "" + set proxy2_host "" + set proxy2_port "" -set got_connection 0 + if {$proxy2 != ""} { + set proxy2_type [proxy_type $proxy2] + set proxy2_hp [proxy_hostport $proxy2] + set s [split $proxy2_hp ":"] + set proxy2_host [lindex $s 0] + set proxy2_port [lindex $s 1] + } -proc setb {} { - wm withdraw . - button .b -text "CONNECT_BR" -command {destroy .} - pack .b - after 1000 check_callback -} + set proxy3_type "" + set proxy3_host "" + set proxy3_port "" -if [info exists env(SSVNC_REVERSE)] { - set s [split $env(SSVNC_REVERSE) ":"] - set rhost [lindex $s 0] - set rport [lindex $s 1] - set rc [catch {set lsock [socket $rhost $rport]}] - if {$rc != 0} { - puts stderr "error reversing" - destroy .; exit 1 + if {$proxy3 != ""} { + set proxy3_type [proxy_type $proxy3] + set proxy3_hp [proxy_hostport $proxy3] + set s [split $proxy3_hp ":"] + set proxy3_host [lindex $s 0] + set proxy3_port [lindex $s 1] } - puts stderr "SSVNC_REVERSE to $rhost $rport OK"; - setb - handle_connection $lsock $rhost $rport -} else { - set lport $env(SSVNC_LISTEN) - set rc [catch {set lsock [socket -myaddr 127.0.0.1 -server handle_connection $lport]}] - if {$rc != 0} { - puts stderr "error listening" - destroy .; exit 1 + + bmesg "1: '$proxy1_host' '$proxy1_port' '$proxy1_type'"; + bmesg "2: '$proxy2_host' '$proxy2_port' '$proxy2_type'"; + bmesg "3: '$proxy3_host' '$proxy3_port' '$proxy3_type'"; + + if [info exists env(SSVNC_REVERSE)] { + set s [split $env(SSVNC_REVERSE) ":"] + set rhost [lindex $s 0] + set rport [lindex $s 1] + set rc [catch {set lsock [socket $rhost $rport]}] + if {$rc != 0} { + puts stderr "error reversing" + destroy .; exit 1 + } + puts stderr "SSVNC_REVERSE to $rhost $rport OK"; + setb + handle_connection $lsock $rhost $rport + } else { + set lport $env(SSVNC_LISTEN) + set rc [catch {set lsock [socket -myaddr 127.0.0.1 -server handle_connection $lport]}] + if {$rc != 0} { + puts stderr "error listening" + destroy .; exit 1 + } + puts stderr "SSVNC_LISTEN on $lport OK"; + setb } - puts stderr "SSVNC_LISTEN on $lport OK"; - setb } diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc b/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc index bf09e19..f592ef1 100755 --- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc +++ b/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc @@ -97,6 +97,42 @@ OPTIONS END exit 0 fi +if [ "X$1" = "X-ssh" ]; then + if [ "X$2" = "X-help" -o "X$2" = "X-h" ]; then + cat << END +sshvnc - a GUI wrapper for SSH VNC connections. + +SYNOPSIS + sshvnc + sshvnc [host][:display] + sshvnc [saved-profile-name] + sshvnc [options] [host-or-profile] + sshvnc --help + +See 'ssvnc $2' and 'ssvnc --help' for more information. +END + exit 0 + fi +fi + +if [ "X$1" = "X-ts" -o "X$1" = "X-tso" ]; then + if [ "X$2" = "X-help" -o "X$2" = "X-h" ]; then + cat << END +tsvnc - a GUI wrapper for SSH VNC connections using x11vnc Terminal Services. + +SYNOPSIS + tsvnc + tsvnc [host][:display] + tsvnc [saved-profile-name] + tsvnc [options] [host-or-profile] + tsvnc --help + +See 'ssvnc $2' and 'tsvnc --help' for more information. +END + exit 0 + fi +fi + if [ "X$XTERM_PRINT" != "X" ]; then XTERM_PRINT="" @@ -113,9 +149,10 @@ PATH=$PATH:/usr/bin:/bin:/usr/bin/X11:/usr/X11R6/bin:/usr/openwin/bin:/usr/sfw/b export PATH if [ "X$FULLNAME" = "XKarl J. Runge" ]; then - VNCVIEWER_POPUP_FIX=1 - export VNCVIEWER_POPUP_FIX - + if [ "X$NOPOPUFIX" = "X" ]; then + VNCVIEWER_POPUP_FIX=1 + export VNCVIEWER_POPUP_FIX + fi PATH=`echo "$PATH" | sed -e 's,runge/bin/override,-------------,'` fi @@ -123,11 +160,12 @@ if [ "X$WISH" = "X" ]; then WISH=wish for try in wish8.4 wish wish8.3 wish8.5 wish8.6 do - if type $try > /dev/null; then + if type $try > /dev/null 2>&1; then WISH=$try break fi done + export WISH fi diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd b/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd index 8c3f054..7b5e62b 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-2008 by Karl J. Runge +# Copyright (c) 2006-2009 by Karl J. Runge # # ssvnc_cmd: # @@ -50,7 +50,7 @@ # # See the TightVNC viewer documentation for on its cmdline arguments. # -# For convenience, here is the current (7/2006) TightVNC viewer -help output: +# For convenience, here is the TightVNC 1.3dev5 viewer -help output: # # TightVNC viewer version 1.3dev5 # @@ -98,9 +98,10 @@ PATH=$PATH:/usr/bin:/bin export PATH if [ "X$FULLNAME" = "XKarl J. Runge" ]; then - VNCVIEWER_POPUP_FIX=1 - export VNCVIEWER_POPUP_FIX - + if [ "X$NOPOPUFIX" = "X" ]; then + VNCVIEWER_POPUP_FIX=1 + export VNCVIEWER_POPUP_FIX + fi PATH=`echo "$PATH" | sed -e 's,runge/bin/override,-------------,'` fi diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer b/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer index ed9e333..7ad1811 100755 --- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer +++ b/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer @@ -3,8 +3,24 @@ # ss_vncviewer: wrapper for vncviewer to use an stunnel SSL tunnel # or an SSH tunnel. # -# Copyright (c) 2006-2008 by Karl J. Runge +# Copyright (c) 2006-2009 by Karl J. Runge # +# ss_vncviewer is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# ss_vncviewer is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with ss_vncviewer; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA +# or see . +# +# # You must have stunnel(8) installed on the system and in your PATH # (however, see the -ssh option below, in which case you will need ssh(1) # installed) Note: stunnel is usually installed in an "sbin" subdirectory. @@ -129,7 +145,7 @@ fi # # turn on verbose debugging output -if [ "X$SS_DEBUG" != "X" ]; then +if [ "X$SS_DEBUG" != "X" -a "X$SS_DEBUG" != "X0" ]; then set -xv fi @@ -219,10 +235,12 @@ if [ "X$1" = "X-viewerflavor" ]; then str=`$VNCVIEWERCMD -h 2>&1 | head -n 5` if echo "$str" | grep -i 'TightVNC.viewer' > /dev/null; then echo "tightvnc" - elif echo "$str" | grep -i 'RealVNC.Ltd' > /dev/null; then - echo "realvnc4" elif echo "$str" | grep -i 'VNC viewer version 3' > /dev/null; then echo "realvnc3" + elif echo "$str" | grep -i 'VNC viewer .*Edition 4' > /dev/null; then + echo "realvnc4" + elif echo "$str" | grep -i 'RealVNC.Ltd' > /dev/null; then + echo "realvnc4" else echo "unknown" fi @@ -442,7 +460,12 @@ if echo "$proxy" | egrep "vencrypt://" > /dev/null; then vtmp=`mytmp "$vtmp"` SSVNC_PREDIGESTED_HANDSHAKE="$vtmp" export SSVNC_PREDIGESTED_HANDSHAKE - #echo "SSVNC_PREDIGESTED_HANDSHAKE=$SSVNC_PREDIGESTED_HANDSHAKE" + if [ "X$SSVNC_USE_OURS" = "X" ]; then + NEED_VENCRYPT_VIEWER_BRIDGE=1 + fi +fi +if [ "X$SSVNC_USE_OURS" = "X" ]; then + VNCVIEWERCMD_EXTRA_OPTS="" fi @@ -658,6 +681,9 @@ final() { if [ "X$tail_pid" != "X" ]; then kill -TERM $tail_pid fi + if [ "X$tail_pid2" != "X" ]; then + kill -TERM $tail_pid2 + fi } if [ "X$reverse" = "X" ]; then @@ -755,17 +781,30 @@ pcode() { cod='#!/usr/bin/perl -# A hack to glue stunnel to a Web proxy or SOCKS for client connections. +# A hack to glue stunnel to a Web or SOCKS proxy, UltraVNC repeater for +# client connections. +# Also acts as a VeNCrypt bridge (by redirecting to stunnel.) use IO::Socket::INET; -if (exists $ENV{PPROXY_SLEEP}) { +if (exists $ENV{PPROXY_SLEEP} && $ENV{PPROXY_SLEEP} > 0) { print STDERR "PPROXY_PID: $$\n"; sleep $ENV{PPROXY_SLEEP}; } -foreach my $var (qw(PPROXY_PROXY PPROXY_SOCKS PPROXY_DEST PPROXY_LISTEN - PPROXY_REVERSE PPROXY_REPEATER PPROXY_REMOVE PPROXY_KILLPID PPROXY_SLEEP)) { +foreach my $var (qw( + PPROXY_DEST + PPROXY_KILLPID + PPROXY_LISTEN + PPROXY_PROXY + PPROXY_REMOVE + PPROXY_REPEATER + PPROXY_REVERSE + PPROXY_SLEEP + PPROXY_SOCKS + PPROXY_VENCRYPT + PPROXY_VENCRYPT_VIEWER_BRIDGE + )) { if (0 || $ENV{SS_DEBUG} || $ENV{SSVNC_VENCRYPT_DEBUG}) { print STDERR "$var: $ENV{$var}\n"; } @@ -808,14 +847,14 @@ sub gettime { return $t; } -sub append_handshake { - my $str = shift; - if ($handshake_file) { - if (open(HSF, ">>$handshake_file")) { - print HSF $str; - close HSF; - } - } +my $listen_handle = ""; +my $sock = ""; +my $parent = $$; + +if ($ENV{PPROXY_VENCRYPT_VIEWER_BRIDGE}) { + my ($from, $to) = split(/,/, $ENV{PPROXY_VENCRYPT_VIEWER_BRIDGE}); + do_vencrypt_viewer_bridge($from, $to); + exit 0; } my ($first, $second, $third) = split(/,/, $ENV{PPROXY_PROXY}, 3); @@ -836,7 +875,7 @@ if ($third ne "") { print STDERR "\n"; -print STDERR "PPROXY v0.2: a tool for Web proxies and SOCKS connections.\n"; +print STDERR "PPROXY v0.3: a tool for Web, SOCKS, and UltraVNC proxies and VeNCrypt bridging.\n"; print STDERR "proxy_host: $proxy_host\n"; print STDERR "proxy_port: $proxy_port\n"; print STDERR "proxy_connect: $connect\n"; @@ -851,7 +890,12 @@ if (1) { print STDERR "\n"; } -my $listen_handle = ""; +sub pdie { + my $msg = shift; + kill_proxy_pids(); + die "$msg"; +} + if ($ENV{PPROXY_REVERSE} ne "") { my ($rhost, $rport) = split(/:/, $ENV{PPROXY_REVERSE}); $rport = 5900 unless $rport; @@ -861,39 +905,57 @@ if ($ENV{PPROXY_REVERSE} ne "") { Proto => "tcp" ); if (! $listen_handle) { - die "pproxy: $! -- PPROXY_REVERSE\n"; + pdie "pproxy: $! -- PPROXY_REVERSE\n"; } print STDERR "PPROXY_REVERSE: connected to $rhost $rport\n"; } elsif ($ENV{PPROXY_LISTEN} ne "") { my $listen_sock = ""; - if ($ENV{PPROXY_LISTEN} =~ /^INADDR_ANY:(.*)/) { - my $p = $1; - $listen_sock = IO::Socket::INET->new( - Listen => 2, - LocalPort => $p, - Proto => "tcp" - ); - } else { - $listen_sock = IO::Socket::INET->new( - Listen => 2, - LocalAddr => "127.0.0.1", - LocalPort => $ENV{PPROXY_LISTEN}, - Proto => "tcp" - ); + my $maxtry = 12; + my $sleep = 5; + my $p2 = ""; + for (my $i=0; $i < $maxtry; $i++) { + if ($ENV{PPROXY_LISTEN} =~ /^INADDR_ANY:(.*)/) { + my $p = $1; + $p2 = "*:$p"; + $listen_sock = IO::Socket::INET->new( + Listen => 2, + LocalPort => $p, + Proto => "tcp" + ); + } else { + $p2 = "localhost:$ENV{PPROXY_LISTEN}"; + $listen_sock = IO::Socket::INET->new( + Listen => 2, + LocalAddr => "127.0.0.1", + LocalPort => $ENV{PPROXY_LISTEN}, + Proto => "tcp" + ); + } + if (! $listen_sock) { + if ($i < $maxtry - 1) { + warn "pproxy: $!\n"; + warn "Could not listen on port $p2, retrying in $sleep seconds... (Ctrl-C to quit)\n"; + sleep $sleep; + } + } else { + last; + } } if (! $listen_sock) { - die "pproxy: $! -- PPROXY_LISTEN\n"; + pdie "pproxy: $! -- PPROXY_LISTEN\n"; } + print STDERR "pproxy: listening on $p2\n"; my $ip; ($listen_handle, $ip) = $listen_sock->accept(); + my $err = $!; + close $listen_sock; if (! $listen_handle) { - die "pproxy: $!\n"; + pdie "pproxy: $err\n"; } - close $listen_sock; } -my $sock = IO::Socket::INET->new( +$sock = IO::Socket::INET->new( PeerAddr => $proxy_host, PeerPort => $proxy_port, Proto => "tcp" @@ -902,13 +964,13 @@ my $sock = IO::Socket::INET->new( if (! $sock) { my $err = $!; unlink($0) if $ENV{PPROXY_REMOVE}; - die "pproxy: $err\n"; + pdie "pproxy: $err\n"; } unlink($0) if $ENV{PPROXY_REMOVE}; if ($ENV{PPROXY_PROXY} =~ /^vencrypt:/ && $ENV{PPROXY_LISTEN} =~ /^INADDR_ANY:/) { - print STDERR "PPROXY: vencrypt+reverse: swapping listen socket with connect socket.\n"; + print STDERR "\nPPROXY: vencrypt+reverse: swapping listen socket with connect socket.\n"; my $tmp_swap = $sock; $sock = $listen_handle; $listen_handle = $tmp_swap; @@ -935,58 +997,123 @@ if ($second ne "") { connection($connect, 1); } -$parent = $$; -$child = fork; -if (! defined $child) { +sub kill_proxy_pids() { + if ($ENV{PPROXY_VENCRYPT_VIEWER_BRIDGE}) { + return; + } if ($ENV{PPROXY_KILLPID}) { foreach my $p (split(/,/, $ENV{PPROXY_KILLPID})) { if ($p =~ /^(\+|-)/) { $p = $parent + $p; } + print STDERR "kill TERM, $p (PPROXY_KILLPID)\n"; kill "TERM", $p; } } - exit 1; } -if ($child) { - print STDERR "pproxy parent\[$$] STDIN -> socket\n"; - if ($listen_handle) { - xfer($listen_handle, $sock); - } else { - xfer(STDIN, $sock); +sub xfer { + my($in, $out) = @_; + $RIN = $WIN = $EIN = ""; + $ROUT = ""; + vec($RIN, fileno($in), 1) = 1; + vec($WIN, fileno($in), 1) = 1; + $EIN = $RIN | $WIN; + + while (1) { + my $nf = 0; + while (! $nf) { + $nf = select($ROUT=$RIN, undef, undef, undef); + } + my $len = sysread($in, $buf, 8192); + if (! defined($len)) { + next if $! =~ /^Interrupted/; + print STDERR "pproxy[$$]: $!\n"; + last; + } elsif ($len == 0) { + print STDERR "pproxy[$$]: Input is EOF.\n"; + last; + } + my $offset = 0; + my $quit = 0; + while ($len) { + my $written = syswrite($out, $buf, $len, $offset); + if (! defined $written) { + print STDERR "pproxy[$$]: Output is EOF. $!\n"; + $quit = 1; + last; + } + $len -= $written; + $offset += $written; + } + last if $quit; } - select(undef, undef, undef, 0.25); - if (kill 0, $child) { - select(undef, undef, undef, 1.5); - print STDERR "pproxy\[$$]: kill TERM $child\n"; - kill "TERM", $child; + close($out); + close($in); + print STDERR "pproxy[$$]: finished xfer.\n"; +} + +sub handler { + print STDERR "pproxy[$$]: got SIGTERM.\n"; + close $listen_handle if $listen_handle; + close $sock if $sock; + exit; +} + +sub xfer_both { + $child = fork; + + if (! defined $child) { + kill_proxy_pids(); + exit 1; } -} else { - print STDERR "pproxy child \[$$] socket -> STDOUT\n"; - if ($listen_handle) { - xfer($sock, $listen_handle); + + $SIG{TERM} = "handler"; + + if ($child) { + if ($listen_handle) { + print STDERR "pproxy parent[$$] listen_handle -> socket\n"; + xfer($listen_handle, $sock); + } else { + print STDERR "pproxy parent[$$] STDIN -> socket\n"; + xfer(STDIN, $sock); + } + select(undef, undef, undef, 0.25); + if (kill 0, $child) { + select(undef, undef, undef, 0.9); + if (kill 0, $child) { + print STDERR "pproxy[$$]: kill TERM child $child\n"; + kill "TERM", $child; + } else { + print STDERR "pproxy[$$]: child $child gone.\n"; + } + } } else { - xfer($sock, STDOUT); - } - select(undef, undef, undef, 0.25); - if (kill 0, $parent) { - select(undef, undef, undef, 1.5); - print STDERR "pproxy\[$$]: kill TERM $parent\n"; - kill "TERM", $parent; - } -} -if ($ENV{PPROXY_KILLPID} ne "") { - if ($ENV{PPROXY_KILLPID}) { - foreach my $p (split(/,/, $ENV{PPROXY_KILLPID})) { - if ($p =~ /^(\+|-)/) { - $p = $parent + $p; + select(undef, undef, undef, 0.05); + if ($listen_handle) { + print STDERR "pproxy child [$$] socket -> listen_handle\n\n"; + xfer($sock, $listen_handle); + } else { + print STDERR "pproxy child [$$] socket -> STDOUT\n\n"; + xfer($sock, STDOUT); + } + select(undef, undef, undef, 0.25); + if (kill 0, $parent) { + select(undef, undef, undef, 0.8); + if (kill 0, $parent) { + print STDERR "pproxy[$$]: kill TERM parent $parent\n"; + kill "TERM", $parent; + } else { + print STDERR "pproxy[$$]: parent $parent gone.\n"; } - print STDERR "kill TERM, $p (PPROXY_KILLPID)\n"; - kill "TERM", $p; } } + + kill_proxy_pids(); } + +xfer_both(); + exit; sub url_parse { @@ -1215,13 +1342,14 @@ sub connection { sub vdie { append_handshake("done\n"); close $sock; + kill_proxy_pids(); exit(1); } sub anontls_handshake { my ($vmode, $db) = @_; - print STDERR "PPROXY: Doing ANONTLS Handshake\n"; + print STDERR "\nPPROXY: Doing ANONTLS Handshake\n"; my $psec = pack("C", $rfbSecTypeAnonTls); syswrite($sock, $psec, 1); @@ -1233,7 +1361,7 @@ sub vencrypt_handshake { my ($vmode, $db) = @_; - print STDERR "PPROXY: Doing VeNCrypt Handshake\n"; + print STDERR "\nPPROXY: Doing VeNCrypt Handshake\n"; my $psec = pack("C", $rfbSecTypeVencrypt); @@ -1426,44 +1554,407 @@ sub vencrypt_dialog { } } -sub xfer { - my($in, $out) = @_; - $RIN = $WIN = $EIN = ""; - $ROUT = ""; - vec($RIN, fileno($in), 1) = 1; - vec($WIN, fileno($in), 1) = 1; - $EIN = $RIN | $WIN; - - while (1) { - my $nf = 0; - while (! $nf) { - $nf = select($ROUT=$RIN, undef, undef, undef); +sub append_handshake { + my $str = shift; + if ($handshake_file) { + if (open(HSF, ">>$handshake_file")) { + print HSF $str; + close HSF; } - my $len = sysread($in, $buf, 8192); - if (! defined($len)) { - next if $! =~ /^Interrupted/; - print STDERR "pproxy\[$$]: $!\n"; - last; - } elsif ($len == 0) { - print STDERR "pproxy\[$$]: Input is EOF.\n"; + } +} + +sub do_vencrypt_viewer_bridge { + my ($listen, $connect) = @_; + print STDERR "\npproxy: starting vencrypt_viewer_bridge[$$]: $listen \-> $connect\n"; + my $db = 0; + my $backwards = 0; + if ($listen < 0) { + $backwards = 1; + $listen = -$listen; + } + if ($handshake_file eq "") { + die "pproxy: vencrypt_viewer_bridge[$$]: no SSVNC_PREDIGESTED_HANDSHAKE\n"; + } + my $listen_sock; + my $maxtry = 12; + my $sleep = 5; + for (my $i=0; $i < $maxtry; $i++) { + $listen_sock = IO::Socket::INET->new( + Listen => 2, + LocalAddr => "127.0.0.1", + LocalPort => $listen, + Proto => "tcp" + ); + if (! $listen_sock) { + if ($i < $maxtry - 1) { + warn "pproxy: vencrypt_viewer_bridge[$$]: $!\n"; + warn "Could not listen on port $listen, retrying in $sleep seconds... (Ctrl-C to quit)\n"; + sleep $sleep; + } + } else { last; } - my $offset = 0; - my $quit = 0; - while ($len) { - my $written = syswrite($out, $buf, $len, $offset); - if (! defined $written) { - print STDERR "pproxy\[$$]: Output is EOF. $!\n"; - $quit = 1; + } + if (! $listen_sock) { + die "pproxy: vencrypt_viewer_bridge[$$]: $!\n"; + } + print STDERR "pproxy: vencrypt_viewer_bridge[$$]: listening on port $listen\n\n"; + my ($viewer_sock, $ip) = $listen_sock->accept(); + my $err = $!; + close $listen_sock; + if (! $viewer_sock) { + die "pproxy: vencrypt_viewer_bridge[$$]: $err\n"; + } + print STDERR "vencrypt_viewer_bridge[$$]: viewer_sock $viewer_sock\n" if $db; + + print STDERR "pproxy: vencrypt_viewer_bridge[$$]: connecting to 127.0.0.1:$connect\n"; + my $server_sock = IO::Socket::INET->new( + PeerAddr => "127.0.0.1", + PeerPort => $connect, + Proto => "tcp" + ); + print STDERR "vencrypt_viewer_bridge[$$]: server_sock $server_sock\n" if $db; + if (! $server_sock) { + my $err = $!; + die "pproxy: vencrypt_viewer_bridge[$$]: $err\n"; + } + + if ($backwards) { + print STDERR "vencrypt_viewer_bridge[$$]: reversing roles of viewer and server.\n"; + my $t = $viewer_sock; + $viewer_sock = $server_sock; + $server_sock = $t; + } + + my %hs = (); + my $dt = 0.2; + my $slept = 0.0; + while ($slept < 20.0) { + select(undef, undef, undef, $dt); + $slept += $dt; + if (-f $handshake_file && open(HSF, "<$handshake_file")) { + my $done = 0; + %hs = (); + my $str = ""; + while () { + print STDERR "vencrypt_viewer_bridge[$$]: $_" if $ENV{VENCRYPT_VIEWER_BRIDGE_DEBUG}; + $str .= "vencrypt_viewer_bridge[$$]: $_"; + chomp; + if ($_ eq "done") { + $done = 1; + } else { + my ($k, $v) = split(/=/, $_, 2); + if ($k ne "" && $v ne "") { + $hs{$k} = $v; + } + } + } + close HSF; + if ($done) { + print STDERR "\n" . $str; last; } - $len -= $written; - $offset += $written; } - last if $quit; } - close($in); - close($out); + if (! exists $hs{server}) { + $hs{server} = "RFB 003.008"; + } + if (! exists $hs{sectype}) { + unlink($handshake_file); + die "pproxy: vencrypt_viewer_bridge[$$]: no sectype.\n"; + } + syswrite($viewer_sock, "$hs{server}\n", length($hs{server}) + 1); + my $viewer_rfb = ""; + for (my $i = 0; $i < 12; $i++) { + my $c; + sysread($viewer_sock, $c, 1); + $viewer_rfb .= $c; + print STDERR $c; + } + my $viewer_major = 3; + my $viewer_minor = 8; + if ($viewer_rfb =~ /RFB (\d+)\.(\d+)/) { + $viewer_major = $1; + $viewer_minor = $2; + } + my $u0 = pack("C", 0); + my $u1 = pack("C", 1); + my $u2 = pack("C", 2); + if ($hs{sectype} == $rfbSecTypeAnonTls) { + unlink($handshake_file); + print STDERR "\npproxy: vencrypt_viewer_bridge[$$]: rfbSecTypeAnonTls\n"; + if ($viewer_major > 3 || $viewer_minor >= 7) { + ; # setup ok, proceed to xfer. + } else { + print STDERR "pproxy: vencrypt_viewer_bridge[$$]: faking RFB version 3.3 to viewer.\n"; + my $n; + sysread($server_sock, $n, 1); + $n = unpack("C", $n); + if ($n == 0) { + die "pproxy: vencrypt_viewer_bridge[$$]: nsectypes == $n.\n"; + } + my %types; + for (my $i = 0; $i < $n; $i++) { + my $t; + sysread($server_sock, $t, 1); + $t = unpack("C", $t); + $types{$t} = 1; + } + my $use = 1; # None + if (exists $types{1}) { + $use = 1; # None + } elsif (exists $types{2}) { + $use = 2; # VncAuth + } else { + die "pproxy: vencrypt_viewer_bridge[$$]: no valid sectypes" . join(",", keys %types) . "\n"; + } + + # send 4 bytes sectype to viewer: + # (note this should be MSB, network byte order...) + my $up = pack("C", $use); + syswrite($viewer_sock, $u0, 1); + syswrite($viewer_sock, $u0, 1); + syswrite($viewer_sock, $u0, 1); + syswrite($viewer_sock, $up, 1); + # and tell server the one we selected: + syswrite($server_sock, $up, 1); + if ($use == 1) { + # even None has security result, so read it here and discard it. + my $sr = ""; + sysread($server_sock, $sr, 4); + } + } + } elsif ($hs{sectype} == $rfbSecTypeVencrypt) { + print STDERR "\npproxy: vencrypt_viewer_bridge[$$]: rfbSecTypeVencrypt\n"; + if (! exists $hs{subtype}) { + unlink($handshake_file); + die "pproxy: vencrypt_viewer_bridge[$$]: no subtype.\n"; + } + my $fake_type = "None"; + my $plain = 0; + my $sub_type = $hs{subtype}; + if ($sub_type == $rfbVencryptTlsNone) { + $fake_type = "None"; + } elsif ($sub_type == $rfbVencryptTlsVnc) { + $fake_type = "VncAuth"; + } elsif ($sub_type == $rfbVencryptTlsPlain) { + $fake_type = "None"; + $plain = 1; + } elsif ($sub_type == $rfbVencryptX509None) { + $fake_type = "None"; + } elsif ($sub_type == $rfbVencryptX509Vnc) { + $fake_type = "VncAuth"; + } elsif ($sub_type == $rfbVencryptX509Plain) { + $fake_type = "None"; + $plain = 1; + } + if ($plain) { + if (!open(W, ">$handshake_file")) { + unlink($handshake_file); + die "pproxy: vencrypt_viewer_bridge[$$]: $handshake_file $!\n"; + } + print W <<"END"; + + proc print_out {} { + global user pass env + + if [info exists env(SSVNC_UP_DEBUG)] { + toplevel .b + button .b.b -text "user=\$user pass=\$pass" -command {destroy .b} + pack .b.b + update + tkwait window .b + } + + if [info exists env(SSVNC_UP_FILE)] { + set fh "" + catch {set fh [open \$env(SSVNC_UP_FILE) w]} + if {\$fh != ""} { + puts \$fh user=\$user\\npass=\$pass + flush \$fh + close \$fh + return + } + } + puts stdout user=\$user\\npass=\$pass + flush stdout + } + + proc center_win {w} { + update + set W [winfo screenwidth \$w] + set W [expr \$W + 1] + wm geometry \$w +\$W+0 + update + set x [expr [winfo screenwidth \$w]/2 - [winfo width \$w]/2] + set y [expr [winfo screenheight \$w]/2 - [winfo height \$w]/2] + + wm geometry \$w +\$x+\$y + wm deiconify \$w + update + } + + wm withdraw . + + global env + set up {} + if [info exists env(SSVNC_UNIXPW)] { + set rm 0 + set up \$env(SSVNC_UNIXPW) + if [regexp {^rm:} \$up] { + set rm 1 + regsub {^rm:} \$up {} up + } + if [file exists \$up] { + set fh "" + set f \$up + catch {set fh [open \$up r]} + if {\$fh != ""} { + gets \$fh u + gets \$fh p + close \$fh + set up "\$u@\$p" + } + if {\$rm} { + catch {file delete \$f} + } + } + } elseif [info exists env(SSVNC_VENCRYPT_USERPASS)] { + set up \$env(SSVNC_VENCRYPT_USERPASS) + } + #puts stderr up=\$up + if {\$up != ""} { + if [regexp {@} \$up] { + global user pass + set user \$up + set pass \$up + regsub {@.*\$} \$user "" user + regsub {^[^@]*@} \$pass "" pass + print_out + exit + } + } + + wm title . {VeNCrypt Viewer Bridge User/Pass} + + set user {} + set pass {} + + label .l -text {SSVNC VeNCrypt Viewer Bridge} + + frame .f0 + frame .f0.fL + label .f0.fL.la -text {Username: } + label .f0.fL.lb -text {Password: } + + pack .f0.fL.la .f0.fL.lb -side top + + frame .f0.fR + entry .f0.fR.ea -width 24 -textvariable user + entry .f0.fR.eb -width 24 -textvariable pass -show * + + pack .f0.fR.ea .f0.fR.eb -side top -fill x + + pack .f0.fL -side left + pack .f0.fR -side right -expand 1 -fill x + + button .no -text Cancel -command {destroy .} + button .ok -text Done -command {print_out; destroy .} + + center_win . + pack .l .f0 .no .ok -side top -fill x + update + wm deiconify . + + bind .f0.fR.ea {focus .f0.fR.eb} + bind .f0.fR.eb {print_out; destroy .} + focus .f0.fR.ea + + wm resizable . 1 0 + wm minsize . [winfo reqwidth .] [winfo reqheight .] +END + close W; + + #system("cat $handshake_file"); + my $w = "wish"; + if ($ENV{WISH}) { + $w = $ENV{WISH}; + } + print STDERR "pproxy: vencrypt_viewer_bridge[$$]: prompt VencryptPlain user and passwd.\n"; + my $res = ""; + if (`uname` =~ /Darwin/) { + my $mtmp = `mktemp /tmp/hsup.XXXXXX`; + chomp $mtmp; + system("env SSVNC_UP_FILE=$mtmp $w $handshake_file"); + $res = `cat $mtmp`; + unlink $mtmp; + } else { + $res = `$w $handshake_file`; + } + my $user = ""; + my $pass = ""; + if ($res =~ /user=(\S*)/) { + $user = $1; + } + if ($res =~ /pass=(\S*)/) { + $pass = $1; + } + print STDERR "pproxy: vencrypt_viewer_bridge[$$]: sending VencryptPlain user and passwd.\n"; + my $ulen = pack("C", length($user)); + my $plen = pack("C", length($pass)); + # (note this should be MSB, network byte order...) + syswrite($server_sock, $u0, 1); + syswrite($server_sock, $u0, 1); + syswrite($server_sock, $u0, 1); + syswrite($server_sock, $ulen, 1); + syswrite($server_sock, $u0, 1); + syswrite($server_sock, $u0, 1); + syswrite($server_sock, $u0, 1); + syswrite($server_sock, $plen, 1); + syswrite($server_sock, $user, length($user)); + syswrite($server_sock, $pass, length($pass)); + } + unlink($handshake_file); + + my $ft = 0; + if ($fake_type eq "None") { + $ft = 1; + } elsif ($fake_type eq "VncAuth") { + $ft = 2; + } else { + die "pproxy: vencrypt_viewer_bridge[$$]: unknown fake type: $fake_type\n"; + } + my $fp = pack("C", $ft); + if ($viewer_major > 3 || $viewer_minor >= 7) { + syswrite($viewer_sock, $u1, 1); + syswrite($viewer_sock, $fp, 1); + my $cr; + sysread($viewer_sock, $cr, 1); + $cr = unpack("C", $cr); + if ($cr != $ft) { + die "pproxy: vencrypt_viewer_bridge[$$]: client selected wrong type: $cr / $ft\n"; + } + } else { + print STDERR "pproxy: vencrypt_viewer_bridge[$$]: faking RFB version 3.3 to viewer.\n"; + # send 4 bytes sect type to viewer: + # (note this should be MSB, network byte order...) + syswrite($viewer_sock, $u0, 1); + syswrite($viewer_sock, $u0, 1); + syswrite($viewer_sock, $u0, 1); + syswrite($viewer_sock, $fp, 1); + if ($ft == 1) { + # even None has security result, so read it here and discard it. + my $sr = ""; + sysread($server_sock, $sr, 4); + } + } + } + + $listen_handle = $viewer_sock; + $sock = $server_sock; + + xfer_both(); } ' # ' @@ -1549,11 +2040,33 @@ END } Kecho() { - if [ "X$USER" = "Xrunge" ]; then + NO_KECHO=1 + if [ "X$USER" = "Xrunge" -a "X$NO_KECHO" = "X" ]; then echo "dbg: $*" fi } +NHAFL_warning() { + echo "" + echo "** Warning: For the proxy: $proxy" + echo "** Warning: the ssh(1) option: $ssh_NHAFL" + echo "** Warning: will be used to avoid frequent 'ssh key has changed for localhost'" + echo "** Warning: dialogs and connection failures (for example, ssh will exit asking" + echo "** Warning: you to manually remove a key from ~/.ssh/known_hosts.)" + echo "** Warning: " + echo "** Warning: This decreases security: a Man-In-The-Middle attack is possible." + echo "** Warning: You can set the SSVNC_SSH_LOCALHOST_AUTH=1 env. var. to disable" + echo "** Warning: using the NoHostAuthenticationForLocalhost ssh option." + echo "** Warning: " + echo "** Warning: A better solution is to configure (in the SSVNC GUI) the setting:" + echo "** Warning: 'Options -> Advanced -> Private SSH KnownHosts file' (or set" + echo "** Warning: SSVNC_KNOWN_HOSTS_FILE directly) to a per-connection known hosts" + echo "** Warning: file. This yields a both secure and convenient solution." + echo "" +} + +# handle ssh case: +# if [ "X$use_ssh" = "X1" ]; then # # USING SSH @@ -1561,6 +2074,8 @@ if [ "X$use_ssh" = "X1" ]; then ssh_port="22" ssh_host="$host" vnc_host="$localhost" + ssh_UKHF="" + localhost_extra="" # let user override ssh via $SSH ssh=${SSH:-"ssh -x"} @@ -1584,6 +2099,22 @@ if [ "X$use_ssh" = "X1" ]; then fi fi + ssh_NHAFL="-o NoHostAuthenticationForLocalhost=yes" + if [ "X$SSVNC_SSH_LOCALHOST_AUTH" = "X1" ]; then + ssh_NHAFL="" + fi + if [ "X$SSVNC_KNOWN_HOSTS_FILE" != "X" ]; then + ssh_NHAFL="" + + ssh_UKHF="-o UserKnownHostsFile=$SSVNC_KNOWN_HOSTS_FILE" + ssh_args="$ssh_args $ssh_UKHF" + if [ ! -f "$SSVNC_KNOWN_HOSTS_FILE" ]; then + touch "$SSVNC_KNOWN_HOSTS_FILE" >/dev/null 2>&1 + fi + chmod 600 "$SSVNC_KNOWN_HOSTS_FILE" >/dev/null 2>&1 + fi + did_ssh_NHAFL="" + if [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" ]; then SSVNC_LIM_ACCEPT_PRELOAD="$SSVNC_BASEDIR/$SSVNC_UNAME/$SSVNC_LIM_ACCEPT_PRELOAD" fi @@ -1602,6 +2133,29 @@ if [ "X$use_ssh" = "X1" ]; then SSVNC_LIM_ACCEPT_PRELOAD="" fi + ssh_vencrypt_proxy="" + # We handle vencrypt for SSH+SSL mode. + if echo "$proxy" | grep 'vencrypt://' > /dev/null; then + proxynew="" + for part in `echo "$proxy" | tr ',' ' '` + do + if echo "$part" | egrep -i '^vencrypt://' > /dev/null; then + ssh_vencrypt_proxy=$part + else + if [ "X$proxynew" = "X" ]; then + proxynew="$part" + else + proxynew="$proxynew,$part" + fi + fi + done + proxy=$proxynew + fi + Kecho ssh_vencrypt_proxy=$ssh_vencrypt_proxy + + # note that user must supply http:// for web proxy in SSH and SSH+SSL. + # No xxxx:// implies ssh server+port. + # 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 @@ -1687,11 +2241,16 @@ if [ "X$use_ssh" = "X1" ]; then port=$port_save host=$host_save - nd=`findfree 6700` + nd=`findfree 6600` PPROXY_LISTEN=$nd; export PPROXY_LISTEN $ptmp & - sleep 2 - ssh_args="$ssh_args -o NoHostAuthenticationForLocalhost=yes" + sleep 1 + if [ "X$ssh_NHAFL" != "X" -a "X$did_ssh_NHAFL" != "X1" ]; then + NHAFL_warning + ssh_args="$ssh_args $ssh_NHAFL" + did_ssh_NHAFL=1 + fi + sleep 1 if [ "X$sproxy1" = "X" ]; then u="" if echo "$host" | grep '@' > /dev/null; then @@ -1702,6 +2261,7 @@ if [ "X$use_ssh" = "X1" ]; then else proxy="${sproxy1_user}$localhost:$nd" fi + localhost_extra=".2" if [ "X$sproxy_rest" != "X" ]; then proxy="$proxy,$sproxy_rest" fi @@ -1733,12 +2293,21 @@ if [ "X$use_ssh" = "X1" ]; then ssh_port2="22" fi proxport=`findfree 3500` + if [ "X$ssh_NHAFL" != "X" -a "X$did_ssh_NHAFL" != "X1" ]; then + NHAFL_warning + did_ssh_NHAFL=1 + sleep 1 + fi echo echo "Running 1st ssh proxy:" - echo "$ssh -f -x $ssh_port1 $targ -e none -o NoHostAuthenticationForLocalhost=yes -L $proxport:$ssh_host2:$ssh_port2 $ssh_host1 \"sleep 30\"" + ukhf="" + if [ "X$ssh_UKHF" != "X" ]; then + ukhf="$ssh_UKHF$localhost_extra" + fi + echo "$ssh -f -x $ssh_port1 $targ -e none $ssh_NHAFL $ukhf -L $proxport:$ssh_host2:$ssh_port2 $ssh_host1 \"sleep 30\"" echo "" - $ssh -f -x $ssh_port1 $targ -e none -o NoHostAuthenticationForLocalhost=yes -L $proxport:$ssh_host2:$ssh_port2 $ssh_host1 "sleep 30" - ssh_args="$ssh_args -o NoHostAuthenticationForLocalhost=yes" + $ssh -f -x $ssh_port1 $targ -e none $ssh_NHAFL $ukhf -L $proxport:$ssh_host2:$ssh_port2 $ssh_host1 "sleep 30" + ssh_args="$ssh_args $ssh_NHAFL" sleep 1 stty sane proxy="${ssh_user2}$localhost:$proxport" @@ -1813,6 +2382,8 @@ if [ "X$use_ssh" = "X1" ]; then elif [ "X$getport" != "X" ]; then tport=/tmp/ss_vncviewer_tport${RANDOM}.$$ tport=`mytmp "$tport"` + tport2=/tmp/ss_vncviewer_tport2${RANDOM}.$$ + tport2=`mytmp "$tport2"` if [ "X$rsh" != "X1" ]; then if echo "$ssh_cmd" | grep "sudo " > /dev/null; then @@ -1826,10 +2397,12 @@ if [ "X$use_ssh" = "X1" ]; then fi echo "$ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args $ssh_host \"$info\"" echo "" - $ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args $ssh_host "$ssh_cmd" > $tport + $ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args $ssh_host "$ssh_cmd" > $tport 2> $tport2 if [ "X$teeport" = "X1" ]; then - tail -f $tport 1>&2 & + tail -f $tport 1>&2 & tail_pid=$! + tail -f $tport2 1>&2 & + tail_pid2=$! fi rc=$? else @@ -1858,11 +2431,11 @@ if [ "X$use_ssh" = "X1" ]; then while [ $i -lt $imax ]; do #echo $sleepit eval $sleepit - PORT=`grep "^PORT=" $tport | head -n 1 | sed -e 's/PORT=//' -e 's/\r//g'` + PORT=`grep "^PORT=" $tport | tr '\r' ' ' | head -n 1 | sed -e 's/PORT=//' -e 's/\r//g' -e 's/ *$//'` if echo "$PORT" | grep '^[0-9][0-9]*$' > /dev/null; then break fi - vnss=`sed -e 's/\r//g' $tport | egrep -i '^(New.* desktop is|A VNC server is already running).*:[0-9[0-9]*$' | head -n 1 | awk '{print $NF}'` + vnss=`sed -e 's/\r//g' $tport $tport2 | egrep -i '^(New.* desktop is|A VNC server is already running).*:[0-9[0-9]*$' | head -n 1 | awk '{print $NF}'` if [ "X$vnss" != "X" ]; then PORT=`echo "$vnss" | awk -F: '{print $2}'` if echo "$PORT" | grep '^[0-9][0-9]*$' > /dev/null; then @@ -1871,14 +2444,16 @@ if [ "X$use_ssh" = "X1" ]; then fi fi if echo "$PORT" | grep '^[0-9][0-9]*$' > /dev/null; then + vnss=`sed -e 's/\r//g' $tport | egrep -i '^(New.* desktop is|A VNC server is already running).*:[0-9[0-9]*$' | head -n 1` + echo "vncserver string: $vnss" 1>&2 break fi fi i=`expr $i + 1` done - echo "PORT=$PORT" 1>&2 - rm -f $tport + echo "found: PORT='$PORT'" 1>&2 + rm -f $tport $tport2 if [ "X$rsh" = "X1" ]; then rsh_viewer "$@" exit $? @@ -2004,6 +2579,16 @@ if [ "X$use_ssh" = "X1" ]; then else proxy="" fi + if [ "X$ssh_vencrypt_proxy" != "X" ]; then + ssh_vencrypt_proxy="vencrypt://$host:$port" + if [ "X$proxy" = "X" ]; then + proxy=$ssh_vencrypt_proxy + else + proxy="$proxy,$ssh_vencrypt_proxy" + fi + Kecho "proxy_now=$proxy" + unset PPROXY_LISTEN + fi fi fi @@ -2034,6 +2619,9 @@ if [ "X$verify" != "X" ]; then verify="$verify verify = 2" fi +if [ "X$SSVNC_STUNNEL_VERIFY3" != "X" ]; then + verify=`echo "$verify" | sed -e 's/verify = 2/verify = 3/'` +fi if [ "X$mycert" != "X" ]; then cert="cert = $mycert" fi @@ -2063,7 +2651,6 @@ if [ "X$proxy" != "X" ]; then PPROXY_LISTEN=$nd export PPROXY_LISTEN if [ "X$reverse" = "X" ]; then - #$ptmp 2>/dev/null & $ptmp & fi sleep 2 @@ -2082,6 +2669,8 @@ else connect="connect = $host:$port" fi +# handle showcert case: +# if [ "X$showcert" = "X1" ]; then if [ "X$proxy" != "X" ]; then PPROXY_LISTEN=$use @@ -2092,6 +2681,23 @@ if [ "X$showcert" = "X1" ]; then $ptmp 2>/dev/null & fi sleep 1 + more_sleep=1 + if uname | grep Linux > /dev/null; then + if netstat -ant | grep LISTEN | grep "127.0.0.1:$use" > /dev/null; then + more_sleep="" + fi + elif uname | grep SunOS > /dev/null; then + if netstat -an -f inet -P tcp | grep LISTEN | grep "127.0.0.1.$use" > /dev/null; then + more_sleep="" + fi + elif uname | egrep -i 'bsd|darwin' > /dev/null; then + if netstat -ant -f inet | grep LISTEN | grep "127.0.0.1.$use" > /dev/null; then + more_sleep="" + fi + fi + if [ "X$more_sleep" = "X1" ]; then + sleep 1 + fi host="$localhost" port="$use" fi @@ -2114,6 +2720,15 @@ if [ "X$showcert" = "X1" ]; then fi #echo "openssl s_client $cipher_args -connect $host:$port" if [ "X$reverse" = "X" ]; then + host $host >/dev/null 2>&1 + host $host >/dev/null 2>&1 + timeout=15 + if [ "X$SSVNC_FETCH_TIMEOUT" != "X" ]; then + timeout=$SSVNC_FETCH_TIMEOUT + fi + if type pkill >/dev/null 2>&1; then + (sleep $timeout; if kill -0 $$; then pkill -TERM -f "openssl.*s_client.*$host.*$port"; fi) >/dev/null 2>&1 & + fi openssl s_client $cipher_args -prexit -connect $host:$port 2>&1 < /dev/null rc=$? else @@ -2183,6 +2798,8 @@ if [ "X$showcert" = "X1" ]; then fi fi +# handle direct connect case: +# if [ "X$direct_connect" != "X" ]; then if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then SSVNC_NO_ENC_WARN=1 @@ -2199,7 +2816,7 @@ if [ "X$direct_connect" != "X" ]; then : else echo "" - echo "** NOTE: THERE WILL BE NO SSL OR SSH ENCRYPTION **" + echo "** WARNING: THERE WILL BE NO SSL OR SSH ENCRYPTION **" echo "" fi fi @@ -2420,6 +3037,14 @@ echo "Using this stunnel configuration:" echo "" cat "$tmp_cfg" | uniq echo "" +if egrep -i '^[ ]*(CApath|CAfile) =' "$tmp_cfg" > /dev/null ; then + : +else + echo "** WARNING: THE STUNNEL CONFIG HAS NO SERVER CERTIFICATE SPECIFIED **" + echo "** WARNING: (the CApath or CAfile stunnel option) THE VNC SERVER WILL **" + echo "** WARNING: NOT BE AUTHENTICATED. A MAN-IN-THE-MIDDLE ATTACK IS POSSIBLE **" + echo "" +fi sleep 1 if [ "X$stunnel_exec" = "X" ]; then @@ -2462,8 +3087,16 @@ if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then echo "sleep $SSVNC_EXTRA_SLEEP" sleep $SSVNC_EXTRA_SLEEP fi -echo "Running viewer:" + if [ "X$reverse" = "X" ]; then + if [ "X$NEED_VENCRYPT_VIEWER_BRIDGE" = "X1" -a "X$ptmp" != "X" ] ; then + port1=`expr 5900 + $N` # stunnel port + port2=`findfree 5970` # bridge port (viewer connects to it.) + N=`expr $port2 - 5900` + env PPROXY_REMOVE=0 PPROXY_SLEEP=0 PPROXY_VENCRYPT_VIEWER_BRIDGE="$port2,$port1" $ptmp & + sleep 1 + fi + echo "Running viewer:" vnc_hp=$localhost:$N if [ "X$stunnel_exec" != "X" ]; then vnc_hp="exec=$STUNNEL $tmp_cfg" @@ -2480,19 +3113,16 @@ if [ "X$reverse" = "X" ]; then fi fi else + echo "Running viewer:" echo "" echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode." echo "" + trap "final" 0 2 15 N2=$N - if [ "X$VNCVIEWER_IS_REALVNC4" = "X1" ]; then - N2=`echo "$N2" | sed -e 's/://g'` - if [ $N2 -le 200 ]; then - N2=`expr $N2 + 5500` - fi + N2_trim=`echo "$N2" | sed -e 's/://g'` + if [ $N2_trim -le 200 ]; then + N2_trim=`expr $N2_trim + 5500` fi - echo "$VNCVIEWERCMD" "$@" -listen $N2 - trap "final" 0 2 15 - echo "" if [ "X$proxy" != "X" ]; then if echo "$proxy" | grep -i '^vencrypt:' > /dev/null; then pstunnel=`echo "$proxy" | awk -F: '{print $2}'` @@ -2502,13 +3132,30 @@ else PPROXY_DEST="$localhost:$pstunnel"; export PPROXY_DEST STUNNEL_ONCE=1; export STUNNEL_ONCE STUNNEL_MAX_CLIENTS=1; export STUNNEL_MAX_CLIENTS + if [ "X$NEED_VENCRYPT_VIEWER_BRIDGE" = "X1" -a "X$ptmp" != "X" ] ; then + port1=`expr 5500 + $N2` + port2=`findfree 5580` + N2=`expr $port2 - 5500` + N2_trim=`echo "$N2" | sed -e 's/://g'` + if [ $N2_trim -le 200 ]; then + N2_trim=`expr $N2_trim + 5500` + fi + env PPROXY_REMOVE=0 PPROXY_SLEEP=0 PPROXY_VENCRYPT_VIEWER_BRIDGE="-$port1,$port2" $ptmp & + sleep 1 + fi else PPROXY_REVERSE="$localhost:$port"; export PPROXY_REVERSE PPROXY_SLEEP=1; export PPROXY_SLEEP; fi PPROXY_KILLPID=+1; export PPROXY_KILLPID; $ptmp & + # Important to have no extra pids generated between here and VNCVIEWERCMD fi + if [ "X$VNCVIEWER_IS_REALVNC4" = "X1" ]; then + N2=$N2_trim + fi + echo "$VNCVIEWERCMD" "$@" -listen $N2 + echo "" $VNCVIEWERCMD "$@" -listen $N2 fi diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl b/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl index 48f849c..533b477 100755 --- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl +++ b/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl @@ -8,7 +8,7 @@ exec wish "$0" "$@" # ssvnc.tcl: gui wrapper to the programs in this # package. Also sets up service port forwarding. # -set version 1.0.24 +set version 1.0.25 set buck_zero $argv0 @@ -156,22 +156,23 @@ proc ts_help {} { Then click on "Connect". - Once the SSH is running (you may need to type a password in the - terminal window that pops up), the TightVNC Viewer (Or perhaps - Chicken-of-the-VNC on Mac OS X) will be automatically started directed - to the local port of the SSH tunnel which, in turn, encrypts and - redirects the connection to the remote VNC server. + Once the SSH is running (you may need to type a password or accept + a new ssh key in the terminal window that pops up), the VNC Viewer + will be automatically started directed to the local port of the SSH + tunnel which, in turn, encrypts and redirects the connection to the + remote VNC server. - x11vnc is run remotely to find or create your terminal services - desktop session. + x11vnc is run remotely to find or create your terminal services desktop + session. It must be installed and accessible on the remote system. Enter "user@hostname.com" in 'VNC Terminal Server' if the remote username is different from the yours on this machine. On Windows - you *MUST* supply the remote username. This entry is passed to SSH; - it could also be an SSH alias you have created (in ~/.ssh/config). + you *MUST* supply the remote username due to a deficiency in Plink. + This entry is passed to SSH; it could also be an SSH alias you have + created (in ~/.ssh/config). If the remote SSH server is run on a non-standard port, e.g. 2222, use - something like this: + something like one of these: far-away.east:2222 fred@someplace.no:2222 @@ -208,6 +209,8 @@ proc ts_help {} { tsvnc hostname tsvnc user@hostname + Note that the 'Verify All Certs' setting is NOT saved in profiles. + Proxies/Gateways: @@ -237,10 +240,13 @@ proc ts_help {} { VNC Terminal Server: ts-server Proxy/Gateway: jsmith@ssh.company.com:2222 - The username@ is not needed if it is the same as on this machine. + On Unix/MacOSX the username@ is not needed if it is the same as on this + machine. A Web or SOCKS proxy can also be used. Use this if you are inside a firewall that prohibits direct connections to remote SSH servers. + In Terminal Services SSH mode, the "http://" prefix is required for + web proxies. VNC Terminal Server: fred@someplace.no Proxy/Gateway: http://myproxy.west:8080 @@ -282,8 +288,13 @@ proc ts_help {} { - Client 8bit Color (VNC Viewer requests low color mode) - Client-Side Caching (experimental x11vnc speedup) - X11VNC Options (set any extra x11vnc options) + - Extra Sleep (delay a bit before starting viewer) + - SSH Local Protections (a bit of safety on local side) + - SSH KnownHosts file (to avoid SSH 'localhost' collisions) - SSVNC Mode (Return to full SSVNC mode) + - Unix ssvncviewer (set options for supplied Unix viewer) + Requirements: @@ -343,7 +354,7 @@ proc help {} { } toplev .h - scroll_text_dismiss .h.f 82 36 + scroll_text_dismiss .h.f 82 37 center_win .h wm title .h "SSL/SSH VNC Viewer Help" @@ -379,11 +390,12 @@ proc help {} { using the VNC protocol (i.e. VNC is tunnelled through the SSL channel after it is established). "x11vnc -ssl ..." does this, and any VNC server can be made to do this by using, e.g., STUNNEL or socat on the remote side. + SSVNC also supports VeNCrypt and ANONTLS SSL/TLS VNC servers (see below.) * Automatic SSH Tunnels are described below. - * To have a "No Encryption" button use the -noenc cmdline option, or select - it under Options. Also see Tip 3) for other ways to disable Encryption. + * The 'No Encryption' option provides a direct connection w/o encryption. + (disable by the -enc option, or Options menu.) More info in Tip 3). Port numbers: @@ -427,7 +439,7 @@ proc help {} { On Windows TightVNC viewer will prompt you if a password is required. NOTE: when you Save a VNC profile, the password is NOT saved (you need - to enter it each time). + to enter it each time). Nor is the 'Verify All Certs' setting. Profiles: @@ -464,6 +476,7 @@ proc help {} { You can use the "Fetch Cert" button to retrieve the Cert and then after you check it is OK (say, via comparing the MD5 or other info) you can "Save" it and use it to verify future connections to servers. + (However, see the note at the end of this section about CA certificates.) When "Verify All Certs" is checked, this check is always enforced, and so the first time you connect to a new server you may need to @@ -472,42 +485,95 @@ proc help {} { "Verify All Certs" is on by default. - However, "Fetch Cert" and "Verify All Certs" are currently disabled + Note, however, "Fetch Cert" and "Verify All Certs" are currently disabled in the very rare "SSH + SSL" usage mode to avoid SSHing in twice. - You can manually set a ServerCert in this case if you like. + You can manually set a ServerCert or CertsDir in this case if you like. - Advanced Method: If you, or your site administrator, goes though the - steps of setting up a Certificate Authority (CA) to sign the VNC server - and/or VNC client Certs, that can be used instead and avoids the need to - manually verify every cert while still authenticating every connection. - More info: http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-ca + + Advanced Method: Certificate Authority (CA): + + If you, or your site administrator, goes though the steps of setting up + a Certificate Authority (CA) to sign the VNC server and/or VNC client + Certs, that can be used instead and avoids the need to manually verify + every cert while still authenticating every connection. More info: + http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-ca See the cmdline option -cacert file below in 'SSL Certificates' for setting a default ServerCert/CA Cert. + You may also Import the CA Cert and save it to the 'Accepted Certs' + directory so the "Verify All Certs" automatic checking will find it. + + Note that if a Server is using a CA signed certificate instead of + its own Self-Signed one, then the default "Verify All Certs/Fetch Cert" + saving mechanism will NOT succeed. You must obtain the CA certificate + and explicitly set it as the ServerCert or Import it to Accepted Certs. + SSL/TLS Variants; VeNCrypt and ANONTLS: - SSVNC can also connect to VNC specific SSL/TLS variants; namely the - VeNCrypt and "TLS" VNC Security types. Vino uses the latter (we call it - "ANONTLS" in ssvnc and x11vnc because that describes it more accurately), - and a growing number use VeNCrypt. + SSVNC can also connect to VNC SSL/TLS variants; namely the VeNCrypt and + "TLS" VNC Security types. Vino uses the latter (we call it "ANONTLS"); + and a growing number use VeNCrypt (QEMU, ggi, virt-manager, VeNCrypt, Xen.) + + Via the VeNCrypt bridge that SSVNC provides, the VeNCrypt/ANONTLS + support ALSO works with ANY 3rd party VNC Viewers you specify via + 'Change VNC Viewer' (e.g. RealVNC, TightVNC, UltraVNC, etc.) that do + not directly support VeNCrypt or ANONTLS. This works on all platforms: + Unix, MacOSX, and Windows. + + + Notes on VeNCrypt/ANONTLS Auto-detection: + + IMPORTANT: VeNCrypt Server Auto-detection *ONLY* occurs in SSL mode + and when an initial fetch-cert action takes place. + + While the initial certificate fetch is taking place SSVNC applies + heuristics to try to automatically detect the VeNCrypt or ANONTLS + protocol use by the VNC server. This way it learns that the server + is using it and then knows to switch to VeNCrypt encrypted SSL/TLS at + the right point. Then SSVNC makes a second (the real) connection to + VNC server and connects the VNC viewer to it. - On Unix and Mac OS X, when "Verify All Certs" is enabled, it applies - heuristics to detect the protocol, and switches to SSL/TLS at the right time. - To improve the accuracy and speed with which this takes place, you can - specify the one or both of the 'Server uses VeNCrypt SSL/TLS encryption' - and 'Server uses Anonymous Diffie-Hellman' in the 'Advanced' options panel. - See its Help for more info. + In the default "Verify All Certs" mode, a fetch cert action always + takes place, and so VeNCrypt/ANONTLS will be autodected. + + However, if you have specified an explicit ServerCert or disabled + "Verify All Certs" then even though the initial fetch cert action is no + longer needed, it is performed anyway because it allows VeNCrypt/ANONTLS + auto-detection. + + To disabled this initial fetch (e.g. you know the VNC server is normal + SSL and not VeNCrypt/ANONTLS and want to connect more quickly) then + select "Do not Probe for VeNCrypt" in the Advanced Options menu. + + On the other hand, if you know the VNC server ONLY supports VeNCrypt or + ANONTLS, to improve the accuracy and speed with which the connection + takes place, you can specify the one or both of the 'Server uses + VeNCrypt SSL encryption' and 'Server uses Anonymous Diffie-Hellman' + in the 'Advanced' options panel. That way guessing via an initial + probe is not needed or performed. See each options's Advanced Options + Help for more info. + + Note that if you are using VeNCrypt or ANONTLS for REVERSE connections + (Listen) then you *MUST* set the 'Server uses VeNCrypt SSL encryption' + (and the ANON-DH if it applies) option in Advanced. Note also that + REVERSE VeNCrypt and ANONTLS connections currently do not work on + Windows. + + Also, if you are using the "Use SSH+SSL" double tunnel, you MUST set + 'Server uses VeNCrypt SSL encryption' (and the ANON-DH if it applies) + because the initial fetch cert is disabled in SSH+SSL mode. Deciphering SSL Negotiation Success or Failure: - Since SSVNC is a "glue program", in this case gluing VNCViewer and - stunnel together (with possibly a proxy helper) reporting is clumsy at - best. In most cases the programs being "glued" are run in a terminal - window where you can see the programs' output. On Windows you will - need to double click on the stunnel tray icon to view its log. + Since SSVNC is a "glue program", in this case gluing VNCViewer and stunnel + together (with possibly a proxy helper) reporting is clumsy at best. + (In SSH encryption mode, it glues to ssh instead of stunnel.) In most + cases the programs being "glued" are run in a terminal window where you + can see the program's output. On Windows you will need to double click + on the stunnel tray icon to view its log. Although the output is quite cryptic, you are encouraged to learn to recognize some of the errors reported in it. @@ -526,9 +592,17 @@ proc help {} { 2008.11.20 08:12:31 LOG3[1662]: SSL_connect: 14090086: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed + Here is a case where the Server's Cert has expired: + + 2009.12.27 12:20:25 LOG4[25500]: VERIFY ERROR: depth=0, error=certificate + has expired: /C=AU/L=... + 2009.12.27 12:20:25 LOG3[25500]: SSL_connect: 14090086: error:14090086:SSL + routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed + + If you disable "Verify All Certs" and do not supply a ServerCert, then there will be no 'VERIFY ...' in the output because the SSVNC - stunnel accepts the server's cert without question. + stunnel accepts the server's cert without question (this is insecure.) Also in the output will be messages about whether the SSL VNC server rejected your connection because it requires you to authenticate @@ -678,26 +752,27 @@ proc help {} { set help_misc { Windows STUNNEL problems: - Note that on Windows when the Viewer connection is finished you will be + Note that on Windows when the Viewer connection is finished by default + SSVNC will try to kill the STUNNEL process for you. + + If Options -> Kill Stunnel Automatically is not set you will be prompted if you want SSVNC to try to kill the STUNNEL process for you. - Usually you will say Yes, however if there are problems connecting you - may want to look at the STUNNEL Log first. + Usually you will say Yes, however if there are problems connecting + you may want to look at the STUNNEL Log first. - Double clicking the STUNNEL tray icon (dark green) will show you its - Log file (useful for debugging connections). + Before it is killed, double clicking the STUNNEL tray icon (dark green) + will show you its Log file (useful for debugging connection problems). - SSVNC will kill the STUNNEL process for you, but you may still need to - move the mouse over the icon to make the picture go away! + Even though SSVNC will kill the STUNNEL process for you, you will + still need to move the mouse over the icon to make the little picture + go away!!! This is unfortunate but there does not seem to be a way + to avoid it. In some cases you may need to terminate STUNNEL manually from the System Tray (right click on dark green icon) and selecting "Exit". - If you want SSVNC to always kill STUNNEL automatically, run with the - '-killstunnel' command line option or set it under Options. You can also - set killstunnel=1 in ssvnc_rc. Recently (1/2009) this option has been - enabled by default, so use -nokillstunnel and killstunnel=0 to disable - it in general, or uncheck the option for the next connection. - + Use -nokillstunnel or killstunnel=0 in ~/.ssvncrc to have SSVNC + start up with stunnel killing disabled. Untrusted Local Users: @@ -824,7 +899,8 @@ proc help {} { Use socks5:// to force the SOCKS5 proxy protocol (e.g. for ssh -D). You can prefix web proxies with http:// but it doesn't matter since - that is the default. + that is the default (note that in SSH or SSH+SSL mode you MUST supply + the http:// prefix for web proxies; see the next section.) Note that Web proxies are often configured to ONLY allow outgoing connections to ports 443 (HTTPS) and 563 (SNEWS), so you might @@ -895,7 +971,9 @@ proc help {} { VNC Host:Display: joe@far-away.east:0 Proxy/Gateway: socks://mysocks.west:1080 - use socks5://... to force the SOCKS5 version. + use socks5://... to force the SOCKS5 version. Note that the http:// + prefix is required for web proxies in SSH or SSH+SSL modes (but it is + the default in SSL mode.) You can chain up to 3 proxies (any combination of http:// and socks://) by separating them with commas (i.e. first,second,third). @@ -912,6 +990,46 @@ proc help {} { Proxy/Gateway: http://mysocks.west:1080,ssh.company.com,joes-pc + + SSH NoHostAuthenticationForLocalhost=yes and UserKnownHostsFile=file + for localhost tunnelling: + + Warning: Note that for proxy use with ssh(1) tunnels going through + localhost are used. This means ssh(1) thinks the remote hostname is + 'localhost', which may cause collisions and confusion when storing + and checking SSH keys. + + By default on Unix when a 'localhost' ssh host is involved the + ssh option -o NoHostAuthenticationForLocalhost=yes is applied (see + ssh_config(1) for details.) This avoids the warnings and ssh refusing + to connect, but it reduces security. A man in the middle attack may + be possible. SSVNC prints out a warning in the terminal every time + the NoHostAuthenticationForLocalhost option is used. + + On Unix to disable the use of NoHostAuthenticationForLocalhost set the env. + variable SSVNC_SSH_LOCALHOST_AUTH=1. + + On Unix a MUCH SAFER and more convenient way to proceed is to set the + known hosts option in Options -> Advanced -> 'Private SSH KnownHosts file' + Then, only for the host in the current profile, a private known_hosts + file will be used and so there will be no 'localhost' collisions. + This method is secure (assuming you verify the SSH key fingerprint) + and avoids the man in the middle attack. + + On Windows, Putty/Plink is used and does not have the UserKnownHosts + or NoHostAuthenticationForLocalhost features. Keys are stored in + the registry as localhost:port pairs and so it is possible to use the + 'Port Slot' option to keep the keys separate to avoid the dialogs and + also maintain good security. + + Note that for the "double SSH gateway" method the risk from using + NoHostAuthenticationForLocalhost is significantly less because the first + ssh connection does not use the option (it connects directly to the remote + host) and the second one is only exposed for the leg inside the first + gateway (but is still vulnerable there when NoHostAuthenticationForLocalhost + is used.) + + UltraVNC Proxies/Gateways: UltraVNC has a "repeater" tool (http://www.uvnc.com/addons/repeater.html @@ -1121,7 +1239,7 @@ proc help {} { Pressing Ctrl-O on the main GUI will bring up the Options Panel. Pressing Ctrl-A on the main GUI will bring up the Advanced Options. - 3) If you want to make a Direct VNC connection, WITH NO SSL OR + 3) If you want to make a Direct VNC connection, WITH *NO* SSL OR SSH ENCRYPTION, use the "vnc://" prefix in the VNC Host:Display entry box, e.g. "vnc://far-away.east:0" This also works for reverse connections, e.g. vnc://0 @@ -1132,17 +1250,25 @@ proc help {} { Shift+Ctrl-E in the entry box is a short-cut to add or remove the prefix "Vnc://" from the host:disp string. - You can also run ssvnc with the '-noenc' cmdline option to have a - check option that lets you turn off Encryption (and profiles will - store this setting). Pressing Ctrl-E on the main panel is a short-cut - to toggle between the -noenc 'No Encryption' mode and normal mode. - The option "Show 'No Encryption' Option" under Options also toggles it. + Note as of SSVNC 1.0.25 the '-noenc' mode is now the default. I.e. + the 'No Encryption' option ('None') is shown by default. To disable + the button supply the '-enc' cmdline option. + + You can also run ssvnc with the '-noenc' cmdline option (now the + default) to have a check option that lets you turn off Encryption + (and profiles will store this setting). Pressing Ctrl-E on + the main panel is a short-cut to toggle between the -noenc + 'No Encryption' mode and normal mode. The option "Show 'No + Encryption' Option" under Options also toggles it. + + The '-enc' option disables the button (and so makes it less obvious + how do disable encryption.) Setting SSVNC_DISABLE_ENCRYPTION_BUTTON=1 in your environment is the same as -noenc. You can also put noenc=1 in your ~/.ssvncrc file. - Apologies that we do not make this easy to figure out how to do, - but the goal of SSVNC is secure and encrypted connections! + Setting SSVNC_DISABLE_ENCRYPTION_BUTTON=0 in your environment is + the same as -enc. You can also put noenc=0 in your ~/.ssvncrc file. Please be cautious/thoughtful when you make a VNC connection with encryption disabled. You may send sensitive information (e.g. a @@ -1160,11 +1286,12 @@ proc help {} { is not sent in plaintext) leaves your VNC password susceptible a dictionary attack unless encryption is used to hide it. - So we force you to learn about and supply the "vnc://" or "Vnc://" - prefix to the host:port or use -noenc or the "Show 'No Encryption' - Option" to disable encryption. This is a small hurdle, but maybe - someone will think twice. It is a shame that VNC has been around - for over 10 years and still does not have built-in strong encryption. + So (before we made the button on by default!) we forced you to + learn about and supply the "vnc://" or "Vnc://" prefix to the + host:port or use -noenc or the "Show 'No Encryption' Option" + to disable encryption. This is a small hurdle, but maybe someone + will think twice. It is a shame that VNC has been around for over + 10 years and still does not have built-in strong encryption. Note the Vnc:// or vnc:// prefix will be stored in any profile that you save so you do not have to enter it every time. @@ -1286,17 +1413,37 @@ proc help {} { and assumed to be free, and is passed to x11vnc's -rfbport option. This only works with x11vnc (not vncserver). - 12) You can change the X DISPLAY variable by typing DISPLAY=... into + 12) Tricks with environment variables: + + You can change the X DISPLAY variable by typing DISPLAY=... into VNC Host:Display and hitting Return or clicking Connect. Same - for HOME=. Setting SLEEP=n increases the amount of time waited - 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 viewer. + for HOME=. On Mac, you can set DYLD_LIBRARY_PATH=... too. + It should propagate down the viewer. + + Setting SLEEP=n increases the amount of time waited before + starting the viewer. The env. var. SSVNC_EXTRA_SLEEP also does + this (and also Sleep: Option setting) Setting FINISH=n sets the + amount of time slept before the Terminal window exits on Unix + and MacOS X. (same as SSVNC_FINISH_SLEEP env. var.) + + Full list of parameters HOME/SSVNC_HOME, DISPLAY/SSVNC_DISPLAY + DYLD_LIBRARY_PATH/SSVNC_DYLD_LIBRARY_PATH, SLEEP/SSVNC_EXTRA_SLEEP + FINISH/SSVNC_FINISH_SLEEP, DEBUG_NETSTAT, REPEATER_FORCE, SSH_ONLY. + (the ones joined by "/" are equivalent names, and the latter can + be set as an env. var. as well.) After you set the parameter, clear out the 'VNC Host:Display' entry and replace it with the actual host and display number. + To replace the xterm terminal where most of the external commands + are run set SSVNC_XTERM_REPLACEMENT to a command that will run + a command in a terminal. I.e.: "$SSVNC_XTERM_REPLACEMENT cmd" + will run cmd. If present, %GEOMETRY is expanded to a desired + +X+Y geometry. If present, %TITLE is expanded to a desired title. + Examples: SSVNC_XTERM_REPLACEMENT='gnome-terminal -e' + SSVNC_XTERM_REPLACEMENT='gnome-terminal -t "%TITLE" -e' + SSVNC_XTERM_REPLACEMENT='konsole -e' + 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. @@ -1340,7 +1487,8 @@ proc help {} { (The above 4 settings apply only to the Terminal Services Mode.) - noenc=1 (same as the -noenc option for a 'No Encryption' button) + noenc=1 (same as the -noenc option for a 'No Encryption' option) + noenc=0 (do not show the 'No Encryption' option) killstunnel=1 (same as -killstunnel), on Windows automatically kills the STUNNEL process when the viewer exits. Disable via killstunnel=0 @@ -1360,8 +1508,11 @@ proc help {} { crl=file (same as -crl file option). Set your default CRL File to "file". If file does not exist ~/.vnc/certs/file is used. - Prefix any of these with "FORCE:" to make them immutable, e.g. - "cacert=FORCE:CA". + Prefix any of these cert/key files with "FORCE:" to make them + immutable, e.g. "cacert=FORCE:CA". + + You can set any environment variable in ~/.ssvncrc by using a line + like env=VAR=value, for example: env=SSVNC_FINISH_SLEEP=2 To change the fonts (see Tip 18 below for examples): @@ -1574,7 +1725,8 @@ proc help_certs {} { 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. + STUNNEL log output to see if the cert has expired. Then create and distribute + a new one. Fetch Cert: @@ -1585,6 +1737,10 @@ proc help_certs {} { To make this verification check permanent, you will need to save the profile via 'Save'. + NOTE: See the CA section below for how "Fetch Cert/Verify All Certs" WILL NOT + WORK when a Certificate Authority (CA) is used (i.e. you need to save the CA's + cert instead.) It will work if the certificate is Self-Signed. + Verify All Certs: If "Verify All Certs" is checked on the main panel, you are always forced @@ -1606,14 +1762,19 @@ proc help_certs {} { SSVNC_NO_VERIFY_ALL=1 before starting. If you do not even want to see the button, use "ssvnc -nvb" or SSVNC_NO_VERIFY_ALL_BUTTON=1. - Note: "Fetch Cert" and "Verify All Certs" do not currently work in "SSH + - SSL" mode. In this case to have server authentication "ServerCert" must - be set explicitly to a file (or "CertsDir" to a directory). + Note: "Fetch Cert" and "Verify All Certs" are currently not implemented in + "SSH + SSL" mode. In this case to have server authentication "ServerCert" + must be set explicitly to a file (or "CertsDir" to a directory). Also note that "Fetch Cert" only works in a limited fashion in "Listen" mode (it is the VNC Server that initiates the connection), and so you may need to be set via "ServerCert" as well. + NOTE: See the CA section below for how "Fetch Cert/Verify All Certs" + WILL NOT WORK when a Certificate Authority (CA) is used (i.e. you need + to save the CA's cert instead.) The "Fetch Cert" saving method will + work if the certificate is Self-Signed. + CA: One can make SSL VNC server authentication more "automatic" as it is in @@ -1626,6 +1787,11 @@ proc help_certs {} { be very convenient because the viewers (i.e. SSVNC) only need the CA cert, not all of the Server certs. + IMPORTANT NOTE: if a VNC Server is using a CA signed certificate instead + of its own Self-Signed one, then "Fetch Cert", etc. saving mechanism + WILL NOT WORK. You must obtain the CA certificate and explicitly set + it as the ServerCert or import it to 'Accepted Certs'. + Now what goes into the panel's entry boxes is described. @@ -1699,7 +1865,7 @@ proc help_certs {} { Import Certificate: - You can paste in Certificate or read one in from a file to add to your + You can paste in a Certificate or read one in from a file to add to your list of Server Certificates. If (also) saved in the 'Accepted Certs' directory, it will be automatically used to verify any Server when in 'Verify All Certs' Mode. @@ -1964,7 +2130,8 @@ set msg { (The above 4 settings apply only to the Terminal Services Mode.) - noenc=1 (same as the -noenc option for a 'No Encryption' button) + noenc=1 (same as the -noenc option for a 'No Encryption' option) + noenc=0 (do not show the 'No Encryption' option) font_default=tk-font-name (sets the font for menus and buttons) font_fixed=tk-font-name (sets the font for help text) @@ -1984,7 +2151,8 @@ proc help_opts {} { set msg { Use SSL: The default, use SSL via STUNNEL (this requires SSL aware VNC - server, e.g. x11vnc -ssl SAVE ...) + server, e.g. x11vnc -ssl SAVE ...) See the description in the + main Help panel. Use SSH: Instead of using STUNNEL SSL, use ssh(1) for the encrypted tunnel. You must be able to log in via ssh to the remote host. @@ -2055,15 +2223,19 @@ set msg { Tunnel the SSL connection through a SSH tunnel. Use this if you want end-to-end SSL and must use a SSH gateway (e.g. to enter a firewall) or if additional SSH port redirs are required - (CUPS, Sound, SMB tunnelling: See Advanced Options). Rarely used - mode, but included in case the need arises. + (CUPS, Sound, SMB tunnelling: See Advanced Options). + + This is a RARELY used mode, but included in case the need arises. No Encryption: - In '-noenc' mode (Ctrl-E also toggles this mode), use this to - make a Direct connection to the VNC Server with no encryption - whatsoever. (Be careful about passwords, etc.) + In '-noenc' mode, which is now the default, (Ctrl-E also toggles + this mode), use this to make a Direct connection to the VNC Server + with no encryption whatsoever. (Be careful about passwords, etc.) + + The -noenc mode is now the default since SSVNC 1.0.25, use + the '-enc' cmdline option to disable the button. Automatically Find X Session: @@ -2239,6 +2411,7 @@ set msg { Compress Level/Quality: Set TightVNC encoding parameters. + Putty PW: On Windows only: use the supplied password for plink SSH logins. Unlike the other options the value is not saved when 'Save' is performed. This feature is useful when @@ -2249,6 +2422,34 @@ set msg { requires setting up and distributing SSH keys). Start up pagent.exe or puttygen.exe and read the instructions there. + Note, that there is a small exposure to someone seeing the + putty password on the plink command line. + + Note that the Putty PW is not cleared if you load in a + new VNC profile. + + + Port Slot: On Windows ports cannot be selected or checked as easily as + on Unix. So listening ports for ssh redirs, proxy tunnelling, + and etc. things are picked via finding a free "slot". + The slots run from 30 to 99 and are locked based on the + existence of a file with the slot number in it. When the + connection is about to be made, a free slot is found and used + to work out some ports (e.g. 5930 for the local VNC port, + etc.) This way simultaneous SSVNC connections can take place. + + One drawback of this is that Putty/Plink stores SSH keys based + on hostname:port, and with a proxy tunnel the hostname is + "localhost". So the Putty key store may have key collisions + for the localhost tunnels, and plink will prompt you to + resolve the conflict WRT a different SSH key being discovered. + + To work around this to some degree you can select a unique + Port Slot (in the range 50-99) for a specific host. Then the + ssh redir port to this host will never change and so the + Putty localhost:fixed-port key should remain valid. + + Mode: To change the GUI Mode, select between the full SSVNC (i.e. SSL and SSH), SSHVNC (i.e. SSH-Only), and Terminal Services mode (TSVNC; uses x11vnc) @@ -2260,6 +2461,9 @@ set msg { Show 'No Encryption' Option: + Note: since SSVNC 1.0.25 the 'No Encryption' Option is + enabled by default. + Select this to display a button that disables both SSL and SSH encryption. This is the same as Ctrl+E. This puts a check item "None" on the main panel and also a "No @@ -2299,7 +2503,7 @@ set msg { jiggle_text .oh.f.t } -proc help_fetch_cert {} { +proc help_fetch_cert {{selfsigned 1}} { toplev .fh scroll_text_dismiss .fh.f 85 35 @@ -2310,52 +2514,72 @@ proc help_fetch_cert {} { wm title .fh "Fetch Certificates Help" set msg { - The above SSL Certificate has been retrieved from the VNC Server via the + The displayed SSL Certificate has been retrieved from the VNC Server via the "Fetch Cert" action. - It has merely been downloaded via the SSL Protocol: **IT HAS NOT BEEN VERIFIED - IN ANY WAY** + It has merely been downloaded via the SSL Protocol: + + *** IT HAS NOT BEEN VERIFIED OR AUTHENTICATED IN ANY WAY *** So, in principle, it could be a fake certificate being inserted by a bad person attempting to perform a Man-In-The-Middle attack on your SSL connection. - If, however, by some external means you can verify the authenticity of - this SSL Certificate you can use it for your VNC SSL connection to the - VNC server you wish to connect to. It will provide an authenticated and - encrypted connection. + If, however, by some external means you can verify the authenticity of this SSL + Certificate you can use it for your VNC SSL connection to the VNC server you + wish to connect to. It will provide an authenticated and encrypted connection. - You can verify the SSL Certificate by comparing the MD5 or SHA1 hash - value via a method/channel you know is safe (i.e. not also under control - of a Man-In-The-Middle attacker). You could also check the text between - the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- tags, etc. + You can verify the SSL Certificate by comparing the MD5 or SHA1 hash value + via a method/channel you know is safe (i.e. not also under control of a + Man-In-The-Middle attacker). You could also check the text between the + -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- tags, etc. Once you are sure it is correct, you can press the Save button to save the - certificate to a file on the local machine for use when you connect via - VNC tunneled through SSL. If you save it, then that file will be set as - the Certificate to verify the VNC server against. You can see this in - the dialog started via the "Certs..." button on the main panel. + certificate to a file on the local machine for use when you connect via VNC + tunneled through SSL. If you save it, then that file will be set as the + Certificate to verify the VNC server against. You can see this in the dialog + started via the "Certs..." button on the main panel. - NOTE: If you want to make PERMANENT the association of the saved SSL - certificate file with the VNC server host, you MUST save the setting as - a profile for loading later. To Save a Profile, click on Options -> Save - Profile ..., and choose a name for the profile and then click on Save. + NOTE: If you want to make Permanent the association of the saved SSL certificate + file with the VNC server host, you MUST save the setting as a profile for + loading later. To Save a Profile, click on Options -> Save Profile ..., + and choose a name for the profile and then click on Save. + + If "Verify All Certs" is checked, then you are forced to check all new certs. + In this case the certs are saved in the 'Accepted Certs' directory against + which all servers will be checked unless "ServerCert" or "CertsDir" has been + set to something else. + + To reload the profile at a later time, click on the "Load" button on the + main panel and then select the name and click "Open". If you want to be + sure the certificate is still associated with the loaded in host, click on + "Certs..." button and make sure the "ServerCert" points to the desired SSL + filename. + + See the Certs... Help for more information. A sophisticated method can be set + up using a Certificate Authority key to verify never before seen certificates + (i.e. like your web browser does). +} + + set msg2 { + -------------------------------------------------------------------------- + NOTE: The certificate that was just downloaded IS NOT a Self-Signed + certificate. It was signed by a Certificate Authority (CA) instead. + So saving it does not make sense because it cannot be used to authenticate + anything. + + You need to Obtain and Save the CA's certificate instead. - If "Verify All Certs" is checked, then you are forced to check all - new certs. In this case the certs are saved in the 'Accepted Certs' - directory against which all servers will be checked unless "ServerCert" - or "CertsDir" has been set to something else. + The remainder of this Help description applies ONLY to Self-Signed + certificates (i.e. NOT the most recently downloaded one.) + -------------------------------------------------------------------------- - To reload the profile at a later time, click on the "Load" button on - the main panel and then select the name and click "Open". If you want - to be sure the certificate is still associated with the loaded in host, - click on "Certs..." button and make sure the "ServerCert" points to the - desired SSL filename. - See the Certs... Help for more information. A sophisticated method - can be set up using a Certificate Authority key to verify never before - seen certificates (i.e. like your web browser does). } + if {!$selfsigned} { + regsub { If, however,} $msg "$msg2 If, however," msg + } + .fh.f.t insert end $msg jiggle_text .fh.f.t } @@ -2481,13 +2705,21 @@ proc win9x_plink_msg {file} { } proc mesg {str} { - set maxx 54 + set maxx 60 + if [regexp {^INFO: without Certificate} $str] { + set maxx 72 + } if {[string length $str] > $maxx} { - set str [string range $str 0 $maxx] + set lend [expr $maxx - 1] + set str [string range $str 0 $lend] append str " ..." } .l configure -text $str update + global env + if [info exists env(SSVNC_MESG_DELAY)] { + after $env(SSVNC_MESG_DELAY) + } } proc get_ssh_hp {str} { @@ -2690,14 +2922,15 @@ proc set_defaults {} { 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 listen_once listen_accept_popup listen_accept_popup_sc + global ssh_known_hosts ssh_known_hosts_filename global ultra_dsm ultra_dsm_type ultra_dsm_file ultra_dsm_noultra ultra_dsm_salt 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 ssvnc_scale ssvnc_escape sbwid_string rfbversion ssvnc_encodings ssvnc_extra_opts use_x11cursor use_nobell use_rawlocal use_popupfix extra_sleep use_listen use_unixpw use_x11vnc_find unixpw_username + global use_port_knocking port_knocking_list port_slot + global ycrop_string ssvnc_scale ssvnc_escape sbwid_string rfbversion ssvnc_encodings ssvnc_extra_opts use_x11cursor use_nobell use_rawlocal use_notty use_popupfix extra_sleep use_listen use_unixpw use_x11vnc_find unixpw_username global disable_ssl_workarounds disable_ssl_workarounds_type - global server_vencrypt server_anondh + global no_probe_vencrypt server_vencrypt server_anondh global include_list global svcert_default mycert_default crlfil_default @@ -2717,6 +2950,7 @@ proc set_defaults {} { set defs(use_send_always) 0 set defs(use_turbovnc) 0 set defs(disable_pipeline) 0 + set defs(no_probe_vencrypt) 0 set defs(server_vencrypt) 0 set defs(server_anondh) 0 set defs(use_grab) 0 @@ -2780,6 +3014,8 @@ proc set_defaults {} { set defs(stunnel_local_protection) 1 set defs(stunnel_local_protection_type) "exec" set defs(ssh_local_protection) 1 + set defs(ssh_known_hosts) 0 + set defs(ssh_known_hosts_filename) "" set defs(multiple_listen) 0 set defs(listen_once) 0 set defs(listen_accept_popup) 0 @@ -2791,6 +3027,8 @@ proc set_defaults {} { set defs(ultra_dsm_noultra) 0 set defs(ultra_dsm_salt) "" + set defs(port_slot) "" + set defs(cups_local_server) "" set defs(cups_remote_port) "" set defs(cups_local_smb_server) "" @@ -2820,6 +3058,7 @@ proc set_defaults {} { set defs(use_x11cursor) 0 set defs(use_nobell) 0 set defs(use_rawlocal) 0 + set defs(use_notty) 0 set defs(use_popupfix) 0 set defs(extra_sleep) "" set defs(use_port_knocking) 0 @@ -2827,6 +3066,45 @@ proc set_defaults {} { set defs(include_list) "" + set dir [get_profiles_dir] + set deffile "" + if [file exists "$dir/defaults"] { + set deffile "$dir/defaults" + } elseif [file exists "$dir/defaults.vnc"] { + set deffile "$dir/defaults.vnc" + } + if {$deffile != ""} { + set fh "" + catch {set fh [open $deffile "r"]} + if {$fh != ""} { + while {[gets $fh line] > -1} { + set line [string trim $line] + if [regexp {^#} $line] { + continue + } + if [regexp {^([^=]*)=(.*)$} $line m var val] { + if {$var == "disp"} { + continue + } + if [info exists defs($var)] { + set pct 0 + if {$var == "smb_mount_list"} { + set pct 1 + } + if {$var == "port_knocking_list"} { + set pct 1 + } + if {$pct} { + regsub -all {%%%} $val "\n" val + } + set defs($var) $val + } + } + } + close $fh + } + } + global ssh_only ts_only if {$ssh_only || $ts_only} { set defs(use_ssl) 0 @@ -3336,6 +3614,7 @@ proc launch_windows_ssh {hp file n} { } elseif {[regexp {cmd=PUTTY} $hp]} { ; } else { + # XXX add :0 instead? mesg "Bad vncdisp, missing :0 ?, $vnc_disp" bell return 0 @@ -3403,11 +3682,13 @@ proc launch_windows_ssh {hp file n} { } } } + #mesg "pproxy: $pproxy"; after 2000 #mesg "sproxy1: $sproxy1"; after 2000 #mesg "sproxy_rest: $sproxy_rest"; after 2000 #mesg "ssh_host: $ssh_host"; after 2000 #mesg "ssh_port: $ssh_port"; after 2000 + if {$sproxy1 != ""} { regsub {:[0-9][0-9]*$} $sproxy1 "" sproxy1_host regsub {^.*@} $sproxy1_host "" sproxy1_host @@ -3425,17 +3706,24 @@ proc launch_windows_ssh {hp file n} { if {$sproxy1_user != ""} { set sproxy1_user "$sproxy1_user@" } + #mesg "sproxy1_host: $sproxy1_host"; after 2000 #mesg "sproxy1_user: $sproxy1_user"; after 2000 #mesg "sproxy1_port: $sproxy1_port"; after 2000 - set port2 [rand_port] + set port2 "" + if [regexp -- {-([0-9][0-9]*)} [file tail $file] mv dport] { + set port2 [expr 21000 + $dport] + } else { + set port2 [rand_port] + } + set env(SSVNC_PROXY) $pproxy set env(SSVNC_LISTEN) $port2 set env(SSVNC_DEST) "$sproxy1_host:$sproxy1_port" - mesg "Starting TCP helper on port $port2 ..." - after 400 + mesg "Starting Proxy TCP helper on port $port2 ..." + after 300 set proxy_pid [exec "connect_br.exe" &] catch { unset env(SSVNC_PROXY) } @@ -3454,7 +3742,7 @@ proc launch_windows_ssh {hp file n} { set proxy "$proxy,$sproxy_rest" } mesg "Set proxy to: $proxy" - after 400 + after 300 } if [regexp {,} $proxy] { if {$is_win9x} { @@ -3469,8 +3757,13 @@ proc launch_windows_ssh {hp file n} { set proxy1 [lindex $s 0] set proxy2 [lindex $s 1] - set p_port [expr 3000 + 1000 * rand()] - set p_port [expr round($p_port)] + set p_port "" + if [regexp -- {-([0-9][0-9]*)} [file tail $file] mv dport] { + set p_port [expr 4000 + $dport] + } else { + set p_port [expr 3000 + 1000 * rand()] + set p_port [expr round($p_port)] + } set s [ssh_split $proxy1] set ssh_user1 [lindex $s 0] @@ -3821,7 +4114,10 @@ proc launch_windows_ssh {hp file n} { } } + vencrypt_tutorial_mesg + set wdraw 1 + #set wdraw 0 if [info exists debug_netstat] { if {$debug_netstat != "" && $debug_netstat != "0"} { set wdraw 0 @@ -4217,7 +4513,7 @@ proc darwin_terminal_cmd {{title ""} {cmd ""} {bg 0}} { } proc unix_terminal_cmd {{geometry "+100+100"} {title "xterm-command"} {cmd "echo test"} {bg 0} {xrm1 ""} {xrm2 ""} {xrm3 ""}} { - global uname + global uname env if {$uname == "Darwin"} { global env set doX 0; @@ -4244,6 +4540,44 @@ proc unix_terminal_cmd {{geometry "+100+100"} {title "xterm-command"} {cmd "echo } } + if [info exists env(SSVNC_XTERM_REPLACEMENT)] { + set tcmd $env(SSVNC_XTERM_REPLACEMENT) + if {$tcmd != ""} { + regsub -all {%GEOMETRY} $tcmd $geometry tcmd + regsub -all {%TITLE} $tcmd $title tcmd + + set tmp1 /tmp/xterm_replacement1.[tpid] + set tmp1 [mytmp $tmp1] + set fh1 "" + catch {set fh1 [open $tmp1 "w"]} + + set tmp2 /tmp/xterm_replacement2.[tpid] + set tmp2 [mytmp $tmp2] + set fh2 "" + catch {set fh2 [open $tmp2 "w"]} + if {$fh1 != "" && $fh2 != ""} { + puts $fh1 "#!/bin/sh"; + puts $fh1 "$cmd" + puts $fh1 "rm -f $tmp1" + close $fh1 + catch {exec chmod 755 $tmp1} + puts $fh2 "#!/bin/sh" + puts $fh2 "$tcmd $tmp1" + puts $fh2 "rm -f $tmp2" + close $fh2 + catch {exec chmod 755 $tmp2} + if {$bg} { + exec $tmp2 2>@stdout & + } else { + exec $tmp2 2>@stdout + } + return + } + catch {close $fh1} + catch {close $fh2} + } + } + if {$bg} { if {$xrm1 == ""} { exec xterm -sb -sl 2000 -geometry "$geometry" -title "$title" -e sh -c "$cmd" 2>@stdout & @@ -4492,10 +4826,6 @@ proc direct_connect_msg {} { } if {$msg != ""} { set msg "Direct connect via vnc://hostname\nThe following options will be disabled:\n\n$msg" - global is_windows - if {0 && $is_windows} { - set msg "Direct connect mode: vnc://host:disp is not supported on Windows." - } raise . tk_messageBox -type ok -icon info -message $msg } @@ -4505,6 +4835,9 @@ proc fetch_cert {save} { global env vncdisplay is_windows set hp [get_vncdisplay] + global vencrypt_detected + set vencrypt_detected "" + global use_listen if {$use_listen} { if {$is_windows} { @@ -4519,34 +4852,46 @@ proc fetch_cert {save} { wm title .fcr "Fetch Cert for Reverse Connections" global fcr_result set fcr_result 0 - eval text .fcr.t -width 55 -height 14 $help_font + eval text .fcr.t -width 55 -height 17 $help_font .fcr.t insert end { In Reverse VNC Connections (-LISTEN) mode, the Fetch Cert operation requires that the Remote VNC Server makes an initial connection NOW so - we can collect its SSL Certificate. + we can collect its SSL Certificate. Note that + this method does not work for VeNCrypt servers. + (If there are problems Fetching, one can always + copy and import the Cert file manually.) Do you want to Continue with this operation? - If so, press "Continue" and then instruct the + If so, press "Continue" and Then instruct the remote VNC Server to make a Reverse Connection to us. Otherwise, press "Cancel" to cancel the Fetch - Cert operation. + Cert operation. } button .fcr.cancel -text Cancel -command {set fcr_result 0; destroy .fcr} button .fcr.continue -text Continue -command {set fcr_result 1; destroy .fcr} - pack .fcr.t .fcr.continue .fcr.cancel -side top -fill x + button .fcr.continu2 -text Continue -command {set fcr_result 1; destroy .fcr} + global uname + if {$uname == "Darwin"} { + pack .fcr.t .fcr.continu2 .fcr.continue .fcr.cancel -side top -fill x + + } else { + pack .fcr.t .fcr.continue .fcr.cancel -side top -fill x + } center_win .fcr tkwait window .fcr + update + after 50 if {$fcr_result != 1} { return } - after 100 update idletasks + after 50 } regsub {[ ]*cmd=.*$} $hp "" tt @@ -4585,76 +4930,92 @@ proc fetch_cert {save} { set cert_text [fetch_cert_windows $hp] } -if [info exists env(CERTDBG)] {puts "\nFetch-0-\n$cert_text"} + if [info exists env(CERTDBG)] {puts "\nFetch-0-\n$cert_text"} - if {! $is_windows} { - set vencrypt 0 - set anondh 0 - if {![regexp {BEGIN CERTIFICATE} $cert_text]} { - if [regexp {CONNECTED} $cert_text] { - if {![regexp -nocase {GET_SERVER_HELLO} $cert_text] - || [regexp -nocase {GET_SERVER_HELLO.*unknown protocol} $cert_text]} { - # suspect VeNCrypt or ANONTLS plaintext RFB - set cert_text "" - set vencrypt 1 - incr pstr - mesg "#${pstr} Fetching $hpnew Cert..." - catch {set cert_text [fetch_cert_unix $hp $vencrypt $anondh]} -if [info exists env(CERTDBG)] {puts "\nFetch-1-\n$cert_text"} - } + set vencrypt 0 + set anondh 0 + if {![regexp {BEGIN CERTIFICATE} $cert_text]} { + if [regexp {CONNECTED} $cert_text] { + set m 0 + if {![regexp -nocase {GET_SERVER_HELLO} $cert_text]} { + set m 1 } - } - if {![regexp {BEGIN CERTIFICATE} $cert_text]} { - if [regexp {CONNECTED} $cert_text] { - if {[regexp -nocase {error.*handshake failure} $cert_text] - || [regexp -nocase {error.*unknown protocol} $cert_text]} { - # suspect Anonymous Diffie Hellman - set cert_text "" - set anondh 1 - incr pstr - mesg "#${pstr} Fetching $hpnew Cert..." - catch {set cert_text [fetch_cert_unix $hp $vencrypt $anondh]} -if [info exists env(CERTDBG)] {puts "\nFetch-2-\n$cert_text"} + if [regexp -nocase -line {GET_SERVER_HELLO.*unknown protocol} $cert_text] { + set m 1 + } + if {!$m && $is_windows} { + if [regexp -nocase {write:errno} $cert_text] { + if [regexp -nocase {no peer certificate} $cert_text] { + set m 1 + } } } - } - if {![regexp {BEGIN CERTIFICATE} $cert_text]} { - if [regexp {CONNECTED} $cert_text] { - if {[regexp -nocase {cipher.*ADH} $cert_text]} { - # it is Anonymous Diffie Hellman - mesg "WARNING: Anonymous Diffie Hellman Server detected" - .f4.getcert configure -state normal - return $cert_text + if {$m} { + # suspect VeNCrypt or ANONTLS plaintext RFB + set cert_text "" + set vencrypt 1 + incr pstr + mesg "#${pstr} Fetching $hpnew Cert... $vencrypt/$anondh" + if {! $is_windows} { + catch {set cert_text [fetch_cert_unix $hp $vencrypt $anondh]} } else { - global vencrypt_detected - set vencrypt_detected "" + after 600 + catch {set cert_text [fetch_cert_windows $hp $vencrypt $anondh]} } + if [info exists env(CERTDBG)] {puts "\nFetch-1-\n$cert_text"} } } - } else { - if {![regexp {BEGIN CERTIFICATE} $cert_text]} { - if [regexp {CONNECTED} $cert_text] { - if {[regexp -nocase {no peer certificate} $cert_text]} { - # suspect Anonymous Diffie Hellman - set cert_text "" - incr pstr - mesg "#${pstr} Fetching $hpnew Cert..." - catch {set cert_text [fetch_cert_windows $hp 1]} + } + if {![regexp {BEGIN CERTIFICATE} $cert_text]} { + if [regexp {CONNECTED} $cert_text] { + set m 0 + if [regexp -nocase -line {error.*handshake failure} $cert_text] { + set m 1 + } + if [regexp -nocase -line {error.*unknown protocol} $cert_text] { + set m 1 + } + if {!$m && $is_windows} { + if [regexp -nocase {no peer certificate} $cert_text] { + set m 1 } } - } - if {![regexp {BEGIN CERTIFICATE} $cert_text]} { - if [regexp {CONNECTED} $cert_text] { - if {[regexp -nocase {cipher.*ADH} $cert_text]} { - # it is Anonymous Diffie Hellman - mesg "WARNING: Anonymous Diffie Hellman Server detected" - .f4.getcert configure -state normal - return $cert_text + if {$m} { + # suspect Anonymous Diffie Hellman + set cert_text "" + set anondh 1 + incr pstr + mesg "#${pstr} Fetching $hpnew Cert... $vencrypt/$anondh" + if {! $is_windows} { + catch {set cert_text [fetch_cert_unix $hp $vencrypt $anondh]} + } else { + after 600 + catch {set cert_text [fetch_cert_windows $hp $vencrypt $anondh]} } + if [info exists env(CERTDBG)] {puts "\nFetch-2-\n$cert_text"} + } + } + } + if {![regexp {BEGIN CERTIFICATE} $cert_text]} { + if [regexp {CONNECTED} $cert_text] { + if {[regexp -nocase -line {cipher.*ADH} $cert_text]} { + # it is Anonymous Diffie Hellman + mesg "WARNING: Anonymous Diffie Hellman Server detected (no Cert)" + after 300 + .f4.getcert configure -state normal + return $cert_text + } else { + global vencrypt_detected + set vencrypt_detected "" } } } + global vencrypt_detected server_vencrypt + if {$vencrypt_detected != "" && !$server_vencrypt} { + mesg "VeNCrypt/ANONTLS server detected." + after 600 + } .f4.getcert configure -state normal mesg "Fetched $hpnew Cert" @@ -4698,10 +5059,37 @@ if [info exists env(CERTDBG)] {puts "\nFetch-2-\n$cert_text"} } set text "" set on 0 + set subject "" + set curr_subject "" + set chain_n -1 + set chain(__empty__) "" foreach line [split $cert_text "\n"] { if [regexp -- {-----BEGIN CERTIFICATE-----} $line] { incr on } + if {$chain_n < -1} { + ; + } elseif [regexp {^ *([0-9]) *s:(.*/[A-Z][A-Z]*=.*$)} $line m cn sb] { + set cn [string trim $cn] + set sb [string trim $sb] + #puts cn=$cn + #puts sb=$sb + if {$subject == ""} { + set subject $sb + } + if {$cn > $chain_n} { + set chain_n $cn + set curr_subject $sb + } else { + set chain_n -2 + } + } elseif [regexp {^ *i:(.*/[A-Z][A-Z]*=.*$)} $line m is] { + set is [string trim $is] + #puts is=$is + if {$curr_subject != ""} { + set chain($curr_subject) $is + } + } if {$on != 1} { continue; } @@ -4710,6 +5098,51 @@ if [info exists env(CERTDBG)] {puts "\nFetch-2-\n$cert_text"} set on 2 } } + set chain_str "subject: not-known\n" + set curr_subject $subject + set self_signed 0 + set top_issuer "" + for {set i 0} {$i < 10} {incr i} { + if {$curr_subject != ""} { + if {$i == 0} { + set chain_str "- subject: $curr_subject\n\n" + } else { + set chain_str "${chain_str}- issuer$i: $curr_subject\n\n" + set top_issuer $curr_subject; + } + if {![info exists chain($curr_subject)]} { + break + } elseif {$chain($curr_subject) == ""} { + break + } elseif {$curr_subject == $chain($curr_subject)} { + set j [expr $i + 1] + set chain_str "${chain_str}- issuer$j: $curr_subject\n\n" + set top_issuer $curr_subject; + if {$i == 0} { + set self_signed 1 + } + break; + } + set curr_subject $chain($curr_subject) + } + } + set chain_str "${chain_str}INFO: SELF_SIGNED=$self_signed\n\n" + if {$self_signed} { + set chain_str "${chain_str}INFO: Certificate is Self-Signed.\n" + set chain_str "${chain_str}INFO: It will successfully authenticate when used as a ServerCert or Accepted-Cert.\n" + set chain_str "${chain_str}INFO: Be sure to check carefully that you trust this certificate before saving it.\n" + } else { + set chain_str "${chain_str}INFO: Certificate is signed by a Certificate Authority (CA).\n" + set chain_str "${chain_str}INFO: It *WILL NOT* successfully authenticate when used as a ServerCert or Accepted-Cert.\n" + set chain_str "${chain_str}INFO: You need to Obtain and Save the CA's Certificate (issuer) instead" + if {$top_issuer != ""} { + set chain_str "${chain_str}:\nINFO: CA: $top_issuer\n" + } else { + set chain_str "${chain_str}.\n" + } + } + #puts "\n$chain_str\n" + global is_windows set tmp "/tmp/cert.hsh.[tpid]" set tmp [mytmp $tmp] @@ -4731,9 +5164,9 @@ if [info exists env(CERTDBG)] {puts "\nFetch-2-\n$cert_text"} if [regexp -nocase {SHA. Finger[^\n]*} $info mvar] { set cert_text "$mvar\n\n$cert_text" } - set cert_text "$cert_text\n\n----------------------------------\nOutput of x509 -text -fingerprint:\n\n$info" + set cert_text "$cert_text\n\n----------------------------------\nOutput of openssl x509 -text -fingerprint:\n\n$info" } - set cert_text "==== SSL Certificate from $hp ====\n\n$cert_text" + set cert_text "==== SSL Certificate from $hp ====\n\n$chain_str\n$cert_text" } if {! $save} { @@ -4742,6 +5175,16 @@ if [info exists env(CERTDBG)] {puts "\nFetch-2-\n$cert_text"} fetch_dialog $cert_text $hp $hpnew $ok $n } + +proc skip_non_self_signed {w hp} { + set msg "Certificate from $hp is not Self-Signed, it was signed by a Certificate Authority (CA). Saving it does not make sense because it cannot be used to authenticate anything. You need to Obtain and Save the CA Certificate instead. Save it anyway?" + set reply [tk_messageBox -type okcancel -default cancel -parent $w -icon warning -message $msg -title "CA Signed Certificate"] + if {$reply == "cancel"} { + return 1 + } else { + return 0 + } +} proc fetch_dialog {cert_text hp hpnew ok n} { toplev .fetch @@ -4749,8 +5192,15 @@ proc fetch_dialog {cert_text hp hpnew ok n} { scroll_text_dismiss .fetch.f 90 $n if {$ok} { - button .fetch.save -text Save -command "destroy .fetch; save_cert {$hpnew}" - button .fetch.help -text Help -command "help_fetch_cert" + set ss 0 + if [regexp {INFO: SELF_SIGNED=1} $cert_text] { + button .fetch.save -text Save -command "destroy .fetch; save_cert {$hpnew}" + set ss 1 + } else { + button .fetch.save -text Save -command "if \[skip_non_self_signed .fetch {$hpnew}\] {return} else {destroy .fetch; save_cert {$hpnew}}" + set ss 0 + } + button .fetch.help -text Help -command "help_fetch_cert $ss" pack .fetch.help .fetch.save -side bottom -fill x .fetch.d configure -text "Cancel" } @@ -4763,10 +5213,19 @@ proc fetch_dialog {cert_text hp hpnew ok n} { } proc get_vencrypt_proxy {hpnew} { + if [regexp -nocase {^vnc://} $hpnew] { + return "" + } set hpnew [get_ssh_hp $hpnew] + regsub -nocase {^[A-z+]*://} $hpnew "" hpnew set list [split $hpnew ":"] set h [lindex $list 0] set p [lindex $list 1] + + if {$p == ""} { + # might not matter, i.e. SSH+SSL only... + set p 5900 + } set hp2 $h if {$p < 0} { set hp2 "$hp2:[expr - $p]" @@ -4780,8 +5239,10 @@ proc get_vencrypt_proxy {hpnew} { proc fetch_cert_unix {hp {vencrypt 0} {anondh 0}} { global use_listen + set hpnew [get_ssh_hp $hp] set proxy [get_ssh_proxy $hp] + if {$vencrypt} { global vencrypt_detected set vencrypt_detected [get_vencrypt_proxy $hpnew] @@ -4816,13 +5277,23 @@ if [info exists env(CERTDBG)] {puts "\nFetch-cmd: $cmd"} return [eval exec $cmd] } -proc fetch_cert_windows {hp {anondh 0}} { +proc fetch_cert_windows {hp {vencrypt 0} {anondh 0}} { regsub {^vnc.*://} $hp "" hp set hpnew [get_ssh_hp $hp] set proxy [get_ssh_proxy $hp] + if {$vencrypt} { + global vencrypt_detected + set vencrypt_detected [get_vencrypt_proxy $hpnew] + if {$proxy != ""} { + set proxy "$proxy,$vencrypt_detected" + } else { + set proxy $vencrypt_detected + } + } + set list [split $hpnew ":"] global win_localhost @@ -4878,8 +5349,8 @@ proc fetch_cert_windows {hp {anondh 0}} { set host $win_localhost set port $port2 - mesg "Starting TCP helper on port $port2 ..." - after 600 + mesg "Starting Proxy TCP helper on port $port2 ..." + after 500 set proxy_pid [exec "connect_br.exe" &] if {$sp == ""} { @@ -4929,6 +5400,9 @@ proc fetch_cert_windows {hp {anondh 0}} { if [regexp {END CERT} $line] { set got 1 } + if {$anondh && [regexp -nocase {cipher.*ADH} $line]} { + set got 1 + } if {$got && [regexp {^ *Verify return code} $line]} { break } @@ -5005,38 +5479,47 @@ proc fetch_cert_windows {hp {anondh 0}} { return $text } -proc check_accepted_certs {} { +proc check_accepted_certs {{probe_only 0}} { global cert_text always_verify_ssl global skip_verify_accepted_certs use_listen - global ultra_dsm server_anondh + global ultra_dsm env + global server_vencrypt server_anondh no_probe_vencrypt if {! $always_verify_ssl} { set skip_verify_accepted_certs 1 - return 1 + if {$server_vencrypt} { + return 1 + } + if {$no_probe_vencrypt} { + return 1 + } } if {$server_anondh} { mesg "WARNING: Anonymous Diffie Hellman (SKIPPING CERT CHECK)" - after 2000 + after 1000 set skip_verify_accepted_certs 1 return 1 } - if {$use_listen} { + if {$ultra_dsm} { return 1; } - if {$ultra_dsm} { + if {$use_listen} { return 1; } global anon_dh_detected set anon_dh_detected 0 - global vencrypt_detected - set vencrypt_detected "" set cert_text [fetch_cert 0] - if {[regexp -nocase {cipher.*ADH} $cert_text]} { - set msg "Anonymous Diffie-Hellman server detected.\nThere will be encryption, but no\nSSL/TLS authentication. Continue?" - set reply [tk_messageBox -type okcancel -icon warning -message $msg -title "Anonymous Diffie-Hellman Detected"] + set mvar "" + if {[regexp -nocase -line {cipher.*ADH} $cert_text mvar]} { + + if [info exists env(CERTDBG)] {puts "\nFetch-MSG-\n$cert_text"} + if [info exists env(CERTDBG)] {puts "\nBEGIN_MVAR: $mvar\nEND_MVAR\n"} + + set msg "Anonymous Diffie-Hellman server detected. There will be encryption, but no SSL/TLS authentication. Continue?" + set reply [tk_messageBox -type okcancel -default ok -icon warning -message $msg -title "Anonymous Diffie-Hellman Detected"] set anon_dh_detected 1 if {$reply == "cancel"} { return 0 @@ -5047,14 +5530,50 @@ proc check_accepted_certs {} { } } + if {$probe_only} { + return 1 + } + if {! $always_verify_ssl} { + return 1 + } + set from "" set fingerprint "" set fingerline "" + set self_signed 1 + set subject_issuer "" + set subject "" + set issuer "" set i 0 foreach line [split $cert_text "\n"] { incr i - if {$i > 4} { + if {$i > 50} { + break + } + if [regexp {^- subject: *(.*)$} $line m val] { + set val [string trim $val] + set subject_issuer "${subject_issuer}subject:$val\n" + set subject $val + } + if [regexp {^- (issuer[0-9][0-9]*): *(.*)$} $line m is val] { + set val [string trim $val] + set subject_issuer "${subject_issuer}$is:$val\n" + set issuer $val + } + if [regexp {^INFO: SELF_SIGNED=(.*)$} $line m val] { + set subject_issuer "${subject_issuer}SELF_SIGNED:$val\n" + } + if [regexp {^depth=} $line] { + break + } + if [regexp {^verify } $line] { + break + } + if [regexp {^CONNECTED} $line] { + break + } + if [regexp {^Certificate chain} $line] { break } if [regexp {^==== SSL Certificate from (.*) ====} $line mv str] { @@ -5064,6 +5583,9 @@ proc check_accepted_certs {} { set fingerline $line set fingerprint [string trim $str] } + if [regexp -nocase {^INFO: SELF_SIGNED=([01])} $line mv str] { + set self_signed $str + } } set fingerprint [string tolower $fingerprint] @@ -5074,6 +5596,7 @@ proc check_accepted_certs {} { regsub -all {^[+a-z]*://} $from "" from regsub -all {:} $from "-" from regsub -all {[\\/=]} $from "_" from + regsub -all {[ ]} $from "_" from if {$from == "" || $fingerprint == ""} { bell @@ -5098,24 +5621,20 @@ proc check_accepted_certs {} { set crt "$adir/$from=$fingerprint.crt" if [file exists $crt] { - mesg "OK: Certificate found in ACCEPTED_CERTS" - after 750 - return 1 - } - - set crt_old "$adir/$fingerprint=$from.crt" - - if [file exists $crt_old] { - mesg "OK: Certificate found in ACCEPTED_CERTS" - after 750 - return 1 + if {$self_signed} { + mesg "OK: Certificate found in ACCEPTED_CERTS" + after 750 + return 1 + } } set cnt 0 foreach f [glob -nocomplain -directory $adir "*$fingerprint*.crt"] { mesg "CERT: $f" after 150 - incr cnt + if {$self_signed} { + incr cnt + } } set oth 0 @@ -5124,9 +5643,6 @@ proc check_accepted_certs {} { if {$f == $crt} { continue } - if {$f == $crt_old} { - continue - } set fb [file tail $f] mesg "OTHER CERT: $fb" if {$cnt > 0} { @@ -5138,13 +5654,11 @@ proc check_accepted_certs {} { lappend others $f incr oth } + foreach f [glob -nocomplain -directory $adir "*.crt"] { if {$f == $crt} { continue } - if {$f == $crt_old} { - continue - } set saw 0 foreach o $others { if {$f == $o} { @@ -5160,15 +5674,63 @@ proc check_accepted_certs {} { continue } set same 0 + set sub "" + set iss "" + set isn -1; while {[gets $fh line] > -1} { if [regexp {^Host-Display: (.*)$} $line mv hd] { if {$hd == $hp || $hd == $from} { set same 1 } } + if [regexp {^subject:(.*)$} $line mv val] { + set sub $val + } + if [regexp {^issue([0-9][0-9]*):(.*)$} $line mv in val] { + if {$in > $isn} { + set isn $in + set iss $val + } + } } close $fh; + if {!$self_signed} { + if {$sub == ""} { + set ossl [get_openssl] + set si_txt [exec $ossl x509 -subject -issuer -noout -in $f] + foreach line [split $si_txt "\n"] { + if [regexp -nocase {^subject= *(.*)$} $line mv str] { + set str [string trim $str] + if {$str != ""} { + set sub $str + } + } elseif [regexp -nocase {^issuer= *(.*)$} $line mv str] { + set str [string trim $str] + if {$iss != ""} { + set iss $str + } + } + } + } + if {$issuer != "" && $sub != ""} { + global env + if [info exists env(CERTDBG)] { + puts "f: $f" + puts "s: $sub" + puts "i: $issuer" + puts "===================" + } + if {$issuer == $sub} { + set fb [file tail $f] + mesg "Certificate Authority (CA) CERT: $fb" + incr cnt + after 500 + } + } + continue + } + if {! $same} { continue } @@ -5184,21 +5746,27 @@ proc check_accepted_certs {} { lappend others $f incr oth } + if {$cnt > 0} { - mesg "OK: Certificate found in ACCEPTED_CERTS" - after 300 + if {$self_signed} { + mesg "OK: Server Certificate found in ACCEPTED_CERTS" + after 400 + } else { + mesg "OK: CA Certificate found in ACCEPTED_CERTS" + after 800 + } return 1 } set hp2 [get_vncdisplay] set msg " - The SSL Certificate from host: + The Self-Signed SSL Certificate from host: $hp2 - with fingerprint: + Fingerprint: $fingerprint - $fingerprint + Subject: $subject is not present in the 'Accepted Certs' directory: @@ -5209,17 +5777,57 @@ proc check_accepted_certs {} { sent to you by the server administrator). - Do you want this certificate to be saved in the accepted certs directory - and then used to SSL authenticate VNC servers? + THE QUESTION: 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. +" + set msg_bottom " Choose 'Ignore Cert for One Connection' to connect a single time to the - server with NO certificate verification. You will see this dialog again + server with *NO* certificate authentication. You will see this dialog again the next time you connect to the same server. + + Choose 'Continue as though I saved it' to launch stunnel and the VNC viewer. + Do this if you know the correct Certificate is in the 'Accepted Certs' + directory. If it is not, stunnel will fail and report 'VERIFY ERROR:...' + + Choose 'Cancel' to not connect to the VNC Server at all. " + set msg_ca " + The CA-signed SSL Certificate from host: + + $hp2 + + Fingerprint: $fingerprint + + Subject: $subject + + Issuer: $issuer + + is signed by a Certificate Authority (CA) (the 'Issuer' above.) + + However, the certificate of the CA 'Issuer' is not present in the + 'Accepted Certs' directory: + + $adir + + You will need to obtain the certificate of the CA 'Issuer' via some means + (perhaps ask the VNC server administrator for it.) Then, after you have + verified that the CA certificate is one that you trust, import the + certificate via Certs -> Import Certificate. Be sure to select to also + save it to the Accepted Certs directory so it will automatically be used. +" + set msg "$msg$msg_bottom" + set msg_ca "$msg_ca$msg_bottom" + + if {!$self_signed} { + set msg $msg_ca + } + if {$oth == 0} { regsub {%WARN} $msg "" msg } else { @@ -5255,20 +5863,30 @@ proc check_accepted_certs {} { foreach l [split $msg "\n"] { incr n } + if {!$self_signed} { + set n [expr $n + 2] + } else { + set n [expr $n + 1] + } toplev .acert scroll_text .acert.f 83 $n button .acert.inspect -text "Inspect and maybe Save Cert ..." -command "destroy .acert; set accept_cert_dialog 1" button .acert.accept -text "Ignore Cert for One Connection " -command "destroy .acert; set accept_cert_dialog 2" + button .acert.continue -text "Continue as though I saved it " -command "destroy .acert; set accept_cert_dialog 3" button .acert.cancel -text "Cancel" -command "destroy .acert; set accept_cert_dialog 0" wm title .acert "Unrecognized SSL Cert!" .acert.f.t insert end $msg - pack .acert.accept .acert.inspect .acert.cancel -side bottom -fill x + pack .acert.cancel .acert.continue .acert.accept .acert.inspect -side bottom -fill x pack .acert.f -side top -fill both -expand 1 + if {! $self_signed} { + catch {.acert.inspect configure -state disabled} + } + center_win .acert global accept_cert_dialog @@ -5282,6 +5900,9 @@ proc check_accepted_certs {} { set skip_verify_accepted_certs 1 return 1 } + if {$accept_cert_dialog == 3} { + return 1 + } if {$accept_cert_dialog != 1} { return 0 } @@ -5294,6 +5915,8 @@ proc check_accepted_certs {} { global do_save_saved_it set do_save_saved_it 0 + global do_save_saved_hash_it + set do_save_saved_hash_it 0 fetch_dialog $cert_text $hp $hp 1 47 update; after 150 @@ -5309,7 +5932,9 @@ proc check_accepted_certs {} { set fetch_cert_filename "" set accepted_cert_dialog_in_progress 0 - save_hash $crt $adir $hp $fingerline $from $fingerprint + if {!$do_save_saved_hash_it} { + save_hash $crt $adir $hp $fingerline $from $fingerprint $subject_issuer + } if {$do_save_saved_it} { return 1 @@ -5318,7 +5943,7 @@ proc check_accepted_certs {} { } } -proc save_hash {crt adir hp fingerline from fingerprint} { +proc save_hash {crt adir hp fingerline from fingerprint {subject_issuer ""}} { if ![file exists $crt] { return } @@ -5327,17 +5952,24 @@ proc save_hash {crt adir hp fingerline from fingerprint} { set hash [string trim $hash] if [regexp {^([0-9a-f][0-9a-f]*)} $hash mv h] { set hashfile "$adir/$h.0" + set hn "$h.0" if [file exists $hashfile] { set hashfile "$adir/$h.1" + set hn "$h.1" + if [file exists $hashfile] { + set hashfile "$adir/$h.2" + set hn "$h.2" + } } set fh [open $crt "a"] if {$fh != ""} { puts $fh "" - puts $fh "SSVNC info:" + puts $fh "SSVNC-info:" puts $fh "Host-Display: $hp" puts $fh "$fingerline" - puts $fh "hash filename: $h.0" - puts $fh "full filename: $from=$fingerprint.crt" + puts $fh "hash-filename: $hn" + puts $fh "full-filename: $from=$fingerprint.crt" + puts -nonewline $fh $subject_issuer close $fh } catch {file copy -force $crt $hashfile} @@ -5489,13 +6121,16 @@ proc init_unixpw {hp} { } proc check_for_listen_ssl_cert {} { - global mycert use_listen use_ssh + global mycert use_listen use_ssh ultra_dsm if {! $use_listen} { return 1 } if {$use_ssh} { return 1 } + if {$ultra_dsm} { + return 1 + } if {$mycert != ""} { return 1 } @@ -5505,13 +6140,13 @@ proc check_for_listen_ssl_cert {} { if {[file exists $name]} { set mycert $name mesg "Using Listen Cert: $name" - after 1000 + after 700 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] + set reply [tk_messageBox -type okcancel -default ok -icon warning -message $msg -title $msg] if {$reply == "cancel"} { return 0 } @@ -5520,7 +6155,7 @@ proc check_for_listen_ssl_cert {} { if {[file exists $name]} { set mycert $name mesg "Using Listen Cert: $name" - after 1000 + after 700 return 1 } return 0 @@ -5530,7 +6165,7 @@ proc listen_verify_all_dialog {hp} { global use_listen always_verify_ssl global did_listen_verify_all_dialog global svcert - global sshssl_sw + global sshssl_sw ultra_dsm if {!$use_listen} { return 1 @@ -5541,6 +6176,9 @@ proc listen_verify_all_dialog {hp} { if {$svcert != ""} { return 1 } + if {$ultra_dsm} { + return 1 + } if [regexp -nocase {^vnc://} $hp] { return 1 } @@ -5559,14 +6197,14 @@ proc listen_verify_all_dialog {hp} { toplev .lvd global help_font wm title .lvd "Verify All Certs for Reverse Connections" - eval text .lvd.t -width 55 -height 21 $help_font + eval text .lvd.t -width 55 -height 22 $help_font .lvd.t insert end { Information: You have the 'Verify All Certs' option enabled in Reverse VNC Connections (-LISTEN) mode. - For this to work, you must have already saved + For this to work, you must have ALREADY saved the remote VNC Server's Certificate to the 'Accepted Certs' directory. Otherwise the incoming Reverse connection will be rejected. @@ -5578,15 +6216,27 @@ proc listen_verify_all_dialog {hp} { If you do not want to save the certificate of the VNC Server making the Reverse connection, - you must disable 'Verify All Certs' (and so - the server authenticity will not be checked.) + you must disable 'Verify All Certs' (note that + this means the server authenticity will not be + checked.) } button .lvd.ok -text OK -command {destroy .lvd} - pack .lvd.t .lvd.ok -side top -fill x + button .lvd.ok2 -text OK -command {destroy .lvd} + button .lvd.disable -text "Disable 'Verify All Certs'" -command {set always_verify_ssl 0; destroy .lvd} + global uname + if {$uname == "Darwin"} { + pack .lvd.t .lvd.ok2 .lvd.disable .lvd.ok -side top -fill x + } else { + pack .lvd.t .lvd.disable .lvd.ok -side top -fill x + } center_win .lvd + update tkwait window .lvd + update + after 50 + update set did_listen_verify_all_dialog 1 return 1 @@ -5608,14 +6258,91 @@ proc reset_stunnel_extra_opts {} { set env(SSVNC_ULTRA_DSM) "" set env(SSVNC_TURBOVNC) "" catch { unset env(VNCVIEWER_NO_PIPELINE_UPDATES) } + catch { unset env(VNCVIEWER_NOTTY) } catch { unset env(SSVNC_ACCEPT_POPUP) } catch { unset env(SSVNC_ACCEPT_POPUP_SC) } + catch { unset env(SSVNC_KNOWN_HOSTS_FILE) } +} + +proc maybe_add_vencrypt {proxy hp} { + global vencrypt_detected server_vencrypt + set vpd "" + if {$vencrypt_detected != ""} { + set vpd $vencrypt_detected + set vencrypt_detected "" + } elseif {$server_vencrypt} { + set vpd [get_vencrypt_proxy $hp] + } + if {$vpd != ""} { + if {$proxy != ""} { + set proxy "$proxy,$vpd" + } else { + set proxy "$vpd" + } + } + return $proxy +} + +proc no_certs_tutorial_mesg {} { + global svcert crtdir + global server_anondh + global always_verify_ssl + + set doit 0 + if {!$always_verify_ssl} { + if {$svcert == ""} { + if {$crtdir == "" || $crtdir == "ACCEPTED_CERTS"} { + set doit 1 + } + } + } elseif {$server_anondh} { + set doit 1 + } + if {$doit} { + mesg "INFO: without Certificate checking man-in-the-middle attack is possible." + } else { + set str "" + catch {set str [.l cget -text]} + if {$str != "" && [regexp {^INFO: without Certificate} $str]} { + mesg "" + } + } +} + +proc vencrypt_tutorial_mesg {} { + global use_ssh use_sshssl use_listen + global server_vencrypt no_probe_vencrypt + global ultra_dsm + + set m "" + if {$use_ssh} { + ; + } elseif {$server_vencrypt} { + ; + } elseif {$ultra_dsm} { + ; + } elseif {$use_listen} { + set m "No VeNCrypt Auto-Detection: Listen mode." + } elseif {$use_sshssl} { + set m "No VeNCrypt Auto-Detection: SSH+SSL mode." + } elseif {$no_probe_vencrypt} { + set m "No VeNCrypt Auto-Detection: Disabled." + } + if {$m != ""} { + mesg $m + after 1000 + } + return $m + + #global svcert always_verify_ssl + #$svcert != "" || !$always_verify_ssl + # set m "No VeNCrypt Auto-Detection: 'Verify All Certs' disabled" } proc launch_unix {hp} { global smb_redir_0 smb_mounts env global vncauth_passwd use_unixpw unixpw_username unixpw_passwd - global ssh_only ts_only use_x11cursor use_nobell use_rawlocal use_popupfix ssvnc_scale ssvnc_escape + global ssh_only ts_only use_x11cursor use_nobell use_rawlocal use_notty use_popupfix ssvnc_scale ssvnc_escape global ssvnc_encodings ssvnc_extra_opts globalize @@ -5726,7 +6453,9 @@ proc launch_unix {hp} { } } if {$ultra_dsm} { - if {![file exists $ultra_dsm_file] && ![regexp {pw=} $ultra_dsm_file]} { + if {$ultra_dsm_type == "securevnc"} { + ; + } elseif {![file exists $ultra_dsm_file] && ![regexp {pw=} $ultra_dsm_file]} { mesg "DSM key file does exist: $ultra_dsm_file" bell after 1000 @@ -5740,6 +6469,12 @@ proc launch_unix {hp} { after 1000 return } + if [regexp {'} $vncauth_passwd] { + mesg "For DSM pw=VNCPASSWD password must not contain single quotes." + bell + after 1000 + return + } } set dsm "ultravnc_dsm_helper " if {$ultra_dsm_noultra} { @@ -5759,9 +6494,13 @@ proc launch_unix {hp} { } } if {$ultra_dsm_file == "pw=VNCPASSWORD" || $ultra_dsm_file == "pw=VNCPASSWD"} { - append dsm " pw=$vncauth_passwd" + append dsm " pw='$vncauth_passwd'" } else { - append dsm " $ultra_dsm_file" + if {$ultra_dsm_file == "" && $ultra_dsm_type == "securevnc"} { + append dsm " none" + } else { + append dsm " $ultra_dsm_file" + } } set env(SSVNC_ULTRA_DSM) $dsm } @@ -5782,7 +6521,7 @@ proc launch_unix {hp} { } 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 + after 700 } if {$skip_ssh || $ultra_dsm} { set cmd "ss_vncviewer" @@ -5812,6 +6551,12 @@ proc launch_unix {hp} { set proxy [get_ssh_proxy $hp] set sshcmd [get_ssh_cmd $hp] + if {$use_sshssl} { + if {!$do_direct} { + set proxy [maybe_add_vencrypt $proxy $hp] + } + } + if {$ts_only} { regsub {:0$} $hpnew "" hpnew if {$proxy == ""} { @@ -5986,6 +6731,7 @@ proc launch_unix {hp} { } if {! $do_direct && ! $ultra_dsm && ![regexp -nocase {ssh://} $hpnew]} { + set did_check 0 if {$mycert != ""} { set cmd "$cmd -mycert '$mycert'" } @@ -5998,7 +6744,9 @@ proc launch_unix {hp} { if {$crtdir == "ACCEPTED_CERTS"} { global skip_verify_accepted_certs set skip_verify_accepted_certs 0 - if {! [check_accepted_certs]} { + + set did_check 1 + if {! [check_accepted_certs 0]} { reset_stunnel_extra_opts return } @@ -6008,27 +6756,20 @@ proc launch_unix {hp} { catch {file mkdir $adir} set cmd "$cmd -verify '$adir'" } + } else { set cmd "$cmd -verify '$crtdir'" } } - } - global vencrypt_detected - if {$vencrypt_detected != ""} { - if {$proxy != ""} { - set proxy "$proxy,$vencrypt_detected" - } else { - set proxy "$vencrypt_detected" - } - set vencrypt_detected "" - } elseif {$server_vencrypt} { - set vdp [get_vencrypt_proxy $hp] - if {$proxy != ""} { - set proxy "$proxy,$vdp" - } else { - set proxy $vdp + if {! $did_check} { + check_accepted_certs 1 } } + + if {!$do_direct} { + set proxy [maybe_add_vencrypt $proxy $hp] + } + if {$proxy != ""} { set cmd "$cmd -proxy '$proxy'" } @@ -6036,20 +6777,22 @@ proc launch_unix {hp} { if [regexp {^.*@} $hp match] { catch {raise .; update} mesg "Trimming \"$match\" from hostname" - after 1000 + after 700 regsub {^.*@} $hp "" hp } if [regexp {@} $proxy] { bell catch {raise .; update} mesg "WARNING: SSL proxy contains \"@\" sign" - after 2000 + after 1500 } } global anon_dh_detected if {$anon_dh_detected || $server_anondh} { - set cmd "$cmd -anondh" + if {!$do_direct} { + set cmd "$cmd -anondh" + } set anon_dh_detected 0 } if {$use_alpha} { @@ -6067,6 +6810,9 @@ proc launch_unix {hp} { if {$disable_pipeline} { set env(VNCVIEWER_NO_PIPELINE_UPDATES) 1 } + if {$ssh_known_hosts_filename != ""} { + set env(SSVNC_KNOWN_HOSTS_FILE) $ssh_known_hosts_filename + } if {$use_grab} { set cmd "$cmd -grab" } @@ -6079,6 +6825,9 @@ proc launch_unix {hp} { if {$use_rawlocal} { set cmd "$cmd -rawlocal" } + if {$use_notty} { + set env(VNCVIEWER_NOTTY) 1 + } if {$use_popupfix} { set cmd "$cmd -popupfix" } @@ -6231,6 +6980,8 @@ proc launch_unix {hp} { } if {$darwin_cotvnc} { set cmd "$cmd --PasswordFile $passwdfile" + } elseif {$flavor == "unknown"} { + ; } else { set cmd "$cmd -passwd $passwdfile" } @@ -6239,6 +6990,8 @@ proc launch_unix {hp} { if {$use_viewonly} { if {$darwin_cotvnc} { set cmd "$cmd --ViewOnly" + } elseif {$flavor == "unknown"} { + ; } elseif {$flavor == "ultravnc"} { set cmd "$cmd /viewonly" } else { @@ -6250,6 +7003,10 @@ proc launch_unix {hp} { set cmd "$cmd --FullScreen" } elseif {$flavor == "ultravnc"} { set cmd "$cmd /fullscreen" + } elseif {$flavor == "unknown"} { + if [regexp {vinagre} $change_vncviewer_path] { + set cmd "$cmd -f" + } } else { set cmd "$cmd -fullscreen" } @@ -6259,6 +7016,10 @@ proc launch_unix {hp} { set cmd "$cmd -lowcolourlevel 1" } elseif {$flavor == "ultravnc"} { set cmd "$cmd /8bit" + } elseif {$flavor == "ultravnc"} { + ; + } elseif {$flavor == "unknown"} { + ; } else { set cmd "$cmd -bgr233" } @@ -6268,6 +7029,8 @@ proc launch_unix {hp} { ; } elseif {$flavor == "ultravnc"} { ; + } elseif {$flavor == "unknown"} { + ; } elseif {! $realvnc4 && ! $realvnc3} { set cmd "$cmd -nojpeg" } @@ -6277,6 +7040,8 @@ proc launch_unix {hp} { ; } elseif {$flavor == "ultravnc"} { ; + } elseif {$flavor == "unknown"} { + ; } elseif {! $realvnc4 && ! $realvnc3} { set cmd "$cmd -noraiseonbeep" } @@ -6286,6 +7051,8 @@ proc launch_unix {hp} { ; } elseif {$flavor == "ultravnc"} { ; + } elseif {$flavor == "unknown"} { + ; } elseif {$realvnc4} { set cmd "$cmd -zliblevel '$use_compresslevel'" } else { @@ -6297,6 +7064,8 @@ proc launch_unix {hp} { ; } elseif {$flavor == "ultravnc"} { ; + } elseif {$flavor == "unknown"} { + ; } elseif {! $realvnc4 && ! $realvnc3} { set cmd "$cmd -quality '$use_quality'" } @@ -6307,6 +7076,8 @@ proc launch_unix {hp} { ; } elseif {$flavor == "ultravnc"} { ; + } elseif {$flavor == "unknown"} { + ; } elseif {$realvnc4} { set cmd "$cmd -preferredencoding zrle" } else { @@ -6366,6 +7137,8 @@ proc launch_unix {hp} { init_unixpw $hp + vencrypt_tutorial_mesg + wm withdraw . update @@ -6378,7 +7151,7 @@ proc launch_unix {hp} { set xrm2 "XTerm*VT100*translations:#override Shift:print()\\nCtrlN:print()" set xrm3 "*mainMenu*print*Label: New SSVNC_GUI" } - set m "Done. You Can X-out or Ctrl-C this Terminal if you like. Ctrl-\\\\ to pause." + set m "Done. You Can X-out or Ctrl-C this Terminal if you like. Use Ctrl-\\\\ to pause." global uname if {$uname == "Darwin"} { regsub {X-out or } $m "" m @@ -6404,8 +7177,17 @@ proc launch_unix {hp} { set sstx "SSVNC" set hptx "$hp (Press Ctrl-C to Stop Listening)" } + + + set s1 5 + set s2 4 + if [info exists env(SSVNC_FINISH_SLEEP)] { + set s1 $env(SSVNC_FINISH_SLEEP); + set s2 $s1 + } + unix_terminal_cmd $geometry "$sstx $hptx" \ - "$te$cmd; set +xv; ulimit -c 0; trap 'printf \"Paused. Press Enter to exit:\"; read x' QUIT; echo; echo $m; echo; echo sleep 5; echo; sleep 5" 0 $xrm1 $xrm2 $xrm3 + "$te$cmd; set +xv; ulimit -c 0; trap 'printf \"Paused. Press Enter to exit:\"; read x' QUIT; echo; echo $m; echo; echo sleep $s1; echo; sleep $s2" 0 $xrm1 $xrm2 $xrm3 set env(SS_VNCVIEWER_SSH_CMD) "" set env(SS_VNCVIEWER_USE_C) "" @@ -6458,9 +7240,9 @@ proc kill_stunnel {pids} { mesg "killing STUNNEL pid: $pid" winkill $pid if {$count == 0} { - after 1200 + after 600 } else { - after 500 + after 300 } incr count } @@ -6498,7 +7280,13 @@ proc note_stunnel_pids {when} { set output [get_task_list] foreach line [split $output "\n\r"] { + set m 0 if [regexp -nocase {stunnel} $line] { + set m 1 + } elseif [regexp -nocase {connect_br} $line] { + set m 1 + } + if {$m} { if [regexp {(-?[0-9][0-9]*)} $line m p] { if {$when == "before"} { set pids_before($p) $line @@ -6561,9 +7349,9 @@ proc launch_shell_only {} { proc to_sshonly {} { global ssh_only ts_only env global showing_no_encryption - if {$showing_no_encryption} { - toggle_no_encryption - } + #if {$showing_no_encryption} { + # toggle_no_encryption + #} if {$ssh_only && !$ts_only} { return } @@ -6612,9 +7400,9 @@ proc toggle_sshonly {} { proc to_tsonly {} { global ts_only global showing_no_encryption - if {$showing_no_encryption} { - toggle_no_encryption - } + #if {$showing_no_encryption} { + # toggle_no_encryption + #} if {$ts_only} { return } @@ -6661,6 +7449,11 @@ proc to_ssvnc {} { catch {.l configure -text $t} catch {.f0.l configure -text "VNC Host:Display"} + #global started_with_noenc + #if {$started_with_noenc} { + # toggle_no_encryption + #} + global vncdisplay vncauth_passwd unixpw_username vncproxy remote_ssh_cmd set vncdisplay "" set vncauth_passwd "" @@ -6733,6 +7526,24 @@ proc launch {{hp ""}} { set vncdisplay "" return 0 } + if {[regexp {^SSH=} $hpt]} { + set t $hpt + regsub {^.*SSH=} $t "" t + set t [string trim $t] + set env(SSH) $t + mesg "set SSH to $t" + set vncdisplay "" + return 0 + } + if {[regexp {^FINISH=} $hpt] || [regexp {^SSVNC_FINISH_SLEEP=} $hpt]} { + set t $hpt + regsub {^.*=} $t "" t + set t [string trim $t] + set env(SSVNC_FINISH_SLEEP) $t + mesg "set SSVNC_FINISH_SLEEP to $t" + set vncdisplay "" + return 0 + } if {[regexp {^DEBUG_NETSTAT=} $hpt]} { set t $hpt regsub {^.*DEBUG_NETSTAT=} $t "" t @@ -6840,7 +7651,9 @@ proc launch {{hp ""}} { # WINDOWS BELOW: if [regexp {^vnc://} $hp] { - direct_connect_msg + if {! [info exists env(SSVNC_NO_ENC_WARN)]} { + direct_connect_msg + } regsub {^vnc://} $hp "" hp direct_connect_windows $hp return @@ -6911,10 +7724,12 @@ proc launch {{hp ""}} { set suffix "bat" } - set file "" - set n "" + set file1 "" + set n1 "" set file2 "" set n2 "" + set n3 "" + set n4 "" set now [clock seconds] set proxy [get_ssh_proxy $hp] @@ -6925,38 +7740,58 @@ proc launch {{hp ""}} { return } - for {set i 30} {$i < 90} {incr i} { + global port_slot + if {$port_slot != ""} { + set file1 "$prefix-$port_slot.$suffix" + set n1 $port_slot + set ps [expr $port_slot + 200] + set file2 "$prefix-$ps.$suffix" + set n2 $ps + mesg "Using Port Slot: $port_slot" + after 700 + } + + for {set i 30} {$i <= 99} {incr i} { set try "$prefix-$i.$suffix" + if {$i == $port_slot} { + continue + } if {[file exists $try]} { set mt [file mtime $try] set age [expr "$now - $mt"] set week [expr "7 * 3600 * 24"] if {$age > $week} { - catch {file delete $file} + catch {file delete $try} } } if {! [file exists $try]} { - if {$use_sshssl || $proxy != ""} { - if {$file != ""} { - set file2 $try - set n2 $i - break - } - } - set file $try - set n $i - if {! $use_sshssl && $proxy == ""} { + if {$file1 == ""} { + set file1 $try + set n1 $i + } elseif {$file2 == ""} { + set file2 $try + set n2 $i + } else { break } } } - if {$file == ""} { + if {$file1 == ""} { mesg "could not find free stunnel file" bell return } + if {$n1 == ""} { + set n1 10 + } + if {$n2 == ""} { + set n2 11 + } + set n3 [expr $n1 + 100] + set n4 [expr $n2 + 100] + global launch_windows_ssh_files set launch_windows_ssh_files "" @@ -6968,14 +7803,14 @@ proc launch {{hp ""}} { if {$use_sshssl} { set rc [launch_windows_ssh $hp $file2 $n2] if {$rc == 0} { - catch {file delete $file} + catch {file delete $file1} catch {file delete $file2} del_launch_windows_ssh_files return } set did_port_knock 1 } elseif {$use_ssh} { - launch_windows_ssh $hp $file $n + launch_windows_ssh $hp $file1 $n1 # WE ARE DONE. return } @@ -6992,7 +7827,7 @@ proc launch {{hp ""}} { if [regexp {^.*@} $host match] { catch {raise .; update} mesg "Trimming \"$match\" from hostname" - after 1000 + after 700 regsub {^.*@} $host "" host } @@ -7017,24 +7852,8 @@ proc launch {{hp ""}} { set port $disp } - if {$proxy != ""} { - if [regexp {@} $proxy] { - bell - catch {raise .; update} - mesg "WARNING: SSL proxy contains \"@\" sign" - after 2000 - } - if {$use_listen} { - set env(SSVNC_REVERSE) "$win_localhost:$port" - } else { - set env(SSVNC_LISTEN) [expr "$n2 + 5900"] - } - set env(SSVNC_PROXY) $proxy - set env(SSVNC_DEST) "$host:$port" - } - if {$debug} { - mesg "file: $file" + mesg "file: $file1" after 1000 } @@ -7048,7 +7867,7 @@ proc launch {{hp ""}} { set fail 0 - set fh [open $file "w"] + set fh [open $file1 "w"] if {$use_listen} { puts $fh "client = no" @@ -7089,6 +7908,8 @@ proc launch {{hp ""}} { } } + set did_check 0 + if {$svcert != ""} { if {! [file exists $svcert]} { mesg "ServerCert does not exist: $svcert" @@ -7101,7 +7922,11 @@ proc launch {{hp ""}} { if {$crtdir == "ACCEPTED_CERTS"} { global skip_verify_accepted_certs set skip_verify_accepted_certs 0 - if {! [check_accepted_certs]} { + set did_check 1 + if {$use_sshssl} { + set skip_verify_accepted_certs 1 + set did_check 0 + } elseif {! [check_accepted_certs 0]} { set fail 1 } if {! $skip_verify_accepted_certs} { @@ -7122,6 +7947,39 @@ proc launch {{hp ""}} { } } + if {!$did_check} { + check_accepted_certs 1 + } + + if {$use_sshssl} { + set p [expr "$n2 + 5900"] + set proxy [maybe_add_vencrypt $proxy "$win_localhost:$p"] + } else { + set proxy [maybe_add_vencrypt $proxy $hp] + } + + if {$proxy != ""} { + if {$use_sshssl} { + ; + } elseif [regexp {@} $proxy] { + bell + catch {raise .; update} + mesg "WARNING: SSL proxy contains \"@\" sign" + after 1500 + } + set env(SSVNC_PROXY) $proxy + set env(SSVNC_DEST) "$host:$port" + if {$use_listen} { + set env(SSVNC_REVERSE) "$win_localhost:$port" + } else { + if {$use_sshssl && [regexp {vencrypt:} $proxy]} { + set env(SSVNC_LISTEN) [expr "$n4 + 5900"] + } else { + set env(SSVNC_LISTEN) [expr "$n2 + 5900"] + } + } + } + global anon_dh_detected server_anondh if {$anon_dh_detected || $server_anondh} { puts $fh "ciphers = ALL:RC4+RSA:+SSLv2:@STRENGTH" @@ -7129,28 +7987,33 @@ proc launch {{hp ""}} { } - if {$n == ""} { - set n 10 - } - if {$n2 == ""} { - set n2 11 - } - puts $fh "\[vnc$n\]" + puts $fh "\[vnc$n1\]" set port2 "" + set port3 "" if {! $use_listen} { - set port2 [expr "$n + 5900"] - puts $fh "accept = $win_localhost:$port2" + set port2 [expr "$n1 + 5900"] + if [regexp {vencrypt:} $proxy] { + set port3 [expr "$n3 + 5900"] + set port2 $port3 + puts $fh "accept = $win_localhost:$port3" + } else { + puts $fh "accept = $win_localhost:$port2" + } - if {$use_sshssl || $proxy != ""} { + if {$use_sshssl && [regexp {vencrypt:} $proxy]} { + set port [expr "$n4 + 5900"] + puts $fh "connect = $win_localhost:$port" + } elseif {$use_sshssl || $proxy != ""} { set port [expr "$n2 + 5900"] puts $fh "connect = $win_localhost:$port" } else { puts $fh "connect = $host:$port" } } else { - set port2 [expr "$n + 5500"] + set port2 [expr "$n1 + 5500"] set hloc "" if {$use_ssh} { + # not reached? set hloc "$win_localhost:" set listening_name "$win_localhost:$port (on remote SSH side)" } else { @@ -7176,29 +8039,45 @@ proc launch {{hp ""}} { } if {$fail} { - catch {file delete $file} + catch {file delete $file1} return } + note_stunnel_pids "before" + set proxy_pid "" + set proxy_pid2 "" if {$proxy != ""} { - mesg "Starting TCP helper on port $port ..." - after 600 + if [regexp {vencrypt:} $proxy] { + set vport [expr "$n1 + 5900"] + mesg "Starting VeNCrypt helper on port $vport,$port3 ..." + after 500 + catch {file delete "$file1.pre"} + set env(SSVNC_PREDIGESTED_HANDSHAKE) "$file1.pre" + set env(SSVNC_VENCRYPT_VIEWER_BRIDGE) "$vport,$port3" + set proxy_pid2 [exec "connect_br.exe" &] + catch { unset env(SSVNC_VENCRYPT_VIEWER_BRIDGE) } + } + mesg "Starting VeNCrypt TCP helper on port $port ..." + after 500 set proxy_pid [exec "connect_br.exe" &] catch { unset env(SSVNC_PROXY) } catch { unset env(SSVNC_LISTEN) } catch { unset env(SSVNC_REVERSE) } catch { unset env(SSVNC_DEST) } + catch { unset env(SSVNC_PREDIGESTED_HANDSHAKE) } } mesg "Starting STUNNEL on port $port2 ..." - after 600 + after 500 - note_stunnel_pids "before" - - set pids [exec stunnel $file &] + set pids [exec stunnel $file1 &] - after 1300 + after 300 + set vtm [vencrypt_tutorial_mesg] + if {$vtm == ""} { + after 1000 + } note_stunnel_pids "after" @@ -7213,11 +8092,11 @@ proc launch {{hp ""}} { wm withdraw . } - do_viewer_windows $n + do_viewer_windows $n1 del_launch_windows_ssh_files - catch {file delete $file} + catch {file delete $file1} if {$debug} { ; @@ -7280,7 +8159,7 @@ proc direct_connect_windows {{hp ""}} { if [regexp {^.*@} $host match] { catch {raise .; update} mesg "Trimming \"$match\" from hostname" - after 1000 + after 700 regsub {^.*@} $host "" host } @@ -7310,7 +8189,7 @@ proc direct_connect_windows {{hp ""}} { bell catch {raise .; update} mesg "WARNING: SSL proxy contains \"@\" sign" - after 2000 + after 1500 } set n2 45 @@ -7336,14 +8215,16 @@ proc direct_connect_windows {{hp ""}} { set proxy_pid "" if {$proxy != ""} { - mesg "Starting TCP helper on port $port ..." - after 600 + mesg "Starting Proxy TCP helper on port $port ..." + after 500 set proxy_pid [exec "connect_br.exe" &] catch { unset env(SSVNC_PROXY) } catch { unset env(SSVNC_LISTEN) } catch { unset env(SSVNC_DEST) } } + vencrypt_tutorial_mesg + catch {destroy .o} catch {destroy .oa} catch {destroy .os} @@ -7550,6 +8431,64 @@ proc set_ultra_dsm_file {{parent "."}} { update } +proc set_ssh_known_hosts_file {{parent "."}} { + global ssh_known_hosts_filename is_windows uname + + if {$ssh_known_hosts_filename == ""} { + set pdir [get_profiles_dir] + set pdir "$pdir/ssh_known_hosts" + catch {file mkdir $pdir} + + global last_load + if {![info exists last_load]} { + set last_load "" + } + if {$last_load != ""} { + set dispf [string trim $last_load] + set dispf [file tail $dispf] + + regsub {\.vnc$} $dispf "" dispf + if {![regexp {\.known$} $dispf]} { + set dispf "$dispf.known" + } + set guess $dispf + } else { + set vncdisp [get_vncdisplay] + set dispf [string trim $vncdisp] + if {$dispf != ""} { + regsub {[ ].*$} $dispf "" dispf + regsub -all {/} $dispf "" dispf + } else { + set dispf "unique-name-here" + } + if {$is_windows || $uname == "Darwin"} { + regsub -all {:} $dispf "-" dispf + } else { + regsub -all {:} $dispf "-" dispf + } + if {![regexp {\.known$} $dispf]} { + set dispf "$dispf.known" + } + set guess $dispf + } + } else { + set pdir [file dirname $ssh_known_hosts_filename] + set guess [file tail $ssh_known_hosts_filename] + } + + set t "" + unix_dialog_resize $parent + if {$pdir != ""} { + set t [tk_getSaveFile -parent $parent -initialdir $pdir -initialfile $guess] + } else { + set t [tk_getSaveFile -parent $parent -initialfile $guess] + } + if {$t != ""} { + set ssh_known_hosts_filename $t + } + update +} + proc show_cert {crt} { if {$crt == ""} { bell @@ -7635,6 +8574,7 @@ proc v_svcert {} { } else { catch {.c.svcert.i configure -state normal} } + no_certs_tutorial_mesg return 1 } @@ -8072,7 +9012,7 @@ proc create_cert {{name ""}} { } set msg { - This dialog helps you to create a simple self-signed SSL certificate. + This dialog helps you to create a simple Self-Signed SSL certificate. On Unix the openssl(1) program must be installed and in $PATH. On Windows, a copy of the openssl program is provided for convenience. @@ -8082,7 +9022,7 @@ proc create_cert {{name ""}} { 1) authenticating yourself (VNC Viewer) to a VNC Server or 2) your verifying the identity of a remote VNC Server. - In either case you will need to safely copy one of the generated + In either case you will need to safely copy one of the generated key or certificate files to the remote VNC Server and have the VNC Server use it. Or you could send it to the system administrator of the VNC Server. @@ -8137,7 +9077,7 @@ proc create_cert {{name ""}} { http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tunnel-int The first one describes how to use x11vnc to create Certificate - Authority (CA) certificates in addition to self-signed ones. + Authority (CA) certificates in addition to Self-Signed ones. Tip: if you choose the "Common Name" to be the internet hostname @@ -8313,9 +9253,26 @@ proc do_save {par} { } set str "" + set subject_issuer "" if {$import_mode == "save_cert_text"} { global save_cert_text set str $save_cert_text + set i 0 + foreach line [split $str "\n"] { + incr i + if {$i > 50} { + break + } + if [regexp {^- subject: *(.*)$} $line m val] { + set subject_issuer "${subject_issuer}subject:$val\n" + } + if [regexp {^- (issuer[0-9][0-9]*): *(.*)$} $line m is val] { + set subject_issuer "${subject_issuer}$is:$val\n" + } + if [regexp {^INFO: SELF_SIGNED=(.*)$} $line m val] { + set subject_issuer "${subject_issuer}SELF_SIGNED:$val\n" + } + } } elseif {$import_mode == "paste"} { set str [$par.paste.t get 1.0 end] } else { @@ -8355,9 +9312,9 @@ proc do_save {par} { set deltmp "" if {$import_save_file == ""} { if {! $is_windows} { - set deltmp /tmp/itmp.[tpid] + set deltmp /tmp/import.[tpid] } else { - set deltmp itmp.[tpid] + set deltmp import.[tpid] } set deltmp [mytmp $deltmp] set import_save_file $deltmp @@ -8396,7 +9353,7 @@ proc do_save {par} { set i 0 foreach line [split $fp_txt "\n"] { incr i - if {$i > 4} { + if {$i > 5} { break } if [regexp -nocase {Fingerprint=(.*)} $line mv str] { @@ -8409,8 +9366,39 @@ proc do_save {par} { regsub -all {:} $fingerprint "-" fingerprint regsub -all {[\\/=]} $fingerprint "_" fingerprint + if {$subject_issuer == ""} { + set si_txt "" + set si_txt [exec $ossl x509 -subject -issuer -noout -in $import_save_file] + set sub "" + set iss "" + foreach line [split $si_txt "\n"] { + if [regexp -nocase {^subject= *(.*)$} $line mv str] { + set str [string trim $str] + set sub $str + } elseif [regexp -nocase {^issuer= *(.*)$} $line mv str] { + set str [string trim $str] + set iss $str + } + } + if {$sub != "" && $iss != ""} { + set subject_issuer "subject:$sub\nissuer1:$iss\n" + if {$sub == $iss} { + set subject_issuer "${subject_issuer}SELF_SIGNED:1\n" + } else { + set subject_issuer "${subject_issuer}SELF_SIGNED:0\n" + } + } + } + global vncdisplay set from [get_ssh_hp $vncdisplay] + if {$from == ""} { + set from [file tail $import_save_file] + regsub {\..*$} $from "" from + } + if {$from == ""} { + set from "import" + } if [regexp -- {^:[0-9][0-9]*$} $from] { set from "listen$from" } @@ -8420,11 +9408,14 @@ proc do_save {par} { regsub -all {^[+a-z]*://} $from "" from regsub -all {:} $from "-" from regsub -all {[\\/=]} $from "_" from + regsub -all {[ ]} $from "_" from set crt "$adir/$from=$fingerprint.crt" catch {file copy -force $import_save_file $crt} - save_hash $crt $adir $hp $fingerline $from $fingerprint + global do_save_saved_hash_it + set do_save_saved_hash_it 1 + save_hash $crt $adir $hp $fingerline $from $fingerprint $subject_issuer } catch {destroy $par} @@ -8538,7 +9529,7 @@ TCQ+tbQ/DOiTXGKx1nlcKoPdkG+QVQVJthlQcpam $w.b configure -state disabled $w.e configure -state disabled - label .icrt.plab -anchor w -text "Paste Certificate here:" + label .icrt.plab -anchor w -text "Paste Certificate here: (extra blank lines above or below are OK)" if {$uname == "Darwin"} { scroll_text .icrt.paste 90 11 } else { @@ -8560,11 +9551,16 @@ TCQ+tbQ/DOiTXGKx1nlcKoPdkG+QVQVJthlQcpam entry $w.e -width 40 -textvariable import_save_file button $w.b -pady 1 -anchor w -text "Browse..." -command import_save_browse + global also_save_to_accepted_certs + set also_save_to_accepted_certs 0 + checkbutton .icrt.ac -anchor w -variable also_save_to_accepted_certs -text \ + "Also Save to the 'Accepted Certs' directory" -relief raised + pack $w.b -side right pack $w.l -side left pack $w.e -side left -expand 1 -fill x - pack .icrt.save .icrt.cancel .icrt.sf .icrt.mf -side bottom -fill x + pack .icrt.save .icrt.cancel .icrt.ac .icrt.sf .icrt.mf -side bottom -fill x pack .icrt.paste .icrt.plab -side bottom -fill x pack .icrt.f -side top -fill both -expand 1 @@ -8578,6 +9574,8 @@ TCQ+tbQ/DOiTXGKx1nlcKoPdkG+QVQVJthlQcpam proc save_cert {hp} { + global cert_text + toplev .scrt wm title .scrt "Import SSL Certificate" @@ -8627,7 +9625,7 @@ proc save_cert {hp} { Click on "Save" to add it to the Accepted Certs. - It, and the others certs in that directory, will be used to authenticate + It, and the other certs in that directory, will be used to authenticate any VNC Server that has "ACCEPTED_CERTS" as the "CertsDir" value in the "Certs..." dialog. This is the default checking policy. } @@ -8662,7 +9660,6 @@ proc save_cert {hp} { button .scrt.save -text "Save" -command {do_save .scrt} } - global cert_text if [regexp -nocase -- {ACCEPT} $cert_text] { if [regexp -nocase -- {Client certificate} $cert_text] { if [regexp -- {^:[0-9][0-9]*$} $hp] { @@ -8962,6 +9959,8 @@ proc load_include {include dir} { if {$fh == ""} { continue } + mesg "Applying template: $inc" + after 100 while {[gets $fh line] > -1} { append inc_str "$line\n" if [regexp {^([^=]*)=(.*)$} $line m var val] { @@ -9141,7 +10140,6 @@ proc load_profile {{parent "."} {infile ""}} { } close $fh - if {$include != ""} { load_include $include $dir } @@ -9219,7 +10217,6 @@ proc load_profile {{parent "."} {infile ""}} { global last_load set last_load [file tail $file] -## regsub {\.vnc$} $last_load "" last_load global uname darwin_cotvnc if {$uname == "Darwin"} { @@ -9262,7 +10259,6 @@ proc save_profile {{parent "."}} { set vncdisp [get_vncdisplay] - set dispf [string trim $vncdisp] if {$dispf != ""} { regsub {[ ].*$} $dispf "" dispf @@ -9301,9 +10297,6 @@ proc save_profile {{parent "."}} { set profdone 1 return } - #if {$file == $last_load && ![regexp {\.vnc$} $file]} { - # set file "$file.vnc" - #} set fh [open $file "w"] if {! [info exists fh]} { set profdone 1 @@ -9365,14 +10358,14 @@ proc save_profile {{parent "."}} { if {$include_list != ""} { load_include $include_list [get_profiles_dir] } + global sshssl_sw if {! $use_ssl && ! $use_ssh && ! $use_sshssl} { - global sshssl_sw if {$sshssl_sw == "none"} { set disable_all_encryption 1 } } - global ts_only + global ts_only ssh_only if {$ts_only} { set ts_mode 1 } else { @@ -9384,6 +10377,9 @@ proc save_profile {{parent "."}} { if {$val == $defs($var)} { set pre "#" } + if {$ssh_only && $var == "use_ssh"} { + set pre "" + } set pct 0 if {$var == "smb_mount_list"} { set pct 1 @@ -9407,6 +10403,11 @@ proc save_profile {{parent "."}} { } close $fh + + mesg "Saved Profile: [file tail $file]" + + set last_load [file tail $file] + set profdone 1 } @@ -12128,7 +13129,7 @@ proc help_advanced_opts {} { to work properly. Please submit bug reports if it appears it should be working for your setup but is not. - Brief descriptions: + Brief (and some not so brief) descriptions: CUPS Print tunnelling: @@ -12174,6 +13175,36 @@ proc help_advanced_opts {} { See the 'X Login' description in 'Terminal Services' Mode Help for more info. + Private SSH KnownHosts file: + + On Unix in SSH mode, let the user specify a non-default + ssh known_hosts file to be used only by the current profile. + This is the UserKnownHostsFile ssh option and is described in the + ssh_config(1) man page. This is useful to avoid proxy 'localhost' + SSH key collisions. + + Normally one should simply let ssh use its default file + ~/.ssh/known_hosts for tracking SSH keys. The only problem that + happens is when multiple SSVNC connections use localhost tunnel + port redirections. These make ssh connect to 'localhost' on some + port (where the proxy is listening.) Then the different keys + from the multiple ssh servers collide when ssh saves them under + 'localhost' in ~/.ssh/known_hosts. + + So if you are using a proxy with SSVNC or doing a "double SSH + gateway" your ssh will connect to a proxy port on localhost, and you + should set a private KnownHosts file for that connection profile. + This is secure and avoids man-in-the-middle attack (as long as + you actually verify the initial save of the SSH key!) + + The default file location will be: + + ~/.vnc/ssh_known_hosts/profile-name.known + + but you can choose any place you like. It must of course be + unique and not shared with another ssh connection otherwise they + both may complain about the key for 'localhost' changing, etc. + SSH Local Port Protections: An LD_PRELOAD hack to limit the number of SSH port redirections @@ -12205,40 +13236,145 @@ proc help_advanced_opts {} { is enabled. Support for secret key encryption to Non-UltraVNC DSM servers is also supported, e.g. x11vnc -enc blowfish:my.key + Do not Probe for VeNCrypt: + + Disable VeNCrypt auto-detection probe when not needed. + + By default in SSL mode an initial probe for the use of the + VeNCrypt or ANONTLS protocol is performed. This is done + during the initial fetch-cert action. Once auto-detected in + the initial probe, the real connection to the VNC Server will + use this information to switch to SSL/TLS at the right point in + the VeNCrypt/ANONTLS handshake. + + In "Verify All Certs" mode initial the fetch-cert action is + required so the automatic probing for VeNCrypt is always done. + The fetch-cert is not needed if you specified a ServerCert or if + you disabled "Verify All Certs". But by default the fetch-cert + is done anyway to try to auto-detect VeNCrypt/ANONTLS. + + Set 'Do not Probe for VeNCrypt' to skip this unneeded fetch-cert + action (and hence speed up connecting.) Use this if you + know the VNC Server uses normal SSL and not VeNCrypt/ANONTLS. + + See also the next option, 'Server uses VeNCrypt SSL encryption' + to if you know it uses VeNCrypt/ANONTLS (the probing will also + be skipped if that option is set.) + Server uses VeNCrypt SSL encryption: - Use the VeNCrypt extension to VNC that switches to an SSL/TLS - tunnel at a certain point in the VNC Handshake. This is in - constrast to the default ssvnc/x11vnc SSL tunnel mode where - the entire VNC session goes through SSL (e.g. vncs://) + Indicate that the VNC server uses the VeNCrypt extension to VNC; + it switches to an SSL/TLS tunnel at a certain point in the + VNC Handshake. This is in constrast to the default ssvnc/x11vnc + SSL tunnel behavior where the *entire* VNC traffic goes through + SSL (i.e. it is vncs:// in the way https:// uses SSL) Enable this option if you know the server supports VeNCrypt. - (SSVNC may also be able to autodetect it and switch). Also use - this option for the older ANONTLS extension (vino). + Also use this option for the older ANONTLS extension (vino). + Doing so will give the quickest and most reliable connection + to VeNCrypt/ANONTLS servers. If set, any probing to try to + auto-detect VeNCrypt/ANONTLS will be skipped. + + Some VNC servers supporting VeNCrypt: VeNCrypt, QEMU, ggi, + virt-manager, and Xen. Vino supports ANONTLS. + + The SSVNC VeNCrypt/ANONTLS support even works with 3rd party + VNC Viewers you specify via 'Change VNC Viewer' (e.g. RealVNC, + TightVNC, UltraVNC etc.) that do not directly support it. Note: many VeNCrypt servers only support Anonymous Diffie Hellman - TLS which has no built in authentication (see next section) + TLS which has NO built in authentication and you will also need + to set the option described in the next section. + + If you are using VeNCrypt or ANONTLS for REVERSE connections + (Listen) then you *MUST* set this 'Server uses VeNCrypt SSL + encryption' option. Note also that REVERSE connections using + VeNCrypt/ANONTLS currently do not work on Windows. + + Also, if you are using the "Use SSH+SSL" double tunnel to a + VeNCrypt/ANONTLS server, you MUST set 'Server uses VeNCrypt + SSL encryption' because "Verify All Certs" is disabled in + SSH+SSL mode. Server uses Anonymous Diffie-Hellman Anonymous Diffie-Hellman can be used for SSL/TLS connections but - there are no Certificates for authentication. Therefore - only passive eavesdropping attacks are prevented, not - Man-In-The-Middle attacks. Not recommended; use verified X509 - certs instead. - - Enable this option if you know the server supports Anon DH. - (SSVNC may also be able to detect it and prompt you whether it - should continue). + there are no Certificates for authentication. Therefore only + passive eavesdropping attacks are prevented, not Man-In-The-Middle + attacks. Not recommended; try to use verified X509 certs instead. + + Enable this option if you know the server only supports Anon DH. + When you do so, remember that ALL Certificate checking will be + skipped (even if you have 'Verify All Certs' selected or set + a ServerCert.) + + SSVNC may be able to autodetect Anon DH even if you haven't + selected 'Server uses Anonymous Diffie-Hellman'. Once detected, it + will prompt you whether it should continue. Set the 'Server uses + Anonymous Diffie-Hellman' option to avoid trying autodetection + (i.e. forcing the issue.) + + Note that most Anonymous Diffie-Hellman VNC Servers do so + via the VeNCrypt or ANONTLS VNC extensions (see the previous + section.) For these servers if you select 'Server uses Anonymous + Diffie-Hellman' you *MUST* ALSO select 'Server uses VeNCrypt SSL + encryption', otherwise SSVNC may have no chance to auto-detect + the VeNCrypt/ANONTLS protocol. + + Also note, if you are using the "Use SSH+SSL" double tunnel to + a VeNCrypt/ANONTLS server using Anon DH you MUST set 'Server + uses Anonymous Diffie-Hellman' because "Verify All Certs" + is disabled in SSH+SSL mode. Include: - Profile template(s) to load before loading a profile (Load - button). For example if you Save a profile called "globals" - that has some settings you use often, then just supply "Include: - globals" to have them applied. You may supply a comma or space - separated list of templates to include. They can be full - path names or basenames relative to the profiles directory. + Default settings and Include Templates: + + Before explaining how Include works, first note that if you + do not prefer some of SSVNC's default settings you can start + up SSVNC and then change the settings for the options that you + want to have a different default value. Then type "defaults" + in VNC Host:Display entry box and press "Save" to save them in + the "defaults.vnc" profile. After this, SSVNC will initialize + all of the default values and then apply your override values + in "defaults". + + For example, suppose you always want to use a different, 3rd + party VNC Viewer. Set Options -> Advanced -> Change VNC Viewer + to what you want, and then save it as the "defaults" profile. + Now that default setting will apply to all profiles, and SSVNC + in its startup state. + + To edit the defaults Load it, make changes, and then Save it. + Delete the "defaults" profile to go back to no modifications. + Note that defaults created and saved while defaults.vnc existed + will NOT be automatically adjusted. + + Include Templates: + + Now suppose you have a certain class of settings that you do + not want to always be applied, but you want them to apply to a + group of profiles. + + For example, suppose you have some settings for very low + bandwidth connections (e.g. low color modes and/or aggressive + compression and quality settings.) Set these values in SSVNC + and then in the VNC Host:Display entry box type in, say, + "slowlink" and then press Save. This will save those settings + in the template profile named "slowlink.vnc". + + Now to create a real profile that uses this template type the + host:disp in "VNC Host:Display" and in Options -> Advanced + -> Includes type in "slowlink". Then press Save to save the + host profile. Then re-Load it. The "slowlink" settings will + be applied after the defaults. Make any other changes to the + setting for this profile and Save it again. Next time you load + it in, the Include template settings will override the defaults + and then the profile itself is read in. + + You may supply a comma or space separated list of templates + to include. They are applied in the order listed. They can be + full path names or basenames relative to the profiles directory. You do not need to supply the .vnc suffix. The non-default settings in them will be applied first, and then any values in the loaded Profile will override them. @@ -12332,6 +13468,25 @@ proc help_ssvncviewer_opts {} { of assuming there is a local tunnel, SSL or SSH, going to the remote machine. + Avoid Using Terminal: + + By default the Unix ssvncviewer will prompt for usernames, + passwords, etc. in the terminal it is running inside of. + Set this option to use windows for messages and prompting as + much as possible. Messages will also go to the terminal, but + all prompts will be done via popup window. + + Note that stunnel(1) may prompt for a passphrase to unlock a + private SSL key. This is fairly rare because it is usually + for Client-side SSL authentication. stunnel will prompt from + the terminal; there seems to be no way around this. + + Also, note that ssh(1) may prompt for an ssh key passphrase + or Unix password. This can be avoided in a number of ways, + the simplest one is to use ssh-agent(1) and ssh-add(1). + However ssh(1) may also prompt you to accept a new public key + for a host or warn you if the key has changed, etc. + Use Popup Fix: Enable a fix that warps the popup (F8) to the mouse pointer. @@ -12350,7 +13505,7 @@ proc help_ssvncviewer_opts {} { TurboVNC: If available on your platform, use a ssvncviewer compiled with - TurboVNC support. This is based on the the VirtualGL project: + TurboVNC support. This is based on the VirtualGL project: http://www.sourceforge.net/projects/virtualgl You will need to install the VirtualGL's TurboJPEG library too. @@ -12359,7 +13514,7 @@ proc help_ssvncviewer_opts {} { ssvnc bundles. See the build instructions for how you might compile your own. - Disable Pipeline Updates: + Disable Pipelined Updates: Disable the TurboVNC-like pipelined updates mode. Pipelined updates is the default even when not TurboVNC enabled. They @@ -12456,6 +13611,7 @@ proc help_ssvncviewer_opts {} { VNCVIEWER_NOBELL (-nobell) VNCVIEWER_X11CURSOR (-x11cursor, see Use X11 Cursor above) VNCVIEWER_RAWLOCAL (-rawlocal, see Use Raw Local above) + VNCVIEWER_NOTTY (-notty, see Avoid Using Terminal above) VNCVIEWER_ESCAPE (-escape, see Escape Keys above) VNCVIEWER_ULTRADSM (-ultradsm) VNCVIEWER_SEND_CLIPBOARD (-sendclipboard) @@ -12478,17 +13634,22 @@ proc help_ssvncviewer_opts {} { SSVNC_NOSOLID (do not do solid region speedup in scaling mode.) SSVNC_PRESERVE_ENCODING (do not switch to ZRLE when scaling) + SSVNC_FINISH_SLEEP (on unix/macosx sleep this many seconds + before exiting the terminal, default 5) - Misc (special usage or debugging): + Misc (special usage or debugging or ss_vncviewer settings): - SSVNC_NO_ULTRA_DSM - SSVNC_ULTRA_FTP_JAR + SSVNC_MESG_DELAY (sleep this many millisec between messages) + SSVNC_EXTRA_SLEEP (same as Sleep: window) + SSVNC_NO_ULTRA_DSM (disable ultravnc dsm encryption) + SSVNC_ULTRA_FTP_JAR (file location of ultraftp.jar jar file) + SSVNC_KNOWN_HOSTS_FILE (file for per-connection ssh known hosts) SSVNC_SCALE_STATS SSVNC_DEBUG_RELEASE SSVNC_DEBUG_ESCAPE_KEYS SSVNC_NO_MAYBE_SYNC - SSVNC_MAX_LISTEN - SSVNC_LISTEN_ONCE + SSVNC_MAX_LISTEN (number of time to listen for reverse conn.) + SSVNC_LISTEN_ONCE (listen for reverse conn. only once) SSVNC_EXIT_DEBUG SSVNC_DEBUG_CHAT SSVNC_NO_MESSAGE_POPUP @@ -12506,7 +13667,6 @@ proc help_ssvncviewer_opts {} { SSVNC_STUNNEL_DEBUG SSVNC_TEST_SEC_TYPE SSVNC_LIM_ACCEPT_PRELOAD - SSVNC_EXTRA_SLEEP SSVNC_SOCKS5 } @@ -12840,9 +14000,16 @@ proc update_no_ultra_dsm {} { ; } elseif {$ultra_dsm_type == "msrc4_sc"} { ; + } elseif {$ultra_dsm_type == "securevnc"} { + ; } else { set ultra_dsm_type guess } + catch {.ultradsm.key.securevnc configure -state normal} + catch {.ultradsm.key.msrc4_sc configure -state normal} + } else { + catch {.ultradsm.key.securevnc configure -state disabled} + catch {.ultradsm.key.msrc4_sc configure -state disabled} } } @@ -12853,32 +14020,35 @@ proc ultra_dsm_dialog {} { wm title .ultradsm "UltraVNC DSM Encryption Plugin" global help_font - scroll_text .ultradsm.f 85 35 + scroll_text .ultradsm.f 85 40 set msg { - On Unix with the provided SSVNC vncviewer, you can connect to an UltraVNC - server that is using one of its DSM encryption plugins: MSRC4, ARC4, AESV2. - More info at: http://www.uvnc.com/features/encryption.html + On Unix and MacOSX with the provided SSVNC vncviewer, you can connect to an + UltraVNC server that is using one of its DSM encryption plugins: MSRC4, ARC4, + AESV2, and SecureVNC. More info at: http://www.uvnc.com/features/encryption.html - IMPORTANT: The UltraVNC DSM implementation contains unfixed errors - that could allow an eavesdropper to recover the session key or traffic - relatively easily. They often do not provide strong encryption, but + IMPORTANT: The UltraVNC DSM MSRC4, ARC4, and AESV2 implementations contain + unfixed errors that could allow an eavesdropper to recover the session + key or traffic easily. They often do not provide strong encryption, but only provide basic obscurity instead. Do not use them with critical data. + The newer SecureVNC Plugin does not suffer from these problems. See the bottom of this help text for how to use symmetric encryption with - Non-UltraVNC servers (for example, x11vnc 0.9.5 or later). This mode does - not suffer the shortcomings of the UltraVNC DSM implementation. + Non-UltraVNC servers (for example, x11vnc 0.9.5 or later). This mode does not + suffer the shortcomings of the UltraVNC MSRC4, ARC4, and AESV2 implementations. You will need to specify the corresponding UltraVNC encryption key (created by you using an UltraVNC server or viewer). It is usually called 'rc4.key' - (for MSRC4), 'arc4.key' (for ARC4), and 'aesv2.key' (for AESV2). Specify - the path to it or Browse for it. Also, specify which type of plugin it is - (or use 'guess' to have it guess via the before mentioned filenames). + (for MSRC4), 'arc4.key' (for ARC4), and 'aesv2.key' (for AESV2). Specify the + path to it or Browse for it. Also, specify which type of plugin it is (or use + 'guess' to have it guess via the before mentioned filenames). - The choice "UVNC SC" enables a special workaround for use with UltraVNC - Single Click and the MSRC4 plugin. It may not be needed on recent SC. + The choice "UVNC SC" enables a special workaround for use with UltraVNC Single + Click and the MSRC4 plugin. It may not be needed on recent SC (e.g. from + ~2009 and later; select "MSRC4" for these newer ones.) - You can also specify pw=my-password instead of a keyfile. + You can also specify pw=my-password instead of a keyfile. Use single quotes + pw='....' if the password contains shell meta-characters `!$&*(){}[]|;<>? Use the literal string 'pw=VNCPASSWD' to have the VNC password that you entered into the 'VNC Password:' be used for the pw=... @@ -12887,26 +14057,61 @@ proc ultra_dsm_dialog {} { Proxying works in this mode, as well as Reverse Connections (Listen) - This encryption mode is currently experimental because unfortunately - the UltraVNC DSM plugin also modifies the RFB protocol, and so the SSVNC - vncviewer had to be modified to support it. The tight and zlib encodings - currently do not work in this mode and are disabled. + The choice "SecureVNC" refers to the SecureVNC Plugin using 128 bit AES or + ARC4 with 2048 bit RSA key exchange described here: + + http://adamwalling.com/SecureVNC + + Note in its default mode SecureVNC is *Vulnerable* to Man-In-The-Middle attacks + (encryption but no server authentication) so do not use it with critical data. + In SecureVNC mode you do not need to supply a 'Ultra DSM Keyfile'. However, + if you DO supply a keyfile filename (recommended) if that file does not exist + you will be prompted if you want to save the UltraVNC server's RSA key in it. + The key's MD5 checksum is displayed so that you can verify that the key is + trusted. One way to print out the SecureVNC public key MD5 checksum is: + + openssl rsa -inform DER -outform DER -pubout -in ./Server_SecureVNC.pkey | dd bs=1 skip=24 | md5sum + + Then on subsequent connections, if you continue to specify this filename, the + SecureVNCPlugin server's RSA key will be checked against the file's contents + and if they differ the connection will be dropped. + + NOTE, However, if the SecureVNC keyfile ends in the string 'ClientAuth.pkey' + then its contents are used for SecureVNC's normal Client Authentication dialog + (you need to use Windows SecureVNCPlugin to generate this file on the server + side, it is usually called "Viewer_ClientAuth.pkey", and then safely copy it + to the viewer side.) If you want to do BOTH Client Auth and server RSA key + storing (recommended), have the keyfile end in 'ClientAuth.pkey.rsa'; that way + the file will be used for storing the server RSA key and then the '.rsa' is + trimmed off and the remainder used for the SecureVNC Client Auth data filename. + + Note that despite its intentions, Client Authentication in the FIRST release of + SecureVNC is still susceptible to Man-In-The-Middle attacks. Even when that + is fixed, SecureVNC Client Authentication is still susceptible to "spoofing" + attacks where the viewer user may be tricked into revealing his VNC or MS-Logon + password if his connection is intercepted. It is recommended you verify and + save the Server key (see above) in addition to using Client Authentication. + + UltraVNC DSM encryption modes are currently experimental because unfortunately + the UltraVNC DSM plugin also modifies the RFB protocol(!), and so the SSVNC + vncviewer had to be modified to support it. The tight, zlib, and some minor + encodings currently do not work in this mode and are disabled. Note that this mode also requires the utility tool named 'ultravnc_dsm_helper' that should be included in your SSVNC kit. - Select 'Non-Ultra DSM' to use symmetric encryption to a Non-UltraVNC server - via a supported symmetric key cipher. x11vnc supports symmetric encryption - via, e.g., "x11vnc -enc aesv2:./my.key". Extra ciphers are enabled for - this mode (e.g. blowfish and 3des). + Select 'Non-Ultra DSM' to use symmetric encryption to a Non-UltraVNC server via + a supported symmetric key cipher. x11vnc supports symmetric encryption via, + e.g., "x11vnc -enc aesv2:./my.key". Extra ciphers are enabled for this mode + (e.g. blowfish and 3des). 'UVNC SC' and SecureVNC do not apply in this mode. Note for the Non-Ultra DSM case it will also work with any VNC Viewer (i.e. selected by Options -> Advanced -> Change VNC Viewer) not only the supplied SSVNC vncviewer. - You can also set the random salt size and initialization vector size in - Salt,IV for example "8,16". See the x11vnc and 'ultravnc_dsm_helper -help' - documentation for more info on this. + For experts: You can also set the random salt size and initialization vector + size in Salt,IV for example "8,16". See the x11vnc and 'ultravnc_dsm_helper + -help' documentation for more info on this. } .ultradsm.f.t insert end $msg @@ -12936,12 +14141,16 @@ proc ultra_dsm_dialog {} { radiobutton .ultradsm.key.msrc4_sc -pady 1 -anchor w -variable ultra_dsm_type -value msrc4_sc \ -text "UVNC SC" + radiobutton .ultradsm.key.securevnc -pady 1 -anchor w -variable ultra_dsm_type -value securevnc \ + -text "SecureVNC" + pack .ultradsm.key.l -side left pack .ultradsm.key.guess -side left pack .ultradsm.key.arc4 -side left pack .ultradsm.key.aesv2 -side left pack .ultradsm.key.msrc4 -side left pack .ultradsm.key.msrc4_sc -side left + pack .ultradsm.key.securevnc -side left frame .ultradsm.nou checkbutton .ultradsm.nou.cb -text "Non-Ultra DSM" -variable ultra_dsm_noultra -command update_no_ultra_dsm @@ -12984,6 +14193,72 @@ proc ultra_dsm_dialog {} { focus .ultradsm.path.e } +proc ssh_known_hosts_dialog {} { + global ssh_known_hosts ssh_known_hosts_filename + + toplev .sshknownhosts + wm title .sshknownhosts "Private SSH KnownHosts file" + + global help_font + scroll_text .sshknownhosts.f 80 31 + + set msg { + Private SSH KnownHosts file: + + On Unix in SSH mode, let the user specify a non-default + ssh known_hosts file to be used only by the current profile. + This is the UserKnownHostsFile ssh option and is described in the + ssh_config(1) man page. This is useful to avoid proxy 'localhost' + SSH key collisions. + + Normally one should simply let ssh use its default file + ~/.ssh/known_hosts for tracking SSH keys. The only problem with + that happens when multiple SSVNC connections use localhost tunnel + port redirections. These make ssh connect to 'localhost' on some + port (where the proxy is listening.) Then the different keys + from the multiple ssh servers collide when ssh saves them under + 'localhost' in ~/.ssh/known_hosts. + + So if you are using a proxy with SSVNC or doing a "double SSH + gateway" your ssh will connect to a proxy port on localhost, and you + should set a private KnownHosts file for that connection profile. + This is secure and avoids man-in-the-middle attack (as long as + you actually verify the initial save of the SSH key!) + + The default file location will be: + + ~/.vnc/ssh_known_hosts/profile-name.known + + but you can choose any place you like. It must of course be + unique and not shared with another ssh connection otherwise they + both may complain about the key for 'localhost' changing, etc. +} + + .sshknownhosts.f.t insert end $msg + + frame .sshknownhosts.path + label .sshknownhosts.path.l -text "SSH KnownHosts file:" + entry .sshknownhosts.path.e -width 40 -textvariable ssh_known_hosts_filename + button .sshknownhosts.path.b -text "Browse..." -command {set_ssh_known_hosts_file .sshknownhosts} + + pack .sshknownhosts.path.l -side left + pack .sshknownhosts.path.e -side left -expand 1 -fill x + pack .sshknownhosts.path.b -side left + + button .sshknownhosts.cancel -text "Cancel" -command {destroy .sshknownhosts; set ssh_known_hosts 0} + bind .sshknownhosts {destroy .sshknownhosts; set ssh_known_hosts 0} + wm protocol .sshknownhosts WM_DELETE_WINDOW {destroy .sshknownhosts; set ssh_known_hosts 0} + button .sshknownhosts.done -text "Done" -command {destroy .sshknownhosts; catch {raise .oa}} + bind .sshknownhosts.path.e {destroy .sshknownhosts; catch {raise .oa}} + + pack .sshknownhosts.f .sshknownhosts.path .sshknownhosts.cancel .sshknownhosts.done -side top -fill x + + center_win .sshknownhosts + wm resizable .sshknownhosts 1 0 + + focus .sshknownhosts.path.e +} + proc ssh_sec_dialog {} { global ssh_local_protection @@ -14035,6 +15310,12 @@ proc set_ts_adv_options {} { if {$is_windows} {.ot2.b$i configure -state disabled} incr i + checkbutton .ot2.b$i -anchor w -variable ssh_known_hosts -text \ + "SSH KnownHosts file" \ + -command {if {$ssh_known_hosts} {ssh_known_hosts_dialog}} + if {$is_windows} {.ot2.b$i configure -state disabled} + incr i + global env if {![info exists env(SSVNC_TS_ALWAYS)]} { button .ot2.b$i -anchor w -text " SSVNC Mode" \ @@ -14146,6 +15427,14 @@ proc set_advanced_options {} { global use_ssl use_ssh use_sshssl + checkbutton .oa.b$i -anchor w -variable ssh_known_hosts -text \ + "Private SSH KnownHosts file" \ + -command {if {$ssh_known_hosts} {ssh_known_hosts_dialog}} + set adv_ssh(knownhosts) .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 ssh_local_protection -text \ "SSH Local Port Protections" \ -command {if {$ssh_local_protection} {ssh_sec_dialog}} @@ -14155,6 +15444,8 @@ proc set_advanced_options {} { if {$is_windows} {.oa.b$i configure -state disabled} incr i + global ssh_only + if {!$ssh_only} { checkbutton .oa.b$i -anchor w -variable stunnel_local_protection -text \ "STUNNEL Local Port Protections" \ -command {if {$stunnel_local_protection} {stunnel_sec_dialog}} @@ -14181,20 +15472,27 @@ proc set_advanced_options {} { if {$use_ssh} {.oa.b$i configure -state disabled} incr i + checkbutton .oa.b$i -anchor w -variable no_probe_vencrypt -text \ + "Do not Probe for VeNCrypt" + global no_probe_vencrypt_button + set no_probe_vencrypt_button .oa.b$i + if {$use_ssh} {.oa.b$i configure -state disabled} + incr i + checkbutton .oa.b$i -anchor w -variable server_vencrypt -text \ "Server uses VeNCrypt SSL encryption" global vencrypt_button set vencrypt_button .oa.b$i - if {$is_windows} {.oa.b$i configure -state disabled} if {$use_ssh} {.oa.b$i configure -state disabled} incr i checkbutton .oa.b$i -anchor w -variable server_anondh -text \ - "Server uses Anonymous Diffie-Hellman" + "Server uses Anonymous Diffie-Hellman" -command no_certs_tutorial_mesg global anondh_button set anondh_button .oa.b$i if {$use_ssh} {.oa.b$i configure -state disabled} incr i + } checkbutton .oa.b$i -anchor w -variable change_vncviewer -text \ "Change VNC Viewer" \ @@ -14206,27 +15504,26 @@ proc set_advanced_options {} { -command {if {$use_port_knocking} {port_knocking_dialog}} incr i - global include_list - frame .oa.b$i - label .oa.b$i.l -text "Include:" - entry .oa.b$i.e -width 10 -textvariable include_list - pack .oa.b$i.l -side left - pack .oa.b$i.e -side right -expand 1 -fill x + for {set j 1} {$j < $i} {incr j} { + pack .oa.b$j -side top -fill x + } - incr i + global include_list extra_sleep + frame .oa.fis + frame .oa.fis.fL + frame .oa.fis.fR + label .oa.fis.fL.la -anchor w -text "Include:" + label .oa.fis.fL.lb -anchor w -text "Sleep:" + pack .oa.fis.fL.la .oa.fis.fL.lb -side top -fill x - global extra_sleep - frame .oa.b$i - label .oa.b$i.l -text "Sleep: " - entry .oa.b$i.e -width 10 -textvariable extra_sleep - pack .oa.b$i.l -side left - pack .oa.b$i.e -side right -expand 1 -fill x + entry .oa.fis.fR.ea -width 10 -textvariable include_list + entry .oa.fis.fR.eb -width 10 -textvariable extra_sleep + pack .oa.fis.fR.ea .oa.fis.fR.eb -side top -fill x - incr i + pack .oa.fis.fL -side left + pack .oa.fis.fR -side right -expand 1 -fill x - for {set j 1} {$j < $i} {incr j} { - pack .oa.b$j -side top -fill x - } + pack .oa.fis -side top -fill x global uname set t1 " Unix ssvncviewer ..." @@ -14274,7 +15571,7 @@ proc set_advanced_options {} { proc set_ssvncviewer_options {} { global is_windows darwin_cotvnc - global use_ssh use_sshssl use_x11cursor use_rawlocal use_popupfix use_alpha use_turbovnc disable_pipeline use_grab use_nobell + global use_ssh use_sshssl use_x11cursor use_rawlocal use_notty use_popupfix use_alpha use_turbovnc disable_pipeline use_grab use_nobell global use_send_clipboard use_send_always global ssvnc_scale ssvnc_escape global server_vencrypt server_anondh @@ -14351,6 +15648,11 @@ proc set_ssvncviewer_options {} { lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled} incr i + checkbutton $fl.b$i -anchor w -variable use_notty -text \ + "Avoid Using Terminal" + lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled} + incr i + checkbutton $fl.b$i -anchor w -variable use_popupfix -text \ "Use Popup Fix" lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled} @@ -14682,7 +15984,7 @@ proc putty_pw_entry {mode} { } proc adv_ssh_tog {on} { global adv_ssh - foreach b {cups snd smb redirs} { + foreach b {cups snd smb redirs knownhosts} { if [info exists adv_ssh($b)] { if {$on} { catch {$adv_ssh($b) configure -state normal} @@ -14696,7 +15998,7 @@ proc adv_ssh_tog {on} { proc adv_listen_ssl_tog {on} { global stunnel_local_protection_button is_windows global disable_ssl_workarounds_button - global vencrypt_button anondh_button ultra_dsm_button + global vencrypt_button no_probe_vencrypt_button anondh_button ultra_dsm_button set blist [list] if [info exists stunnel_local_protection_button] { @@ -14708,6 +16010,9 @@ proc adv_listen_ssl_tog {on} { if [info exists ultra_dsm_button] { lappend blist $ultra_dsm_button } + if [info exists no_probe_vencrypt_button] { + lappend blist $no_probe_vencrypt_button + } if [info exists vencrypt_button] { lappend blist $vencrypt_button } @@ -14725,7 +16030,6 @@ proc adv_listen_ssl_tog {on} { if {$is_windows} { catch {$stunnel_local_protection_button configure -state disabled} catch {$ultra_dsm_button configure -state disabled} - catch {$vencrypt_button configure -state disabled} } } @@ -15020,7 +16324,7 @@ proc set_options {} { } checkbutton .o.b$i -anchor w -variable use_listen -text \ - "Reverse VNC Connection (-LISTEN)" -command {listen_adjust; if {$vncdisplay == ""} {set vncdisplay ":0"} else {set vncdisplay ""}; if {$use_listen} {destroy .o}} + "Reverse VNC Connection (-LISTEN)" -command {listen_adjust; if {$vncdisplay == ""} {set vncdisplay ":0"} else {set vncdisplay ""}; if {0 && $use_listen} {destroy .o}} #if {$is_windows} {.o.b$i configure -state disabled} #if {$darwin_cotvnc} {.o.b$i configure -state disabled} #set darwin_cotvnc_blist(.o.b$i) 1 @@ -15130,12 +16434,15 @@ proc set_options {} { global started_with_noenc - if {$started_with_noenc && $showing_no_encryption} { + if {0 && $started_with_noenc && $showing_no_encryption} { + ; + } elseif {$ssh_only} { ; } else { checkbutton .o.b$i -anchor w -variable showing_no_encryption -text \ - "Show 'No Encryption' Option" -relief raised -pady 5 \ + "Show 'No Encryption' Option" -pady 5 \ -command {toggle_no_encryption 1} + # -relief raised incr i } @@ -15155,17 +16462,26 @@ proc set_options {} { } if {$is_windows} { - frame .o.pw - label .o.pw.l -text "Putty PW:" - entry .o.pw.e -width 10 -show * -textvariable putty_pw - pack .o.pw.l -side left - pack .o.pw.e -side left -expand 1 -fill x - pack .o.pw -side top -fill x - putty_pw_entry check - } + global port_slot putty_pw + + frame .o.pp + frame .o.pp.fL + frame .o.pp.fR + label .o.pp.fL.la -anchor w -text "Putty PW:" + label .o.pp.fL.lb -anchor w -text "Port Slot:" + pack .o.pp.fL.la .o.pp.fL.lb -side top -fill x + + entry .o.pp.fR.ea -width 10 -show * -textvariable putty_pw + entry .o.pp.fR.eb -width 10 -textvariable port_slot + pack .o.pp.fR.ea .o.pp.fR.eb -side top -fill x -# button .o.s_prof -text "Save Profile ..." -command {save_profile .o; raise .o} -# button .o.l_prof -text " Load Profile ..." -command {load_profile .o; raise .o} + pack .o.pp.fL -side left + pack .o.pp.fR -side right -expand 1 -fill x + + pack .o.pp -side top -fill x + + putty_pw_entry check + } global uname set t1 " Advanced ..." @@ -15407,6 +16723,11 @@ proc print_help {} { puts "${b}UltraVNC DSM Encryption Plugin Dialog:\n$str" destroy .ultradsm + ssh_known_hosts_dialog + set str [.sshknownhosts.f.t get 1.0 end] + puts "${b}Private SSH KnownHosts file Dialog:\n$str" + destroy .sshknownhosts + ssh_sec_dialog set str [.sshsec.t get 1.0 end] puts "${b}SSH Local Port Protections Dialog:\n$str" @@ -15421,7 +16742,6 @@ proc print_help {} { set str [.usegrb.t get 1.0 end] puts "${b}Use XGrabServer (for fullscreen) Dialog:\n$str" destroy .usegrb - } proc zeroconf_fill {b m} { @@ -15772,6 +17092,8 @@ if {$tcl_platform(platform) == "unix"} { } } } + catch {option add *Dialog.msg.font {helvetica -14 bold}} + catch {option add *Dialog.msg.wrapLength 4i} } if {$uname == "Darwin"} { @@ -15881,7 +17203,20 @@ global kill_stunnel set kill_stunnel 1 global started_with_noenc -set started_with_noenc 0 + +if {! [info exists env(SSVNC_DISABLE_ENCRYPTION_BUTTON)]} { + set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 1 + set started_with_noenc 1 +} else { + if {$env(SSVNC_DISABLE_ENCRYPTION_BUTTON) == "0"} { + set started_with_noenc 0 + } elseif {$env(SSVNC_DISABLE_ENCRYPTION_BUTTON) == "1"} { + set started_with_noenc 1 + } else { + set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 1 + set started_with_noenc 1 + } +} if [file exists $ssvncrc] { set fh "" @@ -15921,6 +17256,7 @@ if [file exists $ssvncrc] { if [regexp {^font_default=(.*)$} $str m val] { set val [string trim $val] catch {option add *font $val} + catch {option add *Dialog.msg.font $val} } if [regexp {^font_fixed=(.*)$} $str m val] { set val [string trim $val] @@ -15931,6 +17267,11 @@ if [file exists $ssvncrc] { set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 1 set started_with_noenc 1 } + if [regexp {^noenc=0} $str] { + global env + set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 0 + set started_with_noenc 0 + } if [regexp {^cotvnc=1} $str] { global env set env(SSVNC_COTVNC) 1 @@ -15965,6 +17306,10 @@ if [file exists $ssvncrc] { set val [string trim $val] set crlfil_default $val } + if [regexp {^env=([^=]*)=(.*)$} $str m var val] { + global env + set env($var) $val + } } close $fh } @@ -16064,6 +17409,7 @@ if [info exists env(SSVNC_FONT_FIXED)] { if [info exists env(SSVNC_FONT_DEFAULT)] { catch {option add *font $env(SSVNC_FONT_DEFAULT)} + catch {option add *Dialog.msg.font $env(SSVNC_FONT_DEFAULT)} } if [regexp {[ ]} $ffont] { @@ -16273,7 +17619,7 @@ radiobutton .f4.sshssl -anchor w -variable sshssl_sw -value sshssl -command {ssl pack .f4.ssl .f4.ssh .f4.sshssl -side left -fill x set showing_no_encryption 0 -radiobutton .f4.none -anchor w -variable sshssl_sw -value none -command {ssl_ssh_adjust none} -text "None " +radiobutton .f4.none -anchor w -variable sshssl_sw -value none -command {ssl_ssh_adjust none} -text "None " if [disable_encryption] { pack .f4.none -side left set showing_no_encryption 1 @@ -16292,8 +17638,12 @@ if {[info exists env(SSVNC_NO_VERIFY_ALL)]} { set always_verify_ssl 0; } -button .f4.getcert -command {fetch_cert 1} -text "Fetch Cert" -checkbutton .f4.always -variable always_verify_ssl -text "Verify All Certs" +if {$uname == "Darwin"} { + button .f4.getcert -command {fetch_cert 1} -text "Fetch Cert" +} else { + button .f4.getcert -command {fetch_cert 1} -text "Fetch Cert" -padx 3 +} +checkbutton .f4.always -variable always_verify_ssl -text "Verify All Certs" -command no_certs_tutorial_mesg pack .f4.getcert -side right -fill x if {[info exists env(SSVNC_NO_VERIFY_ALL_BUTTON)]} { set always_verify_ssl 0; diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1 b/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1 index 78575ef..12e7bca 100644 --- a/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1 +++ b/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1 @@ -119,13 +119,13 @@ authentication. 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. +thus be enclosed in quotes if more than one is specified. Commas may be used to avoid spaces. +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 @@ -312,6 +312,11 @@ Disable bell. Prefer raw encoding for localhost, default is no, i.e. assumes you have a SSH tunnel instead. .TP +\fB\-notty\fR +Try to avoid using the terminal for interactive +responses: use windows for messages and prompting +instead. Messages will also be printed to terminal. +.TP \fB\-sendclipboard\fR Send the X CLIPBOARD selection (i.e. Ctrl+C, Ctrl+V) instead of the X PRIMARY selection (mouse @@ -530,7 +535,8 @@ Meta_R Super_L Super_R Hyper_L Hyper_R or Mode_switch. Cursor Shape: ~ -nocursorshape X11 Cursor: ~ -x11cursor Cursor Alphablend: ~ -alpha - Toggle Tight/ZRLE: ~ -encodings ... + Toggle Tight/Hextile: ~ -encodings hextile... + Toggle Tight/ZRLE: ~ -encodings zrle... Toggle ZRLE/ZYWRLE: ~ -encodings zywrle... Quality Level ~ -quality (both Tight and ZYWRLE) Compress Level ~ -compresslevel diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle index fc9b3e8..d04ae89 100755 --- a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle +++ b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle @@ -1,7 +1,7 @@ #!/bin/sh rm -rf ./src/tmp/* || exit 1 -vers=1.0.24 +vers=1.0.25 cd .. || exit 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 038cd23..ea9c6fd 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 @@ -664,7 +664,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/Vncviewer vnc_unixsrc/vncview + 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 2009-10-03 12:27:50.000000000 -0400 ++++ vnc_unixsrc/vncviewer/argsresources.c 2009-10-26 23:26:12.000000000 -0400 @@ -31,9 +31,9 @@ char *fallback_resources[] = { @@ -739,12 +739,18 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v : SendRFBEvent()\\n\ : SendRFBEvent()\\n\ : SendRFBEvent()\\n\ -@@ -58,23 +110,123 @@ +@@ -55,26 +107,129 @@ + + "*serverDialog.dialog.label: VNC server:", + "*serverDialog.dialog.value:", ++ "*serverDialog.dialog.value.width: 150", "*serverDialog.dialog.value.translations: #override\\n\ Return: ServerDialogDone()", -+ "*userDialog.dialog.label: Username:", +- "*passwordDialog.dialog.label: Password:", ++ "*userDialog.dialog.label: SSVNC: Enter Username", + "*userDialog.dialog.value:", ++ "*userDialog.dialog.value.width: 150", + "*userDialog.dialog.value.translations: #override\\n\ + Return: UserDialogDone()", + @@ -817,8 +823,9 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v + "*scaleNDialog.dialog.value.translations: #override\\n\ + Return: ScaleNDialogDone()", + - "*passwordDialog.dialog.label: Password:", ++ "*passwordDialog.dialog.label: SSVNC: Enter Password", "*passwordDialog.dialog.value:", ++ "*passwordDialog.dialog.value.width: 150", "*passwordDialog.dialog.value.AsciiSink.echo: False", "*passwordDialog.dialog.value.translations: #override\\n\ Return: PasswordDialogDone()", @@ -863,12 +870,12 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v : SendRFBEvent() HidePopup()", - "*popupButtonCount: 8", -+ "*popupButtonCount: 42", -+ "*popupButtonBreak: 21", ++ "*popupButtonCount: 44", ++ "*popupButtonBreak: 22", "*popup*button1.label: Dismiss popup", "*popup*button1.translations: #override\\n\ -@@ -84,7 +236,7 @@ +@@ -84,7 +239,7 @@ "*popup*button2.translations: #override\\n\ ,: Quit()", @@ -877,7 +884,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v "*popup*button3.type: toggle", "*popup*button3.translations: #override\\n\ : SetFullScreenState()\\n\ -@@ -105,16 +257,418 @@ +@@ -105,16 +260,426 @@ "*popup*button7.label: Send ctrl-alt-del", "*popup*button7.translations: #override\\n\ ,: SendRFBEvent(keydown,Control_L)\ @@ -930,156 +937,164 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v + : SetCursorAlphaState()\\n\ + ,: toggle() ToggleCursorAlpha() HidePopup()", + -+ "*popup*button15.label: Toggle Tight/ZRLE", ++ "*popup*button15.label: Toggle Tight/Hextile", + "*popup*button15.type: toggle", + "*popup*button15.translations: #override\\n\ -+ : SetZRLEState()\\n\ -+ ,: toggle() ToggleTightZRLE() HidePopup()", ++ : SetHextileState()\\n\ ++ ,: toggle() ToggleTightHextile() HidePopup()", + -+ "*popup*button16.label: Toggle ZRLE/ZYWRLE", ++ "*popup*button16.label: Toggle Tight/ZRLE", + "*popup*button16.type: toggle", + "*popup*button16.translations: #override\\n\ ++ : SetZRLEState()\\n\ ++ ,: toggle() ToggleTightZRLE() HidePopup()", ++ ++ "*popup*button17.label: Toggle ZRLE/ZYWRLE", ++ "*popup*button17.type: toggle", ++ "*popup*button17.translations: #override\\n\ + : SetZYWRLEState()\\n\ + ,: toggle() ToggleZRLEZYWRLE() HidePopup()", + -+ "*popup*button17.label: Quality Level", -+ "*popup*button17.translations: #override\\n\ ++ "*popup*button18.label: Quality Level", ++ "*popup*button18.translations: #override\\n\ + ,: HidePopup() ShowQuality()", + -+ "*popup*button18.label: Compress Level", -+ "*popup*button18.translations: #override\\n\ ++ "*popup*button19.label: Compress Level", ++ "*popup*button19.translations: #override\\n\ + ,: HidePopup() ShowCompress()", + -+ "*popup*button19.label: Disable JPEG", -+ "*popup*button19.type: toggle", -+ "*popup*button19.translations: #override\\n\ ++ "*popup*button20.label: Disable JPEG", ++ "*popup*button20.type: toggle", ++ "*popup*button20.translations: #override\\n\ + : SetNOJPEGState()\\n\ + ,: toggle() ToggleJPEG() HidePopup()", + -+ "*popup*button20.label: TurboVNC Settings", -+ "*popup*button20.translations: #override\\n\ ++ "*popup*button21.label: TurboVNC Settings", ++ "*popup*button21.translations: #override\\n\ + ,: HidePopup() ShowTurboVNC()", + -+ "*popup*button21.label: Pipeline Updates", -+ "*popup*button21.type: toggle", -+ "*popup*button21.translations: #override\\n\ ++ "*popup*button22.label: Pipeline Updates", ++ "*popup*button22.type: toggle", ++ "*popup*button22.translations: #override\\n\ + : SetPipelineUpdates()\\n\ + ,: toggle() TogglePipelineUpdates() HidePopup()", + -+ "*popup*button22.label: Full Color", -+ "*popup*button22.type: toggle", -+ "*popup*button22.translations: #override\\n\ ++ "*popup*button23.label: Full Color", ++ "*popup*button23.type: toggle", ++ "*popup*button23.translations: #override\\n\ + : SetFullColorState()\\n\ + ,: toggle() ToggleFullColor() HidePopup()", + -+ "*popup*button23.label: Grey Scale (16 & 8-bpp)", -+ "*popup*button23.type: toggle", -+ "*popup*button23.translations: #override\\n\ ++ "*popup*button24.label: Grey Scale (16 & 8-bpp)", ++ "*popup*button24.type: toggle", ++ "*popup*button24.translations: #override\\n\ + : SetGreyScaleState()\\n\ + ,: toggle() ToggleGreyScale() HidePopup()", + -+ "*popup*button24.label: 16 bit color (BGR565)", -+ "*popup*button24.type: toggle", -+ "*popup*button24.translations: #override\\n\ ++ "*popup*button25.label: 16 bit color (BGR565)", ++ "*popup*button25.type: toggle", ++ "*popup*button25.translations: #override\\n\ + : Set16bppState()\\n\ + ,: toggle() Toggle16bpp() HidePopup()", + -+ "*popup*button25.label: 8 bit color (BGR233)", -+ "*popup*button25.type: toggle", -+ "*popup*button25.translations: #override\\n\ ++ "*popup*button26.label: 8 bit color (BGR233)", ++ "*popup*button26.type: toggle", ++ "*popup*button26.translations: #override\\n\ + : Set8bppState()\\n\ + ,: toggle() Toggle8bpp() HidePopup()", + -+ "*popup*button26.label: - 256 colors", -+ "*popup*button26.type: toggle", -+ "*popup*button26.translations: #override\\n\ ++ "*popup*button27.label: - 256 colors", ++ "*popup*button27.type: toggle", ++ "*popup*button27.translations: #override\\n\ + : Set256ColorsState()\\n\ + ,: toggle() Toggle256Colors() HidePopup()", + -+ "*popup*button27.label: - 64 colors", -+ "*popup*button27.type: toggle", -+ "*popup*button27.translations: #override\\n\ ++ "*popup*button28.label: - 64 colors", ++ "*popup*button28.type: toggle", ++ "*popup*button28.translations: #override\\n\ + : Set64ColorsState()\\n\ + ,: toggle() Toggle64Colors() HidePopup()", + -+ "*popup*button28.label: - 8 colors", -+ "*popup*button28.type: toggle", -+ "*popup*button28.translations: #override\\n\ ++ "*popup*button29.label: - 8 colors", ++ "*popup*button29.type: toggle", ++ "*popup*button29.translations: #override\\n\ + : Set8ColorsState()\\n\ + ,: toggle() Toggle8Colors() HidePopup()", + -+ "*popup*button29.label: Scale Viewer", -+ "*popup*button29.translations: #override\\n\ ++ "*popup*button30.label: Scale Viewer", ++ "*popup*button30.translations: #override\\n\ + ,: HidePopup() SetScale()", + -+ "*popup*button30.label: Escape Keys: Toggle", -+ "*popup*button30.type: toggle", -+ "*popup*button30.translations: #override\\n\ ++ "*popup*button31.label: Escape Keys: Toggle", ++ "*popup*button31.type: toggle", ++ "*popup*button31.translations: #override\\n\ + : SetEscapeKeysState()\\n\ + , : toggle() ToggleEscapeActive() HidePopup()", + -+ "*popup*button31.label: Escape Keys: Help+Set", -+ "*popup*button31.translations: #override\\n\ ++ "*popup*button32.label: Escape Keys: Help+Set", ++ "*popup*button32.translations: #override\\n\ + , : HidePopup() SetEscapeKeys()", + -+ "*popup*button32.label: Set Y Crop (y-max)", -+ "*popup*button32.translations: #override\\n\ ++ "*popup*button33.label: Set Y Crop (y-max)", ++ "*popup*button33.translations: #override\\n\ + ,: HidePopup() SetYCrop()", + -+ "*popup*button33.label: Set Scrollbar Width", -+ "*popup*button33.translations: #override\\n\ ++ "*popup*button34.label: Set Scrollbar Width", ++ "*popup*button34.translations: #override\\n\ + ,: HidePopup() SetScbar()", + -+ "*popup*button34.label: XGrabServer", -+ "*popup*button34.type: toggle", -+ "*popup*button34.translations: #override\\n\ ++ "*popup*button35.label: XGrabServer", ++ "*popup*button35.type: toggle", ++ "*popup*button35.translations: #override\\n\ + : SetXGrabState()\\n\ + ,: toggle() ToggleXGrab() HidePopup()", + -+ "*popup*button35.label: UltraVNC Extensions:", -+ "*popup*button35.translations: #override\\n\ ++ "*popup*button36.label: UltraVNC Extensions:", ++ "*popup*button36.translations: #override\\n\ + ,: HidePopup()", + -+ "*popup*button36.label: - Set 1/n Server Scale", -+ "*popup*button36.translations: #override\\n\ ++ "*popup*button37.label: - Set 1/n Server Scale", ++ "*popup*button37.translations: #override\\n\ + ,: HidePopup() ShowScaleN()", + -+ "*popup*button37.label: - Text Chat", -+ "*popup*button37.type: toggle", -+ "*popup*button37.translations: #override\\n\ ++ "*popup*button38.label: - Text Chat", ++ "*popup*button38.type: toggle", ++ "*popup*button38.translations: #override\\n\ + : SetTextChatState()\\n\ + ,: toggle() ToggleTextChat() HidePopup()", + -+ "*popup*button38.label: - File Transfer", -+ "*popup*button38.type: toggle", -+ "*popup*button38.translations: #override\\n\ ++ "*popup*button39.label: - File Transfer", ++ "*popup*button39.type: toggle", ++ "*popup*button39.translations: #override\\n\ + : SetFileXferState()\\n\ + ,: toggle() ToggleFileXfer() HidePopup()", + -+ "*popup*button39.label: - Single Window", -+ "*popup*button39.type: toggle", -+ "*popup*button39.translations: #override\\n\ ++ "*popup*button40.label: - Single Window", ++ "*popup*button40.type: toggle", ++ "*popup*button40.translations: #override\\n\ + : SetSingleWindowState()\\n\ + ,: toggle() ToggleSingleWindow() HidePopup()", + -+ "*popup*button40.label: - Disable Remote Input", -+ "*popup*button40.type: toggle", -+ "*popup*button40.translations: #override\\n\ ++ "*popup*button41.label: - Disable Remote Input", ++ "*popup*button41.type: toggle", ++ "*popup*button41.translations: #override\\n\ + : SetServerInputState()\\n\ + ,: toggle() ToggleServerInput() HidePopup()", + -+ "*popup*button41.label: Send Clipboard not Primary", -+ "*popup*button41.type: toggle", -+ "*popup*button41.translations: #override\\n\ ++ "*popup*button42.label: Send Clipboard not Primary", ++ "*popup*button42.type: toggle", ++ "*popup*button42.translations: #override\\n\ + : SetSendClipboard()\\n\ + ,: toggle() ToggleSendClipboard() HidePopup()", + -+ "*popup*button42.label: Send Selection Every time", -+ "*popup*button42.type: toggle", -+ "*popup*button42.translations: #override\\n\ ++ "*popup*button43.label: Send Selection Every time", ++ "*popup*button43.type: toggle", ++ "*popup*button43.translations: #override\\n\ + : SetSendAlways()\\n\ + ,: toggle() ToggleSendAlways() HidePopup()", + ++ "*popup*button44.label: ", ++ + "*turboVNC*button0.label: Dismiss", + "*turboVNC*button0.translations: #override\\n\ + ,: HideTurboVNC()", @@ -1301,7 +1316,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v NULL }; -@@ -124,7 +678,7 @@ +@@ -124,7 +689,7 @@ * from a dialog box. */ @@ -1310,7 +1325,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v int vncServerPort = 0; -@@ -135,6 +689,7 @@ +@@ -135,6 +700,7 @@ */ AppData appData; @@ -1318,7 +1333,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v static XtResource appDataResourceList[] = { {"shareDesktop", "ShareDesktop", XtRBool, sizeof(Bool), -@@ -155,14 +710,44 @@ +@@ -155,14 +721,44 @@ {"userLogin", "UserLogin", XtRString, sizeof(String), XtOffsetOf(AppData, userLogin), XtRImmediate, (XtPointer) 0}, @@ -1365,7 +1380,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v {"nColours", "NColours", XtRInt, sizeof(int), XtOffsetOf(AppData, nColours), XtRImmediate, (XtPointer) 256}, -@@ -179,9 +764,12 @@ +@@ -179,9 +775,12 @@ {"requestedDepth", "RequestedDepth", XtRInt, sizeof(int), XtOffsetOf(AppData, requestedDepth), XtRImmediate, (XtPointer) 0}, @@ -1379,7 +1394,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v {"wmDecorationWidth", "WmDecorationWidth", XtRInt, sizeof(int), XtOffsetOf(AppData, wmDecorationWidth), XtRImmediate, (XtPointer) 4}, -@@ -191,6 +779,9 @@ +@@ -191,6 +790,9 @@ {"popupButtonCount", "PopupButtonCount", XtRInt, sizeof(int), XtOffsetOf(AppData, popupButtonCount), XtRImmediate, (XtPointer) 0}, @@ -1389,7 +1404,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v {"debug", "Debug", XtRBool, sizeof(Bool), XtOffsetOf(AppData, debug), XtRImmediate, (XtPointer) False}, -@@ -206,11 +797,13 @@ +@@ -206,11 +808,13 @@ {"bumpScrollPixels", "BumpScrollPixels", XtRInt, sizeof(int), XtOffsetOf(AppData, bumpScrollPixels), XtRImmediate, (XtPointer) 20}, @@ -1404,7 +1419,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v {"enableJPEG", "EnableJPEG", XtRBool, sizeof(Bool), XtOffsetOf(AppData, enableJPEG), XtRImmediate, (XtPointer) True}, -@@ -218,14 +811,85 @@ +@@ -218,14 +822,88 @@ {"useRemoteCursor", "UseRemoteCursor", XtRBool, sizeof(Bool), XtOffsetOf(AppData, useRemoteCursor), XtRImmediate, (XtPointer) True}, @@ -1413,6 +1428,9 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v + + {"useRawLocal", "UseRawLocal", XtRBool, sizeof(Bool), + XtOffsetOf(AppData, useRawLocal), XtRImmediate, (XtPointer) False}, ++ ++ {"notty", "NoTty", XtRBool, sizeof(Bool), ++ XtOffsetOf(AppData, notty), XtRImmediate, (XtPointer) False}, + {"useX11Cursor", "UseX11Cursor", XtRBool, sizeof(Bool), XtOffsetOf(AppData, useX11Cursor), XtRImmediate, (XtPointer) False}, @@ -1492,7 +1510,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v }; -@@ -242,8 +906,28 @@ +@@ -242,8 +920,29 @@ {"-noraiseonbeep", "*raiseOnBeep", XrmoptionNoArg, "False"}, {"-passwd", "*passwordFile", XrmoptionSepArg, 0}, {"-user", "*userLogin", XrmoptionSepArg, 0}, @@ -1518,11 +1536,12 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v + {"-env", "*envDummy", XrmoptionSepArg, 0}, + {"-ycrop", "*yCrop", XrmoptionSepArg, 0}, + {"-rawlocal", "*useRawLocal", XrmoptionNoArg, "True"}, ++ {"-notty", "*notty", XrmoptionNoArg, "True"}, + {"-alpha", "*useCursorAlpha", XrmoptionNoArg, "True"}, {"-owncmap", "*forceOwnCmap", XrmoptionNoArg, "True"}, {"-truecolor", "*forceTrueColour", XrmoptionNoArg, "True"}, {"-truecolour", "*forceTrueColour", XrmoptionNoArg, "True"}, -@@ -253,8 +937,27 @@ +@@ -253,8 +952,27 @@ {"-nojpeg", "*enableJPEG", XrmoptionNoArg, "False"}, {"-nocursorshape", "*useRemoteCursor", XrmoptionNoArg, "False"}, {"-x11cursor", "*useX11Cursor", XrmoptionNoArg, "True"}, @@ -1552,7 +1571,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v }; int numCmdLineOptions = XtNumber(cmdLineOptions); -@@ -267,16 +970,98 @@ +@@ -267,16 +985,100 @@ static XtActionsRec actions[] = { {"SendRFBEvent", SendRFBEvent}, {"ShowPopup", ShowPopup}, @@ -1589,6 +1608,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v + {"Toggle8Colors", Toggle8Colors}, + {"ToggleGreyScale", ToggleGreyScale}, + {"ToggleTightZRLE", ToggleTightZRLE}, ++ {"ToggleTightHextile", ToggleTightHextile}, + {"ToggleZRLEZYWRLE", ToggleZRLEZYWRLE}, + {"ToggleViewOnly", ToggleViewOnly}, + {"ToggleJPEG", ToggleJPEG}, @@ -1625,6 +1645,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v + {"Set8ColorsState", Set8ColorsState}, + {"SetGreyScaleState", SetGreyScaleState}, + {"SetZRLEState", SetZRLEState}, ++ {"SetHextileState", SetHextileState}, + {"SetZYWRLEState", SetZYWRLEState}, + {"SetNOJPEGState", SetNOJPEGState}, + {"SetScaleNState", SetScaleNState}, @@ -1651,7 +1672,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v }; -@@ -302,11 +1087,14 @@ +@@ -302,11 +1104,14 @@ void usage(void) { @@ -1668,7 +1689,16 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v " %s [] -listen []\n" " %s -help\n" "\n" -@@ -332,10 +1120,349 @@ +@@ -319,7 +1124,7 @@ + " -noraiseonbeep\n" + " -passwd (standard VNC authentication)\n" + " -user (Unix login authentication)\n" +- " -encodings (e.g. \"tight copyrect\")\n" ++ " -encodings (e.g. \"tight,copyrect\")\n" + " -bgr233\n" + " -owncmap\n" + " -truecolour\n" +@@ -332,10 +1137,374 @@ " -autopass\n" "\n" "Option names may be abbreviated, e.g. -bgr instead of -bgr233.\n" @@ -1782,6 +1812,30 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v + " -rawlocal Prefer raw encoding for localhost, default is\n" + " no, i.e. assumes you have a SSH tunnel instead.\n" + "\n" ++ " -notty Try to avoid using the terminal for interactive\n" ++ " responses: use windows for messages and prompting\n" ++ " instead. Messages will also be printed to terminal.\n" ++ "\n" ++ " -sendclipboard Send the X CLIPBOARD selection (i.e. Ctrl+C,\n" ++ " Ctrl+V) instead of the X PRIMARY selection (mouse\n" ++ " select and middle button paste.)\n" ++ "\n" ++ " -sendalways Whenever the mouse enters the VNC viewer main\n" ++ " window, send the selection to the VNC server even if\n" ++ " it has not changed. This is like the Xt resource\n" ++ " translation SelectionToVNC(always)\n" ++ "\n" ++ " -recvtext str When cut text is received from the VNC server,\n" ++ " ssvncviewer will set both the X PRIMARY and the\n" ++ " X CLIPBOARD local selections. To control which\n" ++ " is set, specify 'str' as 'primary', 'clipboard',\n" ++ " or 'both' (the default.)\n" ++ "\n" ++ " -graball Grab the entire X server when in fullscreen mode,\n" ++ " needed by some old window managers like fvwm2.\n" ++ "\n" ++ " -popupfix Warp the popup back to the pointer position,\n" ++ " needed by some old window managers like fvwm2.\n" + " -sendclipboard Send the X CLIPBOARD selection (i.e. Ctrl+C,\n" + " Ctrl+V) instead of the X PRIMARY selection (mouse\n" + " select and middle button paste.)\n" @@ -1974,7 +2028,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v + " Cursor Shape: ~ -nocursorshape\n" + " X11 Cursor: ~ -x11cursor\n" + " Cursor Alphablend: ~ -alpha\n" -+ " Toggle Tight/ZRLE: ~ -encodings ...\n" ++ " Toggle Tight/Hextile: ~ -encodings hextile...\n" ++ " Toggle Tight/ZRLE: ~ -encodings zrle...\n" + " Toggle ZRLE/ZYWRLE: ~ -encodings zywrle...\n" + " Quality Level ~ -quality (both Tight and ZYWRLE)\n" + " Compress Level ~ -compresslevel\n" @@ -2020,7 +2075,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v /* -@@ -347,73 +1474,214 @@ +@@ -347,73 +1516,223 @@ void GetArgsAndResources(int argc, char **argv) { @@ -2048,7 +2103,13 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v + appData.useCursorAlpha = True; + } + if (getenv("VNCVIEWER_POPUP_FIX")) { -+ appData.popupFix = True; ++ if (getenv("NOPOPUPFIX")) { ++ ; ++ } else if (!strcmp(getenv("VNCVIEWER_POPUP_FIX"), "0")) { ++ ; ++ } else { ++ appData.popupFix = True; ++ } + } + if (getenv("VNCVIEWER_GRAB_SERVER")) { + appData.grabAll = True; @@ -2074,6 +2135,9 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v + if (getenv("VNCVIEWER_RAWLOCAL")) { + appData.useRawLocal = True; + } ++ if (getenv("VNCVIEWER_NOTTY") || getenv("SSVNC_VNCVIEWER_NOTTY")) { ++ appData.notty = True; ++ } + if (getenv("VNCVIEWER_SBWIDTH")) { + int n = atoi(getenv("VNCVIEWER_SBWIDTH")); + if (n != 0) { @@ -2231,7 +2295,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v + + if (argc == 1) { + vncServerName = DoServerDialog(); -+ if (!isatty(0)) { ++ if (!use_tty()) { + appData.passwordDialog = True; + } + } else if (argc != 2) { @@ -2239,7 +2303,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/v + } else { + vncServerName = argv[1]; + -+ if (!isatty(0)) { ++ if (!use_tty()) { + appData.passwordDialog = True; + } + if (vncServerName[0] == '-') { @@ -3623,7 +3687,7 @@ 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 2009-03-26 23:27:45.000000000 -0400 ++++ vnc_unixsrc/vncviewer/desktop.c 2009-10-16 22:04:39.000000000 -0400 @@ -28,28 +28,487 @@ #include #endif @@ -4215,8 +4279,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview + } + + create_image(); - } - ++} ++ +static Widget scrollbar_y = NULL; + +static int xsst = 2; @@ -4255,8 +4319,8 @@ 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() { @@ -4519,18 +4583,18 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview +#else +#define nfix(i, n) ( i < 0 ? 0 : ( (i >= n) ? (n - 1) : i ) ) +#endif - -- XChangeWindowAttributes(dpy, desktopWin, valuemask, &attr); ++ +int scale_round(int len, double fac) { + double eps = 0.000001; -+ + +- XChangeWindowAttributes(dpy, desktopWin, valuemask, &attr); + len = (int) (len * fac + eps); + if (len < 1) { + len = 1; + } + return len; -+} -+ + } + +static void scale_rect(double factor_x, double factor_y, int blend, int interpolate, + int *px, int *py, int *pw, int *ph, int solid) { + @@ -5058,8 +5122,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview + markit: +/* End taken from x11vnc scale: */ + if (0) {} - } - ++} ++ +void do_scale_stats(int width, int height) { + static double calls = 0.0, sum = 0.0, var = 0.0, last = 0.0; + double A = width * height; @@ -5237,6 +5301,13 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview + if (y + height < si.framebufferHeight) height++; + } + } ++ ++ if (x + width > si.framebufferWidth) { ++ width = si.framebufferWidth - x; ++ if (width <= 0) { ++ break; ++ } ++ } - if (ev->xexpose.x + ev->xexpose.width > si.framebufferWidth) { - ev->xexpose.width = si.framebufferWidth - ev->xexpose.x; @@ -5251,13 +5322,6 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview - SendFramebufferUpdateRequest(ev->xexpose.x, ev->xexpose.y, - ev->xexpose.width, ev->xexpose.height, False); - break; -+ if (x + width > si.framebufferWidth) { -+ width = si.framebufferWidth - x; -+ if (width <= 0) { -+ break; -+ } -+ } -+ + if (y + height > si.framebufferHeight) { + height = si.framebufferHeight - y; + if (height <= 0) { @@ -5337,8 +5401,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview + break; } + check_things(); -+} -+ + } + +extern Position desktopX, desktopY; + +void scroll_desktop(int horiz, int vert, double amount) { @@ -5405,8 +5469,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview + } else if (amount == -1.0) { + XSync(dpy, False); + } - } - ++} ++ +void scale_desktop(int bigger, double frac) { + double current, new; + char tmp[100]; @@ -5622,7 +5686,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview /* * SendRFBEvent is an action which sends an RFB event. It can be used in two -@@ -201,127 +1948,322 @@ +@@ -201,127 +1948,324 @@ * button2 down, 3 for both, etc). */ @@ -5719,7 +5783,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview + if (!do_escape) { + escape_drag_in_progress = 0; + } -+ + +- if (appData.viewOnly) return; + if (do_escape) { + int W = si.framebufferWidth; + int H = si.framebufferHeight; @@ -5779,6 +5844,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview + ToggleX11Cursor(w, ev, params, num_params); + } else if (ks == XK_z || ks == XK_Z) { + ToggleTightZRLE(w, ev, params, num_params); ++ } else if (ks == XK_h || ks == XK_H) { ++ ToggleTightHextile(w, ev, params, num_params); + } else if (ks == XK_f || ks == XK_F) { + ToggleFileXfer(w, ev, params, num_params); + } else if (ks == XK_V) { @@ -5840,8 +5907,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview + if (appData.viewOnly) { + return; + } - -- if (appData.viewOnly) return; ++ + if (*num_params != 0) { + if (strncasecmp(params[0],"key",3) == 0) { + if (*num_params != 2) { @@ -6005,11 +6071,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview + XLookupString(&ev->xkey, keyname, 256, &ks, NULL); - switch (ev->type) { -+ if (IsModifierKey(ks)) { -+ ks = XKeycodeToKeysym(dpy, ev->xkey.keycode, 0); -+ modifierPressed[ev->xkey.keycode] = (ev->type == KeyPress); -+ } - +- - case MotionNotify: - while (XCheckTypedWindowEvent(dpy, desktopWin, MotionNotify, ev)) - ; /* discard all queued motion notify events */ @@ -6038,12 +6100,16 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview - ks = XKeycodeToKeysym(dpy, ev->xkey.keycode, 0); - modifierPressed[ev->xkey.keycode] = (ev->type == KeyPress); - } -+ SendKeyEvent(ks, (ev->type == KeyPress)); -+ return; ++ if (IsModifierKey(ks)) { ++ ks = XKeycodeToKeysym(dpy, ev->xkey.keycode, 0); ++ modifierPressed[ev->xkey.keycode] = (ev->type == KeyPress); ++ } - SendKeyEvent(ks, (ev->type == KeyPress)); - return; -- ++ SendKeyEvent(ks, (ev->type == KeyPress)); ++ return; + - default: - fprintf(stderr,"Invalid event passed to SendRFBEvent\n"); - } @@ -6053,7 +6119,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview } -@@ -329,26 +2271,194 @@ +@@ -329,26 +2273,207 @@ * CreateDotCursor. */ @@ -6120,7 +6186,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview + cursor = XCreatePixmapCursor(dpy, src, msk, &fg, &bg, 1, 1); + XFreePixmap(dpy, src); + XFreePixmap(dpy, msk); -+ + +- return cursor; + return cursor; +} +#endif @@ -6128,7 +6195,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview +int skip_maybe_sync = 0; +void maybe_sync(int width, int height) { + static int singles = 0, always_skip = -1; -+ int singles_max = 32; ++ int singles_max = 64; + + if (always_skip < 0) { + if (getenv("SSVNC_NO_MAYBE_SYNC")) { @@ -6140,6 +6207,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview + if (skip_maybe_sync || always_skip) { + return; + } ++#if 0 + if (width > 1 || height > 1) { + XSync(dpy, False); + singles = 0; @@ -6149,6 +6217,18 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview + XSync(dpy, False); + } + } ++#else ++ if (width * height >= singles_max) { ++ XSync(dpy, False); ++ singles = 0; ++ } else { ++ singles += width * height; ++ if (singles >= singles_max) { ++ XSync(dpy, False); ++ singles = 0; ++ } ++ } ++#endif +} +/* + * FillImage. @@ -6244,8 +6324,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview + dst -= Bpl; + } + } - -- return cursor; ++ + if (image_scale && !did2) { + im = image; + Bpp = im->bits_per_pixel / 8; @@ -6264,7 +6343,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview } -@@ -359,38 +2469,37 @@ +@@ -359,38 +2484,37 @@ void CopyDataToScreen(char *buf, int x, int y, int width, int height) { @@ -6332,7 +6411,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview } -@@ -401,62 +2510,297 @@ +@@ -401,62 +2525,297 @@ static void CopyBGR233ToScreen(CARD8 *buf, int x, int y, int width, int height) { @@ -6686,8 +6765,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncview } diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/dialogs.c vnc_unixsrc/vncviewer/dialogs.c --- vnc_unixsrc.orig/vncviewer/dialogs.c 2000-10-26 15:19:19.000000000 -0400 -+++ vnc_unixsrc/vncviewer/dialogs.c 2009-04-15 14:12:13.000000000 -0400 -@@ -25,7 +25,395 @@ ++++ vnc_unixsrc/vncviewer/dialogs.c 2009-10-27 00:14:05.000000000 -0400 +@@ -25,75 +25,549 @@ #include static Bool serverDialogDone = False; @@ -6703,6 +6782,15 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/dialogs.c vnc_unixsrc/vncview + +extern void popupFixer(Widget wid); + ++int use_tty(void) { ++ if (appData.notty) { ++ return 0; ++ } else if (!isatty(0)) { ++ return 0; ++ } ++ return 1; ++} ++ +void +ScaleDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ @@ -6758,6 +6846,10 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/dialogs.c vnc_unixsrc/vncview + } +} + ++static void xtmove(Widget w) { ++ XtMoveWidget(w, WidthOfScreen(XtScreen(w))*2/5, HeightOfScreen(XtScreen(w))*2/5); ++} ++ +char * +DoScaleDialog() +{ @@ -6771,8 +6863,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/dialogs.c vnc_unixsrc/vncview + + dialog_over(pshell); + -+ XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, -+ HeightOfScreen(XtScreen(pshell))*2/5); ++ if (0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5); + XtPopup(pshell, XtGrabNonexclusive); + XtRealizeWidget(pshell); + @@ -6787,8 +6878,10 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/dialogs.c vnc_unixsrc/vncview + } + + -+ if (appData.popupFix) { ++ if (1 && appData.popupFix) { + popupFixer(pshell); ++ } else { ++ xtmove(pshell); + } + dialog_input(pshell); + wm_delete(pshell, "ScaleDialogDone()"); @@ -6821,8 +6914,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/dialogs.c vnc_unixsrc/vncview + + dialog_over(pshell); + -+ XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, -+ HeightOfScreen(XtScreen(pshell))*2/5); ++ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5); + XtPopup(pshell, XtGrabNonexclusive); + XtRealizeWidget(pshell); + @@ -6838,6 +6930,9 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/dialogs.c vnc_unixsrc/vncview + + if (appData.popupFix) { + popupFixer(pshell); ++ } else { ++ /* too big */ ++ if (0) xtmove(pshell); + } + dialog_input(pshell); + wm_delete(pshell, "EscapeDialogDone()"); @@ -6865,172 +6960,176 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/dialogs.c vnc_unixsrc/vncview +char * +DoYCropDialog() +{ -+ Widget pshell, dialog; -+ char *ycropValue; -+ char *valueString; ++ Widget pshell, dialog; ++ char *ycropValue; ++ char *valueString; + -+ pshell = XtVaCreatePopupShell("ycropDialog", transientShellWidgetClass, ++ pshell = XtVaCreatePopupShell("ycropDialog", transientShellWidgetClass, + toplevel, NULL); -+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); ++ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); + + dialog_over(pshell); + -+ XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, -+ HeightOfScreen(XtScreen(pshell))*2/5); -+ XtPopup(pshell, XtGrabNonexclusive); -+ XtRealizeWidget(pshell); ++ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5); ++ XtPopup(pshell, XtGrabNonexclusive); ++ XtRealizeWidget(pshell); + -+ if (appData.popupFix) { -+ popupFixer(pshell); -+ } ++ if (1 && appData.popupFix) { ++ popupFixer(pshell); ++ } else { ++ xtmove(pshell); ++ } + dialog_input(pshell); + wm_delete(pshell, "YCropDialogDone()"); + -+ ycropDialogDone = False; ++ ycropDialogDone = False; + -+ while (!ycropDialogDone) { -+ XtAppProcessEvent(appContext, XtIMAll); -+ } ++ while (!ycropDialogDone) { ++ XtAppProcessEvent(appContext, XtIMAll); ++ } + -+ valueString = XawDialogGetValueString(dialog); ++ valueString = XawDialogGetValueString(dialog); + rmNL(valueString); -+ ycropValue = XtNewString(valueString); ++ ycropValue = XtNewString(valueString); + -+ XtPopdown(pshell); -+ return ycropValue; ++ XtPopdown(pshell); ++ return ycropValue; +} + +void +ScbarDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ -+ scbarDialogDone = True; ++ scbarDialogDone = True; +} + +char * +DoScbarDialog() +{ -+ Widget pshell, dialog; -+ char *scbarValue; -+ char *valueString; ++ Widget pshell, dialog; ++ char *scbarValue; ++ char *valueString; + -+ pshell = XtVaCreatePopupShell("scbarDialog", transientShellWidgetClass, ++ pshell = XtVaCreatePopupShell("scbarDialog", transientShellWidgetClass, + toplevel, NULL); -+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); ++ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); + + dialog_over(pshell); + -+ XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, -+ HeightOfScreen(XtScreen(pshell))*2/5); -+ XtPopup(pshell, XtGrabNonexclusive); -+ XtRealizeWidget(pshell); ++ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5); ++ XtPopup(pshell, XtGrabNonexclusive); ++ XtRealizeWidget(pshell); + -+ if (appData.popupFix) { -+ popupFixer(pshell); -+ } ++ if (1 && appData.popupFix) { ++ popupFixer(pshell); ++ } else { ++ xtmove(pshell); ++ } + dialog_input(pshell); + wm_delete(pshell, "ScbarDialogDone()"); + -+ scbarDialogDone = False; ++ scbarDialogDone = False; + -+ while (!scbarDialogDone) { -+ XtAppProcessEvent(appContext, XtIMAll); -+ } ++ while (!scbarDialogDone) { ++ XtAppProcessEvent(appContext, XtIMAll); ++ } + -+ valueString = XawDialogGetValueString(dialog); ++ valueString = XawDialogGetValueString(dialog); + rmNL(valueString); -+ scbarValue = XtNewString(valueString); ++ scbarValue = XtNewString(valueString); + -+ XtPopdown(pshell); -+ return scbarValue; ++ XtPopdown(pshell); ++ return scbarValue; +} + +void +ScaleNDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ -+ scaleNDialogDone = True; ++ scaleNDialogDone = True; +} + +char * +DoScaleNDialog() +{ -+ Widget pshell, dialog; -+ char *scaleNValue; -+ char *valueString; ++ Widget pshell, dialog; ++ char *scaleNValue; ++ char *valueString; + -+ pshell = XtVaCreatePopupShell("scaleNDialog", transientShellWidgetClass, ++ pshell = XtVaCreatePopupShell("scaleNDialog", transientShellWidgetClass, + toplevel, NULL); -+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); ++ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); + + dialog_over(pshell); + wm_delete(pshell, "ScaleNDialogDone()"); + -+ XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, -+ HeightOfScreen(XtScreen(pshell))*2/5); -+ XtPopup(pshell, XtGrabNonexclusive); -+ XtRealizeWidget(pshell); ++ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5); ++ XtPopup(pshell, XtGrabNonexclusive); ++ XtRealizeWidget(pshell); + -+ if (appData.popupFix) { -+ popupFixer(pshell); -+ } ++ if (appData.popupFix) { ++ popupFixer(pshell); ++ } else { ++ xtmove(pshell); ++ } + dialog_input(pshell); + wm_delete(pshell, "ScaleNDialogDone()"); + -+ scaleNDialogDone = False; ++ scaleNDialogDone = False; + -+ while (!scaleNDialogDone) { -+ XtAppProcessEvent(appContext, XtIMAll); -+ } ++ while (!scaleNDialogDone) { ++ XtAppProcessEvent(appContext, XtIMAll); ++ } + -+ valueString = XawDialogGetValueString(dialog); ++ valueString = XawDialogGetValueString(dialog); + rmNL(valueString); -+ scaleNValue = XtNewString(valueString); ++ scaleNValue = XtNewString(valueString); + -+ XtPopdown(pshell); -+ return scaleNValue; ++ XtPopdown(pshell); ++ return scaleNValue; +} + +void +QualityDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ -+ qualityDialogDone = True; ++ qualityDialogDone = True; +} + +char * +DoQualityDialog() +{ -+ Widget pshell, dialog; -+ char *qualityValue; -+ char *valueString; ++ Widget pshell, dialog; ++ char *qualityValue; ++ char *valueString; + -+ pshell = XtVaCreatePopupShell("qualityDialog", transientShellWidgetClass, ++ pshell = XtVaCreatePopupShell("qualityDialog", transientShellWidgetClass, + toplevel, NULL); -+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); ++ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); + + dialog_over(pshell); + -+ XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, -+ HeightOfScreen(XtScreen(pshell))*2/5); -+ XtPopup(pshell, XtGrabNonexclusive); -+ XtRealizeWidget(pshell); ++ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5); ++ XtPopup(pshell, XtGrabNonexclusive); ++ XtRealizeWidget(pshell); + -+ if (appData.popupFix) { -+ popupFixer(pshell); -+ } ++ if (1 && appData.popupFix) { ++ popupFixer(pshell); ++ } else { ++ xtmove(pshell); ++ } + dialog_input(pshell); + wm_delete(pshell, "QualityDialogDone() HideQuality()"); + -+ qualityDialogDone = False; ++ qualityDialogDone = False; + -+ while (!qualityDialogDone) { -+ XtAppProcessEvent(appContext, XtIMAll); -+ } ++ while (!qualityDialogDone) { ++ XtAppProcessEvent(appContext, XtIMAll); ++ } + -+ valueString = XawDialogGetValueString(dialog); ++ valueString = XawDialogGetValueString(dialog); + rmNL(valueString); -+ qualityValue = XtNewString(valueString); ++ qualityValue = XtNewString(valueString); + -+ XtPopdown(pshell); -+ return qualityValue; ++ XtPopdown(pshell); ++ return qualityValue; +} + +void @@ -7042,154 +7141,219 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/dialogs.c vnc_unixsrc/vncview +char * +DoCompressDialog() +{ -+ Widget pshell, dialog; -+ char *compressValue; -+ char *valueString; ++ Widget pshell, dialog; ++ char *compressValue; ++ char *valueString; + -+fprintf(stderr, "compress start:\n"); ++ fprintf(stderr, "compress start:\n"); + -+ pshell = XtVaCreatePopupShell("compressDialog", transientShellWidgetClass, ++ pshell = XtVaCreatePopupShell("compressDialog", transientShellWidgetClass, + toplevel, NULL); -+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); ++ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); + + dialog_over(pshell); + -+ XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, -+ HeightOfScreen(XtScreen(pshell))*2/5); -+ XtPopup(pshell, XtGrabNonexclusive); -+ XtRealizeWidget(pshell); ++ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5); ++ XtPopup(pshell, XtGrabNonexclusive); ++ XtRealizeWidget(pshell); + -+ if (appData.popupFix) { -+ popupFixer(pshell); -+ } ++ if (1 && appData.popupFix) { ++ popupFixer(pshell); ++ } else { ++ xtmove(pshell); ++ } + dialog_input(pshell); + wm_delete(pshell, "CompressDialogDone() HideCompress()"); + -+ compressDialogDone = False; ++ compressDialogDone = False; + -+ while (!compressDialogDone) { -+ XtAppProcessEvent(appContext, XtIMAll); -+ } ++ while (!compressDialogDone) { ++ XtAppProcessEvent(appContext, XtIMAll); ++ } + -+ valueString = XawDialogGetValueString(dialog); ++ valueString = XawDialogGetValueString(dialog); + rmNL(valueString); -+ compressValue = XtNewString(valueString); ++ compressValue = XtNewString(valueString); + -+fprintf(stderr, "compress done: %s\n", compressValue); ++ fprintf(stderr, "compress done: %s\n", compressValue); + -+ XtPopdown(pshell); -+ return compressValue; ++ XtPopdown(pshell); ++ return compressValue; +} void ServerDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params) -@@ -44,11 +432,19 @@ + { +- serverDialogDone = True; ++ serverDialogDone = True; + } + + char * + DoServerDialog() + { +- Widget pshell, dialog; +- char *vncServerName; +- char *valueString; ++ Widget pshell, dialog; ++ char *vncServerName; ++ char *valueString; + +- pshell = XtVaCreatePopupShell("serverDialog", transientShellWidgetClass, ++ pshell = XtVaCreatePopupShell("serverDialog", transientShellWidgetClass, toplevel, NULL); - dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); +- dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); ++ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); +- XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, +- HeightOfScreen(XtScreen(pshell))*2/5); +- XtPopup(pshell, XtGrabNonexclusive); +- XtRealizeWidget(pshell); + dialog_over(pshell); -+ - XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, - HeightOfScreen(XtScreen(pshell))*2/5); - XtPopup(pshell, XtGrabNonexclusive); - XtRealizeWidget(pshell); -+ if (appData.popupFix) { -+ popupFixer(pshell); -+ } +- serverDialogDone = False; ++ if (0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5); ++ XtPopup(pshell, XtGrabNonexclusive); ++ XtRealizeWidget(pshell); ++ ++ if (0 && appData.popupFix) { ++ popupFixer(pshell); ++ } else { ++ xtmove(pshell); ++ } + //dialog_input(pshell); + wm_delete(pshell, "ServerDialogDone()"); + - serverDialogDone = False; - - while (!serverDialogDone) { -@@ -56,6 +452,7 @@ - } - - valueString = XawDialogGetValueString(dialog); ++ serverDialogDone = False; ++ ++ while (!serverDialogDone) { ++ XtAppProcessEvent(appContext, XtIMAll); ++ } ++ ++ valueString = XawDialogGetValueString(dialog); + rmNL(valueString); - vncServerName = XtNewString(valueString); ++ vncServerName = XtNewString(valueString); - XtPopdown(pshell); -@@ -63,6 +460,50 @@ - } +- while (!serverDialogDone) { +- XtAppProcessEvent(appContext, XtIMAll); +- } ++ XtPopdown(pshell); ++ return vncServerName; ++} - void +- valueString = XawDialogGetValueString(dialog); +- vncServerName = XtNewString(valueString); ++void +UserDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params) +{ -+ userDialogDone = True; ++ userDialogDone = True; +} -+ + +- XtPopdown(pshell); +- return vncServerName; +char * +DoUserDialog() +{ -+ Widget pshell, dialog; -+ char *userName; -+ char *valueString; ++ Widget pshell, dialog; ++ char *userName; ++ char *valueString; + -+ pshell = XtVaCreatePopupShell("userDialog", transientShellWidgetClass, ++ pshell = XtVaCreatePopupShell("userDialog", transientShellWidgetClass, + toplevel, NULL); -+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); ++ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); + + dialog_over(pshell); + -+ XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, -+ HeightOfScreen(XtScreen(pshell))*2/5); -+ XtPopup(pshell, XtGrabNonexclusive); -+ XtRealizeWidget(pshell); ++ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5); ++ XtPopup(pshell, XtGrabNonexclusive); ++ XtRealizeWidget(pshell); + -+ if (appData.popupFix) { -+ popupFixer(pshell); -+ } ++ if (0 && appData.popupFix) { ++ popupFixer(pshell); ++ } else { ++ xtmove(pshell); ++ } + //dialog_input(pshell); + wm_delete(pshell, "UserDialogDone()"); + -+ userDialogDone = False; ++ userDialogDone = False; + -+ while (!userDialogDone) { -+ XtAppProcessEvent(appContext, XtIMAll); -+ } ++ while (!userDialogDone) { ++ XtAppProcessEvent(appContext, XtIMAll); ++ } + -+ valueString = XawDialogGetValueString(dialog); ++ valueString = XawDialogGetValueString(dialog); + rmNL(valueString); -+ userName = XtNewString(valueString); -+ -+ XtPopdown(pshell); -+ return userName; -+} ++ userName = XtNewString(valueString); + -+void ++ XtPopdown(pshell); ++ return userName; + } + + void PasswordDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params) { -@@ -80,11 +521,19 @@ +- passwordDialogDone = True; ++ passwordDialogDone = True; + } + + char * + DoPasswordDialog() + { +- Widget pshell, dialog; +- char *password; +- char *valueString; ++ Widget pshell, dialog; ++ char *password; ++ char *valueString; + +- pshell = XtVaCreatePopupShell("passwordDialog", transientShellWidgetClass, ++ pshell = XtVaCreatePopupShell("passwordDialog", transientShellWidgetClass, toplevel, NULL); - dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); +- dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); +- +- XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, +- HeightOfScreen(XtScreen(pshell))*2/5); +- XtPopup(pshell, XtGrabNonexclusive); +- XtRealizeWidget(pshell); +- +- passwordDialogDone = False; ++ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); +- while (!passwordDialogDone) { +- XtAppProcessEvent(appContext, XtIMAll); +- } + dialog_over(pshell); -+ - XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, - HeightOfScreen(XtScreen(pshell))*2/5); - XtPopup(pshell, XtGrabNonexclusive); - XtRealizeWidget(pshell); -+ if (appData.popupFix) { -+ popupFixer(pshell); -+ } +- valueString = XawDialogGetValueString(dialog); +- password = XtNewString(valueString); ++ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5); ++ XtPopup(pshell, XtGrabNonexclusive); ++ XtRealizeWidget(pshell); ++ ++ if (0 && appData.popupFix) { ++ popupFixer(pshell); ++ } else { ++ xtmove(pshell); ++ } + //dialog_input(pshell); + wm_delete(pshell, "PasswordDialogDone()"); + - passwordDialogDone = False; - - while (!passwordDialogDone) { -@@ -92,6 +541,7 @@ - } - - valueString = XawDialogGetValueString(dialog); ++ passwordDialogDone = False; ++ ++ while (!passwordDialogDone) { ++ XtAppProcessEvent(appContext, XtIMAll); ++ } ++ ++ valueString = XawDialogGetValueString(dialog); + rmNL(valueString); - password = XtNewString(valueString); ++ password = XtNewString(valueString); - XtPopdown(pshell); +- XtPopdown(pshell); +- return password; ++ XtPopdown(pshell); ++ return password; + } diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/fullscreen.c vnc_unixsrc/vncviewer/fullscreen.c --- vnc_unixsrc.orig/vncviewer/fullscreen.c 2003-10-09 05:23:49.000000000 -0400 +++ vnc_unixsrc/vncviewer/fullscreen.c 2008-10-25 18:22:14.000000000 -0400 @@ -8217,8 +8381,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/h2html.pl vnc_unixsrc/vncview +} 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 2008-10-05 15:16:24.000000000 -0400 -@@ -30,6 +30,18 @@ ++++ vnc_unixsrc/vncviewer/hextile.c 2009-10-16 22:54:40.000000000 -0400 +@@ -30,6 +30,21 @@ #define CARDBPP CONCAT2E(CARD,BPP) #define GET_PIXEL CONCAT2E(GET_PIXEL,BPP) @@ -8233,11 +8397,62 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/hextile.c vnc_unixsrc/vncview + XFillRectangle(dpy, desktopWin, gc, x, y, w, h); \ + } \ + } ++ ++extern int skip_maybe_sync; ++extern void maybe_sync(int w, int h); + static Bool HandleHextileBPP (int rx, int ry, int rw, int rh) { -@@ -66,14 +78,25 @@ +@@ -41,21 +56,43 @@ + int sx, sy, sw, sh; + CARD8 subencoding; + CARD8 nSubrects; ++ int irect = 0, nrects = (rw * rh) / (16 * 16); ++ static int nosync_ycrop = -1; ++ ++ if (nosync_ycrop < 0) { ++ nosync_ycrop = 0; ++ if (getenv("HEXTILE_YCROP_TOO")) { ++ nosync_ycrop = 1; ++ } ++ } + + for (y = ry; y < ry+rh; y += 16) { + for (x = rx; x < rx+rw; x += 16) { + w = h = 16; +- if (rx+rw - x < 16) ++ if (rx+rw - x < 16) { + w = rx+rw - x; +- if (ry+rh - y < 16) ++ } ++ if (ry+rh - y < 16) { + h = ry+rh - y; ++ } ++ ++ if (nrects > 400 && (appData.yCrop == 0 || nosync_ycrop)) { ++ skip_maybe_sync = 0; ++ if (irect++ % 2000 != 0) { ++ if (x < rx+rw-16 || y < ry+rh-16) { ++ skip_maybe_sync = 1; ++ } ++ } ++ } + +- if (!ReadFromRFBServer((char *)&subencoding, 1)) ++ if (!ReadFromRFBServer((char *)&subencoding, 1)) { + return False; ++ } + + if (subencoding & rfbHextileRaw) { +- if (!ReadFromRFBServer(buffer, w * h * (BPP / 8))) ++ if (!ReadFromRFBServer(buffer, w * h * (BPP / 8))) { + return False; ++ } + + CopyDataToScreen(buffer, x, y, w, h); + continue; +@@ -66,14 +103,25 @@ return False; #if (BPP == 8) @@ -8246,12 +8461,12 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/hextile.c vnc_unixsrc/vncview gcv.foreground = BGR233ToPixel[bg]; - else + } else - #endif ++#endif +#if (BPP == 16) + if (appData.useBGR565) { + gcv.foreground = BGR565ToPixel[bg]; + } else -+#endif + #endif + { gcv.foreground = bg; + } @@ -8267,7 +8482,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/hextile.c vnc_unixsrc/vncview if (subencoding & rfbHextileForegroundSpecified) if (!ReadFromRFBServer((char *)&fg, sizeof(fg))) -@@ -101,14 +124,25 @@ +@@ -101,14 +149,25 @@ sh = rfbHextileExtractH(*ptr); ptr++; #if (BPP == 8) @@ -8276,12 +8491,12 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/hextile.c vnc_unixsrc/vncview gcv.foreground = BGR233ToPixel[fg]; - else + } else -+#endif + #endif +#if (BPP == 16) + if (appData.useBGR565) { + gcv.foreground = BGR565ToPixel[fg]; + } else - #endif ++#endif + { gcv.foreground = fg; + } @@ -8297,7 +8512,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/hextile.c vnc_unixsrc/vncview } } else { -@@ -116,13 +150,22 @@ +@@ -116,13 +175,22 @@ return False; #if (BPP == 8) @@ -8322,7 +8537,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/hextile.c vnc_unixsrc/vncview for (i = 0; i < nSubrects; i++) { sx = rfbHextileExtractX(*ptr); -@@ -131,7 +174,11 @@ +@@ -131,7 +199,11 @@ sw = rfbHextileExtractW(*ptr); sh = rfbHextileExtractH(*ptr); ptr++; @@ -8334,7 +8549,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/hextile.c vnc_unixsrc/vncview } } } -@@ -139,3 +186,5 @@ +@@ -139,3 +211,5 @@ return True; } @@ -8342,7 +8557,7 @@ 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 2009-07-28 21:44:32.000000000 -0400 ++++ vnc_unixsrc/vncviewer/listen.c 2009-10-23 11:48:38.000000000 -0400 @@ -32,6 +32,7 @@ #define FLASHDELAY 1 /* seconds */ @@ -8351,10 +8566,11 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/listen.c vnc_unixsrc/vncviewe int listenPort = 0, flashPort = 0; static Font flashFont; -@@ -40,6 +41,75 @@ +@@ -40,6 +41,77 @@ static void flashDisplay(Display *d, char *user); static Bool AllXEventsPredicate(Display *d, XEvent *ev, char *arg); ++void raiseme(int force); + +static int accept_popup_check(int *argc, char **argv, char *sip, char *sih) { + char line[16]; @@ -8365,7 +8581,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/listen.c vnc_unixsrc/vncviewe + return 1; + } + -+ if (!dopopup) { ++ if (!dopopup && use_tty()) { ++ raiseme(1); + fprintf(stderr, "Accept VNC connection? y/[n] "); + fgets(line, sizeof(line), stdin); + if (!strchr(line, 'y') && !strchr(line, 'Y')) { @@ -8427,7 +8644,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/listen.c vnc_unixsrc/vncviewe /* * listenForIncomingConnections() - listen for incoming connections from * servers, and fork a new process to deal with each connection. We must do -@@ -58,8 +128,11 @@ +@@ -58,8 +130,11 @@ int n; int i; char *displayname = NULL; @@ -8439,7 +8656,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/listen.c vnc_unixsrc/vncviewe for (i = 1; i < *argc; i++) { if (strcmp(argv[i], "-display") == 0 && i+1 < *argc) { -@@ -108,23 +181,40 @@ +@@ -108,23 +183,40 @@ exit(1); } @@ -8486,7 +8703,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/listen.c vnc_unixsrc/vncviewe /* discard any X events */ while (XCheckIfEvent(d, &ev, AllXEventsPredicate, NULL)) -@@ -132,12 +222,24 @@ +@@ -132,12 +224,24 @@ FD_ZERO(&fds); @@ -8512,7 +8729,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/listen.c vnc_unixsrc/vncviewe if (FD_ISSET(flashSocket, &fds)) { sock = AcceptTcpConnection(flashSocket); -@@ -151,11 +253,66 @@ +@@ -151,11 +255,66 @@ } close(sock); } @@ -8582,7 +8799,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/listen.c vnc_unixsrc/vncviewe XCloseDisplay(d); -@@ -170,18 +327,28 @@ +@@ -170,18 +329,28 @@ case 0: /* child - return to caller */ close(listenSocket); @@ -8613,7 +8830,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/listen.c vnc_unixsrc/vncviewe break; } } -@@ -200,6 +367,13 @@ +@@ -200,6 +369,13 @@ char **fontNames; int nFontNames; @@ -8627,7 +8844,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/listen.c vnc_unixsrc/vncviewe sprintf(fontName,"-*-courier-bold-r-*-*-%d-*-*-*-*-*-iso8859-1", FLASHWIDTH); fontNames = XListFonts(d, fontName, 1, &nFontNames); -@@ -209,6 +383,9 @@ +@@ -209,6 +385,9 @@ sprintf(fontName,"fixed"); } flashFont = XLoadFont(d, fontName); @@ -8637,7 +8854,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/listen.c vnc_unixsrc/vncviewe } -@@ -222,6 +399,11 @@ +@@ -222,6 +401,11 @@ Window w1, w2, w3, w4; XSetWindowAttributes attr; @@ -8649,7 +8866,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/listen.c vnc_unixsrc/vncviewe XBell(d, 0); XForceScreenSaver(d, ScreenSaverReset); -@@ -284,6 +466,9 @@ +@@ -284,6 +468,9 @@ XDestroyWindow(d, w3); XDestroyWindow(d, w4); XFlush(d); @@ -9056,7 +9273,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/misc.c vnc_unixsrc/vncviewer/ 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 2009-07-29 20:05:17.000000000 -0400 ++++ vnc_unixsrc/vncviewer/popup.c 2009-10-27 00:14:17.000000000 -0400 @@ -25,22 +25,59 @@ #include @@ -9123,7 +9340,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/popup.c vnc_unixsrc/vncviewer } -@@ -52,42 +89,789 @@ +@@ -52,42 +89,786 @@ }; void @@ -9180,7 +9397,6 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/popup.c vnc_unixsrc/vncviewer +{ + if (appData.popupFix) { + popupFixer(scaleN); -+ + } else { + XtMoveWidget(scaleN, event->xbutton.x_root, event->xbutton.y_root); + XtPopup(scaleN, XtGrabNone); @@ -9372,7 +9588,6 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/popup.c vnc_unixsrc/vncviewer +{ + if (appData.popupFix) { + popupFixer(qualityW); -+ + } else { + XtMoveWidget(qualityW, event->xbutton.x_root, event->xbutton.y_root); + XtPopup(qualityW, XtGrabNone); @@ -9430,7 +9645,6 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/popup.c vnc_unixsrc/vncviewer +{ + if (appData.popupFix) { + popupFixer(compressW); -+ + } else { + XtMoveWidget(compressW, event->xbutton.x_root, event->xbutton.y_root); + XtPopup(compressW, XtGrabNone); @@ -9956,7 +10170,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/popup_ad vnc_unixsrc/vncviewe +} diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncviewer/rfbproto.c --- vnc_unixsrc.orig/vncviewer/rfbproto.c 2008-09-05 19:51:24.000000000 -0400 -+++ vnc_unixsrc/vncviewer/rfbproto.c 2009-10-03 12:28:22.000000000 -0400 ++++ vnc_unixsrc/vncviewer/rfbproto.c 2009-11-02 10:02:00.000000000 -0500 @@ -23,6 +23,7 @@ * rfbproto.c - functions to deal with client side of RFB protocol. */ @@ -10020,7 +10234,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie static void ReadConnFailedReason(void); static long ReadCompactLen (void); -@@ -67,6 +109,20 @@ +@@ -67,6 +109,22 @@ static void JpegSetSrcManager(j_decompress_ptr cinfo, CARD8 *compressedData, int compressedLen); @@ -10038,10 +10252,12 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie +static double dt_out_sc = 0.0; +double latency = 0.0; +double connect_time = 0.0; ++ ++void raiseme(int force); int rfbsock; char *desktopName; -@@ -75,6 +131,14 @@ +@@ -75,6 +133,14 @@ char *serverCutText = NULL; Bool newServerCutText = False; @@ -10056,7 +10272,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie int endianTest = 1; static Bool tightVncProtocol = False; -@@ -177,8 +241,26 @@ +@@ -177,8 +243,26 @@ sig_rfbEncodingPointerPos, "Pointer position update"); CapsAdd(encodingCaps, rfbEncodingLastRect, rfbTightVncVendor, sig_rfbEncodingLastRect, "LastRect protocol extension"); @@ -10076,14 +10292,14 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + +static void wmsg(char *msg, int wait) { + fprintf(stderr, "%s", msg); -+ if (!isatty(0) && !getenv("SSVNC_NO_MESSAGE_POPUP")) { ++ if (!use_tty() && !getenv("SSVNC_NO_MESSAGE_POPUP")) { + CreateMsg(msg, wait); + } +} /* * ConnectToRFBServer. -@@ -187,24 +269,167 @@ +@@ -187,24 +271,167 @@ Bool ConnectToRFBServer(const char *hostname, int port) { @@ -10263,7 +10479,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie /* * InitialiseRFBConnection. */ -@@ -212,211 +437,620 @@ +@@ -212,211 +439,620 @@ Bool InitialiseRFBConnection(void) { @@ -10748,7 +10964,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + + switch (secType) { + case rfbSecTypeNone: -+ fprintf(stderr, "No authentication needed\n"); ++ fprintf(stderr, "No VNC authentication needed\n"); + if (viewer_minor == 8) { + CARD32 authResult; + @@ -11039,7 +11255,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } -@@ -451,6 +1085,9 @@ +@@ -451,6 +1087,9 @@ return True; } @@ -11049,7 +11265,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie /* * Negotiate authentication scheme (protocol version 3.7t) -@@ -459,58 +1096,384 @@ +@@ -459,58 +1098,388 @@ static Bool PerformAuthenticationTight(void) { @@ -11079,7 +11295,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie - return True; - } + if (!caps.nAuthTypes) { -+ fprintf(stderr, "No authentication needed\n\n"); ++ fprintf(stderr, "No VNC authentication needed\n\n"); + return True; + } @@ -11145,14 +11361,12 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + return False; + } + } - -- fprintf(stderr, "No suitable authentication schemes offered by server\n"); -- return False; ++ + sprintf(msgbuf, "No suitable authentication schemes offered by server\n"); + wmsg(msgbuf, 1); + return False; - } - ++} ++ +#if 0 +unsigned char encPasswd[8]; +unsigned char encPasswd_MSLOGON[32]; @@ -11164,6 +11378,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + /* code from the old uvnc way (1.0.2?) that would go into AuthenticateVNC() template */ + + if (appData.msLogon != NULL) { ++ raiseme(1); + if (!strcmp(appData.msLogon, "1")) { + char tmp[256]; + fprintf(stderr, "\nUltraVNC MS Logon Username[@Domain]: "); @@ -11235,14 +11450,16 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie +static unsigned long long bytes_to_uint64(char *bytes) { + unsigned long long result = 0; + int i; -+ + +- fprintf(stderr, "No suitable authentication schemes offered by server\n"); +- return False; + for (i=0; i < 8; i++) { + result <<= 8; + result += (unsigned char) bytes[i]; + } + return result; -+} -+ + } + +static void uint64_to_bytes(unsigned long long n, char *bytes) { + int i; + @@ -11381,10 +11598,12 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + + if (appData.msLogon == NULL || !strcmp(appData.msLogon, "1")) { + char tmp[256], *q, *s; -+ fprintf(stderr, "\nUltraVNC MS-Logon Username[@Domain]: "); -+ if (!isatty(0)) { ++ if (!use_tty()) { ++ fprintf(stderr, "\nEnter UltraVNC MS-Logon Username[@Domain] in the popup.\n"); + s = DoUserDialog(); + } else { ++ raiseme(1); ++ fprintf(stderr, "\nUltraVNC MS-Logon Username[@Domain]: "); + if (fgets(tmp, 256, stdin) == NULL) { + exit(1); + } @@ -11395,9 +11614,10 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + appData.msLogon = strdup(s); + } + -+ if (!isatty(0)) { ++ if (!use_tty()) { + gpw = DoPasswordDialog(); + } else { ++ raiseme(1); + gpw = getpass("UltraVNC MS-Logon Password: "); + } + if (! gpw) { @@ -11476,7 +11696,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie /* * Standard VNC authentication. -@@ -519,80 +1482,113 @@ +@@ -519,80 +1488,115 @@ static Bool AuthenticateVNC(void) { @@ -11516,6 +11736,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + } + } else if (appData.autoPass) { + passwd = buffer; ++ raiseme(1); + cstatus = fgets(buffer, sizeof buffer, stdin); + if (cstatus == NULL) { + buffer[0] = '\0'; @@ -11527,9 +11748,10 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie + } + } else if (getenv("VNCVIEWER_PASSWORD")) { + passwd = strdup(getenv("VNCVIEWER_PASSWORD")); -+ } else if (appData.passwordDialog) { ++ } else if (appData.passwordDialog || !use_tty()) { + passwd = DoPasswordDialog(); + } else { ++ raiseme(1); + passwd = getpass("VNC Password: "); + } @@ -11653,7 +11875,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } /* -@@ -602,68 +1598,74 @@ +@@ -602,68 +1606,75 @@ static Bool AuthenticateUnixLogin(void) { @@ -11696,9 +11918,10 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie - fprintf(stderr, "Reading password failed\n"); - return False; - } -+ if (appData.passwordDialog) { ++ if (appData.passwordDialog || !use_tty()) { + passwd = DoPasswordDialog(); + } else { ++ raiseme(1); + passwd = getpass("VNC Password: "); + } + if (!passwd || strlen(passwd) == 0) { @@ -11780,7 +12003,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } -@@ -675,19 +1677,20 @@ +@@ -675,19 +1686,20 @@ static Bool ReadInteractionCaps(void) { @@ -11813,7 +12036,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } -@@ -700,19 +1703,67 @@ +@@ -700,19 +1712,67 @@ static Bool ReadCapabilityList(CapsContainer *caps, int count) { @@ -11890,7 +12113,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie /* * SetFormatAndEncodings. -@@ -729,6 +1780,17 @@ +@@ -729,6 +1789,17 @@ Bool requestCompressLevel = False; Bool requestQualityLevel = False; Bool requestLastRectEncoding = False; @@ -11908,7 +12131,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie spf.type = rfbSetPixelFormat; spf.format = myFormat; -@@ -736,12 +1798,18 @@ +@@ -736,15 +1807,32 @@ spf.format.greenMax = Swap16IfLE(spf.format.greenMax); spf.format.blueMax = Swap16IfLE(spf.format.blueMax); @@ -11927,7 +12150,21 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie if (appData.encodingsString) { char *encStr = appData.encodingsString; int encStrLen; -@@ -754,50 +1822,102 @@ ++ if (strchr(encStr, ',')) { ++ char *p; ++ encStr = strdup(encStr); ++ p = encStr; ++ while (*p != '\0') { ++ if (*p == ',') { ++ *p = ' '; ++ } ++ p++; ++ } ++ } + do { + char *nextEncStr = strchr(encStr, ' '); + if (nextEncStr) { +@@ -754,50 +1842,102 @@ encStrLen = strlen(encStr); } @@ -12046,7 +12283,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 +1926,16 @@ +@@ -806,10 +1946,16 @@ if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding) { encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect); } @@ -12066,7 +12303,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 { -@@ -818,44 +1944,84 @@ +@@ -818,44 +1964,84 @@ } encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect); @@ -12173,7 +12410,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie return True; } -@@ -868,31 +2034,86 @@ +@@ -868,31 +2054,86 @@ Bool SendIncrementalFramebufferUpdateRequest() { @@ -12273,7 +12510,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } -@@ -903,19 +2124,36 @@ +@@ -903,19 +2144,36 @@ Bool SendPointerEvent(int x, int y, int buttonMask) { @@ -12322,7 +12559,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } -@@ -926,12 +2164,20 @@ +@@ -926,12 +2184,20 @@ Bool SendKeyEvent(CARD32 key, Bool down) { @@ -12348,7 +12585,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } -@@ -942,281 +2188,1024 @@ +@@ -942,281 +2208,1024 @@ Bool SendClientCutText(char *str, int len) { @@ -13595,7 +13832,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 +3213,168 @@ +@@ -1224,59 +3233,168 @@ mainly to avoid copyrect using invalid screen contents - not sure if we'd need it otherwise. */ @@ -13797,7 +14034,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } -@@ -1296,26 +3394,93 @@ +@@ -1296,26 +3414,93 @@ #define CONCAT2(a,b) a##b #define CONCAT2E(a,b) CONCAT2(a,b) @@ -13891,7 +14128,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie #undef BPP /* -@@ -1325,23 +3490,27 @@ +@@ -1325,23 +3510,27 @@ static void ReadConnFailedReason(void) { @@ -13933,7 +14170,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie } /* -@@ -1358,9 +3527,9 @@ +@@ -1358,9 +3547,9 @@ " %s significant bit in each byte is leftmost on the screen.\n", (format->bigEndian ? "Most" : "Least")); } else { @@ -13945,7 +14182,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncvie (format->bigEndian ? "Most" : "Least")); } if (format->trueColour) { -@@ -1462,4 +3631,3 @@ +@@ -1462,4 +3651,3 @@ cinfo->src = &jpegSrcManager; } @@ -15272,11 +15509,15 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/tight.c vnc_unixsrc/vncviewer diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/tmake vnc_unixsrc/vncviewer/tmake --- vnc_unixsrc.orig/vncviewer/tmake 1969-12-31 19:00:00.000000000 -0500 -+++ vnc_unixsrc/vncviewer/tmake 2009-03-08 17:11:49.000000000 -0400 -@@ -0,0 +1,13 @@ ++++ vnc_unixsrc/vncviewer/tmake 2009-10-25 10:31:22.000000000 -0400 +@@ -0,0 +1,17 @@ +#!/bin/sh +TURBOVNC_DIR=/home/runge/turbojpeg +make clean ++(cd ../libvncauth || exit 1; make) ++if [ "X$1" = "X-a" ]; then ++ exit ++fi +make CCOPTIONS=-DTURBOVNC EXTRA_LIBRARIES="-L$TURBOVNC_DIR -Xlinker --rpath=$TURBOVNC_DIR -Xlinker --rpath=/usr/local/lib -lturbojpeg" +cp -p vncviewer vncviewer.turbovnc +strip vncviewer.turbovnc @@ -16165,8 +16406,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/turbovnc/turbojpeg.h vnc_unix +#endif 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 2009-10-03 12:28:09.000000000 -0400 -@@ -0,0 +1,793 @@ ++++ vnc_unixsrc/vncviewer/vncviewer._man 2009-10-23 12:24:51.000000000 -0400 +@@ -0,0 +1,799 @@ +'\" t +.\" ** The above line should force tbl to be a preprocessor ** +.\" Man page for X vncviewer @@ -16288,13 +16529,13 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer._man vnc_unixsrc/vn +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. ++thus be enclosed in quotes if more than one is specified. Commas may be used to avoid spaces. ++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 @@ -16481,6 +16722,11 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer._man vnc_unixsrc/vn +Prefer raw encoding for localhost, default is +no, i.e. assumes you have a SSH tunnel instead. +.TP ++\fB\-notty\fR ++Try to avoid using the terminal for interactive ++responses: use windows for messages and prompting ++instead. Messages will also be printed to terminal. ++.TP +\fB\-sendclipboard\fR +Send the X CLIPBOARD selection (i.e. Ctrl+C, +Ctrl+V) instead of the X PRIMARY selection (mouse @@ -16699,7 +16945,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer._man vnc_unixsrc/vn + Cursor Shape: ~ -nocursorshape + X11 Cursor: ~ -x11cursor + Cursor Alphablend: ~ -alpha -+ Toggle Tight/ZRLE: ~ -encodings ... ++ Toggle Tight/Hextile: ~ -encodings hextile... ++ Toggle Tight/ZRLE: ~ -encodings zrle... + Toggle ZRLE/ZYWRLE: ~ -encodings zywrle... + Quality Level ~ -quality (both Tight and ZYWRLE) + Compress Level ~ -compresslevel @@ -16962,7 +17209,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer._man vnc_unixsrc/vn +Karl J. Runge 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 2009-07-28 22:51:20.000000000 -0400 ++++ vnc_unixsrc/vncviewer/vncviewer.c 2009-10-23 11:53:44.000000000 -0400 @@ -22,6 +22,7 @@ */ @@ -16971,10 +17218,12 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi char *programName; XtAppContext appContext; -@@ -29,11 +30,234 @@ +@@ -29,11 +30,241 @@ Widget toplevel; ++extern void raiseme(int force); ++ +void set_sbwidth(int sbw) { + char *q, *p, t[5]; + int i, k, N = 4; @@ -17050,15 +17299,18 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi + } + if (!strcmp(str, ".")) { + char *p; -+ fprintf(stderr, "\nUnix Username: "); -+ if (!isatty(0)) { -+ char *u = DoUserDialog(); ++ if (!use_tty()) { ++ char *u; ++ fprintf(stderr, "\nEnter Unix Username and Password in the popups.\n"); ++ u = DoUserDialog(); + if (strlen(u) >= 100) { + exit(1); + } + sprintf(username, u); + p = DoPasswordDialog(); + } else { ++ raiseme(1); ++ fprintf(stderr, "\nUnix Username: "); + if (fgets(username, N, stdin) == NULL) { + exit(1); + } @@ -17072,9 +17324,11 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi + + } else if (!strcmp(str, "-")) { + char *p, *q; -+ if (!isatty(0)) { ++ if (!use_tty()) { ++ fprintf(stderr, "\nEnter unixuser@unixpasswd in the popup.\n"); + p = DoPasswordDialog(); + } else { ++ raiseme(1); + p = getpass("unixuser@unixpasswd: "); + } + if (! p) { @@ -17208,7 +17462,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 +269,1615 @@ +@@ -45,89 +276,1647 @@ listenForIncomingConnections() returns, setting the listenSpecified flag. */ @@ -17613,13 +17867,11 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi + appData.escapeActive = True; + } +} - -- Cleanup(); ++ +/* + * ToggleNColors + */ - -- return 0; ++ +static Widget w256 = NULL; +static Widget w64 = NULL; +static Widget w8 = NULL; @@ -17705,6 +17957,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi + +static Bool usingZRLE = False; +static Bool usingZYWRLE = False; ++static Bool usingHextile = False; +extern int skip_maybe_sync; + +void @@ -17713,6 +17966,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi + char prefTight[] = "copyrect tight zrle zywrle zlib hextile corre rre raw"; + char prefZRLE[] = "copyrect zrle zywrle tight zlib hextile corre rre raw"; + init_format_change(); ++ usingHextile = False; + if (! appData.encodingsString) { + appDataNew.encodingsString = strdup(prefZRLE); + usingZRLE = True; @@ -17761,6 +18015,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi + char prefZRLE[] = "copyrect zrle zywrle tight zlib hextile corre rre raw"; + init_format_change(); + usingZRLE = True; ++ usingHextile = False; + if (! appData.encodingsString) { + appDataNew.encodingsString = strdup(prefZYWRLE); + usingZYWRLE = True; @@ -17783,6 +18038,52 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi + schedule_format_change(); +} + ++void ++ToggleTightHextile(Widget w, XEvent *ev, String *params, Cardinal *num_params) ++{ ++ char prefTight[] = "copyrect tight zrle zywrle zlib hextile corre rre raw"; ++ char prefHextile[] = "copyrect hextile tight zrle zywrle zlib corre rre raw"; ++ init_format_change(); ++ usingZRLE = False; ++ usingZYWRLE = False; ++ if (! appData.encodingsString) { ++ appDataNew.encodingsString = strdup(prefHextile); ++ usingHextile = True; ++ fprintf(stderr, "prefer: Hextile\n"); ++ } else { ++ char *t, *z; ++ static int first = 1; ++ t = strstr(appData.encodingsString, "tight"); ++ z = strstr(appData.encodingsString, "hextile"); ++ if (first && usingHextile) { ++ appDataNew.encodingsString = strdup(prefTight); ++ usingHextile = False; ++ } else if (! t) { ++ appDataNew.encodingsString = strdup(prefHextile); ++ usingHextile = True; ++ fprintf(stderr, "prefer: Hextile\n"); ++ } else if (! z) { ++ appDataNew.encodingsString = strdup(prefTight); ++ usingHextile = False; ++ skip_maybe_sync = 0; ++ fprintf(stderr, "prefer: Tight\n"); ++ } else { ++ if (t < z) { ++ appDataNew.encodingsString = strdup(prefHextile); ++ usingHextile = True; ++ fprintf(stderr, "prefer: Hextile\n"); ++ } else { ++ appDataNew.encodingsString = strdup(prefTight); ++ usingHextile = False; ++ skip_maybe_sync = 0; ++ fprintf(stderr, "prefer: Tight\n"); ++ } ++ } ++ first = 0; ++ } ++ schedule_format_change(); ++} ++ +void scale_check_zrle(void) { + static int didit = 0; + if (didit) { @@ -17792,7 +18093,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi + if (getenv("SSVNC_PRESERVE_ENCODING")) { + return; + } -+ if (!usingZRLE) { ++ if (!usingZRLE && !usingHextile) { + Widget w; + fprintf(stderr, "\nSwitching to faster ZRLE encoding in client-side scaling mode.\n"); + fprintf(stderr, "Switch back to Tight via the Popup menu if you prefer it.\n\n"); @@ -18078,7 +18379,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi + schedule_fb_update(); + } +} -+ + +- Cleanup(); +void +DoServerScale(Widget w, XEvent *ev, String *params, Cardinal *num_params) +{ @@ -18168,7 +18470,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi + set_server_compress(n); + } +} -+ + +- return 0; +extern void rescale_image(void); + +void @@ -18655,75 +18958,46 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi + } +} + -+void -+SetZRLEState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ ++static init_state(void) { + static int first = 1; + if (first && appData.encodingsString) { -+ char *t, *z, *w; -+ t = strstr(appData.encodingsString, "tight"); -+ z = strstr(appData.encodingsString, "zrle"); -+ w = strstr(appData.encodingsString, "zywrle"); -+ if (t) { -+ if (z) { -+ if (w) { -+ if (t < z && t < w) { -+ usingZRLE = False; -+ } else { -+ usingZRLE = True; -+ } -+ if (z < w) { -+ usingZYWRLE = False; -+ } else { -+ usingZYWRLE = True; -+ } -+ } else { -+ if (t < z) { -+ usingZRLE = False; -+ } else { -+ usingZRLE = True; -+ } -+ usingZYWRLE = False; -+ } -+ } else { -+ if (w) { -+ if (t < w) { -+ usingZRLE = False; -+ } else { -+ usingZRLE = True; -+ } -+ usingZYWRLE = True; -+ } else { -+ usingZRLE = False; -+ usingZYWRLE = False; -+ } -+ } -+ } else { -+ if (z) { -+ if (w) { -+ usingZRLE = True; -+ if (z < w) { -+ usingZYWRLE = False; -+ } else { -+ usingZYWRLE = True; -+ } -+ } else { -+ usingZRLE = True; -+ usingZYWRLE = False; -+ } -+ } else { -+ if (w) { -+ usingZRLE = True; -+ usingZYWRLE = True; -+ } else { -+ usingZRLE = False; -+ usingZYWRLE = False; -+ } -+ } ++ char *t, *z, *y, *h; ++ char *str = appData.encodingsString; ++ int len = strlen(str); ++ ++ t = strstr(str, "tight"); ++ z = strstr(str, "zrle"); ++ y = strstr(str, "zywrle"); ++ h = strstr(str, "hextile"); ++ ++ if (!t) t = str + len; ++ if (!z) z = str + len; ++ if (!y) y = str + len; ++ if (!h) h = str + len; ++ ++ usingZRLE = False; ++ usingZYWRLE = False; ++ usingHextile = False; ++ ++ if (t < z && t < y && t < h) { ++ ; ++ } else if (z < t && z < y && z < h) { ++ usingZRLE = True; ++ } else if (y < t && y < z && y < h) { ++ usingZYWRLE = True; ++ usingZRLE = True; ++ } else if (h < t && h < z && h < y) { ++ usingHextile = True; + } + } + first = 0; + ++} ++ ++void ++SetZRLEState(Widget w, XEvent *ev, String *params, Cardinal *num_params) ++{ ++ init_state(); + if (usingZRLE) { + XtVaSetValues(w, XtNstate, True, NULL); + } else { @@ -18732,8 +19006,20 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncvi +} + +void ++SetHextileState(Widget w, XEvent *ev, String *params, Cardinal *num_params) ++{ ++ init_state(); ++ if (usingHextile) { ++ XtVaSetValues(w, XtNstate, True, NULL); ++ } else { ++ XtVaSetValues(w, XtNstate, False, NULL); ++ } ++} ++ ++void +SetZYWRLEState(Widget w, XEvent *ev, String *params, Cardinal *num_params) +{ ++ init_state(); + if (usingZYWRLE) { + XtVaSetValues(w, XtNstate, True, NULL); + } else { @@ -18862,7 +19148,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 2009-08-01 21:44:48.000000000 -0400 ++++ vnc_unixsrc/vncviewer/vncviewer.h 2009-10-23 11:27:05.000000000 -0400 @@ -28,6 +28,7 @@ #include #include @@ -18886,7 +19172,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncvi #define FLASH_PORT_OFFSET 5400 #define LISTEN_PORT_OFFSET 5500 -@@ -64,60 +71,124 @@ +@@ -64,60 +71,125 @@ #define DEFAULT_VIA_CMD \ (DEFAULT_SSH_CMD " -f -L %L:%H:%R %G sleep 20") @@ -18992,6 +19278,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncvi + + char *passwordFile; + Bool passwordDialog; ++ Bool notty; + + int rawDelay; + int copyRectDelay; @@ -19051,7 +19338,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncvi extern int listenPort, flashPort; extern XrmOptionDescRec cmdLineOptions[]; -@@ -130,10 +201,11 @@ +@@ -130,10 +202,11 @@ /* colour.c */ extern unsigned long BGR233ToPixel[]; @@ -19064,7 +19351,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncvi extern void SetVisualAndCmap(); -@@ -157,13 +229,52 @@ +@@ -157,13 +230,54 @@ extern void DesktopInitBeforeRealization(); extern void DesktopInitAfterRealization(); @@ -19086,6 +19373,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncvi + /* dialogs.c */ ++extern int use_tty(void); ++ +extern void ScaleDialogDone(Widget w, XEvent *event, String *params, + Cardinal *num_params); +extern char *DoScaleDialog(); @@ -19117,7 +19406,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncvi extern void ServerDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params); extern char *DoServerDialog(); -@@ -171,6 +282,10 @@ +@@ -171,6 +285,10 @@ Cardinal *num_params); extern char *DoPasswordDialog(); @@ -19128,7 +19417,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncvi /* fullscreen.c */ extern void ToggleFullScreen(Widget w, XEvent *event, String *params, -@@ -181,6 +296,13 @@ +@@ -181,6 +299,13 @@ extern void FullScreenOn(); extern void FullScreenOff(); @@ -19142,7 +19431,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncvi /* listen.c */ extern void listenForIncomingConnections(); -@@ -196,6 +318,8 @@ +@@ -196,6 +321,8 @@ Cardinal *num_params); extern void Quit(Widget w, XEvent *event, String *params, Cardinal *num_params); @@ -19151,7 +19440,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncvi extern void Cleanup(); /* popup.c */ -@@ -207,6 +331,29 @@ +@@ -207,6 +334,29 @@ Cardinal *num_params); extern void CreatePopup(); @@ -19181,7 +19470,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncvi /* rfbproto.c */ extern int rfbsock; -@@ -229,8 +376,19 @@ +@@ -229,8 +379,19 @@ extern Bool SendClientCutText(char *str, int len); extern Bool HandleRFBServerMessage(); @@ -19201,7 +19490,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncvi /* selection.c */ extern void InitialiseSelection(); -@@ -241,8 +399,9 @@ +@@ -241,8 +402,9 @@ /* shm.c */ @@ -19212,7 +19501,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncvi /* sockets.c */ -@@ -253,10 +412,15 @@ +@@ -253,10 +415,15 @@ extern int FindFreeTcpPort(void); extern int ListenAtTcpPort(int port); extern int ConnectToTcpAddr(unsigned int host, int port); @@ -19228,7 +19517,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncvi extern Bool SameMachine(int sock); /* tunnel.c */ -@@ -271,3 +435,80 @@ +@@ -271,3 +438,82 @@ extern XtAppContext appContext; extern Display* dpy; extern Widget toplevel; @@ -19244,6 +19533,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncvi +extern void Toggle8Colors(Widget w, XEvent *ev, String *params, Cardinal *num_params); +extern void ToggleGreyScale(Widget w, XEvent *ev, String *params, Cardinal *num_params); +extern void ToggleTightZRLE(Widget w, XEvent *ev, String *params, Cardinal *num_params); ++extern void ToggleTightHextile(Widget w, XEvent *ev, String *params, Cardinal *num_params); +extern void ToggleZRLEZYWRLE(Widget w, XEvent *ev, String *params, Cardinal *num_params); +extern void ToggleViewOnly(Widget w, XEvent *ev, String *params, Cardinal *num_params); +extern void ToggleJPEG(Widget w, XEvent *ev, String *params, Cardinal *num_params); @@ -19293,6 +19583,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncvi +extern void Set8ColorsState(Widget w, XEvent *ev, String *params, Cardinal *num_params); +extern void SetGreyScaleState(Widget w, XEvent *ev, String *params, Cardinal *num_params); +extern void SetZRLEState(Widget w, XEvent *ev, String *params, Cardinal *num_params); ++extern void SetHextileState(Widget w, XEvent *ev, String *params, Cardinal *num_params); +extern void SetZYWRLEState(Widget w, XEvent *ev, String *params, Cardinal *num_params); +extern void SetCursorShapeState(Widget w, XEvent *ev, String *params, Cardinal *num_params); +extern void SetCursorAlphaState(Widget w, XEvent *ev, String *params, Cardinal *num_params); @@ -19311,7 +19602,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncvi +extern void SetEscapeKeysState(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 2009-10-03 12:28:09.000000000 -0400 ++++ vnc_unixsrc/vncviewer/vncviewer.man 2009-10-23 12:24:51.000000000 -0400 @@ -5,38 +5,55 @@ .\" Copyright (C) 1998 Marcus.Brinkmann@ruhr-uni-bochum.de .\" Copyright (C) 2000,2001 Red Hat, Inc. @@ -19376,7 +19667,28 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.man vnc_unixsrc/vnc 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 +185,388 @@ +@@ -102,13 +119,13 @@ + 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. ++thus be enclosed in quotes if more than one is specified. Commas may be used to avoid spaces. ++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 +@@ -168,6 +185,394 @@ \fB\-autopass\fR Read a plain-text password from stdin. This option affects only the standard VNC authentication. @@ -19507,6 +19819,11 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.man vnc_unixsrc/vnc +Prefer raw encoding for localhost, default is +no, i.e. assumes you have a SSH tunnel instead. +.TP ++\fB\-notty\fR ++Try to avoid using the terminal for interactive ++responses: use windows for messages and prompting ++instead. Messages will also be printed to terminal. ++.TP +\fB\-sendclipboard\fR +Send the X CLIPBOARD selection (i.e. Ctrl+C, +Ctrl+V) instead of the X PRIMARY selection (mouse @@ -19725,7 +20042,8 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.man vnc_unixsrc/vnc + Cursor Shape: ~ -nocursorshape + X11 Cursor: ~ -x11cursor + Cursor Alphablend: ~ -alpha -+ Toggle Tight/ZRLE: ~ -encodings ... ++ Toggle Tight/Hextile: ~ -encodings hextile... ++ Toggle Tight/ZRLE: ~ -encodings zrle... + Toggle ZRLE/ZYWRLE: ~ -encodings zywrle... + Quality Level ~ -quality (both Tight and ZYWRLE) + Compress Level ~ -compresslevel @@ -19765,7 +20083,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.man vnc_unixsrc/vnc .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 +637,15 @@ +@@ -238,6 +643,15 @@ \-quality and \-nojpeg options above). Tight encoding is usually the best choice for low\-bandwidth network environments (e.g. slow modem connections). @@ -19781,7 +20099,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.man vnc_unixsrc/vnc .SH RESOURCES X resources that \fBvncviewer\fR knows about, aside from the normal Xt resources, are as follows: -@@ -364,12 +772,13 @@ +@@ -364,12 +778,13 @@ .B %R remote TCP port number. .SH SEE ALSO @@ -19798,7 +20116,7 @@ diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.man vnc_unixsrc/vnc \fBMan page authors:\fR .br -@@ -380,3 +789,5 @@ +@@ -380,3 +795,5 @@ Tim Waugh , .br Constantin Kaplinsky