summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xclasses/ssl/ss_vncviewer370
1 files changed, 317 insertions, 53 deletions
diff --git a/classes/ssl/ss_vncviewer b/classes/ssl/ss_vncviewer
index 75020df..12fe6b2 100755
--- a/classes/ssl/ss_vncviewer
+++ b/classes/ssl/ss_vncviewer
@@ -162,6 +162,9 @@ ssh_args=""
showcert=""
reverse=""
+ciphers=""
+anondh="ALL:RC4+RSA:+SSLv2:@STRENGTH"
+
if [ "X$1" = "X-viewerflavor" ]; then
# special case, try to guess which viewer:
#
@@ -196,6 +199,10 @@ if [ "X$SS_VNCVIEWER_NO_MAXCONN" != "X" ]; then
STUNNEL_EXTRA_OPTS=`echo "$STUNNEL_EXTRA_OPTS" | sed -e 's/maxconn/#maxconn/'`
elif echo "$VNCVIEWERCMD" | egrep -i '^(xmessage|sleep )' > /dev/null; then
STUNNEL_EXTRA_OPTS=`echo "$STUNNEL_EXTRA_OPTS" | sed -e 's/maxconn/#maxconn/'`
+else
+ STUNNEL_ONCE=1; export STUNNEL_ONCE
+ STUNNEL_MAX_CLIENTS=1; export STUNNEL_MAX_CLIENTS
+ STUNNEL_NO_SYSLOG=1; export STUNNEL_NO_SYSLOG
fi
# grab our cmdline options:
@@ -217,6 +224,10 @@ do
;;
"-sshargs") shift; ssh_args="$1"
;;
+ "-anondh") ciphers="ciphers=$anondh"
+ ;;
+ "-ciphers") shift; ciphers="ciphers=$1"
+ ;;
"-alpha") gotalpha=1
;;
"-showcert") showcert=1
@@ -235,6 +246,8 @@ do
;;
"-scale") shift; SSVNC_SCALE="$1"; export SSVNC_SCALE
;;
+ "-escape") shift; VNCVIEWER_ESCAPE="$1"; export VNCVIEWER_ESCAPE
+ ;;
"-ssvnc_encodings") shift; VNCVIEWER_ENCODINGS="$1"; export VNCVIEWER_ENCODINGS
;;
"-rfbversion") shift; VNCVIEWER_RFBVERSION="$1"; export VNCVIEWER_RFBVERSION
@@ -302,6 +315,47 @@ fi
orig="$1"
shift
+dL="-L"
+if uname -sr | egrep 'SunOS 5\.[5-8]' > /dev/null; then
+ dL="-h"
+fi
+
+# a portable, but not absolutely safe, tmp file creator
+mytmp() {
+ tf=$1
+ if type mktemp > /dev/null 2>&1; then
+ # if we have mktemp(1), use it:
+ tf2="$tf.XXXXXX"
+ tf2=`mktemp "$tf2"`
+ if [ "X$tf2" != "X" -a -f "$tf2" ]; then
+ if [ "X$DEBUG_MKTEMP" != "X" ]; then
+ echo "mytmp-mktemp: $tf2" 1>&2
+ fi
+ echo "$tf2"
+ return
+ fi
+ fi
+ # fallback to multiple cmds:
+ rm -rf "$tf" || exit 1
+ if [ -d "$tf" ]; then
+ echo "tmp file $tf still exists as a directory."
+ exit 1
+ elif [ $dL "$tf" ]; then
+ echo "tmp file $tf still exists as a symlink."
+ exit 1
+ elif [ -f "$tf" ]; then
+ echo "tmp file $tf still exists."
+ exit 1
+ fi
+ touch "$tf" || exit 1
+ chmod 600 "$tf" || exit 1
+ rchk
+ if [ "X$DEBUG_MKTEMP" != "X" ]; then
+ echo "mytmp-touch: $tf" 1>&2
+ fi
+ echo "$tf"
+}
+
# set up special case of ultravnc single click III mode:
if echo "$proxy" | egrep "^sslrepeater://" > /dev/null; then
pstr=`echo "$proxy" | sed -e 's,sslrepeater://,,'`
@@ -313,6 +367,13 @@ if echo "$proxy" | egrep "^sslrepeater://" > /dev/null; then
echo "reset: SSVNC_REPEATER=$SSVNC_REPEATER orig=$orig proxy=''"
proxy=""
fi
+if echo "$proxy" | egrep "vencrypt://" > /dev/null; then
+ vtmp="/tmp/ss_handshake${RANDOM}.$$.txt"
+ vtmp=`mytmp "$vtmp"`
+ SSVNC_PREDIGESTED_HANDSHAKE="$vtmp"
+ export SSVNC_PREDIGESTED_HANDSHAKE
+ #echo "SSVNC_PREDIGESTED_HANDSHAKE=$SSVNC_PREDIGESTED_HANDSHAKE"
+fi
# check -ssh and -mycert/-verify conflict:
@@ -559,47 +620,6 @@ rchk() {
}
rchk
-dL="-L"
-if uname -sr | egrep 'SunOS 5\.[5-8]' > /dev/null; then
- dL="-h"
-fi
-
-# a portable, but not absolutely safe, tmp file creator
-mytmp() {
- tf=$1
- if type mktemp > /dev/null 2>&1; then
- # if we have mktemp(1), use it:
- tf2="$tf.XXXXXX"
- tf2=`mktemp "$tf2"`
- if [ "X$tf2" != "X" -a -f "$tf2" ]; then
- if [ "X$DEBUG_MKTEMP" != "X" ]; then
- echo "mytmp-mktemp: $tf2" 1>&2
- fi
- echo "$tf2"
- return
- fi
- fi
- # fallback to multiple cmds:
- rm -rf "$tf" || exit 1
- if [ -d "$tf" ]; then
- echo "tmp file $tf still exists as a directory."
- exit 1
- elif [ $dL "$tf" ]; then
- echo "tmp file $tf still exists as a symlink."
- exit 1
- elif [ -f "$tf" ]; then
- echo "tmp file $tf still exists."
- exit 1
- fi
- touch "$tf" || exit 1
- chmod 600 "$tf" || exit 1
- rchk
- if [ "X$DEBUG_MKTEMP" != "X" ]; then
- echo "mytmp-touch: $tf" 1>&2
- fi
- echo "$tf"
-}
-
# trick for the undocumented rsh://host:port method.
rsh_setup() {
if echo "$ssh_host" | grep '@' > /dev/null; then
@@ -663,6 +683,32 @@ if ($ENV{PPROXY_SOCKS} ne "" && $ENV{PPROXY_PROXY} !~ m,^socks5?://,i) {
}
}
+my $rfbSecTypeTlsVnc = 18;
+my $rfbSecTypeVencrypt = 19;
+
+my $rfbVencryptPlain = 256;
+my $rfbVencryptTlsNone = 257;
+my $rfbVencryptTlsVnc = 258;
+my $rfbVencryptTlsPlain = 259;
+my $rfbVencryptX509None = 260;
+my $rfbVencryptX509Vnc = 261;
+my $rfbVencryptX509Plain = 262;
+
+my $handshake_file = "";
+if (exists $ENV{SSVNC_PREDIGESTED_HANDSHAKE}) {
+ $handshake_file = $ENV{SSVNC_PREDIGESTED_HANDSHAKE};
+}
+
+sub append_handshake {
+ my $str = shift;
+ if ($handshake_file) {
+ if (open(HSF, ">>$handshake_file")) {
+ print HSF $str;
+ close HSF;
+ }
+ }
+}
+
my ($first, $second, $third) = split(/,/, $ENV{PPROXY_PROXY}, 3);
my ($mode_1st, $mode_2nd, $mode_3rd) = ("", "", "");
@@ -823,6 +869,18 @@ sub url_parse {
if ($hostport !~ /:\d+/) {
$hostport .= ":5900";
}
+ } elsif ($hostport =~ m,^vencrypt://(\S*)$,i) {
+ # vencrypt handshake.
+ $hostport = $1;
+ my $m = "connect";
+ if ($hostpost =~ /^(\S+)\+(\S+)$/) {
+ $hostport = $1;
+ $mode = $2;
+ }
+ $mode = "vencrypt:$m";
+ if ($hostport !~ /:\d+/) {
+ $hostport .= ":5900";
+ }
}
return ($hostport, $mode);
}
@@ -830,6 +888,7 @@ sub url_parse {
sub setmode {
my $mode = shift;
$ENV{PPROXY_REPEATER} = "";
+ $ENV{PPROXY_VENCRYPT} = "";
if ($mode =~ /^socks/) {
if ($mode =~ /^socks5/) {
$ENV{PPROXY_SOCKS} = 5;
@@ -839,6 +898,9 @@ sub setmode {
} elsif ($mode =~ /^repeater:(.*)/) {
$ENV{PPROXY_REPEATER} = $1;
$ENV{PPROXY_SOCKS} = "";
+ } elsif ($mode =~ /^vencrypt:(.*)/) {
+ $ENV{PPROXY_VENCRYPT} = $1;
+ $ENV{PPROXY_SOCKS} = "";
} else {
$ENV{PPROXY_SOCKS} = "";
}
@@ -980,6 +1042,9 @@ sub connection {
sysread($sock, $c, 1);
print STDERR $c;
}
+ } elsif ($ENV{PPROXY_VENCRYPT} ne "") {
+ my $vencrypt = $ENV{PPROXY_VENCRYPT};
+ vencrypt_dialog($vencrypt);
} else {
# Web Proxy:
@@ -1008,6 +1073,189 @@ sub connection {
}
}
+sub vdie {
+ append_handshake("done\n");
+ close $sock;
+ exit(1);
+}
+
+sub tlsvnc_handshake {
+ my ($vmode, $db) = @_;
+
+ print STDERR "PPROXY: Doing TLSVNC Handshake\n";
+
+ my $psec = pack("C", $rfbSecTypeTlsVnc);
+ syswrite($sock, $psec, 1);
+
+ append_handshake("done\n");
+}
+
+sub vencrypt_handshake {
+
+ my ($vmode, $db) = @_;
+
+ print STDERR "PPROXY: Doing VeNCrypt Handshake\n";
+
+ my $psec = pack("C", $rfbSecTypeVencrypt);
+ syswrite($sock, $psec, 1);
+
+ my $vmajor;
+ my $vminor;
+ sysread($sock, $vmajor, 1);
+ sysread($sock, $vminor, 1);
+
+ vdie if $vmajor eq "" || $vminor eq "";
+
+ $vmajor = unpack("C", $vmajor);
+ $vminor = unpack("C", $vminor);
+ print STDERR "$vmajor.$vminor\n" if $db;
+
+ vdie if $vmajor ne 0;
+ vdie if $vminor < 2;
+
+ $vmajor = pack("C", 0);
+ $vminor = pack("C", 2);
+ append_handshake("subversion=0.2\n");
+
+ syswrite($sock, $vmajor, 1);
+ syswrite($sock, $vminor, 1);
+
+ my $result;
+ sysread($sock, $result, 1);
+
+ vdie if $result eq "";
+ $result = unpack("C", $result);
+ print STDERR "result=$result\n" if $db;
+
+ vdie if $result ne 0;
+
+ my $nsubtypes;
+ sysread($sock, $nsubtypes, 1);
+
+ vdie if $nsubtypes eq "";
+ $nsubtypes = unpack("C", $nsubtypes);
+ print STDERR "nsubtypes=$nsubtypes\n" if $db;
+
+ my %subtypes;
+
+ for (my $i = 0; $i < $nsubtypes; $i++) {
+ my $subtype = "";
+ sysread($sock, $subtype, 4);
+ vdie if length($subtype) != 4;
+
+ # XXX fix 64bit.
+ $subtype = unpack("N", $subtype);
+ print STDERR "subtype: $subtype\n" if $db;
+ $subtypes{$subtype} = 1;
+ append_handshake("sst$i=$subtype\n");
+ }
+
+ my $subtype = 0;
+ if (exists $subtypes{$rfbVencryptX509None}) {
+ $subtype = $rfbVencryptX509None;
+ print STDERR "selected rfbVencryptX509None\n" if $db;
+ } elsif (exists $subtypes{$rfbVencryptX509Vnc}) {
+ $subtype = $rfbVencryptX509Vnc;
+ print STDERR "selected rfbVencryptX509Vnc\n" if $db;
+ } elsif (exists $subtypes{$rfbVencryptX509Plain}) {
+ $subtype = $rfbVencryptX509Plain;
+ print STDERR "selected rfbVencryptX509Plain\n" if $db;
+ } elsif (exists $subtypes{$rfbVencryptTlsNone}) {
+ $subtype = $rfbVencryptTlsNone;
+ print STDERR "selected rfbVencryptTlsNone\n" if $db;
+ } elsif (exists $subtypes{$rfbVencryptTlsVnc}) {
+ $subtype = $rfbVencryptTlsVnc;
+ print STDERR "selected rfbVencryptTlsVnc\n" if $db;
+ } elsif (exists $subtypes{$rfbVencryptTlsPlain}) {
+ $subtype = $rfbVencryptTlsPlain;
+ print STDERR "selected rfbVencryptTlsPlain\n" if $db;
+ }
+ append_handshake("subtype=$subtype\n");
+
+ my $pst = pack("N", $subtype);
+ syswrite($sock, $pst, 4);
+
+ vdie if $subtype == 0;
+
+ my $ok;
+ sysread($sock, $ok, 1);
+ $ok = unpack("C", $ok);
+ print STDERR "ok=$ok\n" if $db;
+
+ append_handshake("done\n");
+
+ vdie if $ok == 0;
+}
+
+sub vencrypt_dialog {
+ my $vmode = shift;
+ my $db = 0;
+
+ $db = 1 if exists $ENV{SS_DEBUG};
+
+ append_handshake("mode=$vmode\n");
+
+ my $server_rfb = "";
+ syswrite($sock, $rep, 250);
+ for (my $i = 0; $i < 12; $i++) {
+ my $c;
+ sysread($sock, $c, 1);
+ $server_rfb .= $c;
+ print STDERR $c;
+ }
+ print STDERR "server_rfb: $server_rfb\n" if $db;
+ append_handshake("server=$server_rfb");
+
+ my $minor = "";
+ if ($server_rfb =~ /^RFB 003\.(\d+)/) {
+ $minor = $1;
+ } else {
+ vdie;
+ }
+ my $viewer_rfb = "RFB 003.008\n";
+ if ($minor < 7) {
+ vdie;
+ } elsif ($minor == 7) {
+ $viewer_rfb = "RFB 003.007\n";
+ }
+ syswrite($sock, $viewer_rfb, 12);
+ append_handshake("viewer=$viewer_rfb");
+
+ my $nsec;
+
+ sysread($sock, $nsec, 1);
+ vdie if $nsec eq "";
+
+ $nsec = unpack("C", $nsec);
+
+ print STDERR "nsec: $nsec\n" if $db;
+ vdie if $nsec eq 0 || $nsec > 100;
+
+ my %sectypes = ();
+
+ for (my $i = 0; $i < $nsec; $i++) {
+ my $sec;
+ sysread($sock, $sec, 1);
+ vdie if $sec eq "";
+ $sec = unpack("C", $sec);
+ print STDERR "sec: $sec\n" if $db;
+ $sectypes{$sec} = 1;
+ }
+
+ if (exists $sectypes{$rfbSecTypeVencrypt}) {
+ print STDERR "found rfbSecTypeVencrypt\n" if $db;
+ append_handshake("sectype=$rfbSecTypeVencrypt\n");
+ vencrypt_handshake($vmode, $db);
+ } elsif (exists $sectypes{$rfbSecTypeTlsVnc}) {
+ print STDERR "found rfbSecTypeTlsVnc\n" if $db;
+ append_handshake("sectype=$rfbSecTypeTlsVnc\n");
+ tlsvnc_handshake($vmode, $db);
+ } else {
+ print STDERR "No supported sec-type found\n" if $db;
+ vdie;
+ }
+}
+
sub xfer {
my($in, $out) = @_;
$RIN = $WIN = $EIN = "";
@@ -1102,8 +1350,8 @@ if [ "X$use_ssh" = "X1" ]; then
if echo "$proxy" | egrep '(http|https|socks|socks4|socks5)://' > /dev/null; then
# Handle Web or SOCKS proxy(ies) for the initial connect.
-Kecho host=$host
-Kecho port=$port
+ Kecho host=$host
+ Kecho port=$port
pproxy=""
sproxy1=""
sproxy_rest=""
@@ -1124,9 +1372,10 @@ Kecho port=$port
done
pproxy=`echo "$pproxy" | sed -e 's/^,,*//' -e 's/,,*/,/g'`
sproxy_rest=`echo "$sproxy_rest" | sed -e 's/^,,*//' -e 's/,,*/,/g'`
-Kecho pproxy=$pproxy
-Kecho sproxy1=$sproxy1
-Kecho sproxy_rest=$sproxy_rest
+
+ Kecho pproxy=$pproxy
+ Kecho sproxy1=$sproxy1
+ Kecho sproxy_rest=$sproxy_rest
sproxy1_host=""
sproxy1_port=""
@@ -1162,9 +1411,9 @@ Kecho sproxy_rest=$sproxy_rest
fi
fi
-Kecho sproxy1_host=$sproxy1_host
-Kecho sproxy1_port=$sproxy1_port
-Kecho sproxy1_user=$sproxy1_user
+ Kecho sproxy1_host=$sproxy1_host
+ Kecho sproxy1_port=$sproxy1_port
+ Kecho sproxy1_user=$sproxy1_user
ptmp="/tmp/ss_vncviewer_ssh${RANDOM}.$$.pl"
ptmp=`mytmp "$ptmp"`
@@ -1202,7 +1451,7 @@ Kecho sproxy1_user=$sproxy1_user
if [ "X$sproxy_rest" != "X" ]; then
proxy="$proxy,$sproxy_rest"
fi
-Kecho proxy=$proxy
+ Kecho proxy=$proxy
fi
if echo "$proxy" | grep "," > /dev/null; then
@@ -1548,13 +1797,26 @@ if [ "X$showcert" = "X1" ]; then
if [ "X$proxy" != "X" ]; then
PPROXY_LISTEN=$use
export PPROXY_LISTEN
- $ptmp 2>/dev/null &
+ if [ "X$SS_DEBUG" != "X" ]; then
+ $ptmp &
+ else
+ $ptmp 2>/dev/null &
+ fi
sleep 1
host="localhost"
port="$use"
fi
- openssl s_client -connect $host:$port 2>&1 < /dev/null
- exit $?
+ cipher_args=""
+ if [ "X$ciphers" != "X" ]; then
+ cipher_args=`echo "$ciphers" | sed -e 's/ciphers=/-cipher /'`
+ fi
+ #echo "openssl s_client $cipher_args -connect $host:$port"
+ openssl s_client $cipher_args -prexit -connect $host:$port 2>&1 < /dev/null
+ rc=$?
+ if [ "X$SSVNC_PREDIGESTED_HANDSHAKE" != "X" ]; then
+ rm -f $SSVNC_PREDIGESTED_HANDSHAKE
+ fi
+ exit $rc
fi
if [ "X$direct_connect" != "X" ]; then
@@ -1781,6 +2043,7 @@ foreground = yes
pid =
client = yes
debug = 6
+$ciphers
$STUNNEL_EXTRA_OPTS
$STUNNEL_EXTRA_OPTS_USER
$verify
@@ -1816,6 +2079,7 @@ foreground = yes
pid =
client = no
debug = 6
+$ciphers
$STUNNEL_EXTRA_OPTS
$STUNNEL_EXTRA_OPTS_USER
$verify