diff options
Diffstat (limited to 'x11vnc/misc/enhanced_tightvnc_viewer/bin')
-rwxr-xr-x | x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer | 433 | ||||
-rwxr-xr-x | x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl | 1399 |
2 files changed, 1443 insertions, 389 deletions
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer b/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer index 7ad1811..63ddac5 100755 --- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer +++ b/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer @@ -382,7 +382,9 @@ if [ "X$reverse" != "X" ]; then echo "*Warning*: -listen and a single proxy/gateway does not make sense." sleep 2 fi - SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE + + # we now try to PPROXY_LOOP_THYSELF, set this var to disable that. + #SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE fi fi if [ "X$ssh_cmd" = "X" ]; then @@ -520,12 +522,6 @@ if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then fi fi -# (possibly) tell the vncviewer to only listen on lo: -if [ "X$reverse" != "X" -a "X$direct_connect" = "X" ]; then - VNCVIEWER_LISTEN_LOCALHOST=1 - export VNCVIEWER_LISTEN_LOCALHOST -fi - # rsh mode is an internal/secret thing only I use. rsh="" if echo "$orig" | grep '^rsh://' > /dev/null; then @@ -551,11 +547,98 @@ else fi # extract host and disp number: -host=`echo "$orig" | awk -F: '{print $1}'` -disp=`echo "$orig" | awk -F: '{print $2}'` + +# try to see if it is ipv6 address: +ipv6=0 +if echo "$orig" | grep '\[' > /dev/null; then + # ipv6 [fe80::219:dbff:fee5:3f92%eth1]:5900 + host=`echo "$orig" | sed -e 's/\].*$//' -e 's/\[//'` + disp=`echo "$orig" | sed -e 's/^.*\]://'` + ipv6=1 +elif echo "$orig" | grep ':..*:' > /dev/null; then + # ipv6 fe80::219:dbff:fee5:3f92%eth1:5900 + host=`echo "$orig" | sed -e 's/:[^:]*$//'` + disp=`echo "$orig" | sed -e 's/^.*://'` + ipv6=1 +else + # regular host:port + host=`echo "$orig" | awk -F: '{print $1}'` + disp=`echo "$orig" | awk -F: '{print $2}'` +fi + +if [ "X$reverse" != "X" -a "X$STUNNEL_LISTEN" = "X" -a "X$host" != "X" ]; then + STUNNEL_LISTEN=$host + echo "set STUNNEL_LISTEN=$STUNNEL_LISTEN" +fi + if [ "X$host" = "X" ]; then host=$localhost fi + +if [ "X$SSVNC_IPV6" = "X0" ]; then + # disable checking for it. + ipv6=0 +#elif [ "X$reverse" != "X" -a "X$ipv6" = "X1" ]; then +# ipv6=0 +elif [ "X$ipv6" = "X1" ]; then + : +elif echo "$host" | grep '^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' > /dev/null; then + : +else + # regular hostname, can't be sure... + host "$host" >/dev/null 2>&1 + host "$host" >/dev/null 2>&1 + hout=`host "$host" 2>/dev/null` + if echo "$hout" | grep -i 'has ipv6 address' > /dev/null; then + if echo "$hout" | grep -i 'has address' > /dev/null; then + : + else + echo "ipv6: "`echo "$hout" | grep -i 'has ipv6 address' | head -n 1` + ipv6=1 + fi + fi + if [ "X$ipv6" = "X0" ]; then + dout=`dig -t any "$host" 2>/dev/null` + if echo "$dout" | grep -i "^$host" | grep '[ ]AAAA[ ]' > /dev/null; then + if echo "$dout" | grep -i "^$host" | grep '[ ]A[ ]' > /dev/null; then + : + else + echo "ipv6: "`echo "$dout" | grep -i '[ ]AAAA[ ]' | head -n 1` + ipv6=1 + fi + fi + fi + if [ "X$ipv6" = "X0" ]; then + sout=`env LOOKUP="$host" \ + perl -e ' eval {use Socket}; exit 0 if $@; + eval {use Socket6}; exit 0 if $@; + @res = getaddrinfo($ENV{LOOKUP}, "daytime", AF_UNSPEC, SOCK_STREAM); + $ipv4 = 0; + $ipv6 = 0; + $ip6 = ""; + while (scalar(@res) >= 5) { + ($family, $socktype, $proto, $saddr, $canon, @res) = @res; + $ipv4 = 1 if $family == AF_INET; + $ipv6 = 1 if $family == AF_INET6; + if ($family == AF_INET6 && $ip6 eq "") { + my ($host, $port) = getnameinfo($saddr, NI_NUMERICHOST | NI_NUMERICSERV); + $ip6 = $host; + } + } + if (! $ipv4 && $ipv6) { + print "AF_INET6_ONLY: $ENV{LOOKUP}: $ip6\n"; + } + exit 0; + ' 2>/dev/null` + if echo "$sout" | grep AF_INET6_ONLY > /dev/null; then + echo "$sout" + ipv6=1 + fi + fi +fi +if [ "X$ipv6" = "X1" ]; then + echo "ipv6: addr=$host disp=$disp" +fi if [ "X$disp" = "X" ]; then port="" # probably -listen mode. elif [ $disp -lt 0 ]; then @@ -573,6 +656,21 @@ else port=$disp fi +if [ "X$ipv6" = "X1" -a "X$direct_connect" = "X1" ]; then + if [ "X$proxy" = "X" -a "X$reverse" = "X" ]; then + proxy="ipv6://$host:$port" + echo "direct connect: set proxy=$proxy" + fi +fi + +# (possibly) tell the vncviewer to only listen on lo: +if [ "X$reverse" != "X" ]; then + if [ "X$direct_connect" = "X" -o "X$proxy" != "X" -o "X$STUNNEL_LISTEN" != "X" ]; then + VNCVIEWER_LISTEN_LOCALHOST=1 + export VNCVIEWER_LISTEN_LOCALHOST + fi +fi + # try to find an open listening port via netstat(1): inuse="" if uname | grep Linux > /dev/null; then @@ -787,6 +885,60 @@ pcode() { use IO::Socket::INET; +my $have_inet6 = ""; +eval "use IO::Socket::INET6;"; +$have_inet6 = 1 if $@ eq ""; + +#my $have_sock6 = ""; +#eval "use Socket; use Socket6;"; +#$have_sock6 = 1 if $@ eq ""; + +if (exists $ENV{PPROXY_LOOP_THYSELF}) { + # used for reverse vnc, run a repeating outer loop. + print STDERR "PPROXY_LOOP: $ENV{PPROXY_LOOP_THYSELF}\n"; + my $rm = $ENV{PPROXY_REMOVE}; + my $lp = $ENV{PPROXY_LOOP_THYSELF}; + delete $ENV{PPROXY_REMOVE}; + delete $ENV{PPROXY_LOOP_THYSELF}; + $ENV{PPROXY_LOOP_THYSELF_MASTER} = $$; + my $pid = $$; + my $dbg = 0; + my $c = 0; + use POSIX ":sys_wait_h"; + while (1) { + $pid = fork(); + last if ! defined $pid; + if ($pid eq "0") { + last; + } + $c++; + print STDERR "\nPPROXY_LOOP: pid=$$ child=$pid count=$c\n"; + while (1) { + waitpid(-1, WNOHANG); + fsleep(0.25); + if (! kill 0, $pid) { + print STDERR "PPROXY_LOOP: child=$pid gone.\n"; + last; + } + print STDERR "PPROXY_LOOP: child=$pid alive.\n" if $dbg; + if (! -f $lp) { + print STDERR "PPROXY_LOOP: flag file $lp gone, killing $pid\n"; + kill TERM, $pid; + fsleep(0.1); + wait; + last; + } + print STDERR "PPROXY_LOOP: file exists $lp\n" if $dbg; + } + last if ! -f $lp; + fsleep(0.25); + } + if ($pid ne "0") { + unlink($0) if $rm; + exit 0; + } +} + if (exists $ENV{PPROXY_SLEEP} && $ENV{PPROXY_SLEEP} > 0) { print STDERR "PPROXY_PID: $$\n"; sleep $ENV{PPROXY_SLEEP}; @@ -835,7 +987,7 @@ if (exists $ENV{SSVNC_PREDIGESTED_HANDSHAKE}) { } my $have_gettimeofday = 0; -eval "use Time::HiRes"; +eval "use Time::HiRes;"; if ($@ eq "") { $have_gettimeofday = 1; } @@ -862,7 +1014,11 @@ my ($mode_1st, $mode_2nd, $mode_3rd) = ("", "", ""); ($first, $mode_1st) = url_parse($first); -my ($proxy_host, $proxy_port) = split(/:/, $first); +my ($proxy_host, $proxy_port) = ($first, ""); +if ($proxy_host =~ /^(.*):(\d+)$/) { + $proxy_host = $1; + $proxy_port = $2; +} my $connect = $ENV{PPROXY_DEST}; if ($second ne "") { @@ -875,13 +1031,15 @@ if ($third ne "") { print STDERR "\n"; -print STDERR "PPROXY v0.3: a tool for Web, SOCKS, and UltraVNC proxies and VeNCrypt bridging.\n"; +print STDERR "PPROXY v0.4: a tool for Web, SOCKS, and UltraVNC proxies and for\n"; +print STDERR "PPROXY v0.4: IPv6 and VNC VeNCrypt bridging.\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 "pproxy_reverse: $ENV{PPROXY_REVERSE}\n"; +print STDERR "io_socket_inet6: $have_inet6\n"; print STDERR "\n"; if (1) { print STDERR "pproxy 1st: $first\t- $mode_1st\n"; @@ -897,15 +1055,29 @@ sub pdie { } if ($ENV{PPROXY_REVERSE} ne "") { - my ($rhost, $rport) = split(/:/, $ENV{PPROXY_REVERSE}); + my ($rhost, $rport) = ($ENV{PPROXY_REVERSE}, ""); + if ($rhost =~ /^(.*):(\d+)$/) { + $rhost = $1; + $rport = $2; + } $rport = 5900 unless $rport; + my $emsg = ""; $listen_handle = IO::Socket::INET->new( PeerAddr => $rhost, PeerPort => $rport, Proto => "tcp" ); + $emsg = $!; + if (! $listen_handle && $have_inet6) { + eval {$listen_handle = IO::Socket::INET6->new( + PeerAddr => $rhost, + PeerPort => $rport, + Proto => "tcp" + );}; + $emsg .= " / $!"; + } if (! $listen_handle) { - pdie "pproxy: $! -- PPROXY_REVERSE\n"; + pdie "pproxy: $emsg -- PPROXY_REVERSE\n"; } print STDERR "PPROXY_REVERSE: connected to $rhost $rport\n"; @@ -914,27 +1086,75 @@ if ($ENV{PPROXY_REVERSE} ne "") { my $maxtry = 12; my $sleep = 5; my $p2 = ""; + my $emsg = ""; for (my $i=0; $i < $maxtry; $i++) { - if ($ENV{PPROXY_LISTEN} =~ /^INADDR_ANY:(.*)/) { - my $p = $1; - $p2 = "*:$p"; + my ($if, $p) = ("", $ENV{PPROXY_LISTEN}); + if ($p =~ /^(.*):(\d+)$/) { + $if = $1; + $p = $2; + } + $p2 = "*:$p"; + if ($if eq "") { + $if = "localhost"; + } + print STDERR "pproxy interface: $if\n"; + + $emsg = ""; + if (($if eq "INADDR_ANY6" || $if eq "::") && $have_inet6) { + eval {$listen_sock = IO::Socket::INET6->new( + Listen => 2, + ReuseAddr => 1, + Domain => AF_INET6, + LocalAddr => "::", + LocalPort => $p, + Proto => "tcp" + );}; + $p2 = ":::$p"; + } elsif ($if =~ /^INADDR_ANY/) { $listen_sock = IO::Socket::INET->new( Listen => 2, + ReuseAddr => 1, LocalPort => $p, Proto => "tcp" ); + } elsif (($if eq "INADDR_LOOPBACK6" || $if eq "::1") && $have_inet6) { + $p2 = "::1:$p"; + eval {$listen_sock = IO::Socket::INET6->new( + Listen => 2, + ReuseAddr => 1, + Domain => AF_INET6, + LocalAddr => "::1", + LocalPort => $p, + Proto => "tcp" + );}; + $p2 = "::1:$p"; } else { - $p2 = "localhost:$ENV{PPROXY_LISTEN}"; + $p2 = "$if:$p"; $listen_sock = IO::Socket::INET->new( Listen => 2, - LocalAddr => "127.0.0.1", - LocalPort => $ENV{PPROXY_LISTEN}, + ReuseAddr => 1, + LocalAddr => $if, + LocalPort => $p, Proto => "tcp" ); + $emsg = $!; + + if (! $listen_sock && $have_inet6) { + print STDERR "PPROXY_LISTEN: retry with INET6\n"; + eval {$listen_sock = IO::Socket::INET6->new( + Listen => 2, + ReuseAddr => 1, + Domain => AF_INET6, + LocalAddr => $if, + LocalPort => $p, + Proto => "tcp" + );}; + $emsg .= " / $!"; + } } if (! $listen_sock) { if ($i < $maxtry - 1) { - warn "pproxy: $!\n"; + warn "pproxy: $emsg $!\n"; warn "Could not listen on port $p2, retrying in $sleep seconds... (Ctrl-C to quit)\n"; sleep $sleep; } @@ -943,7 +1163,7 @@ if ($ENV{PPROXY_REVERSE} ne "") { } } if (! $listen_sock) { - pdie "pproxy: $! -- PPROXY_LISTEN\n"; + pdie "pproxy: $emsg -- PPROXY_LISTEN\n"; } print STDERR "pproxy: listening on $p2\n"; my $ip; @@ -953,6 +1173,24 @@ if ($ENV{PPROXY_REVERSE} ne "") { if (! $listen_handle) { pdie "pproxy: $err\n"; } + + if ($ENV{PPROXY_LOOP_THYSELF_MASTER}) { + my $sml = $ENV{SSVNC_MULTIPLE_LISTEN}; + if ($sml ne "" && $sml ne "0") { + setpgrp(0, 0); + if (fork()) { + close $viewer_sock; + wait; + exit 0; + } + if (fork()) { + close $viewer_sock; + exit 0; + } + setpgrp(0, 0); + $parent = $$; + } + } } $sock = IO::Socket::INET->new( @@ -961,15 +1199,27 @@ $sock = IO::Socket::INET->new( Proto => "tcp" ); +my $err = ""; + +if (! $sock && $have_inet6) { + $err = $!; + + eval {$sock = IO::Socket::INET6->new( + PeerAddr => $proxy_host, + PeerPort => $proxy_port, + Proto => "tcp" + );}; + $err .= " / $!"; +} + if (! $sock) { - my $err = $!; unlink($0) if $ENV{PPROXY_REMOVE}; pdie "pproxy: $err\n"; } unlink($0) if $ENV{PPROXY_REMOVE}; -if ($ENV{PPROXY_PROXY} =~ /^vencrypt:/ && $ENV{PPROXY_LISTEN} =~ /^INADDR_ANY:/) { +if ($ENV{PPROXY_PROXY} =~ /^vencrypt:/ && $ENV{PPROXY_VENCRYPT_REVERSE}) { print STDERR "\nPPROXY: vencrypt+reverse: swapping listen socket with connect socket.\n"; my $tmp_swap = $sock; $sock = $listen_handle; @@ -1116,6 +1366,10 @@ xfer_both(); exit; +sub fsleep { + select(undef, undef, undef, shift); +} + sub url_parse { my $hostport = shift; my $mode = "http"; @@ -1128,11 +1382,14 @@ sub url_parse { } elsif ($hostport =~ m,^https?://(\S*)$,i) { $mode = "http"; $hostport = $1; + } elsif ($hostport =~ m,^ipv6://(\S*)$,i) { + $mode = "ipv6"; + $hostport = $1; } elsif ($hostport =~ m,^repeater://(\S*)\+(\S*)$,i) { # ultravnc repeater proxy. $hostport = $1; $mode = "repeater:$2"; - if ($hostport !~ /:\d+/) { + if ($hostport !~ /:\d+$/) { $hostport .= ":5900"; } } elsif ($hostport =~ m,^vencrypt://(\S*)$,i) { @@ -1144,7 +1401,7 @@ sub url_parse { $mode = $2; } $mode = "vencrypt:$m"; - if ($hostport !~ /:\d+/) { + if ($hostport !~ /:\d+$/) { $hostport .= ":5900"; } } @@ -1161,6 +1418,8 @@ sub setmode { } else { $ENV{PPROXY_SOCKS} = 1; } + } elsif ($mode =~ /^ipv6/i) { + $ENV{PPROXY_SOCKS} = 0; } elsif ($mode =~ /^repeater:(.*)/) { $ENV{PPROXY_REPEATER} = $1; $ENV{PPROXY_SOCKS} = ""; @@ -1180,7 +1439,11 @@ sub connection { if ($ENV{PPROXY_SOCKS} eq "5") { # SOCKS5 - my ($h, $p) = split(/:/, $CONNECT); + my ($h, $p) = ($CONNECT, ""); + if ($h =~ /^(.*):(\d+)$/) { + $h = $1; + $p = $2; + } $con .= pack("C", 0x05); $con .= pack("C", 0x01); $con .= pack("C", 0x00); @@ -1242,9 +1505,13 @@ sub connection { exit(1); } - } elsif ($ENV{PPROXY_SOCKS} ne "") { + } elsif ($ENV{PPROXY_SOCKS} eq "1") { # SOCKS4 SOCKS4a - my ($h, $p) = split(/:/, $CONNECT); + my ($h, $p) = ($CONNECT, ""); + if ($h =~ /^(.*):(\d+)$/) { + $h = $1; + $p = $2; + } $con .= pack("C", 0x04); $con .= pack("C", 0x01); $con .= pack("n", $p); @@ -1296,6 +1563,9 @@ sub connection { close $sock; exit(1); } + } elsif ($ENV{PPROXY_SOCKS} eq "0") { + # hack for ipv6 "proxy", nothing to do, assume INET6 call worked. + ; } elsif ($ENV{PPROXY_REPEATER} ne "") { my $rep = $ENV{PPROXY_REPEATER}; print STDERR "repeater: $rep\n"; @@ -1582,6 +1852,7 @@ sub do_vencrypt_viewer_bridge { for (my $i=0; $i < $maxtry; $i++) { $listen_sock = IO::Socket::INET->new( Listen => 2, + ReuseAddr => 1, LocalAddr => "127.0.0.1", LocalPort => $listen, Proto => "tcp" @@ -1606,6 +1877,23 @@ sub do_vencrypt_viewer_bridge { if (! $viewer_sock) { die "pproxy: vencrypt_viewer_bridge[$$]: $err\n"; } + if ($ENV{PPROXY_LOOP_THYSELF_MASTER}) { + my $sml = $ENV{SSVNC_MULTIPLE_LISTEN}; + if ($sml ne "" && $sml ne "0") { + setpgrp(0, 0); + if (fork()) { + close $viewer_sock; + wait; + exit 0; + } + if (fork()) { + close $viewer_sock; + exit 0; + } + setpgrp(0, 0); + $parent = $$; + } + } print STDERR "vencrypt_viewer_bridge[$$]: viewer_sock $viewer_sock\n" if $db; print STDERR "pproxy: vencrypt_viewer_bridge[$$]: connecting to 127.0.0.1:$connect\n"; @@ -2055,13 +2343,18 @@ NHAFL_warning() { echo "** Warning: you to manually remove a key from ~/.ssh/known_hosts.)" echo "** Warning: " echo "** Warning: This decreases security: a Man-In-The-Middle attack is possible." + echo "** Warning: For chained ssh connections the first ssh leg is secure but the" + echo "** Warning: 2nd ssh leg is vulnerable. For an ssh connection going through" + echo "** Warning: a HTTP or SOCKS proxy the ssh connection is vulnerable." + echo "** Warning: " echo "** Warning: You can set the SSVNC_SSH_LOCALHOST_AUTH=1 env. var. to disable" - echo "** Warning: using the NoHostAuthenticationForLocalhost ssh option." + echo "** Warning: using the NoHostAuthenticationForLocalhost=yes ssh option." echo "** Warning: " echo "** Warning: A better solution is to configure (in the SSVNC GUI) the setting:" echo "** Warning: 'Options -> Advanced -> Private SSH KnownHosts file' (or set" echo "** Warning: SSVNC_KNOWN_HOSTS_FILE directly) to a per-connection known hosts" - echo "** Warning: file. This yields a both secure and convenient solution." + echo "** Warning: file. That file holds the 'localhost' cert for this specific" + echo "** Warning: connection. This yields a both secure and convenient solution." echo "" } @@ -2243,6 +2536,7 @@ if [ "X$use_ssh" = "X1" ]; then nd=`findfree 6600` PPROXY_LISTEN=$nd; export PPROXY_LISTEN + # XXX no reverse forever PPROXY_LOOP_THYSELF ... $ptmp & sleep 1 if [ "X$ssh_NHAFL" != "X" -a "X$did_ssh_NHAFL" != "X1" ]; then @@ -2633,6 +2927,16 @@ if [ "X$crl" != "X" ]; then fi fi +if [ "X$showcert" = "X1" ]; then + if [ "X$ipv6" = "X1" -a "X$proxy" = "X" ]; then + proxy="ipv6://$host:$port" + fi +fi + +if [ "X$direct_connect" != "X" -a "X$STUNNEL_LISTEN" != "X" ]; then + proxy=reverse_direct +fi + ptmp="" if [ "X$proxy" != "X" ]; then ptmp="/tmp/ss_vncviewer${RANDOM}.$$.pl" @@ -2841,9 +3145,22 @@ if [ "X$direct_connect" != "X" ]; then PPROXY_LISTEN=$use export PPROXY_LISTEN else - PPROXY_REVERSE="$localhost:$use" - export PPROXY_REVERSE - pps=3 + if [ "X$proxy" = "Xreverse_direct" ]; then + PPROXY_LISTEN="$STUNNEL_LISTEN:`expr 5500 + $disp`" + PPROXY_DEST="$localhost:$use" + PPROXY_PROXY="ipv6://$localhost:$use" # not always ipv6.. + export PPROXY_LISTEN PPROXY_DEST PPROXY_PROXY + pps=1 + else + PPROXY_REVERSE="$localhost:$use" + export PPROXY_LISTEN + pps=3 + fi + if [ "X$SSVNC_LISTEN_ONCE" != "X1" ]; then + PPROXY_LOOP_THYSELF=`mytmp "/tmp/pproxy_loop_thyself.${RANDOM}.$$"` + export PPROXY_LOOP_THYSELF + pps=2 + fi if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then pps=`expr $pps + $SSVNC_EXTRA_SLEEP` fi @@ -2904,10 +3221,13 @@ if [ "X$direct_connect" != "X" ]; then echo "" trap "final" 0 2 15 if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then - echo "NOTE: The ultravnc_dsm_helper only runs once. So after the first LISTEN" - echo " ends, you may have to Press Ctrl-C and restart for another connection." - echo "" - SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE + if [ "X$SSVNC_LISTEN_ONCE" = "X1" ]; then + echo "NOTE: The ultravnc_dsm_helper only runs once. So after the first LISTEN" + echo " ends you must restart the Listening mode. You may also need to" + echo " Press Ctrl-C to stop the viewer and restart for another connection." + echo "" + fi + #SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE VNCVIEWER_LISTEN_LOCALHOST=1 export VNCVIEWER_LISTEN_LOCALHOST dport=`expr 5500 + $disp` @@ -2917,8 +3237,13 @@ if [ "X$direct_connect" != "X" ]; then echo echo "$ustr &" echo - $cmd & - dsm_pid=$! + if [ "X$SSVNC_LISTEN_ONCE" = "X1" ]; then + $cmd & + dsm_pid=$! + else + while [ 1 ]; do $cmd; sleep 1; done & + dsm_pid=$! + fi sleep 2 disp=$use if [ $disp -ge 5500 ]; then @@ -2935,6 +3260,9 @@ if [ "X$direct_connect" != "X" ]; then echo "$VNCVIEWERCMD" "$@" -listen $disp2 echo "" $VNCVIEWERCMD "$@" -listen $disp2 + if [ "X$PPROXY_LOOP_THYSELF" != "X" ]; then + rm -f $PPROXY_LOOP_THYSELF + fi fi exit $? fi @@ -2998,6 +3326,8 @@ else hloc="" if [ "X$use_ssh" = "X1" ]; then hloc="$localhost:" + elif [ "X$STUNNEL_LISTEN" != "X" ]; then + hloc="$STUNNEL_LISTEN:" fi if echo "$proxy" | grep -i '^vencrypt:' > /dev/null; then hloc="$localhost:" @@ -3127,7 +3457,12 @@ else if echo "$proxy" | grep -i '^vencrypt:' > /dev/null; then pstunnel=`echo "$proxy" | awk -F: '{print $2}'` plisten=`echo "$proxy" | awk -F: '{print $3}'` - PPROXY_LISTEN="INADDR_ANY:$plisten"; export PPROXY_LISTEN + IF=INADDR_ANY + if [ "X$STUNNEL_LISTEN" != "X" ]; then + IF=$STUNNEL_LISTEN + fi + PPROXY_VENCRYPT_REVERSE=1; export PPROXY_VENCRYPT_REVERSE + PPROXY_LISTEN="$IF:$plisten"; export PPROXY_LISTEN PPROXY_PROXY="vencrypt://$localhost:$pstunnel"; export PPROXY_PROXY PPROXY_DEST="$localhost:$pstunnel"; export PPROXY_DEST STUNNEL_ONCE=1; export STUNNEL_ONCE @@ -3140,6 +3475,11 @@ else if [ $N2_trim -le 200 ]; then N2_trim=`expr $N2_trim + 5500` fi + if [ "X$SSVNC_LISTEN_ONCE" != "X1" ]; then + PPROXY_LOOP_THYSELF=`mytmp "/tmp/pproxy_loop_thyself1.${RANDOM}.$$"` + export PPROXY_LOOP_THYSELF + PPROXY_LOOP_THYSELF0=$PPROXY_LOOP_THYSELF + fi env PPROXY_REMOVE=0 PPROXY_SLEEP=0 PPROXY_VENCRYPT_VIEWER_BRIDGE="-$port1,$port2" $ptmp & sleep 1 fi @@ -3148,6 +3488,10 @@ else PPROXY_SLEEP=1; export PPROXY_SLEEP; fi PPROXY_KILLPID=+1; export PPROXY_KILLPID; + if [ "X$SSVNC_LISTEN_ONCE" != "X1" ]; then + PPROXY_LOOP_THYSELF=`mytmp "/tmp/pproxy_loop_thyself2.${RANDOM}.$$"` + export PPROXY_LOOP_THYSELF + fi $ptmp & # Important to have no extra pids generated between here and VNCVIEWERCMD fi @@ -3157,6 +3501,13 @@ else echo "$VNCVIEWERCMD" "$@" -listen $N2 echo "" $VNCVIEWERCMD "$@" -listen $N2 + + if [ "X$PPROXY_LOOP_THYSELF" != "X" ]; then + rm -f $PPROXY_LOOP_THYSELF + fi + if [ "X$PPROXY_LOOP_THYSELF0" != "X" ]; then + rm -f $PPROXY_LOOP_THYSELF0 + fi fi sleep 1 diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl b/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl index 3e63ba5..21f3d9f 100755 --- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl +++ b/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl @@ -3,12 +3,12 @@ exec wish "$0" "$@" # -# Copyright (c) 2006-2009 by Karl J. Runge <runge@karlrunge.com> +# Copyright (c) 2006-2010 by Karl J. Runge <runge@karlrunge.com> # # ssvnc.tcl: gui wrapper to the programs in this # package. Also sets up service port forwarding. # -set version 1.0.25 +set version 1.0.27 set buck_zero $argv0 @@ -249,15 +249,21 @@ proc ts_help {} { Use username@host (e.g. joe@ts-server or jsmith@ssh.company.com) if the user name differs between machines. - To use a non-standard ssh port (i.e. a port other than 22) in - Proxy/Gateways use something like this for port 2222: + NOTE: On Windows you MUST always supply the username@ because putty's + plink requires it. + + NON-STANDARD SSH PORT: To use a non-standard ssh port (i.e. a port other + than 22) you need to use the Proxy/Gateways as well. E.g. something + like this for port 2222: + VNC Terminal Server: ts-server Proxy/Gateway: jsmith@ssh.company.com:2222 On Unix/MacOSX the username@ is not needed if it is the same as on this machine. + A Web or SOCKS proxy can also be used. Use this if you are inside a firewall that prohibits direct connections to remote SSH servers. In Terminal Services SSH mode, the "http://" prefix is required for @@ -413,8 +419,9 @@ proc help {} { * Automatic SSH Tunnels are described below. - * The 'No Encryption' option provides a direct connection w/o encryption. - (disable by the -enc option, or Options menu.) More info in Tip 3). + * The 'No Encryption' / 'None' option provides a direct connection without + encryption (disable the button with the -enc option, or Options menu.) + More info in Tip 5. Port numbers: @@ -428,9 +435,12 @@ proc help {} { If you must use a TCP port less than 200, specify a negative value, e.g.: 24.67.132.27:-80 - For Reverse VNC connections (listening viewer, See Tip 6 and + For Reverse VNC connections (listening viewer, See Tip 2 and Options -> Help), the port mapping is similar, except "listening display :0" corresponds to port 5500, :1 to 5501, etc. + Specify a specific interface, e.g. 192.168.1.1:0 to have stunnel + only listen on that interface. IPv6 also works, e.g. :::0 or ::1:0 + This also works for UN-encrypted reverse connections as well ('None'). Zeroconf/Bonjour: @@ -480,7 +490,7 @@ proc help {} { ssvnc vnc+ssl://hostname:0 (same) ssvnc vnc+ssh://hostname:0 (connect to hostname VNC disp 0 via SSH) - see the Tips 3 and 9 for more about the URL-like syntax. + see the Tips 5 and 7 for more about the URL-like syntax. SSL Certificate Verification: @@ -667,7 +677,7 @@ proc help {} { To connect to a non-standard SSH port, see SSH Proxies/Gateways section. - See Tip 13) for how to make this application be SSH-only with the -ssh + See Tip 8) for how to make this application be SSH-only with the -ssh command line option or "sshvnc". @@ -688,7 +698,7 @@ proc help {} { VNC Host:Display username@somehost.com:2 Remote SSH Command: x11vnc -find -rfbport 5902 -nopw - See the Tip 11) for using x11vnc PORT=NNNN feature (or vncserver(1) + See the Tip 18) for using x11vnc PORT=NNNN feature (or vncserver(1) output) to not need to specify the VNC display number or the x11vnc -rfbport option. @@ -764,7 +774,7 @@ proc help {} { See also these links for more information: http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tunnel-ext - http://www.stunnel.org + http://stunnel.mirt.net http://www.tightvnc.com } @@ -803,7 +813,7 @@ proc help {} { By 'do not trust' we mean they might try to gain access to remote machines you connect to via SSVNC. Note that an untrusted local user can often obtain root access in a short amount of time; if a - user has acheived that, then all bets are off for ANYTHING that you + user has achieved that, then all bets are off for ANYTHING that you do on the workstation. It is best to get rid of Untrusted Local Users as soon as possible. @@ -819,7 +829,7 @@ proc help {} { If the untrusted local user tries to connect to these ports, he may succeed by varying degrees to gain access to the remote machine. We now list some safeguards one can put in place to try to make this - more difficult to acheive. + more difficult to achieve. It probably pays to have the VNC server require a password, even though there has already been SSL or SSH authentication (via @@ -886,7 +896,7 @@ proc help {} { set help_prox { Here are a number of long sections on all sorts of proxies, Web, SOCKS, - ssh, UltraVNC, Single Click, etc., etc. + SSH tunnels/gateways, UltraVNC, Single Click, etc., etc. Proxies/Gateways: @@ -917,18 +927,22 @@ proc help {} { 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 in SSH or SSH+SSL mode you MUST supply - the http:// prefix for web proxies; see the next section.) + + You can prefix web proxies with http:// in SSL mode but it doesn't matter + since that is the default for a proxy. (NOTE that in SSH or SSH+SSL + mode you MUST supply the http:// prefix for web proxies because in those + modes an SSH tunnel is the default proxy type: see the next section.) Note that Web proxies are often configured to ONLY allow outgoing connections to ports 443 (HTTPS) and 563 (SNEWS), so you might have run the VNC server (or router port redirector) on those ports. SOCKS proxies usually have no restrictions on port number. - You can chain up to 3 proxies (any combination of http:// and + You can chain up to 3 proxies (any combination of web (http://) and socks://) by separating them with commas (i.e. first,second,third). + Proxies also work for un-encrypted connections ("None" or vnc://, Tip 5) + See the ss_vncviewer description and x11vnc FAQ for info on proxies: http://www.karlrunge.com/x11vnc/faq.html#ss_vncviewer @@ -942,8 +956,8 @@ proc help {} { VNC server. However, Web and SOCKS proxies can also be used (see below). For example if a company had a central login server: "ssh.company.com" - (accessible from the internet) and the internal workstation name was - "joes-pc", one could put this in: + (accessible from the internet) and the internal workstation with VNC was + named "joes-pc", then to create an SSH tunnel one could put this in: VNC Host:Display: joes-pc:0 Proxy/Gateway: ssh.company.com @@ -951,7 +965,8 @@ proc help {} { It is OK if the hostname "joes-pc" only resolves inside the firewall. 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 the viewer -> ssh.company.com 1st leg is + an encrypted tunnel). To SSH encrypt BOTH legs, try the "double SSH gateway" method using the "comma" notation: @@ -959,24 +974,28 @@ proc help {} { VNC Host:Display: localhost:0 Proxy/Gateway: ssh.company.com,joes-pc - this requires an SSH server running on joes-pc. So an initial SSH + this requires an SSH server also running on joes-pc. So an initial SSH login is done to ssh.company.com, then a 2nd SSH is performed (through port a redirection of the first) to login straight to joes-pc where the VNC server is running. Use username@host (e.g. joe@joes-pc jsmith@ssh.company.com) if the - user names differ between the various machines. On Windows you MUST - supply the usernames. + user names differ between the various machines. - To use a non-standard ssh port (i.e. a port other than 22) you need to - use the Proxy/Gateways as well. E.g. something like this for port 2222: + NOTE: On Windows you MUST always supply the username@ because putty's + plink requires it. + + + NON-STANDARD SSH PORT: To use a non-standard ssh port (i.e. a port other + than 22) you need to use the Proxy/Gateways as well. E.g. something + like this for port 2222: VNC Host:Display: localhost:0 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. + On Unix/MacOSX 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 @@ -990,12 +1009,14 @@ proc help {} { VNC Host:Display: joe@far-away.east:0 Proxy/Gateway: socks://mysocks.west:1080 - use socks5://... to force the SOCKS5 version. Note that the http:// - prefix is required for web proxies in SSH or SSH+SSL modes (but it is - the default in SSL mode.) + Use socks5://... to force the SOCKS5 version. Note that the http:// + prefix is REQUIRED for web proxies in SSH or SSH+SSL modes (but it is + the default proxy type in SSL mode.) - You can chain up to 3 proxies (any combination of http:// and - socks://) by separating them with commas (i.e. first,second,third). + You can chain up to 3 proxies (any combination of http://, socks:// + and ssh) by separating them with commas (i.e. first,second,third). + + Note: the Web and/or SOCKS proxies must come before any SSH gateways. For a non-standard SSH port and a Web or SOCKS proxy try: @@ -1006,15 +1027,15 @@ proc help {} { 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 + Proxy/Gateway: socks://mysocks.west:1080,ssh.company.com,joes-pc - SSH NoHostAuthenticationForLocalhost=yes and UserKnownHostsFile=file - for localhost tunnelling: + Some Notes on SSH localhost tunnelling with SSH options + NoHostAuthenticationForLocalhost=yes and UserKnownHostsFile=file: - Warning: Note that for proxy use with ssh(1) tunnels going through - localhost are used. This means ssh(1) thinks the remote hostname is + Warning: Note that for proxy use with ssh(1), tunnels going through + 'localhost' are used. This means ssh(1) thinks the remote hostname is 'localhost', which may cause collisions and confusion when storing and checking SSH keys. @@ -1026,7 +1047,7 @@ proc help {} { the NoHostAuthenticationForLocalhost option is used. On Unix to disable the use of NoHostAuthenticationForLocalhost set the env. - variable SSVNC_SSH_LOCALHOST_AUTH=1. + variable SSVNC_SSH_LOCALHOST_AUTH=1. This may induce extra ssh(1) dialogs. On Unix a MUCH SAFER and more convenient way to proceed is to set the known hosts option in Options -> Advanced -> 'Private SSH KnownHosts file' @@ -1063,10 +1084,10 @@ proc help {} { Note: it seems only SSL SSVNC connections make sense with the UltraVNC repeater. SSH connections (previous section) do not seem to - and so are not enabled to (let us know if you find a way to use it). + and so are not enabled to (let us know if you find a way to use it.) Unencrypted (aka Direct) SSVNC VNC connections (Vnc:// prefix in - 'VNC Host:Display'; see Tip 3) also work with the UltraVNC repeater. + 'VNC Host:Display'; see Tip 5) also work with the UltraVNC repeater. For the mode I repeater the viewer initiates the connection and passes a string that is the VNC server's IP address (or hostname) @@ -1084,12 +1105,12 @@ proc help {} { The Proxy/Gateway format is repeater://proxy:port+vncserver:display. The string after the "+" sign is passed to the repeater server for it to interpret (and so does not have to be the UltraVNC repeater; - you could create your own if you wanted to). For this example, + you could create your own if you wanted to.) For this example, instead of joes-pc:1 it could be joes-pc:5901 or 192.168.1.4:1, 192.168.1.4:5901, etc. If you do not supply a proxy port, then the default 5900 is assumed, - e.g. repeater://myuvncrep.west+joes-pc:1 + e.g. use repeater://myuvncrep.west+joes-pc:1 for port 5901. For the mode II repeater both the VNC viewer and VNC server initiate @@ -1118,7 +1139,7 @@ proc help {} { connection in this situation. Note that for unencrypted (i.e. direct) SSVNC connections (see vnc:// - in Tip 3) there is no need to use a reverse "Listening connection" + in Tip 5) there is no need to use a reverse "Listening connection" and so you might as well use a forward connection. For mode II when tunnelling via SSL, you probably should also disable @@ -1128,9 +1149,9 @@ proc help {} { is no way to do the initial "Fetch Cert" and check if it has been previously accepted. - Even when you disable "Verify All Certs", you are free to set a - ServerCert or CertsDir under "Certs ..." to authenticate the VNC - Server against. + Even when you disable "Verify All Certs", you are of course free to + set a ServerCert or CertsDir under "Certs ..." to authenticate the + VNC Server against. Also, after the connection you MUST terminate the listening VNC Viewer (Ctrl-C) and connect again (the proxy only runs once.) In Windows, @@ -1170,7 +1191,7 @@ proc help {} { The SC EXE is a VNC *server* that starts up a Reverse VNC connection to a Listening Viewer (e.g. the viewer address/port/ID is hardwired into the SC EXE). So SC is not really a proxy, but it can be used - with UltraVNC repeater proxies and we include it here. + with UltraVNC repeater proxies and so we describe it here. One important point for SC III binary creation: do NOT include "-id N" in the helpdesk.txt config file. This is because the with @@ -1190,7 +1211,7 @@ proc help {} { mode and the SSL encrypted "SC III" mode. For both cases SSVNC must be run in Listening mode (Options -> Reverse VNC Connection) - For SC I, enable Reverse VNC Connection and put Vnc://0 (see Tip 3 + For SC I, enable Reverse VNC Connection and put Vnc://0 (see Tip 5 below) in the VNC Host:Display to disable encryption (use a different number if you are not using the default listening port 5500). Then click on the "Listen" button and finally have the user run your @@ -1242,46 +1263,211 @@ proc help {} { SSVNC vncviewer. The modified viewer is needed; stock VNC viewers will not work. Also, proxy chaining (bouncing off of more than one proxy) currently does not work. + + + VeNCrypt is treated as a proxy: + + SSVNC supports the VeNCrypt VNC security type. You will find out more + about this security type in the other parts of the Help documentation. + In short, it does a bit of plain-text VNC protocol negotiation before + switching to SSL/TLS encryption and authentication. + + SSVNC implements its VeNCrypt support as final proxy in a chain + of proxies. You don't need to know this or specify anything, but + it is good to know since it uses up one of the 3 proxies you are + allowed to chain together. If you watch the command output you will + see the vencrypt:// proxy item. + + You can specify that a VNC server uses VeNCrypt (Options -> Advanced) + or you can let SSVNC try to autodetect VeNCrypt. + + + IPv6 can be treated as a proxy for UN-ENCRYPTED connections: + + Read Tip 20 about SSVNC's IPv6 (128 bit IP addresses) support. + In short, because stunnel and ssh support IPv6 hostnames and + addresses, SSVNC does too without you needing to do anything. + + However, in some usages modes you will need to specify the IPv6 + server destination in the Proxy/Gateway entry box. The only case + this appears to be needed is when making an un-encrypted connection + to an IPv6 VNC server. In this case neither stunnel nor ssh are + used and you need to specify something like this: + + VNC Host:Display: localhost:0 + Proxy/Gateway: ipv6://2001:4860:b009::68:5900 + + and then select 'None' as the encryption type. Note that the above + 'localhost:0' setting can be anything; it is basically ignored. + + Note that on Unix, MacOSX, and Windows un-encrypted ipv6 connections + are AUTODETECTED and so you likely never need to supply ipv6:// + Only try it if there are problems. Also note that the ipv6:// + proxy type does not work on Windows, so only the autodetection is + available there. + + Note that if there is some other proxy, e.g. SOCKS or HTTP and that + proxy server is an IPv6 host (or will connect you to one) then any + sort of connection through that proxy will work OK: un-encrypted as + well as SSL or SSH connections, etc. + + Unencrypted connection is the only special case where you may need + to specify an ipv6:// proxy. If you find another use let us know. + + See Tip 20 for more info. } set help_tips { Tips and Tricks: - 1) On Unix to get a 2nd GUI (e.g. for a 2nd connection) press Ctrl-N - on the GUI. If only the xterm window is visible you can press - Ctrl-N or try Ctrl-LeftButton -> New SSVNC_GUI. On Windows you - will have to manually Start a new one: Start -> Run ..., etc. + Table of Contents: + + 1) Connect to Non-Standard SSH port. + 2) Reverse VNC connections (Listening) + 3) Global options in ~/.ssvncrc + 4) Fonts + 5) vnc://host for un-encrypted connection + 6) Home directory for memory stick usage, etc. + 7) vncs:// vncssl:// vnc+ssl:// vnc+ssh:// URL-like prefixes + 8) sshvnc / -ssh SSH only GUI + 9) tsvnc / -ts Terminal services only GUI (SSH+x11vnc) + 10) 2nd GUI window on Unix/MacOSX + 11) Ctrl-L or Button3 to Load profile + 12) SHELL command or Ctrl-S for SSH terminal w/o VNC + 13) KNOCK command for port-knock sequence + 14) Unix/MacOSX general SSL redirector (not just VNC) + 15) Environment variables + 16) Bigger "Open File" dialog window + 17) Unix/MacOSX extra debugging output + 18) Dynamic VNC Server Port determination with SSH + 19) No -t ssh cmdline option for older sshd + 20) IPv6 support. + + 1) To connect in SSH-Mode to a server running SSH on a non-standard + port (22 is the standard port) you need to use the Proxy/Gateway + setting. The following is from the Proxies Help panel: + + NON-STANDARD SSH PORT: To use a non-standard ssh port (i.e. a port other + than 22) you need to use the Proxy/Gateways as well. E.g. something + like this for port 2222: + + VNC Host:Display: localhost:0 + 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. + + 2) Reverse VNC connections (Listening) are possible as well. + In this case the VNC Server initiates the connection to your + waiting (i.e. listening) SSVNC viewer. - 2) Pressing the "Load" button or pressing Ctrl-L or Clicking the Right - mouse button on the main GUI will invoke the Load dialog. + Go to Options and select "Reverse VNC connection". In the 'VNC + Host:Display' entry box put in the number (e.g. "0" or ":0", or + ":1", etc) that corresponds to the Listening display (0 -> port + 5500, 1 -> port 5501, etc.) you want to use. Then clicking on + 'Listen' puts your SSVNC viewer in a "listening" state on that + port number, waiting for a connection from the VNC Server. - Pressing Ctrl-O on the main GUI will bring up the Options Panel. - Pressing Ctrl-A on the main GUI will bring up the Advanced Options. + On Windows or using a 3rd party VNC Viewer multiple, simultaneous + reverse connections are always enabled. On Unix/MacOSX with the + provided ssvncviewer they are disabled by default. To enable them: + Options -> Advanced -> Unix ssvncviewer -> Multiple LISTEN Connections + + Specify a specific interface, e.g. 192.168.1.1:0 to have stunnel + only listen on that interface. IPv6 works too, e.g. :::0 or ::1:0 + This also works for UN-encrypted reverse connections as well ('None'). + + See the Options Help for more info. + + 3) You can put global options in your ~/.ssvncrc file (ssvnc_rc on + Windows). Currently they are: + + Put "mode=tsvnc" or "mode=sshvnc" in the ~/.ssvncrc file to have + the application start up in the given mode. + + desktop_type=wmaker (e.g.) to switch the default Desktop Type. + + desktop_size=1280x1024 (e.g.) to switch the default Desktop Size. + + desktop_depth=24 (e.g.) to switch the default Desktop Color Depth + + xserver_type=Xdummy (e.g.) to switch the default X Server Type. + + (The above 4 settings apply only to the Terminal Services Mode.) + + noenc=1 (same as the -noenc option for a 'No Encryption' option) + noenc=0 (do not show the 'No Encryption' option) + + killstunnel=1 (same as -killstunnel), on Windows automatically kills + the STUNNEL process when the viewer exits. Disable via killstunnel=0 + and -nokillstunnel. + + ipv6=0 act as though IPv6 was not detected. + ipv6=1 act as though IPv6 was detected. + + cotvnc=1 have the default vncviewer on Mac OS X be the Chicken of + the VNC. By default the included ssvnc X11 vncviewer is used + (requires Mac OS X X11 server to be running.) + + mycert=file (same as -mycert file option). Set your default MyCert + to "file". If file does not exist ~/.vnc/certs/file is used. + + cacert=file (same as -cacert file option). Set your default ServerCert + to "file". If file does not exist ~/.vnc/certs/file is used. If + file is "CA" then ~/.vnc/certs/CA/cacert.pem is used. + + crl=file (same as -crl file option). Set your default CRL File + to "file". If file does not exist ~/.vnc/certs/file is used. + + Prefix any of these cert/key files with "FORCE:" to make them + immutable, e.g. "cacert=FORCE:CA". + + You can set any environment variable in ~/.ssvncrc by using a line + like env=VAR=value, for example: env=SSVNC_FINISH_SLEEP=2 + + To change the fonts (see Tip 4 below for examples): + + font_default=tk-font-name (sets the font for menus and buttons) + font_fixed=tk-font-name (sets the font for help text) + + 4) Fonts: To change the tk fonts, set these environment variables + before starting up ssvnc: SSVNC_FONT_DEFAULT and SSVNC_FONT_FIXED. + For example: + + % env SSVNC_FONT_DEFAULT='helvetica -20 bold' ssvnc + % env SSVNC_FONT_FIXED='courier -14' ssvnc + + or set both of them at once. You can also set 'font_default' and + 'font_fixed' in your ~/.ssvncrc. E.g.: - 3) If you want to make a Direct VNC connection, WITH *NO* SSL OR - SSH ENCRYPTION, use the "vnc://" prefix in the VNC Host:Display - entry box, e.g. "vnc://far-away.east:0" This also works for - reverse connections, e.g. vnc://0 + font_default=helvetica -16 bold + font_fixed=courier -12 + + 5) If you want to make a Direct VNC connection, WITH *NO* SSL OR + SSH ENCRYPTION or authentication, use the "vnc://" prefix in the + VNC Host:Display entry box, e.g. "vnc://far-away.east:0" This + also works for reverse connections, e.g. vnc://0 Use Vnc:// (i.e. capital 'V') to avoid being prompted if you are sure you want no encryption. For example, "Vnc://far-away.east:0" - Shift+Ctrl-E in the entry box is a short-cut to add or remove the prefix "Vnc://" from the host:disp string. - Note as of SSVNC 1.0.25 the '-noenc' mode is now the default. I.e. - the 'No Encryption' option ('None') is shown by default. To disable - the button supply the '-enc' cmdline option. - - You can also run ssvnc with the '-noenc' cmdline option (now the - default) to have a check option that lets you turn off Encryption - (and profiles will store this setting). Pressing Ctrl-E on - the main panel is a short-cut to toggle between the -noenc - 'No Encryption' mode and normal mode. The option "Show 'No - Encryption' Option" under Options also toggles it. + You can also run ssvnc with the '-noenc' cmdline option (now + the default) to have a check option 'None' that lets you turn off + Encryption (and profiles will store this setting). Pressing Ctrl-E + on the main panel is a short-cut to toggle between the -noenc 'No + Encryption' mode and normal mode. The option "Show 'No Encryption' + Option" under Options also toggles it. The '-enc' option disables the button (and so makes it less obvious - how do disable encryption.) + to naive users how to disable encryption.) + + Note as of SSVNC 1.0.25 the '-noenc' mode is now the default. I.e. + the 'No Encryption' option ('None') is shown by default. When + you select 'None' you do not need to supply the "vnc://" prefix. + To disable the button supply the '-enc' cmdline option. Setting SSVNC_DISABLE_ENCRYPTION_BUTTON=1 in your environment is the same as -noenc. You can also put noenc=1 in your ~/.ssvncrc file. @@ -1294,23 +1480,23 @@ proc help {} { password) over the network that can be sniffed. It is also possible (although difficult) for someone to hijack an - unencrypted VNC session. + existing unencrypted VNC session. Often SSVNC is used to connect to x11vnc where the Unix username and password is sent over the channel. It would be a very bad idea to - let that data be sent over an unencrypted connection. In general, + let that data be sent over an unencrypted connection! In general, it is not wise to have a plaintext VNC connection. Note that even the VNC Password challenge-response method (the password - is not sent in plaintext) leaves your VNC password susceptible a + is not sent in plaintext) leaves your VNC password susceptible to a dictionary attack unless encryption is used to hide it. - So (before we made the button on by default!) we forced you to - learn about and supply the "vnc://" or "Vnc://" prefix to the - host:port or use -noenc or the "Show 'No Encryption' Option" + So (well, before we made the button visible by default!) we forced + you to learn about and supply the "vnc://" or "Vnc://" prefix to + the host:port or use -noenc or the "Show 'No Encryption' Option" to disable encryption. This is a small hurdle, but maybe someone - will think twice. It is a shame that VNC has been around for over - 10 years and still does not have built-in strong encryption. + will think twice. It is a shame that VNC has been around for + over 10 years and still does not have built-in strong encryption. Note the Vnc:// or vnc:// prefix will be stored in any profile that you save so you do not have to enter it every time. @@ -1318,65 +1504,7 @@ proc help {} { Set the env var SSVNC_NO_ENC_WARN=1 to skip the warning prompts the same as the capitalized Vnc:// does. - 4) If you use "SHELL" for the "Remote SSH Command" (or in the display - line: "user@hostname cmd=SHELL") then you get an SSH shell only: - no VNC viewer will be launched. On Windows "PUTTY" will try - to use putty.exe (better terminal emulation than plink.exe). - - A ShortCut for this is Ctrl-S with user@hostname in the entry box. - - 5) If you use "KNOCK" for the "Remote SSH Command" (or in the display - line "user@hostname cmd=KNOCK") then only the port-knocking is done. - - A ShortCut for this is Ctrl-P with hostname 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. - - 6) Reverse VNC connections (Listening) are possible as well. - In this case the VNC Server initiates the connection to your - waiting (i.e. listening) SSVNC viewer. - - Go to Options and select "Reverse VNC connection". In the 'VNC - Host:Display' entry box put in the number (e.g. "0" or ":0", or - ":1", etc) that corresponds to the Listening display (0 -> port - 5500, 1 -> port 5501, etc.) you want to use. Then clicking on - 'Listen' puts your SSVNC viewer in a "listening" state on that - port number, waiting for a connection from the VNC Server. - - See the Options Help for more info. - - 7) On Unix to have SSVNC act as a general STUNNEL redirector (i.e. no - VNC), put the desired host:port in VNC Host:Display (use a - negative port value if it is to be less than 200), then go to - Options -> Advanced -> Change VNC Viewer. Change the "viewer" - command to be "xmessage OK" or "xmessage <port>" (or sleep) where - port is the desired local listening port. Then click Connect. - If you didn't set the local port look for it in the terminal output. - - On Windows set 'viewer' to "NOTEPAD" or similar; you can't - control the port though. It is usually 5930, 5931, ... Watch - the messages or look at the stunnel log. - - 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 - to disable the ssh "-t" option being used (that can prevent the - command from being run). - - 9) In the VNC Host:Display entry you can also use these "URL-like" - prefixes: - - vncs://host:0, vncssl://host:0, vnc+ssl://host:0 for SSL - - and - - vncssh://host:0, vnc+ssh://host:0 for SSH - - There is no need to toggle the SSL/SSH setting. These also work - from the command line, e.g.: ssvnc vnc+ssh://mymachine:10 - - 10) Mobile USB memory stick / flash drive usage: You can unpack + 6) Mobile USB memory stick / flash drive usage: You can unpack ssvnc to a flash drive for impromptu usage (e.g. from a friends computer). @@ -1400,70 +1528,19 @@ proc help {} { cd \ssvnc\Windows start \ssvnc\Windows\ssvnc.exe - 11) Dynamic VNC Server Port determination and redirection: If you - are running SSVNC on Unix and are using SSH to start the remote - VNC server and the VNC server prints out the line "PORT=NNNN" - to indicate which dynamic port it is using (x11vnc does this), - then if you prefix the SSH command with "PORT=" SSVNC will watch - for the PORT=NNNN line and uses ssh's built in SOCKS proxy - (ssh -D ...) to connect to the dynamic VNC server port through - the SSH tunnel. For example: - - VNC Host:Display user@somehost.com - Remote SSH Command: PORT= x11vnc -find -nopw - - or "PORT= x11vnc -display :0 -localhost", etc. Or use "P= ..." - - There is also code to detect the display of the regular Unix - vncserver(1). It extracts the display (and hence port) from - the lines "New 'X' desktop is hostname:4" and also - "VNC server is already running as :4". So you can use - something like: - - PORT= vncserver; sleep 15 - or: PORT= vncserver :4; sleep 15 - - the latter is preferred because when you reconnect with it will - find the already running one. The former one will keep creating - new X sessions if called repeatedly. - - On Windows if PORT= is supplied SOCKS proxying is not used, but - rather a high, random value of the VNC port is chosen (e.g. 8453) - and assumed to be free, and is passed to x11vnc's -rfbport option. - This only works with x11vnc (not vncserver). - - 12) Tricks with environment variables: - - You can change the X DISPLAY variable by typing DISPLAY=... into - VNC Host:Display and hitting Return or clicking Connect. Same - for HOME=. On Mac, you can set DYLD_LIBRARY_PATH=... too. - It should propagate down the viewer. + 7) In the VNC Host:Display entry you can also use these "URL-like" + prefixes: - Setting SLEEP=n increases the amount of time waited before - starting the viewer. The env. var. SSVNC_EXTRA_SLEEP also does - this (and also Sleep: Option setting) Setting FINISH=n sets the - amount of time slept before the Terminal window exits on Unix - and MacOS X. (same as SSVNC_FINISH_SLEEP env. var.) + vncs://host:0, vncssl://host:0, vnc+ssl://host:0 for SSL - Full list of parameters HOME/SSVNC_HOME, DISPLAY/SSVNC_DISPLAY - DYLD_LIBRARY_PATH/SSVNC_DYLD_LIBRARY_PATH, SLEEP/SSVNC_EXTRA_SLEEP - FINISH/SSVNC_FINISH_SLEEP, DEBUG_NETSTAT, REPEATER_FORCE, SSH_ONLY. - (the ones joined by "/" are equivalent names, and the latter can - be set as an env. var. as well.) + and - After you set the parameter, clear out the 'VNC Host:Display' - entry and replace it with the actual host and display number. + vncssh://host:0, vnc+ssh://host:0 for SSH - To replace the xterm terminal where most of the external commands - are run set SSVNC_XTERM_REPLACEMENT to a command that will run - a command in a terminal. I.e.: "$SSVNC_XTERM_REPLACEMENT cmd" - will run cmd. If present, %GEOMETRY is expanded to a desired - +X+Y geometry. If present, %TITLE is expanded to a desired title. - Examples: SSVNC_XTERM_REPLACEMENT='gnome-terminal -e' - SSVNC_XTERM_REPLACEMENT='gnome-terminal -t "%TITLE" -e' - SSVNC_XTERM_REPLACEMENT='konsole -e' + There is no need to toggle the SSL/SSH setting. These also work + from the command line, e.g.: ssvnc vnc+ssh://mymachine:10 - 13) If you want this application to be SSH only, then supply the + 8) If you want this application to be SSH only, then supply the command line option "-ssh" or set the env. var SSVNC_SSH_ONLY=1. Then no GUI elements specific to SSL will appear (the @@ -1477,7 +1554,7 @@ proc help {} { Or in your ~/.ssvncrc (or ~/ssvnc_rc on Windows) put "mode=sshvnc" to have the tool always start up in that mode. - 14) For an even simpler "Terminal Services" mode use "tsvnc" or + 9) For an even simpler "Terminal Services" mode use "tsvnc" or "tsvnc.bat" (or "-ts" option). This mode automatically launches x11vnc on the remote side to find or create your Desktop session (usually the Xvfb X server). So x11vnc must be available on the @@ -1490,53 +1567,82 @@ proc help {} { Or in your ~/.ssvncrc (or ~/ssvnc_rc on Windows) put "mode=tsvnc" to have the tool always start up in that mode. - 15) You can put global options in your ~/.ssvncrc file (ssvnc_rc on - Windows). Currently they are: + 10) On Unix to get a 2nd GUI (e.g. for a 2nd connection) press Ctrl-N + on the GUI. If only the xterm window is visible you can press + Ctrl-N or try Ctrl-LeftButton -> New SSVNC_GUI. On Windows you + will have to manually Start a new one: Start -> Run ..., etc. - Put "mode=tsvnc" or "mode=sshvnc" in the ~/.ssvncrc file to have - the application start up in the given mode. + 11) Pressing the "Load" button or pressing Ctrl-L or Clicking the Right + mouse button on the main GUI will invoke the Load dialog. - desktop_type=wmaker (e.g.) to switch the default Desktop Type. + Pressing Ctrl-O on the main GUI will bring up the Options Panel. + Pressing Ctrl-A on the main GUI will bring up the Advanced Options. - desktop_size=1280x1024 (e.g.) to switch the default Desktop Size. + 12) If you use "SHELL" for the "Remote SSH Command" (or in the display + line: "user@hostname cmd=SHELL") then you get an SSH shell only: + no VNC viewer will be launched. On Windows "PUTTY" will try + to use putty.exe (better terminal emulation than plink.exe). - desktop_depth=24 (e.g.) to switch the default Desktop Color Depth + A ShortCut for this is Ctrl-S with user@hostname in the entry box. - xserver_type=Xdummy (e.g.) to switch the default X Server Type. + 13) If you use "KNOCK" for the "Remote SSH Command" (or in the display + line "user@hostname cmd=KNOCK") then only the port-knocking is done. - (The above 4 settings apply only to the Terminal Services Mode.) + A ShortCut for this is Ctrl-P with hostname the entry box. - noenc=1 (same as the -noenc option for a 'No Encryption' option) - noenc=0 (do not show the 'No Encryption' option) + 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. - killstunnel=1 (same as -killstunnel), on Windows automatically kills - the STUNNEL process when the viewer exits. Disable via killstunnel=0 - and -nokillstunnel. + 14) On Unix to have SSVNC act as a general STUNNEL redirector (i.e. no + VNC), put the desired host:port in VNC Host:Display (use a + negative port value if it is to be less than 200), then go to + Options -> Advanced -> Change VNC Viewer. Change the "viewer" + command to be "xmessage OK" or "xmessage <port>" (or sleep) where + 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. - cotvnc=1 have the default vncviewer on Mac OS X be the Chicken of - the VNC. By default the included ssvnc X11 vncviewer is used - (requires Mac OS X X11 server to be running.) + On Windows set 'viewer' to "NOTEPAD" or similar; you can't + control the port though. It is usually 5930, 5931, ... Watch + the messages or look at the stunnel log. - mycert=file (same as -mycert file option). Set your default MyCert - to "file". If file does not exist ~/.vnc/certs/file is used. + 15) Tricks with environment variables: - cacert=file (same as -cacert file option). Set your default ServerCert - to "file". If file does not exist ~/.vnc/certs/file is used. If - file is "CA" then ~/.vnc/certs/CA/cacert.pem is used. + You can change the X DISPLAY variable by typing DISPLAY=... into + VNC Host:Display and hitting Return or clicking Connect. Same + for HOME=. On Mac, you can set DYLD_LIBRARY_PATH=... too. + It should propagate down the viewer. - crl=file (same as -crl file option). Set your default CRL File - to "file". If file does not exist ~/.vnc/certs/file is used. + Setting SLEEP=n increases the amount of time waited before + starting the viewer. The env. var. SSVNC_EXTRA_SLEEP also does + this (and also Sleep: Option setting) Setting FINISH=n sets the + amount of time slept before the Terminal window exits on Unix + and MacOS X. (same as SSVNC_FINISH_SLEEP env. var.) - Prefix any of these cert/key files with "FORCE:" to make them - immutable, e.g. "cacert=FORCE:CA". + Full list of parameters HOME/SSVNC_HOME, DISPLAY/SSVNC_DISPLAY + DYLD_LIBRARY_PATH/SSVNC_DYLD_LIBRARY_PATH, SLEEP/SSVNC_EXTRA_SLEEP + FINISH/SSVNC_FINISH_SLEEP, DEBUG_NETSTAT, REPEATER_FORCE, + SSH_ONLY, TS_ONLY, NO_DELETE, BAT_SLEEP, IPV6/SSVNC_IPV6=0 or 1. + See below for more info. (the ones joined by "/" are equivalent + names, and the latter can be set as an env. var. as well.) - You can set any environment variable in ~/.ssvncrc by using a line - like env=VAR=value, for example: env=SSVNC_FINISH_SLEEP=2 + After you set the parameter, clear out the 'VNC Host:Display' + entry and replace it with the actual host and display number. - To change the fonts (see Tip 18 below for examples): + To replace the xterm terminal where most of the external commands + are run set SSVNC_XTERM_REPLACEMENT to a command that will run + a command in a terminal. I.e.: "$SSVNC_XTERM_REPLACEMENT cmd" + will run cmd. If present, %GEOMETRY is expanded to a desired + +X+Y geometry. If present, %TITLE is expanded to a desired title. + Examples: SSVNC_XTERM_REPLACEMENT='gnome-terminal -e' + SSVNC_XTERM_REPLACEMENT='gnome-terminal -t "%TITLE" -e' + SSVNC_XTERM_REPLACEMENT='konsole -e' - font_default=tk-font-name (sets the font for menus and buttons) - font_fixed=tk-font-name (sets the font for help text) + More info: EXTRA_SLEEP: seconds of extra sleep in scripts; + FINISH_SLEEP: final extra sleep at end; DEBUG_NETSTAT put up a + window showing what netstat reports; NO_DELETE: do not delete tmp + bat files on Windows (for debugging); BAT_SLEEP: sleep this many + seconds at the end of each Windows bat file (for debugging.) 16) On Unix you can make the "Open File" and "Save File" dialogs bigger by setting the env. var. SSVNC_BIGGER_DIALOG=1 or @@ -1547,18 +1653,115 @@ proc help {} { vars to 1: SSVNC_STUNNEL_DEBUG, SSVNC_VENCRYPT_DEBUG, and SS_DEBUG (very verbose) - 18) Fonts: To change the tk fonts, set these environment variables - before starting up ssvnc: SSVNC_FONT_DEFAULT and SSVNC_FONT_FIXED. - For example: + 18) Dynamic VNC Server Port determination and redirection: If you + are running SSVNC on Unix and are using SSH to start the remote + VNC server and the VNC server prints out the line "PORT=NNNN" + to indicate which dynamic port it is using (x11vnc does this), + then if you prefix the SSH command with "PORT=" SSVNC will watch + for the PORT=NNNN line and uses ssh's built in SOCKS proxy + (ssh -D ...) to connect to the dynamic VNC server port through + the SSH tunnel. For example: - % env SSVNC_FONT_DEFAULT='helvetica -20 bold' ssvnc - % env SSVNC_FONT_FIXED='courier -14' ssvnc + VNC Host:Display user@somehost.com + Remote SSH Command: PORT= x11vnc -find -nopw - or set both of them at once. You can also set 'font_default' and - 'font_fixed' in your ~/.ssvncrc. E.g.: + or "PORT= x11vnc -display :0 -localhost", etc. Or use "P= ..." - font_default=helvetica -16 bold - font_fixed=courier -12 + There is also code to detect the display of the regular Unix + vncserver(1). It extracts the display (and hence port) from + the lines "New 'X' desktop is hostname:4" and also + "VNC server is already running as :4". So you can use + something like: + + PORT= vncserver; sleep 15 + or: PORT= vncserver :4; sleep 15 + + the latter is preferred because when you reconnect with it will + find the already running one. The former one will keep creating + new X sessions if called repeatedly. + + On Windows if PORT= is supplied SOCKS proxying is not used, but + rather a high, random value of the VNC port is chosen (e.g. 8453) + and assumed to be free, and is passed to x11vnc's -rfbport option. + This only works with x11vnc (not vncserver). + + 19) 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 + to disable the ssh "-t" option being used (that can prevent the + command from being run). + + 20) SSVNC is basically a wrapper for the stunnel and ssh programs, + and because those two programs have good IPv6 support SSVNC will + for most usage modes support it as well. IPv6 is 128 bit internet + addresses (as opposed to IPv4 with its 32 bit xxx.yyy.zzz.nnn IPs. + + So for basic SSL and SSH connections if you type in an IPv6 IP + address, e.g. '2001:4860:b009::68', or a hostname with only an + IPv6 lookup, e.g. ipv6.l.google.com, the connection will work + because stunnel and ssh handle these properly. + + Note that you often need to supply a display number or port after + the address so put it, e.g. ':0' at the end: 2001:4860:b009::68:0 + You can also use the standard notation [2001:4860:b009::68]:0 + that is more clear. You MUST specify the display if you use + the IPv6 address notation (but :0 is still the default for a + non-numeric hostname string.) + + IPv4 addresses encoded in IPv6 notation also work, e.g. + ::ffff:192.168.1.100 should work for the most part. + + SSVNC on Unix and MacOSX also has its own Proxy helper tool + (pproxy) This script has been modified to handle IPv6 hostnames + and addresses as long as the IO::Socket::INET6 Perl module + is available. On Windows the relay6.exe tool is used. + + So for the most part IPv6 should work without you having to do + anything special. However, for rare usage, the proxy helper tool + can also treat and IPv6 address as a special sort of 'proxy'. + So in the entry Proxy/Gateway you can include ipv6://host:port + and the IPv6 host will simply be connected to and the data + transferred. In this usage mode, set the VNC Host:Display + to anything, e.g. 'localhost:0'; it is ignored if the ipv6:// + endpoint is specified as a proxy. Need for ipv6:// usage proxy + should be rare. + + Note that for link local (not global) IPv6 addresses you may + need to include the network interface at the end of the address, + e.g. fe80::a00:20ff:fefd:53d4%eth0 + + Note that one can use a 3rd party VNC Viewer with SSVNC (see + Options -> Advanced -> Change VNC Viewer.) IPv6 will work for + them as well even if they do not support IPv6. + + IPv6 support on Unix, MacOSX, and Windows is essentially complete + for all types of connections (including proxied, unencrypted and + reverse connections.) Let us know if you find a scenario that + does not work (see the known exception for putty/plink below.) + + You can set ipv6=0 in your ssvncrc, then no special relaying for + IPv6 will be done (do this if there are problems or slowness in + trying to relay ipv6 and you know you will not connect to any + such hosts.) Set ipv6=1 to force the special processing even if + IPv6 was not autodetected. To change this dynamically, you also + enter IPV6=... in the VNC Host:Display entry box and press Enter. + Also on Unix or MacOSX you can set the env. var. SSVNC_IPV6=0 + to disable the wrapper script from checking if hosts have ipv6 + addresses (this is the same as setting ipv6=0 in ssvncrc or by + the setting ipv6 in the Entry box.) + + On Windows plink.exe (SSH client) currently doesn't work for + IPv6 address strings (e.g. 2001:4860:b009::68) but it does work + for hostname strings that resolve to IPv6 addresses. + + Note that one can make a home-brew SOCKS5 ipv4-to-ipv6 gateway + proxy using ssh like this: + + ssh -D '*:1080' localhost "printf 'Press Enter to Exit: '; read x" + + then specify a proxy like socks5://hostname:1080 where hostname + is the machine running the above ssh command. Add '-v' to the + ssh cmdline for verbose output. See also the x11vnc inet6to4 tool + (a direct ipv4/6 relay, not socks.) } global version @@ -1845,7 +2048,7 @@ proc help_certs {} { The former corresponds to the "CAfile" STUNNEL parameter. The latter corresponds to the "CApath" STUNNEL parameter. - See stunnel(8) or www.stunnel.org for more information. + See stunnel(8) or stunnel.mirt.net for more information. If the remote VNC Server fails to authenticate itself with respect to the specified certificate(s), then the VNC Viewer (your side) will drop the @@ -1936,7 +2139,7 @@ proc help_certs {} { http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tunnel-ext http://www.karlrunge.com/x11vnc/ssl.html - http://www.stunnel.org + http://stunnel.mirt.net A common way to create and use a VNC Server certificate is: @@ -2055,7 +2258,7 @@ set msg { On MacOSX try to use the bundled X11 vncviewer instead of the Chicken of the VNC viewer; the Xquartz X server must be installed (it is by default on 10.5.x) and the DISPLAY variable must be set - (see Tip 12 of SSVNC Help to do this manually.) + (see Tip 15 of SSVNC Help to do this manually.) Advanced Options: @@ -2325,6 +2528,7 @@ set msg { Reverse VNC Connection: Reverse (listening) VNC connections are possible as well. + Enable with this button "Reverse VNC Connection (-LISTEN)" In this case the VNC Server initiates the connection to your waiting (i.e. listening) SSVNC viewer. @@ -2362,6 +2566,12 @@ set msg { The "listen.pem" will be reused in later SSL Listening connections unless you specify a different one with MyCert. + On Windows or using a 3rd party VNC Viewer multiple, + simultaneous reverse connections are always enabled. + On Unix/MacOSX with the provided ssvncviewer they are disabled + by default. To enable them: + Options -> Advanced -> Unix ssvncviewer -> Multiple LISTEN Conns. + For reverse connections in SSH or SSH + SSL modes it is a little trickier. The SSH tunnel (with -R tunnel) must be established and remain up waiting for reverse connections. @@ -2388,6 +2598,10 @@ set msg { viewers supplied in the SSVNC package will only listen on localhost so these precautions are not needed. + Specify a specific interface, e.g. 192.168.1.1:0 to have stunnel + only listen on that interface. IPv6 works too, e.g. :::0 or ::1:0 + Also works for UN-encrypted reverse connections as well ('None'). + Note that for SSL connections use of "Proxy/Gateway" does not make sense: the remote side cannot initiate its reverse connection via the Proxy. @@ -2413,7 +2627,7 @@ set msg { instead of the Chicken of the VNC viewer; The Xquartz X server must be installed (it is by default on 10.5.x) and the DISPLAY variable must - be set (see Tip 12 of Help to do this manually.) + be set (see Tip 15 of Help to do this manually.) Put cotvnc=1 in ~/.ssvncrc to switch the default. Kill Stunnel Automatically: @@ -2492,7 +2706,7 @@ set msg { a check item "None" on the main panel and also a "No Encryption" check item in the "Options" panel. If you select this item, there will be NO encryption for the VNC - connection (use cautiously) See Tip 3) under Help for more + connection (use cautiously) See Tip 5) under Help for more information about disabling encryption. @@ -3227,6 +3441,9 @@ proc do_viewer_windows {n} { append cmd " /quality $use_quality" } } + + set ipv6_pid2 "" + set extra "" if {$use_listen} { if {$vncviewer_realvnc4} { append cmd " listen=1" @@ -3237,7 +3454,18 @@ proc do_viewer_windows {n} { if {$nn < 100} { set nn [expr "$nn + 5500"] } + global direct_connect_reverse_host_orig is_win9x + if {$direct_connect_reverse_host_orig != "" && !$is_win9x} { + set nn2 [expr $nn + 15] + set h0 $direct_connect_reverse_host_orig + global win_localhost + set extra "\n\n relay6.exe $nn $win_localhost $nn2 /b:$h0" + set ipv6_pid2 [exec relay6.exe $nn $win_localhost $nn2 /b:$h0 &] + set nn $nn2 + } + append cmd " $nn" + global did_listening_message if {$did_listening_message < 3} { incr did_listening_message @@ -3268,7 +3496,7 @@ proc do_viewer_windows {n} { ONLY AFTER THAT will you return to the SSVNC GUI. - Click OK now to start the Listening VNC Viewer. + Click OK now to start the Listening VNC Viewer.$extra " global use_ssh use_sshssl if {$use_ssh || $use_sshssl} { @@ -3322,6 +3550,11 @@ proc do_viewer_windows {n} { mesg $cmd set emess "" set rc [catch {eval exec $cmd} emess] + + if {$ipv6_pid2 != ""} { + winkill $ipv6_pid2 + } + if {$rc != 0} { raise . tk_messageBox -type ok -icon error -message $emess -title "Error: $cmd" @@ -3422,6 +3655,50 @@ proc guess_nat_ip {} { return $ip } +proc check_for_ipv6 {} { + global is_windows have_ipv6 + if {$have_ipv6 != ""} { + return + } + if {! $is_windows} { + set out "" + catch {set out [exec netstat -an]} + if [regexp {tcp6} $out] { + set have_ipv6 1 + } elseif [regexp {udp6} $out] { + set have_ipv6 1 + } elseif [regexp {:::} $out] { + set have_ipv6 1 + } elseif [regexp {::1} $out] { + set have_ipv6 1 + } elseif [regexp {TCP: IPv6.*LISTEN} $out] { + set have_ipv6 1 + } else { + set have_ipv6 0 + } + } else { + set out [get_ipconfig] + set out [string trim $out] + if {$out == ""} { + catch {set out [exec ping6 -n 1 -w 2000 ::1]} + if [regexp {Reply from.*bytes} $out] { + if [regexp {Received = 1} $out] { + set have_ipv6 1 + return + } + } + set have_ipv6 0 + return + } + foreach line [split $out "\n\r"] { + if {[regexp -nocase {IP Address.*:[ \t]*[a-f0-9]*:[a-f0-9]*:} $line]} { + set have_ipv6 1 + return + } + } + set have_ipv6 0 + } +} proc guess_ip {} { global is_windows if {! $is_windows} { @@ -3458,6 +3735,31 @@ proc guess_ip {} { } } } + foreach line [split $out "\n\r"] { + if {[regexp -nocase {IP Address.*:[ \t]*([:a-f0-9][%:a-f0-9]*)} $line mvar ip]} { + set ip [string trim $ip] + if [regexp {^[.0]*$} $ip] { + continue + } + if [regexp {127\.0\.0\.1} $ip] { + continue + } + if {$ip != ""} { + return $ip + } + } + } + } +} + +proc bat_sleep {fh} { + global env + if [info exists env(SSVNC_BAT_SLEEP)] { + puts $fh "@echo ." + puts $fh "@echo -----" + puts $fh "@echo Debug: BAT SLEEP for $env(SSVNC_BAT_SLEEP) seconds ..." + puts $fh "@ping -n $env(SSVNC_BAT_SLEEP) -w 1000 0.0.0.1 > NUL" + puts $fh "@echo BAT SLEEP done." } } @@ -3470,14 +3772,23 @@ proc windows_start_sound_daemon {file} { set fh2 [open $file2 "w"] puts $fh2 $sound_daemon_local_cmd + bat_sleep $fh2 puts $fh2 "del $file2" close $fh2 mesg "Starting SOUND daemon..." if [info exists env(COMSPEC)] { - exec $env(COMSPEC) /c $file2 & + if [info exists env(SSVNC_BAT_SLEEP)] { + exec $env(COMSPEC) /c start $env(COMSPEC) /c $file2 & + } else { + exec $env(COMSPEC) /c $file2 & + } } else { - exec cmd.exe /c $file2 & + if [info exists env(SSVNC_BAT_SLEEP)] { + exec cmd.exe /c start cmd.exe /c $file2 & + } else { + exec cmd.exe /c $file2 & + } } after 1500 } @@ -3564,10 +3875,11 @@ proc make_plink {} { } proc ssh_split {str} { - if {! [regexp {:} $str]} { + regsub { .*$} $str "" str + if {! [regexp {:[0-9][0-9]*$} $str]} { append str ":22" } - regsub {:.*$} $str "" ssh_host + regsub {:[0-9][0-9]*$} $str "" ssh_host regsub {^.*:} $str "" ssh_port if {$ssh_port == ""} { set ssh_port 22 @@ -3624,10 +3936,12 @@ proc launch_windows_ssh {hp file n} { set vnc_disp $hpnew regsub {^.*:} $vnc_disp "" vnc_disp + regsub {\.bat} $file ".flg" flag + if {$ts_only} { regsub {:0$} $hpnew "" hpnew if {$proxy == ""} { - if {[regexp {^([^:]*):([0-9][0-9]*)$} $hpnew mv sshhst sshpt]} { + if {[regexp {^(.*):([0-9][0-9]*)$} $hpnew mv sshhst sshpt]} { set proxy "$sshhst:$sshpt" set hpnew $win_localhost } @@ -3677,9 +3991,11 @@ proc launch_windows_ssh {hp file n} { set vnc_port $vnc_disp } + global ssh_ipv6_pid + set ssh_ipv6_pid "" + set ssh_port 22 - set ssh_host $hpnew - regsub {:.*$} $ssh_host "" ssh_host + set ssh_host [host_part $hpnew] set double_ssh "" set p_port "" @@ -3749,12 +4065,20 @@ proc launch_windows_ssh {hp file n} { set port2 [rand_port] } + global have_ipv6 + if {$have_ipv6} { + set res [ipv6_proxy $pproxy "" ""] + set pproxy [lindex $res 0] + set ssh_ipv6_pid [lindex $res 3] + } + set env(SSVNC_PROXY) $pproxy set env(SSVNC_LISTEN) $port2 set env(SSVNC_DEST) "$sproxy1_host:$sproxy1_port" mesg "Starting Proxy TCP helper on port $port2 ..." after 300 + # ssh br case: set proxy_pid [exec "connect_br.exe" &] catch { unset env(SSVNC_PROXY) } @@ -3779,6 +4103,8 @@ proc launch_windows_ssh {hp file n} { if {$is_win9x} { mesg "Double proxy does not work on Win9x" bell + winkill $ssh_ipv6_pid + set ssh_ipv6_pid "" return 0 } # user1@gateway:port1,user2@workstation:port2 @@ -3806,6 +4132,13 @@ proc launch_windows_ssh {hp file n} { set ssh_host2 [lindex $s 1] set ssh_port2 [lindex $s 2] + if {! [regexp {^[0-9][0-9]*$} $ssh_port1]} { + set ssh_port1 22 + } + if {! [regexp {^[0-9][0-9]*$} $ssh_port2]} { + set ssh_port2 22 + } + set u1 "" if {$ssh_user1 != ""} { set u1 "${ssh_user1}@" @@ -3823,16 +4156,14 @@ proc launch_windows_ssh {hp file n} { set proxy_use $proxy } - set ssh_host $proxy_use - regsub {:.*$} $ssh_host "" ssh_host - set ssh_port $proxy_use - regsub {^.*:} $ssh_port "" ssh_port - if {$ssh_port == ""} { + set ssh_host [host_part $proxy_use] + + set ssh_port [port_part $proxy_use] + if {! [regexp {^[0-9][0-9]*$} $ssh_port]} { set ssh_port 22 } - set vnc_host $hpnew - regsub {:.*$} $vnc_host "" vnc_host + set vnc_host [host_part $hpnew] if {$vnc_host == ""} { set vnc_host $win_localhost } @@ -3841,6 +4172,8 @@ proc launch_windows_ssh {hp file n} { if {![regexp {^[^ ][^ ]*@} $ssh_host]} { mesg "You must supply a username: user@host..." bell + winkill $ssh_ipv6_pid + set ssh_ipv6_pid "" return 0 } @@ -3898,6 +4231,7 @@ proc launch_windows_ssh {hp file n} { regsub {\.bat} $file "pre.cmd" file_pre_cmd set fh [open $file_pre_cmd "w"] puts $fh "$setup_cmds sleep 10; " + bat_sleep $fh close $fh # VF @@ -3917,11 +4251,13 @@ proc launch_windows_ssh {hp file n} { } puts $fh $plink_str - if {$file_pre_cmd != ""} { - puts $fh "del $file_pre_cmd" + bat_sleep $fh + if {![info exists env(SSVNC_NO_DELETE)]} { + if {$file_pre_cmd != ""} { + puts $fh "del $file_pre_cmd" + } + puts $fh "del $file_pre" } - puts $fh "del $file_pre" - close $fh } } @@ -3995,6 +4331,7 @@ proc launch_windows_ssh {hp file n} { append str " sleep $sleep; " } puts $fh_cmd $str + bat_sleep $fh_cmd close $fh_cmd set sshcmd $setup_cmds @@ -4083,10 +4420,14 @@ proc launch_windows_ssh {hp file n} { puts $fh "echo \" \"" } puts $fh $plink_str - if {$file_cmd != ""} { - puts $fh "del $file_cmd" + bat_sleep $fh + puts $fh "del $flag" + if {![info exists env(SSVNC_NO_DELETE)]} { + if {$file_cmd != ""} { + puts $fh "del $file_cmd" + } + puts $fh "del $file" } - puts $fh "del $file" close $fh catch {destroy .o} @@ -4094,13 +4435,17 @@ proc launch_windows_ssh {hp file n} { catch {destroy .os} if { ![do_port_knock $ssh_host start]} { - catch {file delete $file} - if {$file_cmd != ""} { - catch {file delete $file_cmd} - } - if {$file_pre != ""} { - catch {file delete $file_pre} + if {![info exists env(SSVNC_NO_DELETE)]} { + catch {file delete $file} + if {$file_cmd != ""} { + catch {file delete $file_cmd} + } + if {$file_pre != ""} { + catch {file delete $file_pre} + } } + winkill $ssh_ipv6_pid + set ssh_ipv6_pid "" return 0 } @@ -4111,7 +4456,11 @@ proc launch_windows_ssh {hp file n} { regsub {\.bat} $file "dob.bat" file_double set fhdouble [open $file_double "w"] puts $fhdouble $plink_str_double_ssh - puts $fhdouble "del $file_double" + bat_sleep $fhdouble + puts $fhdouble "del $flag" + if {![info exists env(SSVNC_NO_DELETE)]} { + puts $fhdouble "del $file_double" + } close $fhdouble set com "cmd.exe" @@ -4119,7 +4468,16 @@ proc launch_windows_ssh {hp file n} { set com $env(COMSPEC) } - exec $com /c $file_double & + set ff [open $flag "w"] + puts $ff "flag" + close $ff + + global env + if [info exists env(SSVNC_BAT_SLEEP)] { + exec $com /c start $com /c $file_double & + } else { + exec $com /c $file_double & + } set waited 0 set gotit 0 @@ -4139,7 +4497,11 @@ proc launch_windows_ssh {hp file n} { break } set waited [expr "$waited + 500"] + if {![file exists $flag]} { + break + } } + catch {file delete $flag} if {! $gotit} { after 5000 } @@ -4155,6 +4517,10 @@ proc launch_windows_ssh {hp file n} { } } + set ff [open $flag "w"] + puts $ff "flag" + close $ff + if {$is_win9x} { if {$wdraw} { wm withdraw . @@ -4198,7 +4564,12 @@ proc launch_windows_ssh {hp file n} { mesg "Click on *This* Label when done with 1st SSH 0/$sl" after 600 - exec $com /c $file_pre & + global env + if [info exists env(SSVNC_BAT_SLEEP)] { + exec $com /c start $com /c $file_pre & + } else { + exec $com /c $file_pre & + } catch {lower .; update; raise .; update} @@ -4227,11 +4598,17 @@ proc launch_windows_ssh {hp file n} { if {$wdraw} { wm withdraw . } + update if {$do_shell && [regexp {FINISH} $port_knocking_list]} { catch {exec $com /c $file} } else { - exec $com /c $file & + global env + if [info exists env(SSVNC_BAT_SLEEP)] { + exec $com /c start $com /c $file & + } else { + exec $com /c $file & + } } after 1000 } @@ -4244,8 +4621,10 @@ proc launch_windows_ssh {hp file n} { } return 1 } + set made_plink 0 if {$is_win9x} { make_plink + set made_plink 1 } global plink_status set plink_status "" @@ -4279,8 +4658,17 @@ proc launch_windows_ssh {hp file n} { if {$cnt >= 12} { set cnt 0 } + if {![file exists $flag]} { + set plink_status flag_gone + break + } } + catch {file delete $flag} if {$plink_status == ""} { + if {! $made_plink} { + make_plink + set made_plink 1 + } vwait plink_status } @@ -4300,6 +4688,13 @@ proc launch_windows_ssh {hp file n} { } if {$plink_status != "yes"} { + set m "unknown" + if {$plink_status == "flag_gone"} { + set m "plink script failed" + } elseif {$plink_status == ""} { + set m "timeout" + } + mesg "Error ($m) to $hp" wm deiconify . } else { after 1000 @@ -4312,19 +4707,24 @@ proc launch_windows_ssh {hp file n} { do_port_knock $ssh_host finish } - if {$file != ""} { - catch {file delete $file} - } - if {$file_pre != ""} { - catch {file delete $file_pre} - } - if {$file_pre_cmd != ""} { - catch {file delete $file_pre_cmd} - } - if {$file_double != ""} { - catch {file delete $file_double} + if {![info exists env(SSVNC_NO_DELETE)]} { + if {$file != ""} { + catch {file delete $file} + } + if {$file_pre != ""} { + catch {file delete $file_pre} + } + if {$file_pre_cmd != ""} { + catch {file delete $file_pre_cmd} + } + if {$file_double != ""} { + catch {file delete $file_double} + } } + winkill $ssh_ipv6_pid + set ssh_ipv6_pid "" + global sound_daemon_local_kill if {! $is_win9x && $use_sound && $sound_daemon_local_kill && $sound_daemon_local_cmd != ""} { windows_stop_sound_daemon @@ -4684,7 +5084,7 @@ proc do_unix_pre {tag proxy hp pk_hp} { if {$proxy == ""} { set pxy $hp - regsub {:.*$} $pxy "" pxy + regsub {:[0-9][0-9]*$} $pxy "" pxy set c "$c -proxy '$pxy'" } else { set c "$c -proxy '$proxy'" @@ -5031,7 +5431,7 @@ proc fetch_cert {save} { if [regexp {CONNECTED} $cert_text] { if {[regexp -nocase -line {cipher.*ADH} $cert_text]} { # it is Anonymous Diffie Hellman - mesg "WARNING: Anonymous Diffie Hellman Server detected (no Cert)" + mesg "WARNING: Anonymous Diffie Hellman Server detected (NO CERT)" after 300 .f4.getcert configure -state normal return $cert_text @@ -5044,7 +5444,7 @@ proc fetch_cert {save} { global vencrypt_detected server_vencrypt if {$vencrypt_detected != "" && !$server_vencrypt} { - mesg "VeNCrypt/ANONTLS server detected." + mesg "VeNCrypt or ANONTLS server detected." after 600 } @@ -5247,15 +5647,35 @@ proc fetch_dialog {cert_text hp hpnew ok n} { jiggle_text .fetch.f.t } + +proc host_part {hp} { + regsub {^ *} $hp "" hp + regsub { .*$} $hp "" hp + if [regexp {^[0-9][0-9]*$} $hp] { + return "" + } + set h $hp + regsub {:[0-9][0-9]*$} $hp "" h + return $h +} + +proc port_part {hp} { + regsub { .*$} $hp "" hp + set p "" + if [regexp {:([0-9][0-9]*)$} $hp m val] { + set p $val + } + return $p +} + proc get_vencrypt_proxy {hpnew} { if [regexp -nocase {^vnc://} $hpnew] { return "" } set hpnew [get_ssh_hp $hpnew] - regsub -nocase {^[A-z+]*://} $hpnew "" hpnew - set list [split $hpnew ":"] - set h [lindex $list 0] - set p [lindex $list 1] + regsub -nocase {^[a-z0-9+]*://} $hpnew "" hpnew + set h [host_part $hpnew] + set p [port_part $hpnew] if {$p == ""} { # might not matter, i.e. SSH+SSL only... @@ -5306,13 +5726,130 @@ proc fetch_cert_unix {hp {vencrypt 0} {anondh 0}} { lappend cmd "2>/dev/null" } global env -if [info exists env(CERTDBG)] {puts "\nFetch-cmd: $cmd"} + if [info exists env(CERTDBG)] {puts "\nFetch-cmd: $cmd"} set env(SSVNC_SHOWCERT_EXIT_0) 1 return [eval exec $cmd] } +proc win_nslookup {host} { + global win_nslookup_cache + if [info exists win_nslookup_cache($host)] { + return $win_nslookup_cache($host) + } + if [regexp -nocase {[^a-z0-9:._-]} $host] { + set win_nslookup_cache($host) "invalid" + return $win_nslookup_cache($host) + } + if [regexp {^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$} $host] { + set win_nslookup_cache($host) $host + return $win_nslookup_cache($host) + } + if [regexp -nocase {^[a-f0-9]*:[a-f0-9:]*:[a-f0-9:]*$} $host] { + set win_nslookup_cache($host) $host + return $win_nslookup_cache($host) + } + set nsout "" + catch {set nsout [exec nslookup $host]} + if {$nsout == "" || [regexp -nocase {server failed} $nsout]} { + after 250 + set nsout "" + catch {set nsout [exec nslookup $host]} + } + if {$nsout == "" || [regexp -nocase {server failed} $nsout]} { + set win_nslookup_cache($host) "unknown" + return $win_nslookup_cache($host) + } + regsub -all {Server:[^\n]*\nAddress:[^\n]*} $nsout "" nsout + regsub {^.*Name:} $nsout "" nsout + if [regexp {Address:[ \t]*([^\n]+)} $nsout mv addr] { + set addr [string trim $addr] + if {$addr != ""} { + set win_nslookup_cache($host) $addr + return $win_nslookup_cache($host) + } + } + set win_nslookup_cache($host) "unknown" + return $win_nslookup_cache($host) +} + +proc win_ipv4 {host} { + global win_localhost + set ip [win_nslookup $host]; + if [regexp {^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$} $ip] { + return 1 + } + return 0 +} + +proc ipv6_proxy {proxy host port} { + global is_windows win_localhost have_ipv6 + + if {!$have_ipv6} { + return [list $proxy $host $port ""] + } elseif {!$is_windows} { + return [list $proxy $host $port ""] + } else { + set h0 "" + set p0 "" + set port3 "" + set ipv6_pid "" + set proxy0 $proxy + if {$proxy == ""} { + if [win_ipv4 $host] { + return [list $proxy $host $port ""] + } + set port3 [rand_port] + set h0 $host + set p0 $port + set host $win_localhost + set port $port3 + } else { + set parts [split $proxy ","] + set n [llength $parts] + for {set i 0} {$i < $n} {incr i} { + set part [lindex $parts $i] + set prefix "" + regexp -nocase {^[a-z0-9+]*://} $part prefix + regsub -nocase {^[a-z0-9+]*://} $part "" part + set modit 0 + set h1 "" + set p1 "" + if [regexp {^(.*):([0-9][0-9]*)$} $part mvar h1 p1] { + if {$h1 == "localhost" || $h1 == $win_localhost} { + continue + } elseif [win_ipv4 $h1] { + break + } + set modit 1 + } else { + break + } + if {$modit} { + set port3 [rand_port] + set h0 $h1 + set p0 $p1 + lset parts $i "$prefix$win_localhost:$port3" + break + } + } + if {$h0 != "" && $p0 != "" && $port3 != ""} { + set proxy [join $parts ","] + #mesg "Reset proxy: $proxy"; after 3000 + } + } + if {$h0 != "" && $p0 != "" && $port3 != ""} { + mesg "Starting IPV6 helper on port $port3 ..." + set ipv6_pid [exec relay6.exe $port3 "$h0" "$p0" /b:$win_localhost &] + after 400 + #mesg "r6 $port3 $h0 $p0"; after 3000 + } + return [list $proxy $host $port $ipv6_pid] + } +} + proc fetch_cert_windows {hp {vencrypt 0} {anondh 0}} { + global have_ipv6 regsub {^vnc.*://} $hp "" hp @@ -5329,11 +5866,10 @@ proc fetch_cert_windows {hp {vencrypt 0} {anondh 0}} { } } - set list [split $hpnew ":"] + set host [host_part $hpnew] global win_localhost - set host [lindex $list 0] if {$host == ""} { set host $win_localhost } @@ -5343,9 +5879,7 @@ proc fetch_cert_windows {hp {vencrypt 0} {anondh 0}} { regsub {^.*@} $host "" host } - set disp [lindex $list 1] - set disp [string trim $disp] - regsub { .*$} $disp "" disp + set disp [port_part $hpnew] if {[regexp {^-[0-9][0-9]*$} $disp]} { ; @@ -5360,6 +5894,15 @@ proc fetch_cert_windows {hp {vencrypt 0} {anondh 0}} { set port $disp } + set ipv6_pid "" + if {$have_ipv6} { + set res [ipv6_proxy $proxy $host $port] + set proxy [lindex $res 0] + set host [lindex $res 1] + set port [lindex $res 2] + set ipv6_pid [lindex $res 3] + } + if {$proxy != ""} { global env @@ -5384,8 +5927,10 @@ proc fetch_cert_windows {hp {vencrypt 0} {anondh 0}} { set host $win_localhost set port $port2 + mesg "Starting Proxy TCP helper on port $port2 ..." - after 500 + after 300 + # fetch cert br case: set proxy_pid [exec "connect_br.exe" &] if {$sp == ""} { @@ -5451,6 +5996,10 @@ proc fetch_cert_windows {hp {vencrypt 0} {anondh 0}} { foreach pid $pids { winkill $pid } + if {$ipv6_pid != ""} { + winkill $ipv6_pid + } + catch {close $ph} catch {file delete $tin $tou} return $text @@ -5511,6 +6060,9 @@ proc fetch_cert_windows {hp {vencrypt 0} {anondh 0}} { close $ph } catch {file delete $tin $tou} + if {$ipv6_pid != ""} { + winkill $ipv6_pid + } return $text } @@ -6551,6 +7103,24 @@ proc launch_unix {hp} { set env(SSVNC_MULTIPLE_LISTEN) "1" } + if {$use_ssh} { + ; + } elseif {$use_sshssl} { + ; + } elseif {$use_ssl} { + set prox [get_ssh_proxy $hp] + if {$prox != "" && [regexp {@} $prox]} { + mesg "Error: proxy contains '@' Did you mean to use SSH mode?" + bell + return + } + if [regexp {@} $hp] { + mesg "Error: host contains '@' Did you mean to use SSH mode?" + bell + return + } + } + if {$use_ssh || $use_sshssl} { if {$ssh_local_protection} { if {![info exists env(LIM_ACCEPT)]} { @@ -6600,6 +7170,7 @@ proc launch_unix {hp} { if {$ts_only} { regsub {:0$} $hpnew "" hpnew if {$proxy == ""} { + # XXX host_part if {[regexp {^([^:]*):([0-9][0-9]*)$} $hpnew mv sshhst sshpt]} { set proxy "$sshhst:$sshpt" set hpnew "localhost" @@ -6729,7 +7300,8 @@ proc launch_unix {hp} { set env(SS_VNCVIEWER_SSH_ONLY) 1 if {$proxy == ""} { set hpt $hpnew - regsub {:[0-9]*$} $hpt "" hpt + # XXX host_part + regsub {:[0-9][0-9]*$} $hpt "" hpt set cmd "$cmd -proxy '$hpt'" } set geometry [xterm_center_geometry] @@ -7177,7 +7749,9 @@ proc launch_unix {hp} { init_unixpw $hp - vencrypt_tutorial_mesg + if {! $do_direct} { + vencrypt_tutorial_mesg + } wm withdraw . update @@ -7347,6 +7921,11 @@ proc note_stunnel_pids {when} { proc del_launch_windows_ssh_files {} { global launch_windows_ssh_files + global env + + if {[info exists env(SSVNC_NO_DELETE)]} { + return + } if {$launch_windows_ssh_files != ""} { foreach tf [split $launch_windows_ssh_files] { @@ -7526,7 +8105,7 @@ proc launch {{hp ""}} { regsub {^.*HOME=} $t "" t set t [string trim $t] set env(SSVNC_HOME) $t - mesg "set SSVNC_HOME to $t" + mesg "Set SSVNC_HOME to $t" set vncdisplay "" return 0 } @@ -7535,7 +8114,7 @@ proc launch {{hp ""}} { regsub {^.*DISPLAY=} $t "" t set t [string trim $t] set env(DISPLAY) $t - mesg "set DISPLAY to $t" + mesg "Set DISPLAY to $t" set vncdisplay "" global uname darwin_cotvnc if {$uname == "Darwin"} { @@ -7553,7 +8132,7 @@ proc launch {{hp ""}} { set t [string trim $t] set env(DYLD_LIBRARY_PATH) $t set env(SSVNC_DYLD_LIBRARY_PATH) $t - mesg "set DYLD_LIBRARY_PATH to $t" + mesg "Set DYLD_LIBRARY_PATH to $t" set vncdisplay "" return 0 } @@ -7562,7 +8141,7 @@ proc launch {{hp ""}} { regsub {^.*SLEEP=} $t "" t set t [string trim $t] set env(SSVNC_EXTRA_SLEEP) $t - mesg "set SSVNC_EXTRA_SLEEP to $t" + mesg "Set SSVNC_EXTRA_SLEEP to $t" set vncdisplay "" return 0 } @@ -7571,7 +8150,7 @@ proc launch {{hp ""}} { regsub {^.*SSH=} $t "" t set t [string trim $t] set env(SSH) $t - mesg "set SSH to $t" + mesg "Set SSH to $t" set vncdisplay "" return 0 } @@ -7580,7 +8159,25 @@ proc launch {{hp ""}} { regsub {^.*=} $t "" t set t [string trim $t] set env(SSVNC_FINISH_SLEEP) $t - mesg "set SSVNC_FINISH_SLEEP to $t" + mesg "Set SSVNC_FINISH_SLEEP to $t" + set vncdisplay "" + return 0 + } + if {[regexp {^NO_DELETE=} $hpt] || [regexp {^SSVNC_NO_DELETE=} $hpt]} { + set t $hpt + regsub {^.*=} $t "" t + set t [string trim $t] + set env(SSVNC_NO_DELETE) $t + mesg "Set SSVNC_NO_DELETE to $t" + set vncdisplay "" + return 0 + } + if {[regexp {^BAT_SLEEP=} $hpt] || [regexp {^SSVNC_BAT_SLEEP=} $hpt]} { + set t $hpt + regsub {^.*=} $t "" t + set t [string trim $t] + set env(SSVNC_BAT_SLEEP) $t + mesg "Set SSVNC_BAT_SLEEP to $t" set vncdisplay "" return 0 } @@ -7589,7 +8186,7 @@ proc launch {{hp ""}} { regsub {^.*DEBUG_NETSTAT=} $t "" t global debug_netstat set debug_netstat $t - mesg "set DEBUG_NETSTAT to $t" + mesg "Set DEBUG_NETSTAT to $t" set vncdisplay "" return 0 } @@ -7597,7 +8194,7 @@ proc launch {{hp ""}} { set t $hpt regsub {^.*REPEATER_FORCE=} $t "" t set env(REPEATER_FORCE) $t - mesg "set REPEATER_FORCE to $t" + mesg "Set REPEATER_FORCE to $t" set vncdisplay "" return 0 } @@ -7619,6 +8216,14 @@ proc launch {{hp ""}} { return 0 } + if {[regexp -nocase {^IPV6=([01])} $hpt mv val]} { + global env have_ipv6 + set have_ipv6 $val + set env(SSVNC_IPV6) $val + mesg "Set have_ipv6 to $val" + set vncdisplay "" + return 0 + } regsub {[ ]*cmd=.*$} $hp "" tt @@ -7637,6 +8242,7 @@ proc launch {{hp ""}} { mac_raise return } + # XXX host_part if {! [regexp ":" $hp]} { if {! [regexp {cmd=} $hp]} { set s [string trim $hp] @@ -7649,7 +8255,7 @@ proc launch {{hp ""}} { } if {!$use_ssl && !$use_ssh && !$use_sshssl && $sshssl_sw == "none"} { - regsub -nocase {^[A-z+]*://} $hp "" hp + regsub -nocase {^[a-z0-9+]*://} $hp "" hp set hp "Vnc://$hp" } @@ -7840,11 +8446,33 @@ proc launch {{hp ""}} { global listening_name set listening_name "" + if {$use_ssh} { + ; + } elseif {$use_sshssl} { + ; + } elseif {$use_ssl} { + if {$proxy != "" && [regexp {@} $proxy]} { + mesg "Error: proxy contains '@' Did you mean to use SSH mode?" + bell + return + } + if [regexp {@} $hp] { + mesg "Error: host contains '@' Did you mean to use SSH mode?" + bell + return + } + } + + global ssh_ipv6_pid + set ssh_ipv6_pid "" + if {$use_sshssl} { set rc [launch_windows_ssh $hp $file2 $n2] if {$rc == 0} { - catch {file delete $file1} - catch {file delete $file2} + if {![info exists env(SSVNC_NO_DELETE)]} { + catch {file delete $file1} + catch {file delete $file2} + } del_launch_windows_ssh_files return } @@ -7855,11 +8483,11 @@ proc launch {{hp ""}} { return } - set list [split $hp ":"] + set host [host_part $hp]; + set host_orig $host global win_localhost - set host [lindex $list 0] if {$host == ""} { set host $win_localhost } @@ -7871,9 +8499,7 @@ proc launch {{hp ""}} { regsub {^.*@} $host "" host } - set disp [lindex $list 1] - set disp [string trim $disp] - regsub { .*$} $disp "" disp + set disp [port_part $hp] if {[regexp {^-[0-9][0-9]*$} $disp]} { ; } elseif {$disp == "" || ! [regexp {^[0-9][0-9]*$} $disp]} { @@ -7998,6 +8624,16 @@ proc launch {{hp ""}} { set proxy [maybe_add_vencrypt $proxy $hp] } + set ipv6_pid "" + global have_ipv6 + if {$have_ipv6} { + set res [ipv6_proxy $proxy $host $port] + set proxy [lindex $res 0] + set host [lindex $res 1] + set port [lindex $res 2] + set ipv6_pid [lindex $res 3] + } + if {$proxy != ""} { if {$use_sshssl} { ; @@ -8063,6 +8699,9 @@ proc launch {{hp ""}} { } set listening_name "$hn:$port (or nn.nn.nn.nn:$port, etc.)" } + if {$host_orig != "" && $hloc == ""} { + set hloc "$host_orig:" + } puts $fh "accept = $hloc$port" puts $fh "connect = $win_localhost:$port2" } @@ -8079,7 +8718,17 @@ proc launch {{hp ""}} { } if {$fail} { - catch {file delete $file1} + if {![info exists env(SSVNC_NO_DELETE)]} { + catch {file delete $file1} + } + catch { unset env(SSVNC_PROXY) } + catch { unset env(SSVNC_LISTEN) } + catch { unset env(SSVNC_REVERSE) } + catch { unset env(SSVNC_DEST) } + catch { unset env(SSVNC_PREDIGESTED_HANDSHAKE) } + winkill $ipv6_pid + winkill $ssh_ipv6_pid + set ssh_ipv6_pid "" return } @@ -8087,19 +8736,23 @@ proc launch {{hp ""}} { set proxy_pid "" set proxy_pid2 "" + if {$proxy != ""} { if [regexp {vencrypt:} $proxy] { set vport [expr "$n1 + 5900"] mesg "Starting VeNCrypt helper on port $vport,$port3 ..." after 500 - catch {file delete "$file1.pre"} + if {![info exists env(SSVNC_NO_DELETE)]} { + catch {file delete "$file1.pre"} + } set env(SSVNC_PREDIGESTED_HANDSHAKE) "$file1.pre" set env(SSVNC_VENCRYPT_VIEWER_BRIDGE) "$vport,$port3" set proxy_pid2 [exec "connect_br.exe" &] catch { unset env(SSVNC_VENCRYPT_VIEWER_BRIDGE) } } - mesg "Starting VeNCrypt TCP helper on port $port ..." - after 500 + mesg "Starting TCP helper on port $port ..." + after 400 + # ssl br case: set proxy_pid [exec "connect_br.exe" &] catch { unset env(SSVNC_PROXY) } catch { unset env(SSVNC_LISTEN) } @@ -8136,7 +8789,9 @@ proc launch {{hp ""}} { del_launch_windows_ssh_files - catch {file delete $file1} + if {![info exists env(SSVNC_NO_DELETE)]} { + catch {file delete $file1} + } if {$debug} { ; @@ -8169,6 +8824,9 @@ proc launch {{hp ""}} { win_nokill_msg } mesg "Disconnected from $hp." + winkill $ipv6_pid + winkill $ssh_ipv6_pid + set ssh_ipv6_pid "" global is_win9x use_sound sound_daemon_local_kill sound_daemon_local_cmd if {! $is_win9x && $use_sound && $sound_daemon_local_kill && $sound_daemon_local_cmd != ""} { @@ -8187,11 +8845,11 @@ proc direct_connect_windows {{hp ""}} { global listening_name set listening_name "" - set list [split $hp ":"] + set host [host_part $hp] - global win_localhost + set host_orig $host - set host [lindex $list 0] + global win_localhost if {$host == ""} { set host $win_localhost } @@ -8203,9 +8861,7 @@ proc direct_connect_windows {{hp ""}} { regsub {^.*@} $host "" host } - set disp [lindex $list 1] - set disp [string trim $disp] - regsub { .*$} $disp "" disp + set disp [port_part $hp] if {[regexp {^-[0-9][0-9]*$} $disp]} { ; } elseif {$disp == "" || ! [regexp {^[0-9][0-9]*$} $disp]} { @@ -8224,6 +8880,16 @@ proc direct_connect_windows {{hp ""}} { set port $disp } + global have_ipv6 + set ipv6_pid "" + if {$have_ipv6 && !$use_listen} { + set res [ipv6_proxy $proxy $host $port] + set proxy [lindex $res 0] + set host [lindex $res 1] + set port [lindex $res 2] + set ipv6_pid [lindex $res 3] + } + if {$proxy != ""} { if [regexp {@} $proxy] { bell @@ -8250,13 +8916,18 @@ proc direct_connect_windows {{hp ""}} { } if {$fail} { + catch { unset env(SSVNC_PROXY) } + catch { unset env(SSVNC_LISTEN) } + catch { unset env(SSVNC_DEST) } + winkill $ipv6_pid return } set proxy_pid "" if {$proxy != ""} { mesg "Starting Proxy TCP helper on port $port ..." - after 500 + after 400 + # unencrypted br case: set proxy_pid [exec "connect_br.exe" &] catch { unset env(SSVNC_PROXY) } catch { unset env(SSVNC_LISTEN) } @@ -8275,9 +8946,14 @@ proc direct_connect_windows {{hp ""}} { if {$n >= 5500} { set n [expr $n - 5500] } + global direct_connect_reverse_host_orig + set direct_connect_reverse_host_orig $host_orig + do_viewer_windows "$n" + + set direct_connect_reverse_host_orig "" } else { - if {$port >= 5900} { + if {$port >= 5900 && $port < 6100} { set port [expr $port - 5900] } do_viewer_windows "$host:$port" @@ -8287,6 +8963,8 @@ proc direct_connect_windows {{hp ""}} { mesg "Disconnected from $hp." + winkill $ipv6_pid + global port_knocking_list if [regexp {FINISH} $port_knocking_list] { do_port_knock $host finish @@ -10363,7 +11041,8 @@ proc save_profile {{parent "."}} { } set h [string trim $vncdisp] set p $h - regsub {:.*$} $h "" h + # XXX host_part + regsub {:[0-9][0-9]*$} $h "" h set host $h regsub {[ ].*$} $p "" p regsub {^.*:} $p "" p @@ -10394,7 +11073,7 @@ proc save_profile {{parent "."}} { set proxyport "" } else { set p $h - regsub {:.*$} $h "" h + regsub {:[0-9][0-9]*$} $h "" h set proxy $h regsub {[ ].*$} $p "" p regsub {^.*:} $p "" p @@ -10499,13 +11178,18 @@ proc rand_port {} { global rand_port_list set p "" - for {set i 0} {$i < 20} {incr i} { + for {set i 0} {$i < 30} {incr i} { set p [expr 25000 + 35000 * rand()] set p [expr round($p)] if {![info exists rand_port_list($p)]} { break } } + if {$p == ""} { + unset rand_port_list + set p [expr 25000 + 35000 * rand()] + set p [expr round($p)] + } set rand_port_list($p) 1 return $p } @@ -10635,7 +11319,7 @@ proc get_smb_redir {} { set lhost "" set lport "" if {$hostport != ""} { - if [regexp {(.*):(.*)} $hostport mvar lhost lport] { + if [regexp {(.*):([0-9][0-9]*)} $hostport mvar lhost lport] { ; } else { set lhost $hostport @@ -10643,7 +11327,7 @@ proc get_smb_redir {} { } } else { if [regexp {//([^/][^/]*)/} $share mvar h] { - if [regexp {(.*):(.*)} $h mvar lhost lport] { + if [regexp {(.*):([0-9][0-9]*)} $h mvar lhost lport] { ; } else { set lhost $h @@ -13704,6 +14388,8 @@ proc help_ssvncviewer_opts {} { VNCVIEWERCMD (unix viewer command, default vncviewer) VNCVIEWERCMD_OVERRIDE (force override of VNCVIEWERCMD) VNCVIEWERCMD_EXTRA_OPTS (extra options to pass to VNCVIEWERCMD) + VNCVIEWER_LISTEN_LOCALHOST (force ssvncviewer to -listen on localhost) + VNCVIEWER_NO_SEC_TYPE_TIGHT(force ssvncviewer to skip rfbSecTypeTight) SSVNC_MULTIPLE_LISTEN (-multilisten, see Multiple LISTEN above) SSVNC_ACCEPT_POPUP (-acceptpopup, see Accept Popup Dialog) @@ -13731,6 +14417,7 @@ proc help_ssvncviewer_opts {} { SSVNC_NO_MAYBE_SYNC SSVNC_MAX_LISTEN (number of time to listen for reverse conn.) SSVNC_LISTEN_ONCE (listen for reverse conn. only once) + STUNNEL_LISTEN (stunnel interface for reverse conn. SSVNC_EXIT_DEBUG SSVNC_DEBUG_CHAT SSVNC_NO_MESSAGE_POPUP @@ -13749,6 +14436,7 @@ proc help_ssvncviewer_opts {} { SSVNC_TEST_SEC_TYPE SSVNC_LIM_ACCEPT_PRELOAD SSVNC_SOCKS5 + SSVNC_IPV6 (0 to disable ss_vncviewer ipv6 check) } .av.f.t insert end $msg @@ -14414,7 +15102,7 @@ proc multilisten_dialog {} { wm title .multil "Multiple LISTEN Connections" global help_font - set h 35 + set h 36 if [small_height] { set h 30 } @@ -14430,8 +15118,9 @@ proc multilisten_dialog {} { This option only applies on Unix or MaOSX when using the supplied SSVNC vncviewer. If you specify your own VNC Viewer it has no effect. - On Windows (only the stock TightVNC viewer is provided) it has no - effect. On MacOSX if the COTVNC viewer is used it has no effect. + On Windows (only the stock TightVNC viewer is provided) it has no effect + because the Windows SSVNC can ONLY do "Multiple LISTEN Connections". + Similarly on MacOSX if the COTVNC viewer is used there is no effect. Rationale: To play it safe, the Unix vncviewer provided by SSVNC (ssvncviewer) only allows one LISTEN reverse connection at a time. @@ -14646,9 +15335,10 @@ proc do_port_knock {hp mode} { set default_delay 150 set host [string trim $hp] + # XXX host_part regsub {^vnc://} $host "" host regsub {^.*@} $host "" host - regsub {:.*$} $host "" host + regsub {:[0-9][0-9]*$} $host "" host set host0 [string trim $host] if {$host0 == ""} { @@ -14749,7 +15439,7 @@ proc do_port_knock {hp mode} { set line [string trim $first] } - if {[regexp {^(.*):(.*)$} $line mv host port]} { + if {[regexp {^(.*):([0-9][0-9]*)$} $line mv host port]} { ; } else { set host $host0 @@ -14850,7 +15540,7 @@ proc do_port_knock {hp mode} { raise . tk_messageBox -type ok -icon error -message $emess -title "Error: socket -async $host $port" } - set socks($i) $s + set sockets($i) $s # seems we have to close it immediately to avoid multiple SYN's. # does not help on Win9x. catch {after 30; close $s}; @@ -14868,7 +15558,7 @@ proc do_port_knock {hp mode} { if {0} { for {set j 0} {$j < $i} {incr j} { - set $s $socks($j) + set $s $sockets($j) if {$s != ""} { catch {close $s} } @@ -17146,7 +17836,7 @@ proc toggle_vnc_prefix {} { if [regexp -nocase {^vnc://} $vncdisplay] { regsub -nocase {^vnc://} $vncdisplay "" vncdisplay } else { - regsub -nocase {^[A-z+]*://} $vncdisplay "" vncdisplay + regsub -nocase {^[a-z0-9+]*://} $vncdisplay "" vncdisplay set vncdisplay "Vnc://$vncdisplay" } catch {.f0.e icursor end} @@ -17174,6 +17864,10 @@ if {! $is_windows} { set ffont "fixed" +global have_ipv6 +set have_ipv6 "" +check_for_ipv6 + # need to check if "fixed" font under XFT on tk8.5 is actually fixed width!! if {$tcl_platform(platform) == "unix"} { set ls "" @@ -17389,6 +18083,15 @@ if [file exists $ssvncrc] { if [regexp {^killstunnel=0} $str] { set kill_stunnel 0 } + global have_ipv6 + if [regexp {^ipv6=1} $str] { + set have_ipv6 1 + set env(SSVNC_IPV6) 1 + } + if [regexp {^ipv6=0} $str] { + set have_ipv6 0 + set env(SSVNC_IPV6) 0 + } if [regexp {^mycert=(.*)$} $str m val] { set val [string trim $val] set mycert_default $val @@ -17892,7 +18595,7 @@ for {set i 0} {$i < $argc} {incr i} { break; } } - if {! $ok && [regexp {:} $item]} { + if {! $ok && [regexp {:[0-9][0-9]*$} $item]} { global vncdisplay set vncdisplay $item set ok 1 |