Commit e24cf949 authored by runge's avatar runge

ssvnc sync: connect_br.tcl socks4/5 http proxies, ss_vncviewer socks5 proxy....

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
parent ecbd1a49
#!/usr/bin/wish #!/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 {} { proc check_callback {} {
global debug global debug
if {$debug} { if {$debug} {
...@@ -61,41 +8,40 @@ proc check_callback {} { ...@@ -61,41 +8,40 @@ proc check_callback {} {
after 1000 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 {} { proc check_closed {} {
global client_fh server_fh debug global got_connection debug
global got_connection global client_fh server_fh
if {! $got_connection} { if {! $got_connection} {
return return
} }
set delay 100
if {$client_fh != "" && [eof $client_fh]} { if {$client_fh != "" && [eof $client_fh]} {
if {$debug} { if {$debug} {
puts stderr "client_fh EOF" puts stderr "client_fh EOF"
} }
catch {flush $client_fh} getout
after $delay
catch {close $client_fh}
after $delay
catch {flush $server_fh}
after $delay
catch {close $server_fh}
destroy .
exit
} }
if {$server_fh != "" && [eof $server_fh]} { if {$server_fh != "" && [eof $server_fh]} {
if {$debug} { if {$debug} {
puts stderr "server_fh EOF" puts stderr "server_fh EOF"
} }
catch {flush $server_fh} getout
after $delay
catch {close $server_fh}
after $delay
catch {flush $client_fh}
after $delay
catch {close $client_fh}
destroy .
exit
} }
} }
...@@ -106,7 +52,7 @@ proc xfer_in_to_out {} { ...@@ -106,7 +52,7 @@ proc xfer_in_to_out {} {
if {$debug} { if {$debug} {
puts stderr "xfer_in_to_out: $str" puts stderr "xfer_in_to_out: $str"
} }
if {$server_fh != ""} { if {$server_fh != "" && $str != ""} {
puts -nonewline $server_fh $str puts -nonewline $server_fh $str
flush $server_fh flush $server_fh
} }
...@@ -121,7 +67,7 @@ proc xfer_out_to_in {} { ...@@ -121,7 +67,7 @@ proc xfer_out_to_in {} {
if {$debug} { if {$debug} {
puts stderr "xfer_out_to_in: $str" puts stderr "xfer_out_to_in: $str"
} }
if {$client_fh != ""} { if {$client_fh != "" && $str != ""} {
puts -nonewline $client_fh $str puts -nonewline $client_fh $str
flush $client_fh flush $client_fh
} }
...@@ -129,42 +75,14 @@ proc xfer_out_to_in {} { ...@@ -129,42 +75,14 @@ proc xfer_out_to_in {} {
check_closed check_closed
} }
proc handle_connection {fh host port} { proc do_connect_http {sock hostport which} {
global proxy1_host proxy1_port global debug cur_proxy
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
set con "" set con ""
if {$proxy2 != ""} { append con "CONNECT $hostport HTTP/1.1\r\n"
append con "CONNECT $proxy2 HTTP/1.1\r\n" append con "Host: $hostport\r\n"
append con "Host: $proxy2\r\n\r\n" append con "Connection: close\r\n\r\n"
} else {
append con "CONNECT $dest HTTP/1.1\r\n" puts stderr "pxy=$which CONNECT $hostport HTTP/1.1 via $cur_proxy"
append con "Host: $dest\r\n\r\n"
}
puts -nonewline $sock $con puts -nonewline $sock $con
flush $sock flush $sock
...@@ -172,68 +90,413 @@ proc handle_connection {fh host port} { ...@@ -172,68 +90,413 @@ proc handle_connection {fh host port} {
set r "" set r ""
set cnt 0 set cnt 0
while {1} { while {1} {
incr cnt
set c [read $sock 1] set c [read $sock 1]
if {$c == ""} { if {$c == ""} {
check_closed check_closed
after 20 after 20
} }
incr cnt
if {$debug} {
.b configure -text "A $cnt -- $c"
update
}
append r $c append r $c
if {[regexp "\r\n\r\n" $r] || [regexp "a--no--\n\n" $r]} { if {[regexp "\r\n\r\n" $r] || [regexp "a--no--\n\n" $r]} {
break break
} }
if {$cnt > 3000} { if {$cnt > 30000} {
break break
} }
} }
if {! [regexp {HTTP/.* 200} $r]} { if {! [regexp {HTTP/.* 200} $r]} {
puts stderr "did not find HTTP 200 #1" puts stderr "did not find HTTP 200 #1"
if {1} { destroy .
destroy . exit 1
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 != ""} { proc do_connect_socks5 {sock hostport which} {
set con "" global debug cur_proxy
append con "CONNECT $dest HTTP/1.1\r\n"
append con "Host: $dest\r\n\r\n"
puts -nonewline $sock $con set s [split $hostport ":"]
flush $sock 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 len [string length $host]
set cnt 0 set p1 [binary format ccccc 5 1 0 3 $len]
while {1} { 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] set c [read $sock 1]
if {$c == ""} { if {$c == ""} {
check_closed check_closed
after 20 after 20
continue
} }
incr cnt break;
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
}
} }
if {! [regexp {HTTP/.* 200} $r]} { if {$c == ""} {
puts stderr "did not find HTTP 200 #2" puts stderr "socks5 failure c: $r"
destroy . destroy .
exit 1 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 $fh readable xfer_in_to_out
fileevent $sock readable xfer_out_to_in 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
...@@ -38,6 +38,9 @@ ...@@ -38,6 +38,9 @@
# (the first CONNECT is done through host1:port1 to host2:port2 # (the first CONNECT is done through host1:port1 to host2:port2
# and then a 2nd CONNECT to the destination VNC server.) # 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' # -showcert Only fetch the certificate using the 'openssl s_client'
# command (openssl(1) must in installed). # command (openssl(1) must in installed).
# #
...@@ -46,6 +49,8 @@ ...@@ -46,6 +49,8 @@
# #
# A few other args (not related to SSL and certs): # 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 # -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. # must be able to log into the remote machine via ssh.
# #
...@@ -112,12 +117,14 @@ VNCVIEWERCMD=${VNCVIEWERCMD:-vncviewer} ...@@ -112,12 +117,14 @@ VNCVIEWERCMD=${VNCVIEWERCMD:-vncviewer}
# Same for STUNNEL, e.g. set it to /path/to/stunnel or stunnel4, etc. # 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 if [ "X$SS_DEBUG" != "X" ]; then
set -xv set -xv
fi fi
PATH=$PATH:/usr/sbin:/usr/local/sbin:/dist/sbin; export PATH 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 if [ "X$STUNNEL" = "X" ]; then
type stunnel4 > /dev/null 2>&1 type stunnel4 > /dev/null 2>&1
if [ $? = 0 ]; then if [ $? = 0 ]; then
...@@ -131,23 +138,32 @@ help() { ...@@ -131,23 +138,32 @@ help() {
tail -n +2 "$0" | sed -e '/^$/ q' tail -n +2 "$0" | sed -e '/^$/ q'
} }
secondtry=""
gotalpha="" gotalpha=""
use_ssh="" use_ssh=""
use_sshssl="" use_sshssl=""
direct_connect="" direct_connect=""
ssh_sleep=15 ssh_sleep=15
# sleep longer in -listen mode:
if echo "$*" | grep '.*-listen' > /dev/null; then if echo "$*" | grep '.*-listen' > /dev/null; then
ssh_sleep=1800 ssh_sleep=1800
fi fi
ssh_cmd="" ssh_cmd=""
# env override of ssh_cmd:
if [ "X$SS_VNCVIEWER_SSH_CMD" != "X" ]; then if [ "X$SS_VNCVIEWER_SSH_CMD" != "X" ]; then
ssh_cmd="$SS_VNCVIEWER_SSH_CMD" ssh_cmd="$SS_VNCVIEWER_SSH_CMD"
fi fi
ssh_args="" ssh_args=""
showcert="" showcert=""
reverse="" reverse=""
if [ "X$1" = "X-viewerflavor" ]; then if [ "X$1" = "X-viewerflavor" ]; then
# special case, try to guess which viewer:
#
if echo "$VNCVIEWERCMD" | egrep -i '^(xmessage|sleep )' > /dev/null; then if echo "$VNCVIEWERCMD" | egrep -i '^(xmessage|sleep )' > /dev/null; then
echo "unknown" echo "unknown"
exit 0 exit 0
...@@ -160,6 +176,7 @@ if [ "X$1" = "X-viewerflavor" ]; then ...@@ -160,6 +176,7 @@ if [ "X$1" = "X-viewerflavor" ]; then
echo "ultravnc" echo "ultravnc"
exit 0 exit 0
fi fi
# OK, run it for help output...
str=`$VNCVIEWERCMD -h 2>&1 | head -n 5` str=`$VNCVIEWERCMD -h 2>&1 | head -n 5`
if echo "$str" | grep -i 'TightVNC.viewer' > /dev/null; then if echo "$str" | grep -i 'TightVNC.viewer' > /dev/null; then
echo "tightvnc" echo "tightvnc"
...@@ -173,6 +190,7 @@ if [ "X$1" = "X-viewerflavor" ]; then ...@@ -173,6 +190,7 @@ if [ "X$1" = "X-viewerflavor" ]; then
exit 0 exit 0
fi fi
# maxconn is something we added to stunnel, this disables it:
if [ "X$SS_VNCVIEWER_NO_MAXCONN" != "X" ]; then if [ "X$SS_VNCVIEWER_NO_MAXCONN" != "X" ]; then
STUNNEL_EXTRA_OPTS=`echo "$STUNNEL_EXTRA_OPTS" | sed -e 's/maxconn/#maxconn/'` STUNNEL_EXTRA_OPTS=`echo "$STUNNEL_EXTRA_OPTS" | sed -e 's/maxconn/#maxconn/'`
elif echo "$VNCVIEWERCMD" | egrep -i '^(xmessage|sleep )' > /dev/null; then elif echo "$VNCVIEWERCMD" | egrep -i '^(xmessage|sleep )' > /dev/null; then
...@@ -206,6 +224,8 @@ do ...@@ -206,6 +224,8 @@ do
;; ;;
"-reverse") reverse=1 "-reverse") reverse=1
;; ;;
"-2nd") secondtry=1
;;
"-grab") VNCVIEWER_GRAB_SERVER=1; export VNCVIEWER_GRAB_SERVER "-grab") VNCVIEWER_GRAB_SERVER=1; export VNCVIEWER_GRAB_SERVER
;; ;;
"-h"*) help; exit 0 "-h"*) help; exit 0
...@@ -218,11 +238,13 @@ do ...@@ -218,11 +238,13 @@ do
shift shift
done done
# this is the -t ssh option (gives better keyboard responsd thru SSH tunnel)
targ="-t" targ="-t"
if [ "X$SS_VNCVIEWER_NO_T" != "X" ]; then if [ "X$SS_VNCVIEWER_NO_T" != "X" ]; then
targ="" targ=""
fi fi
# set the alpha blending env. hack:
if [ "X$gotalpha" = "X1" ]; then if [ "X$gotalpha" = "X1" ]; then
VNCVIEWER_ALPHABLEND=1 VNCVIEWER_ALPHABLEND=1
export VNCVIEWER_ALPHABLEND export VNCVIEWER_ALPHABLEND
...@@ -230,9 +252,11 @@ else ...@@ -230,9 +252,11 @@ else
NO_ALPHABLEND=1 NO_ALPHABLEND=1
export NO_ALPHABLEND export NO_ALPHABLEND
fi fi
if [ "X$reverse" != "X" ]; then if [ "X$reverse" != "X" ]; then
ssh_sleep=1800 ssh_sleep=1800
if [ "X$proxy" != "X" ]; then if [ "X$proxy" != "X" ]; then
# check proxy usage under reverse connection:
if [ "X$use_ssh" = "X" -a "X$use_sshssl" = "X" ]; then if [ "X$use_ssh" = "X" -a "X$use_sshssl" = "X" ]; then
echo "" echo ""
echo "*Warning*: SSL -listen and a Web proxy does not make sense." echo "*Warning*: SSL -listen and a Web proxy does not make sense."
...@@ -247,12 +271,16 @@ if [ "X$reverse" != "X" ]; then ...@@ -247,12 +271,16 @@ if [ "X$reverse" != "X" ]; then
fi fi
fi fi
if [ "X$ssh_cmd" = "X" ]; then if [ "X$ssh_cmd" = "X" ]; then
# if no remote ssh cmd, sleep a bit:
ssh_cmd="sleep $ssh_sleep" ssh_cmd="sleep $ssh_sleep"
fi fi
# this should be a host:display:
#
orig="$1" orig="$1"
shift shift
# check -ssh and -mycert/-verify conflict:
if [ "X$use_ssh" = "X1" -a "X$use_sshssl" = "X" ]; then if [ "X$use_ssh" = "X1" -a "X$use_sshssl" = "X" ]; then
if [ "X$mycert" != "X" -o "X$verify" != "X" ]; then if [ "X$mycert" != "X" -o "X$verify" != "X" ]; then
echo "-mycert and -verify cannot be used in -ssh mode" 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 ...@@ -260,12 +288,15 @@ if [ "X$use_ssh" = "X1" -a "X$use_sshssl" = "X" ]; then
fi fi
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 if echo "$orig" | grep '^V[Nn][Cc]://' > /dev/null; then
SSVNC_NO_ENC_WARN=1 SSVNC_NO_ENC_WARN=1
export SSVNC_NO_ENC_WARN export SSVNC_NO_ENC_WARN
orig=`echo "$orig" | sed -e 's/^...:/vnc:/'` orig=`echo "$orig" | sed -e 's/^...:/vnc:/'`
fi fi
# interprest the pseudo URL proto:// strings:
if echo "$orig" | grep '^vnc://' > /dev/null; then if echo "$orig" | grep '^vnc://' > /dev/null; then
orig=`echo "$orig" | sed -e 's,vnc://,,'` orig=`echo "$orig" | sed -e 's,vnc://,,'`
verify="" verify=""
...@@ -286,11 +317,14 @@ elif echo "$orig" | grep '^vnc+ssh://' > /dev/null; then ...@@ -286,11 +317,14 @@ elif echo "$orig" | grep '^vnc+ssh://' > /dev/null; then
orig=`echo "$orig" | sed -e 's,vnc.ssh://,,'` orig=`echo "$orig" | sed -e 's,vnc.ssh://,,'`
use_ssh=1 use_ssh=1
fi fi
# (possibly) tell the vncviewer to only listen on lo:
if [ "X$reverse" != "X" -a "X$direct_connect" = "X" ]; then if [ "X$reverse" != "X" -a "X$direct_connect" = "X" ]; then
VNCVIEWER_LISTEN_LOCALHOST=1 VNCVIEWER_LISTEN_LOCALHOST=1
export VNCVIEWER_LISTEN_LOCALHOST export VNCVIEWER_LISTEN_LOCALHOST
fi fi
# rsh mode is an internal/secret thing only I use.
rsh="" rsh=""
if echo "$orig" | grep '^rsh://' > /dev/null; then if echo "$orig" | grep '^rsh://' > /dev/null; then
use_ssh=1 use_ssh=1
...@@ -302,11 +336,11 @@ elif echo "$orig" | grep '^rsh:' > /dev/null; then ...@@ -302,11 +336,11 @@ elif echo "$orig" | grep '^rsh:' > /dev/null; then
orig=`echo "$orig" | sed -e 's,rsh:,,'` orig=`echo "$orig" | sed -e 's,rsh:,,'`
fi fi
# play around with host:display port: # play around with host:display port:
if echo "$orig" | grep ':' > /dev/null; then if echo "$orig" | grep ':' > /dev/null; then
: :
else else
# add or assume :0 if no ':'
if [ "X$reverse" = "X" ]; then if [ "X$reverse" = "X" ]; then
orig="$orig:0" orig="$orig:0"
elif [ "X$orig" = "X" ]; then elif [ "X$orig" = "X" ]; then
...@@ -314,20 +348,24 @@ else ...@@ -314,20 +348,24 @@ else
fi fi
fi fi
# extract host and disp number:
host=`echo "$orig" | awk -F: '{print $1}'` host=`echo "$orig" | awk -F: '{print $1}'`
disp=`echo "$orig" | awk -F: '{print $2}'` disp=`echo "$orig" | awk -F: '{print $2}'`
if [ "X$host" = "X" ]; then if [ "X$host" = "X" ]; then
host=localhost host=localhost
fi fi
if [ $disp -lt 0 ]; then if [ $disp -lt 0 ]; then
# negative means use |n| without question:
port=`expr 0 - $disp` port=`expr 0 - $disp`
elif [ $disp -lt 200 ]; then elif [ $disp -lt 200 ]; then
# less than 200 means 5900+n
if [ "X$reverse" = "X" ]; then if [ "X$reverse" = "X" ]; then
port=`expr $disp + 5900` port=`expr $disp + 5900`
else else
port=`expr $disp + 5500` port=`expr $disp + 5500`
fi fi
else else
# otherwise use the number directly, e.g. 443, 2345
port=$disp port=$disp
fi fi
...@@ -342,8 +380,11 @@ elif uname | grep -i bsd > /dev/null; then ...@@ -342,8 +380,11 @@ elif uname | grep -i bsd > /dev/null; then
# add others... # add others...
fi fi
# this is a crude attempt for unique ports tags, etc.
date_sec=`date +%S` 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 echo "$VNCVIEWERCMD" | grep '^sleep[ ][ ]*[0-9][0-9]*' > /dev/null; then
if [ "X$SS_VNCVIEWER_LISTEN_PORT" = "X" ]; then if [ "X$SS_VNCVIEWER_LISTEN_PORT" = "X" ]; then
p=`echo "$VNCVIEWERCMD" | awk '{print $3}'` p=`echo "$VNCVIEWERCMD" | awk '{print $3}'`
...@@ -360,6 +401,7 @@ elif echo "$VNCVIEWERCMD" | grep '^xmessage[ ][ ]*[0-9][0-9]*' > /dev/null; th ...@@ -360,6 +401,7 @@ elif echo "$VNCVIEWERCMD" | grep '^xmessage[ ][ ]*[0-9][0-9]*' > /dev/null; th
fi fi
fi fi
# utility to find a free port to listen on.
findfree() { findfree() {
try0=$1 try0=$1
try=$try0 try=$try0
...@@ -369,8 +411,13 @@ findfree() { ...@@ -369,8 +411,13 @@ findfree() {
echo "$SS_VNCVIEWER_LISTEN_PORT" echo "$SS_VNCVIEWER_LISTEN_PORT"
return return
fi fi
if [ $try -ge 6000 ]; then
fmax=`expr $try + 1000`
else
fmax=6000
fi
while [ $try -lt 6000 ] while [ $try -lt $fmax ]
do do
if [ "X$inuse" = "X" ]; then if [ "X$inuse" = "X" ]; then
break break
...@@ -390,6 +437,8 @@ findfree() { ...@@ -390,6 +437,8 @@ findfree() {
echo $use0 echo $use0
} }
# utility for exiting; kills some helper processes,
# removes files, etc.
final() { final() {
echo "" echo ""
if [ "X$SS_VNCVIEWER_RM" != "X" ]; then if [ "X$SS_VNCVIEWER_RM" != "X" ]; then
...@@ -420,6 +469,7 @@ final() { ...@@ -420,6 +469,7 @@ final() {
} }
if [ "X$reverse" = "X" ]; then if [ "X$reverse" = "X" ]; then
# normal connections try 5930-5999:
use=`findfree 5930` use=`findfree 5930`
if [ $use -ge 5900 ]; then if [ $use -ge 5900 ]; then
N=`expr $use - 5900` N=`expr $use - 5900`
...@@ -427,6 +477,7 @@ if [ "X$reverse" = "X" ]; then ...@@ -427,6 +477,7 @@ if [ "X$reverse" = "X" ]; then
N=$use N=$use
fi fi
else else
# reverse connections:
p2=`expr $port + 30` p2=`expr $port + 30`
use=`findfree $p2` use=`findfree $p2`
if [ $use -ge 5500 ]; then if [ $use -ge 5500 ]; then
...@@ -436,17 +487,20 @@ else ...@@ -436,17 +487,20 @@ else
fi fi
fi fi
# this is for my special use of ss_vncip -> vncip viewer.
if echo "$0" | grep vncip > /dev/null; then if echo "$0" | grep vncip > /dev/null; then
VNCVIEWERCMD="$VNCIPCMD" VNCVIEWERCMD="$VNCIPCMD"
fi fi
rchk() { rchk() {
# a kludge to set $RANDOM if we are not bash:
if [ "X$BASH_VERSION" = "X" ]; then if [ "X$BASH_VERSION" = "X" ]; then
RANDOM=`date +%S``sh -c 'echo $$'``ps -elf 2>&1 | sum 2>&1 | awk '{print $1}'` RANDOM=`date +%S``sh -c 'echo $$'``ps -elf 2>&1 | sum 2>&1 | awk '{print $1}'`
fi fi
} }
rchk rchk
# a portable, but not absolutely safe, tmp file creator
mytmp() { mytmp() {
tf=$1 tf=$1
rm -rf "$tf" || exit 1 rm -rf "$tf" || exit 1
...@@ -465,6 +519,7 @@ mytmp() { ...@@ -465,6 +519,7 @@ mytmp() {
rchk rchk
} }
# trick for the undocumented rsh://host:port method.
rsh_setup() { rsh_setup() {
if echo "$ssh_host" | grep '@' > /dev/null; then if echo "$ssh_host" | grep '@' > /dev/null; then
ul=`echo "$ssh_host" | awk -F@ '{print $1}'` ul=`echo "$ssh_host" | awk -F@ '{print $1}'`
...@@ -476,6 +531,7 @@ rsh_setup() { ...@@ -476,6 +531,7 @@ rsh_setup() {
ssh_cmd=`echo "$ssh_cmd" | sed -e 's/ -localhost/ /g'` ssh_cmd=`echo "$ssh_cmd" | sed -e 's/ -localhost/ /g'`
} }
# trick for the undocumented rsh://host:port method.
rsh_viewer() { rsh_viewer() {
trap "final" 0 2 15 trap "final" 0 2 15
if [ "X$PORT" = "X" ]; then if [ "X$PORT" = "X" ]; then
...@@ -489,22 +545,505 @@ rsh_viewer() { ...@@ -489,22 +545,505 @@ rsh_viewer() {
echo "$VNCVIEWERCMD" "$@" $ssh_host:$vdpy echo "$VNCVIEWERCMD" "$@" $ssh_host:$vdpy
echo "" echo ""
$VNCVIEWERCMD "$@" $ssh_host:$vdpy $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 if [ "X$use_ssh" = "X1" ]; then
#
# USING SSH
#
ssh_port="22" ssh_port="22"
ssh_host="$host" ssh_host="$host"
vnc_host="localhost" vnc_host="localhost"
# let user override ssh via $SSH
ssh=${SSH:-"ssh -x"} 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 if echo "$proxy" | grep "," > /dev/null; then
proxy1=`echo "$proxy" | awk -F, '{print $1}'` proxy1=`echo "$proxy" | awk -F, '{print $1}'`
proxy2=`echo "$proxy" | awk -F, '{print $2}'` proxy2=`echo "$proxy" | awk -F, '{print $2}'`
# user1@gw1.com:port1,user2@ws2:port2 # user1@gw1.com:port1,user2@ws2:port2
ssh_host1=`echo "$proxy1" | awk -F: '{print $1}'` ssh_host1=`echo "$proxy1" | awk -F: '{print $1}'`
ssh_port1=`echo "$proxy1" | awk -F: '{print $2}'` ssh_port1=`echo "$proxy1" | awk -F: '{print $2}'`
if [ "X$ssh_port1" != "X" ]; then if [ "X$ssh_port1" != "X" ]; then
ssh_port1="-p 22" ssh_port1="-p $ssh_port1"
fi fi
ssh_host2=`echo "$proxy2" | awk -F: '{print $1}'` ssh_host2=`echo "$proxy2" | awk -F: '{print $1}'`
ssh_user2=`echo "$ssh_host2" | awk -F@ '{print $1}'` ssh_user2=`echo "$ssh_host2" | awk -F@ '{print $1}'`
...@@ -522,8 +1061,9 @@ if [ "X$use_ssh" = "X1" ]; then ...@@ -522,8 +1061,9 @@ if [ "X$use_ssh" = "X1" ]; then
proxport=`findfree 3500` proxport=`findfree 3500`
echo echo
echo "Running 1st ssh proxy:" echo "Running 1st ssh proxy:"
echo "$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\""
$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"
ssh_args="$ssh_args -o NoHostAuthenticationForLocalhost=yes" ssh_args="$ssh_args -o NoHostAuthenticationForLocalhost=yes"
sleep 1 sleep 1
stty sane stty sane
...@@ -538,6 +1078,7 @@ if [ "X$use_ssh" = "X1" ]; then ...@@ -538,6 +1078,7 @@ if [ "X$use_ssh" = "X1" ]; then
ssh_host=`echo "$proxy" | awk -F: '{print $1}'` ssh_host=`echo "$proxy" | awk -F: '{print $1}'`
vnc_host="$host" vnc_host="$host"
fi fi
echo "" echo ""
echo "Running ssh:" echo "Running ssh:"
sz=`echo "$ssh_cmd" | wc -c` sz=`echo "$ssh_cmd" | wc -c`
...@@ -632,8 +1173,16 @@ if [ "X$use_ssh" = "X1" ]; then ...@@ -632,8 +1173,16 @@ if [ "X$use_ssh" = "X1" ]; then
stty sane stty sane
i=0 i=0
while [ $i -lt 10 ]; do if type perl > /dev/null 2>&1; then
sleep 1 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'` 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 if echo "$PORT" | grep '^[0-9][0-9]*$' > /dev/null; then
break break
...@@ -660,6 +1209,9 @@ if [ "X$use_ssh" = "X1" ]; then ...@@ -660,6 +1209,9 @@ if [ "X$use_ssh" = "X1" ]; then
exit $? exit $?
fi fi
PPROXY_SOCKS=1 PPROXY_SOCKS=1
if [ "X$SSVNC_SOCKS5" != "X" ]; then
PPROXY_SOCKS=5
fi
export PPROXY_SOCKS export PPROXY_SOCKS
host="localhost" host="localhost"
port="$PORT" port="$PORT"
...@@ -704,13 +1256,19 @@ if [ "X$use_ssh" = "X1" ]; then ...@@ -704,13 +1256,19 @@ if [ "X$use_ssh" = "X1" ]; then
if [ "X$getport" != "X" ]; then if [ "X$getport" != "X" ]; then
: :
elif [ "X$ssh_cmd" = "Xsleep $ssh_sleep" ] ; then elif [ "X$ssh_cmd" = "Xsleep $ssh_sleep" ] ; then
#echo T sleep 1
sleep 1 sleep 1
elif echo "$ssh_cmd" | grep '^sleep ' >/dev/null; then
#echo T sleep 2
sleep 2
else else
# let any command get started a bit. # let any command get started a bit.
#echo T sleep 5
sleep 5 sleep 5
fi fi
echo "" echo ""
if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then
#echo T sleep $SSVNC_EXTRA_SLEEP
sleep $SSVNC_EXTRA_SLEEP sleep $SSVNC_EXTRA_SLEEP
fi fi
#reset #reset
...@@ -724,6 +1282,13 @@ if [ "X$use_ssh" = "X1" ]; then ...@@ -724,6 +1282,13 @@ if [ "X$use_ssh" = "X1" ]; then
echo "$VNCVIEWERCMD" "$@" localhost:$N echo "$VNCVIEWERCMD" "$@" localhost:$N
echo "" echo ""
$VNCVIEWERCMD "$@" localhost:$N $VNCVIEWERCMD "$@" localhost:$N
if [ $? != 0 ]; then
echo "vncviewer command failed: $?"
if [ "X$secondtry" = "X1" ]; then
sleep 2
$VNCVIEWERCMD "$@" localhost:$N
fi
fi
else else
echo "" echo ""
echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode." echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode."
...@@ -765,229 +1330,26 @@ if [ "X$mycert" != "X" ]; then ...@@ -765,229 +1330,26 @@ if [ "X$mycert" != "X" ]; then
cert="cert = $mycert" cert="cert = $mycert"
fi 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="" ptmp=""
if [ "X$proxy" != "X" ]; then if [ "X$proxy" != "X" ]; then
ptmp="/tmp/ss_vncviewer${RANDOM}.$$.pl" ptmp="/tmp/ss_vncviewer${RANDOM}.$$.pl"
mytmp "$ptmp" mytmp "$ptmp"
PPROXY_REMOVE=1; export PPROXY_REMOVE
pcode "$ptmp" pcode "$ptmp"
if [ "X$showcert" != "X1" -a "X$direct_connect" = "X" ]; then if [ "X$showcert" != "X1" -a "X$direct_connect" = "X" ]; then
if uname | grep Darwin >/dev/null; 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 PPROXY_LISTEN=$nd
export PPROXY_LISTEN export PPROXY_LISTEN
$ptmp 2>/dev/null & $ptmp 2>/dev/null &
sleep 3 #sleep 3
sleep 2
host="localhost" host="localhost"
port="$nd" port="$nd"
connect="connect = localhost:$nd" connect="connect = localhost:$nd"
else else
# otherwise on unix we can exec it:
connect="exec = $ptmp" connect="exec = $ptmp"
fi fi
else else
...@@ -1002,7 +1364,7 @@ if [ "X$showcert" = "X1" ]; then ...@@ -1002,7 +1364,7 @@ if [ "X$showcert" = "X1" ]; then
PPROXY_LISTEN=$use PPROXY_LISTEN=$use
export PPROXY_LISTEN export PPROXY_LISTEN
$ptmp 2>/dev/null & $ptmp 2>/dev/null &
sleep 3 sleep 1
host="localhost" host="localhost"
port="$use" port="$use"
fi fi
...@@ -1018,8 +1380,11 @@ if [ "X$direct_connect" != "X" ]; then ...@@ -1018,8 +1380,11 @@ if [ "X$direct_connect" != "X" ]; then
echo "** NOTE: THERE WILL BE NO SSL OR SSH ENCRYPTION **" echo "** NOTE: THERE WILL BE NO SSL OR SSH ENCRYPTION **"
echo "" echo ""
fi fi
x=""
if [ "X$SSVNC_NO_ENC_WARN" != "X" ]; then 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 elif type printf > /dev/null 2>&1; then
printf "Are you sure you want to continue? [y]/n " printf "Are you sure you want to continue? [y]/n "
read x read x
...@@ -1036,12 +1401,15 @@ if [ "X$direct_connect" != "X" ]; then ...@@ -1036,12 +1401,15 @@ if [ "X$direct_connect" != "X" ]; then
export PPROXY_LISTEN export PPROXY_LISTEN
$ptmp & $ptmp &
if [ "X$reverse" = "X" ]; then if [ "X$reverse" = "X" ]; then
sleep 2 #sleep 2
#echo T sleep 1
sleep 1
fi fi
host="localhost" host="localhost"
disp="$N" disp="$N"
fi fi
if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then
#echo T sleep $SSVNC_EXTRA_SLEEP
sleep $SSVNC_EXTRA_SLEEP sleep $SSVNC_EXTRA_SLEEP
fi fi
if [ "X$reverse" = "X" ]; then if [ "X$reverse" = "X" ]; then
...@@ -1049,6 +1417,13 @@ if [ "X$direct_connect" != "X" ]; then ...@@ -1049,6 +1417,13 @@ if [ "X$direct_connect" != "X" ]; then
trap "final" 0 2 15 trap "final" 0 2 15
echo "" echo ""
$VNCVIEWERCMD "$@" $host:$disp $VNCVIEWERCMD "$@" $host:$disp
if [ $? != 0 ]; then
echo "vncviewer command failed: $?"
if [ "X$secondtry" = "X1" ]; then
sleep 2
$VNCVIEWERCMD "$@" $host:$disp
fi
fi
else else
echo "" echo ""
echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode." echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode."
...@@ -1175,6 +1550,8 @@ sleep 1 ...@@ -1175,6 +1550,8 @@ sleep 1
echo "" echo ""
echo "Running stunnel:" echo "Running stunnel:"
echo "$STUNNEL $tmp" echo "$STUNNEL $tmp"
st=`echo "$STUNNEL" | awk '{print $1}'`
$st -help > /dev/null 2>&1
$STUNNEL "$tmp" < /dev/tty > /dev/tty & $STUNNEL "$tmp" < /dev/tty > /dev/tty &
stunnel_pid=$! stunnel_pid=$!
echo "" echo ""
...@@ -1182,13 +1559,14 @@ echo "" ...@@ -1182,13 +1559,14 @@ echo ""
# pause here to let the user supply a possible passphrase for the # pause here to let the user supply a possible passphrase for the
# mycert key: # mycert key:
if [ "X$mycert" != "X" ]; then if [ "X$mycert" != "X" ]; then
sleep 2 sleep 1
echo "" echo ""
echo "(pausing for possible certificate passphrase dialog)" echo "(pausing for possible certificate passphrase dialog)"
echo "" echo ""
sleep 2 sleep 4
fi fi
sleep 2 #echo T sleep 1
sleep 1
rm -f "$tmp" rm -f "$tmp"
echo "" echo ""
...@@ -1201,6 +1579,13 @@ if [ "X$reverse" = "X" ]; then ...@@ -1201,6 +1579,13 @@ if [ "X$reverse" = "X" ]; then
trap "final" 0 2 15 trap "final" 0 2 15
echo "" echo ""
$VNCVIEWERCMD "$@" localhost:$N $VNCVIEWERCMD "$@" localhost:$N
if [ $? != 0 ]; then
echo "vncviewer command failed: $?"
if [ "X$secondtry" = "X1" ]; then
sleep 2
$VNCVIEWERCMD "$@" localhost:$N
fi
fi
else else
echo "" echo ""
echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode." echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode."
......
...@@ -8,7 +8,7 @@ exec wish "$0" "$@" ...@@ -8,7 +8,7 @@ exec wish "$0" "$@"
# ssvnc.tcl: gui wrapper to the programs in this # ssvnc.tcl: gui wrapper to the programs in this
# package. Also sets up service port forwarding. # package. Also sets up service port forwarding.
# #
set version 1.0.19 set version 1.0.20
set buck_zero $argv0 set buck_zero $argv0
...@@ -111,16 +111,16 @@ proc ts_help {} { ...@@ -111,16 +111,16 @@ proc ts_help {} {
You MUST be able to log in via SSH to the remote terminal server. 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. 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 This mode is started by the commands 'tsvnc' or 'ssvnc -ts' or
toggling by pressing Ctrl-t. "SSVNC Mode" under Options -> Advanced toggling by pressing Ctrl-t. "SSVNC Mode" under Options -> Advanced
will also return to the full SSVNC. will also return to the full SSVNC.
Or in your ~/.ssvncrc (or ~/ssvnc_rc on Windows) put "mode=tsvnc" Or in your ~/.ssvncrc (or ~/ssvnc_rc on Windows) put "mode=tsvnc"
to have the tool always start up in that 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
To constrain the UI, run with -tso or SSVNC_TS_ALWAYS set to prevent Services mode.
leaving the Terminal Services mode.
Hosts and Displays: Hosts and Displays:
...@@ -150,36 +150,61 @@ proc ts_help {} { ...@@ -150,36 +150,61 @@ proc ts_help {} {
you *MUST* supply the remote username. This entry is passed to SSH; 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). 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: Proxies/Gateways:
Proxy/Gateway is usually a gateway machine to log into via SSH Proxy/Gateway is usually a gateway machine to log into via SSH that is
that is not the machine running the VNC terminal services. 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" For example if a company had a central login server: "ssh.company.com"
(accessible from the internet) and the internal server name was (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 VNC Terminal Server: ts-server
Proxy/Gateway: ssh.company.com Proxy/Gateway: ssh.company.com
It is OK if the hostname "ts-server" only resolves inside the firewall. 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 The 2nd host, ts-server in this example, MUST also be running an SSH
SSH server and you must be able to log into it. 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) Use username@host (e.g. joe@ts-server or jsmith@ssh.company.com)
if the user name differs between machines. if the user name differs between machines.
To use a non-standard ssh port (i.e. a port other than 22) you need to To use a non-standard ssh port (i.e. a port other than 22) in
use the Proxies/Gateways as well. Something like this for port 2222: 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 VNC Terminal Server: fred@someplace.no
Proxy/Gateway: jsmith@ssh.company.com:2222 Proxy/Gateway: http://myproxy.west:8080
The username@ is not needed if it is the same as on this machine. The or for SOCKS:
above will also work going to a different internal machine,
e.g. "ts-server", as in the first example. 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: Options:
...@@ -247,7 +272,7 @@ proc ts_help {} { ...@@ -247,7 +272,7 @@ proc ts_help {} {
Real X servers: 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 regular X session running on the physical hardware that you are
ALREADY logged into you can access to that display as well (x11vnc ALREADY logged into you can access to that display as well (x11vnc
will find it). will find it).
...@@ -262,6 +287,10 @@ proc ts_help {} { ...@@ -262,6 +287,10 @@ proc ts_help {} {
X server on the workstation, a VIRTUAL (Xvfb, etc.) server will be X server on the workstation, a VIRTUAL (Xvfb, etc.) server will be
created for you (that may or may not be what you want). 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: More Info:
See these links for more information: See these links for more information:
...@@ -299,8 +328,11 @@ proc help {} { ...@@ -299,8 +328,11 @@ proc help {} {
it is often "0". Examples: it is often "0". Examples:
snoopy:0 snoopy:0
far-away.east:0 far-away.east:0
sunray-srv1.west:17 sunray-srv1.west:17
24.67.132.27:0 24.67.132.27:0
Then click on "Connect". When you do so the STUNNEL program will be Then click on "Connect". When you do so the STUNNEL program will be
...@@ -311,12 +343,12 @@ proc help {} { ...@@ -311,12 +343,12 @@ proc help {} {
port of the SSL tunnel which, in turn, encrypts and redirects the port of the SSL tunnel which, in turn, encrypts and redirects the
connection to the remote VNC server. 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 using the VNC protocol (i.e. VNC is tunnelled through the SSL channel
after it is established). "x11vnc -ssl ..." does this, and any VNC 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. 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 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.: the VNC display = port - 5900), use the full port number itself, e.g.:
...@@ -329,55 +361,77 @@ proc help {} { ...@@ -329,55 +361,77 @@ proc help {} {
e.g.: 24.67.132.27:-80 e.g.: 24.67.132.27:-80
*IMPORTANT*: If you do not take the steps to verify the VNC Server's SSL Certificate Verification:
SSL Certificate, you are vulnerable to a Man-In-The-Middle attack.
Only passive network sniffing attacks will be prevented. *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 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) 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 When "Verify All Certs" is checked, this check is always enforced,
so the first time you connect to a new server you may need to follow and so the first time you connect to a new server you may need to
a few dialogs to inspect and save the server certificate. See the follow a few dialogs to inspect and save the server certificate.
"Certs... -> Help" for information on how to manage certificates. See the "Certs... -> Help" for information on how to manage certificates.
"Fetch Cert" and "Verify All Certs" are currently disabled in the "Fetch Cert" and "Verify All Certs" are currently disabled in the rare
"SSH + SSL" mode (e.g. SSH is used to enter a firewall gateway, "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). 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 Note that on Windows when the Viewer connection is finished you may
need to terminate STUNNEL manually from the System Tray (right click 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: VNC Password:
On Unix or MacOSX if there is a VNC password for the server you On Unix or MacOSX if there is a VNC password for the server you
can enter it in the "VNC Password:" entry box. can enter it in the "VNC Password:" entry box.
This is *REQUIRED* on MacOSX when Chicken of the VNC (the default) This is *REQUIRED* on MacOSX when Chicken of the VNC is used.
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 Unix if you choose not to enter the password you will be prompted
On Windows TightVNC viewer should prompt you. 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 NOTE: when you Save a VNC profile, the password is not saved (you
need to enter it each time). need to enter it each time).
SSH: SSH:
Click on "Use SSH" or go to "Options ..." if you want to use an Click on "Use SSH" if you want to use an *SSH* tunnel instead of SSL
*SSH* tunnel instead of SSL (then the VNC Server does not need to (then the VNC Server does not need to speak SSL or use STUNNEL).
speak SSL or use STUNNEL). You will need to be able to login to the You will need to be able to login to your account on the remote host
remote host via SSH (e.g. via password or ssh-agent). 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. if your remote username is different from the one on the local viewer
Use something like "username@hostname.com:0" if the remote username machine. On Windows you MUST supply the "username@" part.
is different. "SSH + SSL" is similar but its use is more rare. See
the Help under Options for more info.
See Tip 13) below for how to make this application be SSH only with "SSH + SSL" is similar but its use is more rare because it requires 2
the -ssh command line option. 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: Proxies/Gateways:
...@@ -387,40 +441,49 @@ proc help {} { ...@@ -387,40 +441,49 @@ proc help {} {
entry box: entry box:
VNC Host-Display: host:number VNC Host-Display: host:number
Proxy/Gateway: gw-host:port Proxy/Gateway: proxy-host:port
e.g.: e.g.:
VNC Host-Display: far-away.east:0 VNC Host-Display: far-away.east:0
Proxy/Gateway: mygateway.com:8080 Proxy/Gateway: myproxy.west: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.
If the "double proxy" case is required (e.g. coming out of a web 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.: reach the VNC server), separate them via a comma, e.g.:
VNC Host-Display: far-away:0 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 -> myproxy.west -> myhome.net -> far-away (VNC)
So it goes: viewer -> local-proxy -> mygateway.com -> 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: See the ss_vncviewer description and x11vnc FAQ for info on proxies:
http://www.karlrunge.com/x11vnc/#ss_vncviewer http://www.karlrunge.com/x11vnc/#ss_vncviewer
http://www.karlrunge.com/x11vnc/#faq-ssl-java-viewer-proxy http://www.karlrunge.com/x11vnc/#faq-ssl-java-viewer-proxy
SSH Proxies/Gateways: SSH Proxies/Gateways:
Proxy/Gateway also applies to SSH mode, it is a usually a gateway 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 machine to log into via ssh that is not the workstation running the
VNC server. 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" For example if a company had a central login server: "ssh.company.com"
(accessible from the internet) and the internal workstation name was (accessible from the internet) and the internal workstation name was
...@@ -434,25 +497,58 @@ proc help {} { ...@@ -434,25 +497,58 @@ proc help {} {
The 2nd leg, from ssh.company.com -> joes-pc is done by a ssh -L 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). redir and is not encrypted (but viewer -> ssh.company.com is encrypted).
To SSH encrypt both legs, try the "double gateway" using the above To SSH encrypt BOTH legs, try the "double SSH gateway" method using
"comma" notation: the "comma" notation:
VNC Host:Display: localhost:0 VNC Host:Display: localhost:0
Proxy/Gateway: ssh.company.com,joes-pc Proxy/Gateway: ssh.company.com,joes-pc
this requires an SSH server running on joes-pc. Use username@host this requires an SSH server running on joes-pc. So an initial SSH
(e.g. joe@joes-pc jsmith@ssh.company.com) if the user name differs. 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 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 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: Remote SSH Command:
...@@ -460,15 +556,16 @@ proc help {} { ...@@ -460,15 +556,16 @@ proc help {} {
to run on the remote ssh host in the "Remote SSH Command" entry. 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 default is just to sleep a bit (e.g. sleep 30) to make sure
the port tunnels are established. Alternatively you could have the the port tunnels are established. Alternatively you could have the
remote command start the VNC server, e.g. x11vnc -nopw -display :0 remote command start the VNC server, e.g.
-rfbport 5900 -localhost
x11vnc -display :0 -rfbport 5900 -localhost -nopw
When starting the VNC server this way, note that sometimes you When starting the VNC server this way, note that sometimes you
will need to correlate the VNC Display number with the "-rfbport" will need to correlate the VNC Display number with the "-rfbport"
(or similar) option of the server. E.g.: (or similar) option of the server. E.g.:
VNC Host:Display username@somehost.com:2 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 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 vncserver(1) output) to not need to specify the VNC display number
...@@ -518,9 +615,9 @@ proc help {} { ...@@ -518,9 +615,9 @@ proc help {} {
More Options: More Options:
To set other Options, e.g. to use SSH instead of STUNNEL SSL, or To set other Options, e.g. for View-Only usage or to limit the
View-Only usage, click on the "Options ..." button and read the Help number of colors used. click on the "Options ..." button and read
there. the Help there.
Profiles: Profiles:
...@@ -560,24 +657,24 @@ proc help {} { ...@@ -560,24 +657,24 @@ proc help {} {
Ctrl-N or try Ctrl-LeftButton -> New SSVNC_GUI. On Windows you Ctrl-N or try Ctrl-LeftButton -> New SSVNC_GUI. On Windows you
will have to manually Start a new one: Start -> Run ..., etc. 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: 2) If you use "SHELL" for the "Remote SSH Command" (or in the display
no VNC viewer will be launched. On Windows "user@hostname cmd=PUTTY" line: "user@hostname cmd=SHELL") then you get an SSH shell only:
will try to use putty.exe (better terminal emulation than no VNC viewer will be launched. On Windows "PUTTY" will try
plink.exe). A ShortCut for this is Ctrl-S as long as user@hostname to use putty.exe (better terminal emulation than plink.exe).
is present in the entry box. You can also put the string in the A ShortCut for this is Ctrl-S as long as user@hostname is present
"Remote SSH Command" entry. in the entry box.
3) If you use "user@hostname cmd=KNOCK" then only the port-knocking 3) If you use "KNOCK" for the "Remote SSH Command" (or int he display
is performed. A ShortCut for this is Ctrl-P as long as hostname line "user@hostname cmd=KNOCK") then only the port-knocking is
is present in the entry box. If it matches cmd=KNOCKF, i.e. an performed. A ShortCut for this is Ctrl-P as long as hostname
extra "F", then the port-knocking "FINISH" sequence is sent, if any. 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. 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 4) Pressing the "Load" button or pressing Ctrl-L or Clicking the Right
mouse button on the main GUI will invoke the Load dialog. 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 ENCRYPTION, use the "vnc://" prefix, e.g. vnc://far-away.east:0
This also works for reverse connections (see below). This also works for reverse connections (see below).
...@@ -600,8 +697,8 @@ proc help {} { ...@@ -600,8 +697,8 @@ proc help {} {
port is the desired local listening port. Then click Connect. 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. 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 On Windows set it to "NOTEPAD" or similar; you can't control the
the port though. It is usually 5930. 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), 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 you will probably need to set the env. var. SS_VNCVIEWER_NO_T=1
...@@ -609,10 +706,16 @@ proc help {} { ...@@ -609,10 +706,16 @@ proc help {} {
command from being run). command from being run).
9) In the VNC Host:Display entry you can also use these "URL-like" 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 prefixes:
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 vncs://host:0, vncssl://host:0, vnc+ssl://host:0 for SSL
the command line, e.g.: ssvnc vnc+ssh://mymachine:10
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 10) Mobile USB memory stick / flash drive usage: You can unpack
ssvnc to a flash drive for impromptu usage (e.g. from a friends ssvnc to a flash drive for impromptu usage (e.g. from a friends
...@@ -624,7 +727,7 @@ proc help {} { ...@@ -624,7 +727,7 @@ proc help {} {
WARNING: if you use ssvnc from an "Internet Cafe", i.e. an WARNING: if you use ssvnc from an "Internet Cafe", i.e. an
untrusted computer, an unscrupulous person may be capturing 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 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 directory you want. It can be set after starting ssvnc by putting
...@@ -640,7 +743,7 @@ proc help {} { ...@@ -640,7 +743,7 @@ proc help {} {
the SSH tunnel. For example: the SSH tunnel. For example:
VNC Host:Display user@somehost.com 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= ..." or "PORT= x11vnc -display :0 -localhost", etc. Or use "P= ..."
...@@ -671,9 +774,8 @@ proc help {} { ...@@ -671,9 +774,8 @@ proc help {} {
13) If you want this application to be SSH only, then supply the 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. command line option "-ssh" or set the env. var SSVNC_SSH_ONLY=1.
Then no GUI elements specific to SSL will appear (the Then no GUI elements specific to SSL will appear (the
documentation will refer to the SSL mode, however). You cannot documentation will refer to the SSL mode, however). To convert
Load an SSL profile when in this mode. To convert a running a running app to ssh-only select "Mode: SSH-Only" in Options.
app to ssh-only select "Mode: SSH-Only" in Options.
The wrapper scripts "sshvnc" and "sshvnc.bat" will start it up The wrapper scripts "sshvnc" and "sshvnc.bat" will start it up
automatically this way. automatically this way.
...@@ -699,13 +801,13 @@ proc help {} { ...@@ -699,13 +801,13 @@ proc help {} {
Put "mode=tsvnc" or "mode=sshvnc" in the ~/.ssvncrc file to have Put "mode=tsvnc" or "mode=sshvnc" in the ~/.ssvncrc file to have
the application start up in the given mode. 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.) (The above 4 settings apply only to the Terminal Services Mode.)
...@@ -722,6 +824,14 @@ proc help {} { ...@@ -722,6 +824,14 @@ proc help {} {
jiggle_text .h.f.t 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 # You can also specify the remote SSH command by putting a string like
# #
# cmd=x11vnc -nopw -display :0 -rfbport 5900 -localhost # cmd=x11vnc -nopw -display :0 -rfbport 5900 -localhost
...@@ -1163,7 +1273,7 @@ set msg { ...@@ -1163,7 +1273,7 @@ set msg {
Windows you *MUST* always supply the "user@" part (due to a Windows you *MUST* always supply the "user@" part (due to a
plink deficiency). E.g.: 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 Gateway: If an intermediate gateway machine must be used
...@@ -1190,19 +1300,27 @@ set msg { ...@@ -1190,19 +1300,27 @@ set msg {
VNC Host:Display: localhost:0 VNC Host:Display: localhost:0
Proxy/Gateway: user@gateway-host:port,user@workstation:port 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 Remote Command: In the "Remote SSH Command" entry you can to
indicate that a remote command to be run. The default is indicate that a remote command to be run. The default is
"sleep 15". For example, to run x11vnc for your X :0 display: "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: Trick: If you use "SHELL" asl the "Remote SSH Command" then
no VNC viewer will be launched. On Windows "cmd=PUTTY" will you get an SSH shell only: no VNC viewer will be launched.
try to use putty.exe (better terminal emulation than plink.exe) On Windows "PUTTY" will try to use putty.exe (better terminal
A shortcut for this is Ctrl-S as long as user@hostname is present emulation than plink.exe) A shortcut for this is Ctrl-S as
in the "VNC Host:Display" box. long as user@hostname is present in the "VNC Host:Display" box.
Use SSH + SSL: Use SSH + SSL:
...@@ -1231,13 +1349,15 @@ set msg { ...@@ -1231,13 +1349,15 @@ set msg {
does it attaches to it; otherwise the x11vnc VNC server exits does it attaches to it; otherwise the x11vnc VNC server exits
immediately followed by your VNC Viewer. immediately followed by your VNC Viewer.
The PORT= option just means to let x11vnc pick its own VNC The PORT= option just means to let x11vnc pick its own
port and then connect to whatever it picked. 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' The idea for this mode is you simply type 'username@workstation'
in the VNC Host:Display box, Select 'Options -> Automatically in the VNC Host:Display box, Select 'Options -> Automatically
Find X Session', and then click Connect. The tsvnc mode Find X Session', and then click Connect. The tsvnc mode is
is similar. similar (it runs x11vnc on the remote side with the intent
of automatically finding, or creating, your desktop).
Automatically Find X Login/Greeter: Automatically Find X Login/Greeter:
...@@ -1255,7 +1375,8 @@ set msg { ...@@ -1255,7 +1375,8 @@ set msg {
An initial ssh running 'sudo id' is performed to try to An initial ssh running 'sudo id' is performed to try to
'prime' sudo so the 2nd one that runs x11vnc does not need '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 See the 'X Login' description in 'Terminal Services' Mode
Help for more info. Help for more info.
...@@ -1312,7 +1433,7 @@ set msg { ...@@ -1312,7 +1433,7 @@ set msg {
prior to any connections. prior to any connections.
For reverse connections in SSH or SSH + SSL modes it is a 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. established and remain up waiting for reverse connections.
The default time is "sleep 1800", i.e. 30 mins. You can put The default time is "sleep 1800", i.e. 30 mins. You can put
a longer or shorter sleep in "Remote SSH Command" (perhaps a longer or shorter sleep in "Remote SSH Command" (perhaps
...@@ -2106,7 +2227,8 @@ proc guess_nat_ip {} { ...@@ -2106,7 +2227,8 @@ proc guess_nat_ip {} {
set ip "unknown" set ip "unknown"
if {$s != ""} { if {$s != ""} {
fconfigure $s -buffering none 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 "Host: www.whatismyip.com"
puts $s "Connection: close" puts $s "Connection: close"
puts $s "" puts $s ""
...@@ -2116,6 +2238,7 @@ proc guess_nat_ip {} { ...@@ -2116,6 +2238,7 @@ proc guess_nat_ip {} {
if {! $on && [regexp {<HEAD>} $line]} {set on 1} if {! $on && [regexp {<HEAD>} $line]} {set on 1}
if {! $on && [regexp {<HTML>} $line]} {set on 1} if {! $on && [regexp {<HTML>} $line]} {set on 1}
if {! $on && [regexp {<TITLE>} $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} { if {! $on} {
continue; continue;
} }
...@@ -2297,7 +2420,20 @@ proc launch_windows_ssh {hp file n} { ...@@ -2297,7 +2420,20 @@ proc launch_windows_ssh {hp file n} {
regsub {^.*:} $vnc_disp "" vnc_disp regsub {^.*:} $vnc_disp "" vnc_disp
if {$ts_only} { 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]} { } elseif {![regexp {^-?[0-9][0-9]*$} $vnc_disp]} {
if {[regexp {cmd=SHELL} $hp]} { if {[regexp {cmd=SHELL} $hp]} {
; ;
...@@ -2342,6 +2478,88 @@ proc launch_windows_ssh {hp file n} { ...@@ -2342,6 +2478,88 @@ proc launch_windows_ssh {hp file n} {
set double_ssh "" set double_ssh ""
set p_port "" set p_port ""
if {$proxy != ""} { 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 [regexp {,} $proxy] {
if {$is_win9x} { if {$is_win9x} {
mesg "Double proxy does not work on Win9x" mesg "Double proxy does not work on Win9x"
...@@ -2598,6 +2816,7 @@ proc launch_windows_ssh {hp file n} { ...@@ -2598,6 +2816,7 @@ proc launch_windows_ssh {hp file n} {
if {$vnc_host == ""} { if {$vnc_host == ""} {
set vnc_host "localhost" set vnc_host "localhost"
} }
regsub {^.*@} $vnc_host "" vnc_host
set redir "-L $use:$vnc_host:$vnc_port" set redir "-L $use:$vnc_host:$vnc_port"
if {$use_listen} { if {$use_listen} {
...@@ -3475,7 +3694,21 @@ proc fetch_cert_windows {hp} { ...@@ -3475,7 +3694,21 @@ proc fetch_cert_windows {hp} {
if {$proxy != ""} { if {$proxy != ""} {
global env 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_PROXY) $proxy
set env(SSVNC_LISTEN) $port2 set env(SSVNC_LISTEN) $port2
set env(SSVNC_DEST) "$host:$port" set env(SSVNC_DEST) "$host:$port"
...@@ -3485,9 +3718,22 @@ proc fetch_cert_windows {hp} { ...@@ -3485,9 +3718,22 @@ proc fetch_cert_windows {hp} {
mesg "Starting TCP helper on port $port2 ..." mesg "Starting TCP helper on port $port2 ..."
after 600 after 600
set proxy_pid [exec "connect_br.exe" &] set proxy_pid [exec "connect_br.exe" &]
unset -nocomplain env(SSVNC_PROXY)
unset -nocomplain env(SSVNC_LISTEN) if {$sp == ""} {
unset -nocomplain env(SSVNC_DEST) 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] set ossl [get_openssl]
...@@ -3809,7 +4055,7 @@ proc check_accepted_certs {} { ...@@ -3809,7 +4055,7 @@ proc check_accepted_certs {} {
.acert.f.t insert end $msg .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 pack .acert.f -side top -fill both -expand 1
center_win .acert center_win .acert
...@@ -4053,15 +4299,28 @@ proc launch_unix {hp} { ...@@ -4053,15 +4299,28 @@ proc launch_unix {hp} {
set proxy [get_ssh_proxy $hp] set proxy [get_ssh_proxy $hp]
set sshcmd [get_ssh_cmd $hp] set sshcmd [get_ssh_cmd $hp]
if {$ts_only && $proxy != "" && ![regexp {,} $proxy]} { if {$ts_only} {
regsub {:[0-9]*$} $hpnew "" h2 regsub {:0$} $hpnew "" hpnew
set proxy "$proxy,$h2" if {$proxy == ""} {
regsub {^[^:]*} $hpnew "localhost" hpnew 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 hp=$hp
#puts hpn=$hpnew #puts hpn=$hpnew
#puts pxy=$proxy #puts pxy=$proxy
#puts cmd=$sshcmd #puts cmd=$sshcmd
set hp $hpnew set hp $hpnew
if {$proxy != ""} { if {$proxy != ""} {
...@@ -6021,7 +6280,7 @@ proc create_cert {} { ...@@ -6021,7 +6280,7 @@ proc create_cert {} {
button .ccrt.create -text "Generate Cert" -command {destroy .ccrt; catch {raise .c}; do_oss_create} 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 set ew 40
...@@ -6127,6 +6386,10 @@ proc import_save_browse {{par ".icrt"}} { ...@@ -6127,6 +6386,10 @@ proc import_save_browse {{par ".icrt"}} {
proc do_save {par} { proc do_save {par} {
global import_mode import_file import_save_file global import_mode import_file import_save_file
global also_save_to_accepted_certs 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} { if {$import_save_file == "" && ! $also_save_to_accepted_certs} {
tk_messageBox -parent $par -type ok -icon error \ tk_messageBox -parent $par -type ok -icon error \
...@@ -6378,7 +6641,7 @@ TCQ+tbQ/DOiTXGKx1nlcKoPdkG+QVQVJthlQcpam ...@@ -6378,7 +6641,7 @@ TCQ+tbQ/DOiTXGKx1nlcKoPdkG+QVQVJthlQcpam
pack $w.l -side left pack $w.l -side left
pack $w.e -side left -expand 1 -fill x 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.paste .icrt.plab -side bottom -fill x
pack .icrt.f -side top -fill both -expand 1 pack .icrt.f -side top -fill both -expand 1
...@@ -7253,7 +7516,12 @@ proc get_sound_redir {} { ...@@ -7253,7 +7516,12 @@ proc get_sound_redir {} {
set loc $sound_daemon_local_port set loc $sound_daemon_local_port
if {! [regexp {:} $loc]} { 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" set redir "$sound_daemon_remote_port:$loc"
regsub -all {['" ]} $redir {} redir; #" regsub -all {['" ]} $redir {} redir; #"
...@@ -8260,7 +8528,7 @@ proc ts_cups_dialog {} { ...@@ -8260,7 +8528,7 @@ proc ts_cups_dialog {} {
global cups_local_server cups_remote_port cups_manage_rcfile cups_x11vnc global cups_local_server cups_remote_port cups_manage_rcfile cups_x11vnc
global cups_local_smb_server cups_remote_smb_port global cups_local_smb_server cups_remote_smb_port
scroll_text .cups.f 80 29 scroll_text .cups.f 80 30
set msg { set msg {
...@@ -8271,7 +8539,8 @@ proc ts_cups_dialog {} { ...@@ -8271,7 +8539,8 @@ proc ts_cups_dialog {} {
Enter the VNC Viewer side (i.e. where you are sitting) CUPS server Enter the VNC Viewer side (i.e. where you are sitting) CUPS server
under "Local CUPS Server". Use "localhost:631" if there is one under "Local CUPS Server". Use "localhost:631" if there is one
on your viewer machine (cupsd), or, say, "my-print-srv:631" for a 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 The remote Desktop session will have the variables CUPS_SERVER and
IPP_PORT set so all printing applications will be redirected to your IPP_PORT set so all printing applications will be redirected to your
...@@ -8303,8 +8572,13 @@ proc ts_cups_dialog {} { ...@@ -8303,8 +8572,13 @@ proc ts_cups_dialog {} {
} }
.cups.f.t insert end $msg .cups.f.t insert end $msg
global uname
if {$cups_local_server == ""} { 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 == ""} { if {$cups_remote_port == ""} {
set cups_remote_port [expr "6731 + int(1000 * rand())"] set cups_remote_port [expr "6731 + int(1000 * rand())"]
...@@ -8313,6 +8587,8 @@ proc ts_cups_dialog {} { ...@@ -8313,6 +8587,8 @@ proc ts_cups_dialog {} {
global is_windows global is_windows
if {$is_windows} { if {$is_windows} {
set cups_local_smb_server "IP:139" set cups_local_smb_server "IP:139"
} elseif {$uname == "Darwin"} {
set cups_local_smb_server "127.0.0.1:139"
} else { } else {
set cups_local_smb_server "localhost:139" set cups_local_smb_server "localhost:139"
} }
...@@ -8459,8 +8735,13 @@ proc cups_dialog {} { ...@@ -8459,8 +8735,13 @@ proc cups_dialog {} {
} }
.cups.f.t insert end $msg .cups.f.t insert end $msg
global uname
if {$cups_local_server == ""} { 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 == ""} { if {$cups_remote_port == ""} {
set cups_remote_port "6631" set cups_remote_port "6631"
...@@ -8469,6 +8750,8 @@ proc cups_dialog {} { ...@@ -8469,6 +8750,8 @@ proc cups_dialog {} {
global is_windows global is_windows
if {$is_windows} { if {$is_windows} {
set cups_local_smb_server "IP:139" set cups_local_smb_server "IP:139"
} elseif {$uname == "Darwin"} {
set cups_local_smb_server "127.0.0.1:139"
} else { } else {
set cups_local_smb_server "localhost:139" set cups_local_smb_server "localhost:139"
} }
...@@ -10368,16 +10651,17 @@ proc choose_desktop_dialog {} { ...@@ -10368,16 +10651,17 @@ proc choose_desktop_dialog {} {
radiobutton .sd.b3 -anchor w -variable ts_desktop_type -value Xsession -text cde 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.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.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.b6 -anchor w -variable ts_desktop_type -value xfce -text xfce
radiobutton .sd.b7 -anchor w -variable ts_desktop_type -value twm -text twm radiobutton .sd.b7 -anchor w -variable ts_desktop_type -value enlightenment -text enlightenment
radiobutton .sd.b8 -anchor w -variable ts_desktop_type -value failsafe -text failsafe 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 ""} 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 ""} 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 ""} wm protocol .sd WM_DELETE_WINDOW {destroy .sd; set choose_desktop 0; set ts_desktop_type ""}
button .sd.done -text "Done" -command {destroy .sd} 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 center_win .sd
} }
...@@ -10692,7 +10976,7 @@ proc set_advanced_options {} { ...@@ -10692,7 +10976,7 @@ proc set_advanced_options {} {
checkbutton .oa.b$i -anchor w -variable use_grab -text \ checkbutton .oa.b$i -anchor w -variable use_grab -text \
"Use XGrabServer" "Use XGrabServer"
if {$darwin_cotvnc} {.o.b$i configure -state disabled} if {$darwin_cotvnc} {.oa.b$i configure -state disabled}
set ix $i set ix $i
incr i incr i
...@@ -10992,9 +11276,9 @@ proc x11vnc_find_adjust {which} { ...@@ -10992,9 +11276,9 @@ proc x11vnc_find_adjust {which} {
regsub -all {[ ]*-localhost[ ]*} $remote_ssh_cmd " " remote_ssh_cmd regsub -all {[ ]*-localhost[ ]*} $remote_ssh_cmd " " remote_ssh_cmd
regsub -all {[ ]*-env FD_XDM=1[ ]*} $remote_ssh_cmd " " remote_ssh_cmd regsub -all {[ ]*-env FD_XDM=1[ ]*} $remote_ssh_cmd " " remote_ssh_cmd
if {$use_x11vnc_find} { 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 { } 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
regsub {^[ ]*} $remote_ssh_cmd "" remote_ssh_cmd regsub {^[ ]*} $remote_ssh_cmd "" remote_ssh_cmd
...@@ -11169,9 +11453,18 @@ proc set_options {} { ...@@ -11169,9 +11453,18 @@ proc set_options {} {
button .o.ssh -anchor w -text " SSH-Only Mode" -command {to_sshonly; destroy .o} 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.tso -anchor w -text " Terminal Svc Mode" -command {to_tsonly; destroy .o}
} }
button .o.advanced -anchor w -text " Advanced ..." -command set_advanced_options global uname
button .o.clear -anchor w -text " Clear Options" -command set_defaults set t1 " Advanced ..."
button .o.delete -anchor w -text " Delete Profile ..." -command {destroy .o; delete_profile} 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.clear -side top -fill x
pack .o.delete -side top -fill x pack .o.delete -side top -fill x
...@@ -11479,6 +11772,9 @@ if {$uname == "Darwin"} { ...@@ -11479,6 +11772,9 @@ if {$uname == "Darwin"} {
} }
} }
set help_font "-font {Monaco 10}" set help_font "-font {Monaco 10}"
#option add *Button.font Helvetica widgetDefault
catch {option add *Button.font {System 10} widgetDefault}
} }
set putty_pw "" set putty_pw ""
......
#!/bin/sh #!/bin/sh
rm -rf ./src/tmp/* || exit 1 rm -rf ./src/tmp/* || exit 1
vers=1.0.19 vers=1.0.20
cd .. || exit 1 cd .. || exit 1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment