1#!/bin/sh 2# 3# ss_vncviewer: wrapper for vncviewer to use an stunnel SSL tunnel 4# or an SSH tunnel. 5# 6# Copyright (c) 2006-2009 by Karl J. Runge <runge@karlrunge.com> 7# 8# ss_vncviewer is free software; you can redistribute it and/or modify 9# it under the terms of the GNU General Public License as published by 10# the Free Software Foundation; either version 2 of the License, or (at 11# your option) any later version. 12# 13# ss_vncviewer is distributed in the hope that it will be useful, 14# but WITHOUT ANY WARRANTY; without even the implied warranty of 15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16# GNU General Public License for more details. 17# 18# You should have received a copy of the GNU General Public License 19# along with ss_vncviewer; if not, write to the Free Software 20# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA 21# or see <http://www.gnu.org/licenses/>. 22# 23# 24# You must have stunnel(8) installed on the system and in your PATH 25# (however, see the -ssh option below, in which case you will need ssh(1) 26# installed) Note: stunnel is usually installed in an "sbin" subdirectory. 27# 28# You should have "x11vnc -ssl ..." or "x11vnc -stunnel ..." 29# already running as the VNC server on the remote machine. 30# (or use stunnel on the server side for any other VNC server) 31# 32# 33# Usage: ss_vncviewer [cert-args] host:display <vncviewer-args> 34# 35# e.g.: ss_vncviewer snoopy:0 36# ss_vncviewer snoopy:0 -encodings "copyrect tight zrle hextile" 37# 38# [cert-args] can be: 39# 40# -verify /path/to/cacert.pem 41# -mycert /path/to/mycert.pem 42# -crl /path/to/my_crl.pem (or directory) 43# -proxy host:port 44# 45# -verify specifies a CA cert PEM file (or a self-signed one) for 46# authenticating the VNC server. 47# 48# -mycert specifies this client's cert+key PEM file for the VNC server to 49# authenticate this client. 50# 51# -proxy try host:port as a Web proxy to use the CONNECT method 52# to reach the VNC server (e.g. your firewall requires a proxy). 53# 54# For the "double proxy" case use -proxy host1:port1,host2:port2 55# (the first CONNECT is done through host1:port1 to host2:port2 56# and then a 2nd CONNECT to the destination VNC server.) 57# 58# Use socks://host:port, socks4://host:port, or socks5://host,port 59# to force usage of a SOCKS proxy. Also repeater://host:port and 60# sslrepeater://host:port. 61# 62# -showcert Only fetch the certificate using the 'openssl s_client' 63# command (openssl(1) must in installed). On ssvnc 1.0.27 and 64# later the bundled command 'ultravnc_dsm_helper' is used. 65# 66# See http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-ca for details on 67# SSL certificates with VNC. 68# 69# A few other args (not related to SSL and certs): 70# 71# -2nd Run the vncviewer a 2nd time if the first connections fails. 72# 73# -ssh Use ssh instead of stunnel SSL. ssh(1) must be installed and you 74# must be able to log into the remote machine via ssh. 75# 76# In this case "host:display" may be of the form "user@host:display" 77# where "user@host" is used for the ssh login (see ssh(1) manpage). 78# 79# If -proxy is supplied it can be of the forms: "gwhost" "gwhost:port" 80# "user@gwhost" or "user@gwhost:port". "gwhost" is an incoming ssh 81# gateway machine (the VNC server is not running there), an ssh -L 82# redir is used to "host" in "host:display" from "gwhost". Any "user@" 83# part must be in the -proxy string (not in "host:display"). 84# 85# Under -proxy use "gwhost:port" if connecting to any ssh port 86# other than the default (22). (even for the non-gateway case, 87# -proxy must be used to specify a non-standard ssh port) 88# 89# A "double ssh" can be specified via a -proxy string with the two 90# hosts separated by a comma: 91# 92# [user1@]host1[:port1],[user2@]host2[:port2] 93# 94# in which case a ssh to host1 and thru it via a -L redir a 2nd 95# ssh is established to host2. 96# 97# Examples: 98# 99# ss_vncviewer -ssh bob@bobs-home.net:0 100# ss_vncviewer -ssh -sshcmd 'x11vnc -localhost' bob@bobs-home.net:0 101# 102# ss_vncviewer -ssh -proxy fred@mygate.com:2022 mymachine:0 103# ss_vncviewer -ssh -proxy bob@bobs-home.net:2222 localhost:0 104# 105# ss_vncviewer -ssh -proxy fred@gw-host,fred@peecee localhost:0 106# 107# -sshcmd cmd Run "cmd" via ssh instead of the default "sleep 15" 108# e.g. -sshcmd 'x11vnc -display :0 -localhost -rfbport 5900' 109# 110# -sshargs "args" pass "args" to the ssh process, e.g. -L/-R port redirs. 111# 112# -sshssl Tunnel the SSL connection thru a SSH connection. The tunnel as 113# under -ssh is set up and the SSL connection goes thru it. Use 114# this if you want to have and end-to-end SSL connection but must 115# go thru a SSH gateway host (e.g. not the vnc server). Or use 116# this if you need to tunnel additional services via -R and -L 117# (see -sshargs above). 118# 119# ss_vncviewer -sshssl -proxy fred@mygate.com mymachine:0 120# 121# -listen (or -reverse) set up a reverse connection. 122# 123# -alpha turn on cursor alphablending hack if you are using the 124# enhanced tightvnc vncviewer. 125# 126# -grab turn on XGrabServer hack if you are using the enhanced tightvnc 127# vncviewer (e.g. for fullscreen mode in some windowmanagers like 128# fvwm that do not otherwise work in fullscreen mode) 129# 130# 131# set VNCVIEWERCMD to whatever vncviewer command you want to use. 132# 133VNCIPCMD=${VNCVIEWERCMD:-vncip} 134VNCVIEWERCMD=${VNCVIEWERCMD:-vncviewer} 135if [ "X$SSVNC_TURBOVNC" != "X" ]; then 136 if echo "$VNCVIEWERCMD" | grep '\.turbovnc' > /dev/null; then 137 : 138 else 139 if type "$VNCVIEWERCMD.turbovnc" > /dev/null 2>/dev/null; then 140 VNCVIEWERCMD="$VNCVIEWERCMD.turbovnc" 141 fi 142 fi 143fi 144# 145# Same for STUNNEL, e.g. set it to /path/to/stunnel or stunnel4, etc. 146# 147 148# turn on verbose debugging output 149if [ "X$SS_DEBUG" != "X" -a "X$SS_DEBUG" != "X0" ]; then 150 set -xv 151fi 152 153PATH=$PATH:/usr/sbin:/usr/local/sbin:/dist/sbin; export PATH 154 155localhost="localhost" 156if uname | grep Darwin >/dev/null; then 157 localhost="127.0.0.1" 158fi 159 160# work out which stunnel to use (debian installs as stunnel4) 161stunnel_set_here="" 162if [ "X$STUNNEL" = "X" ]; then 163 check_stunnel=1 164 if [ "X$SSVNC_BASEDIRNAME" != "X" ]; then 165 if [ -x "$SSVNC_BASEDIRNAME/stunnel" ]; then 166 type stunnel > /dev/null 2>&1 167 if [ $? = 0 ]; then 168 # found ours 169 STUNNEL=stunnel 170 check_stunnel=0 171 fi 172 fi 173 fi 174 if [ "X$check_stunnel" = "X1" ]; then 175 type stunnel4 > /dev/null 2>&1 176 if [ $? = 0 ]; then 177 STUNNEL=stunnel4 178 else 179 STUNNEL=stunnel 180 fi 181 fi 182 stunnel_set_here=1 183fi 184 185help() { 186 tail -n +2 "$0" | sed -e '/^$/ q' 187} 188 189secondtry="" 190gotalpha="" 191use_ssh="" 192use_sshssl="" 193direct_connect="" 194ssh_sleep=15 195 196# sleep longer in -listen mode: 197if echo "$*" | grep '.*-listen' > /dev/null; then 198 ssh_sleep=1800 199fi 200 201 202ssh_cmd="" 203# env override of ssh_cmd: 204if [ "X$SS_VNCVIEWER_SSH_CMD" != "X" ]; then 205 ssh_cmd="$SS_VNCVIEWER_SSH_CMD" 206fi 207 208ssh_args="" 209showcert="" 210reverse="" 211 212ciphers="" 213anondh="ALL:RC4+RSA:+SSLv2:@STRENGTH" 214anondh_set="" 215stunnel_debug="6" 216if [ "X$SS_DEBUG" != "X" -o "X$SSVNC_VENCRYPT_DEBUG" != "X" -o "X$SSVNC_STUNNEL_DEBUG" != "X" ]; then 217 stunnel_debug="7" 218fi 219 220if [ "X$1" = "X-viewerflavor" ]; then 221 # special case, try to guess which viewer: 222 # 223 if echo "$VNCVIEWERCMD" | egrep -i '^(xmessage|sleep )' > /dev/null; then 224 echo "unknown" 225 exit 0 226 fi 227 if echo "$VNCVIEWERCMD" | grep -i chicken.of > /dev/null; then 228 echo "cotvnc" 229 exit 0 230 fi 231 if echo "$VNCVIEWERCMD" | grep -i ultra > /dev/null; then 232 echo "ultravnc" 233 exit 0 234 fi 235 # OK, run it for help output... 236 str=`$VNCVIEWERCMD -h 2>&1 | head -n 5` 237 if echo "$str" | grep -i 'TightVNC.viewer' > /dev/null; then 238 echo "tightvnc" 239 elif echo "$str" | grep -i 'VNC viewer version 3' > /dev/null; then 240 echo "realvnc3" 241 elif echo "$str" | grep -i 'VNC viewer .*Edition 4' > /dev/null; then 242 echo "realvnc4" 243 elif echo "$str" | grep -i 'RealVNC.Ltd' > /dev/null; then 244 echo "realvnc4" 245 else 246 echo "unknown" 247 fi 248 exit 0 249fi 250if [ "X$1" = "X-viewerhelp" ]; then 251 $VNCVIEWERCMD -h 2>&1 252 exit 0 253fi 254 255# grab our cmdline options: 256while [ "X$1" != "X" ] 257do 258 case $1 in 259 "-verify") shift; verify="$1" 260 ;; 261 "-mycert") shift; mycert="$1" 262 ;; 263 "-crl") shift; crl="$1" 264 ;; 265 "-proxy") shift; proxy="$1" 266 ;; 267 "-ssh") use_ssh=1 268 ;; 269 "-sshssl") use_ssh=1 270 use_sshssl=1 271 ;; 272 "-sshcmd") shift; ssh_cmd="$1" 273 ;; 274 "-sshargs") shift; ssh_args="$1" 275 ;; 276 "-anondh") ciphers="ciphers=$anondh" 277 ULTRAVNC_DSM_HELPER_SHOWCERT_ADH=1 278 export ULTRAVNC_DSM_HELPER_SHOWCERT_ADH 279 anondh_set=1 280 ;; 281 "-ciphers") shift; ciphers="ciphers=$1" 282 ;; 283 "-alpha") gotalpha=1 284 ;; 285 "-showcert") showcert=1 286 ;; 287 "-listen") reverse=1 288 ;; 289 "-reverse") reverse=1 290 ;; 291 "-2nd") secondtry=1 292 ;; 293 "-grab") VNCVIEWER_GRAB_SERVER=1; export VNCVIEWER_GRAB_SERVER 294 ;; 295 "-x11cursor") VNCVIEWER_X11CURSOR=1; export VNCVIEWER_X11CURSOR 296 ;; 297 "-rawlocal") VNCVIEWER_RAWLOCAL=1; export VNCVIEWER_RAWLOCAL 298 ;; 299 "-scale") shift; SSVNC_SCALE="$1"; export SSVNC_SCALE 300 ;; 301 "-onelisten") SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE 302 ;; 303 "-sendclipboard") VNCVIEWER_SEND_CLIPBOARD=1; export VNCVIEWER_SEND_CLIPBOARD 304 ;; 305 "-sendalways") VNCVIEWER_SEND_ALWAYS=1; export VNCVIEWER_SEND_ALWAYS 306 ;; 307 "-recvtext") shift; VNCVIEWER_RECV_TEXT="$1"; export VNCVIEWER_RECV_TEXT 308 ;; 309 "-escape") shift; VNCVIEWER_ESCAPE="$1"; export VNCVIEWER_ESCAPE 310 ;; 311 "-ssvnc_encodings") shift; VNCVIEWER_ENCODINGS="$1"; export VNCVIEWER_ENCODINGS 312 ;; 313 "-ssvnc_extra_opts") shift; VNCVIEWERCMD_EXTRA_OPTS="$1"; export VNCVIEWERCMD_EXTRA_OPTS 314 ;; 315 "-rfbversion") shift; VNCVIEWER_RFBVERSION="$1"; export VNCVIEWER_RFBVERSION 316 ;; 317 "-nobell") VNCVIEWER_NOBELL=1; export VNCVIEWER_NOBELL 318 ;; 319 "-popupfix") VNCVIEWER_POPUP_FIX=1; export VNCVIEWER_POPUP_FIX 320 ;; 321 "-realvnc4") VNCVIEWER_IS_REALVNC4=1; export VNCVIEWER_IS_REALVNC4 322 ;; 323 "-h"*) help; exit 0 324 ;; 325 "--h"*) help; exit 0 326 ;; 327 *) break 328 ;; 329 esac 330 shift 331done 332 333# maxconn is something we added to stunnel, this disables it: 334if [ "X$SS_VNCVIEWER_NO_MAXCONN" != "X" ]; then 335 STUNNEL_EXTRA_OPTS=`echo "$STUNNEL_EXTRA_OPTS" | sed -e 's/maxconn/#maxconn/'` 336elif echo "$VNCVIEWERCMD" | egrep -i '^(xmessage|sleep )' > /dev/null; then 337 STUNNEL_EXTRA_OPTS=`echo "$STUNNEL_EXTRA_OPTS" | sed -e 's/maxconn/#maxconn/'` 338elif [ "X$reverse" != "X" ]; then 339 STUNNEL_EXTRA_OPTS=`echo "$STUNNEL_EXTRA_OPTS" | sed -e 's/maxconn/#maxconn/'` 340else 341 # new way (our patches). other than the above, we set these: 342 if [ "X$SKIP_STUNNEL_ONCE" = "X" ]; then 343 STUNNEL_ONCE=1; export STUNNEL_ONCE 344 fi 345 if [ "X$SKIP_STUNNEL_MAX_CLIENTS" = "X" ]; then 346 STUNNEL_MAX_CLIENTS=1; export STUNNEL_MAX_CLIENTS 347 fi 348fi 349# always set this one: 350if [ "X$SKIP_STUNNEL_NO_SYSLOG" = "X" ]; then 351 STUNNEL_NO_SYSLOG=1; export STUNNEL_NO_SYSLOG 352fi 353 354# this is the -t ssh option (gives better keyboard response thru SSH tunnel) 355targ="-t" 356if [ "X$SS_VNCVIEWER_NO_T" != "X" ]; then 357 targ="" 358fi 359 360# set the alpha blending env. hack: 361if [ "X$gotalpha" = "X1" ]; then 362 VNCVIEWER_ALPHABLEND=1 363 export VNCVIEWER_ALPHABLEND 364else 365 NO_ALPHABLEND=1 366 export NO_ALPHABLEND 367fi 368 369if [ "X$reverse" != "X" ]; then 370 ssh_sleep=1800 371 if [ "X$proxy" != "X" ]; then 372 # check proxy usage under reverse connection: 373 if [ "X$use_ssh" = "X" -a "X$use_sshssl" = "X" ]; then 374 echo "" 375 if echo "$proxy" | egrep -i "(repeater|vencrypt)://" > /dev/null; then 376 : 377 else 378 echo "*Warning*: SSL -listen and a Web proxy does not make sense." 379 sleep 2 380 fi 381 elif echo "$proxy" | grep "," > /dev/null; then 382 : 383 else 384 echo "" 385 echo "*Warning*: -listen and a single proxy/gateway does not make sense." 386 sleep 2 387 fi 388 389 # we now try to PPROXY_LOOP_THYSELF, set this var to disable that. 390 #SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE 391 fi 392fi 393if [ "X$ssh_cmd" = "X" ]; then 394 # if no remote ssh cmd, sleep a bit: 395 ssh_cmd="sleep $ssh_sleep" 396fi 397 398# this should be a host:display: 399# 400orig="$1" 401shift 402 403dL="-L" 404if uname -sr | egrep 'SunOS 5\.[5-8]' > /dev/null; then 405 dL="-h" 406fi 407 408have_uvnc_dsm_helper_showcert="" 409if [ "X$showcert" = "X1" -a "X$SSVNC_USE_S_CLIENT" = "X" -a "X$reverse" = "X" ]; then 410 if type ultravnc_dsm_helper >/dev/null 2>&1; then 411 if ultravnc_dsm_helper -help 2>&1 | grep -w showcert >/dev/null; then 412 have_uvnc_dsm_helper_showcert=1 413 fi 414 fi 415fi 416have_uvnc_dsm_helper_ipv6="" 417if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then 418 if type ultravnc_dsm_helper >/dev/null 2>&1; then 419 if ultravnc_dsm_helper -help 2>&1 | grep -iw ipv6 >/dev/null; then 420 have_uvnc_dsm_helper_ipv6=1 421 fi 422 fi 423fi 424 425rchk() { 426 # a kludge to set $RANDOM if we are not bash: 427 if [ "X$BASH_VERSION" = "X" ]; then 428 RANDOM=`date +%S``sh -c 'echo $$'``ps -elf 2>&1 | sum 2>&1 | awk '{print $1}'` 429 fi 430} 431rchk 432 433# a portable, but not absolutely safe, tmp file creator 434mytmp() { 435 tf=$1 436 if type mktemp > /dev/null 2>&1; then 437 # if we have mktemp(1), use it: 438 tf2="$tf.XXXXXX" 439 tf2=`mktemp "$tf2"` 440 if [ "X$tf2" != "X" -a -f "$tf2" ]; then 441 if [ "X$DEBUG_MKTEMP" != "X" ]; then 442 echo "mytmp-mktemp: $tf2" 1>&2 443 fi 444 echo "$tf2" 445 return 446 fi 447 fi 448 # fallback to multiple cmds: 449 rm -rf "$tf" || exit 1 450 if [ -d "$tf" ]; then 451 echo "tmp file $tf still exists as a directory." 452 exit 1 453 elif [ $dL "$tf" ]; then 454 echo "tmp file $tf still exists as a symlink." 455 exit 1 456 elif [ -f "$tf" ]; then 457 echo "tmp file $tf still exists." 458 exit 1 459 fi 460 touch "$tf" || exit 1 461 chmod 600 "$tf" || exit 1 462 rchk 463 if [ "X$DEBUG_MKTEMP" != "X" ]; then 464 echo "mytmp-touch: $tf" 1>&2 465 fi 466 echo "$tf" 467} 468 469# set up special case of ultravnc single click III mode: 470if echo "$proxy" | egrep "^sslrepeater://" > /dev/null; then 471 pstr=`echo "$proxy" | sed -e 's,sslrepeater://,,'` 472 pstr1=`echo "$pstr" | sed -e 's/+.*$//'` 473 pstr2=`echo "$pstr" | sed -e 's/^[^+]*+//'` 474 SSVNC_REPEATER="SCIII=$pstr2"; export SSVNC_REPEATER 475 orig=$pstr1 476 echo 477 echo "reset: SSVNC_REPEATER=$SSVNC_REPEATER orig=$orig proxy=''" 478 proxy="" 479fi 480if echo "$proxy" | egrep "vencrypt://" > /dev/null; then 481 vtmp="/tmp/ss_handshake${RANDOM}.$$.txt" 482 vtmp=`mytmp "$vtmp"` 483 SSVNC_PREDIGESTED_HANDSHAKE="$vtmp" 484 export SSVNC_PREDIGESTED_HANDSHAKE 485 if [ "X$SSVNC_USE_OURS" = "X" ]; then 486 NEED_VENCRYPT_VIEWER_BRIDGE=1 487 fi 488fi 489if [ "X$SSVNC_USE_OURS" = "X" ]; then 490 VNCVIEWERCMD_EXTRA_OPTS="" 491fi 492 493 494# check -ssh and -mycert/-verify conflict: 495if [ "X$use_ssh" = "X1" -a "X$use_sshssl" = "X" ]; then 496 if [ "X$mycert" != "X" -o "X$verify" != "X" ]; then 497 echo "-mycert and -verify cannot be used in -ssh mode" 498 exit 1 499 fi 500fi 501 502# direct mode Vnc:// means show no warnings. 503# direct mode vnc:// will show warnings. 504if echo "$orig" | grep '^V[Nn][Cc]://' > /dev/null; then 505 SSVNC_NO_ENC_WARN=1 506 export SSVNC_NO_ENC_WARN 507 orig=`echo "$orig" | sed -e 's/^...:/vnc:/'` 508fi 509 510# interprest the pseudo URL proto:// strings: 511if echo "$orig" | grep '^vnc://' > /dev/null; then 512 orig=`echo "$orig" | sed -e 's,vnc://,,'` 513 verify="" 514 mycert="" 515 crl="" 516 use_ssh="" 517 use_sshssl="" 518 direct_connect=1 519elif echo "$orig" | grep '^vncs://' > /dev/null; then 520 orig=`echo "$orig" | sed -e 's,vncs://,,'` 521elif echo "$orig" | grep '^vncssl://' > /dev/null; then 522 orig=`echo "$orig" | sed -e 's,vncssl://,,'` 523elif echo "$orig" | grep '^vnc+ssl://' > /dev/null; then 524 orig=`echo "$orig" | sed -e 's,vnc.ssl://,,'` 525elif echo "$orig" | grep '^vncssh://' > /dev/null; then 526 orig=`echo "$orig" | sed -e 's,vncssh://,,'` 527 use_ssh=1 528elif echo "$orig" | grep '^vnc+ssh://' > /dev/null; then 529 orig=`echo "$orig" | sed -e 's,vnc.ssh://,,'` 530 use_ssh=1 531fi 532 533if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then 534 verify="" 535 mycert="" 536 crl="" 537 use_ssh="" 538 use_sshssl="" 539 direct_connect=1 540 if echo "$SSVNC_ULTRA_DSM" | grep 'noultra:' > /dev/null; then 541 SSVNC_NO_ULTRA_DSM=1; export SSVNC_NO_ULTRA_DSM 542 fi 543fi 544 545# rsh mode is an internal/secret thing only I use. 546rsh="" 547if echo "$orig" | grep '^rsh://' > /dev/null; then 548 use_ssh=1 549 rsh=1 550 orig=`echo "$orig" | sed -e 's,rsh://,,'` 551elif echo "$orig" | grep '^rsh:' > /dev/null; then 552 use_ssh=1 553 rsh=1 554 orig=`echo "$orig" | sed -e 's,rsh:,,'` 555fi 556 557# play around with host:display port: 558if echo "$orig" | grep ':[0-9][0-9]*$' > /dev/null; then 559 : 560else 561 # add or assume :0 if no ':' 562 if [ "X$reverse" = "X" ]; then 563 orig="$orig:0" 564 elif [ "X$orig" = "X" ]; then 565 orig=":0" 566 fi 567fi 568 569# extract host and disp number: 570 571# try to see if it is ipv6 address: 572ipv6=0 573if echo "$orig" | grep '\[' > /dev/null; then 574 # ipv6 [fe80::219:dbff:fee5:3f92%eth1]:5900 575 host=`echo "$orig" | sed -e 's/\].*$//' -e 's/\[//'` 576 disp=`echo "$orig" | sed -e 's/^.*\]://'` 577 ipv6=1 578elif echo "$orig" | grep ':..*:' > /dev/null; then 579 # ipv6 fe80::219:dbff:fee5:3f92%eth1:5900 580 host=`echo "$orig" | sed -e 's/:[^:]*$//'` 581 disp=`echo "$orig" | sed -e 's/^.*://'` 582 ipv6=1 583else 584 # regular host:port 585 host=`echo "$orig" | awk -F: '{print $1}'` 586 disp=`echo "$orig" | awk -F: '{print $2}'` 587fi 588 589if [ "X$reverse" != "X" -a "X$STUNNEL_LISTEN" = "X" -a "X$host" != "X" ]; then 590 STUNNEL_LISTEN=$host 591 echo "set STUNNEL_LISTEN=$STUNNEL_LISTEN" 592fi 593 594if [ "X$host" = "X" ]; then 595 host=$localhost 596fi 597 598if [ "X$SSVNC_IPV6" = "X0" ]; then 599 # disable checking for it. 600 ipv6=0 601#elif [ "X$reverse" != "X" -a "X$ipv6" = "X1" ]; then 602# ipv6=0 603elif [ "X$ipv6" = "X1" ]; then 604 : 605elif echo "$host" | grep '^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' > /dev/null; then 606 : 607else 608 # regular hostname, can't be sure... 609 gout="" 610 if type getent > /dev/null 2>/dev/null; then 611 gout=`getent hosts "$host" 2>/dev/null` 612 fi 613 if echo "$gout" | grep ':.*:' > /dev/null; then 614 if echo "$gout" | grep '^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' > /dev/null; then 615 : 616 else 617 echo "ipv6: "`echo "$gout" | grep ':.*:' | head -n 1` 618 ipv6=1 619 fi 620 fi 621 if [ "X$ipv6" = "X0" ]; then 622 hout="" 623 if type host > /dev/null 2>/dev/null; then 624 host "$host" >/dev/null 2>&1 625 host "$host" >/dev/null 2>&1 626 hout=`host "$host" 2>/dev/null` 627 fi 628 if echo "$hout" | grep -i 'has ipv6 address' > /dev/null; then 629 if echo "$hout" | grep -i 'has address' > /dev/null; then 630 : 631 else 632 echo "ipv6: "`echo "$hout" | grep -i 'has ipv6 address' | head -n 1` 633 ipv6=1 634 fi 635 fi 636 fi 637 if [ "X$ipv6" = "X0" ]; then 638 dout="" 639 if type dig > /dev/null 2>/dev/null; then 640 dout=`dig -t any "$host" 2>/dev/null` 641 fi 642 if echo "$dout" | grep -i "^$host" | grep '[ ]AAAA[ ]' > /dev/null; then 643 if echo "$dout" | grep -i "^$host" | grep '[ ]A[ ]' > /dev/null; then 644 : 645 else 646 echo "ipv6: "`echo "$dout" | grep -i '[ ]AAAA[ ]' | head -n 1` 647 ipv6=1 648 fi 649 fi 650 fi 651 if [ "X$ipv6" = "X0" ]; then 652 sout=`env LOOKUP="$host" \ 653 perl -e ' eval {use Socket}; exit 0 if $@; 654 eval {use Socket6}; exit 0 if $@; 655 @res = getaddrinfo($ENV{LOOKUP}, "daytime", AF_UNSPEC, SOCK_STREAM); 656 $ipv4 = 0; 657 $ipv6 = 0; 658 $ip6 = ""; 659 while (scalar(@res) >= 5) { 660 ($family, $socktype, $proto, $saddr, $canon, @res) = @res; 661 $ipv4 = 1 if $family == AF_INET; 662 $ipv6 = 1 if $family == AF_INET6; 663 if ($family == AF_INET6 && $ip6 eq "") { 664 my ($host, $port) = getnameinfo($saddr, NI_NUMERICHOST | NI_NUMERICSERV); 665 $ip6 = $host; 666 } 667 } 668 if (! $ipv4 && $ipv6) { 669 print "AF_INET6_ONLY: $ENV{LOOKUP}: $ip6\n"; 670 } 671 exit 0; 672 ' 2>/dev/null` 673 if echo "$sout" | grep AF_INET6_ONLY > /dev/null; then 674 echo "$sout" 675 ipv6=1 676 fi 677 fi 678fi 679if [ "X$ipv6" = "X1" ]; then 680 echo "ipv6: addr=$host disp=$disp" 681fi 682if [ "X$disp" = "X" ]; then 683 port="" # probably -listen mode. 684elif [ $disp -lt 0 ]; then 685 # negative means use |n| without question: 686 port=`expr 0 - $disp` 687elif [ $disp -lt 200 ]; then 688 # less than 200 means 5900+n 689 if [ "X$reverse" = "X" ]; then 690 port=`expr $disp + 5900` 691 else 692 port=`expr $disp + 5500` 693 fi 694else 695 # otherwise use the number directly, e.g. 443, 2345 696 port=$disp 697fi 698 699if [ "X$ipv6" = "X1" -a "X$direct_connect" = "X1" ]; then 700 if [ "X$proxy" = "X" -a "X$reverse" = "X" ]; then 701 if [ "X$SSVNC_ULTRA_DSM" != "X" -a "X$have_uvnc_dsm_helper_ipv6" = "X1" ]; then 702 : 703 elif [ "X$SSVNC_NO_IPV6_PROXY" != "X" ]; then 704 : 705 elif [ "X$SSVNC_NO_IPV6_PROXY_DIRECT" != "X" ]; then 706 : 707 elif [ "X$SSVNC_USE_OURS" = "X1" ]; then 708 # requires 1.0.27 and later ssvncviewer binary 709 : 710 else 711 proxy="ipv6://$host:$port" 712 echo "direct connect: set proxy=$proxy" 713 fi 714 fi 715fi 716 717# (possibly) tell the vncviewer to only listen on lo: 718if [ "X$reverse" != "X" ]; then 719 if [ "X$direct_connect" = "X" -o "X$proxy" != "X" -o "X$STUNNEL_LISTEN" != "X" ]; then 720 VNCVIEWER_LISTEN_LOCALHOST=1 721 export VNCVIEWER_LISTEN_LOCALHOST 722 fi 723fi 724 725# try to find an open listening port via netstat(1): 726inuse="" 727if uname | grep Linux > /dev/null; then 728 inuse=`netstat -ant | egrep 'LISTEN|WAIT|ESTABLISH|CLOSE' | awk '{print $4}' | sed 's/^.*://'` 729elif uname | grep SunOS > /dev/null; then 730 inuse=`netstat -an -f inet -P tcp | egrep 'LISTEN|WAIT|ESTABLISH|CLOSE' | awk '{print $1}' | sed 's/^.*\.//'` 731elif uname | egrep -i 'bsd|darwin' > /dev/null; then 732 inuse=`netstat -ant -f inet | egrep 'LISTEN|WAIT|ESTABLISH|CLOSE' | awk '{print $4}' | sed 's/^.*\.//'` 733# add others... 734fi 735 736# this is a crude attempt for unique ports tags, etc. 737date_sec=`date +%S` 738 739# these are special cases of no vnc, e.g. sleep or xmessage. 740# these are for using ssvnc as a general port redirector. 741if echo "$VNCVIEWERCMD" | grep '^sleep[ ][ ]*[0-9][0-9]*' > /dev/null; then 742 if [ "X$SS_VNCVIEWER_LISTEN_PORT" = "X" ]; then 743 p=`echo "$VNCVIEWERCMD" | awk '{print $3}'` 744 if [ "X$p" != "X" ]; then 745 SS_VNCVIEWER_LISTEN_PORT=$p 746 fi 747 fi 748 p2=`echo "$VNCVIEWERCMD" | awk '{print $2}'` 749 VNCVIEWERCMD="eval sleep $p2; echo Local " 750elif echo "$VNCVIEWERCMD" | grep '^xmessage[ ][ ]*[0-9][0-9]*' > /dev/null; then 751 if [ "X$SS_VNCVIEWER_LISTEN_PORT" = "X" ]; then 752 p=`echo "$VNCVIEWERCMD" | awk '{print $2}'` 753 SS_VNCVIEWER_LISTEN_PORT=$p 754 fi 755fi 756 757# utility to find a free port to listen on. 758findfree() { 759 try0=$1 760 try=$try0 761 use0="" 762 763 if [ "X$SS_VNCVIEWER_LISTEN_PORT" != "X" ]; then 764 echo "$SS_VNCVIEWER_LISTEN_PORT" 765 return 766 fi 767 if [ $try -ge 6000 ]; then 768 fmax=`expr $try + 1000` 769 else 770 fmax=6000 771 fi 772 773 while [ $try -lt $fmax ] 774 do 775 if [ "X$inuse" = "X" ]; then 776 break 777 fi 778 if echo "$inuse" | grep -w $try > /dev/null; then 779 : 780 else 781 use0=$try 782 break 783 fi 784 try=`expr $try + 1` 785 done 786 if [ "X$use0" = "X" ]; then 787 use0=`expr $date_sec + $try0` 788 fi 789 790 echo $use0 791} 792 793# utility for exiting; kills some helper processes, 794# removes files, etc. 795final() { 796 echo "" 797 if [ "X$tmp_cfg" != "X" ]; then 798 rm -f $tmp_cfg 799 fi 800 if [ "X$SS_VNCVIEWER_RM" != "X" ]; then 801 rm -f $SS_VNCVIEWER_RM 2>/dev/null 802 fi 803 if [ "X$tcert" != "X" ]; then 804 rm -f $tcert 805 fi 806 if [ "X$pssh" != "X" ]; then 807 echo "Terminating background ssh process" 808 echo kill -TERM "$pssh" 809 kill -TERM "$pssh" 2>/dev/null 810 sleep 1 811 kill -KILL "$pssh" 2>/dev/null 812 pssh="" 813 fi 814 if [ "X$stunnel_pid" != "X" ]; then 815 echo "Terminating background stunnel process" 816 echo kill -TERM "$stunnel_pid" 817 kill -TERM "$stunnel_pid" 2>/dev/null 818 sleep 1 819 kill -KILL "$stunnel_pid" 2>/dev/null 820 stunnel_pid="" 821 fi 822 if [ "X$dsm_pid" != "X" ]; then 823 echo "Terminating background ultravnc_dsm_helper process" 824 echo kill -TERM "$dsm_pid" 825 kill -TERM "$dsm_pid" 2>/dev/null 826 sleep 1 827 kill -KILL "$dsm_pid" 2>/dev/null 828 stunnel_pid="" 829 fi 830 if [ "X$tail_pid" != "X" ]; then 831 kill -TERM $tail_pid 832 fi 833 if [ "X$tail_pid2" != "X" ]; then 834 kill -TERM $tail_pid2 835 fi 836} 837 838if [ "X$reverse" = "X" ]; then 839 # normal connections try 5930-5999: 840 if [ "X$showcert" = "X" ]; then 841 use=`findfree 5930` 842 else 843 # move away from normal place for (possibly many) -showcert 844 pstart=`date +%S` 845 pstart=`expr 6130 + $pstart + $pstart` 846 use=`findfree $pstart` 847 fi 848 if [ $use -ge 5900 ]; then 849 N=`expr $use - 5900` 850 else 851 N=$use 852 fi 853else 854 # reverse connections: 855 p2=`expr $port + 30` 856 use=`findfree $p2` 857 if [ $use -ge 5500 ]; then 858 N=`expr $use - 5500` 859 else 860 N=$use 861 fi 862fi 863 864# this is for my special use of ss_vncip -> vncip viewer. 865if echo "$0" | grep vncip > /dev/null; then 866 VNCVIEWERCMD="$VNCIPCMD" 867fi 868 869if echo "$VNCVIEWERCMD" | egrep -i '^(xmessage|sleep )' > /dev/null; then 870 : 871elif [ "X$VNCVIEWERCMD_EXTRA_OPTS" != "X" ]; then 872 VNCVIEWERCMD="$VNCVIEWERCMD $VNCVIEWERCMD_EXTRA_OPTS" 873fi 874 875# trick for the undocumented rsh://host:port method. 876rsh_setup() { 877 if echo "$ssh_host" | grep '@' > /dev/null; then 878 ul=`echo "$ssh_host" | awk -F@ '{print $1}'` 879 ul="-l $ul" 880 ssh_host=`echo "$ssh_host" | awk -F@ '{print $2}'` 881 else 882 ul="" 883 fi 884 ssh_cmd=`echo "$ssh_cmd" | sed -e 's/ -localhost/ /g'` 885} 886 887# trick for the undocumented rsh://host:port method. 888rsh_viewer() { 889 trap "final" 0 2 15 890 if [ "X$PORT" = "X" ]; then 891 exit 1 892 elif [ $PORT -ge 5900 ]; then 893 vdpy=`expr $PORT - 5900` 894 else 895 vdpy=":$PORT" 896 fi 897 stty sane 898 echo "$VNCVIEWERCMD" "$@" $ssh_host:$vdpy 899 echo "" 900 $VNCVIEWERCMD "$@" $ssh_host:$vdpy 901 if [ $? != 0 ]; then 902 sleep 2 903 $VNCVIEWERCMD "$@" $ssh_host:$vdpy 904 fi 905} 906 907check_perl() { 908 if type "$1" > /dev/null 2>&1; then 909 : 910 elif [ ! -x "$1" ]; then 911 echo "" 912 echo "*******************************************************" 913 echo "** Problem finding the Perl command '$1': **" 914 echo "" 915 type "perl" 916 echo "" 917 echo "** Perhaps you need to install the Perl package. **" 918 echo "*******************************************************" 919 echo "" 920 sleep 5 921 fi 922} 923 924# this is the PPROXY tool. used only here for now... 925pcode() { 926 tf=$1 927 PPROXY_PROXY=$proxy; export PPROXY_PROXY 928 PPROXY_DEST="$host:$port"; export PPROXY_DEST 929 check_perl /usr/bin/perl 930 931 cod='#!/usr/bin/perl 932 933# A hack to glue stunnel to a Web or SOCKS proxy, UltraVNC repeater for 934# client connections. 935# Also acts as a VeNCrypt bridge (by redirecting to stunnel.) 936 937use IO::Socket::INET; 938 939my $have_inet6 = ""; 940eval "use IO::Socket::INET6;"; 941$have_inet6 = 1 if $@ eq ""; 942 943#my $have_sock6 = ""; 944#eval "use Socket; use Socket6;"; 945#$have_sock6 = 1 if $@ eq ""; 946 947if (exists $ENV{PPROXY_LOOP_THYSELF}) { 948 # used for reverse vnc, run a repeating outer loop. 949 print STDERR "PPROXY_LOOP: $ENV{PPROXY_LOOP_THYSELF}\n"; 950 my $rm = $ENV{PPROXY_REMOVE}; 951 my $lp = $ENV{PPROXY_LOOP_THYSELF}; 952 delete $ENV{PPROXY_REMOVE}; 953 delete $ENV{PPROXY_LOOP_THYSELF}; 954 $ENV{PPROXY_LOOP_THYSELF_MASTER} = $$; 955 my $pid = $$; 956 my $dbg = 0; 957 my $c = 0; 958 use POSIX ":sys_wait_h"; 959 while (1) { 960 $pid = fork(); 961 last if ! defined $pid; 962 if ($pid eq "0") { 963 last; 964 } 965 $c++; 966 print STDERR "\nPPROXY_LOOP: pid=$$ child=$pid count=$c\n"; 967 while (1) { 968 waitpid(-1, WNOHANG); 969 fsleep(0.25); 970 if (! kill 0, $pid) { 971 print STDERR "PPROXY_LOOP: child=$pid gone.\n"; 972 last; 973 } 974 print STDERR "PPROXY_LOOP: child=$pid alive.\n" if $dbg; 975 if (! -f $lp) { 976 print STDERR "PPROXY_LOOP: flag file $lp gone, killing $pid\n"; 977 kill TERM, $pid; 978 fsleep(0.1); 979 wait; 980 last; 981 } 982 print STDERR "PPROXY_LOOP: file exists $lp\n" if $dbg; 983 } 984 last if ! -f $lp; 985 fsleep(0.25); 986 } 987 if ($pid ne "0") { 988 unlink($0) if $rm; 989 exit 0; 990 } 991} 992 993if (exists $ENV{PPROXY_SLEEP} && $ENV{PPROXY_SLEEP} > 0) { 994 print STDERR "PPROXY_PID: $$\n"; 995 sleep $ENV{PPROXY_SLEEP}; 996} 997 998foreach my $var (qw( 999 PPROXY_DEST 1000 PPROXY_KILLPID 1001 PPROXY_LISTEN 1002 PPROXY_PROXY 1003 PPROXY_REMOVE 1004 PPROXY_REPEATER 1005 PPROXY_REVERSE 1006 PPROXY_SLEEP 1007 PPROXY_SOCKS 1008 PPROXY_VENCRYPT 1009 PPROXY_VENCRYPT_VIEWER_BRIDGE 1010 )) { 1011 if (0 || $ENV{SS_DEBUG} || $ENV{SSVNC_VENCRYPT_DEBUG}) { 1012 print STDERR "$var: $ENV{$var}\n"; 1013 } 1014} 1015 1016if ($ENV{PPROXY_SOCKS} ne "" && $ENV{PPROXY_PROXY} !~ m,^socks5?://,i) { 1017 if ($ENV{PPROXY_SOCKS} eq "5") { 1018 $ENV{PPROXY_PROXY} = "socks5://$ENV{PPROXY_PROXY}"; 1019 } else { 1020 $ENV{PPROXY_PROXY} = "socks://$ENV{PPROXY_PROXY}"; 1021 } 1022} 1023 1024my $rfbSecTypeAnonTls = 18; 1025my $rfbSecTypeVencrypt = 19; 1026 1027my $rfbVencryptPlain = 256; 1028my $rfbVencryptTlsNone = 257; 1029my $rfbVencryptTlsVnc = 258; 1030my $rfbVencryptTlsPlain = 259; 1031my $rfbVencryptX509None = 260; 1032my $rfbVencryptX509Vnc = 261; 1033my $rfbVencryptX509Plain = 262; 1034 1035my $handshake_file = ""; 1036if (exists $ENV{SSVNC_PREDIGESTED_HANDSHAKE}) { 1037 $handshake_file = $ENV{SSVNC_PREDIGESTED_HANDSHAKE}; 1038} 1039 1040my $have_gettimeofday = 0; 1041eval "use Time::HiRes;"; 1042if ($@ eq "") { 1043 $have_gettimeofday = 1; 1044} 1045sub gettime { 1046 my $t = "0.0"; 1047 if ($have_gettimeofday) { 1048 $t = Time::HiRes::gettimeofday(); 1049 } 1050 return $t; 1051} 1052 1053my $listen_handle = ""; 1054my $sock = ""; 1055my $parent = $$; 1056 1057my $initial_data = ""; 1058 1059if ($ENV{PPROXY_VENCRYPT_VIEWER_BRIDGE}) { 1060 my ($from, $to) = split(/,/, $ENV{PPROXY_VENCRYPT_VIEWER_BRIDGE}); 1061 do_vencrypt_viewer_bridge($from, $to); 1062 exit 0; 1063} 1064 1065my ($first, $second, $third) = split(/,/, $ENV{PPROXY_PROXY}, 3); 1066my ($mode_1st, $mode_2nd, $mode_3rd) = ("", "", ""); 1067 1068($first, $mode_1st) = url_parse($first); 1069 1070my ($proxy_host, $proxy_port) = ($first, ""); 1071if ($proxy_host =~ /^(.*):(\d+)$/) { 1072 $proxy_host = $1; 1073 $proxy_port = $2; 1074} 1075my $connect = $ENV{PPROXY_DEST}; 1076 1077if ($second ne "") { 1078 ($second, $mode_2nd) = url_parse($second); 1079} 1080 1081if ($third ne "") { 1082 ($third, $mode_3rd) = url_parse($third); 1083} 1084 1085 1086print STDERR "\n"; 1087print STDERR "PPROXY v0.4: a tool for Web, SOCKS, and UltraVNC proxies and for\n"; 1088print STDERR "PPROXY v0.4: IPv6 and VNC VeNCrypt bridging.\n"; 1089print STDERR "proxy_host: $proxy_host\n"; 1090print STDERR "proxy_port: $proxy_port\n"; 1091print STDERR "proxy_connect: $connect\n"; 1092print STDERR "pproxy_params: $ENV{PPROXY_PROXY}\n"; 1093print STDERR "pproxy_listen: $ENV{PPROXY_LISTEN}\n"; 1094print STDERR "pproxy_reverse: $ENV{PPROXY_REVERSE}\n"; 1095print STDERR "io_socket_inet6: $have_inet6\n"; 1096print STDERR "\n"; 1097if (! $have_inet6) { 1098 print STDERR "PPROXY: To enable IPv6 connections, install the IO::Socket::INET6 perl module.\n\n"; 1099} 1100 1101if (1) { 1102 print STDERR "pproxy 1st: $first\t- $mode_1st\n"; 1103 print STDERR "pproxy 2nd: $second\t- $mode_2nd\n"; 1104 print STDERR "pproxy 3rd: $third\t- $mode_3rd\n"; 1105 print STDERR "\n"; 1106} 1107 1108sub pdie { 1109 my $msg = shift; 1110 kill_proxy_pids(); 1111 die "$msg"; 1112} 1113 1114if ($ENV{PPROXY_REVERSE} ne "") { 1115 my ($rhost, $rport) = ($ENV{PPROXY_REVERSE}, ""); 1116 if ($rhost =~ /^(.*):(\d+)$/) { 1117 $rhost = $1; 1118 $rport = $2; 1119 } 1120 $rport = 5900 unless $rport; 1121 my $emsg = ""; 1122 $listen_handle = IO::Socket::INET->new( 1123 PeerAddr => $rhost, 1124 PeerPort => $rport, 1125 Proto => "tcp" 1126 ); 1127 $emsg = $!; 1128 if (! $listen_handle && $have_inet6) { 1129 eval {$listen_handle = IO::Socket::INET6->new( 1130 PeerAddr => $rhost, 1131 PeerPort => $rport, 1132 Proto => "tcp" 1133 );}; 1134 $emsg .= " / $!"; 1135 } 1136 if (! $listen_handle) { 1137 pdie "pproxy: $emsg -- PPROXY_REVERSE\n"; 1138 } 1139 print STDERR "PPROXY_REVERSE: connected to $rhost $rport\n"; 1140 1141} elsif ($ENV{PPROXY_LISTEN} ne "") { 1142 my $listen_sock = ""; 1143 my $maxtry = 12; 1144 my $sleep = 5; 1145 my $p2 = ""; 1146 my $emsg = ""; 1147 for (my $i=0; $i < $maxtry; $i++) { 1148 my ($if, $p) = ("", $ENV{PPROXY_LISTEN}); 1149 if ($p =~ /^(.*):(\d+)$/) { 1150 $if = $1; 1151 $p = $2; 1152 } 1153 $p2 = "*:$p"; 1154 if ($if eq "") { 1155 $if = "localhost"; 1156 } 1157 print STDERR "pproxy interface: $if\n"; 1158 1159 $emsg = ""; 1160 if (($if eq "INADDR_ANY6" || $if eq "::") && $have_inet6) { 1161 eval {$listen_sock = IO::Socket::INET6->new( 1162 Listen => 2, 1163 ReuseAddr => 1, 1164 Domain => AF_INET6, 1165 LocalAddr => "::", 1166 LocalPort => $p, 1167 Proto => "tcp" 1168 );}; 1169 $p2 = ":::$p"; 1170 } elsif ($if =~ /^INADDR_ANY/) { 1171 $listen_sock = IO::Socket::INET->new( 1172 Listen => 2, 1173 ReuseAddr => 1, 1174 LocalPort => $p, 1175 Proto => "tcp" 1176 ); 1177 } elsif (($if eq "INADDR_LOOPBACK6" || $if eq "::1") && $have_inet6) { 1178 $p2 = "::1:$p"; 1179 eval {$listen_sock = IO::Socket::INET6->new( 1180 Listen => 2, 1181 ReuseAddr => 1, 1182 Domain => AF_INET6, 1183 LocalAddr => "::1", 1184 LocalPort => $p, 1185 Proto => "tcp" 1186 );}; 1187 $p2 = "::1:$p"; 1188 } else { 1189 $p2 = "$if:$p"; 1190 $listen_sock = IO::Socket::INET->new( 1191 Listen => 2, 1192 ReuseAddr => 1, 1193 LocalAddr => $if, 1194 LocalPort => $p, 1195 Proto => "tcp" 1196 ); 1197 $emsg = $!; 1198 1199 if (! $listen_sock && $have_inet6) { 1200 print STDERR "PPROXY_LISTEN: retry with INET6\n"; 1201 eval {$listen_sock = IO::Socket::INET6->new( 1202 Listen => 2, 1203 ReuseAddr => 1, 1204 Domain => AF_INET6, 1205 LocalAddr => $if, 1206 LocalPort => $p, 1207 Proto => "tcp" 1208 );}; 1209 $emsg .= " / $!"; 1210 } 1211 } 1212 if (! $listen_sock) { 1213 if ($i < $maxtry - 1) { 1214 warn "pproxy: $emsg $!\n"; 1215 warn "Could not listen on port $p2, retrying in $sleep seconds... (Ctrl-C to quit)\n"; 1216 sleep $sleep; 1217 } 1218 } else { 1219 last; 1220 } 1221 } 1222 if (! $listen_sock) { 1223 pdie "pproxy: $emsg -- PPROXY_LISTEN\n"; 1224 } 1225 print STDERR "pproxy: listening on $p2\n"; 1226 my $ip; 1227 ($listen_handle, $ip) = $listen_sock->accept(); 1228 my $err = $!; 1229 close $listen_sock; 1230 if (! $listen_handle) { 1231 pdie "pproxy: $err\n"; 1232 } 1233 1234 if ($ENV{PPROXY_LOOP_THYSELF_MASTER}) { 1235 my $sml = $ENV{SSVNC_MULTIPLE_LISTEN}; 1236 if ($sml ne "" && $sml ne "0") { 1237 setpgrp(0, 0); 1238 if (fork()) { 1239 close $viewer_sock; 1240 wait; 1241 exit 0; 1242 } 1243 if (fork()) { 1244 close $viewer_sock; 1245 exit 0; 1246 } 1247 setpgrp(0, 0); 1248 $parent = $$; 1249 } 1250 } 1251} 1252 1253$sock = IO::Socket::INET->new( 1254 PeerAddr => $proxy_host, 1255 PeerPort => $proxy_port, 1256 Proto => "tcp" 1257); 1258 1259my $err = ""; 1260 1261if (! $sock && $have_inet6) { 1262 $err = $!; 1263 1264 print STDERR "pproxy: $!\n"; 1265 1266 eval {$sock = IO::Socket::INET6->new( 1267 PeerAddr => $proxy_host, 1268 PeerPort => $proxy_port, 1269 Proto => "tcp" 1270 );}; 1271 $err .= " / $!"; 1272} 1273 1274if (! $sock && ($proxy_host =~ /^::ffff:(\d+\.\d+\.\d+\.\d+)$/i || $proxy_host =~ /^::ffff:([\da-f]+:[\da-f]+)$/i)) { 1275 print STDERR "pproxy: $!\n"; 1276 my $ipv4_addr = $1; 1277 if ($ipv4_addr =~ /:/) { 1278 my ($a, $b) = split(/:/, $ipv4_addr); 1279 $a = hex($a); 1280 $b = hex($b); 1281 $ipv4_addr = sprintf("%d.", ($a & 0xff00) >> 8); 1282 $ipv4_addr .= sprintf("%d.", ($a & 0x00ff)); 1283 $ipv4_addr .= sprintf("%d.", ($b & 0xff00) >> 8); 1284 $ipv4_addr .= sprintf("%d", ($b & 0x00ff)); 1285 } 1286 1287 print STDERR "pproxy: re-trying with ipv4 addr: $ipv4_addr\n"; 1288 1289 eval {$sock = IO::Socket::INET->new( 1290 PeerAddr => $ipv4_addr, 1291 PeerPort => $proxy_port, 1292 Proto => "tcp" 1293 );}; 1294 $err .= " / $!"; 1295} 1296 1297if (! $sock) { 1298 unlink($0) if $ENV{PPROXY_REMOVE}; 1299 pdie "pproxy: $err\n"; 1300} 1301 1302unlink($0) if $ENV{PPROXY_REMOVE}; 1303 1304if ($ENV{PPROXY_PROXY} =~ /^vencrypt:/ && $ENV{PPROXY_VENCRYPT_REVERSE}) { 1305 print STDERR "\nPPROXY: vencrypt+reverse: swapping listen socket with connect socket.\n"; 1306 my $tmp_swap = $sock; 1307 $sock = $listen_handle; 1308 $listen_handle = $tmp_swap; 1309} 1310 1311$cur_proxy = $first; 1312setmode($mode_1st); 1313 1314if ($second ne "") { 1315 connection($second, 1); 1316 1317 setmode($mode_2nd); 1318 $cur_proxy = $second; 1319 1320 if ($third ne "") { 1321 connection($third, 2); 1322 setmode($mode_3rd); 1323 $cur_proxy = $third; 1324 connection($connect, 3); 1325 } else { 1326 connection($connect, 2); 1327 } 1328} else { 1329 connection($connect, 1); 1330} 1331 1332sub kill_proxy_pids() { 1333 if ($ENV{PPROXY_VENCRYPT_VIEWER_BRIDGE}) { 1334 return; 1335 } 1336 if ($ENV{PPROXY_KILLPID}) { 1337 foreach my $p (split(/,/, $ENV{PPROXY_KILLPID})) { 1338 if ($p =~ /^(\+|-)/) { 1339 $p = $parent + $p; 1340 } 1341 print STDERR "kill TERM, $p (PPROXY_KILLPID)\n"; 1342 kill "TERM", $p; 1343 } 1344 } 1345} 1346 1347sub xfer { 1348 my($in, $out) = @_; 1349 $RIN = $WIN = $EIN = ""; 1350 $ROUT = ""; 1351 vec($RIN, fileno($in), 1) = 1; 1352 vec($WIN, fileno($in), 1) = 1; 1353 $EIN = $RIN | $WIN; 1354 1355 while (1) { 1356 my $nf = 0; 1357 while (! $nf) { 1358 $nf = select($ROUT=$RIN, undef, undef, undef); 1359 } 1360 my $len = sysread($in, $buf, 8192); 1361 if (! defined($len)) { 1362 next if $! =~ /^Interrupted/; 1363 print STDERR "pproxy[$$]: $!\n"; 1364 last; 1365 } elsif ($len == 0) { 1366 print STDERR "pproxy[$$]: Input is EOF.\n"; 1367 last; 1368 } 1369 my $offset = 0; 1370 my $quit = 0; 1371 while ($len) { 1372 my $written = syswrite($out, $buf, $len, $offset); 1373 if (! defined $written) { 1374 print STDERR "pproxy[$$]: Output is EOF. $!\n"; 1375 $quit = 1; 1376 last; 1377 } 1378 $len -= $written; 1379 $offset += $written; 1380 } 1381 last if $quit; 1382 } 1383 close($out); 1384 close($in); 1385 print STDERR "pproxy[$$]: finished xfer.\n"; 1386} 1387 1388sub handler { 1389 print STDERR "pproxy[$$]: got SIGTERM.\n"; 1390 close $listen_handle if $listen_handle; 1391 close $sock if $sock; 1392 exit; 1393} 1394 1395sub xfer_both { 1396 $child = fork; 1397 1398 if (! defined $child) { 1399 kill_proxy_pids(); 1400 exit 1; 1401 } 1402 1403 $SIG{TERM} = "handler"; 1404 1405 if ($child) { 1406 if ($listen_handle) { 1407 print STDERR "pproxy parent[$$] listen_handle -> socket\n"; 1408 xfer($listen_handle, $sock); 1409 } else { 1410 print STDERR "pproxy parent[$$] STDIN -> socket\n"; 1411 xfer(STDIN, $sock); 1412 } 1413 select(undef, undef, undef, 0.25); 1414 if (kill 0, $child) { 1415 select(undef, undef, undef, 0.9); 1416 if (kill 0, $child) { 1417 print STDERR "pproxy[$$]: kill TERM child $child\n"; 1418 kill "TERM", $child; 1419 } else { 1420 print STDERR "pproxy[$$]: child $child gone.\n"; 1421 } 1422 } 1423 } else { 1424 select(undef, undef, undef, 0.05); 1425 if ($listen_handle) { 1426 print STDERR "pproxy child [$$] socket -> listen_handle\n"; 1427 if ($initial_data ne "") { 1428 my $len = length $initial_data; 1429 print STDERR "pproxy child [$$] sending initial_data, length $len\n\n"; 1430 syswrite($listen_handle, $initial_data, $len); 1431 } else { 1432 print STDERR "\n"; 1433 } 1434 xfer($sock, $listen_handle); 1435 } else { 1436 print STDERR "pproxy child [$$] socket -> STDOUT\n"; 1437 if ($initial_data ne "") { 1438 my $len = length $initial_data; 1439 print STDERR "pproxy child [$$] sending initial_data, length $len\n\n"; 1440 syswrite(STDOUT, $initial_data, $len); 1441 } else { 1442 print STDERR "\n"; 1443 } 1444 xfer($sock, STDOUT); 1445 } 1446 select(undef, undef, undef, 0.25); 1447 if (kill 0, $parent) { 1448 select(undef, undef, undef, 0.8); 1449 if (kill 0, $parent) { 1450 print STDERR "pproxy[$$]: kill TERM parent $parent\n"; 1451 kill "TERM", $parent; 1452 } else { 1453 print STDERR "pproxy[$$]: parent $parent gone.\n"; 1454 } 1455 } 1456 } 1457 1458 kill_proxy_pids(); 1459} 1460 1461xfer_both(); 1462 1463exit; 1464 1465sub fsleep { 1466 select(undef, undef, undef, shift); 1467} 1468 1469sub url_parse { 1470 my $hostport = shift; 1471 my $mode = "http"; 1472 if ($hostport =~ m,^socks4?://(\S*)$,i) { 1473 $mode = "socks4"; 1474 $hostport = $1; 1475 } elsif ($hostport =~ m,^socks5://(\S*)$,i) { 1476 $mode = "socks5"; 1477 $hostport = $1; 1478 } elsif ($hostport =~ m,^https?://(\S*)$,i) { 1479 $mode = "http"; 1480 $hostport = $1; 1481 } elsif ($hostport =~ m,^ipv6://(\S*)$,i) { 1482 $mode = "ipv6"; 1483 $hostport = $1; 1484 } elsif ($hostport =~ m,^repeater://(\S*)\+(\S*)$,i) { 1485 # ultravnc repeater proxy. 1486 $hostport = $1; 1487 $mode = "repeater:$2"; 1488 if ($hostport !~ /:\d+$/) { 1489 $hostport .= ":5900"; 1490 } 1491 } elsif ($hostport =~ m,^vencrypt://(\S*)$,i) { 1492 # vencrypt handshake. 1493 $hostport = $1; 1494 my $m = "connect"; 1495 if ($hostpost =~ /^(\S+)\+(\S+)$/) { 1496 $hostport = $1; 1497 $mode = $2; 1498 } 1499 $mode = "vencrypt:$m"; 1500 if ($hostport !~ /:\d+$/) { 1501 $hostport .= ":5900"; 1502 } 1503 } 1504 return ($hostport, $mode); 1505} 1506 1507sub setmode { 1508 my $mode = shift; 1509 $ENV{PPROXY_REPEATER} = ""; 1510 $ENV{PPROXY_VENCRYPT} = ""; 1511 if ($mode =~ /^socks/) { 1512 if ($mode =~ /^socks5/) { 1513 $ENV{PPROXY_SOCKS} = 5; 1514 } else { 1515 $ENV{PPROXY_SOCKS} = 1; 1516 } 1517 } elsif ($mode =~ /^ipv6/i) { 1518 $ENV{PPROXY_SOCKS} = 0; 1519 } elsif ($mode =~ /^repeater:(.*)/) { 1520 $ENV{PPROXY_REPEATER} = $1; 1521 $ENV{PPROXY_SOCKS} = ""; 1522 } elsif ($mode =~ /^vencrypt:(.*)/) { 1523 $ENV{PPROXY_VENCRYPT} = $1; 1524 $ENV{PPROXY_SOCKS} = ""; 1525 } else { 1526 $ENV{PPROXY_SOCKS} = ""; 1527 } 1528} 1529 1530sub connection { 1531 my ($CONNECT, $w) = @_; 1532 1533 my $con = ""; 1534 my $msg = ""; 1535 1536 if ($ENV{PPROXY_SOCKS} eq "5") { 1537 # SOCKS5 1538 my ($h, $p) = ($CONNECT, ""); 1539 if ($h =~ /^(.*):(\d+)$/) { 1540 $h = $1; 1541 $p = $2; 1542 } 1543 $con .= pack("C", 0x05); 1544 $con .= pack("C", 0x01); 1545 $con .= pack("C", 0x00); 1546 1547 $msg = "SOCKS5 via $cur_proxy to $h:$p\n\n"; 1548 print STDERR "proxy_request$w: $msg"; 1549 1550 syswrite($sock, $con, length($con)); 1551 1552 my ($n1, $n2, $n3, $n4, $n5, $n6); 1553 my ($r1, $r2, $r3, $r4, $r5, $r6); 1554 my ($s1, $s2, $s3, $s4, $s5, $s6); 1555 1556 $n1 = sysread($sock, $r1, 1); 1557 $n2 = sysread($sock, $r2, 1); 1558 1559 $s1 = unpack("C", $r1); 1560 $s2 = unpack("C", $r2); 1561 if ($s1 != 0x05 || $s2 != 0x00) { 1562 print STDERR "SOCKS5 fail s1=$s1 s2=$s2 n1=$n1 n2=$n2\n"; 1563 close $sock; 1564 exit(1); 1565 } 1566 1567 $con = ""; 1568 $con .= pack("C", 0x05); 1569 $con .= pack("C", 0x01); 1570 $con .= pack("C", 0x00); 1571 $con .= pack("C", 0x03); 1572 $con .= pack("C", length($h)); 1573 $con .= $h; 1574 $con .= pack("C", $p >> 8); 1575 $con .= pack("C", $p & 0xff); 1576 1577 syswrite($sock, $con, length($con)); 1578 1579 $n1 = sysread($sock, $r1, 1); 1580 $n2 = sysread($sock, $r2, 1); 1581 $n3 = sysread($sock, $r3, 1); 1582 $n4 = sysread($sock, $r4, 1); 1583 $s1 = unpack("C", $r1); 1584 $s2 = unpack("C", $r2); 1585 $s3 = unpack("C", $r3); 1586 $s4 = unpack("C", $r4); 1587 1588 if ($s4 == 0x1) { 1589 sysread($sock, $r5, 4 + 2); 1590 } elsif ($s4 == 0x3) { 1591 sysread($sock, $r5, 1); 1592 $s5 = unpack("C", $r5); 1593 sysread($sock, $r6, $s5 + 2); 1594 } elsif ($s4 == 0x4) { 1595 sysread($sock, $r5, 16 + 2); 1596 } 1597 1598 if ($s1 != 0x5 || $s2 != 0x0 || $s3 != 0x0) { 1599 print STDERR "SOCKS5 failed: s1=$s1 s2=$s2 s3=$s3 s4=$s4 n1=$n1 n2=$n2 n3=$n3 n4=$n4\n"; 1600 close $sock; 1601 exit(1); 1602 } 1603 1604 } elsif ($ENV{PPROXY_SOCKS} eq "1") { 1605 # SOCKS4 SOCKS4a 1606 my ($h, $p) = ($CONNECT, ""); 1607 if ($h =~ /^(.*):(\d+)$/) { 1608 $h = $1; 1609 $p = $2; 1610 } 1611 $con .= pack("C", 0x04); 1612 $con .= pack("C", 0x01); 1613 $con .= pack("n", $p); 1614 1615 my $SOCKS_4a = 0; 1616 if ($h eq "localhost" || $h eq "127.0.0.1") { 1617 $con .= pack("C", 127); 1618 $con .= pack("C", 0); 1619 $con .= pack("C", 0); 1620 $con .= pack("C", 1); 1621 } elsif ($h =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) { 1622 $con .= pack("C", $1); 1623 $con .= pack("C", $2); 1624 $con .= pack("C", $3); 1625 $con .= pack("C", $4); 1626 } else { 1627 $con .= pack("C", 0); 1628 $con .= pack("C", 0); 1629 $con .= pack("C", 0); 1630 $con .= pack("C", 3); 1631 $SOCKS_4a = 1; 1632 } 1633 1634 $con .= "nobody"; 1635 $con .= pack("C", 0); 1636 1637 $msg = "SOCKS4 via $cur_proxy to $h:$p\n\n"; 1638 if ($SOCKS_4a) { 1639 $con .= $h; 1640 $con .= pack("C", 0); 1641 $msg =~ s/SOCKS4/SOCKS4a/; 1642 } 1643 print STDERR "proxy_request$w: $msg"; 1644 syswrite($sock, $con, length($con)); 1645 1646 my $ok = 1; 1647 for (my $i = 0; $i < 8; $i++) { 1648 my $c; 1649 sysread($sock, $c, 1); 1650 my $s = unpack("C", $c); 1651 if ($i == 0) { 1652 $ok = 0 if $s != 0x0; 1653 } elsif ($i == 1) { 1654 $ok = 0 if $s != 0x5a; 1655 } 1656 } 1657 if (! $ok) { 1658 print STDERR "SOCKS4 failed.\n"; 1659 close $sock; 1660 exit(1); 1661 } 1662 } elsif ($ENV{PPROXY_SOCKS} eq "0") { 1663 # hack for ipv6 "proxy", nothing to do, assume INET6 call worked. 1664 ; 1665 } elsif ($ENV{PPROXY_REPEATER} ne "") { 1666 my $rep = $ENV{PPROXY_REPEATER}; 1667 print STDERR "repeater: $rep\n"; 1668 $rep .= pack("x") x 250; 1669 syswrite($sock, $rep, 250); 1670 1671 my $rfb = ""; 1672 1673 my $ok = 1; 1674 for (my $i = 0; $i < 12; $i++) { 1675 my $c; 1676 last if $ENV{PPROXY_GENERIC_REPEATER}; 1677 sysread($sock, $c, 1); 1678 print STDERR $c; 1679 $rfb .= $c; 1680 } 1681 if ($rfb ne "" && $rfb !~ /^RFB 000\.000/) { 1682 $initial_data = $rfb; 1683 $rfb =~ s/\n//g; 1684 print STDERR "detected non-UltraVNC repeater; forwarding \"$rfb\"\nlength: ", length($initial_data), "\n"; 1685 } 1686 } elsif ($ENV{PPROXY_VENCRYPT} ne "") { 1687 my $vencrypt = $ENV{PPROXY_VENCRYPT}; 1688 vencrypt_dialog($vencrypt); 1689 1690 } else { 1691 # Web Proxy: 1692 $con = "CONNECT $CONNECT HTTP/1.1\r\n"; 1693 $con .= "Host: $CONNECT\r\n"; 1694 $con .= "Connection: close\r\n\r\n"; 1695 $msg = $con; 1696 1697 print STDERR "proxy_request$w: via $cur_proxy:\n$msg"; 1698 syswrite($sock, $con, length($con)); 1699 1700 my $rep = ""; 1701 my $n = 0; 1702 while ($rep !~ /\r\n\r\n/ && $n < 30000) { 1703 my $c; 1704 sysread($sock, $c, 1); 1705 print STDERR $c; 1706 $rep .= $c; 1707 $n++; 1708 } 1709 if ($rep !~ m,HTTP/.* 200,) { 1710 print STDERR "HTTP CONNECT failed.\n"; 1711 close $sock; 1712 exit(1); 1713 } 1714 } 1715} 1716 1717sub vdie { 1718 append_handshake("done\n"); 1719 close $sock; 1720 kill_proxy_pids(); 1721 exit(1); 1722} 1723 1724sub anontls_handshake { 1725 my ($vmode, $db) = @_; 1726 1727 print STDERR "\nPPROXY: Doing ANONTLS Handshake\n"; 1728 1729 my $psec = pack("C", $rfbSecTypeAnonTls); 1730 syswrite($sock, $psec, 1); 1731 1732 append_handshake("done\n"); 1733} 1734 1735sub vencrypt_handshake { 1736 1737 my ($vmode, $db) = @_; 1738 1739 print STDERR "\nPPROXY: Doing VeNCrypt Handshake\n"; 1740 1741 my $psec = pack("C", $rfbSecTypeVencrypt); 1742 1743 if (exists $ENV{SSVNC_TEST_SEC_TYPE}) { 1744 my $fake = $ENV{SSVNC_TEST_SEC_TYPE}; 1745 print STDERR "PPROXY: sending sec-type: $fake\n"; 1746 $psec = pack("C", $fake); 1747 } 1748 1749 syswrite($sock, $psec, 1); 1750 1751 my $vmajor; 1752 my $vminor; 1753 sysread($sock, $vmajor, 1); 1754 sysread($sock, $vminor, 1); 1755 1756 vdie if $vmajor eq "" || $vminor eq ""; 1757 1758 $vmajor = unpack("C", $vmajor); 1759 $vminor = unpack("C", $vminor); 1760 print STDERR "server vencrypt version $vmajor.$vminor\n" if $db; 1761 1762 if (exists $ENV{SSVNC_TEST_SEC_TYPE}) { 1763 print STDERR "PPROXY: continuing on in test mode.\n"; 1764 } else { 1765 vdie if $vmajor ne 0; 1766 vdie if $vminor < 2; 1767 } 1768 1769 $vmajor = pack("C", 0); 1770 $vminor = pack("C", 2); 1771 append_handshake("subversion=0.2\n"); 1772 1773 syswrite($sock, $vmajor, 1); 1774 syswrite($sock, $vminor, 1); 1775 1776 my $result; 1777 sysread($sock, $result, 1); 1778 print STDERR "result empty\n" if $db && $result eq ""; 1779 1780 vdie if $result eq ""; 1781 $result = unpack("C", $result); 1782 print STDERR "result=$result\n" if $db; 1783 1784 vdie if $result ne 0; 1785 1786 my $nsubtypes; 1787 sysread($sock, $nsubtypes, 1); 1788 1789 vdie if $nsubtypes eq ""; 1790 $nsubtypes = unpack("C", $nsubtypes); 1791 print STDERR "nsubtypes=$nsubtypes\n" if $db; 1792 1793 my %subtypes; 1794 1795 for (my $i = 0; $i < $nsubtypes; $i++) { 1796 my $subtype = ""; 1797 sysread($sock, $subtype, 4); 1798 vdie if length($subtype) != 4; 1799 1800 # XXX fix 64bit. 1801 $subtype = unpack("N", $subtype); 1802 print STDERR "subtype: $subtype\n" if $db; 1803 $subtypes{$subtype} = 1; 1804 append_handshake("sst$i=$subtype\n"); 1805 } 1806 1807 my $subtype = 0; 1808 if (exists $subtypes{$rfbVencryptX509None}) { 1809 $subtype = $rfbVencryptX509None; 1810 print STDERR "selected rfbVencryptX509None\n" if $db; 1811 } elsif (exists $subtypes{$rfbVencryptX509Vnc}) { 1812 $subtype = $rfbVencryptX509Vnc; 1813 print STDERR "selected rfbVencryptX509Vnc\n" if $db; 1814 } elsif (exists $subtypes{$rfbVencryptX509Plain}) { 1815 $subtype = $rfbVencryptX509Plain; 1816 print STDERR "selected rfbVencryptX509Plain\n" if $db; 1817 } elsif (exists $subtypes{$rfbVencryptTlsNone}) { 1818 $subtype = $rfbVencryptTlsNone; 1819 print STDERR "selected rfbVencryptTlsNone\n" if $db; 1820 } elsif (exists $subtypes{$rfbVencryptTlsVnc}) { 1821 $subtype = $rfbVencryptTlsVnc; 1822 print STDERR "selected rfbVencryptTlsVnc\n" if $db; 1823 } elsif (exists $subtypes{$rfbVencryptTlsPlain}) { 1824 $subtype = $rfbVencryptTlsPlain; 1825 print STDERR "selected rfbVencryptTlsPlain\n" if $db; 1826 } 1827 1828 if (exists $ENV{SSVNC_TEST_SEC_SUBTYPE}) { 1829 my $fake = $ENV{SSVNC_TEST_SEC_SUBTYPE}; 1830 print STDERR "PPROXY: sending sec-subtype: $fake\n"; 1831 $subtype = $fake; 1832 } 1833 1834 append_handshake("subtype=$subtype\n"); 1835 1836 my $pst = pack("N", $subtype); 1837 syswrite($sock, $pst, 4); 1838 1839 if (exists $ENV{SSVNC_TEST_SEC_SUBTYPE}) { 1840 print STDERR "PPROXY: continuing on in test mode.\n"; 1841 } else { 1842 vdie if $subtype == 0; 1843 } 1844 1845 my $ok; 1846 sysread($sock, $ok, 1); 1847 $ok = unpack("C", $ok); 1848 print STDERR "ok=$ok\n" if $db; 1849 1850 append_handshake("done\n"); 1851 1852 vdie if $ok == 0; 1853} 1854 1855sub vencrypt_dialog { 1856 my $vmode = shift; 1857 my $db = 0; 1858 1859 $db = 1 if exists $ENV{SS_DEBUG}; 1860 $db = 1 if exists $ENV{SSVNC_VENCRYPT_DEBUG}; 1861 1862 append_handshake("mode=$vmode\n"); 1863 1864 my $server_rfb = ""; 1865 #syswrite($sock, $rep, 250); 1866 for (my $i = 0; $i < 12; $i++) { 1867 my $c; 1868 sysread($sock, $c, 1); 1869 $server_rfb .= $c; 1870 print STDERR $c; 1871 } 1872 print STDERR "server_rfb: $server_rfb\n" if $db; 1873 append_handshake("server=$server_rfb"); 1874 1875 my $minor = ""; 1876 if ($server_rfb =~ /^RFB 003\.(\d+)/) { 1877 $minor = $1; 1878 } else { 1879 vdie; 1880 } 1881 my $viewer_rfb = "RFB 003.008\n"; 1882 if ($minor < 7) { 1883 vdie; 1884 } elsif ($minor == 7) { 1885 $viewer_rfb = "RFB 003.007\n"; 1886 } 1887 my $nsec; 1888 my $t1 = gettime(); 1889 my $t0 = gettime(); 1890 1891 syswrite($sock, $viewer_rfb, 12); 1892 sysread($sock, $nsec, 1); 1893 1894 $t1 = gettime(); 1895 $t1 = sprintf("%.6f", $t1 - $t0); 1896 1897 append_handshake("viewer=$viewer_rfb"); 1898 append_handshake("latency=$t1\n"); 1899 1900 vdie if $nsec eq ""; 1901 1902 $nsec = unpack("C", $nsec); 1903 1904 print STDERR "nsec: $nsec\n" if $db; 1905 vdie if $nsec eq 0 || $nsec > 100; 1906 1907 my %sectypes = (); 1908 1909 for (my $i = 0; $i < $nsec; $i++) { 1910 my $sec; 1911 sysread($sock, $sec, 1); 1912 vdie if $sec eq ""; 1913 $sec = unpack("C", $sec); 1914 print STDERR "sec: $sec\n" if $db; 1915 $sectypes{$sec} = 1; 1916 } 1917 1918 if (exists $sectypes{$rfbSecTypeVencrypt}) { 1919 print STDERR "found rfbSecTypeVencrypt\n" if $db; 1920 append_handshake("sectype=$rfbSecTypeVencrypt\n"); 1921 vencrypt_handshake($vmode, $db); 1922 } elsif (exists $sectypes{$rfbSecTypeAnonTls}) { 1923 print STDERR "found rfbSecTypeAnonTls\n" if $db; 1924 append_handshake("sectype=$rfbSecTypeAnonTls\n"); 1925 anontls_handshake($vmode, $db); 1926 } else { 1927 print STDERR "No supported sec-type found\n" if $db; 1928 vdie; 1929 } 1930} 1931 1932sub append_handshake { 1933 my $str = shift; 1934 if ($handshake_file) { 1935 if (open(HSF, ">>$handshake_file")) { 1936 print HSF $str; 1937 close HSF; 1938 } 1939 } 1940} 1941 1942sub do_vencrypt_viewer_bridge { 1943 my ($listen, $connect) = @_; 1944 print STDERR "\npproxy: starting vencrypt_viewer_bridge[$$]: $listen \-> $connect\n"; 1945 my $db = 0; 1946 my $backwards = 0; 1947 if ($listen < 0) { 1948 $backwards = 1; 1949 $listen = -$listen; 1950 } 1951 if ($handshake_file eq "") { 1952 die "pproxy: vencrypt_viewer_bridge[$$]: no SSVNC_PREDIGESTED_HANDSHAKE\n"; 1953 } 1954 my $listen_sock; 1955 my $maxtry = 12; 1956 my $sleep = 5; 1957 for (my $i=0; $i < $maxtry; $i++) { 1958 $listen_sock = IO::Socket::INET->new( 1959 Listen => 2, 1960 ReuseAddr => 1, 1961 LocalAddr => "127.0.0.1", 1962 LocalPort => $listen, 1963 Proto => "tcp" 1964 ); 1965 if (! $listen_sock) { 1966 if ($i < $maxtry - 1) { 1967 warn "pproxy: vencrypt_viewer_bridge[$$]: $!\n"; 1968 warn "Could not listen on port $listen, retrying in $sleep seconds... (Ctrl-C to quit)\n"; 1969 sleep $sleep; 1970 } 1971 } else { 1972 last; 1973 } 1974 } 1975 if (! $listen_sock) { 1976 die "pproxy: vencrypt_viewer_bridge[$$]: $!\n"; 1977 } 1978 print STDERR "pproxy: vencrypt_viewer_bridge[$$]: listening on port $listen\n\n"; 1979 my ($viewer_sock, $ip) = $listen_sock->accept(); 1980 my $err = $!; 1981 close $listen_sock; 1982 if (! $viewer_sock) { 1983 die "pproxy: vencrypt_viewer_bridge[$$]: $err\n"; 1984 } 1985 if ($ENV{PPROXY_LOOP_THYSELF_MASTER}) { 1986 my $sml = $ENV{SSVNC_MULTIPLE_LISTEN}; 1987 if ($sml ne "" && $sml ne "0") { 1988 setpgrp(0, 0); 1989 if (fork()) { 1990 close $viewer_sock; 1991 wait; 1992 exit 0; 1993 } 1994 if (fork()) { 1995 close $viewer_sock; 1996 exit 0; 1997 } 1998 setpgrp(0, 0); 1999 $parent = $$; 2000 } 2001 } 2002 print STDERR "vencrypt_viewer_bridge[$$]: viewer_sock $viewer_sock\n" if $db; 2003 2004 print STDERR "pproxy: vencrypt_viewer_bridge[$$]: connecting to 127.0.0.1:$connect\n"; 2005 my $server_sock = IO::Socket::INET->new( 2006 PeerAddr => "127.0.0.1", 2007 PeerPort => $connect, 2008 Proto => "tcp" 2009 ); 2010 print STDERR "vencrypt_viewer_bridge[$$]: server_sock $server_sock\n" if $db; 2011 if (! $server_sock) { 2012 my $err = $!; 2013 die "pproxy: vencrypt_viewer_bridge[$$]: $err\n"; 2014 } 2015 2016 if ($backwards) { 2017 print STDERR "vencrypt_viewer_bridge[$$]: reversing roles of viewer and server.\n"; 2018 my $t = $viewer_sock; 2019 $viewer_sock = $server_sock; 2020 $server_sock = $t; 2021 } 2022 2023 my %hs = (); 2024 my $dt = 0.2; 2025 my $slept = 0.0; 2026 while ($slept < 20.0) { 2027 select(undef, undef, undef, $dt); 2028 $slept += $dt; 2029 if (-f $handshake_file && open(HSF, "<$handshake_file")) { 2030 my $done = 0; 2031 %hs = (); 2032 my $str = ""; 2033 while (<HSF>) { 2034 print STDERR "vencrypt_viewer_bridge[$$]: $_" if $ENV{VENCRYPT_VIEWER_BRIDGE_DEBUG}; 2035 $str .= "vencrypt_viewer_bridge[$$]: $_"; 2036 chomp; 2037 if ($_ eq "done") { 2038 $done = 1; 2039 } else { 2040 my ($k, $v) = split(/=/, $_, 2); 2041 if ($k ne "" && $v ne "") { 2042 $hs{$k} = $v; 2043 } 2044 } 2045 } 2046 close HSF; 2047 if ($done) { 2048 print STDERR "\n" . $str; 2049 last; 2050 } 2051 } 2052 } 2053 if (! exists $hs{server}) { 2054 $hs{server} = "RFB 003.008"; 2055 } 2056 if (! exists $hs{sectype}) { 2057 unlink($handshake_file); 2058 die "pproxy: vencrypt_viewer_bridge[$$]: no sectype.\n"; 2059 } 2060 syswrite($viewer_sock, "$hs{server}\n", length($hs{server}) + 1); 2061 my $viewer_rfb = ""; 2062 for (my $i = 0; $i < 12; $i++) { 2063 my $c; 2064 sysread($viewer_sock, $c, 1); 2065 $viewer_rfb .= $c; 2066 print STDERR $c; 2067 } 2068 my $viewer_major = 3; 2069 my $viewer_minor = 8; 2070 if ($viewer_rfb =~ /RFB (\d+)\.(\d+)/) { 2071 $viewer_major = $1; 2072 $viewer_minor = $2; 2073 } 2074 my $u0 = pack("C", 0); 2075 my $u1 = pack("C", 1); 2076 my $u2 = pack("C", 2); 2077 if ($hs{sectype} == $rfbSecTypeAnonTls) { 2078 unlink($handshake_file); 2079 print STDERR "\npproxy: vencrypt_viewer_bridge[$$]: rfbSecTypeAnonTls\n"; 2080 if ($viewer_major > 3 || $viewer_minor >= 7) { 2081 ; # setup ok, proceed to xfer. 2082 } else { 2083 print STDERR "pproxy: vencrypt_viewer_bridge[$$]: faking RFB version 3.3 to viewer.\n"; 2084 my $n; 2085 sysread($server_sock, $n, 1); 2086 $n = unpack("C", $n); 2087 if ($n == 0) { 2088 die "pproxy: vencrypt_viewer_bridge[$$]: nsectypes == $n.\n"; 2089 } 2090 my %types; 2091 for (my $i = 0; $i < $n; $i++) { 2092 my $t; 2093 sysread($server_sock, $t, 1); 2094 $t = unpack("C", $t); 2095 $types{$t} = 1; 2096 } 2097 my $use = 1; # None 2098 if (exists $types{1}) { 2099 $use = 1; # None 2100 } elsif (exists $types{2}) { 2101 $use = 2; # VncAuth 2102 } else { 2103 die "pproxy: vencrypt_viewer_bridge[$$]: no valid sectypes" . join(",", keys %types) . "\n"; 2104 } 2105 2106 # send 4 bytes sectype to viewer: 2107 # (note this should be MSB, network byte order...) 2108 my $up = pack("C", $use); 2109 syswrite($viewer_sock, $u0, 1); 2110 syswrite($viewer_sock, $u0, 1); 2111 syswrite($viewer_sock, $u0, 1); 2112 syswrite($viewer_sock, $up, 1); 2113 # and tell server the one we selected: 2114 syswrite($server_sock, $up, 1); 2115 if ($use == 1) { 2116 # even None has security result, so read it here and discard it. 2117 my $sr = ""; 2118 sysread($server_sock, $sr, 4); 2119 } 2120 } 2121 } elsif ($hs{sectype} == $rfbSecTypeVencrypt) { 2122 print STDERR "\npproxy: vencrypt_viewer_bridge[$$]: rfbSecTypeVencrypt\n"; 2123 if (! exists $hs{subtype}) { 2124 unlink($handshake_file); 2125 die "pproxy: vencrypt_viewer_bridge[$$]: no subtype.\n"; 2126 } 2127 my $fake_type = "None"; 2128 my $plain = 0; 2129 my $sub_type = $hs{subtype}; 2130 if ($sub_type == $rfbVencryptTlsNone) { 2131 $fake_type = "None"; 2132 } elsif ($sub_type == $rfbVencryptTlsVnc) { 2133 $fake_type = "VncAuth"; 2134 } elsif ($sub_type == $rfbVencryptTlsPlain) { 2135 $fake_type = "None"; 2136 $plain = 1; 2137 } elsif ($sub_type == $rfbVencryptX509None) { 2138 $fake_type = "None"; 2139 } elsif ($sub_type == $rfbVencryptX509Vnc) { 2140 $fake_type = "VncAuth"; 2141 } elsif ($sub_type == $rfbVencryptX509Plain) { 2142 $fake_type = "None"; 2143 $plain = 1; 2144 } 2145 if ($plain) { 2146 if (!open(W, ">$handshake_file")) { 2147 unlink($handshake_file); 2148 die "pproxy: vencrypt_viewer_bridge[$$]: $handshake_file $!\n"; 2149 } 2150 print W <<"END"; 2151 2152 proc print_out {} { 2153 global user pass env 2154 2155 if [info exists env(SSVNC_UP_DEBUG)] { 2156 toplevel .b 2157 button .b.b -text "user=\$user pass=\$pass" -command {destroy .b} 2158 pack .b.b 2159 update 2160 tkwait window .b 2161 } 2162 2163 if [info exists env(SSVNC_UP_FILE)] { 2164 set fh "" 2165 catch {set fh [open \$env(SSVNC_UP_FILE) w]} 2166 if {\$fh != ""} { 2167 puts \$fh user=\$user\\npass=\$pass 2168 flush \$fh 2169 close \$fh 2170 return 2171 } 2172 } 2173 puts stdout user=\$user\\npass=\$pass 2174 flush stdout 2175 } 2176 2177 proc center_win {w} { 2178 update 2179 set W [winfo screenwidth \$w] 2180 set W [expr \$W + 1] 2181 wm geometry \$w +\$W+0 2182 update 2183 set x [expr [winfo screenwidth \$w]/2 - [winfo width \$w]/2] 2184 set y [expr [winfo screenheight \$w]/2 - [winfo height \$w]/2] 2185 2186 wm geometry \$w +\$x+\$y 2187 wm deiconify \$w 2188 update 2189 } 2190 2191 wm withdraw . 2192 2193 global env 2194 set up {} 2195 if [info exists env(SSVNC_UNIXPW)] { 2196 set rm 0 2197 set up \$env(SSVNC_UNIXPW) 2198 if [regexp {^rm:} \$up] { 2199 set rm 1 2200 regsub {^rm:} \$up {} up 2201 } 2202 if [file exists \$up] { 2203 set fh "" 2204 set f \$up 2205 catch {set fh [open \$up r]} 2206 if {\$fh != ""} { 2207 gets \$fh u 2208 gets \$fh p 2209 close \$fh 2210 set up "\$u@\$p" 2211 } 2212 if {\$rm} { 2213 catch {file delete \$f} 2214 } 2215 } 2216 } elseif [info exists env(SSVNC_VENCRYPT_USERPASS)] { 2217 set up \$env(SSVNC_VENCRYPT_USERPASS) 2218 } 2219 #puts stderr up=\$up 2220 if {\$up != ""} { 2221 if [regexp {@} \$up] { 2222 global user pass 2223 set user \$up 2224 set pass \$up 2225 regsub {@.*\$} \$user "" user 2226 regsub {^[^@]*@} \$pass "" pass 2227 print_out 2228 exit 2229 } 2230 } 2231 2232 wm title . {VeNCrypt Viewer Bridge User/Pass} 2233 2234 set user {} 2235 set pass {} 2236 2237 label .l -text {SSVNC VeNCrypt Viewer Bridge} 2238 2239 frame .f0 2240 frame .f0.fL 2241 label .f0.fL.la -text {Username: } 2242 label .f0.fL.lb -text {Password: } 2243 2244 pack .f0.fL.la .f0.fL.lb -side top 2245 2246 frame .f0.fR 2247 entry .f0.fR.ea -width 24 -textvariable user 2248 entry .f0.fR.eb -width 24 -textvariable pass -show * 2249 2250 pack .f0.fR.ea .f0.fR.eb -side top -fill x 2251 2252 pack .f0.fL -side left 2253 pack .f0.fR -side right -expand 1 -fill x 2254 2255 button .no -text Cancel -command {destroy .} 2256 button .ok -text Done -command {print_out; destroy .} 2257 2258 center_win . 2259 pack .l .f0 .no .ok -side top -fill x 2260 update 2261 wm deiconify . 2262 2263 bind .f0.fR.ea <Return> {focus .f0.fR.eb} 2264 bind .f0.fR.eb <Return> {print_out; destroy .} 2265 focus .f0.fR.ea 2266 2267 wm resizable . 1 0 2268 wm minsize . [winfo reqwidth .] [winfo reqheight .] 2269END 2270 close W; 2271 2272 #system("cat $handshake_file"); 2273 my $w = "wish"; 2274 if ($ENV{WISH}) { 2275 $w = $ENV{WISH}; 2276 } 2277 print STDERR "pproxy: vencrypt_viewer_bridge[$$]: prompt VencryptPlain user and passwd.\n"; 2278 my $res = ""; 2279 if (`uname` =~ /Darwin/) { 2280 my $mtmp = `mktemp /tmp/hsup.XXXXXX`; 2281 chomp $mtmp; 2282 system("env SSVNC_UP_FILE=$mtmp $w $handshake_file"); 2283 $res = `cat $mtmp`; 2284 unlink $mtmp; 2285 } else { 2286 $res = `$w $handshake_file`; 2287 } 2288 my $user = ""; 2289 my $pass = ""; 2290 if ($res =~ /user=(\S*)/) { 2291 $user = $1; 2292 } 2293 if ($res =~ /pass=(\S*)/) { 2294 $pass = $1; 2295 } 2296 print STDERR "pproxy: vencrypt_viewer_bridge[$$]: sending VencryptPlain user and passwd.\n"; 2297 my $ulen = pack("C", length($user)); 2298 my $plen = pack("C", length($pass)); 2299 # (note this should be MSB, network byte order...) 2300 syswrite($server_sock, $u0, 1); 2301 syswrite($server_sock, $u0, 1); 2302 syswrite($server_sock, $u0, 1); 2303 syswrite($server_sock, $ulen, 1); 2304 syswrite($server_sock, $u0, 1); 2305 syswrite($server_sock, $u0, 1); 2306 syswrite($server_sock, $u0, 1); 2307 syswrite($server_sock, $plen, 1); 2308 syswrite($server_sock, $user, length($user)); 2309 syswrite($server_sock, $pass, length($pass)); 2310 } 2311 unlink($handshake_file); 2312 2313 my $ft = 0; 2314 if ($fake_type eq "None") { 2315 $ft = 1; 2316 } elsif ($fake_type eq "VncAuth") { 2317 $ft = 2; 2318 } else { 2319 die "pproxy: vencrypt_viewer_bridge[$$]: unknown fake type: $fake_type\n"; 2320 } 2321 my $fp = pack("C", $ft); 2322 if ($viewer_major > 3 || $viewer_minor >= 7) { 2323 syswrite($viewer_sock, $u1, 1); 2324 syswrite($viewer_sock, $fp, 1); 2325 my $cr; 2326 sysread($viewer_sock, $cr, 1); 2327 $cr = unpack("C", $cr); 2328 if ($cr != $ft) { 2329 die "pproxy: vencrypt_viewer_bridge[$$]: client selected wrong type: $cr / $ft\n"; 2330 } 2331 } else { 2332 print STDERR "pproxy: vencrypt_viewer_bridge[$$]: faking RFB version 3.3 to viewer.\n"; 2333 # send 4 bytes sect type to viewer: 2334 # (note this should be MSB, network byte order...) 2335 syswrite($viewer_sock, $u0, 1); 2336 syswrite($viewer_sock, $u0, 1); 2337 syswrite($viewer_sock, $u0, 1); 2338 syswrite($viewer_sock, $fp, 1); 2339 if ($ft == 1) { 2340 # even None has security result, so read it here and discard it. 2341 my $sr = ""; 2342 sysread($server_sock, $sr, 4); 2343 } 2344 } 2345 } 2346 2347 $listen_handle = $viewer_sock; 2348 $sock = $server_sock; 2349 2350 xfer_both(); 2351} 2352' 2353 # ' 2354 # xpg_echo will expand \n \r, etc. 2355 # try to unset and then test for it. 2356 if type shopt > /dev/null 2>&1; then 2357 shopt -u xpg_echo >/dev/null 2>&1 2358 fi 2359 v='print STDOUT "abc\n";' 2360 echo "$v" > $tf 2361 chmod 700 $tf 2362 2363 lc=`wc -l $tf | awk '{print $1}'` 2364 if [ "X$lc" = "X1" ]; then 2365 echo "$cod" > $tf 2366 else 2367 printf "%s" "$cod" > $tf 2368 echo "" >> $tf 2369 fi 2370 # prime perl 2371 perl -e 'use IO::Socket::INET; select(undef, undef, undef, 0.01)' >/dev/null 2>&1 2372} 2373 2374# make_tcert is no longer invoked via the ssvnc gui (Listen mode). 2375# make_tcert is for testing only now via -mycert BUILTIN 2376make_tcert() { 2377 tcert="/tmp/ss_vnc_viewer_tcert${RANDOM}.$$" 2378 tcert=`mytmp "$tcert"` 2379 cat > $tcert <<END 2380-----BEGIN RSA PRIVATE KEY----- 2381MIIEowIBAAKCAQEAvkfXxb0wcxgrjV2ziFikjII+ze8iKcTBt47L0GM/c21efelN 2382+zZpJUUXLu4zz8Ryq8Q+sQgfNy7uTOpN9bUUaOk1TnD7gaDQnQWiNHmqbW2kL+DS 2383OKngJVPo9dETAS8hf7+D1e1DBZxjTc1a4RQqWJixwpYj99ixWzu8VC2m/xXsjvOs 2384jp4+DLBB490nbkwvstmhmiWm1CmI5O5xOkgioVNQqHvQMdVKOSz9PpbjvZiRX1Uo 2385qoMrk+2NOqwP90TB35yPASXb9zXKpO7DLhkube+yYGf+yk46aD707L07Eb7cosFP 2386S84vNZ9gX7rQ0UOwm5rYA/oZTBskgaqhtIzkLwIDAQABAoIBAD4ot/sXt5kRn0Ca 2387CIkU9AQWlC+v28grR2EQW9JiaZrqcoDNUzUqbCTJsi4ZkIFh2lf0TsqELbZYNW6Y 23886AjJM7al4E0UqYSKJTv2WCuuRxdiRs2BMwthqyBmjeanev7bB6V0ybt7u3Y8xU/o 2389MrTuYnr4vrEjXPKdLirwk7AoDbKsRXHSIiHEIBOq1+dUQ32t36ukdnnza4wKDLZc 2390PKHiCdCk/wOGhuDlxD6RspqUAlRnJ8/aEhrgWxadFXw1hRhRsf/v1shtB0T3DmTe 2391Jchjwyiw9mryb9JZAcKxW+fUc4EVvj6VdQGqYInQJY5Yxm5JAlVQUJicuuJEvn6A 2392rj5osQECgYEA552CaHpUiFlB4HGkjaH00kL+f0+gRF4PANCPk6X3UPDVYzKnzmuu 2393yDvIdEETGFWBwoztUrOOKqVvPEQ+kBa2+DWWYaERZLtg2cI5byfDJxQ3ldzilS3J 23941S3WgCojqcsG/hlxoQJ1dZFanUy/QhUZ0B+wlC+Zp1Q8AyuGQvhHp68CgYEA0lBI 2395eqq2GGCdJuNHMPFbi8Q0BnX55LW5C1hWjhuYiEkb3hOaIJuJrqvayBlhcQa2cGqp 2396uP34e9UCfoeLgmoCQ0b4KpL2NGov/mL4i8bMgog4hcoYuIi3qxN18vVR14VKEh4U 2397RLk0igAYPU+IK2QByaQlBo9OSaKkcfm7U1/pK4ECgYAxr6VpGk0GDvfF2Tsusv6d 2398GIgV8ZP09qSLTTJvvxvF/lQYeqZq7sjI5aJD5i3de4JhpO/IXQJzfZfWOuGc8XKA 23993qYK/Y2IqXXGYRcHFGWV/Y1LFd55mCADHlk0l1WdOBOg8P5iRu/Br9PbiLpCx9oI 2400vrOXpnp03eod1/luZmqguwKBgQCWFRSj9Q7ddpSvG6HCG3ro0qsNsUMTI1tZ7UBX 2401SPogx4tLf1GN03D9ZUZLZVFUByZKMtPLX/Hi7K9K/A9ikaPrvsl6GEX6QYzeTGJx 24023Pw0amFrmDzr8ySewNR6/PXahxPEuhJcuI31rPufRRI3ZLah3rFNbRbBFX+klkJH 2403zTnoAQKBgDbUK/aQFGduSy7WUT7LlM3UlGxJ2sA90TQh4JRQwzur0ACN5GdYZkqM 2404YBts4sBJVwwJoxD9OpbvKu3uKCt41BSj0/KyoBzjT44S2io2tj1syujtlVUsyyBy 2405/ca0A7WBB8lD1D7QMIhYUm2O9kYtSCLlUTHt5leqGaRG38DqlX36 2406-----END RSA PRIVATE KEY----- 2407-----BEGIN CERTIFICATE----- 2408MIIDzDCCArQCCQDSzxzxqhyqLzANBgkqhkiG9w0BAQQFADCBpzELMAkGA1UEBhMC 2409VVMxFjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxDzANBgNVBAcTBkJvc3RvbjETMBEG 2410A1UEChMKTXkgQ29tcGFueTEcMBoGA1UECxMTUHJvZHVjdCBEZXZlbG9wbWVudDEZ 2411MBcGA1UEAxMQd3d3Lm5vd2hlcmUubm9uZTEhMB8GCSqGSIb3DQEJARYSYWRtaW5A 2412bm93aGVyZS5ub25lMB4XDTA3MDMyMzE4MDc0NVoXDTI2MDUyMjE4MDc0NVowgacx 2413CzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNldHRzMQ8wDQYDVQQHEwZC 2414b3N0b24xEzARBgNVBAoTCk15IENvbXBhbnkxHDAaBgNVBAsTE1Byb2R1Y3QgRGV2 2415ZWxvcG1lbnQxGTAXBgNVBAMTEHd3dy5ub3doZXJlLm5vbmUxITAfBgkqhkiG9w0B 2416CQEWEmFkbWluQG5vd2hlcmUubm9uZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC 2417AQoCggEBAL5H18W9MHMYK41ds4hYpIyCPs3vIinEwbeOy9BjP3NtXn3pTfs2aSVF 2418Fy7uM8/EcqvEPrEIHzcu7kzqTfW1FGjpNU5w+4Gg0J0FojR5qm1tpC/g0jip4CVT 24196PXREwEvIX+/g9XtQwWcY03NWuEUKliYscKWI/fYsVs7vFQtpv8V7I7zrI6ePgyw 2420QePdJ25ML7LZoZolptQpiOTucTpIIqFTUKh70DHVSjks/T6W472YkV9VKKqDK5Pt 2421jTqsD/dEwd+cjwEl2/c1yqTuwy4ZLm3vsmBn/spOOmg+9Oy9OxG+3KLBT0vOLzWf 2422YF+60NFDsJua2AP6GUwbJIGqobSM5C8CAwEAATANBgkqhkiG9w0BAQQFAAOCAQEA 2423vGomHEp6TVU83X2EBUgnbOhzKJ9u3fOI/Uf5L7p//Vxqow7OR1cguzh/YEzmXOIL 2424ilMVnzX9nj/bvcLAuqEP7MR1A8f4+E807p/L/Sf49BiCcwQq5I966sGKYXjkve+T 24252GTBNwMSq+5kLSf6QY8VZI+qnrAudEQMeJByQhTZZ0dH8Njeq8EGl9KUio+VWaiW 2426CQK6xJuAvAHqa06OjLmwu1fYD4GLGSrOIiRVkSXV8qLIUmzxdJaIRznkFWsrCEKR 2427wAH966SAOvd2s6yOHMvyDRIL7WHxfESB6rDHsdIW/yny1fBePjv473KrxyXtbz7I 2428dMw1yW09l+eEo4A7GzwOdw== 2429-----END CERTIFICATE----- 2430END 2431 chmod 600 $tcert 2432 echo "$tcert" 2433} 2434 2435Kecho() { 2436 NO_KECHO=1 2437 if [ "X$USER" = "Xrunge" -a "X$NO_KECHO" = "X" ]; then 2438 echo "dbg: $*" 2439 fi 2440} 2441 2442NHAFL_warning() { 2443 echo "" 2444 echo "** Warning: For the proxy: $proxy" 2445 echo "** Warning: the ssh(1) option: $ssh_NHAFL" 2446 echo "** Warning: will be used to avoid frequent 'ssh key has changed for localhost'" 2447 echo "** Warning: dialogs and connection failures (for example, ssh will exit asking" 2448 echo "** Warning: you to manually remove a key from ~/.ssh/known_hosts.)" 2449 echo "** Warning: " 2450 echo "** Warning: This decreases security: a Man-In-The-Middle attack is possible." 2451 echo "** Warning: For chained ssh connections the first ssh leg is secure but the" 2452 echo "** Warning: 2nd ssh leg is vulnerable. For an ssh connection going through" 2453 echo "** Warning: a HTTP or SOCKS proxy the ssh connection is vulnerable." 2454 echo "** Warning: " 2455 echo "** Warning: You can set the SSVNC_SSH_LOCALHOST_AUTH=1 env. var. to disable" 2456 echo "** Warning: using the NoHostAuthenticationForLocalhost=yes ssh option." 2457 echo "** Warning: " 2458 echo "** Warning: A better solution is to configure (in the SSVNC GUI) the setting:" 2459 echo "** Warning: 'Options -> Advanced -> Private SSH KnownHosts file' (or set" 2460 echo "** Warning: SSVNC_KNOWN_HOSTS_FILE directly) to a per-connection known hosts" 2461 echo "** Warning: file. That file holds the 'localhost' cert for this specific" 2462 echo "** Warning: connection. This yields a both secure and convenient solution." 2463 echo "" 2464} 2465 2466space_expand() { 2467 str=`echo "$1" | sed -e 's/%SPACE/ /g' -e 's/%TAB/\t/g'` 2468 echo "$str" 2469} 2470 2471# handle ssh case: 2472# 2473if [ "X$use_ssh" = "X1" ]; then 2474 # 2475 # USING SSH 2476 # 2477 ssh_port="22" 2478 ssh_host="$host" 2479 vnc_host="$localhost" 2480 ssh_UKHF="" 2481 localhost_extra="" 2482 # let user override ssh via $SSH 2483 ssh=${SSH:-"ssh -x"} 2484 2485 sshword=`echo "$ssh" | awk '{print $1}'` 2486 if [ "X$sshword" != "X" ]; then 2487 if [ -x "$sshword" ]; then 2488 : 2489 elif type "$sshword" > /dev/null 2>&1; then 2490 : 2491 else 2492 echo "" 2493 echo "*********************************************************" 2494 echo "** Problem finding the SSH command '$sshword': **" 2495 echo "" 2496 type "$sshword" 2497 echo "" 2498 echo "** Perhaps you need to install the SSH client package. **" 2499 echo "*********************************************************" 2500 echo "" 2501 sleep 5 2502 fi 2503 fi 2504 2505 ssh_NHAFL="-o NoHostAuthenticationForLocalhost=yes" 2506 if [ "X$SSVNC_SSH_LOCALHOST_AUTH" = "X1" ]; then 2507 ssh_NHAFL="" 2508 fi 2509 if [ "X$SSVNC_KNOWN_HOSTS_FILE" != "X" ]; then 2510 ssh_NHAFL="" 2511 2512 ssh_UKHF="-o UserKnownHostsFile=$SSVNC_KNOWN_HOSTS_FILE" 2513 ssh_args="$ssh_args $ssh_UKHF" 2514 if [ ! -f "$SSVNC_KNOWN_HOSTS_FILE" ]; then 2515 touch "$SSVNC_KNOWN_HOSTS_FILE" >/dev/null 2>&1 2516 fi 2517 chmod 600 "$SSVNC_KNOWN_HOSTS_FILE" >/dev/null 2>&1 2518 fi 2519 did_ssh_NHAFL="" 2520 2521 if [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" ]; then 2522 SSVNC_LIM_ACCEPT_PRELOAD="$SSVNC_BASEDIR/$SSVNC_UNAME/$SSVNC_LIM_ACCEPT_PRELOAD" 2523 fi 2524 if [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" ]; then 2525 echo "" 2526 echo "SSVNC_LIM_ACCEPT_PRELOAD=$SSVNC_LIM_ACCEPT_PRELOAD" 2527 fi 2528 2529 if [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" -a -f "$SSVNC_LIM_ACCEPT_PRELOAD" ]; then 2530 plvar=LD_PRELOAD 2531 if uname | grep Darwin >/dev/null; then 2532 plvar="DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES" 2533 fi 2534 ssh="env $plvar=$SSVNC_LIM_ACCEPT_PRELOAD $ssh" 2535 else 2536 SSVNC_LIM_ACCEPT_PRELOAD="" 2537 fi 2538 2539 ssh_vencrypt_proxy="" 2540 # We handle vencrypt for SSH+SSL mode. 2541 if echo "$proxy" | grep 'vencrypt://' > /dev/null; then 2542 proxynew="" 2543 for part in `echo "$proxy" | tr ',' ' '` 2544 do 2545 if echo "$part" | egrep -i '^vencrypt://' > /dev/null; then 2546 ssh_vencrypt_proxy=$part 2547 else 2548 if [ "X$proxynew" = "X" ]; then 2549 proxynew="$part" 2550 else 2551 proxynew="$proxynew,$part" 2552 fi 2553 fi 2554 done 2555 proxy=$proxynew 2556 fi 2557 Kecho ssh_vencrypt_proxy=$ssh_vencrypt_proxy 2558 2559 # note that user must supply http:// for web proxy in SSH and SSH+SSL. 2560 # No xxxx:// implies ssh server+port. 2561 # 2562 if echo "$proxy" | egrep '(http|https|socks|socks4|socks5)://' > /dev/null; then 2563 # Handle Web or SOCKS proxy(ies) for the initial connect. 2564 Kecho host=$host 2565 Kecho port=$port 2566 pproxy="" 2567 sproxy1="" 2568 sproxy_rest="" 2569 for part in `echo "$proxy" | tr ',' ' '` 2570 do 2571 Kecho proxy_part=$part 2572 if [ "X$part" = "X" ]; then 2573 continue 2574 elif echo "$part" | egrep -i '^(http|https|socks|socks4|socks5)://' > /dev/null; then 2575 pproxy="$pproxy,$part" 2576 else 2577 if [ "X$sproxy1" = "X" ]; then 2578 sproxy1="$part" 2579 else 2580 sproxy_rest="$sproxy_rest,$part" 2581 fi 2582 fi 2583 done 2584 pproxy=`echo "$pproxy" | sed -e 's/^,,*//' -e 's/,,*/,/g'` 2585 sproxy_rest=`echo "$sproxy_rest" | sed -e 's/^,,*//' -e 's/,,*/,/g'` 2586 2587 Kecho pproxy=$pproxy 2588 Kecho sproxy1=$sproxy1 2589 Kecho sproxy_rest=$sproxy_rest 2590 2591 sproxy1_host="" 2592 sproxy1_port="" 2593 sproxy1_user="" 2594 2595 if [ "X$sproxy1" != "X" ]; then 2596 # XXX fix ipv6 ip adder here and below. 2597 sproxy1_host=`echo "$sproxy1" | awk -F: '{print $1}'` 2598 sproxy1_user=`echo "$sproxy1_host" | awk -F@ '{print $1}'` 2599 sproxy1_host=`echo "$sproxy1_host" | awk -F@ '{print $2}'` 2600 if [ "X$sproxy1_host" = "X" ]; then 2601 sproxy1_host=$sproxy1_user 2602 sproxy1_user="" 2603 else 2604 sproxy1_user="${sproxy1_user}@" 2605 fi 2606 sproxy1_port=`echo "$sproxy1" | awk -F: '{print $2}'` 2607 if [ "X$sproxy1_port" = "X" ]; then 2608 sproxy1_port="22" 2609 fi 2610 else 2611 sproxy1_host=`echo "$host" | awk -F: '{print $1}'` 2612 sproxy1_user=`echo "$sproxy1_host" | awk -F@ '{print $1}'` 2613 sproxy1_host=`echo "$sproxy1_host" | awk -F@ '{print $2}'` 2614 if [ "X$sproxy1_host" = "X" ]; then 2615 sproxy1_host=$sproxy1_user 2616 sproxy1_user="" 2617 else 2618 sproxy1_user="${sproxy1_user}@" 2619 fi 2620 sproxy1_port=`echo "$host" | awk -F: '{print $2}'` 2621 if [ "X$sproxy1_port" = "X" ]; then 2622 sproxy1_port="22" 2623 fi 2624 fi 2625 2626 Kecho sproxy1_host=$sproxy1_host 2627 Kecho sproxy1_port=$sproxy1_port 2628 Kecho sproxy1_user=$sproxy1_user 2629 2630 ptmp="/tmp/ss_vncviewer_ssh${RANDOM}.$$.pl" 2631 ptmp=`mytmp "$ptmp"` 2632 PPROXY_REMOVE=1; export PPROXY_REMOVE 2633 proxy=$pproxy 2634 port_save=$port 2635 host_save=$host 2636 if [ "X$sproxy1_host" != "X" ]; then 2637 host=$sproxy1_host 2638 fi 2639 if [ "X$sproxy1_port" != "X" ]; then 2640 port=$sproxy1_port 2641 fi 2642 host=`echo "$host" | sed -e 's/^.*@//'` 2643 port=`echo "$port" | sed -e 's/^.*://'` 2644 pcode "$ptmp" 2645 port=$port_save 2646 host=$host_save 2647 2648 nd=`findfree 6600` 2649 PPROXY_LISTEN=$nd; export PPROXY_LISTEN 2650 # XXX no reverse forever PPROXY_LOOP_THYSELF ... 2651 $ptmp & 2652 sleep 1 2653 if [ "X$ssh_NHAFL" != "X" -a "X$did_ssh_NHAFL" != "X1" ]; then 2654 NHAFL_warning 2655 ssh_args="$ssh_args $ssh_NHAFL" 2656 did_ssh_NHAFL=1 2657 fi 2658 sleep 1 2659 if [ "X$sproxy1" = "X" ]; then 2660 u="" 2661 if echo "$host" | grep '@' > /dev/null; then 2662 u=`echo "$host" | sed -e 's/@.*$/@/'` 2663 fi 2664 2665 proxy="${u}$localhost:$nd" 2666 else 2667 proxy="${sproxy1_user}$localhost:$nd" 2668 fi 2669 localhost_extra=".2" 2670 if [ "X$sproxy_rest" != "X" ]; then 2671 proxy="$proxy,$sproxy_rest" 2672 fi 2673 Kecho proxy=$proxy 2674 fi 2675 2676 if echo "$proxy" | grep "," > /dev/null; then 2677 2678 proxy1=`echo "$proxy" | awk -F, '{print $1}'` 2679 proxy2=`echo "$proxy" | awk -F, '{print $2}'` 2680 2681 # user1@gw1.com:port1,user2@ws2:port2 2682 ssh_host1=`echo "$proxy1" | awk -F: '{print $1}'` 2683 ssh_port1=`echo "$proxy1" | awk -F: '{print $2}'` 2684 if [ "X$ssh_port1" != "X" ]; then 2685 ssh_port1="-p $ssh_port1" 2686 fi 2687 ssh_host2=`echo "$proxy2" | awk -F: '{print $1}'` 2688 ssh_user2=`echo "$ssh_host2" | awk -F@ '{print $1}'` 2689 ssh_host2=`echo "$ssh_host2" | awk -F@ '{print $2}'` 2690 if [ "X$ssh_host2" = "X" ]; then 2691 ssh_host2=$ssh_user2 2692 ssh_user2="" 2693 else 2694 ssh_user2="${ssh_user2}@" 2695 fi 2696 ssh_port2=`echo "$proxy2" | awk -F: '{print $2}'` 2697 if [ "X$ssh_port2" = "X" ]; then 2698 ssh_port2="22" 2699 fi 2700 proxport=`findfree 3500` 2701 if [ "X$ssh_NHAFL" != "X" -a "X$did_ssh_NHAFL" != "X1" ]; then 2702 NHAFL_warning 2703 did_ssh_NHAFL=1 2704 sleep 1 2705 fi 2706 echo 2707 echo "Running 1st ssh proxy:" 2708 ukhf="" 2709 if [ "X$ssh_UKHF" != "X" ]; then 2710 ukhf="$ssh_UKHF$localhost_extra" 2711 fi 2712 if echo "$ssh_host1" | grep '%' > /dev/null; then 2713 uath=`space_expand "$ssh_host1"` 2714 else 2715 uath="$ssh_host1" 2716 fi 2717 echo "$ssh -f -x $ssh_port1 $targ -e none $ssh_NHAFL $ukhf -L $proxport:$ssh_host2:$ssh_port2 \"$uath\" \"sleep 30\"" 2718 echo "" 2719 $ssh -f -x $ssh_port1 $targ -e none $ssh_NHAFL $ukhf -L $proxport:$ssh_host2:$ssh_port2 "$uath" "sleep 30" 2720 ssh_args="$ssh_args $ssh_NHAFL" 2721 sleep 1 2722 stty sane 2723 proxy="${ssh_user2}$localhost:$proxport" 2724 fi 2725 2726 if [ "X$proxy" != "X" ]; then 2727 ssh_port=`echo "$proxy" | awk -F: '{print $2}'` 2728 if [ "X$ssh_port" = "X" ]; then 2729 ssh_port="22" 2730 fi 2731 ssh_host=`echo "$proxy" | awk -F: '{print $1}'` 2732 vnc_host="$host" 2733 fi 2734 2735 echo "" 2736 echo "Running ssh:" 2737 sz=`echo "$ssh_cmd" | wc -c` 2738 if [ "$sz" -gt 300 ]; then 2739 info="..." 2740 else 2741 info="$ssh_cmd" 2742 fi 2743 2744 C="" 2745 if [ "X$SS_VNCVIEWER_USE_C" != "X" ]; then 2746 C="-C" 2747 fi 2748 2749 getport="" 2750 teeport="" 2751 if echo "$ssh_cmd" | egrep "(PORT=|P=) " > /dev/null; then 2752 getport=1 2753 if echo "$ssh_cmd" | egrep "P= " > /dev/null; then 2754 teeport=1 2755 fi 2756 2757 PORT="" 2758 ssh_cmd=`echo "$ssh_cmd" | sed -e 's/PORT=[ ]*//' -e 's/P=//'` 2759 SSVNC_NO_ENC_WARN=1 2760 if [ "X$use_sshssl" = "X" ]; then 2761 direct_connect=1 2762 fi 2763 fi 2764 if [ "X$getport" != "X" ]; then 2765 ssh_redir="-D ${use}" 2766 elif [ "X$reverse" = "X" ]; then 2767 ssh_redir="-L ${use}:${vnc_host}:${port}" 2768 else 2769 ssh_redir="-R ${port}:${vnc_host}:${use}" 2770 fi 2771 pmark=`sh -c 'echo $$'` 2772 2773 # the -t option actually speeds up typing response via VNC!! 2774 if [ "X$ssh_port" = "X22" ]; then 2775 ssh_port="" 2776 else 2777 ssh_port="-p $ssh_port" 2778 fi 2779 2780 if echo "$ssh_host" | grep '%' > /dev/null; then 2781 uath=`space_expand "$ssh_host"` 2782 else 2783 uath="$ssh_host" 2784 fi 2785 if [ "X$SS_VNCVIEWER_SSH_ONLY" != "X" ]; then 2786 echo "$ssh -x $ssh_port $targ $C $ssh_args \"$uath\" \"$info\"" 2787 echo "" 2788 $ssh -x $ssh_port $targ $C $ssh_args "$uath" "$ssh_cmd" 2789 exit $? 2790 2791 elif [ "X$SS_VNCVIEWER_NO_F" != "X" ]; then 2792 echo "$ssh -x $ssh_port $targ $C $ssh_redir $ssh_args \"$uath\" \"$info\"" 2793 echo "" 2794 $ssh -x $ssh_port $targ $C $ssh_redir $ssh_args "$uath" "$ssh_cmd" 2795 rc=$? 2796 2797 elif [ "X$getport" != "X" ]; then 2798 tport=/tmp/ss_vncviewer_tport${RANDOM}.$$ 2799 tport=`mytmp "$tport"` 2800 tport2=/tmp/ss_vncviewer_tport2${RANDOM}.$$ 2801 tport2=`mytmp "$tport2"` 2802 2803 if [ "X$rsh" != "X1" ]; then 2804 if echo "$ssh_cmd" | grep "sudo " > /dev/null; then 2805 echo "" 2806 echo "Initial ssh with 'sudo id' to prime sudo so hopefully the next one" 2807 echo "will require no password..." 2808 echo "" 2809 targ="-t" 2810 $ssh -x $ssh_port $targ $ssh_args "$uath" "sudo id; tty" 2811 echo "" 2812 fi 2813 echo "$ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args \"$uath\" \"$info\"" 2814 echo "" 2815 $ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args "$uath" "$ssh_cmd" > $tport 2> $tport2 2816 if [ "X$teeport" = "X1" ]; then 2817 tail -f $tport 1>&2 & 2818 tail_pid=$! 2819 tail -f $tport2 1>&2 & 2820 tail_pid2=$! 2821 fi 2822 rc=$? 2823 else 2824 rsh_setup 2825 echo "rsh $ul \"$ssh_host\" \"$ssh_cmd\"" 2826 echo "" 2827 rsh $ul "$ssh_host" "$ssh_cmd" > $tport & 2828 sleep 1 2829 rc=0 2830 fi 2831 2832 if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then 2833 echo "sleep $SSVNC_EXTRA_SLEEP" 2834 sleep $SSVNC_EXTRA_SLEEP 2835 fi 2836 2837 stty sane 2838 i=0 2839 if type perl > /dev/null 2>&1; then 2840 imax=50 2841 sleepit="perl -e 'select(undef, undef, undef, 0.20)'" 2842 else 2843 imax=10 2844 sleepit="sleep 1" 2845 fi 2846 while [ $i -lt $imax ]; do 2847 #echo $sleepit 2848 eval $sleepit 2849 PORT=`grep "^PORT=" $tport | tr '\r' ' ' | head -n 1 | sed -e 's/PORT=//' -e 's/\r//g' -e 's/ *$//'` 2850 if echo "$PORT" | grep '^[0-9][0-9]*$' > /dev/null; then 2851 break 2852 fi 2853 vnss=`sed -e 's/\r//g' $tport $tport2 | egrep -i '^(New.* desktop is|A VNC server is already running).*:[0-9[0-9]*$' | head -n 1 | awk '{print $NF}'` 2854 if [ "X$vnss" != "X" ]; then 2855 PORT=`echo "$vnss" | awk -F: '{print $2}'` 2856 if echo "$PORT" | grep '^[0-9][0-9]*$' > /dev/null; then 2857 if [ $PORT -lt 100 ]; then 2858 PORT=`expr $PORT + 5900` 2859 fi 2860 fi 2861 if echo "$PORT" | grep '^[0-9][0-9]*$' > /dev/null; then 2862 vnss=`sed -e 's/\r//g' $tport | egrep -i '^(New.* desktop is|A VNC server is already running).*:[0-9[0-9]*$' | head -n 1` 2863 echo "vncserver string: $vnss" 1>&2 2864 break 2865 fi 2866 fi 2867 i=`expr $i + 1` 2868 done 2869 2870 echo "found: PORT='$PORT'" 1>&2 2871 lh6="" 2872 if [ "X$SSVNC_PORT_IPV6" != "X" ]; then 2873 lh6=1 2874 elif egrep 'Info: listening on IPv6 only|Info: listening only on IPv6' $tport > /dev/null; then 2875 lh6=1 2876 fi 2877 if [ "X$lh6" = "X1" ]; then 2878 echo "set SOCKS5 localhost to ::1" 1>&2 2879 fi 2880 rm -f $tport $tport2 2881 if [ "X$rsh" = "X1" ]; then 2882 rsh_viewer "$@" 2883 exit $? 2884 fi 2885 PPROXY_SOCKS=5 2886 if [ "X$SSVNC_SOCKS5" != "X" ]; then 2887 PPROXY_SOCKS=5 2888 elif [ "X$SSVNC_SOCKS4" != "X" ]; then 2889 PPROXY_SOCKS=1 2890 fi 2891 export PPROXY_SOCKS 2892 if [ "X$lh6" = "X" ]; then 2893 host="$localhost" 2894 else 2895 host="::1" 2896 fi 2897 port="$PORT" 2898 proxy="$localhost:$use" 2899 2900 else 2901 if [ "X$rsh" != "X1" ]; then 2902 echo "$ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args \"$uath\" \"$info\"" 2903 echo "" 2904 $ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args "$uath" "$ssh_cmd" 2905 rc=$? 2906 else 2907 rsh_setup 2908 echo "rsh $ul \"$ssh_host\" \"$ssh_cmd\"" 2909 echo "" 2910 rsh $ul "$ssh_host" "$ssh_cmd" & 2911 sleep 1 2912 PORT=$port 2913 rsh_viewer "$@" 2914 exit $? 2915 fi 2916 fi 2917 2918 if [ "$rc" != "0" ]; then 2919 echo "" 2920 echo "ssh to \"$uath\" failed." 2921 exit 1 2922 fi 2923 stty sane 2924 2925 c=0 2926 pssh="" 2927 while [ $c -lt 40 ] 2928 do 2929 p=`expr $pmark + $c` 2930 pout=`ps -p "$p" 2>/dev/null | grep -v '^[ ]*PID' | sed -e 's/-L.*$//' -e 's/-x .*$//'` 2931 if echo "$pout" | grep "ssh" > /dev/null; then 2932 if echo "$pout" | egrep -i 'ssh.*(-add|-agent|-ask|-keygen|-argv0|vnc)' >/dev/null; then 2933 : 2934 elif echo "$pout" | egrep -i 'scp|sshd' >/dev/null; then 2935 : 2936 else 2937 pssh=$p 2938 break 2939 fi 2940 fi 2941 c=`expr $c + 1` 2942 done 2943 if [ "X$getport" != "X" ]; then 2944 : 2945 elif [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" ] ; then 2946 sleep 2 2947 elif [ "X$ssh_cmd" = "Xsleep $ssh_sleep" ] ; then 2948 #echo T sleep 1 2949 sleep 1 2950 elif echo "$ssh_cmd" | grep '^sleep ' >/dev/null; then 2951 #echo T sleep 2 2952 sleep 2 2953 else 2954 # let any command get started a bit. 2955 #echo T sleep 5 2956 sleep 5 2957 fi 2958 echo "" 2959 #reset 2960 stty sane 2961 if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then 2962 echo "sleep $SSVNC_EXTRA_SLEEP" 2963 sleep $SSVNC_EXTRA_SLEEP 2964 fi 2965 echo "ssh_pid='$pssh'"; echo 2966 if [ "X$use_sshssl" = "X" -a "X$getport" = "X" ]; then 2967 if [ "X$SSVNC_EXTRA_COMMAND" != "X" ]; then 2968 (sh -c "$SSVNC_EXTRA_COMMAND") & 2969 echo "($SSVNC_EXTRA_COMMAND) &"; echo 2970 fi 2971 echo "Running viewer:" 2972 2973 trap "final" 0 2 15 2974 if [ "X$reverse" = "X" ]; then 2975 echo "$VNCVIEWERCMD" "$@" $localhost:$N 2976 echo "" 2977 $VNCVIEWERCMD "$@" $localhost:$N 2978 if [ $? != 0 ]; then 2979 echo "vncviewer command failed: $?" 2980 if [ "X$secondtry" = "X1" ]; then 2981 sleep 2 2982 $VNCVIEWERCMD "$@" $localhost:$N 2983 fi 2984 fi 2985 else 2986 echo "" 2987 echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode." 2988 echo "" 2989 N2=$N 2990 if [ "X$VNCVIEWER_IS_REALVNC4" = "X1" ]; then 2991 N2=`echo "$N2" | sed -e 's/://g'` 2992 if [ $N2 -le 200 ]; then 2993 N2=`expr $N2 + 5500` 2994 fi 2995 fi 2996 echo "$VNCVIEWERCMD" "$@" -listen $N2 2997 echo "" 2998 $VNCVIEWERCMD "$@" -listen $N2 2999 fi 3000 3001 exit $? 3002 else 3003 use2=`findfree 5960` 3004 host0=$host 3005 port0=$port 3006 host=$localhost 3007 port=$use 3008 use=$use2 3009 N=`expr $use - 5900` 3010 if [ "X$getport" != "X" ]; then 3011 host="$host0" 3012 port="$port0" 3013 else 3014 proxy="" 3015 fi 3016 if [ "X$ssh_vencrypt_proxy" != "X" ]; then 3017 ssh_vencrypt_proxy="vencrypt://$host:$port" 3018 if [ "X$proxy" = "X" ]; then 3019 proxy=$ssh_vencrypt_proxy 3020 else 3021 proxy="$proxy,$ssh_vencrypt_proxy" 3022 fi 3023 Kecho "proxy_now=$proxy" 3024 unset PPROXY_LISTEN 3025 fi 3026 fi 3027fi 3028 3029if [ "X$stunnel_set_here" = "X1" -a "X$showcert" = "X" ]; then 3030 if type $STUNNEL > /dev/null 2>&1; then 3031 : 3032 else 3033 echo "" 3034 echo "***************************************************************" 3035 echo "** Problem finding the Stunnel command '$STUNNEL': **" 3036 echo "" 3037 type $STUNNEL 3038 echo "" 3039 echo "** Perhaps you need to install the stunnel/stunnel4 package. **" 3040 echo "***************************************************************" 3041 echo "" 3042 sleep 5 3043 fi 3044fi 3045 3046# create the stunnel config file: 3047if [ "X$verify" != "X" ]; then 3048 if [ -d $verify ]; then 3049 verify="CApath = $verify" 3050 else 3051 verify="CAfile = $verify" 3052 fi 3053 verify="$verify 3054verify = 2" 3055fi 3056if [ "X$SSVNC_STUNNEL_VERIFY3" != "X" ]; then 3057 verify=`echo "$verify" | sed -e 's/verify = 2/verify = 3/'` 3058fi 3059if [ "X$mycert" != "X" ]; then 3060 cert="cert = $mycert" 3061fi 3062if [ "X$crl" != "X" ]; then 3063 if [ -d $crl ]; then 3064 crl="CRLpath = $crl" 3065 else 3066 crl="CRLfile = $crl" 3067 fi 3068fi 3069 3070if [ "X$showcert" = "X1" ]; then 3071 if [ "X$have_uvnc_dsm_helper_showcert" = "X1" ]; then 3072 : 3073 elif [ "X$SSVNC_NO_IPV6_PROXY" != "X" ]; then 3074 : 3075 elif [ "X$ipv6" = "X1" -a "X$proxy" = "X" ]; then 3076 proxy="ipv6://$host:$port" 3077 fi 3078fi 3079 3080if [ "X$direct_connect" != "X" -a "X$STUNNEL_LISTEN" != "X" ]; then 3081 proxy=reverse_direct 3082fi 3083 3084ptmp="" 3085if [ "X$proxy" != "X" ]; then 3086 ptmp="/tmp/ss_vncviewer${RANDOM}.$$.pl" 3087 ptmp=`mytmp "$ptmp"` 3088 PPROXY_REMOVE=1; export PPROXY_REMOVE 3089 pcode "$ptmp" 3090 if [ "X$showcert" != "X1" -a "X$direct_connect" = "X" ]; then 3091 if uname | egrep 'Darwin|SunOS' >/dev/null; then 3092 vout=`echo "$proxy" | grep -i vencrypt` 3093 if [ "X$vout" != "X" -a "X$reverse" = "X1" ]; then 3094 # need to exec for reverse vencrypt 3095 connect="exec = $ptmp" 3096 else 3097 # on mac and solaris we need to listen on socket instead of stdio: 3098 nd=`findfree 6700` 3099 PPROXY_LISTEN=$nd 3100 export PPROXY_LISTEN 3101 if [ "X$reverse" = "X" ]; then 3102 $ptmp & 3103 fi 3104 sleep 2 3105 host="$localhost" 3106 port="$nd" 3107 connect="connect = $localhost:$nd" 3108 fi 3109 else 3110 # otherwise on unix we can exec it: 3111 connect="exec = $ptmp" 3112 fi 3113 else 3114 connect="exec = $ptmp" 3115 fi 3116else 3117 connect="connect = $host:$port" 3118fi 3119 3120# handle showcert case: 3121# 3122if [ "X$showcert" = "X1" ]; then 3123 if [ "X$proxy" != "X" ]; then 3124 PPROXY_LISTEN=$use 3125 export PPROXY_LISTEN 3126 if [ "X$SS_DEBUG" != "X" ]; then 3127 $ptmp & 3128 else 3129 $ptmp 2>/dev/null & 3130 fi 3131 sleep 1 3132 more_sleep=1 3133 if uname | grep Linux > /dev/null; then 3134 if netstat -ant | grep LISTEN | grep "127.0.0.1:$use" > /dev/null; then 3135 more_sleep="" 3136 fi 3137 elif uname | grep SunOS > /dev/null; then 3138 if netstat -an -f inet -P tcp | grep LISTEN | grep "127.0.0.1.$use" > /dev/null; then 3139 more_sleep="" 3140 fi 3141 elif uname | egrep -i 'bsd|darwin' > /dev/null; then 3142 if netstat -ant -f inet | grep LISTEN | grep "127.0.0.1.$use" > /dev/null; then 3143 more_sleep="" 3144 fi 3145 fi 3146 if [ "X$more_sleep" = "X1" ]; then 3147 sleep 1 3148 fi 3149 host="$localhost" 3150 port="$use" 3151 fi 3152 cipher_args="" 3153 if [ "X$ciphers" != "X" ]; then 3154 cipher_args=`echo "$ciphers" | sed -e 's/ciphers=/-cipher /'` 3155 fi 3156 if [ "X$have_uvnc_dsm_helper_showcert" = "X1" ]; then 3157 : 3158 elif type openssl > /dev/null 2>&1; then 3159 : 3160 else 3161 echo "" 3162 echo "********************************************************" 3163 echo "** Problem finding the OpenSSL command 'openssl': **" 3164 echo "" 3165 type openssl 2>&1 3166 echo "" 3167 echo "** Perhaps you need to install the 'openssl' package. **" 3168 echo "********************************************************" 3169 echo "" 3170 fi 3171 #echo "openssl s_client $cipher_args -connect $host:$port" 3172 if [ "X$reverse" = "X" ]; then 3173 if type host > /dev/null 2>/dev/null; then 3174 host $host >/dev/null 2>&1 3175 host $host >/dev/null 2>&1 3176 fi 3177 timeout=15 3178 if [ "X$SSVNC_FETCH_TIMEOUT" != "X" ]; then 3179 timeout=$SSVNC_FETCH_TIMEOUT 3180 fi 3181 if [ "X$have_uvnc_dsm_helper_showcert" = "X1" ]; then 3182 if type pkill >/dev/null 2>&1; then 3183 (sleep $timeout; if kill -0 $$; then pkill -TERM -f "ultravnc_dsm_helper.*$host.*$port"; fi) >/dev/null 2>&1 & 3184 fi 3185 ultravnc_dsm_helper showcert $host:$port 2>&1 3186 else 3187 if type pkill >/dev/null 2>&1; then 3188 (sleep $timeout; if kill -0 $$; then pkill -TERM -f "openssl.*s_client.*$host.*$port"; fi) >/dev/null 2>&1 & 3189 fi 3190 openssl s_client $cipher_args -prexit -connect $host:$port 2>&1 < /dev/null 3191 fi 3192 rc=$? 3193 else 3194 tcert="" 3195 if [ "X$mycert" = "X" ]; then 3196 tcert=`make_tcert` 3197 cert_args="-cert $tcert -CAfile $tcert" 3198 else 3199 cert_args="-cert $mycert -CAfile $mycert" 3200 fi 3201 tmp_out=/tmp/showcert_out${RANDOM}.$$ 3202 tmp_out=`mytmp "$tmp_out"` 3203 tmp_err=/tmp/showcert_err${RANDOM}.$$ 3204 tmp_err=`mytmp "$tmp_err"` 3205 3206 #echo "openssl s_server $cipher_args $cert_args -accept $port -verify 2 > $tmp_out 2> $tmp_err" 1>&2 3207 3208 # assume we have perl: 3209 check_perl perl 3210 3211 perl -e " 3212 \$p = open(O, \"|openssl s_server $cipher_args $cert_args -accept $port -verify 2 1>$tmp_out 2> $tmp_err\"); 3213 exit 1 unless \$p; 3214 while (1) { 3215 sleep 1; 3216 if (!open(F, \"<$tmp_out\")) { 3217 kill \$p; 3218 exit 1; 3219 } 3220 while (<F>) { 3221 if (/RFB 00/) { 3222 fsleep(0.25); 3223 print O \"RFB 000.000\\n\"; 3224 fsleep(1.00); 3225 kill \$p; 3226 fsleep(0.25); 3227 exit 0; 3228 } 3229 } 3230 close F; 3231 } 3232 sub fsleep { 3233 select(undef, undef, undef, shift); 3234 } 3235 "; 3236 3237 echo "" 3238 cat $tmp_out 3239 echo "" 3240 echo "----2----" 3241 cat $tmp_err 3242 if grep BEGIN.CERTIFICATE $tmp_out >/dev/null; then 3243 rc=0 3244 else 3245 rc=1 3246 fi 3247 3248 rm -f $tmp_out $tmp_err 3249 fi 3250 if [ "X$SSVNC_PREDIGESTED_HANDSHAKE" != "X" ]; then 3251 rm -f $SSVNC_PREDIGESTED_HANDSHAKE 3252 fi 3253 if [ "X$SSVNC_SHOWCERT_EXIT_0" = "X1" ]; then 3254 exit 0 3255 else 3256 exit $rc 3257 fi 3258fi 3259 3260# handle direct connect case: 3261# 3262if [ "X$direct_connect" != "X" ]; then 3263 if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then 3264 SSVNC_NO_ENC_WARN=1 3265 echo "" 3266 echo "Using UltraVNC DSM Plugin key for encryption:" 3267 echo "" 3268 ustr=`echo "$SSVNC_ULTRA_DSM" | sed -e 's/pw=[^ ]*/pw=******/g'` 3269 echo " $ustr PORT HOST:PORT" 3270 echo "" 3271 elif [ "X$getport" = "X" ]; then 3272 echo "" 3273 echo "Running viewer for direct connection:" 3274 if echo X"$@" | grep chatonly > /dev/null; then 3275 : 3276 else 3277 echo "" 3278 echo "** WARNING: THERE WILL BE NO SSL OR SSH ENCRYPTION **" 3279 echo "" 3280 fi 3281 fi 3282 x="" 3283 if [ "X$SSVNC_NO_ENC_WARN" != "X" ]; then 3284 if [ "X$getport" = "X" ]; then 3285 sleep 1 3286 fi 3287 elif type printf > /dev/null 2>&1; then 3288 printf "Are you sure you want to continue? [y]/n " 3289 read x 3290 else 3291 echo -n "Are you sure you want to continue? [y]/n " 3292 read x 3293 fi 3294 if [ "X$x" = "Xn" ]; then 3295 exit 1 3296 fi 3297 echo "" 3298 if [ "X$ptmp" != "X" ]; then 3299 if [ "X$reverse" = "X" ]; then 3300 PPROXY_LISTEN=$use 3301 export PPROXY_LISTEN 3302 else 3303 if [ "X$proxy" = "Xreverse_direct" ]; then 3304 PPROXY_LISTEN="$STUNNEL_LISTEN:`expr 5500 + $disp`" 3305 PPROXY_DEST="$localhost:$use" 3306 PPROXY_PROXY="ipv6://$localhost:$use" # not always ipv6.. 3307 export PPROXY_LISTEN PPROXY_DEST PPROXY_PROXY 3308 pps=1 3309 else 3310 PPROXY_REVERSE="$localhost:$use" 3311 export PPROXY_LISTEN 3312 pps=3 3313 fi 3314 if [ "X$SSVNC_LISTEN_ONCE" != "X1" ]; then 3315 PPROXY_LOOP_THYSELF=`mytmp "/tmp/pproxy_loop_thyself.${RANDOM}.$$"` 3316 export PPROXY_LOOP_THYSELF 3317 pps=2 3318 fi 3319 if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then 3320 pps=`expr $pps + $SSVNC_EXTRA_SLEEP` 3321 fi 3322 PPROXY_SLEEP=$pps; export PPROXY_SLEEP; 3323 PPROXY_KILLPID=+1; export PPROXY_KILLPID; 3324 fi 3325 3326 $ptmp & 3327 3328 if [ "X$reverse" = "X" ]; then 3329 #sleep 2 3330 #echo T sleep 1 3331 sleep 1 3332 fi 3333 host="$localhost" 3334 disp="$N" 3335 port=`expr $disp + 5900` 3336 fi 3337 if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then 3338 echo "T sleep $SSVNC_EXTRA_SLEEP" 3339 sleep $SSVNC_EXTRA_SLEEP 3340 fi 3341 if [ "X$SSVNC_EXTRA_COMMAND" != "X" ]; then 3342 (sh -c "$SSVNC_EXTRA_COMMAND") & 3343 echo "($SSVNC_EXTRA_COMMAND) &"; echo 3344 fi 3345 if [ "X$reverse" = "X" ]; then 3346 hostdisp="$host:$disp" 3347 if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then 3348 if [ "X$SSVNC_USE_OURS" = "X1" ]; then 3349 hostdisp="exec=$SSVNC_ULTRA_DSM 0 $host:$port" 3350 else 3351 pf=`findfree 5970` 3352 cmd="$SSVNC_ULTRA_DSM -$pf $host:$port" 3353 pf=`expr $pf - 5900` 3354 hostdisp="$localhost:$pf" 3355 ustr=`echo "$cmd" | sed -e 's/pw=[^ ]*/pw=******/g'` 3356 echo "Running:" 3357 echo 3358 echo "$ustr &" 3359 echo 3360 $cmd & 3361 dsm_pid=$! 3362 sleep 2 3363 fi 3364 fi 3365 hostdisp2=`echo "$hostdisp" | sed -e 's/pw=[^ ]*/pw=******/g'` 3366 echo "$VNCVIEWERCMD" "$@" "$hostdisp2" 3367 trap "final" 0 2 15 3368 echo "" 3369 $VNCVIEWERCMD "$@" "$hostdisp" 3370 if [ $? != 0 ]; then 3371 echo "vncviewer command failed: $?" 3372 if [ "X$secondtry" = "X1" ]; then 3373 sleep 2 3374 $VNCVIEWERCMD "$@" "$hostdisp" 3375 fi 3376 fi 3377 else 3378 echo "" 3379 echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode." 3380 echo "" 3381 trap "final" 0 2 15 3382 if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then 3383 if [ "X$SSVNC_LISTEN_ONCE" = "X1" ]; then 3384 echo "NOTE: The ultravnc_dsm_helper only runs once. So after the first LISTEN" 3385 echo " ends you must restart the Listening mode. You may also need to" 3386 echo " Press Ctrl-C to stop the viewer and restart for another connection." 3387 echo "" 3388 fi 3389 #SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE 3390 VNCVIEWER_LISTEN_LOCALHOST=1 3391 export VNCVIEWER_LISTEN_LOCALHOST 3392 dport=`expr 5500 + $disp` 3393 cmd="$SSVNC_ULTRA_DSM $dport $localhost:$use" 3394 ustr=`echo "$cmd" | sed -e 's/pw=[^ ]*/pw=******/g'` 3395 echo "Running:" 3396 echo 3397 echo "$ustr &" 3398 echo 3399 if [ "X$SSVNC_LISTEN_ONCE" = "X1" ]; then 3400 $cmd & 3401 dsm_pid=$! 3402 else 3403 while [ 1 ]; do $cmd; sleep 1; done & 3404 dsm_pid=$! 3405 fi 3406 sleep 2 3407 disp=$use 3408 if [ $disp -ge 5500 ]; then 3409 disp=`expr $disp - 5500` 3410 fi 3411 fi 3412 disp2=$disp 3413 if [ "X$VNCVIEWER_IS_REALVNC4" = "X1" ]; then 3414 disp2=`echo "$disp2" | sed -e 's/://g'` 3415 if [ $disp2 -le 200 ]; then 3416 disp2=`expr $disp2 + 5500` 3417 fi 3418 fi 3419 echo "$VNCVIEWERCMD" "$@" -listen $disp2 3420 echo "" 3421 $VNCVIEWERCMD "$@" -listen $disp2 3422 if [ "X$PPROXY_LOOP_THYSELF" != "X" ]; then 3423 rm -f $PPROXY_LOOP_THYSELF 3424 fi 3425 fi 3426 exit $? 3427fi 3428 3429tmp_cfg=/tmp/ss_vncviewer${RANDOM}.$$ 3430tmp_cfg=`mytmp "$tmp_cfg"` 3431 3432stunnel_exec="" 3433if [ "X$SSVNC_USE_OURS" != "X1" ]; then 3434 : 3435elif echo $STUNNEL_EXTRA_SVC_OPTS | grep '#stunnel-exec' > /dev/null; then 3436 stunnel_exec="#" 3437fi 3438 3439if [ "X$reverse" = "X" ]; then 3440 3441 if echo "$proxy" | grep "^repeater://" > /dev/null; then 3442 if [ "X$cert" = "XBUILTIN" ]; then 3443 ttcert=`make_tcert` 3444 cert="cert = $ttcert" 3445 fi 3446 # Note for listen mode, an empty cert will cause stunnel to fail. 3447 # The ssvnc gui will have already taken care of this. 3448 fi 3449 3450 cat > "$tmp_cfg" <<END 3451foreground = yes 3452pid = 3453client = yes 3454debug = $stunnel_debug 3455$ciphers 3456$STUNNEL_EXTRA_OPTS 3457$STUNNEL_EXTRA_OPTS_USER 3458$cert 3459$crl 3460$verify 3461 3462${stunnel_exec}[vnc_stunnel] 3463${stunnel_exec}accept = $localhost:$use 3464$connect 3465$STUNNEL_EXTRA_SVC_OPTS 3466$STUNNEL_EXTRA_SVC_OPTS_USER 3467 3468END 3469 3470else 3471 # REVERSE case: 3472 3473 stunnel_exec="" # doesn't work for listening. 3474 3475 p2=`expr 5500 + $N` 3476 connect="connect = $localhost:$p2" 3477 if [ "X$cert" = "XBUILTIN" ]; then 3478 ttcert=`make_tcert` 3479 cert="cert = $ttcert" 3480 fi 3481 # Note for listen mode, an empty cert will cause stunnel to fail. 3482 # The ssvnc gui will have already taken care of this. 3483 3484 3485 hloc="" 3486 if [ "X$use_ssh" = "X1" ]; then 3487 hloc="$localhost:" 3488 elif [ "X$STUNNEL_LISTEN" != "X" ]; then 3489 hloc="$STUNNEL_LISTEN:" 3490 fi 3491 if echo "$proxy" | grep -i '^vencrypt:' > /dev/null; then 3492 hloc="$localhost:" 3493 pv=`findfree 5570` 3494 proxy="vencrypt:$pv:$port" 3495 port=$pv 3496 if [ "X$anondh_set" = "X1" ]; then 3497 # not needed for ANONDH in this mode 3498 #ciphers="ciphers = ADH:@STRENGTH" 3499 : 3500 fi 3501 fi 3502 cat > "$tmp_cfg" <<END 3503foreground = yes 3504pid = 3505client = no 3506debug = $stunnel_debug 3507$ciphers 3508$STUNNEL_EXTRA_OPTS 3509$STUNNEL_EXTRA_OPTS_USER 3510$cert 3511$crl 3512$verify 3513 3514[vnc_stunnel] 3515accept = $hloc$port 3516$connect 3517$STUNNEL_EXTRA_SVC_OPTS 3518$STUNNEL_EXTRA_SVC_OPTS_USER 3519 3520END 3521 3522fi 3523 3524echo "" 3525echo "Using this stunnel configuration:" 3526echo "" 3527cat "$tmp_cfg" | uniq 3528echo "" 3529if egrep -i '^[ ]*(CApath|CAfile) =' "$tmp_cfg" > /dev/null ; then 3530 : 3531else 3532 echo "** WARNING: THE STUNNEL CONFIG HAS NO SERVER CERTIFICATE SPECIFIED **" 3533 echo "** WARNING: (the CApath or CAfile stunnel option) THE VNC SERVER WILL **" 3534 echo "** WARNING: NOT BE AUTHENTICATED. A MAN-IN-THE-MIDDLE ATTACK IS POSSIBLE **" 3535 echo "" 3536fi 3537sleep 1 3538 3539if [ "X$stunnel_exec" = "X" ]; then 3540 echo "" 3541 echo "Running stunnel:" 3542 echo "$STUNNEL $tmp_cfg" 3543 st=`echo "$STUNNEL" | awk '{print $1}'` 3544 $st -help > /dev/null 2>&1 3545 $STUNNEL "$tmp_cfg" < /dev/tty > /dev/tty & 3546 stunnel_pid=$! 3547 echo "" 3548 3549 # pause here to let the user supply a possible passphrase for the 3550 # mycert key: 3551 if [ "X$mycert" != "X" ]; then 3552 nsl=10 3553 dsl=0 3554 if [ ! -f $mycert ]; then 3555 dsl=0 3556 elif grep -i 'Proc-Type.*ENCRYPTED' "$mycert" > /dev/null 2>/dev/null; then 3557 dsl=1 3558 fi 3559 if [ "X$dsl" = "X1" ]; then 3560 echo "" 3561 echo "(** pausing $nsl secs for possible certificate passphrase dialog **)" 3562 echo "" 3563 sleep $nsl 3564 echo "(** done pausing for passphrase **)" 3565 echo "" 3566 fi 3567 fi 3568 #echo T sleep 1 3569 sleep 1 3570 rm -f "$tmp_cfg" 3571fi 3572 3573 3574echo "" 3575if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then 3576 echo "sleep $SSVNC_EXTRA_SLEEP" 3577 sleep $SSVNC_EXTRA_SLEEP 3578fi 3579if [ "X$SSVNC_EXTRA_COMMAND" != "X" ]; then 3580 (sh -c "$SSVNC_EXTRA_COMMAND") & 3581 echo "($SSVNC_EXTRA_COMMAND) &"; echo 3582fi 3583 3584if [ "X$reverse" = "X" ]; then 3585 if [ "X$NEED_VENCRYPT_VIEWER_BRIDGE" = "X1" -a "X$ptmp" != "X" ] ; then 3586 port1=`expr 5900 + $N` # stunnel port 3587 port2=`findfree 5970` # bridge port (viewer connects to it.) 3588 N=`expr $port2 - 5900` 3589 env PPROXY_REMOVE=0 PPROXY_SLEEP=0 PPROXY_VENCRYPT_VIEWER_BRIDGE="$port2,$port1" $ptmp & 3590 sleep 1 3591 fi 3592 echo "Running viewer:" 3593 vnc_hp=$localhost:$N 3594 if [ "X$stunnel_exec" != "X" ]; then 3595 vnc_hp="exec=$STUNNEL $tmp_cfg" 3596 fi 3597 echo "$VNCVIEWERCMD" "$@" "$vnc_hp" 3598 trap "final" 0 2 15 3599 echo "" 3600 $VNCVIEWERCMD "$@" "$vnc_hp" 3601 if [ $? != 0 ]; then 3602 echo "vncviewer command failed: $?" 3603 if [ "X$secondtry" = "X1" ]; then 3604 sleep 2 3605 $VNCVIEWERCMD "$@" "$vnc_hp" 3606 fi 3607 fi 3608else 3609 echo "Running viewer:" 3610 echo "" 3611 echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode." 3612 echo "" 3613 trap "final" 0 2 15 3614 N2=$N 3615 N2_trim=`echo "$N2" | sed -e 's/://g'` 3616 if [ $N2_trim -le 200 ]; then 3617 N2_trim=`expr $N2_trim + 5500` 3618 fi 3619 if [ "X$proxy" != "X" ]; then 3620 if echo "$proxy" | grep -i '^vencrypt:' > /dev/null; then 3621 pstunnel=`echo "$proxy" | awk -F: '{print $2}'` 3622 plisten=`echo "$proxy" | awk -F: '{print $3}'` 3623 IF=INADDR_ANY 3624 if [ "X$STUNNEL_LISTEN" != "X" ]; then 3625 IF=$STUNNEL_LISTEN 3626 fi 3627 PPROXY_VENCRYPT_REVERSE=1; export PPROXY_VENCRYPT_REVERSE 3628 PPROXY_LISTEN="$IF:$plisten"; export PPROXY_LISTEN 3629 PPROXY_PROXY="vencrypt://$localhost:$pstunnel"; export PPROXY_PROXY 3630 PPROXY_DEST="$localhost:$pstunnel"; export PPROXY_DEST 3631 STUNNEL_ONCE=1; export STUNNEL_ONCE 3632 STUNNEL_MAX_CLIENTS=1; export STUNNEL_MAX_CLIENTS 3633 if [ "X$NEED_VENCRYPT_VIEWER_BRIDGE" = "X1" -a "X$ptmp" != "X" ] ; then 3634 port1=`expr 5500 + $N2` 3635 port2=`findfree 5580` 3636 N2=`expr $port2 - 5500` 3637 N2_trim=`echo "$N2" | sed -e 's/://g'` 3638 if [ $N2_trim -le 200 ]; then 3639 N2_trim=`expr $N2_trim + 5500` 3640 fi 3641 if [ "X$SSVNC_LISTEN_ONCE" != "X1" ]; then 3642 PPROXY_LOOP_THYSELF=`mytmp "/tmp/pproxy_loop_thyself1.${RANDOM}.$$"` 3643 export PPROXY_LOOP_THYSELF 3644 PPROXY_LOOP_THYSELF0=$PPROXY_LOOP_THYSELF 3645 fi 3646 env PPROXY_REMOVE=0 PPROXY_SLEEP=0 PPROXY_VENCRYPT_VIEWER_BRIDGE="-$port1,$port2" $ptmp & 3647 sleep 1 3648 fi 3649 else 3650 PPROXY_REVERSE="$localhost:$port"; export PPROXY_REVERSE 3651 PPROXY_SLEEP=1; export PPROXY_SLEEP; 3652 fi 3653 PPROXY_KILLPID=+1; export PPROXY_KILLPID; 3654 if [ "X$SSVNC_LISTEN_ONCE" != "X1" ]; then 3655 PPROXY_LOOP_THYSELF=`mytmp "/tmp/pproxy_loop_thyself2.${RANDOM}.$$"` 3656 export PPROXY_LOOP_THYSELF 3657 fi 3658 $ptmp & 3659 # Important to have no extra pids generated between here and VNCVIEWERCMD 3660 fi 3661 if [ "X$VNCVIEWER_IS_REALVNC4" = "X1" ]; then 3662 N2=$N2_trim 3663 fi 3664 echo "$VNCVIEWERCMD" "$@" -listen $N2 3665 echo "" 3666 $VNCVIEWERCMD "$@" -listen $N2 3667 3668 if [ "X$PPROXY_LOOP_THYSELF" != "X" ]; then 3669 rm -f $PPROXY_LOOP_THYSELF 3670 fi 3671 if [ "X$PPROXY_LOOP_THYSELF0" != "X" ]; then 3672 rm -f $PPROXY_LOOP_THYSELF0 3673 fi 3674fi 3675 3676sleep 1 3677