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