diff options
author | runge <runge> | 2007-10-27 23:55:04 +0000 |
---|---|---|
committer | runge <runge> | 2007-10-27 23:55:04 +0000 |
commit | e24cf9491ccf696bc6b1ac36574861a343408cd0 (patch) | |
tree | 0f1ac51402fb4a74cadf7730fea998dc9c8bf51b /x11vnc | |
parent | ecbd1a49027ce3e617b254734a1d980762f6d07f (diff) | |
download | libvncserver-e24cf9491ccf696bc6b1ac36574861a343408cd0.zip libvncserver-e24cf9491ccf696bc6b1ac36574861a343408cd0.tar.gz |
ssvnc sync: connect_br.tcl socks4/5 http proxies, ss_vncviewer socks5 proxy. ssh 1st proxy. whatismyip.com fix. 127.0.0.1 on Darwin
Diffstat (limited to 'x11vnc')
4 files changed, 1457 insertions, 513 deletions
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 a023c1f..a20b6bf 100755 --- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl +++ b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl @@ -1,57 +1,4 @@ #!/usr/bin/wish - -global env - -set proxy1 "" -set proxy2 "" -set client_fh "" -set server_fh "" - -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" - } -} - -set dest $env(SSVNC_DEST) - -if [regexp {,} $env(SSVNC_PROXY)] { - set s [split $env(SSVNC_PROXY) ","] - set proxy1 [lindex $s 0] - set proxy2 [lindex $s 1] -} else { - set proxy1 $env(SSVNC_PROXY) -} - -set s [split $proxy1 ":"] -set proxy1_host [lindex $s 0] -set proxy1_port [lindex $s 1] - -if {$proxy2 != ""} { - set s [split $proxy2 ":"] - set proxy2_host [lindex $s 0] - set proxy2_port [lindex $s 1] -} - -set lport $env(SSVNC_LISTEN) - -set got_connection 0 -set lsock [socket -myaddr 127.0.0.1 -server handle_connection $lport] - -if {1} { - wm withdraw . -} -button .b -text "CONNECT_BR" -command {destroy .} -pack .b -after 1000 check_callback - proc check_callback {} { global debug if {$debug} { @@ -61,41 +8,40 @@ proc check_callback {} { after 1000 check_callback } +proc getout {} { + global client_fh server_fh + + set delay 50 + catch {flush $client_fh} + after $delay + catch {close $client_fh} + after $delay + catch {flush $server_fh} + after $delay + catch {close $server_fh} + after $delay + destroy . + exit +} + proc check_closed {} { - global client_fh server_fh debug - global got_connection + global got_connection debug + global client_fh server_fh if {! $got_connection} { return } - set delay 100 if {$client_fh != "" && [eof $client_fh]} { if {$debug} { puts stderr "client_fh EOF" } - catch {flush $client_fh} - after $delay - catch {close $client_fh} - after $delay - catch {flush $server_fh} - after $delay - catch {close $server_fh} - destroy . - exit + getout } if {$server_fh != "" && [eof $server_fh]} { if {$debug} { puts stderr "server_fh EOF" } - catch {flush $server_fh} - after $delay - catch {close $server_fh} - after $delay - catch {flush $client_fh} - after $delay - catch {close $client_fh} - destroy . - exit + getout } } @@ -106,7 +52,7 @@ proc xfer_in_to_out {} { if {$debug} { puts stderr "xfer_in_to_out: $str" } - if {$server_fh != ""} { + if {$server_fh != "" && $str != ""} { puts -nonewline $server_fh $str flush $server_fh } @@ -121,7 +67,7 @@ proc xfer_out_to_in {} { if {$debug} { puts stderr "xfer_out_to_in: $str" } - if {$client_fh != ""} { + if {$client_fh != "" && $str != ""} { puts -nonewline $client_fh $str flush $client_fh } @@ -129,42 +75,14 @@ proc xfer_out_to_in {} { check_closed } -proc handle_connection {fh host port} { - global proxy1_host proxy1_port - global proxy2_host proxy2_port - global proxy1 proxy2 - global dest - global debug - global got_connection - - if {$got_connection} { - catch {close $fh} - return - } - set got_connection 1 - - if {$debug} { - puts stderr "connection from: $host $port" - puts stderr "socket $proxy1_host $proxy1_port" - } - - set sock [socket $proxy1_host $proxy1_port] - - global client_fh server_fh - set client_fh $fh - set server_fh $sock - - fconfigure $fh -translation binary -blocking 0 - fconfigure $sock -translation binary -blocking 0 - +proc do_connect_http {sock hostport which} { + global debug cur_proxy set con "" - if {$proxy2 != ""} { - append con "CONNECT $proxy2 HTTP/1.1\r\n" - append con "Host: $proxy2\r\n\r\n" - } else { - append con "CONNECT $dest HTTP/1.1\r\n" - append con "Host: $dest\r\n\r\n" - } + append con "CONNECT $hostport HTTP/1.1\r\n" + append con "Host: $hostport\r\n" + append con "Connection: close\r\n\r\n" + + puts stderr "pxy=$which CONNECT $hostport HTTP/1.1 via $cur_proxy" puts -nonewline $sock $con flush $sock @@ -172,68 +90,413 @@ proc handle_connection {fh host port} { set r "" set cnt 0 while {1} { + incr cnt set c [read $sock 1] if {$c == ""} { check_closed after 20 } - incr cnt - if {$debug} { - .b configure -text "A $cnt -- $c" - update - } append r $c if {[regexp "\r\n\r\n" $r] || [regexp "a--no--\n\n" $r]} { break } - if {$cnt > 3000} { + if {$cnt > 30000} { break } } if {! [regexp {HTTP/.* 200} $r]} { puts stderr "did not find HTTP 200 #1" - if {1} { - destroy . - exit 1 + destroy . + exit 1 + } +} + +proc do_connect_socks4 {sock hostport which} { + global debug cur_proxy + + set s [split $hostport ":"] + set host [lindex $s 0] + set port [lindex $s 1] + + set i1 "" + set i2 "" + set i3 "" + set i4 "" + + set socks4a 0 + + if {$host == "localhost" || $host == "127.0.0.1"} { + set i1 127 + set i2 0 + set i3 0 + set i4 1 + + } elseif [regexp {^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$} $host] { + set n [split $host "."] + set i1 [lindex $n 0] + set i2 [lindex $n 1] + set i3 [lindex $n 2] + set i4 [lindex $n 3] + } else { + set i1 0 + set i2 0 + set i3 0 + set i4 3 + + set socks4a 1 + } + + if {$socks4a} { + puts stderr "pxy=$which socks4a connection to $host:$port via $cur_proxy" + } else { + puts stderr "pxy=$which socks4 connection to $host:$port via $cur_proxy" + } + + set p1 [binary format ccScccc 4 1 $port $i1 $i2 $i3 $i4] + set p2 "nobody" + set p3 [binary format c 0] + + puts -nonewline $sock $p1 + puts -nonewline $sock $p2 + puts -nonewline $sock $p3 + if {$socks4a} { + puts -nonewline $sock $host + puts -nonewline $sock $p3 + } + flush $sock + + set r ""; set s ""; set i 0; set cnt 0 + set ok 1 + while {$cnt < 30000 && $i < 8} { + incr cnt + set c [read $sock 1] + if {$c == ""} { + check_closed + after 20 + continue + } + + binary scan $c c s + if {$i == 0 && $s != 0} { + puts stderr "socks4: $i - $s" + set ok 0 } + if {$i == 1 && $s != 90} { + puts stderr "socks4: $i - $s" + set ok 0 + } + set r "$r,$s" + incr i + } + if {! $ok} { + puts stderr "socks4 failure: $r" + destroy . + exit 1 } +} - if {$proxy2 != ""} { - set con "" - append con "CONNECT $dest HTTP/1.1\r\n" - append con "Host: $dest\r\n\r\n" +proc do_connect_socks5 {sock hostport which} { + global debug cur_proxy - puts -nonewline $sock $con - flush $sock + set s [split $hostport ":"] + set host [lindex $s 0] + set port [lindex $s 1] + + set p1 [binary format ccc 5 1 0] + puts -nonewline $sock $p1 + flush $sock + + set r ""; set s ""; set i 0; set cnt 0 + set ok 1 + while {$cnt < 30000 && $i < 2} { + incr cnt + set c [read $sock 1] + if {$c == ""} { + check_closed + after 20 + continue + } + + binary scan $c c s + if {$i == 0 && $s != 5} { + puts stderr "$i - $s" + set ok 0 + } + if {$i == 1 && $s != 0} { + puts stderr "$i - $s" + set ok 0 + } + set r "$r,$s" + incr i + } + if {! $ok} { + puts stderr "socks5 failure: $r" + destroy . + exit 1 + } - set r "" - set cnt 0 - while {1} { + set len [string length $host] + set p1 [binary format ccccc 5 1 0 3 $len] + set p2 $host + + set n1 [expr int($port/256)] + set n2 [expr "$port - $n1 * 256"] + set p3 [binary format cc $n1 $n2] + + puts stderr "pxy=$which socks5 connection to $host:$port via $cur_proxy" + + puts -nonewline $sock $p1 + puts -nonewline $sock $p2 + puts -nonewline $sock $p3 + flush $sock + + set i1 ""; set i2 ""; set i3 ""; set i4 "" + set r ""; set s ""; set i 0; set cnt 0 + set ok 1 + while {$cnt < 30000 && $i < 4} { + incr cnt + set c [read $sock 1] + if {$c == ""} { + check_closed + after 20 + continue + } + + binary scan $c c s + if {$i == 0} { + set i1 $s + } elseif {$i == 1} { + set i2 $s + } elseif {$i == 2} { + set i3 $s + } elseif {$i == 3} { + set i4 $s + } + incr i + } + set r "i1=$i1,i2=$i2,i3=$i3,i4=$i4" + + if {$i4 == 1} { + set n 6 + } elseif {$i4 == 3} { + set c "" + for {set i 0} {$i < 1000} {incr i} { set c [read $sock 1] if {$c == ""} { check_closed after 20 + continue } - incr cnt - if {$debug} { - .b configure -text "B $cnt -- $c" - update - } - append r $c - if {[regexp "\r\n\r\n" $r] || [regexp "a--no--\n\n" $r]} { - break - } - if {$cnt > 3000} { - break - } + break; } - if {! [regexp {HTTP/.* 200} $r]} { - puts stderr "did not find HTTP 200 #2" + if {$c == ""} { + puts stderr "socks5 failure c: $r" destroy . exit 1 } + binary scan $c c s + set n [expr $s + 2] + } elseif {$i4 == 4} { + set n 18 + } else { + puts stderr "socks5 failure x: $r" + destroy . + exit 1 } + #puts "n=$n --- $r" + + set i 0; set cnt 0 + while {$cnt < 30000 && $i < $n} { + incr cnt + set c [read $sock 1] + if {$c == ""} { + check_closed + after 20 + continue + } + incr i + } + if {$i1 != 5 || $i2 != 0 || $i3 != 0} { + puts stderr "socks failure $r" + destroy . + exit 1 + } +} + +proc do_connect {sock type hostport which} { + if {$type == "http"} { + do_connect_http $sock $hostport $which + } elseif {$type == "socks"} { + do_connect_socks4 $sock $hostport $which + } elseif {$type == "socks5"} { + do_connect_socks5 $sock $hostport $which + } +} + +proc handle_connection {fh host port} { + global proxy1_host proxy1_port proxy1_type + global proxy2_host proxy2_port proxy2_type + global proxy3_host proxy3_port proxy3_type + global proxy1 proxy2 proxy3 dest + global debug cur_proxy + global got_connection + + if {$got_connection} { + catch {close $fh} + return + } + set got_connection 1 + + if {$debug} { + puts stderr "connection from: $host $port" + puts stderr "socket $proxy1_host $proxy1_port" + } + + set rc [catch {set sock [socket $proxy1_host $proxy1_port]}] + if {$rc != 0} { + puts stderr "error connecting" + catch {close $sock} + destroy . + exit + } + + if {$debug} { + puts stderr "got sock: $sock" + } + + global client_fh server_fh + set client_fh $fh + set server_fh $sock + + 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 1 + + set cur_proxy $proxy2 + if {$proxy3 != ""} { + do_connect $sock $proxy2_type $proxy3 2 + + set cur_proxy $proxy3 + do_connect $sock $proxy3_type $dest 3 + + } else { + do_connect $sock $proxy2_type $dest 2 + } + } else { + do_connect $sock $proxy1_type $dest 1 + } } + +proc proxy_type {proxy} { + if [regexp -nocase {^socks://} $proxy] { + return "socks" + } elseif [regexp -nocase {^socks4://} $proxy] { + return "socks" + } elseif [regexp -nocase {^socks4a://} $proxy] { + return "socks" + } elseif [regexp -nocase {^socks5://} $proxy] { + return "socks5" + } elseif [regexp -nocase {^http://} $proxy] { + return "http" + } elseif [regexp -nocase {^https://} $proxy] { + return "http" + } else { + return "http" + } +} + +global env + +set proxy1 "" +set proxy2 "" +set proxy3 "" +set client_fh "" +set server_fh "" + +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)]} { + destroy .; exit; + } +} + +set dest $env(SSVNC_DEST) + +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 proxy1_type [proxy_type $proxy1] +regsub {^[A-z0-9][A-z0-9]*://} $proxy1 "" proxy1 + +set s [split $proxy1 ":"] +set proxy1_host [lindex $s 0] +set proxy1_port [lindex $s 1] + +set proxy2_type "" +set proxy2_host "" +set proxy2_port "" + +set proxy3_type "" +set proxy3_host "" +set proxy3_port "" + +if {$proxy2 != ""} { + set proxy2_type [proxy_type $proxy2] + regsub {^[A-z0-9][A-z0-9]*://} $proxy2 "" proxy2 + set s [split $proxy2 ":"] + set proxy2_host [lindex $s 0] + set proxy2_port [lindex $s 1] +} + +if {$proxy3 != ""} { + set proxy3_type [proxy_type $proxy3] + regsub {^[A-z0-9][A-z0-9]*://} $proxy3 "" proxy3 + set s [split $proxy3 ":"] + set proxy3_host [lindex $s 0] + set proxy3_port [lindex $s 1] +} + +set lport $env(SSVNC_LISTEN) + +set got_connection 0 +set rc [catch {set lsock [socket -myaddr 127.0.0.1 -server handle_connection $lport]}] +if {$rc != 0} { + puts stderr "error listening" + destroy . + exit +} + +if {1} { + wm withdraw . +} +button .b -text "CONNECT_BR" -command {destroy .} +pack .b +after 1000 check_callback diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer b/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer index a7b8073..7bf11a7 100755 --- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer +++ b/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer @@ -38,6 +38,9 @@ # (the first CONNECT is done through host1:port1 to host2:port2 # and then a 2nd CONNECT to the destination VNC server.) # +# Use socks://host:port, socks4://host:port, or socks5://host,port +# to force usage of a SOCKS proxy. +# # -showcert Only fetch the certificate using the 'openssl s_client' # command (openssl(1) must in installed). # @@ -46,6 +49,8 @@ # # A few other args (not related to SSL and certs): # +# -2nd Run the vncviewer a 2nd time if the first connections fails. +# # -ssh Use ssh instead of stunnel SSL. ssh(1) must be installed and you # must be able to log into the remote machine via ssh. # @@ -112,12 +117,14 @@ VNCVIEWERCMD=${VNCVIEWERCMD:-vncviewer} # Same for STUNNEL, e.g. set it to /path/to/stunnel or stunnel4, etc. # +# turn on verbose debugging output if [ "X$SS_DEBUG" != "X" ]; then set -xv fi PATH=$PATH:/usr/sbin:/usr/local/sbin:/dist/sbin; export PATH +# work out which stunnel t use (debian installs as stunnel4) if [ "X$STUNNEL" = "X" ]; then type stunnel4 > /dev/null 2>&1 if [ $? = 0 ]; then @@ -131,23 +138,32 @@ help() { tail -n +2 "$0" | sed -e '/^$/ q' } +secondtry="" gotalpha="" use_ssh="" use_sshssl="" direct_connect="" ssh_sleep=15 + +# sleep longer in -listen mode: if echo "$*" | grep '.*-listen' > /dev/null; then ssh_sleep=1800 fi + + ssh_cmd="" +# env override of ssh_cmd: if [ "X$SS_VNCVIEWER_SSH_CMD" != "X" ]; then ssh_cmd="$SS_VNCVIEWER_SSH_CMD" fi + ssh_args="" showcert="" reverse="" if [ "X$1" = "X-viewerflavor" ]; then + # special case, try to guess which viewer: + # if echo "$VNCVIEWERCMD" | egrep -i '^(xmessage|sleep )' > /dev/null; then echo "unknown" exit 0 @@ -160,6 +176,7 @@ if [ "X$1" = "X-viewerflavor" ]; then echo "ultravnc" exit 0 fi + # OK, run it for help output... str=`$VNCVIEWERCMD -h 2>&1 | head -n 5` if echo "$str" | grep -i 'TightVNC.viewer' > /dev/null; then echo "tightvnc" @@ -173,6 +190,7 @@ if [ "X$1" = "X-viewerflavor" ]; then exit 0 fi +# maxconn is something we added to stunnel, this disables it: if [ "X$SS_VNCVIEWER_NO_MAXCONN" != "X" ]; then STUNNEL_EXTRA_OPTS=`echo "$STUNNEL_EXTRA_OPTS" | sed -e 's/maxconn/#maxconn/'` elif echo "$VNCVIEWERCMD" | egrep -i '^(xmessage|sleep )' > /dev/null; then @@ -206,6 +224,8 @@ do ;; "-reverse") reverse=1 ;; + "-2nd") secondtry=1 + ;; "-grab") VNCVIEWER_GRAB_SERVER=1; export VNCVIEWER_GRAB_SERVER ;; "-h"*) help; exit 0 @@ -218,11 +238,13 @@ do shift done +# this is the -t ssh option (gives better keyboard responsd thru SSH tunnel) targ="-t" if [ "X$SS_VNCVIEWER_NO_T" != "X" ]; then targ="" fi +# set the alpha blending env. hack: if [ "X$gotalpha" = "X1" ]; then VNCVIEWER_ALPHABLEND=1 export VNCVIEWER_ALPHABLEND @@ -230,9 +252,11 @@ else NO_ALPHABLEND=1 export NO_ALPHABLEND fi + if [ "X$reverse" != "X" ]; then ssh_sleep=1800 if [ "X$proxy" != "X" ]; then + # check proxy usage under reverse connection: if [ "X$use_ssh" = "X" -a "X$use_sshssl" = "X" ]; then echo "" echo "*Warning*: SSL -listen and a Web proxy does not make sense." @@ -247,12 +271,16 @@ if [ "X$reverse" != "X" ]; then fi fi if [ "X$ssh_cmd" = "X" ]; then + # if no remote ssh cmd, sleep a bit: ssh_cmd="sleep $ssh_sleep" fi +# this should be a host:display: +# orig="$1" shift +# check -ssh and -mycert/-verify conflict: if [ "X$use_ssh" = "X1" -a "X$use_sshssl" = "X" ]; then if [ "X$mycert" != "X" -o "X$verify" != "X" ]; then echo "-mycert and -verify cannot be used in -ssh mode" @@ -260,12 +288,15 @@ if [ "X$use_ssh" = "X1" -a "X$use_sshssl" = "X" ]; then fi fi +# direct mode Vnc:// means show no warnings. +# direct mode vnc:// will show warnings. if echo "$orig" | grep '^V[Nn][Cc]://' > /dev/null; then SSVNC_NO_ENC_WARN=1 export SSVNC_NO_ENC_WARN orig=`echo "$orig" | sed -e 's/^...:/vnc:/'` fi +# interprest the pseudo URL proto:// strings: if echo "$orig" | grep '^vnc://' > /dev/null; then orig=`echo "$orig" | sed -e 's,vnc://,,'` verify="" @@ -286,11 +317,14 @@ elif echo "$orig" | grep '^vnc+ssh://' > /dev/null; then orig=`echo "$orig" | sed -e 's,vnc.ssh://,,'` use_ssh=1 fi + +# (possibly) tell the vncviewer to only listen on lo: if [ "X$reverse" != "X" -a "X$direct_connect" = "X" ]; then VNCVIEWER_LISTEN_LOCALHOST=1 export VNCVIEWER_LISTEN_LOCALHOST fi +# rsh mode is an internal/secret thing only I use. rsh="" if echo "$orig" | grep '^rsh://' > /dev/null; then use_ssh=1 @@ -302,11 +336,11 @@ elif echo "$orig" | grep '^rsh:' > /dev/null; then orig=`echo "$orig" | sed -e 's,rsh:,,'` fi - # play around with host:display port: if echo "$orig" | grep ':' > /dev/null; then : else + # add or assume :0 if no ':' if [ "X$reverse" = "X" ]; then orig="$orig:0" elif [ "X$orig" = "X" ]; then @@ -314,20 +348,24 @@ else fi fi +# extract host and disp number: host=`echo "$orig" | awk -F: '{print $1}'` disp=`echo "$orig" | awk -F: '{print $2}'` if [ "X$host" = "X" ]; then host=localhost fi if [ $disp -lt 0 ]; then + # negative means use |n| without question: port=`expr 0 - $disp` elif [ $disp -lt 200 ]; then + # less than 200 means 5900+n if [ "X$reverse" = "X" ]; then port=`expr $disp + 5900` else port=`expr $disp + 5500` fi else + # otherwise use the number directly, e.g. 443, 2345 port=$disp fi @@ -342,8 +380,11 @@ elif uname | grep -i bsd > /dev/null; then # add others... fi +# this is a crude attempt for unique ports tags, etc. date_sec=`date +%S` +# these are special cases of no vnc, e.g. sleep or xmessage. +# these are for using ssvnc as a general port redirector. if echo "$VNCVIEWERCMD" | grep '^sleep[ ][ ]*[0-9][0-9]*' > /dev/null; then if [ "X$SS_VNCVIEWER_LISTEN_PORT" = "X" ]; then p=`echo "$VNCVIEWERCMD" | awk '{print $3}'` @@ -360,6 +401,7 @@ elif echo "$VNCVIEWERCMD" | grep '^xmessage[ ][ ]*[0-9][0-9]*' > /dev/null; th fi fi +# utility to find a free port to listen on. findfree() { try0=$1 try=$try0 @@ -369,8 +411,13 @@ findfree() { echo "$SS_VNCVIEWER_LISTEN_PORT" return fi + if [ $try -ge 6000 ]; then + fmax=`expr $try + 1000` + else + fmax=6000 + fi - while [ $try -lt 6000 ] + while [ $try -lt $fmax ] do if [ "X$inuse" = "X" ]; then break @@ -390,6 +437,8 @@ findfree() { echo $use0 } +# utility for exiting; kills some helper processes, +# removes files, etc. final() { echo "" if [ "X$SS_VNCVIEWER_RM" != "X" ]; then @@ -420,6 +469,7 @@ final() { } if [ "X$reverse" = "X" ]; then + # normal connections try 5930-5999: use=`findfree 5930` if [ $use -ge 5900 ]; then N=`expr $use - 5900` @@ -427,6 +477,7 @@ if [ "X$reverse" = "X" ]; then N=$use fi else + # reverse connections: p2=`expr $port + 30` use=`findfree $p2` if [ $use -ge 5500 ]; then @@ -436,17 +487,20 @@ else fi fi +# this is for my special use of ss_vncip -> vncip viewer. if echo "$0" | grep vncip > /dev/null; then VNCVIEWERCMD="$VNCIPCMD" fi rchk() { + # a kludge to set $RANDOM if we are not bash: if [ "X$BASH_VERSION" = "X" ]; then RANDOM=`date +%S``sh -c 'echo $$'``ps -elf 2>&1 | sum 2>&1 | awk '{print $1}'` fi } rchk +# a portable, but not absolutely safe, tmp file creator mytmp() { tf=$1 rm -rf "$tf" || exit 1 @@ -465,6 +519,7 @@ mytmp() { rchk } +# trick for the undocumented rsh://host:port method. rsh_setup() { if echo "$ssh_host" | grep '@' > /dev/null; then ul=`echo "$ssh_host" | awk -F@ '{print $1}'` @@ -476,6 +531,7 @@ rsh_setup() { ssh_cmd=`echo "$ssh_cmd" | sed -e 's/ -localhost/ /g'` } +# trick for the undocumented rsh://host:port method. rsh_viewer() { trap "final" 0 2 15 if [ "X$PORT" = "X" ]; then @@ -489,22 +545,505 @@ rsh_viewer() { echo "$VNCVIEWERCMD" "$@" $ssh_host:$vdpy echo "" $VNCVIEWERCMD "$@" $ssh_host:$vdpy + if [ $? != 0 ]; then + sleep 2 + $VNCVIEWERCMD "$@" $ssh_host:$vdpy + fi +} + +# this is the PPROXY tool. used only here for now... +pcode() { + tf=$1 + PPROXY_PROXY=$proxy; export PPROXY_PROXY + PPROXY_DEST="$host:$port"; export PPROXY_DEST + cod='#!/usr/bin/perl + +# A hack to glue stunnel to a Web proxy or SOCKS for client connections. + +use IO::Socket::INET; + +my ($first, $second, $third) = split(/,/, $ENV{PPROXY_PROXY}, 3); + +if ($first =~ m,^socks4?://(\S*)$,i) { + $ENV{PPROXY_SOCKS} = 1; + $first = $1; +} elsif ($first =~ m,^socks5://(\S*)$,i) { + $ENV{PPROXY_SOCKS} = 5; + $first = $1; +} elsif ($first =~ m,^https?://(\S*)$,i) { + $ENV{PPROXY_SOCKS} = ""; + $first = $1; +} + +my ($proxy_host, $proxy_port) = split(/:/, $first); +my $connect = $ENV{PPROXY_DEST}; + +my $mode_2nd = ""; +if ($second ne "") { + if ($second =~ m,^socks4?://(\S*)$,i) { + $mode_2nd = "socks4"; + $second = $1; + } elsif ($second =~ m,^socks5://(\S*)$,i) { + $mode_2nd = "socks5"; + $second = $1; + } elsif ($second =~ m,^https?://(\S*)$,i) { + $mode_2nd = "http"; + $second = $1; + } +} + +my $mode_3rd = ""; +if ($third ne "") { + if ($third =~ m,^socks4?://(\S*)$,i) { + $mode_3rd = "socks4"; + $third = $1; + } elsif ($third =~ m,^socks5://(\S*)$,i) { + $mode_3rd = "socks5"; + $third = $1; + } elsif ($third =~ m,^https?://(\S*)$,i) { + $mode_3rd = "http"; + $third = $1; + } +} + +print STDERR "\n"; +print STDERR "PPROXY v0.2: a tool for Web proxies and SOCKS connections.\n"; +print STDERR "proxy_host: $proxy_host\n"; +print STDERR "proxy_port: $proxy_port\n"; +print STDERR "proxy_connect: $connect\n"; +print STDERR "pproxy_params: $ENV{PPROXY_PROXY}\n"; +print STDERR "pproxy_listen: $ENV{PPROXY_LISTEN}\n"; +print STDERR "\n"; + +my $listen_handle = ""; +if ($ENV{PPROXY_LISTEN} != "") { + my $listen_sock = IO::Socket::INET->new( + Listen => 2, + LocalAddr => "localhost", + LocalPort => $ENV{PPROXY_LISTEN}, + Proto => "tcp" + ); + if (! $listen_sock) { + die "pproxy: $!\n"; + } + my $ip; + ($listen_handle, $ip) = $listen_sock->accept(); + if (! $listen_handle) { + die "pproxy: $!\n"; + } +} + +my $sock = IO::Socket::INET->new( + PeerAddr => $proxy_host, + PeerPort => $proxy_port, + Proto => "tcp" +); + +if (! $sock) { + my $err = $!; + unlink($0) if $ENV{PPROXY_REMOVE}; + die "pproxy: $err\n"; +} + +sub connection { + my ($CONNECT, $w) = @_; + + my $con = ""; + my $msg = ""; + + if ($ENV{PPROXY_SOCKS} eq "5") { + # SOCKS5 + my ($h, $p) = split(/:/, $CONNECT); + $con .= pack("C", 0x05); + $con .= pack("C", 0x01); + $con .= pack("C", 0x00); + + $msg = "SOCKS5 via $cur_proxy to $h:$p\n\n"; + print STDERR "proxy_request$w: $msg"; + + syswrite($sock, $con, length($con)); + + my ($n1, $n2, $n3, $n4, $n5, $n6); + my ($r1, $r2, $r3, $r4, $r5, $r6); + my ($s1, $s2, $s3, $s4, $s5, $s6); + + $n1 = sysread($sock, $r1, 1); + $n2 = sysread($sock, $r2, 1); + + $s1 = unpack("C", $r1); + $s2 = unpack("C", $r2); + if ($s1 != 0x05 || $s2 != 0x00) { + print STDERR "SOCKS5 fail s1=$s1 s2=$s2 n1=$n1 n2=$n2\n"; + close $sock; + exit(1); + } + + $con = ""; + $con .= pack("C", 0x05); + $con .= pack("C", 0x01); + $con .= pack("C", 0x00); + $con .= pack("C", 0x03); + $con .= pack("C", length($h)); + $con .= $h; + $con .= pack("C", $p >> 8); + $con .= pack("C", $p & 0xff); + + syswrite($sock, $con, length($con)); + + $n1 = sysread($sock, $r1, 1); + $n2 = sysread($sock, $r2, 1); + $n3 = sysread($sock, $r3, 1); + $n4 = sysread($sock, $r4, 1); + $s1 = unpack("C", $r1); + $s2 = unpack("C", $r2); + $s3 = unpack("C", $r3); + $s4 = unpack("C", $r4); + + if ($s4 == 0x1) { + sysread($sock, $r5, 4 + 2); + } elsif ($s4 == 0x3) { + sysread($sock, $r5, 1); + $s5 = unpack("C", $r5); + sysread($sock, $r6, $s5 + 2); + } elsif ($s4 == 0x4) { + sysread($sock, $r5, 16 + 2); + } + + if ($s1 != 0x5 || $s2 != 0x0 || $s3 != 0x0) { + print STDERR "SOCKS5 failed: s1=$s1 s2=$s2 s3=$s3 s4=$s4 n1=$n1 n2=$n2 n3=$n3 n4=$n4\n"; + close $sock; + exit(1); + } + + } elsif ($ENV{PPROXY_SOCKS} ne "") { + # SOCKS4 SOCKS4a + my ($h, $p) = split(/:/, $CONNECT); + $con .= pack("C", 0x04); + $con .= pack("C", 0x01); + $con .= pack("n", $p); + + my $SOCKS_4a = 0; + if ($h eq "localhost" || $h eq "127.0.0.1") { + $con .= pack("C", 127); + $con .= pack("C", 0); + $con .= pack("C", 0); + $con .= pack("C", 1); + } elsif ($h =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) { + $con .= pack("C", $1); + $con .= pack("C", $2); + $con .= pack("C", $3); + $con .= pack("C", $4); + } else { + $con .= pack("C", 0); + $con .= pack("C", 0); + $con .= pack("C", 0); + $con .= pack("C", 3); + $SOCKS_4a = 1; + } + + $con .= "nobody"; + $con .= pack("C", 0); + + $msg = "SOCKS4 via $cur_proxy to $h:$p\n\n"; + if ($SOCKS_4a) { + $con .= $h; + $con .= pack("C", 0); + $msg =~ s/SOCKS4/SOCKS4a/; + } + print STDERR "proxy_request$w: $msg"; + syswrite($sock, $con, length($con)); + + my $ok = 1; + for (my $i = 0; $i < 8; $i++) { + my $c; + sysread($sock, $c, 1); + my $s = unpack("C", $c); + if ($i == 0) { + $ok = 0 if $s != 0x0; + } elsif ($i == 1) { + $ok = 0 if $s != 0x5a; + } + } + if (! $ok) { + print STDERR "SOCKS4 failed.\n"; + close $sock; + exit(1); + } + + } else { + # Web Proxy: + $con = "CONNECT $CONNECT HTTP/1.1\r\n"; + $con .= "Host: $CONNECT\r\n"; + $con .= "Connection: close\r\n\r\n"; + $msg = $con; + + print STDERR "proxy_request$w: via $cur_proxy:\n$msg"; + syswrite($sock, $con, length($con)); + + my $rep = ""; + my $n = 0; + while ($rep !~ /\r\n\r\n/ && $n < 30000) { + my $c; + sysread($sock, $c, 1); + print STDERR $c; + $rep .= $c; + $n++; + } + if ($rep !~ m,HTTP/.* 200,) { + print STDERR "HTTP CONNECT failed.\n"; + close $sock; + exit(1); + } + } +} + +unlink($0) if $ENV{PPROXY_REMOVE}; + +$cur_proxy = $first; + +if ($second ne "") { + connection($second, 1); + + setmode($mode_2nd); + $cur_proxy = $second; + + if ($third ne "") { + connection($third, 2); + setmode($mode_3rd); + $cur_proxy = $third; + connection($connect, 3); + } else { + connection($connect, 2); + } +} else { + connection($connect, 1); +} + +$parent = $$; +$child = fork; +if (! defined $child) { + exit 1; +} + +if ($child) { + print STDERR "pproxy parent\[$$] STDIN -> socket\n"; + if ($listen_handle) { + xfer($listen_handle, $sock); + } else { + xfer(STDIN, $sock); + } + 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; + } +} else { + print STDERR "pproxy child \[$$] socket -> STDOUT\n"; + if ($listen_handle) { + xfer($sock, $listen_handle); + } 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; + } +} +exit; + +sub setmode { + my $mode = shift; + if ($mode =~ /^socks/) { + if ($mode =~ /^socks5/) { + $ENV{PPROXY_SOCKS} = 5; + } else { + $ENV{PPROXY_SOCKS} = 1; + } + } else { + $ENV{PPROXY_SOCKS} = ""; + } +} + +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; + } + close($in); + close($out); +} +' + echo "$cod" > $tf + chmod 700 $tf + # prime perl + perl -e 'use IO::Socket::INET; select(undef, undef, undef, 0.01)' >/dev/null 2>&1 +} + +Kecho() { + if [ "X$USER" = "Xrunge" ]; then + echo "dbg: $*" + fi } if [ "X$use_ssh" = "X1" ]; then + # + # USING SSH + # ssh_port="22" ssh_host="$host" vnc_host="localhost" + # let user override ssh via $SSH ssh=${SSH:-"ssh -x"} + 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 +Kecho port=$port + pproxy="" + sproxy1="" + sproxy_rest="" + for part in `echo "$proxy" | tr ',' ' '` + do + Kecho proxy_part=$part + if [ "X$part" = "X" ]; then + continue + elif echo "$part" | egrep -i '^(http|https|socks|socks4|socks5)://' > /dev/null; then + pproxy="$pproxy,$part" + else + if [ "X$sproxy1" = "X" ]; then + sproxy1="$part" + else + sproxy_rest="$sproxy_rest,$part" + fi + fi + done + pproxy=`echo "$pproxy" | sed -e 's/^,,*//' -e 's/,,*/,/g'` + sproxy_rest=`echo "$sproxy_rest" | sed -e 's/^,,*//' -e 's/,,*/,/g'` +Kecho pproxy=$pproxy +Kecho sproxy1=$sproxy1 +Kecho sproxy_rest=$sproxy_rest + + sproxy1_host="" + sproxy1_port="" + sproxy1_user="" + + if [ "X$sproxy1" != "X" ]; then + sproxy1_host=`echo "$sproxy1" | awk -F: '{print $1}'` + sproxy1_user=`echo "$sproxy1_host" | awk -F@ '{print $1}'` + sproxy1_host=`echo "$sproxy1_host" | awk -F@ '{print $2}'` + if [ "X$sproxy1_host" = "X" ]; then + sproxy1_host=$sproxy1_user + sproxy1_user="" + else + sproxy1_user="${sproxy1_user}@" + fi + sproxy1_port=`echo "$sproxy1" | awk -F: '{print $2}'` + if [ "X$sproxy1_port" = "X" ]; then + sproxy1_port="22" + fi + else + sproxy1_host=`echo "$host" | awk -F: '{print $1}'` + sproxy1_user=`echo "$sproxy1_host" | awk -F@ '{print $1}'` + sproxy1_host=`echo "$sproxy1_host" | awk -F@ '{print $2}'` + if [ "X$sproxy1_host" = "X" ]; then + sproxy1_host=$sproxy1_user + sproxy1_user="" + else + sproxy1_user="${sproxy1_user}@" + fi + sproxy1_port=`echo "$host" | awk -F: '{print $2}'` + if [ "X$sproxy1_port" = "X" ]; then + sproxy1_port="22" + fi + fi + +Kecho sproxy1_host=$sproxy1_host +Kecho sproxy1_port=$sproxy1_port +Kecho sproxy1_user=$sproxy1_user + + ptmp="/tmp/ss_vncviewer${RANDOM}.$$.pl" + mytmp "$ptmp" + PPROXY_REMOVE=1; export PPROXY_REMOVE + proxy=$pproxy + port_save=$port + host_save=$host + if [ "X$sproxy1_host" != "X" ]; then + host=$sproxy1_host + fi + if [ "X$sproxy1_port" != "X" ]; then + port=$sproxy1_port + fi + host=`echo "$host" | sed -e 's/^.*@//'` + port=`echo "$port" | sed -e 's/^.*://'` + pcode "$ptmp" + port=$port_save + host=$host_save + + nd=`findfree 6700` + PPROXY_LISTEN=$nd; export PPROXY_LISTEN + $ptmp & + sleep 2 + ssh_args="$ssh_args -o NoHostAuthenticationForLocalhost=yes" + if [ "X$sproxy1" = "X" ]; then + u="" + if echo "$host" | grep '@' > /dev/null; then + u=`echo "$host" | sed -e 's/@.*$/@/'` + fi + + proxy="${u}localhost:$nd" + else + proxy="${sproxy1_user}localhost:$nd" + fi + if [ "X$sproxy_rest" != "X" ]; then + proxy="$proxy,$sproxy_rest" + fi +Kecho proxy=$proxy + fi + if echo "$proxy" | grep "," > /dev/null; then + proxy1=`echo "$proxy" | awk -F, '{print $1}'` proxy2=`echo "$proxy" | awk -F, '{print $2}'` + # user1@gw1.com:port1,user2@ws2:port2 ssh_host1=`echo "$proxy1" | awk -F: '{print $1}'` ssh_port1=`echo "$proxy1" | awk -F: '{print $2}'` if [ "X$ssh_port1" != "X" ]; then - ssh_port1="-p 22" + ssh_port1="-p $ssh_port1" fi ssh_host2=`echo "$proxy2" | awk -F: '{print $1}'` ssh_user2=`echo "$ssh_host2" | awk -F@ '{print $1}'` @@ -522,8 +1061,9 @@ if [ "X$use_ssh" = "X1" ]; then proxport=`findfree 3500` echo echo "Running 1st ssh proxy:" - echo "$ssh -f -x $ssh_port1 $targ -e none -L $proxport:$ssh_host2:$ssh_port2 $ssh_host1 \"sleep 30\"" - $ssh -f -x $ssh_port1 $targ -e none -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\"" + 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" sleep 1 stty sane @@ -538,6 +1078,7 @@ if [ "X$use_ssh" = "X1" ]; then ssh_host=`echo "$proxy" | awk -F: '{print $1}'` vnc_host="$host" fi + echo "" echo "Running ssh:" sz=`echo "$ssh_cmd" | wc -c` @@ -632,8 +1173,16 @@ if [ "X$use_ssh" = "X1" ]; then stty sane i=0 - while [ $i -lt 10 ]; do - sleep 1 + if type perl > /dev/null 2>&1; then + imax=50 + sleepit="perl -e 'select(undef, undef, undef, 0.20)'" + else + imax=10 + sleepit="sleep 1" + fi + while [ $i -lt $imax ]; do + #echo $sleepit + eval $sleepit PORT=`grep "^PORT=" $tport | head -n 1 | sed -e 's/PORT=//' -e 's/\r//g'` if echo "$PORT" | grep '^[0-9][0-9]*$' > /dev/null; then break @@ -660,6 +1209,9 @@ if [ "X$use_ssh" = "X1" ]; then exit $? fi PPROXY_SOCKS=1 + if [ "X$SSVNC_SOCKS5" != "X" ]; then + PPROXY_SOCKS=5 + fi export PPROXY_SOCKS host="localhost" port="$PORT" @@ -704,13 +1256,19 @@ if [ "X$use_ssh" = "X1" ]; then if [ "X$getport" != "X" ]; then : elif [ "X$ssh_cmd" = "Xsleep $ssh_sleep" ] ; then + #echo T sleep 1 sleep 1 + elif echo "$ssh_cmd" | grep '^sleep ' >/dev/null; then + #echo T sleep 2 + sleep 2 else # let any command get started a bit. + #echo T sleep 5 sleep 5 fi echo "" if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then + #echo T sleep $SSVNC_EXTRA_SLEEP sleep $SSVNC_EXTRA_SLEEP fi #reset @@ -724,6 +1282,13 @@ if [ "X$use_ssh" = "X1" ]; then echo "$VNCVIEWERCMD" "$@" localhost:$N echo "" $VNCVIEWERCMD "$@" localhost:$N + if [ $? != 0 ]; then + echo "vncviewer command failed: $?" + if [ "X$secondtry" = "X1" ]; then + sleep 2 + $VNCVIEWERCMD "$@" localhost:$N + fi + fi else echo "" echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode." @@ -765,229 +1330,26 @@ if [ "X$mycert" != "X" ]; then cert="cert = $mycert" fi -pcode() { - tf=$1 - PPROXY_PROXY=$proxy; export PPROXY_PROXY - PPROXY_DEST="$host:$port"; export PPROXY_DEST - cod='#!/usr/bin/perl - -# A hack to glue stunnel to a Web proxy or SOCKS for client connections. - -use IO::Socket::INET; - -my ($first, $second) = split(/,/, $ENV{PPROXY_PROXY}); -my ($proxy_host, $proxy_port) = split(/:/, $first); -my $connect = $ENV{PPROXY_DEST}; - -print STDERR "PPROXY v0.1: a tool for Web proxies and SOCKS connections.\n"; -print STDERR "proxy_host: $proxy_host\n"; -print STDERR "proxy_port: $proxy_port\n"; -print STDERR "proxy_connect: $connect\n"; -print STDERR "pproxy_listen: $ENV{PPROXY_LISTEN}\n"; -print STDERR "\n"; - -my $listen_handle = ""; -if ($ENV{PPROXY_LISTEN} != "") { - my $listen_sock = IO::Socket::INET->new( - Listen => 2, - LocalAddr => "localhost", - LocalPort => $ENV{PPROXY_LISTEN}, - Proto => "tcp" - ); - if (! $listen_sock) { - die "pproxy: $!\n"; - } - my $ip; - ($listen_handle, $ip) = $listen_sock->accept(); - if (! $listen_handle) { - die "pproxy: $!\n"; - } -} - -my $sock = IO::Socket::INET->new( - PeerAddr => $proxy_host, - PeerPort => $proxy_port, - Proto => "tcp" -); - -if (! $sock) { - unlink($0); - die "pproxy: $!\n"; -} - -my $con = ""; -my $con0 = ""; -if ($ENV{PPROXY_SOCKS} ne "") { - $second = ""; - my ($h, $p) = split(/:/, $connect); - $con .= pack("C", 0x04); - $con .= pack("C", 0x01); - $con .= pack("n", $p); - - my $SOCKS_4a = 0; - if ($h eq "localhost" || $h eq "127.0.0.1") { - $con .= pack("C", 127); - $con .= pack("C", 0); - $con .= pack("C", 0); - $con .= pack("C", 1); - } elsif ($h =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) { - $con .= pack("C", $1); - $con .= pack("C", $2); - $con .= pack("C", $3); - $con .= pack("C", $4); - } else { - $con .= pack("C", 0); - $con .= pack("C", 0); - $con .= pack("C", 0); - $con .= pack("C", 3); - $SOCKS_4a = 1; - } - - $con .= "nobody"; - $con .= pack("C", 0); - - if ($SOCKS_4a) { - $con .= $h; - $con .= pack("C", 0); - } - $con0 = "SOCKS4 via $proxy_host:$proxy_port to $h:$p\n\n"; - -} elsif ($second ne "") { - $con = "CONNECT $second HTTP/1.1\r\n"; - $con .= "Host: $second\r\n\r\n"; - $con0 = $con; -} else { - $con = "CONNECT $connect HTTP/1.1\r\n"; - $con .= "Host: $connect\r\n\r\n"; - $con0 = $con; -} - -print STDERR "proxy_request1: $con0"; -print $sock $con; - -unlink($0); - -my $rep = ""; -if ($ENV{PPROXY_SOCKS} ne "") { - $rep = "HTTP/1.0 200"; - for (my $i = 0; $i < 8; $i++) { - my $c; - sysread($sock, $c, 1); - my $s = unpack("C", $c); - if ($i == 0) { - $rep = "" if $s != 0x0; - } elsif ($i == 1) { - $rep = "" if $s != 0x5a; - } - } -} else { - while ($rep !~ /\r\n\r\n/) { - my $c; - sysread($sock, $c, 1); - print STDERR $c; - $rep .= $c; - } -} -if ($rep !~ m,HTTP/.* 200,) { - die "proxy error: $rep\n"; -} - -if ($second ne "") { - $con = "CONNECT $connect HTTP/1.1\r\n"; - $con .= "Host: $connect\r\n\r\n"; - print STDERR "proxy_request2: $con"; - - print $sock $con; - - $rep = ""; - while ($rep !~ /\r\n\r\n/) { - my $c; - sysread($sock, $c, 1); - print STDERR $c; - $rep .= $c; - } - if ($rep !~ m,HTTP/.* 200,) { - die "proxy error: $rep\n"; - } -} - -if (fork) { - print STDERR "pproxy parent\[$$] STDIN -> socket\n"; - if ($listen_handle) { - xfer($listen_handle, $sock); - } else { - xfer(STDIN, $sock); - } -} else { - print STDERR "pproxy child \[$$] socket -> STDOUT\n"; - if ($listen_handle) { - xfer($sock, $listen_handle); - } else { - xfer($sock, STDOUT); - } -} -exit; - -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; - } - close($in); - close($out); -} -' - echo "$cod" > $tf - chmod 700 $tf -} - ptmp="" if [ "X$proxy" != "X" ]; then ptmp="/tmp/ss_vncviewer${RANDOM}.$$.pl" mytmp "$ptmp" + PPROXY_REMOVE=1; export PPROXY_REMOVE pcode "$ptmp" if [ "X$showcert" != "X1" -a "X$direct_connect" = "X" ]; then if uname | grep Darwin >/dev/null; then - nd=`expr $use + 333` + # on mac we need to listen on socket instead of stdio: + nd=`findfree 6700` PPROXY_LISTEN=$nd export PPROXY_LISTEN $ptmp 2>/dev/null & - sleep 3 + #sleep 3 + sleep 2 host="localhost" port="$nd" connect="connect = localhost:$nd" else + # otherwise on unix we can exec it: connect="exec = $ptmp" fi else @@ -1002,7 +1364,7 @@ if [ "X$showcert" = "X1" ]; then PPROXY_LISTEN=$use export PPROXY_LISTEN $ptmp 2>/dev/null & - sleep 3 + sleep 1 host="localhost" port="$use" fi @@ -1018,8 +1380,11 @@ if [ "X$direct_connect" != "X" ]; then echo "** NOTE: THERE WILL BE NO SSL OR SSH ENCRYPTION **" echo "" fi + x="" if [ "X$SSVNC_NO_ENC_WARN" != "X" ]; then - sleep 1 + if [ "X$getport" = "X" ]; then + sleep 1 + fi elif type printf > /dev/null 2>&1; then printf "Are you sure you want to continue? [y]/n " read x @@ -1036,12 +1401,15 @@ if [ "X$direct_connect" != "X" ]; then export PPROXY_LISTEN $ptmp & if [ "X$reverse" = "X" ]; then - sleep 2 + #sleep 2 + #echo T sleep 1 + sleep 1 fi host="localhost" disp="$N" fi if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then + #echo T sleep $SSVNC_EXTRA_SLEEP sleep $SSVNC_EXTRA_SLEEP fi if [ "X$reverse" = "X" ]; then @@ -1049,6 +1417,13 @@ if [ "X$direct_connect" != "X" ]; then trap "final" 0 2 15 echo "" $VNCVIEWERCMD "$@" $host:$disp + if [ $? != 0 ]; then + echo "vncviewer command failed: $?" + if [ "X$secondtry" = "X1" ]; then + sleep 2 + $VNCVIEWERCMD "$@" $host:$disp + fi + fi else echo "" echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode." @@ -1175,6 +1550,8 @@ sleep 1 echo "" echo "Running stunnel:" echo "$STUNNEL $tmp" +st=`echo "$STUNNEL" | awk '{print $1}'` +$st -help > /dev/null 2>&1 $STUNNEL "$tmp" < /dev/tty > /dev/tty & stunnel_pid=$! echo "" @@ -1182,13 +1559,14 @@ echo "" # pause here to let the user supply a possible passphrase for the # mycert key: if [ "X$mycert" != "X" ]; then - sleep 2 + sleep 1 echo "" echo "(pausing for possible certificate passphrase dialog)" echo "" - sleep 2 + sleep 4 fi -sleep 2 +#echo T sleep 1 +sleep 1 rm -f "$tmp" echo "" @@ -1201,6 +1579,13 @@ if [ "X$reverse" = "X" ]; then trap "final" 0 2 15 echo "" $VNCVIEWERCMD "$@" localhost:$N + if [ $? != 0 ]; then + echo "vncviewer command failed: $?" + if [ "X$secondtry" = "X1" ]; then + sleep 2 + $VNCVIEWERCMD "$@" localhost:$N + fi + fi else echo "" echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode." diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl b/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl index 71da7a6..94e1e47 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.19 +set version 1.0.20 set buck_zero $argv0 @@ -111,16 +111,16 @@ proc ts_help {} { You MUST be able to log in via SSH to the remote terminal server. Ask your administrator to set this up for you if it isn't already. + Also see "Requirements" below. This mode is started by the commands 'tsvnc' or 'ssvnc -ts' or toggling by pressing Ctrl-t. "SSVNC Mode" under Options -> Advanced will also return to the full SSVNC. Or in your ~/.ssvncrc (or ~/ssvnc_rc on Windows) put "mode=tsvnc" - to have the tool always start up in that mode. - - To constrain the UI, run with -tso or SSVNC_TS_ALWAYS set to prevent - leaving the Terminal Services mode. + to have the tool always start up in that mode. To constrain the UI, + run with -tso or SSVNC_TS_ALWAYS set to prevent leaving the Terminal + Services mode. Hosts and Displays: @@ -150,36 +150,61 @@ proc ts_help {} { 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). + If the remote SSH server is run on a non-standard port, e.g. 2222, use + something like this: + + far-away.east:2222 + fred@someplace.no:2222 + + (unlike SSVNC mode, the number is the SSH port, not the VNC display) + Proxies/Gateways: - Proxy/Gateway is usually a gateway machine to log into via SSH - that is not the machine running the VNC terminal services. + Proxy/Gateway is usually a gateway machine to log into via SSH that is + not the machine running the VNC terminal services. However, Web and + SOCKS proxies can also be used (see below). For example if a company had a central login server: "ssh.company.com" (accessible from the internet) and the internal server name was - "ts-server", one could put in for the + "ts-server", one could put in VNC Terminal Server: ts-server Proxy/Gateway: ssh.company.com It is OK if the hostname "ts-server" only resolves inside the firewall. - The 2nd host, ts-server in this example, MUST also be running an - SSH server and you must be able to log into it. + The 2nd host, ts-server in this example, MUST also be running an SSH + server and you must be able to log into it. You may need to supply + a 2nd password to it to login. Use username@host (e.g. joe@ts-server or jsmith@ssh.company.com) if the user name differs between machines. - To use a non-standard ssh port (i.e. a port other than 22) you need to - use the Proxies/Gateways as well. Something like this for port 2222: + To use a non-standard ssh port (i.e. a port other than 22) in + Proxy/Gateways use something like this for port 2222: + + 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. + + 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. - VNC Host:Display: localhost - Proxy/Gateway: jsmith@ssh.company.com:2222 + VNC Terminal Server: fred@someplace.no + Proxy/Gateway: http://myproxy.west:8080 - The username@ is not needed if it is the same as on this machine. The - above will also work going to a different internal machine, - e.g. "ts-server", as in the first example. + or for SOCKS: + + VNC Terminal Server: fred@someplace.no + Proxy/Gateway: socks://mysocks.west:1080 + + use socks5://... to force the SOCKS5 version. For a non-standard + port the above would be, e.g., fred@someplace.no:2222 + + One can also chain proxies and other things. See the section + "SSH Proxies/Gateways" in the Main SSVNC Help for full details. Options: @@ -247,7 +272,7 @@ proc ts_help {} { Real X servers: - As a BONUS, if on the remote host, say a workstation, you have a + As a *BONUS*, if on the remote host, say a workstation, you have a regular X session running on the physical hardware that you are ALREADY logged into you can access to that display as well (x11vnc will find it). @@ -262,6 +287,10 @@ proc ts_help {} { X server on the workstation, a VIRTUAL (Xvfb, etc.) server will be created for you (that may or may not be what you want). + The X Login Advanced setting can be used to connect to a X Display + Manger Greeter login panel (no one is logged in yet). This requires + sudo(1) privileges on the remote machine. + More Info: See these links for more information: @@ -299,8 +328,11 @@ proc help {} { it is often "0". Examples: snoopy:0 + far-away.east:0 + sunray-srv1.west:17 + 24.67.132.27:0 Then click on "Connect". When you do so the STUNNEL program will be @@ -311,12 +343,12 @@ proc help {} { port of the SSL tunnel which, in turn, encrypts and redirects the connection to the remote VNC server. - The remote VNC server must support an initial SSL handshake before + The remote VNC server MUST support an initial SSL handshake before 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 on the remote side. - SSH tunnels are described below. + Automatic SSH tunnels are described below. If you are using a port less than the default VNC port 5900 (usually the VNC display = port - 5900), use the full port number itself, e.g.: @@ -329,55 +361,77 @@ proc help {} { e.g.: 24.67.132.27:-80 - *IMPORTANT*: If you do not take the steps to verify the VNC Server's - SSL Certificate, you are vulnerable to a Man-In-The-Middle attack. - Only passive network sniffing attacks will be prevented. + SSL Certificate Verification: + + *IMPORTANT*: If you do not take the steps to VERIFY the VNC Server's SSL + Certificate, you are theoretically vulnerable to a Man-In-The-Middle + attack. Without SSL Certificate verification, only passive network + sniffing attacks will be guaranteed to be prevented. 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. + you can "Save" it and use it to verify future connections to servers. - If "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 follow - a few dialogs to inspect and save the server certificate. See the - "Certs... -> Help" for information on how to manage 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 + follow a few dialogs to inspect and save the server certificate. + See the "Certs... -> Help" for information on how to manage certificates. - "Fetch Cert" and "Verify All Certs" are currently disabled in the - "SSH + SSL" mode (e.g. SSH is used to enter a firewall gateway, + "Fetch Cert" and "Verify All Certs" are currently disabled in the rare + "SSH + SSL" usage mode (e.g. SSH is used to enter a firewall gateway, and then SSL is tunneled through that to reach the workstation). + Windows STUNNEL: + Note that on Windows when the Viewer connection is finished you may need to terminate STUNNEL manually from the System Tray (right click - on dark green icon) and selecting "Exit". + on dark green icon) and selecting "Exit". Double clicking that icon + will show you its log file (useful for debugging connections). + + SSVNC will try to kill the STUNNEL process for you, but you may still + need to move the mouse over the icon to make it go away. + VNC Password: On Unix or MacOSX if there is a VNC password for the server you can enter it in the "VNC Password:" entry box. - This is *REQUIRED* on MacOSX when Chicken of the VNC (the default) - is used. On Unix if you choose not to enter the password you will - be prompted for it in the terminal window running TightVNC viewer. - On Windows TightVNC viewer should prompt you. + This is *REQUIRED* on MacOSX when Chicken of the VNC is used. + + On Unix if you choose not to enter the password you will be prompted + for it in the terminal window running TightVNC viewer if one is required. + + On Windows TightVNC viewer should prompt you when a password is required. NOTE: when you Save a VNC profile, the password is not saved (you need to enter it each time). + SSH: - Click on "Use SSH" or go to "Options ..." if you want to use an - *SSH* tunnel instead of SSL (then the VNC Server does not need to - speak SSL or use STUNNEL). You will need to be able to login to the - remote host via SSH (e.g. via password or ssh-agent). + Click on "Use SSH" if you want to use an *SSH* tunnel instead of SSL + (then the VNC Server does not need to speak SSL or use STUNNEL). + You will need to be able to login to your account on the remote host + via SSH (e.g. via password or ssh-agent). + + Specify the SSH hostname and VNC display in the VNC Host:Display entry. + Use something like: + + username@far-away.east:0 - Specify the hostname and VNC display in the VNC Host:Display entry. - Use something like "username@hostname.com:0" if the remote username - is different. "SSH + SSL" is similar but its use is more rare. See - the Help under Options for more info. + if your remote username is different from the one on the local viewer + machine. On Windows you MUST supply the "username@" part. - See Tip 13) below for how to make this application be SSH only with - the -ssh command line option. + "SSH + SSL" is similar but its use is more rare because it requires 2 + encrypted tunnels to reach the VNC server. See the Help under Options + for more info. + + To connect to a non-standard SSH port, see SSH Proxies/Gateways below. + + See Tip 13) below for how to make this application be SSH-only with + the -ssh command line option or "sshvnc". Proxies/Gateways: @@ -387,40 +441,49 @@ proc help {} { entry box: VNC Host-Display: host:number - Proxy/Gateway: gw-host:port + Proxy/Gateway: proxy-host:port e.g.: VNC Host-Display: far-away.east:0 - Proxy/Gateway: mygateway.com:8080 - - Or Alternatively one can supply both hosts separated by - spaces (with the proxy second) in the VNC Host:Display box: - - VNC Host-Display: far-away.east:0 mygateway.com:8080 - - This looks a little strange, but it actually how SSVNC stores the - host info internally. + Proxy/Gateway: myproxy.west:8080 If the "double proxy" case is required (e.g. coming out of a web - proxied firewall environment and then into a 2nd proxy to ultimately + proxied firewall environment and then INTO a 2nd proxy to ultimately reach the VNC server), separate them via a comma, e.g.: VNC Host-Display: far-away:0 - Proxy/Gateway: local-proxy:8080,mygateway.com:443 + Proxy/Gateway: myproxy.west:8080,myhome.net:443 - (either as above, or alternatively putting both strings in Host:Display) - So it goes: viewer -> local-proxy -> mygateway.com -> far-away (VNC) + So it goes: viewer -> myproxy.west -> myhome.net -> far-away (VNC) + + The proxies are assumed to be Web proxies. To use SOCKS proxies: + + VNC Host-Display: far-away.east:0 + Proxy/Gateway: socks://mysocks.west:1080 + + 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. + + Note that Web proxies are often configured to only allow outgoing + connections to ports 443 (HTTPS) and 563 (SNEWS), so you might + have run the VNC server (or router port redirector) on those ports. + SOCKS proxies usually have no restrictions on port number. + + On Unix you can chain up to 3 proxies (any combination of http:// and + socks://) by separating them with commas (i.e. first,second,third). See the ss_vncviewer description and x11vnc FAQ for info on proxies: http://www.karlrunge.com/x11vnc/#ss_vncviewer http://www.karlrunge.com/x11vnc/#faq-ssl-java-viewer-proxy + SSH Proxies/Gateways: - Proxy/Gateway also applies to SSH mode, it is a usually a gateway - machine to log into via SSH that is not the workstation running the - VNC server. + Proxy/Gateway also applies to SSH mode, it is a usually a gateway SSH + machine to log into via ssh that is not the workstation running the + VNC server. However, Web and SOCKS proxies can also be used (see below). For example if a company had a central login server: "ssh.company.com" (accessible from the internet) and the internal workstation name was @@ -434,25 +497,58 @@ proc help {} { The 2nd leg, from ssh.company.com -> joes-pc is done by a ssh -L redir and is not encrypted (but viewer -> ssh.company.com is encrypted). - To SSH encrypt both legs, try the "double gateway" using the above - "comma" notation: + To SSH encrypt BOTH legs, try the "double SSH gateway" method using + the "comma" notation: VNC Host:Display: localhost:0 Proxy/Gateway: ssh.company.com,joes-pc - this requires an SSH server running on joes-pc. Use username@host - (e.g. joe@joes-pc jsmith@ssh.company.com) if the user name differs. + this requires an SSH server running on joes-pc. So an initial SSH + login is done to ssh.company.com, then a 2nd SSH is performed (through + port a redirection of the first) to login straight to joes-pc where + the VNC server is running. + + Use username@host (e.g. joe@joes-pc jsmith@ssh.company.com) if the + user names differ between the various machines. On Windows you MUST + supply the usernames. To use a non-standard ssh port (i.e. a port other than 22) you need to - use the Proxies/Gateways as well. Something like this for port 2222: + use the Proxy/Gateways as well. E.g. something like this for port 2222: VNC Host:Display: localhost:0 - Proxy/Gateway: joe@ssh.company.com:2222 + Proxy/Gateway: joe@far-away.east:2222 + + The username@ is not needed if it is the same as on the client. This + will also work going to a different internal machine, e.g. "joes-pc:0" + instead of "localhost:0", as in the first example. + + A Web or SOCKS proxy can also be used with SSH. Use this if you are + inside a firewall that prohibits direct connections to remote SSH servers. + + VNC Host:Display: joe@far-away.east:0 + Proxy/Gateway: http://myproxy.west:8080 + + or for SOCKS: + + VNC Host:Display: joe@far-away.east:0 + Proxy/Gateway: socks://mysocks.west:1080 + + use socks5://... to force the SOCKS5 version. + + On Unix you can chain up to 3 proxies (any combination of http:// and + socks://) by separating them with commas (i.e. first,second,third). + + For a non-standard SSH port and a Web or SOCKS proxy try: + + VNC Host:Display: localhost:0 + Proxy/Gateway: http://myproxy.west:8080,joe@far-away.east:2222 + + Even the "double SSH gateway" method (2 SSH encrypted legs) described + above works with an initial Web or SOCKS proxy, e.g.: + + VNC Host:Display: localhost:0 + Proxy/Gateway: http://mysocks.west:1080,ssh.company.com,joes-pc - The username@ is not needed if it is the same as on the client. - (Also, localhost:0 is actually the same as :0). This will also work - going to a different internal machine, e.g. "joes-pc:0", as in the - first example. Remote SSH Command: @@ -460,15 +556,16 @@ proc help {} { to run on the remote ssh host in the "Remote SSH Command" entry. The default is just to sleep a bit (e.g. sleep 30) to make sure the port tunnels are established. Alternatively you could have the - remote command start the VNC server, e.g. x11vnc -nopw -display :0 - -rfbport 5900 -localhost + remote command start the VNC server, e.g. + + x11vnc -display :0 -rfbport 5900 -localhost -nopw When starting the VNC server this way, note that sometimes you will need to correlate the VNC Display number with the "-rfbport" (or similar) option of the server. E.g.: VNC Host:Display username@somehost.com:2 - Remote SSH Command: x11vnc -find -rfbport 5902 + Remote SSH Command: x11vnc -find -rfbport 5902 -nopw See the the Tip below (11) for using x11vnc PORT=NNNN feature (or vncserver(1) output) to not need to specify the VNC display number @@ -518,9 +615,9 @@ proc help {} { More Options: - To set other Options, e.g. to use SSH instead of STUNNEL SSL, or - View-Only usage, click on the "Options ..." button and read the Help - there. + To set other Options, e.g. for View-Only usage or to limit the + number of colors used. click on the "Options ..." button and read + the Help there. Profiles: @@ -560,24 +657,24 @@ proc help {} { Ctrl-N or try Ctrl-LeftButton -> New SSVNC_GUI. On Windows you will have to manually Start a new one: Start -> Run ..., etc. - 2) If you use "user@hostname cmd=SHELL" then you get an SSH shell only: - no VNC viewer will be launched. On Windows "user@hostname cmd=PUTTY" - will try to use putty.exe (better terminal emulation than - plink.exe). A ShortCut for this is Ctrl-S as long as user@hostname - is present in the entry box. You can also put the string in the - "Remote SSH Command" entry. - - 3) If you use "user@hostname cmd=KNOCK" then only the port-knocking - is performed. A ShortCut for this is Ctrl-P as long as hostname - is present in the entry box. If it matches cmd=KNOCKF, i.e. an - extra "F", then the port-knocking "FINISH" sequence is sent, if any. + 2) If you use "SHELL" for the "Remote SSH Command" (or in the display + line: "user@hostname cmd=SHELL") then you get an SSH shell only: + no VNC viewer will be launched. On Windows "PUTTY" will try + to use putty.exe (better terminal emulation than plink.exe). + A ShortCut for this is Ctrl-S as long as user@hostname is present + in the entry box. + + 3) If you use "KNOCK" for the "Remote SSH Command" (or int he display + line "user@hostname cmd=KNOCK") then only the port-knocking is + performed. A ShortCut for this is Ctrl-P as long as hostname + is present in the entry box. If it is KNOCKF, i.e. an extra + "F", then the port-knocking "FINISH" sequence is sent, if any. A ShortCut for this Shift-Ctrl-P as long as hostname is present. - You can also put the string in the "Remote SSH Command" entry. 4) Pressing the "Load" button or pressing Ctrl-L or Clicking the Right mouse button on the main GUI will invoke the Load dialog. - 5) If you want to do a Direct VNC connection, WITH *NO* SSL OR SSH + 5) If you want to do a Direct VNC connection, WITH **NO(* SSL OR SSH ENCRYPTION, use the "vnc://" prefix, e.g. vnc://far-away.east:0 This also works for reverse connections (see below). @@ -600,8 +697,8 @@ proc help {} { port is the desired local listening port. Then click Connect. If you didn't set the local port look for it in the terminal output. - On Windows set it to "NOTEPAD" or similar; you can't control - the port though. It is usually 5930. + On Windows set it to "NOTEPAD" or similar; you can't control the + port though. It is usually 5930, 5931, ... Watch the messages. 8) On Unix if you are going to an older SSH server (e.g. Solaris 10), you will probably need to set the env. var. SS_VNCVIEWER_NO_T=1 @@ -609,10 +706,16 @@ proc help {} { command from being run). 9) In the VNC Host:Display entry you can also use these "URL-like" - prefixes: vncs://host:0, vncssl://host:0, and vnc+ssl://host:0 - for SSL, and vncssh://host:0 and vnc+ssh://host:0 for SSH. There - is no need to toggle the SSL/SSH setting. These also work from - the command line, e.g.: ssvnc vnc+ssh://mymachine:10 + prefixes: + + vncs://host:0, vncssl://host:0, vnc+ssl://host:0 for SSL + + and + + vncssh://host:0, vnc+ssh://host:0 for SSH + + There is no need to toggle the SSL/SSH setting. These also work + from the command line, e.g.: ssvnc vnc+ssh://mymachine:10 10) Mobile USB memory stick / flash drive usage: You can unpack ssvnc to a flash drive for impromptu usage (e.g. from a friends @@ -624,7 +727,7 @@ proc help {} { WARNING: if you use ssvnc from an "Internet Cafe", i.e. an untrusted computer, an unscrupulous person may be capturing - keystrokes, etc. + keystrokes, etc.! You can also set the SSVNC_HOME env. var. to point to any directory you want. It can be set after starting ssvnc by putting @@ -640,7 +743,7 @@ proc help {} { the SSH tunnel. For example: VNC Host:Display user@somehost.com - Remote SSH Command: PORT= x11vnc -find + Remote SSH Command: PORT= x11vnc -find -nopw or "PORT= x11vnc -display :0 -localhost", etc. Or use "P= ..." @@ -671,9 +774,8 @@ proc help {} { 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. Then no GUI elements specific to SSL will appear (the - documentation will refer to the SSL mode, however). You cannot - Load an SSL profile when in this mode. To convert a running - app to ssh-only select "Mode: SSH-Only" in Options. + documentation will refer to the SSL mode, however). To convert + a running app to ssh-only select "Mode: SSH-Only" in Options. The wrapper scripts "sshvnc" and "sshvnc.bat" will start it up automatically this way. @@ -699,13 +801,13 @@ proc help {} { Put "mode=tsvnc" or "mode=sshvnc" in the ~/.ssvncrc file to have the application start up in the given mode. - desktop_type=wmaker (e.g.) to switch the default Desktop Type. + desktop_type=wmaker (e.g.) to switch the default Desktop Type. - desktop_size=1280x1024 (e.g.) to switch the default Desktop Size. + desktop_size=1280x1024 (e.g.) to switch the default Desktop Size. - desktop_depth=24 (e.g.) to switch the default Desktop Color Depth. + desktop_depth=24 (e.g.) to switch the default Desktop Color Depth - xserver_type=Xdummy (e.g.) to switch the default X Server Type. + xserver_type=Xdummy (e.g.) to switch the default X Server Type. (The above 4 settings apply only to the Terminal Services Mode.) @@ -722,6 +824,14 @@ proc help {} { jiggle_text .h.f.t } +# Or Alternatively one can supply both hosts separated by +# spaces (with the proxy second) in the VNC Host:Display box: +# +# VNC Host-Display: far-away.east:0 theproxy.net:8080 +# +# This looks a little strange, but it actually how SSVNC stores the +# host info internally. + # You can also specify the remote SSH command by putting a string like # # cmd=x11vnc -nopw -display :0 -rfbport 5900 -localhost @@ -1163,7 +1273,7 @@ set msg { Windows you *MUST* always supply the "user@" part (due to a plink deficiency). E.g.: - fred@far-away.east:0 + VNC Host:Display: fred@far-away.east:0 Gateway: If an intermediate gateway machine must be used @@ -1190,19 +1300,27 @@ set msg { VNC Host:Display: localhost:0 Proxy/Gateway: user@gateway-host:port,user@workstation:port + Web and SOCKS proxies can also be used with SSH: + + VNC Host:Display: user@workstation:0 + Proxy/Gateway: socks://socks.server:1080 + + See the "SSH Proxies/Gateways" in the Main Help document for full + details. + Remote Command: In the "Remote SSH Command" entry you can to indicate that a remote command to be run. The default is "sleep 15". For example, to run x11vnc for your X :0 display: - x11vnc -nopw -display :0 + x11vnc -display :0 -nopw - Trick: If you use "cmd=SHELL" then you get an SSH shell only: - no VNC viewer will be launched. On Windows "cmd=PUTTY" will - try to use putty.exe (better terminal emulation than plink.exe) - A shortcut for this is Ctrl-S as long as user@hostname is present - in the "VNC Host:Display" box. + Trick: If you use "SHELL" asl the "Remote SSH Command" then + you get an SSH shell only: no VNC viewer will be launched. + On Windows "PUTTY" will try to use putty.exe (better terminal + emulation than plink.exe) A shortcut for this is Ctrl-S as + long as user@hostname is present in the "VNC Host:Display" box. Use SSH + SSL: @@ -1231,13 +1349,15 @@ set msg { does it attaches to it; otherwise the x11vnc VNC server exits immediately followed by your VNC Viewer. - The PORT= option just means to let x11vnc pick its own VNC - port and then connect to whatever it picked. + The PORT= option just means to let x11vnc pick its own + VNC port and then connect to whatever it picked. Use P= + for more debugging output. The idea for this mode is you simply type 'username@workstation' in the VNC Host:Display box, Select 'Options -> Automatically - Find X Session', and then click Connect. The tsvnc mode - is similar. + Find X Session', and then click Connect. The tsvnc mode is + similar (it runs x11vnc on the remote side with the intent + of automatically finding, or creating, your desktop). Automatically Find X Login/Greeter: @@ -1255,7 +1375,8 @@ set msg { An initial ssh running 'sudo id' is performed to try to 'prime' sudo so the 2nd one that runs x11vnc does not need - a password. This may not always succeed... + a password. This may not always succeed... please mail us + the details if it doesn't. See the 'X Login' description in 'Terminal Services' Mode Help for more info. @@ -1312,7 +1433,7 @@ set msg { prior to any connections. For reverse connections in SSH or SSH + SSL modes it is a - little trickier. The SSH tunnel (with -R redirect) must be + little trickier. The SSH tunnel (with -R tunnel) must be established and remain up waiting for reverse connections. The default time is "sleep 1800", i.e. 30 mins. You can put a longer or shorter sleep in "Remote SSH Command" (perhaps @@ -2106,7 +2227,8 @@ proc guess_nat_ip {} { set ip "unknown" if {$s != ""} { fconfigure $s -buffering none - puts $s "GET / HTTP/1.1" + #puts $s "GET / HTTP/1.1" + puts $s "GET /automation/n09230945.asp HTTP/1.1" puts $s "Host: www.whatismyip.com" puts $s "Connection: close" puts $s "" @@ -2116,6 +2238,7 @@ proc guess_nat_ip {} { if {! $on && [regexp {<HEAD>} $line]} {set on 1} if {! $on && [regexp {<HTML>} $line]} {set on 1} if {! $on && [regexp {<TITLE>} $line]} {set on 1} + if {! $on && [regexp {^[0-9][0-9]*\.[0-9]} $line]} {set on 1} if {! $on} { continue; } @@ -2297,7 +2420,20 @@ proc launch_windows_ssh {hp file n} { regsub {^.*:} $vnc_disp "" vnc_disp if {$ts_only} { - ; + regsub {:0$} $hpnew "" hpnew + if {$proxy == ""} { + if {[regexp {^([^:]*):([0-9][0-9]*)$} $hpnew mv sshhst sshpt]} { + set proxy "$sshhst:$sshpt" + set hpnew "localhost" + } + } else { + if {![regexp {,} $proxy]} { + if {$hpnew != "localhost"} { + set proxy "$proxy,$hpnew" + set hpnew "localhost" + } + } + } } elseif {![regexp {^-?[0-9][0-9]*$} $vnc_disp]} { if {[regexp {cmd=SHELL} $hp]} { ; @@ -2342,6 +2478,88 @@ proc launch_windows_ssh {hp file n} { set double_ssh "" set p_port "" if {$proxy != ""} { + if [regexp -nocase {(http|https|socks|socks4|socks5)://} $proxy] { + set pproxy "" + set sproxy1 "" + set sproxy_rest "" + set sproxy1_host "" + set sproxy1_user "" + set sproxy1_port "" + foreach part [split $proxy ","] { + if {[regexp {^[ ]*$} $part]} { + continue + } + if [regexp -nocase {^(http|https|socks|socks4|socks5)://} $part] { + if {$pproxy == ""} { + set pproxy $part + } else { + set pproxy "$pproxy,$part" + } + } else { + if {$sproxy1 == ""} { + set sproxy1 $part + } else { + if {$sproxy_rest == ""} { + set sproxy_rest $part + } else { + set sproxy_rest "$sproxy_rest,$part" + } + } + } + } +#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 + regsub {@.*$} $sproxy1 "" sproxy1_user + regsub {^.*:} $sproxy1 "" sproxy1_port + } else { + regsub {:[0-9][0-9]*$} $ssh_host "" sproxy1_host + regsub {^.*@} $sproxy1_host "" sproxy1_host + regsub {@.*$} $ssh_host "" sproxy1_user + regsub {^.*:} $ssh_host "" sproxy1_port + } + if {![regexp {^[0-9][0-9]*$} $sproxy1_port]} { + set sproxy1_port 22 + } + 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 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 + set proxy_pid [exec "connect_br.exe" &] + + unset -nocomplain env(SSVNC_PROXY) + unset -nocomplain env(SSVNC_LISTEN) + unset -nocomplain env(SSVNC_DEST) + + if {$sproxy1 == ""} { + set proxy "localhost:$port2" + if [regexp {^(.*)@} $ssh_host mv u] { + set proxy "$u@$proxy" + } + } else { + set proxy "${sproxy1_user}localhost:$port2" + } + if {$sproxy_rest != ""} { + set proxy "$proxy,$sproxy_rest" + } + mesg "Set proxy to: $proxy" + after 400 + } if [regexp {,} $proxy] { if {$is_win9x} { mesg "Double proxy does not work on Win9x" @@ -2598,6 +2816,7 @@ proc launch_windows_ssh {hp file n} { if {$vnc_host == ""} { set vnc_host "localhost" } + regsub {^.*@} $vnc_host "" vnc_host set redir "-L $use:$vnc_host:$vnc_port" if {$use_listen} { @@ -3475,7 +3694,21 @@ proc fetch_cert_windows {hp} { if {$proxy != ""} { global env - set port2 5991 + set port2 [rand_port] + + set sp "" + if [info exists env(SSVNC_PROXY)] { + set sp $env(SSVNC_PROXY) + } + set sl "" + if [info exists env(SSVNC_LISTEN)] { + set sl $env(SSVNC_LISTEN) + } + set sd "" + if [info exists env(SSVNC_DEST)] { + set sd $env(SSVNC_DEST) + } + set env(SSVNC_PROXY) $proxy set env(SSVNC_LISTEN) $port2 set env(SSVNC_DEST) "$host:$port" @@ -3485,9 +3718,22 @@ proc fetch_cert_windows {hp} { mesg "Starting TCP helper on port $port2 ..." after 600 set proxy_pid [exec "connect_br.exe" &] - unset -nocomplain env(SSVNC_PROXY) - unset -nocomplain env(SSVNC_LISTEN) - unset -nocomplain env(SSVNC_DEST) + + if {$sp == ""} { + unset -nocomplain env(SSVNC_PROXY) + } else { + set env(SSVNC_PROXY) $sp + } + if {$sl == ""} { + unset -nocomplain env(SSVNC_LISTEN) + } else { + set env(SSVNC_LISTEN) $sl + } + if {$sd == ""} { + unset -nocomplain env(SSVNC_DEST) + } else { + set env(SSVNC_DEST) $sd + } } set ossl [get_openssl] @@ -3809,7 +4055,7 @@ proc check_accepted_certs {} { .acert.f.t insert end $msg - pack .acert.cancel .acert.accept .acert.inspect -side bottom -fill x + pack .acert.accept .acert.inspect .acert.cancel -side bottom -fill x pack .acert.f -side top -fill both -expand 1 center_win .acert @@ -4053,15 +4299,28 @@ proc launch_unix {hp} { set proxy [get_ssh_proxy $hp] set sshcmd [get_ssh_cmd $hp] - if {$ts_only && $proxy != "" && ![regexp {,} $proxy]} { - regsub {:[0-9]*$} $hpnew "" h2 - set proxy "$proxy,$h2" - regsub {^[^:]*} $hpnew "localhost" hpnew + if {$ts_only} { + regsub {:0$} $hpnew "" hpnew + if {$proxy == ""} { + if {[regexp {^([^:]*):([0-9][0-9]*)$} $hpnew mv sshhst sshpt]} { + set proxy "$sshhst:$sshpt" + set hpnew "localhost" + } + } else { + if {![regexp {,} $proxy]} { + if {$hpnew != "localhost"} { + set proxy "$proxy,$hpnew" + set hpnew "localhost" + } + } + } } + #puts hp=$hp #puts hpn=$hpnew #puts pxy=$proxy #puts cmd=$sshcmd + set hp $hpnew if {$proxy != ""} { @@ -6021,7 +6280,7 @@ proc create_cert {} { button .ccrt.create -text "Generate Cert" -command {destroy .ccrt; catch {raise .c}; do_oss_create} - pack .ccrt.cancel .ccrt.create -side bottom -fill x + pack .ccrt.create .ccrt.cancel -side bottom -fill x set ew 40 @@ -6127,6 +6386,10 @@ proc import_save_browse {{par ".icrt"}} { proc do_save {par} { global import_mode import_file import_save_file global also_save_to_accepted_certs + + if {![info exists also_save_to_accepted_certs]} { + set also_save_to_accepted_certs 0 + } if {$import_save_file == "" && ! $also_save_to_accepted_certs} { tk_messageBox -parent $par -type ok -icon error \ @@ -6378,7 +6641,7 @@ TCQ+tbQ/DOiTXGKx1nlcKoPdkG+QVQVJthlQcpam pack $w.l -side left pack $w.e -side left -expand 1 -fill x - pack .icrt.cancel .icrt.save .icrt.sf .icrt.mf -side bottom -fill x + pack .icrt.save .icrt.cancel .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 @@ -7253,7 +7516,12 @@ proc get_sound_redir {} { set loc $sound_daemon_local_port if {! [regexp {:} $loc]} { - set loc "localhost:$loc" + global uname + if {$uname == "Darwin"} { + set loc "127.0.0.1:$loc" + } else { + set loc "localhost:$loc" + } } set redir "$sound_daemon_remote_port:$loc" regsub -all {['" ]} $redir {} redir; #" @@ -8260,7 +8528,7 @@ proc ts_cups_dialog {} { global cups_local_server cups_remote_port cups_manage_rcfile cups_x11vnc global cups_local_smb_server cups_remote_smb_port - scroll_text .cups.f 80 29 + scroll_text .cups.f 80 30 set msg { @@ -8271,7 +8539,8 @@ proc ts_cups_dialog {} { Enter the VNC Viewer side (i.e. where you are sitting) CUPS server under "Local CUPS Server". Use "localhost:631" if there is one on your viewer machine (cupsd), or, say, "my-print-srv:631" for a - nearby CUPS print server. 631 is the default CUPS port. + nearby CUPS print server. 631 is the default CUPS port. On + MacOSX it seems better to use "127.0.0.1" than "localhost". The remote Desktop session will have the variables CUPS_SERVER and IPP_PORT set so all printing applications will be redirected to your @@ -8303,8 +8572,13 @@ proc ts_cups_dialog {} { } .cups.f.t insert end $msg + global uname if {$cups_local_server == ""} { - set cups_local_server "localhost:631" + if {$uname == "Darwin"} { + set cups_local_server "127.0.0.1:631" + } else { + set cups_local_server "localhost:631" + } } if {$cups_remote_port == ""} { set cups_remote_port [expr "6731 + int(1000 * rand())"] @@ -8313,6 +8587,8 @@ proc ts_cups_dialog {} { global is_windows if {$is_windows} { set cups_local_smb_server "IP:139" + } elseif {$uname == "Darwin"} { + set cups_local_smb_server "127.0.0.1:139" } else { set cups_local_smb_server "localhost:139" } @@ -8459,8 +8735,13 @@ proc cups_dialog {} { } .cups.f.t insert end $msg + global uname if {$cups_local_server == ""} { - set cups_local_server "localhost:631" + if {$uname == "Darwin"} { + set cups_local_server "127.0.0.1:631" + } else { + set cups_local_server "localhost:631" + } } if {$cups_remote_port == ""} { set cups_remote_port "6631" @@ -8469,6 +8750,8 @@ proc cups_dialog {} { global is_windows if {$is_windows} { set cups_local_smb_server "IP:139" + } elseif {$uname == "Darwin"} { + set cups_local_smb_server "127.0.0.1:139" } else { set cups_local_smb_server "localhost:139" } @@ -10368,16 +10651,17 @@ proc choose_desktop_dialog {} { radiobutton .sd.b3 -anchor w -variable ts_desktop_type -value Xsession -text cde radiobutton .sd.b4 -anchor w -variable ts_desktop_type -value mwm -text mwm radiobutton .sd.b5 -anchor w -variable ts_desktop_type -value wmaker -text wmaker - radiobutton .sd.b6 -anchor w -variable ts_desktop_type -value enlightenment -text enlightenment - radiobutton .sd.b7 -anchor w -variable ts_desktop_type -value twm -text twm - radiobutton .sd.b8 -anchor w -variable ts_desktop_type -value failsafe -text failsafe + radiobutton .sd.b6 -anchor w -variable ts_desktop_type -value xfce -text xfce + radiobutton .sd.b7 -anchor w -variable ts_desktop_type -value enlightenment -text enlightenment + radiobutton .sd.b8 -anchor w -variable ts_desktop_type -value twm -text twm + radiobutton .sd.b9 -anchor w -variable ts_desktop_type -value failsafe -text failsafe button .sd.cancel -text "Cancel" -command {destroy .sd; set choose_desktop 0; set ts_desktop_type ""} bind .sd <Escape> {destroy .sd; set choose_desktop 0; set ts_desktop_type ""} wm protocol .sd WM_DELETE_WINDOW {destroy .sd; set choose_desktop 0; set ts_desktop_type ""} button .sd.done -text "Done" -command {destroy .sd} - pack .sd.l1 .sd.l2 .sd.b1 .sd.b2 .sd.b3 .sd.b4 .sd.b5 .sd.b6 .sd.b7 .sd.b8 .sd.cancel .sd.done -side top -fill x + pack .sd.l1 .sd.l2 .sd.b1 .sd.b2 .sd.b3 .sd.b4 .sd.b5 .sd.b6 .sd.b7 .sd.b8 .sd.b9 .sd.cancel .sd.done -side top -fill x center_win .sd } @@ -10692,7 +10976,7 @@ proc set_advanced_options {} { checkbutton .oa.b$i -anchor w -variable use_grab -text \ "Use XGrabServer" - if {$darwin_cotvnc} {.o.b$i configure -state disabled} + if {$darwin_cotvnc} {.oa.b$i configure -state disabled} set ix $i incr i @@ -10992,9 +11276,9 @@ proc x11vnc_find_adjust {which} { regsub -all {[ ]*-localhost[ ]*} $remote_ssh_cmd " " remote_ssh_cmd regsub -all {[ ]*-env FD_XDM=1[ ]*} $remote_ssh_cmd " " remote_ssh_cmd if {$use_x11vnc_find} { - set remote_ssh_cmd "PORT= x11vnc -find -localhost $remote_ssh_cmd" + set remote_ssh_cmd "PORT= x11vnc -find -localhost -nopw $remote_ssh_cmd" } else { - set remote_ssh_cmd "PORT= sudo x11vnc -find -localhost -env FD_XDM=1 $remote_ssh_cmd" + set remote_ssh_cmd "PORT= sudo x11vnc -find -localhost -env FD_XDM=1 -nopw $remote_ssh_cmd" } regsub {[ ]*$} $remote_ssh_cmd "" remote_ssh_cmd regsub {^[ ]*} $remote_ssh_cmd "" remote_ssh_cmd @@ -11169,9 +11453,18 @@ proc set_options {} { button .o.ssh -anchor w -text " SSH-Only Mode" -command {to_sshonly; destroy .o} button .o.tso -anchor w -text " Terminal Svc Mode" -command {to_tsonly; destroy .o} } - button .o.advanced -anchor w -text " Advanced ..." -command set_advanced_options - button .o.clear -anchor w -text " Clear Options" -command set_defaults - button .o.delete -anchor w -text " Delete Profile ..." -command {destroy .o; delete_profile} + global uname + set t1 " Advanced ..." + set t2 " Clear Options" + set t3 " Delete Profile ..." + if {$uname == "Darwin"} { + regsub {^ *} $t1 "" t1 + regsub {^ *} $t2 "" t2 + regsub {^ *} $t3 "" t3 + } + button .o.advanced -anchor w -text $t1 -command set_advanced_options + button .o.clear -anchor w -text $t2 -command set_defaults + button .o.delete -anchor w -text $t3 -command {destroy .o; delete_profile} pack .o.clear -side top -fill x pack .o.delete -side top -fill x @@ -11479,6 +11772,9 @@ if {$uname == "Darwin"} { } } set help_font "-font {Monaco 10}" + + #option add *Button.font Helvetica widgetDefault + catch {option add *Button.font {System 10} widgetDefault} } set putty_pw "" diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle index 2c21b05..8abccf3 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.19 +vers=1.0.20 cd .. || exit 1 |