add libvncserver
[presencevnc] / libvnc / classes / ssl / ss_vncviewer
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-2008 by Karl J. Runge <runge@karlrunge.com>
7 #
8 # You must have stunnel(8) installed on the system and in your PATH
9 # (however, see the -ssh option below, in which case you will need ssh(1)
10 # installed)  Note: stunnel is usually installed in an "sbin" subdirectory.
11 #
12 # You should have "x11vnc -ssl ..." or "x11vnc -stunnel ..." 
13 # already running as the VNC server on the remote machine.
14 # (or use stunnel on the server side for any other VNC server)
15 #
16 #
17 # Usage: ss_vncviewer [cert-args] host:display <vncviewer-args>
18 #
19 # e.g.:  ss_vncviewer snoopy:0
20 #        ss_vncviewer snoopy:0 -encodings "copyrect tight zrle hextile"
21 #
22 # [cert-args] can be:
23 #
24 #       -verify /path/to/cacert.pem             
25 #       -mycert /path/to/mycert.pem             
26 #       -crl    /path/to/my_crl.pem  (or directory)
27 #       -proxy  host:port
28 #
29 # -verify specifies a CA cert PEM file (or a self-signed one) for
30 #         authenticating the VNC server.
31 #
32 # -mycert specifies this client's cert+key PEM file for the VNC server to
33 #         authenticate this client. 
34 #
35 # -proxy  try host:port as a Web proxy to use the CONNECT method
36 #         to reach the VNC server (e.g. your firewall requires a proxy).
37 #
38 #         For the "double proxy" case use -proxy host1:port1,host2:port2
39 #         (the first CONNECT is done through host1:port1 to host2:port2
40 #         and then a 2nd CONNECT to the destination VNC server.)
41 #
42 #         Use socks://host:port, socks4://host:port, or socks5://host,port
43 #         to force usage of a SOCKS proxy.  Also repeater://host:port and
44 #         sslrepeater://host:port.
45 #
46 # -showcert  Only fetch the certificate using the 'openssl s_client'
47 #            command (openssl(1) must in installed).
48 #
49 #    See http://www.karlrunge.com/x11vnc/#faq-ssl-ca for details on SSL
50 #    certificates with VNC.
51 #
52 # A few other args (not related to SSL and certs):
53 #
54 # -2nd    Run the vncviewer a 2nd time if the first connections fails.
55 #
56 # -ssh    Use ssh instead of stunnel SSL.  ssh(1) must be installed and you
57 #         must be able to log into the remote machine via ssh.
58 #
59 #         In this case "host:display" may be of the form "user@host:display"
60 #         where "user@host" is used for the ssh login (see ssh(1) manpage).
61 #
62 #         If -proxy is supplied it can be of the forms: "gwhost" "gwhost:port"
63 #         "user@gwhost" or "user@gwhost:port".  "gwhost" is an incoming ssh 
64 #         gateway machine (the VNC server is not running there), an ssh -L
65 #         redir is used to "host" in "host:display" from "gwhost". Any "user@"
66 #         part must be in the -proxy string (not in "host:display").
67 #
68 #         Under -proxy use "gwhost:port" if connecting to any ssh port
69 #         other than the default (22).  (even for the non-gateway case,
70 #         -proxy must be used to specify a non-standard ssh port)
71 #
72 #         A "double ssh" can be specified via a -proxy string with the two
73 #         hosts separated by a comma:
74 #
75 #             [user1@]host1[:port1],[user2@]host2[:port2]
76 #
77 #         in which case a ssh to host1 and thru it via a -L redir a 2nd
78 #         ssh is established to host2.  
79 #
80 #         Examples:
81 #
82 #         ss_vncviewer -ssh bob@bobs-home.net:0
83 #         ss_vncviewer -ssh -sshcmd 'x11vnc -localhost' bob@bobs-home.net:0
84 #
85 #         ss_vncviewer -ssh -proxy fred@mygate.com:2022 mymachine:0
86 #         ss_vncviewer -ssh -proxy bob@bobs-home.net:2222 localhost:0
87 #
88 #         ss_vncviewer -ssh -proxy fred@gw-host,fred@peecee localhost:0
89 #
90 # -sshcmd cmd   Run "cmd" via ssh instead of the default "sleep 15"
91 #               e.g. -sshcmd 'x11vnc -display :0 -localhost -rfbport 5900'
92 #
93 # -sshargs "args"  pass "args" to the ssh process, e.g. -L/-R port redirs.
94 #
95 # -sshssl Tunnel the SSL connection thru a SSH connection.  The tunnel as
96 #         under -ssh is set up and the SSL connection goes thru it.  Use
97 #         this if you want to have and end-to-end SSL connection but must
98 #         go thru a SSH gateway host (e.g. not the vnc server).  Or use
99 #         this if you need to tunnel additional services via -R and -L 
100 #         (see -sshargs above).
101 #
102 #         ss_vncviewer -sshssl -proxy fred@mygate.com mymachine:0
103 #
104 # -listen (or -reverse) set up a reverse connection.
105 #
106 # -alpha  turn on cursor alphablending hack if you are using the
107 #         enhanced tightvnc vncviewer.
108 #
109 # -grab   turn on XGrabServer hack if you are using the enhanced tightvnc
110 #         vncviewer (e.g. for fullscreen mode in some windowmanagers like
111 #         fvwm that do not otherwise work in fullscreen mode)
112 #
113 #
114 # set VNCVIEWERCMD to whatever vncviewer command you want to use.
115 #
116 VNCIPCMD=${VNCVIEWERCMD:-vncip}
117 VNCVIEWERCMD=${VNCVIEWERCMD:-vncviewer}
118 #
119 # Same for STUNNEL, e.g. set it to /path/to/stunnel or stunnel4, etc.
120 #
121
122 # turn on verbose debugging output
123 if [ "X$SS_DEBUG" != "X" ]; then
124         set -xv 
125 fi
126
127 PATH=$PATH:/usr/sbin:/usr/local/sbin:/dist/sbin; export PATH
128
129 localhost="localhost"
130 if uname | grep Darwin >/dev/null; then
131         localhost="127.0.0.1"
132 fi
133
134 # work out which stunnel to use (debian installs as stunnel4)
135 if [ "X$STUNNEL" = "X" ]; then
136         check_stunnel=1
137         if [ "X$SSVNC_BASEDIRNAME" != "X" ]; then
138                 if [ -x "$SSVNC_BASEDIRNAME/stunnel" ]; then
139                         type stunnel > /dev/null 2>&1
140                         if [ $? = 0 ]; then
141                                 # found ours
142                                 STUNNEL=stunnel
143                                 check_stunnel=0
144                         fi
145                 fi
146         fi
147         if [ "X$check_stunnel" = "X1" ]; then
148                 type stunnel4 > /dev/null 2>&1
149                 if [ $? = 0 ]; then
150                         STUNNEL=stunnel4
151                 else
152                         STUNNEL=stunnel
153                 fi
154         fi
155 fi
156
157 help() {
158         tail -n +2 "$0" | sed -e '/^$/ q'
159 }
160
161 secondtry=""
162 gotalpha=""
163 use_ssh=""
164 use_sshssl=""
165 direct_connect=""
166 ssh_sleep=15
167
168 # sleep longer in -listen mode:
169 if echo "$*" | grep '.*-listen' > /dev/null; then
170         ssh_sleep=1800
171 fi
172
173
174 ssh_cmd=""
175 # env override of ssh_cmd:
176 if [ "X$SS_VNCVIEWER_SSH_CMD" != "X" ]; then
177         ssh_cmd="$SS_VNCVIEWER_SSH_CMD"
178 fi
179
180 ssh_args=""
181 showcert=""
182 reverse=""
183
184 ciphers=""
185 anondh="ALL:RC4+RSA:+SSLv2:@STRENGTH"
186 anondh_set=""
187 stunnel_debug="6"
188 if [ "X$SS_DEBUG" != "X" -o "X$SSVNC_VENCRYPT_DEBUG" != "X" -o "X$SSVNC_STUNNEL_DEBUG" != "X" ]; then
189         stunnel_debug="7"
190 fi
191
192 if [ "X$1" = "X-viewerflavor" ]; then
193         # special case, try to guess which viewer:
194         #
195         if echo "$VNCVIEWERCMD" | egrep -i '^(xmessage|sleep )' > /dev/null; then
196                 echo "unknown"
197                 exit 0
198         fi
199         if echo "$VNCVIEWERCMD" | grep -i chicken.of > /dev/null; then
200                 echo "cotvnc"
201                 exit 0
202         fi
203         if echo "$VNCVIEWERCMD" | grep -i ultra > /dev/null; then
204                 echo "ultravnc"
205                 exit 0
206         fi
207         # OK, run it for help output...
208         str=`$VNCVIEWERCMD -h 2>&1 | head -n 5`
209         if echo "$str" | grep -i 'TightVNC.viewer' > /dev/null; then
210                 echo "tightvnc"
211         elif echo "$str" | grep -i 'RealVNC.Ltd' > /dev/null; then
212                 echo "realvnc4"
213         elif echo "$str" | grep -i 'VNC viewer version 3' > /dev/null; then
214                 echo "realvnc3"
215         else
216                 echo "unknown"
217         fi
218         exit 0
219 fi
220 if [ "X$1" = "X-viewerhelp" ]; then
221         $VNCVIEWERCMD -h 2>&1
222         exit 0
223 fi
224
225 # grab our cmdline options:
226 while [ "X$1" != "X" ]
227 do
228     case $1 in 
229         "-verify")      shift; verify="$1"
230                 ;;
231         "-mycert")      shift; mycert="$1"
232                 ;;
233         "-crl")         shift; crl="$1"
234                 ;;
235         "-proxy")       shift; proxy="$1"
236                 ;;
237         "-ssh")         use_ssh=1
238                 ;;
239         "-sshssl")      use_ssh=1
240                         use_sshssl=1
241                 ;;
242         "-sshcmd")      shift; ssh_cmd="$1"
243                 ;;
244         "-sshargs")     shift; ssh_args="$1"
245                 ;;
246         "-anondh")      ciphers="ciphers=$anondh"
247                         anondh_set=1
248                 ;;
249         "-ciphers")     shift; ciphers="ciphers=$1"
250                 ;;
251         "-alpha")       gotalpha=1
252                 ;;
253         "-showcert")    showcert=1
254                 ;;
255         "-listen")      reverse=1
256                 ;;
257         "-reverse")     reverse=1
258                 ;;
259         "-2nd")         secondtry=1
260                 ;;
261         "-grab")        VNCVIEWER_GRAB_SERVER=1; export VNCVIEWER_GRAB_SERVER
262                 ;;
263         "-x11cursor")   VNCVIEWER_X11CURSOR=1; export VNCVIEWER_X11CURSOR
264                 ;;
265         "-rawlocal")    VNCVIEWER_RAWLOCAL=1; export VNCVIEWER_RAWLOCAL
266                 ;;
267         "-scale")       shift; SSVNC_SCALE="$1"; export SSVNC_SCALE
268                 ;;
269         "-onelisten")   SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE
270                 ;;
271         "-escape")      shift; VNCVIEWER_ESCAPE="$1"; export VNCVIEWER_ESCAPE
272                 ;;
273         "-ssvnc_encodings")     shift; VNCVIEWER_ENCODINGS="$1"; export VNCVIEWER_ENCODINGS
274                 ;;
275         "-rfbversion")  shift; VNCVIEWER_RFBVERSION="$1"; export VNCVIEWER_RFBVERSION
276                 ;;
277         "-nobell")      VNCVIEWER_NOBELL=1; export VNCVIEWER_NOBELL
278                 ;;
279         "-popupfix")    VNCVIEWER_POPUP_FIX=1; export VNCVIEWER_POPUP_FIX
280                 ;;
281         "-realvnc4")    VNCVIEWER_IS_REALVNC4=1; export VNCVIEWER_IS_REALVNC4
282                 ;;
283         "-h"*)  help; exit 0
284                 ;;
285         "--h"*) help; exit 0
286                 ;;
287         *)      break
288                 ;;
289     esac
290     shift
291 done
292
293 # maxconn is something we added to stunnel, this disables it:
294 if [ "X$SS_VNCVIEWER_NO_MAXCONN" != "X" ]; then
295         STUNNEL_EXTRA_OPTS=`echo "$STUNNEL_EXTRA_OPTS" | sed -e 's/maxconn/#maxconn/'`
296 elif echo "$VNCVIEWERCMD" | egrep -i '^(xmessage|sleep )' > /dev/null; then
297         STUNNEL_EXTRA_OPTS=`echo "$STUNNEL_EXTRA_OPTS" | sed -e 's/maxconn/#maxconn/'`
298 elif [ "X$reverse" != "X" ]; then
299         STUNNEL_EXTRA_OPTS=`echo "$STUNNEL_EXTRA_OPTS" | sed -e 's/maxconn/#maxconn/'`
300 else
301         # new way (our patches).  other than the above, we set these:
302         if [ "X$SKIP_STUNNEL_ONCE" = "X" ]; then
303                 STUNNEL_ONCE=1; export STUNNEL_ONCE
304         fi
305         if [ "X$SKIP_STUNNEL_MAX_CLIENTS" = "X" ]; then
306                 STUNNEL_MAX_CLIENTS=1; export STUNNEL_MAX_CLIENTS
307         fi
308 fi
309 # always set this one:
310 if [ "X$SKIP_STUNNEL_NO_SYSLOG" = "X" ]; then
311         STUNNEL_NO_SYSLOG=1; export STUNNEL_NO_SYSLOG
312 fi
313
314 # this is the -t ssh option (gives better keyboard response thru SSH tunnel)
315 targ="-t"
316 if [ "X$SS_VNCVIEWER_NO_T" != "X" ]; then
317         targ=""
318 fi
319
320 # set the alpha blending env. hack: 
321 if [ "X$gotalpha" = "X1" ]; then
322         VNCVIEWER_ALPHABLEND=1
323         export VNCVIEWER_ALPHABLEND
324 else
325         NO_ALPHABLEND=1
326         export NO_ALPHABLEND
327 fi
328
329 if [ "X$reverse" != "X" ]; then
330         ssh_sleep=1800
331         if [ "X$proxy" != "X" ]; then
332                 # check proxy usage under reverse connection:
333                 if [ "X$use_ssh" = "X" -a "X$use_sshssl" = "X" ]; then
334                         echo ""
335                         if echo "$proxy" | egrep -i "(repeater|vencrypt)://" > /dev/null; then
336                                 :
337                         else
338                                 echo "*Warning*: SSL -listen and a Web proxy does not make sense."
339                                 sleep 2
340                         fi
341                 elif echo "$proxy" | grep "," > /dev/null; then
342                         :
343                 else
344                         echo ""
345                         echo "*Warning*: -listen and a single proxy/gateway does not make sense."
346                         sleep 2
347                 fi
348                 SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE
349         fi
350 fi
351 if [ "X$ssh_cmd" = "X" ]; then
352         # if no remote ssh cmd, sleep a bit:
353         ssh_cmd="sleep $ssh_sleep"
354 fi
355
356 # this should be a host:display:
357 #
358 orig="$1"
359 shift
360
361 dL="-L"
362 if uname -sr | egrep 'SunOS 5\.[5-8]' > /dev/null; then
363         dL="-h"
364 fi
365
366 rchk() {
367         # a kludge to set $RANDOM if we are not bash:
368         if [ "X$BASH_VERSION" = "X" ]; then
369                 RANDOM=`date +%S``sh -c 'echo $$'``ps -elf 2>&1 | sum 2>&1 | awk '{print $1}'`
370         fi
371 }
372 rchk
373
374 # a portable, but not absolutely safe, tmp file creator
375 mytmp() {
376         tf=$1
377         if type mktemp > /dev/null 2>&1; then
378                 # if we have mktemp(1), use it:
379                 tf2="$tf.XXXXXX"
380                 tf2=`mktemp "$tf2"`
381                 if [ "X$tf2" != "X" -a -f "$tf2" ]; then
382                         if [ "X$DEBUG_MKTEMP" != "X" ]; then
383                                 echo "mytmp-mktemp: $tf2" 1>&2
384                         fi
385                         echo "$tf2"
386                         return
387                 fi
388         fi
389         # fallback to multiple cmds:
390         rm -rf "$tf" || exit 1
391         if [ -d "$tf" ]; then
392                 echo "tmp file $tf still exists as a directory."
393                 exit 1
394         elif [ $dL "$tf" ]; then
395                 echo "tmp file $tf still exists as a symlink."
396                 exit 1
397         elif [ -f "$tf" ]; then
398                 echo "tmp file $tf still exists."
399                 exit 1
400         fi
401         touch "$tf" || exit 1
402         chmod 600 "$tf" || exit 1
403         rchk
404         if [ "X$DEBUG_MKTEMP" != "X" ]; then
405                 echo "mytmp-touch: $tf" 1>&2
406         fi
407         echo "$tf"
408 }
409
410 # set up special case of ultravnc single click III mode:
411 if echo "$proxy" | egrep "^sslrepeater://" > /dev/null; then
412         pstr=`echo "$proxy" | sed -e 's,sslrepeater://,,'`
413         pstr1=`echo "$pstr" | sed -e 's/+.*$//'`
414         pstr2=`echo "$pstr" | sed -e 's/^[^+]*+//'`
415         SSVNC_REPEATER="SCIII=$pstr2"; export SSVNC_REPEATER
416         orig=$pstr1
417         echo
418         echo "reset: SSVNC_REPEATER=$SSVNC_REPEATER orig=$orig proxy=''"
419         proxy=""
420 fi
421 if echo "$proxy" | egrep "vencrypt://" > /dev/null; then
422         vtmp="/tmp/ss_handshake${RANDOM}.$$.txt"
423         vtmp=`mytmp "$vtmp"`
424         SSVNC_PREDIGESTED_HANDSHAKE="$vtmp"
425         export SSVNC_PREDIGESTED_HANDSHAKE
426         #echo "SSVNC_PREDIGESTED_HANDSHAKE=$SSVNC_PREDIGESTED_HANDSHAKE"
427 fi
428
429
430 # check -ssh and -mycert/-verify conflict:
431 if [ "X$use_ssh" = "X1" -a "X$use_sshssl" = "X" ]; then
432         if [ "X$mycert" != "X" -o "X$verify" != "X" ]; then
433                 echo "-mycert and -verify cannot be used in -ssh mode" 
434                 exit 1
435         fi
436 fi
437
438 # direct mode Vnc:// means show no warnings.
439 # direct mode vnc:// will show warnings.
440 if echo "$orig" | grep '^V[Nn][Cc]://' > /dev/null; then
441         SSVNC_NO_ENC_WARN=1
442         export SSVNC_NO_ENC_WARN
443         orig=`echo "$orig" | sed -e 's/^...:/vnc:/'`
444 fi
445
446 # interprest the pseudo URL proto:// strings:
447 if echo "$orig" | grep '^vnc://' > /dev/null; then
448         orig=`echo "$orig" | sed -e 's,vnc://,,'`
449         verify=""
450         mycert=""
451         crl=""
452         use_ssh=""
453         use_sshssl=""
454         direct_connect=1
455 elif echo "$orig" | grep '^vncs://' > /dev/null; then
456         orig=`echo "$orig" | sed -e 's,vncs://,,'`
457 elif echo "$orig" | grep '^vncssl://' > /dev/null; then
458         orig=`echo "$orig" | sed -e 's,vncssl://,,'`
459 elif echo "$orig" | grep '^vnc+ssl://' > /dev/null; then
460         orig=`echo "$orig" | sed -e 's,vnc.ssl://,,'`
461 elif echo "$orig" | grep '^vncssh://' > /dev/null; then
462         orig=`echo "$orig" | sed -e 's,vncssh://,,'`
463         use_ssh=1
464 elif echo "$orig" | grep '^vnc+ssh://' > /dev/null; then
465         orig=`echo "$orig" | sed -e 's,vnc.ssh://,,'`
466         use_ssh=1
467 fi
468
469 if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then
470         verify=""
471         mycert=""
472         crl=""
473         use_ssh=""
474         use_sshssl=""
475         direct_connect=1
476         if echo "$SSVNC_ULTRA_DSM" | grep 'noultra:' > /dev/null; then
477                 SSVNC_NO_ULTRA_DSM=1; export SSVNC_NO_ULTRA_DSM
478         fi
479 fi
480
481 # (possibly) tell the vncviewer to only listen on lo: 
482 if [ "X$reverse" != "X" -a "X$direct_connect" = "X" ]; then
483         VNCVIEWER_LISTEN_LOCALHOST=1
484         export VNCVIEWER_LISTEN_LOCALHOST
485 fi
486
487 # rsh mode is an internal/secret thing only I use.
488 rsh=""
489 if echo "$orig" | grep '^rsh://' > /dev/null; then
490         use_ssh=1
491         rsh=1
492         orig=`echo "$orig" | sed -e 's,rsh://,,'`
493 elif echo "$orig" | grep '^rsh:' > /dev/null; then
494         use_ssh=1
495         rsh=1
496         orig=`echo "$orig" | sed -e 's,rsh:,,'`
497 fi
498
499 # play around with host:display port:
500 if echo "$orig" | grep ':' > /dev/null; then
501         :
502 else
503         # add or assume :0 if no ':'
504         if [ "X$reverse" = "X" ]; then
505                 orig="$orig:0"
506         elif [ "X$orig" = "X" ]; then
507                 orig=":0"
508         fi
509 fi
510
511 # extract host and disp number:
512 host=`echo "$orig" | awk -F: '{print $1}'`
513 disp=`echo "$orig" | awk -F: '{print $2}'`
514 if [ "X$host" = "X" ]; then
515         host=$localhost
516 fi
517 if [ "X$disp" = "X" ]; then
518         port="" # probably -listen mode.
519 elif [ $disp -lt 0 ]; then
520         # negative means use |n| without question:
521         port=`expr 0 - $disp`
522 elif [ $disp -lt 200 ]; then
523         # less than 200 means 5900+n
524         if [ "X$reverse" = "X" ]; then
525                 port=`expr $disp + 5900`
526         else
527                 port=`expr $disp + 5500`
528         fi
529 else
530         # otherwise use the number directly, e.g. 443, 2345
531         port=$disp
532 fi
533
534 # try to find an open listening port via netstat(1):
535 inuse=""
536 if uname | grep Linux > /dev/null; then
537         inuse=`netstat -ant | egrep 'LISTEN|WAIT|ESTABLISH|CLOSE' | awk '{print $4}' | sed 's/^.*://'`
538 elif uname | grep SunOS > /dev/null; then
539         inuse=`netstat -an -f inet -P tcp | egrep 'LISTEN|WAIT|ESTABLISH|CLOSE' | awk '{print $1}' | sed 's/^.*\.//'`
540 elif uname | egrep -i 'bsd|darwin' > /dev/null; then
541         inuse=`netstat -ant -f inet | egrep 'LISTEN|WAIT|ESTABLISH|CLOSE' | awk '{print $4}' | sed 's/^.*\.//'`
542 # add others...
543 fi
544
545 # this is a crude attempt for unique ports tags, etc.
546 date_sec=`date +%S`
547
548 # these are special cases of no vnc, e.g. sleep or xmessage.
549 # these are for using ssvnc as a general port redirector.
550 if echo "$VNCVIEWERCMD" | grep '^sleep[         ][      ]*[0-9][0-9]*' > /dev/null; then
551         if [ "X$SS_VNCVIEWER_LISTEN_PORT" = "X" ]; then
552                 p=`echo "$VNCVIEWERCMD" | awk '{print $3}'`
553                 if [ "X$p" != "X" ]; then
554                         SS_VNCVIEWER_LISTEN_PORT=$p
555                 fi
556         fi
557         p2=`echo "$VNCVIEWERCMD" | awk '{print $2}'`
558         VNCVIEWERCMD="eval sleep $p2; echo Local "
559 elif echo "$VNCVIEWERCMD" | grep '^xmessage[    ][      ]*[0-9][0-9]*' > /dev/null; then
560         if [ "X$SS_VNCVIEWER_LISTEN_PORT" = "X" ]; then
561                 p=`echo "$VNCVIEWERCMD" | awk '{print $2}'`
562                 SS_VNCVIEWER_LISTEN_PORT=$p
563         fi
564 fi
565
566 # utility to find a free port to listen on.
567 findfree() {
568         try0=$1
569         try=$try0
570         use0=""
571
572         if [ "X$SS_VNCVIEWER_LISTEN_PORT" != "X" ]; then
573                 echo "$SS_VNCVIEWER_LISTEN_PORT"
574                 return  
575         fi
576         if [ $try -ge 6000 ]; then
577                 fmax=`expr $try + 1000`
578         else
579                 fmax=6000
580         fi
581
582         while [ $try -lt $fmax ]
583         do
584                 if [ "X$inuse" = "X" ]; then
585                         break
586                 fi
587                 if echo "$inuse" | grep -w $try > /dev/null; then
588                         :
589                 else
590                         use0=$try
591                         break
592                 fi
593                 try=`expr $try + 1`
594         done
595         if [ "X$use0" = "X" ]; then
596                 use0=`expr $date_sec + $try0`
597         fi
598
599         echo $use0
600 }
601
602 # utility for exiting; kills some helper processes,
603 # removes files, etc.
604 final() {
605         echo ""
606         if [ "X$tmp_cfg" != "X" ]; then
607                 rm -f $tmp_cfg
608         fi
609         if [ "X$SS_VNCVIEWER_RM" != "X" ]; then
610                 rm -f $SS_VNCVIEWER_RM 2>/dev/null
611         fi
612         if [ "X$tcert" != "X" ]; then
613                 rm -f $tcert
614         fi
615         if [ "X$pssh" != "X" ]; then
616                 echo "Terminating background ssh process"
617                 echo kill -TERM "$pssh"
618                 kill -TERM "$pssh" 2>/dev/null
619                 sleep 1
620                 kill -KILL "$pssh" 2>/dev/null
621                 pssh=""
622         fi
623         if [ "X$stunnel_pid" != "X" ]; then
624                 echo "Terminating background stunnel process"
625                 echo kill -TERM "$stunnel_pid"
626                 kill -TERM "$stunnel_pid" 2>/dev/null
627                 sleep 1
628                 kill -KILL "$stunnel_pid" 2>/dev/null
629                 stunnel_pid=""
630         fi
631         if [ "X$dsm_pid" != "X" ]; then
632                 echo "Terminating background ultravnc_dsm_helper process"
633                 echo kill -TERM "$dsm_pid"
634                 kill -TERM "$dsm_pid" 2>/dev/null
635                 sleep 1
636                 kill -KILL "$dsm_pid" 2>/dev/null
637                 stunnel_pid=""
638         fi
639         if [ "X$tail_pid" != "X" ]; then
640                 kill -TERM $tail_pid
641         fi
642 }
643
644 if [ "X$reverse" = "X" ]; then
645         # normal connections try 5930-5999:
646         if [ "X$showcert" = "X" ]; then
647                 use=`findfree 5930`
648         else
649                 # move away from normal place for (possibly many) -showcert
650                 pstart=`date +%S`
651                 pstart=`expr 6130 + $pstart + $pstart`
652                 use=`findfree $pstart`
653         fi
654         if [ $use -ge 5900 ]; then
655                 N=`expr $use - 5900`
656         else
657                 N=$use
658         fi
659 else
660         # reverse connections:
661         p2=`expr $port + 30`
662         use=`findfree $p2`
663         if [ $use -ge 5500 ]; then
664                 N=`expr $use - 5500`
665         else
666                 N=$use
667         fi
668 fi
669
670 # this is for my special use of ss_vncip -> vncip viewer.
671 if echo "$0" | grep vncip > /dev/null; then
672         VNCVIEWERCMD="$VNCIPCMD"
673 fi
674
675 # trick for the undocumented rsh://host:port method.
676 rsh_setup() {
677         if echo "$ssh_host" | grep '@' > /dev/null; then
678                 ul=`echo "$ssh_host" | awk -F@ '{print $1}'`
679                 ul="-l $ul"
680                 ssh_host=`echo "$ssh_host" | awk -F@ '{print $2}'`
681         else
682                 ul=""
683         fi
684         ssh_cmd=`echo "$ssh_cmd" | sed -e 's/ -localhost/ /g'`
685 }
686
687 # trick for the undocumented rsh://host:port method.
688 rsh_viewer() {
689         trap "final" 0 2 15
690         if [ "X$PORT" = "X" ]; then
691                 exit 1
692         elif [ $PORT -ge 5900 ]; then
693                 vdpy=`expr $PORT - 5900`
694         else
695                 vdpy=":$PORT"
696         fi
697         stty sane
698         echo "$VNCVIEWERCMD" "$@" $ssh_host:$vdpy
699         echo ""
700         $VNCVIEWERCMD "$@" $ssh_host:$vdpy
701         if [ $? != 0 ]; then
702                 sleep 2
703                 $VNCVIEWERCMD "$@" $ssh_host:$vdpy
704         fi
705 }
706
707 # this is the PPROXY tool.  used only here for now... 
708 pcode() {
709         tf=$1
710         PPROXY_PROXY=$proxy; export PPROXY_PROXY
711         PPROXY_DEST="$host:$port"; export PPROXY_DEST
712         cod='#!/usr/bin/perl
713
714 # A hack to glue stunnel to a Web proxy or SOCKS for client connections.
715
716 use IO::Socket::INET;
717
718 if (exists $ENV{PPROXY_SLEEP}) {
719         print STDERR "PPROXY_PID: $$\n";
720         sleep $ENV{PPROXY_SLEEP};
721 }
722
723 foreach my $var (qw(PPROXY_PROXY PPROXY_SOCKS PPROXY_DEST PPROXY_LISTEN
724     PPROXY_REVERSE PPROXY_REPEATER PPROXY_REMOVE PPROXY_KILLPID PPROXY_SLEEP)) {
725         if (0 || $ENV{SS_DEBUG} || $ENV{SSVNC_VENCRYPT_DEBUG}) {
726                 print STDERR "$var: $ENV{$var}\n";
727         }
728
729
730 if ($ENV{PPROXY_SOCKS} ne "" && $ENV{PPROXY_PROXY} !~ m,^socks5?://,i) {
731         if ($ENV{PPROXY_SOCKS} eq "5") {
732                 $ENV{PPROXY_PROXY} = "socks5://$ENV{PPROXY_PROXY}";
733         } else {
734                 $ENV{PPROXY_PROXY} = "socks://$ENV{PPROXY_PROXY}";
735         }
736 }
737
738 my $rfbSecTypeAnonTls  = 18;
739 my $rfbSecTypeVencrypt = 19;
740
741 my $rfbVencryptPlain        = 256;
742 my $rfbVencryptTlsNone      = 257;
743 my $rfbVencryptTlsVnc       = 258;
744 my $rfbVencryptTlsPlain     = 259;
745 my $rfbVencryptX509None     = 260;
746 my $rfbVencryptX509Vnc      = 261;
747 my $rfbVencryptX509Plain    = 262;
748
749 my $handshake_file = "";
750 if (exists $ENV{SSVNC_PREDIGESTED_HANDSHAKE})  {
751         $handshake_file = $ENV{SSVNC_PREDIGESTED_HANDSHAKE};
752 }
753
754 sub append_handshake {
755         my $str = shift;
756         if ($handshake_file) {
757                 if (open(HSF, ">>$handshake_file")) {
758                         print HSF $str;
759                         close HSF;
760                 }
761         }
762 }
763
764 my ($first, $second, $third) = split(/,/, $ENV{PPROXY_PROXY}, 3);
765 my ($mode_1st, $mode_2nd, $mode_3rd) = ("", "", "");
766
767 ($first, $mode_1st) = url_parse($first);
768
769 my ($proxy_host, $proxy_port) = split(/:/, $first);
770 my $connect = $ENV{PPROXY_DEST};
771
772 if ($second ne "") {
773         ($second, $mode_2nd) = url_parse($second);
774 }
775
776 if ($third ne "") {
777         ($third, $mode_3rd) = url_parse($third);
778 }
779
780
781 print STDERR "\n";
782 print STDERR "PPROXY v0.2: a tool for Web proxies and SOCKS connections.\n";
783 print STDERR "proxy_host:       $proxy_host\n";
784 print STDERR "proxy_port:       $proxy_port\n";
785 print STDERR "proxy_connect:    $connect\n";
786 print STDERR "pproxy_params:    $ENV{PPROXY_PROXY}\n";
787 print STDERR "pproxy_listen:    $ENV{PPROXY_LISTEN}\n";
788 print STDERR "pproxy_reverse:   $ENV{PPROXY_REVERSE}\n";
789 print STDERR "\n";
790 if (1) {
791         print STDERR "pproxy 1st: $first\t- $mode_1st\n";
792         print STDERR "pproxy 2nd: $second\t- $mode_2nd\n";
793         print STDERR "pproxy 3rd: $third\t- $mode_3rd\n";
794         print STDERR "\n";
795 }
796
797 my $listen_handle = "";
798 if ($ENV{PPROXY_REVERSE} ne "") {
799         my ($rhost, $rport) = split(/:/, $ENV{PPROXY_REVERSE});
800         $rport = 5900 unless $rport;
801         $listen_handle = IO::Socket::INET->new(
802                 PeerAddr => $rhost,
803                 PeerPort => $rport,
804                 Proto => "tcp"
805         );
806         if (! $listen_handle) {
807                 die "pproxy: $! -- PPROXY_REVERSE\n";
808         }
809         print STDERR "PPROXY_REVERSE: connected to $rhost $rport\n";
810
811 } elsif ($ENV{PPROXY_LISTEN} ne "") {
812         my $listen_sock = "";
813         if ($ENV{PPROXY_LISTEN} =~ /^INADDR_ANY:(.*)/) {
814                 my $p = $1;
815                 $listen_sock = IO::Socket::INET->new(
816                         Listen    => 2,
817                         LocalPort => $p,
818                         Proto     => "tcp"
819                 );
820         } else {
821                 $listen_sock = IO::Socket::INET->new(
822                         Listen    => 2,
823                         LocalAddr => "127.0.0.1",
824                         LocalPort => $ENV{PPROXY_LISTEN},
825                         Proto     => "tcp"
826                 );
827         }
828         if (! $listen_sock) {
829                 die "pproxy: $! -- PPROXY_LISTEN\n";
830         }
831         my $ip;
832         ($listen_handle, $ip) = $listen_sock->accept();
833         if (! $listen_handle) {
834                 die "pproxy: $!\n";
835         }
836         close $listen_sock;
837 }
838
839 my $sock = IO::Socket::INET->new(
840         PeerAddr => $proxy_host,
841         PeerPort => $proxy_port,
842         Proto => "tcp"
843 );
844
845 if (! $sock) {
846         my $err = $!;
847         unlink($0) if $ENV{PPROXY_REMOVE};
848         die "pproxy: $err\n";
849 }
850
851 unlink($0) if $ENV{PPROXY_REMOVE};
852
853 if ($ENV{PPROXY_PROXY} =~ /^vencrypt:/ && $ENV{PPROXY_LISTEN} =~ /^INADDR_ANY:/) {
854         print STDERR "PPROXY: vencrypt+reverse: swapping listen socket with connect socket.\n";
855         my $tmp_swap = $sock;
856         $sock = $listen_handle;
857         $listen_handle = $tmp_swap;
858 }
859
860 $cur_proxy = $first;
861 setmode($mode_1st);
862
863 if ($second ne "") {
864         connection($second, 1);
865
866         setmode($mode_2nd);
867         $cur_proxy = $second;
868
869         if ($third ne "") {
870                 connection($third, 2);
871                 setmode($mode_3rd);
872                 $cur_proxy = $third;
873                 connection($connect, 3);
874         } else {
875                 connection($connect, 2);
876         }
877 } else {
878         connection($connect, 1);
879 }
880
881 $parent = $$;
882 $child = fork;
883 if (! defined $child) {
884         if ($ENV{PPROXY_KILLPID}) {
885                 foreach my $p (split(/,/, $ENV{PPROXY_KILLPID})) {
886                         if ($p =~ /^(\+|-)/) {
887                                 $p = $parent + $p;
888                         }
889                         kill "TERM", $p;
890                 }
891         }
892         exit 1;
893 }
894
895 if ($child) {
896         print STDERR "pproxy parent\[$$]  STDIN -> socket\n";
897         if ($listen_handle) {
898                 xfer($listen_handle, $sock);
899         } else {
900                 xfer(STDIN, $sock);
901         }
902         select(undef, undef, undef, 0.25);
903         if (kill 0, $child) {
904                 select(undef, undef, undef, 1.5);
905                 print STDERR "pproxy\[$$]: kill TERM $child\n";
906                 kill "TERM", $child;
907         }
908 } else {
909         print STDERR "pproxy child \[$$]  socket -> STDOUT\n";
910         if ($listen_handle) {
911                 xfer($sock, $listen_handle);
912         } else {
913                 xfer($sock, STDOUT);
914         }
915         select(undef, undef, undef, 0.25);
916         if (kill 0, $parent) {
917                 select(undef, undef, undef, 1.5);
918                 print STDERR "pproxy\[$$]: kill TERM $parent\n";
919                 kill "TERM", $parent;
920         }
921 }
922 if ($ENV{PPROXY_KILLPID} ne "") {
923         if ($ENV{PPROXY_KILLPID}) {
924                 foreach my $p (split(/,/, $ENV{PPROXY_KILLPID})) {
925                         if ($p =~ /^(\+|-)/) {
926                                 $p = $parent + $p;
927                         }
928                         print STDERR "kill TERM, $p (PPROXY_KILLPID)\n";
929                         kill "TERM", $p;
930                 }
931         }
932 }
933 exit;
934
935 sub url_parse {
936         my $hostport = shift;
937         my $mode = "http";
938         if ($hostport =~ m,^socks4?://(\S*)$,i) {
939                 $mode = "socks4";
940                 $hostport = $1;
941         } elsif ($hostport =~ m,^socks5://(\S*)$,i) {
942                 $mode = "socks5";
943                 $hostport = $1;
944         } elsif ($hostport =~ m,^https?://(\S*)$,i) {
945                 $mode = "http";
946                 $hostport = $1;
947         } elsif ($hostport =~ m,^repeater://(\S*)\+(\S*)$,i) {
948                 # ultravnc repeater proxy.
949                 $hostport = $1;
950                 $mode = "repeater:$2";
951                 if ($hostport !~ /:\d+/) {
952                         $hostport .= ":5900";
953                 }
954         } elsif ($hostport =~ m,^vencrypt://(\S*)$,i) {
955                 # vencrypt handshake.
956                 $hostport = $1;
957                 my $m = "connect";
958                 if ($hostpost =~ /^(\S+)\+(\S+)$/) {
959                         $hostport = $1;
960                         $mode = $2;
961                 }
962                 $mode = "vencrypt:$m";
963                 if ($hostport !~ /:\d+/) {
964                         $hostport .= ":5900";
965                 }
966         }
967         return ($hostport, $mode);
968 }
969
970 sub setmode {
971         my $mode = shift;
972         $ENV{PPROXY_REPEATER} = "";
973         $ENV{PPROXY_VENCRYPT} = "";
974         if ($mode =~ /^socks/) {
975                 if ($mode =~ /^socks5/) {
976                         $ENV{PPROXY_SOCKS} = 5;
977                 } else {
978                         $ENV{PPROXY_SOCKS} = 1;
979                 }
980         } elsif ($mode =~ /^repeater:(.*)/) {
981                 $ENV{PPROXY_REPEATER} = $1;
982                 $ENV{PPROXY_SOCKS} = "";
983         } elsif ($mode =~ /^vencrypt:(.*)/) {
984                 $ENV{PPROXY_VENCRYPT} = $1;
985                 $ENV{PPROXY_SOCKS} = "";
986         } else {
987                 $ENV{PPROXY_SOCKS} = "";
988         }
989 }
990
991 sub connection {
992         my ($CONNECT, $w) = @_;
993
994         my $con = "";
995         my $msg = "";
996
997         if ($ENV{PPROXY_SOCKS} eq "5") {
998                 # SOCKS5
999                 my ($h, $p) = split(/:/, $CONNECT);
1000                 $con .= pack("C", 0x05);
1001                 $con .= pack("C", 0x01);
1002                 $con .= pack("C", 0x00);
1003
1004                 $msg = "SOCKS5 via $cur_proxy to $h:$p\n\n";
1005                 print STDERR "proxy_request$w: $msg";
1006
1007                 syswrite($sock, $con, length($con));
1008
1009                 my ($n1, $n2, $n3, $n4, $n5, $n6);
1010                 my ($r1, $r2, $r3, $r4, $r5, $r6);
1011                 my ($s1, $s2, $s3, $s4, $s5, $s6);
1012
1013                 $n1 = sysread($sock, $r1, 1);
1014                 $n2 = sysread($sock, $r2, 1);
1015
1016                 $s1 = unpack("C", $r1);
1017                 $s2 = unpack("C", $r2);
1018                 if ($s1 != 0x05 || $s2 != 0x00) {
1019                         print STDERR "SOCKS5 fail s1=$s1 s2=$s2 n1=$n1 n2=$n2\n";
1020                         close $sock;
1021                         exit(1);
1022                 }
1023
1024                 $con = "";
1025                 $con .= pack("C", 0x05);
1026                 $con .= pack("C", 0x01);
1027                 $con .= pack("C", 0x00);
1028                 $con .= pack("C", 0x03);
1029                 $con .= pack("C", length($h));
1030                 $con .= $h;
1031                 $con .= pack("C", $p >> 8);
1032                 $con .= pack("C", $p & 0xff);
1033
1034                 syswrite($sock, $con, length($con));
1035
1036                 $n1 = sysread($sock, $r1, 1);
1037                 $n2 = sysread($sock, $r2, 1);
1038                 $n3 = sysread($sock, $r3, 1);
1039                 $n4 = sysread($sock, $r4, 1);
1040                 $s1 = unpack("C", $r1);
1041                 $s2 = unpack("C", $r2);
1042                 $s3 = unpack("C", $r3);
1043                 $s4 = unpack("C", $r4);
1044
1045                 if ($s4 == 0x1) {
1046                         sysread($sock, $r5, 4 + 2);
1047                 } elsif ($s4 == 0x3) {
1048                         sysread($sock, $r5, 1);
1049                         $s5 = unpack("C", $r5);
1050                         sysread($sock, $r6, $s5 + 2);
1051                 } elsif ($s4 == 0x4) {
1052                         sysread($sock, $r5, 16 + 2);
1053                 }
1054
1055                 if ($s1 != 0x5 || $s2 != 0x0 || $s3 != 0x0) {
1056                         print STDERR "SOCKS5 failed: s1=$s1 s2=$s2 s3=$s3 s4=$s4 n1=$n1 n2=$n2 n3=$n3 n4=$n4\n";
1057                         close $sock;
1058                         exit(1);
1059                 }
1060
1061         } elsif ($ENV{PPROXY_SOCKS} ne "") {
1062                 # SOCKS4 SOCKS4a
1063                 my ($h, $p) = split(/:/, $CONNECT);
1064                 $con .= pack("C", 0x04);
1065                 $con .= pack("C", 0x01);
1066                 $con .= pack("n", $p);
1067
1068                 my $SOCKS_4a = 0;
1069                 if ($h eq "localhost" || $h eq "127.0.0.1") {
1070                         $con .= pack("C", 127);
1071                         $con .= pack("C", 0);
1072                         $con .= pack("C", 0);
1073                         $con .= pack("C", 1);
1074                 } elsif ($h =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) {
1075                         $con .= pack("C", $1);
1076                         $con .= pack("C", $2);
1077                         $con .= pack("C", $3);
1078                         $con .= pack("C", $4);
1079                 } else {
1080                         $con .= pack("C", 0);
1081                         $con .= pack("C", 0);
1082                         $con .= pack("C", 0);
1083                         $con .= pack("C", 3);
1084                         $SOCKS_4a = 1;
1085                 }
1086
1087                 $con .= "nobody";
1088                 $con .= pack("C", 0);
1089
1090                 $msg = "SOCKS4 via $cur_proxy to $h:$p\n\n";
1091                 if ($SOCKS_4a) {
1092                         $con .= $h;
1093                         $con .= pack("C", 0);
1094                         $msg =~ s/SOCKS4/SOCKS4a/;
1095                 }
1096                 print STDERR "proxy_request$w: $msg";
1097                 syswrite($sock, $con, length($con));
1098
1099                 my $ok = 1;
1100                 for (my $i = 0; $i < 8; $i++) {
1101                         my $c;
1102                         sysread($sock, $c, 1);
1103                         my $s = unpack("C", $c);
1104                         if ($i == 0) {
1105                                 $ok = 0 if $s != 0x0;
1106                         } elsif ($i == 1) {
1107                                 $ok = 0 if $s != 0x5a;
1108                         }
1109                 }
1110                 if (! $ok) {
1111                         print STDERR "SOCKS4 failed.\n";
1112                         close $sock;
1113                         exit(1);
1114                 }
1115         } elsif ($ENV{PPROXY_REPEATER} ne "") {
1116                 my $rep = $ENV{PPROXY_REPEATER};
1117                 print STDERR "repeater: $rep\n";
1118                 $rep .= pack("x") x 250;
1119                 syswrite($sock, $rep, 250);
1120
1121                 my $ok = 1;
1122                 for (my $i = 0; $i < 12; $i++) {
1123                         my $c;
1124                         sysread($sock, $c, 1);
1125                         print STDERR $c;
1126                 }
1127         } elsif ($ENV{PPROXY_VENCRYPT} ne "") {
1128                 my $vencrypt = $ENV{PPROXY_VENCRYPT};
1129                 vencrypt_dialog($vencrypt);
1130
1131         } else {
1132                 # Web Proxy:
1133                 $con = "CONNECT $CONNECT HTTP/1.1\r\n";
1134                 $con   .= "Host: $CONNECT\r\n";
1135                 $con   .= "Connection: close\r\n\r\n";
1136                 $msg = $con;
1137
1138                 print STDERR "proxy_request$w: via $cur_proxy:\n$msg";
1139                 syswrite($sock, $con, length($con));
1140
1141                 my $rep = "";
1142                 my $n = 0;
1143                 while ($rep !~ /\r\n\r\n/ && $n < 30000) {
1144                         my $c;
1145                         sysread($sock, $c, 1);
1146                         print STDERR $c;
1147                         $rep .= $c;
1148                         $n++;
1149                 }
1150                 if ($rep !~ m,HTTP/.* 200,) {
1151                         print STDERR "HTTP CONNECT failed.\n";
1152                         close $sock;
1153                         exit(1);
1154                 }
1155         }
1156 }
1157
1158 sub vdie {
1159         append_handshake("done\n");
1160         close $sock;
1161         exit(1);
1162 }
1163
1164 sub anontls_handshake {
1165         my ($vmode, $db) = @_;
1166
1167         print STDERR "PPROXY: Doing ANONTLS Handshake\n";
1168
1169         my $psec = pack("C", $rfbSecTypeAnonTls);
1170         syswrite($sock, $psec, 1);
1171
1172         append_handshake("done\n");
1173 }
1174
1175 sub vencrypt_handshake {
1176         
1177         my ($vmode, $db) = @_;
1178
1179         print STDERR "PPROXY: Doing VeNCrypt Handshake\n";
1180
1181         my $psec = pack("C", $rfbSecTypeVencrypt);
1182
1183         if (exists $ENV{SSVNC_TEST_SEC_TYPE}) {
1184                 my $fake = $ENV{SSVNC_TEST_SEC_TYPE};
1185                 print STDERR "PPROXY: sending sec-type: $fake\n";
1186                 $psec = pack("C", $fake);
1187         }
1188
1189         syswrite($sock, $psec, 1);
1190
1191         my $vmajor;
1192         my $vminor;
1193         sysread($sock, $vmajor, 1);
1194         sysread($sock, $vminor, 1);
1195
1196         vdie if $vmajor eq "" || $vminor eq "";
1197
1198         $vmajor = unpack("C", $vmajor);
1199         $vminor = unpack("C", $vminor);
1200         print STDERR "server vencrypt version $vmajor.$vminor\n" if $db;
1201
1202         if (exists $ENV{SSVNC_TEST_SEC_TYPE}) {
1203                 print STDERR "PPROXY: continuing on in test mode.\n";
1204         } else {
1205                 vdie if $vmajor ne 0;
1206                 vdie if $vminor < 2;
1207         }
1208
1209         $vmajor = pack("C", 0);
1210         $vminor = pack("C", 2);
1211         append_handshake("subversion=0.2\n");
1212
1213         syswrite($sock, $vmajor, 1);
1214         syswrite($sock, $vminor, 1);
1215
1216         my $result;
1217         sysread($sock, $result, 1);
1218         print STDERR "result empty\n" if $db && $result eq "";
1219
1220         vdie if $result eq "";
1221         $result = unpack("C", $result);
1222         print STDERR "result=$result\n" if $db;
1223
1224         vdie if $result ne 0;
1225
1226         my $nsubtypes;
1227         sysread($sock, $nsubtypes, 1);
1228
1229         vdie if $nsubtypes eq "";
1230         $nsubtypes = unpack("C", $nsubtypes);
1231         print STDERR "nsubtypes=$nsubtypes\n" if $db;
1232
1233         my %subtypes;
1234
1235         for (my $i = 0; $i < $nsubtypes; $i++) {
1236                 my $subtype = ""; 
1237                 sysread($sock, $subtype, 4);
1238                 vdie if length($subtype) != 4;
1239
1240                 # XXX fix 64bit.
1241                 $subtype = unpack("N", $subtype);
1242                 print STDERR "subtype: $subtype\n" if $db;
1243                 $subtypes{$subtype} = 1;
1244                 append_handshake("sst$i=$subtype\n");
1245         }
1246
1247         my $subtype = 0;
1248         if (exists $subtypes{$rfbVencryptX509None})  {
1249                 $subtype = $rfbVencryptX509None;
1250                 print STDERR "selected rfbVencryptX509None\n" if $db;
1251         } elsif (exists $subtypes{$rfbVencryptX509Vnc})  {
1252                 $subtype = $rfbVencryptX509Vnc;
1253                 print STDERR "selected rfbVencryptX509Vnc\n" if $db;
1254         } elsif (exists $subtypes{$rfbVencryptX509Plain})  {
1255                 $subtype = $rfbVencryptX509Plain;
1256                 print STDERR "selected rfbVencryptX509Plain\n" if $db;
1257         } elsif (exists $subtypes{$rfbVencryptTlsNone})  {
1258                 $subtype = $rfbVencryptTlsNone;
1259                 print STDERR "selected rfbVencryptTlsNone\n" if $db;
1260         } elsif (exists $subtypes{$rfbVencryptTlsVnc})  {
1261                 $subtype = $rfbVencryptTlsVnc;
1262                 print STDERR "selected rfbVencryptTlsVnc\n" if $db;
1263         } elsif (exists $subtypes{$rfbVencryptTlsPlain})  {
1264                 $subtype = $rfbVencryptTlsPlain;
1265                 print STDERR "selected rfbVencryptTlsPlain\n" if $db;
1266         }
1267
1268         if (exists $ENV{SSVNC_TEST_SEC_SUBTYPE}) {
1269                 my $fake = $ENV{SSVNC_TEST_SEC_SUBTYPE};
1270                 print STDERR "PPROXY: sending sec-subtype: $fake\n";
1271                 $subtype = $fake;
1272         }
1273
1274         append_handshake("subtype=$subtype\n");
1275
1276         my $pst = pack("N", $subtype);
1277         syswrite($sock, $pst, 4); 
1278
1279         if (exists $ENV{SSVNC_TEST_SEC_SUBTYPE}) {
1280                 print STDERR "PPROXY: continuing on in test mode.\n";
1281         } else {
1282                 vdie if $subtype == 0;
1283         }
1284
1285         my $ok;
1286         sysread($sock, $ok, 1);
1287         $ok = unpack("C", $ok);
1288         print STDERR "ok=$ok\n" if $db;
1289
1290         append_handshake("done\n");
1291
1292         vdie if $ok == 0;
1293 }
1294
1295 sub vencrypt_dialog {
1296         my $vmode = shift;
1297         my $db = 0;
1298
1299         $db = 1 if exists $ENV{SS_DEBUG};
1300         $db = 1 if exists $ENV{SSVNC_VENCRYPT_DEBUG};
1301
1302         append_handshake("mode=$vmode\n");
1303
1304         my $server_rfb = "";
1305         #syswrite($sock, $rep, 250);
1306         for (my $i = 0; $i < 12; $i++) {
1307                 my $c;
1308                 sysread($sock, $c, 1);
1309                 $server_rfb .= $c;
1310                 print STDERR $c;
1311         }
1312         print STDERR "server_rfb: $server_rfb\n" if $db;
1313         append_handshake("server=$server_rfb");
1314
1315         my $minor = "";
1316         if ($server_rfb =~ /^RFB 003\.(\d+)/) {
1317                 $minor = $1;
1318         } else {
1319                 vdie;
1320         }
1321         my $viewer_rfb = "RFB 003.008\n";
1322         if ($minor < 7) {
1323                 vdie;
1324         } elsif ($minor == 7) {
1325                 $viewer_rfb = "RFB 003.007\n";
1326         }
1327         syswrite($sock, $viewer_rfb, 12);
1328         append_handshake("viewer=$viewer_rfb");
1329
1330         my $nsec;
1331
1332         sysread($sock, $nsec, 1);
1333         vdie if $nsec eq "";
1334
1335         $nsec = unpack("C", $nsec);
1336
1337         print STDERR "nsec: $nsec\n" if $db;
1338         vdie if $nsec eq 0 || $nsec > 100;
1339
1340         my %sectypes = ();
1341
1342         for (my $i = 0; $i < $nsec; $i++) {
1343                 my $sec;
1344                 sysread($sock, $sec, 1);
1345                 vdie if $sec eq "";
1346                 $sec = unpack("C", $sec);
1347                 print STDERR "sec: $sec\n" if $db;
1348                 $sectypes{$sec} = 1;
1349         }
1350         
1351         if (exists $sectypes{$rfbSecTypeVencrypt}) {
1352                 print STDERR "found rfbSecTypeVencrypt\n" if $db;
1353                 append_handshake("sectype=$rfbSecTypeVencrypt\n");
1354                 vencrypt_handshake($vmode, $db);
1355         } elsif (exists $sectypes{$rfbSecTypeAnonTls}) {
1356                 print STDERR "found rfbSecTypeAnonTls\n" if $db;
1357                 append_handshake("sectype=$rfbSecTypeAnonTls\n");
1358                 anontls_handshake($vmode, $db);
1359         } else {
1360                 print STDERR "No supported sec-type found\n" if $db;
1361                 vdie;
1362         }
1363 }
1364
1365 sub xfer {
1366         my($in, $out) = @_;
1367         $RIN = $WIN = $EIN = "";
1368         $ROUT = "";
1369         vec($RIN, fileno($in), 1) = 1;
1370         vec($WIN, fileno($in), 1) = 1;
1371         $EIN = $RIN | $WIN;
1372
1373         while (1) {
1374                 my $nf = 0;
1375                 while (! $nf) {
1376                         $nf = select($ROUT=$RIN, undef, undef, undef);
1377                 }
1378                 my $len = sysread($in, $buf, 8192);
1379                 if (! defined($len)) {
1380                         next if $! =~ /^Interrupted/;
1381                         print STDERR "pproxy\[$$]: $!\n";
1382                         last;
1383                 } elsif ($len == 0) {
1384                         print STDERR "pproxy\[$$]: Input is EOF.\n";
1385                         last;
1386                 }
1387                 my $offset = 0;
1388                 my $quit = 0;
1389                 while ($len) {
1390                         my $written = syswrite($out, $buf, $len, $offset);
1391                         if (! defined $written) {
1392                                 print STDERR "pproxy\[$$]: Output is EOF. $!\n";
1393                                 $quit = 1;
1394                                 last;
1395                         }
1396                         $len -= $written;
1397                         $offset += $written;
1398                 }
1399                 last if $quit;
1400         }
1401         close($in);
1402         close($out);
1403 }
1404 '
1405         # '
1406         # xpg_echo will expand \n \r, etc.
1407         # try to unset and then test for it.
1408         if type shopt > /dev/null 2>&1; then
1409                 shopt -u xpg_echo >/dev/null 2>&1
1410         fi
1411         v='print STDOUT "abc\n";'
1412         echo "$v" > $tf
1413         chmod 700 $tf
1414
1415         lc=`wc -l $tf | awk '{print $1}'`
1416         if [ "X$lc" = "X1" ]; then
1417                 echo "$cod" > $tf
1418         else
1419                 printf "%s" "$cod" > $tf
1420                 echo "" >> $tf
1421         fi
1422         # prime perl
1423         perl -e 'use IO::Socket::INET; select(undef, undef, undef, 0.01)' >/dev/null 2>&1
1424 }
1425
1426 # make_tcert is no longer invoked via the ssvnc gui (Listen mode).
1427 # make_tcert is for testing only now via -mycert BUILTIN
1428 make_tcert() {
1429         tcert="/tmp/ss_vnc_viewer_tcert${RANDOM}.$$"
1430         tcert=`mytmp "$tcert"`
1431         cat > $tcert <<END
1432 -----BEGIN RSA PRIVATE KEY-----
1433 MIIEowIBAAKCAQEAvkfXxb0wcxgrjV2ziFikjII+ze8iKcTBt47L0GM/c21efelN
1434 +zZpJUUXLu4zz8Ryq8Q+sQgfNy7uTOpN9bUUaOk1TnD7gaDQnQWiNHmqbW2kL+DS
1435 OKngJVPo9dETAS8hf7+D1e1DBZxjTc1a4RQqWJixwpYj99ixWzu8VC2m/xXsjvOs
1436 jp4+DLBB490nbkwvstmhmiWm1CmI5O5xOkgioVNQqHvQMdVKOSz9PpbjvZiRX1Uo
1437 qoMrk+2NOqwP90TB35yPASXb9zXKpO7DLhkube+yYGf+yk46aD707L07Eb7cosFP
1438 S84vNZ9gX7rQ0UOwm5rYA/oZTBskgaqhtIzkLwIDAQABAoIBAD4ot/sXt5kRn0Ca
1439 CIkU9AQWlC+v28grR2EQW9JiaZrqcoDNUzUqbCTJsi4ZkIFh2lf0TsqELbZYNW6Y
1440 6AjJM7al4E0UqYSKJTv2WCuuRxdiRs2BMwthqyBmjeanev7bB6V0ybt7u3Y8xU/o
1441 MrTuYnr4vrEjXPKdLirwk7AoDbKsRXHSIiHEIBOq1+dUQ32t36ukdnnza4wKDLZc
1442 PKHiCdCk/wOGhuDlxD6RspqUAlRnJ8/aEhrgWxadFXw1hRhRsf/v1shtB0T3DmTe
1443 Jchjwyiw9mryb9JZAcKxW+fUc4EVvj6VdQGqYInQJY5Yxm5JAlVQUJicuuJEvn6A
1444 rj5osQECgYEA552CaHpUiFlB4HGkjaH00kL+f0+gRF4PANCPk6X3UPDVYzKnzmuu
1445 yDvIdEETGFWBwoztUrOOKqVvPEQ+kBa2+DWWYaERZLtg2cI5byfDJxQ3ldzilS3J
1446 1S3WgCojqcsG/hlxoQJ1dZFanUy/QhUZ0B+wlC+Zp1Q8AyuGQvhHp68CgYEA0lBI
1447 eqq2GGCdJuNHMPFbi8Q0BnX55LW5C1hWjhuYiEkb3hOaIJuJrqvayBlhcQa2cGqp
1448 uP34e9UCfoeLgmoCQ0b4KpL2NGov/mL4i8bMgog4hcoYuIi3qxN18vVR14VKEh4U
1449 RLk0igAYPU+IK2QByaQlBo9OSaKkcfm7U1/pK4ECgYAxr6VpGk0GDvfF2Tsusv6d
1450 GIgV8ZP09qSLTTJvvxvF/lQYeqZq7sjI5aJD5i3de4JhpO/IXQJzfZfWOuGc8XKA
1451 3qYK/Y2IqXXGYRcHFGWV/Y1LFd55mCADHlk0l1WdOBOg8P5iRu/Br9PbiLpCx9oI
1452 vrOXpnp03eod1/luZmqguwKBgQCWFRSj9Q7ddpSvG6HCG3ro0qsNsUMTI1tZ7UBX
1453 SPogx4tLf1GN03D9ZUZLZVFUByZKMtPLX/Hi7K9K/A9ikaPrvsl6GEX6QYzeTGJx
1454 3Pw0amFrmDzr8ySewNR6/PXahxPEuhJcuI31rPufRRI3ZLah3rFNbRbBFX+klkJH
1455 zTnoAQKBgDbUK/aQFGduSy7WUT7LlM3UlGxJ2sA90TQh4JRQwzur0ACN5GdYZkqM
1456 YBts4sBJVwwJoxD9OpbvKu3uKCt41BSj0/KyoBzjT44S2io2tj1syujtlVUsyyBy
1457 /ca0A7WBB8lD1D7QMIhYUm2O9kYtSCLlUTHt5leqGaRG38DqlX36
1458 -----END RSA PRIVATE KEY-----
1459 -----BEGIN CERTIFICATE-----
1460 MIIDzDCCArQCCQDSzxzxqhyqLzANBgkqhkiG9w0BAQQFADCBpzELMAkGA1UEBhMC
1461 VVMxFjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxDzANBgNVBAcTBkJvc3RvbjETMBEG
1462 A1UEChMKTXkgQ29tcGFueTEcMBoGA1UECxMTUHJvZHVjdCBEZXZlbG9wbWVudDEZ
1463 MBcGA1UEAxMQd3d3Lm5vd2hlcmUubm9uZTEhMB8GCSqGSIb3DQEJARYSYWRtaW5A
1464 bm93aGVyZS5ub25lMB4XDTA3MDMyMzE4MDc0NVoXDTI2MDUyMjE4MDc0NVowgacx
1465 CzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNldHRzMQ8wDQYDVQQHEwZC
1466 b3N0b24xEzARBgNVBAoTCk15IENvbXBhbnkxHDAaBgNVBAsTE1Byb2R1Y3QgRGV2
1467 ZWxvcG1lbnQxGTAXBgNVBAMTEHd3dy5ub3doZXJlLm5vbmUxITAfBgkqhkiG9w0B
1468 CQEWEmFkbWluQG5vd2hlcmUubm9uZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
1469 AQoCggEBAL5H18W9MHMYK41ds4hYpIyCPs3vIinEwbeOy9BjP3NtXn3pTfs2aSVF
1470 Fy7uM8/EcqvEPrEIHzcu7kzqTfW1FGjpNU5w+4Gg0J0FojR5qm1tpC/g0jip4CVT
1471 6PXREwEvIX+/g9XtQwWcY03NWuEUKliYscKWI/fYsVs7vFQtpv8V7I7zrI6ePgyw
1472 QePdJ25ML7LZoZolptQpiOTucTpIIqFTUKh70DHVSjks/T6W472YkV9VKKqDK5Pt
1473 jTqsD/dEwd+cjwEl2/c1yqTuwy4ZLm3vsmBn/spOOmg+9Oy9OxG+3KLBT0vOLzWf
1474 YF+60NFDsJua2AP6GUwbJIGqobSM5C8CAwEAATANBgkqhkiG9w0BAQQFAAOCAQEA
1475 vGomHEp6TVU83X2EBUgnbOhzKJ9u3fOI/Uf5L7p//Vxqow7OR1cguzh/YEzmXOIL
1476 ilMVnzX9nj/bvcLAuqEP7MR1A8f4+E807p/L/Sf49BiCcwQq5I966sGKYXjkve+T
1477 2GTBNwMSq+5kLSf6QY8VZI+qnrAudEQMeJByQhTZZ0dH8Njeq8EGl9KUio+VWaiW
1478 CQK6xJuAvAHqa06OjLmwu1fYD4GLGSrOIiRVkSXV8qLIUmzxdJaIRznkFWsrCEKR
1479 wAH966SAOvd2s6yOHMvyDRIL7WHxfESB6rDHsdIW/yny1fBePjv473KrxyXtbz7I
1480 dMw1yW09l+eEo4A7GzwOdw==
1481 -----END CERTIFICATE-----
1482 END
1483         chmod 600 $tcert
1484         echo "$tcert"
1485 }
1486
1487 Kecho() {
1488         if [ "X$USER" = "Xrunge" ]; then
1489                 echo "dbg: $*"
1490         fi
1491 }
1492
1493 if [ "X$use_ssh" = "X1" ]; then
1494         #
1495         # USING SSH
1496         #
1497         ssh_port="22"
1498         ssh_host="$host"
1499         vnc_host="$localhost"
1500         # let user override ssh via $SSH
1501         ssh=${SSH:-"ssh -x"}
1502
1503         if [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" ]; then
1504                 SSVNC_LIM_ACCEPT_PRELOAD="$SSVNC_BASEDIR/$SSVNC_UNAME/$SSVNC_LIM_ACCEPT_PRELOAD"
1505         fi
1506         if [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" ]; then
1507                 echo ""
1508                 echo "SSVNC_LIM_ACCEPT_PRELOAD=$SSVNC_LIM_ACCEPT_PRELOAD"
1509         fi
1510
1511         if [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" -a -f "$SSVNC_LIM_ACCEPT_PRELOAD" ]; then
1512                 plvar=LD_PRELOAD
1513                 if uname | grep Darwin >/dev/null; then
1514                         plvar="DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES"
1515                 fi
1516                 ssh="env $plvar=$SSVNC_LIM_ACCEPT_PRELOAD $ssh"
1517         else
1518                 SSVNC_LIM_ACCEPT_PRELOAD=""
1519         fi
1520
1521         if echo "$proxy" | egrep '(http|https|socks|socks4|socks5)://' > /dev/null; then
1522                 # Handle Web or SOCKS proxy(ies) for the initial connect.
1523                 Kecho host=$host
1524                 Kecho port=$port
1525                 pproxy=""
1526                 sproxy1=""
1527                 sproxy_rest=""
1528                 for part in `echo "$proxy" | tr ',' ' '`
1529                 do
1530                         Kecho proxy_part=$part
1531                         if [ "X$part" = "X" ]; then
1532                                 continue
1533                         elif echo "$part" | egrep -i '^(http|https|socks|socks4|socks5)://' > /dev/null; then
1534                                 pproxy="$pproxy,$part"
1535                         else
1536                                 if [ "X$sproxy1" = "X" ]; then
1537                                         sproxy1="$part"
1538                                 else
1539                                         sproxy_rest="$sproxy_rest,$part"
1540                                 fi
1541                         fi
1542                 done
1543                 pproxy=`echo "$pproxy" | sed -e 's/^,,*//' -e 's/,,*/,/g'`
1544                 sproxy_rest=`echo "$sproxy_rest" | sed -e 's/^,,*//' -e 's/,,*/,/g'`
1545
1546                 Kecho pproxy=$pproxy
1547                 Kecho sproxy1=$sproxy1
1548                 Kecho sproxy_rest=$sproxy_rest
1549
1550                 sproxy1_host=""
1551                 sproxy1_port=""
1552                 sproxy1_user=""
1553
1554                 if [ "X$sproxy1" != "X" ]; then
1555                         sproxy1_host=`echo "$sproxy1" | awk -F: '{print $1}'`
1556                         sproxy1_user=`echo "$sproxy1_host" | awk -F@ '{print $1}'`
1557                         sproxy1_host=`echo "$sproxy1_host" | awk -F@ '{print $2}'`
1558                         if [ "X$sproxy1_host" = "X" ]; then
1559                                 sproxy1_host=$sproxy1_user
1560                                 sproxy1_user=""
1561                         else
1562                                 sproxy1_user="${sproxy1_user}@"
1563                         fi
1564                         sproxy1_port=`echo "$sproxy1" | awk -F: '{print $2}'`
1565                         if [ "X$sproxy1_port" = "X" ]; then
1566                                 sproxy1_port="22"
1567                         fi
1568                 else
1569                         sproxy1_host=`echo "$host" | awk -F: '{print $1}'`
1570                         sproxy1_user=`echo "$sproxy1_host" | awk -F@ '{print $1}'`
1571                         sproxy1_host=`echo "$sproxy1_host" | awk -F@ '{print $2}'`
1572                         if [ "X$sproxy1_host" = "X" ]; then
1573                                 sproxy1_host=$sproxy1_user
1574                                 sproxy1_user=""
1575                         else
1576                                 sproxy1_user="${sproxy1_user}@"
1577                         fi
1578                         sproxy1_port=`echo "$host" | awk -F: '{print $2}'`
1579                         if [ "X$sproxy1_port" = "X" ]; then
1580                                 sproxy1_port="22"
1581                         fi
1582                 fi
1583
1584                 Kecho sproxy1_host=$sproxy1_host
1585                 Kecho sproxy1_port=$sproxy1_port
1586                 Kecho sproxy1_user=$sproxy1_user
1587
1588                 ptmp="/tmp/ss_vncviewer_ssh${RANDOM}.$$.pl"
1589                 ptmp=`mytmp "$ptmp"`
1590                 PPROXY_REMOVE=1; export PPROXY_REMOVE
1591                 proxy=$pproxy
1592                 port_save=$port
1593                 host_save=$host
1594                 if [ "X$sproxy1_host" != "X" ]; then
1595                         host=$sproxy1_host
1596                 fi
1597                 if [ "X$sproxy1_port" != "X" ]; then
1598                         port=$sproxy1_port
1599                 fi
1600                 host=`echo "$host" | sed -e 's/^.*@//'`
1601                 port=`echo "$port" | sed -e 's/^.*://'`
1602                 pcode "$ptmp"
1603                 port=$port_save
1604                 host=$host_save
1605
1606                 nd=`findfree 6700`
1607                 PPROXY_LISTEN=$nd; export PPROXY_LISTEN
1608                 $ptmp &
1609                 sleep 2
1610                 ssh_args="$ssh_args -o NoHostAuthenticationForLocalhost=yes"
1611                 if [ "X$sproxy1" = "X" ]; then
1612                         u=""
1613                         if echo "$host" | grep '@' > /dev/null; then
1614                                 u=`echo "$host" | sed -e 's/@.*$/@/'`
1615                         fi
1616                         
1617                         proxy="${u}$localhost:$nd"
1618                 else
1619                         proxy="${sproxy1_user}$localhost:$nd"
1620                 fi
1621                 if [ "X$sproxy_rest" != "X" ]; then
1622                         proxy="$proxy,$sproxy_rest"
1623                 fi
1624                 Kecho proxy=$proxy
1625         fi
1626
1627         if echo "$proxy" | grep "," > /dev/null; then
1628
1629                 proxy1=`echo "$proxy" | awk -F, '{print $1}'`
1630                 proxy2=`echo "$proxy" | awk -F, '{print $2}'`
1631
1632                 # user1@gw1.com:port1,user2@ws2:port2
1633                 ssh_host1=`echo "$proxy1" | awk -F: '{print $1}'`
1634                 ssh_port1=`echo "$proxy1" | awk -F: '{print $2}'`
1635                 if [ "X$ssh_port1" != "X" ]; then
1636                         ssh_port1="-p $ssh_port1"
1637                 fi
1638                 ssh_host2=`echo "$proxy2" | awk -F: '{print $1}'`
1639                 ssh_user2=`echo "$ssh_host2" | awk -F@ '{print $1}'`
1640                 ssh_host2=`echo "$ssh_host2" | awk -F@ '{print $2}'`
1641                 if [ "X$ssh_host2" = "X" ]; then
1642                         ssh_host2=$ssh_user2
1643                         ssh_user2=""
1644                 else
1645                         ssh_user2="${ssh_user2}@"
1646                 fi
1647                 ssh_port2=`echo "$proxy2" | awk -F: '{print $2}'`
1648                 if [ "X$ssh_port2" = "X" ]; then
1649                         ssh_port2="22"
1650                 fi
1651                 proxport=`findfree 3500`
1652                 echo
1653                 echo "Running 1st ssh proxy:"
1654                 echo "$ssh -f -x $ssh_port1 $targ -e none -o NoHostAuthenticationForLocalhost=yes -L $proxport:$ssh_host2:$ssh_port2 $ssh_host1 \"sleep 30\""
1655                 echo ""
1656                       $ssh -f -x $ssh_port1 $targ -e none -o NoHostAuthenticationForLocalhost=yes -L $proxport:$ssh_host2:$ssh_port2 $ssh_host1 "sleep 30"
1657                 ssh_args="$ssh_args -o NoHostAuthenticationForLocalhost=yes"
1658                 sleep 1
1659                 stty sane
1660                 proxy="${ssh_user2}$localhost:$proxport"
1661         fi
1662
1663         if [ "X$proxy" != "X" ]; then
1664                 ssh_port=`echo "$proxy" | awk -F: '{print $2}'`
1665                 if [ "X$ssh_port" = "X" ]; then
1666                         ssh_port="22"
1667                 fi
1668                 ssh_host=`echo "$proxy" | awk -F: '{print $1}'`
1669                 vnc_host="$host"
1670         fi
1671
1672         echo ""
1673         echo "Running ssh:"
1674         sz=`echo "$ssh_cmd" | wc -c`
1675         if [ "$sz" -gt 300 ]; then
1676                 info="..."
1677         else
1678                 info="$ssh_cmd"
1679         fi
1680
1681         C=""
1682         if [ "X$SS_VNCVIEWER_USE_C" != "X" ]; then
1683                 C="-C"
1684         fi
1685
1686         getport=""
1687         teeport=""
1688         if echo "$ssh_cmd" | egrep "(PORT=|P=) " > /dev/null; then
1689                 getport=1
1690                 if echo "$ssh_cmd" | egrep "P= " > /dev/null; then
1691                         teeport=1
1692                 fi
1693
1694                 PORT=""
1695                 ssh_cmd=`echo "$ssh_cmd" | sed -e 's/PORT=[     ]*//' -e 's/P=//'`
1696                 SSVNC_NO_ENC_WARN=1
1697                 if [ "X$use_sshssl" = "X" ]; then
1698                         direct_connect=1
1699                 fi
1700         fi
1701         if [ "X$getport" != "X" ]; then
1702                 ssh_redir="-D ${use}"
1703         elif [ "X$reverse" = "X" ]; then
1704                 ssh_redir="-L ${use}:${vnc_host}:${port}"
1705         else
1706                 ssh_redir="-R ${port}:${vnc_host}:${use}"
1707         fi
1708         pmark=`sh -c 'echo $$'`
1709
1710         # the -t option actually speeds up typing response via VNC!!
1711         if [ "X$ssh_port" = "X22" ]; then
1712                 ssh_port=""
1713         else
1714                 ssh_port="-p $ssh_port"
1715         fi
1716
1717         if [ "X$SS_VNCVIEWER_SSH_ONLY" != "X" ]; then
1718                 echo "$ssh -x $ssh_port $targ $C $ssh_args $ssh_host \"$info\""
1719                 echo ""
1720                 $ssh -x $ssh_port $targ $C $ssh_args $ssh_host "$ssh_cmd"
1721                 exit $?
1722
1723         elif [ "X$SS_VNCVIEWER_NO_F" != "X" ]; then
1724                 echo "$ssh -x $ssh_port $targ $C $ssh_redir $ssh_args $ssh_host \"$info\""
1725                 echo ""
1726                 $ssh -x $ssh_port $targ $C $ssh_redir $ssh_args $ssh_host "$ssh_cmd"
1727                 rc=$?
1728
1729         elif [ "X$getport" != "X" ]; then
1730                 tport=/tmp/ss_vncviewer_tport${RANDOM}.$$
1731                 tport=`mytmp "$tport"`
1732
1733                 if [ "X$rsh" != "X1" ]; then
1734                         if echo "$ssh_cmd" | grep "sudo " > /dev/null; then
1735                                 echo ""
1736                                 echo "Initial ssh with 'sudo id' to prime sudo so hopefully the next one"
1737                                 echo "will require no password..."
1738                                 echo ""
1739                                 targ="-t"
1740                                 $ssh -x $ssh_port $targ $ssh_args $ssh_host "sudo id; tty"
1741                                 echo ""
1742                         fi
1743                         echo "$ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args $ssh_host \"$info\""
1744                         echo ""
1745                         $ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args $ssh_host "$ssh_cmd" > $tport 
1746                         if [ "X$teeport" = "X1" ]; then
1747                                 tail -f $tport 1>&2 &
1748                                 tail_pid=$!
1749                         fi
1750                         rc=$?
1751                 else
1752                         rsh_setup
1753                         echo "rsh $ul $ssh_host \"$ssh_cmd\""
1754                         echo ""
1755                         rsh $ul $ssh_host "$ssh_cmd" > $tport &
1756                         sleep 1
1757                         rc=0
1758                 fi
1759
1760                 if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then
1761                         echo "sleep $SSVNC_EXTRA_SLEEP"
1762                         sleep $SSVNC_EXTRA_SLEEP
1763                 fi
1764
1765                 stty sane
1766                 i=0
1767                 if type perl > /dev/null 2>&1; then
1768                         imax=50
1769                         sleepit="perl -e 'select(undef, undef, undef, 0.20)'"
1770                 else
1771                         imax=10
1772                         sleepit="sleep 1"
1773                 fi
1774                 while [ $i -lt $imax ]; do
1775                         #echo $sleepit
1776                         eval $sleepit
1777                         PORT=`grep "^PORT=" $tport | head -n 1 | sed -e 's/PORT=//' -e 's/\r//g'`
1778                         if echo "$PORT" | grep '^[0-9][0-9]*$' > /dev/null; then
1779                                 break
1780                         fi
1781                         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 | awk '{print $NF}'`
1782                         if [ "X$vnss" != "X" ]; then
1783                                 PORT=`echo "$vnss" | awk -F: '{print $2}'`
1784                                 if echo "$PORT" | grep '^[0-9][0-9]*$' > /dev/null; then
1785                                         if [ $PORT -lt 100 ]; then
1786                                                 PORT=`expr $PORT + 5900`
1787                                         fi
1788                                 fi
1789                                 if echo "$PORT" | grep '^[0-9][0-9]*$' > /dev/null; then
1790                                         break
1791                                 fi
1792                         fi
1793                         i=`expr $i + 1`
1794                 done
1795
1796                 echo "PORT=$PORT" 1>&2
1797                 rm -f $tport
1798                 if [ "X$rsh" = "X1" ]; then
1799                         rsh_viewer "$@"
1800                         exit $?
1801                 fi
1802                 PPROXY_SOCKS=1
1803                 if [ "X$SSVNC_SOCKS5" != "X" ]; then
1804                         PPROXY_SOCKS=5
1805                 fi
1806                 export PPROXY_SOCKS
1807                 host="$localhost"
1808                 port="$PORT"
1809                 proxy="$localhost:$use"
1810
1811         else
1812                 if [ "X$rsh" != "X1" ]; then
1813                         echo "$ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args $ssh_host \"$info\""
1814                         echo ""
1815                         $ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args $ssh_host "$ssh_cmd"
1816                         rc=$?
1817                 else
1818                         rsh_setup
1819                         echo "rsh $ul $ssh_host \"$ssh_cmd\""
1820                         echo ""
1821                         rsh $ul $ssh_host "$ssh_cmd" &
1822                         sleep 1
1823                         PORT=$port
1824                         rsh_viewer "$@"
1825                         exit $?
1826                 fi
1827         fi
1828
1829         if [ "$rc" != "0" ]; then
1830                 echo ""
1831                 echo "ssh to $ssh_host failed."
1832                 exit 1
1833         fi
1834         stty sane
1835
1836         c=0
1837         pssh=""
1838         while [ $c -lt 40 ]
1839         do
1840                 p=`expr $pmark + $c`
1841                 pout=`ps -p "$p" 2>/dev/null | grep -v '^[      ]*PID' | sed -e 's/-L.*$//' -e 's/-x .*$//'`
1842                 if echo "$pout" | grep "ssh" > /dev/null; then
1843                         if echo "$pout" | egrep -i 'ssh.*(-add|-agent|-ask|-keygen|-argv0|vnc)' >/dev/null; then
1844                                 :
1845                         elif echo "$pout" | egrep -i 'scp|sshd' >/dev/null; then
1846                                 :
1847                         else
1848                                 pssh=$p
1849                                 break
1850                         fi
1851                 fi
1852                 c=`expr $c + 1`
1853         done
1854         if [ "X$getport" != "X" ]; then
1855                 :
1856         elif [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" ] ; then
1857                 sleep 2
1858         elif [ "X$ssh_cmd" = "Xsleep $ssh_sleep" ] ; then
1859                 #echo T sleep 1
1860                 sleep 1
1861         elif echo "$ssh_cmd" | grep '^sleep ' >/dev/null; then
1862                 #echo T sleep 2
1863                 sleep 2
1864         else
1865                 # let any command get started a bit.
1866                 #echo T sleep 5
1867                 sleep 5
1868         fi
1869         echo ""
1870         #reset
1871         stty sane
1872         if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then
1873                 echo "sleep $SSVNC_EXTRA_SLEEP"
1874                 sleep $SSVNC_EXTRA_SLEEP
1875         fi
1876         echo "ssh_pid='$pssh'"; echo
1877         if [ "X$use_sshssl" = "X" -a "X$getport" = "X" ]; then
1878                 echo "Running viewer:"
1879
1880                 trap "final" 0 2 15
1881                 if [ "X$reverse" = "X" ]; then
1882                         echo "$VNCVIEWERCMD" "$@" $localhost:$N
1883                         echo ""
1884                         $VNCVIEWERCMD "$@" $localhost:$N
1885                         if [ $? != 0 ]; then
1886                                 echo "vncviewer command failed: $?"
1887                                 if [ "X$secondtry" = "X1" ]; then
1888                                         sleep 2
1889                                         $VNCVIEWERCMD "$@" $localhost:$N
1890                                 fi
1891                         fi
1892                 else
1893                         echo ""
1894                         echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode."
1895                         echo ""
1896                         N2=$N
1897                         if [ "X$VNCVIEWER_IS_REALVNC4" = "X1" ]; then
1898                                 N2=`echo "$N2" | sed -e 's/://g'`
1899                                 if [ $N2 -le 200 ]; then
1900                                         N2=`expr $N2 + 5500`
1901                                 fi
1902                         fi
1903                         echo "$VNCVIEWERCMD" "$@" -listen $N2
1904                         echo ""
1905                         $VNCVIEWERCMD "$@" -listen $N2
1906                 fi
1907
1908                 exit $?
1909         else
1910                 use2=`findfree 5960`
1911                 host0=$host
1912                 port0=$port
1913                 host=$localhost
1914                 port=$use
1915                 use=$use2
1916                 N=`expr $use - 5900`
1917                 if [ "X$getport" != "X" ]; then
1918                         host="$host0"
1919                         port="$port0"
1920                 else
1921                         proxy=""
1922                 fi
1923         fi
1924 fi
1925
1926 # create the stunnel config file:
1927 if [ "X$verify" != "X" ]; then
1928         if [ -d $verify ]; then
1929                 verify="CApath = $verify"
1930         else
1931                 verify="CAfile = $verify"
1932         fi
1933         verify="$verify
1934 verify = 2"
1935 fi
1936 if [ "X$mycert" != "X" ]; then
1937         cert="cert = $mycert"
1938 fi
1939 if [ "X$crl" != "X" ]; then
1940         if [ -d $crl ]; then
1941                 crl="CRLpath = $crl"
1942         else
1943                 crl="CRLfile = $crl"
1944         fi
1945 fi
1946
1947 ptmp=""
1948 if [ "X$proxy" != "X" ]; then
1949         ptmp="/tmp/ss_vncviewer${RANDOM}.$$.pl"
1950         ptmp=`mytmp "$ptmp"`
1951         PPROXY_REMOVE=1; export PPROXY_REMOVE
1952         pcode "$ptmp"
1953         if [ "X$showcert" != "X1" -a "X$direct_connect" = "X" ]; then
1954                 if uname | egrep 'Darwin|SunOS' >/dev/null; then
1955                         vout=`echo "$proxy" | grep -i vencrypt`
1956                         if [ "X$vout" != "X" -a "X$reverse" = "X1" ]; then
1957                                 # need to exec for reverse vencrypt
1958                                 connect="exec = $ptmp"
1959                         else
1960                                 # on mac and solaris we need to listen on socket instead of stdio:
1961                                 nd=`findfree 6700`
1962                                 PPROXY_LISTEN=$nd
1963                                 export PPROXY_LISTEN
1964                                 if [ "X$reverse" = "X" ]; then
1965                                         #$ptmp 2>/dev/null &
1966                                         $ptmp &
1967                                 fi
1968                                 sleep 2
1969                                 host="$localhost"
1970                                 port="$nd"
1971                                 connect="connect = $localhost:$nd"
1972                         fi
1973                 else
1974                         # otherwise on unix we can exec it:
1975                         connect="exec = $ptmp"
1976                 fi
1977         else
1978                 connect="exec = $ptmp"
1979         fi
1980 else
1981         connect="connect = $host:$port"
1982 fi
1983
1984 if [ "X$showcert" = "X1" ]; then
1985         if [ "X$proxy" != "X" ]; then
1986                 PPROXY_LISTEN=$use
1987                 export PPROXY_LISTEN
1988                 if [ "X$SS_DEBUG" != "X" ]; then
1989                         $ptmp &
1990                 else
1991                         $ptmp 2>/dev/null &
1992                 fi
1993                 sleep 1
1994                 host="$localhost"
1995                 port="$use"
1996         fi
1997         cipher_args=""
1998         if [ "X$ciphers" != "X" ]; then
1999                 cipher_args=`echo "$ciphers" | sed -e 's/ciphers=/-cipher /'`
2000         fi
2001         #echo "openssl s_client $cipher_args -connect $host:$port" 
2002         if [ "X$reverse" = "X" ]; then
2003                 openssl s_client $cipher_args -prexit -connect $host:$port 2>&1 < /dev/null
2004                 rc=$?
2005         else
2006                 tcert=""
2007                 if [ "X$mycert" = "X" ]; then
2008                         tcert=`make_tcert`
2009                         cert_args="-cert $tcert -CAfile $tcert"
2010                 else
2011                         cert_args="-cert $mycert -CAfile $mycert"
2012                 fi
2013                 tmp_out=/tmp/showcert_out${RANDOM}.$$
2014                 tmp_out=`mytmp "$tmp_out"`
2015                 tmp_err=/tmp/showcert_err${RANDOM}.$$
2016                 tmp_err=`mytmp "$tmp_err"`
2017
2018                 #echo "openssl s_server $cipher_args $cert_args -accept $port -verify 2 > $tmp_out 2> $tmp_err" 1>&2
2019
2020                 perl -e "
2021                         \$p = open(O, \"|openssl s_server $cipher_args $cert_args -accept $port -verify 2 1>$tmp_out 2> $tmp_err\");
2022                         exit 1 unless \$p;
2023                         while (1) {
2024                                 sleep 1;
2025                                 if (!open(F, \"<$tmp_out\")) {
2026                                         kill \$p;
2027                                         exit 1;
2028                                 }
2029                                 while (<F>) {
2030                                         if (/RFB 00/) {
2031                                                 fsleep(0.25);
2032                                                 print O \"RFB 000.000\\n\";
2033                                                 fsleep(1.00);
2034                                                 kill \$p;
2035                                                 fsleep(0.25);
2036                                                 exit 0;
2037                                         }
2038                                 }
2039                                 close F;
2040                         }
2041                         sub fsleep {
2042                                 select(undef, undef, undef, shift);
2043                         }
2044                 ";
2045
2046                 echo ""
2047                 cat $tmp_out
2048                 echo ""
2049                 echo "----2----"
2050                 cat $tmp_err
2051                 if grep BEGIN.CERTIFICATE $tmp_out >/dev/null; then
2052                         rc=0
2053                 else
2054                         rc=1
2055                 fi
2056
2057                 rm -f $tmp_out $tmp_err
2058         fi
2059         if [ "X$SSVNC_PREDIGESTED_HANDSHAKE" != "X" ]; then
2060                 rm -f $SSVNC_PREDIGESTED_HANDSHAKE
2061         fi
2062         exit $rc
2063 fi
2064
2065 if [ "X$direct_connect" != "X" ]; then
2066         if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then
2067                 SSVNC_NO_ENC_WARN=1
2068                 echo ""
2069                 echo "Using UltraVNC DSM Plugin key for encryption:"
2070                 echo ""
2071                 ustr=`echo "$SSVNC_ULTRA_DSM" | sed -e 's/pw=[^ ]*/pw=******/g'`
2072                 echo "  $ustr PORT HOST:PORT"
2073                 echo ""
2074         elif [ "X$getport" = "X" ]; then
2075                 echo ""
2076                 echo "Running viewer for direct connection:"
2077                 if echo X"$@" | grep chatonly > /dev/null; then
2078                         :
2079                 else
2080                         echo ""
2081                         echo "** NOTE: THERE WILL BE NO SSL OR SSH ENCRYPTION **"
2082                         echo ""
2083                 fi
2084         fi
2085         x=""
2086         if [ "X$SSVNC_NO_ENC_WARN" != "X" ]; then
2087                 if [ "X$getport" = "X" ]; then
2088                         sleep 1
2089                 fi
2090         elif type printf > /dev/null 2>&1; then
2091                 printf  "Are you sure you want to continue? [y]/n "
2092                 read x
2093         else
2094                 echo -n "Are you sure you want to continue? [y]/n "
2095                 read x
2096         fi
2097         if [ "X$x" = "Xn" ]; then
2098                 exit 1
2099         fi
2100         echo ""
2101         if [ "X$ptmp" != "X" ]; then
2102                 if [ "X$reverse" = "X" ]; then
2103                         PPROXY_LISTEN=$use
2104                         export PPROXY_LISTEN
2105                 else
2106                         PPROXY_REVERSE="$localhost:$use"
2107                         export PPROXY_REVERSE
2108                         pps=3
2109                         if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then
2110                                 pps=`expr $pps + $SSVNC_EXTRA_SLEEP`
2111                         fi
2112                         PPROXY_SLEEP=$pps; export PPROXY_SLEEP;
2113                         PPROXY_KILLPID=+1; export PPROXY_KILLPID;
2114                 fi
2115
2116                 $ptmp &
2117
2118                 if [ "X$reverse" = "X" ]; then
2119                         #sleep 2
2120                         #echo T sleep 1
2121                         sleep 1
2122                 fi
2123                 host="$localhost"
2124                 disp="$N"
2125                 port=`expr $disp + 5900`
2126         fi
2127         if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then
2128                 echo "T sleep $SSVNC_EXTRA_SLEEP"
2129                 sleep $SSVNC_EXTRA_SLEEP
2130         fi
2131         if [ "X$reverse" = "X" ]; then
2132                 hostdisp="$host:$disp"
2133                 if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then
2134                         if [ "X$SSVNC_USE_OURS" = "X1" ]; then
2135                                 hostdisp="exec=$SSVNC_ULTRA_DSM 0 $host:$port"
2136                         else
2137                                 pf=`findfree 5970`
2138                                 cmd="$SSVNC_ULTRA_DSM -$pf $host:$port"
2139                                 pf=`expr $pf - 5900`
2140                                 hostdisp="$localhost:$pf"
2141                                 ustr=`echo "$cmd" | sed -e 's/pw=[^ ]*/pw=******/g'`
2142                                 echo "Running:"
2143                                 echo
2144                                 echo "$ustr &"
2145                                 echo
2146                                 $cmd &
2147                                 dsm_pid=$!
2148                                 sleep 2
2149                         fi
2150                 fi
2151                 hostdisp2=`echo "$hostdisp" | sed -e 's/pw=[^ ]*/pw=******/g'`
2152                 echo "$VNCVIEWERCMD" "$@" "$hostdisp2"
2153                 trap "final" 0 2 15
2154                 echo ""
2155                 $VNCVIEWERCMD "$@" "$hostdisp"
2156                 if [ $? != 0 ]; then
2157                         echo "vncviewer command failed: $?"
2158                         if [ "X$secondtry" = "X1" ]; then
2159                                 sleep 2
2160                                 $VNCVIEWERCMD "$@" "$hostdisp"
2161                         fi
2162                 fi
2163         else
2164                 echo ""
2165                 echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode."
2166                 echo ""
2167                 trap "final" 0 2 15
2168                 if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then
2169                         echo "NOTE: The ultravnc_dsm_helper only runs once.  So after the first LISTEN"
2170                         echo "      ends, you may have to Press Ctrl-C and restart for another connection."
2171                         echo ""
2172                         SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE
2173                         VNCVIEWER_LISTEN_LOCALHOST=1
2174                         export VNCVIEWER_LISTEN_LOCALHOST
2175                         dport=`expr 5500 + $disp`
2176                         cmd="$SSVNC_ULTRA_DSM $dport $localhost:$use"
2177                         ustr=`echo "$cmd" | sed -e 's/pw=[^ ]*/pw=******/g'`
2178                         echo "Running:"
2179                         echo
2180                         echo "$ustr &"
2181                         echo
2182                         $cmd &
2183                         dsm_pid=$!
2184                         sleep 2
2185                         disp=$use
2186                         if [ $disp -ge 5500 ]; then
2187                                 disp=`expr $disp - 5500`
2188                         fi
2189                 fi
2190                 disp2=$disp
2191                 if [ "X$VNCVIEWER_IS_REALVNC4" = "X1" ]; then
2192                         disp2=`echo "$disp2" | sed -e 's/://g'`
2193                         if [ $disp2 -le 200 ]; then
2194                                 disp2=`expr $disp2 + 5500`
2195                         fi
2196                 fi
2197                 echo "$VNCVIEWERCMD" "$@" -listen $disp2
2198                 echo ""
2199                 $VNCVIEWERCMD "$@" -listen $disp2
2200         fi
2201         exit $?
2202 fi
2203
2204 tmp_cfg=/tmp/ss_vncviewer${RANDOM}.$$
2205 tmp_cfg=`mytmp "$tmp_cfg"`
2206
2207 stunnel_exec=""
2208 if [ "X$SSVNC_USE_OURS" != "X1" ]; then
2209         :
2210 elif echo $STUNNEL_EXTRA_SVC_OPTS | grep '#stunnel-exec' > /dev/null; then
2211         stunnel_exec="#"
2212 fi
2213
2214 if [ "X$reverse" = "X" ]; then
2215
2216         if echo "$proxy" | grep "^repeater://" > /dev/null; then
2217                 if [ "X$cert" = "XBUILTIN" ]; then
2218                         ttcert=`make_tcert`
2219                         cert="cert = $ttcert"
2220                 fi
2221                 # Note for listen mode, an empty cert will cause stunnel to fail.
2222                 # The ssvnc gui will have already taken care of this.
2223         fi
2224
2225         cat > "$tmp_cfg" <<END
2226 foreground = yes
2227 pid =
2228 client = yes
2229 debug = $stunnel_debug
2230 $ciphers
2231 $STUNNEL_EXTRA_OPTS
2232 $STUNNEL_EXTRA_OPTS_USER
2233 $cert
2234 $crl
2235 $verify
2236
2237 ${stunnel_exec}[vnc_stunnel]
2238 ${stunnel_exec}accept = $localhost:$use
2239 $connect
2240 $STUNNEL_EXTRA_SVC_OPTS
2241 $STUNNEL_EXTRA_SVC_OPTS_USER
2242
2243 END
2244
2245 else
2246         # REVERSE case:
2247
2248         stunnel_exec="" # doesn't work for listening.
2249
2250         p2=`expr 5500 + $N`
2251         connect="connect = $localhost:$p2"
2252         if [ "X$cert" = "XBUILTIN" ]; then
2253                 ttcert=`make_tcert`
2254                 cert="cert = $ttcert"
2255         fi
2256         # Note for listen mode, an empty cert will cause stunnel to fail.
2257         # The ssvnc gui will have already taken care of this.
2258
2259
2260         hloc=""
2261         if [ "X$use_ssh" = "X1" ]; then
2262                 hloc="$localhost:"
2263         fi
2264         if echo "$proxy" | grep -i '^vencrypt:' > /dev/null; then
2265                 hloc="$localhost:"
2266                 pv=`findfree 5570`
2267                 proxy="vencrypt:$pv:$port"
2268                 port=$pv
2269                 if [ "X$anondh_set" = "X1" ]; then
2270                         # not needed for ANONDH in this mode
2271                         #ciphers="ciphers = ADH:@STRENGTH"
2272                         :
2273                 fi
2274         fi
2275         cat > "$tmp_cfg" <<END
2276 foreground = yes
2277 pid =
2278 client = no
2279 debug = $stunnel_debug
2280 $ciphers
2281 $STUNNEL_EXTRA_OPTS
2282 $STUNNEL_EXTRA_OPTS_USER
2283 $cert
2284 $crl
2285 $verify
2286
2287 [vnc_stunnel]
2288 accept = $hloc$port
2289 $connect
2290 $STUNNEL_EXTRA_SVC_OPTS
2291 $STUNNEL_EXTRA_SVC_OPTS_USER
2292
2293 END
2294
2295 fi
2296
2297 echo ""
2298 echo "Using this stunnel configuration:"
2299 echo ""
2300 cat "$tmp_cfg" | uniq
2301 echo ""
2302 sleep 1
2303
2304 if [ "X$stunnel_exec" = "X" ]; then
2305         echo ""
2306         echo "Running stunnel:"
2307         echo "$STUNNEL $tmp_cfg"
2308         st=`echo "$STUNNEL" | awk '{print $1}'`
2309         $st -help > /dev/null 2>&1
2310         $STUNNEL "$tmp_cfg" < /dev/tty > /dev/tty &
2311         stunnel_pid=$!
2312         echo ""
2313
2314         # pause here to let the user supply a possible passphrase for the
2315         # mycert key:
2316         if [ "X$mycert" != "X" ]; then
2317                 nsl=10
2318                 dsl=0
2319                 if [ ! -f $mycert ]; then
2320                         dsl=0
2321                 elif grep -i 'Proc-Type.*ENCRYPTED' "$mycert" > /dev/null 2>/dev/null; then
2322                         dsl=1
2323                 fi
2324                 if [ "X$dsl" = "X1" ]; then
2325                         echo ""
2326                         echo "(** pausing $nsl secs for possible certificate passphrase dialog **)"
2327                         echo ""
2328                         sleep $nsl
2329                         echo "(** done pausing for passphrase **)"
2330                         echo ""
2331                 fi
2332         fi
2333         #echo T sleep 1
2334         sleep 1
2335         rm -f "$tmp_cfg"
2336 fi
2337
2338
2339 echo ""
2340 if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then
2341         echo "sleep $SSVNC_EXTRA_SLEEP"
2342         sleep $SSVNC_EXTRA_SLEEP
2343 fi
2344 echo "Running viewer:"
2345 if [ "X$reverse" = "X" ]; then
2346         vnc_hp=$localhost:$N
2347         if [ "X$stunnel_exec" != "X" ]; then
2348                 vnc_hp="exec=$STUNNEL $tmp_cfg"
2349         fi
2350         echo "$VNCVIEWERCMD" "$@" "$vnc_hp"
2351         trap "final" 0 2 15
2352         echo ""
2353         $VNCVIEWERCMD "$@" "$vnc_hp"
2354         if [ $? != 0 ]; then
2355                 echo "vncviewer command failed: $?"
2356                 if [ "X$secondtry" = "X1" ]; then
2357                         sleep 2
2358                         $VNCVIEWERCMD "$@" "$vnc_hp"
2359                 fi
2360         fi
2361 else
2362         echo ""
2363         echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode."
2364         echo ""
2365         N2=$N
2366         if [ "X$VNCVIEWER_IS_REALVNC4" = "X1" ]; then
2367                 N2=`echo "$N2" | sed -e 's/://g'`
2368                 if [ $N2 -le 200 ]; then
2369                         N2=`expr $N2 + 5500`
2370                 fi
2371         fi
2372         echo "$VNCVIEWERCMD" "$@" -listen $N2
2373         trap "final" 0 2 15
2374         echo ""
2375         if [ "X$proxy" != "X" ]; then
2376                 if echo "$proxy" | grep -i '^vencrypt:' > /dev/null; then
2377                         pstunnel=`echo "$proxy" | awk -F: '{print $2}'`
2378                         plisten=`echo "$proxy" | awk -F: '{print $3}'`
2379                         PPROXY_LISTEN="INADDR_ANY:$plisten"; export PPROXY_LISTEN
2380                         PPROXY_PROXY="vencrypt://$localhost:$pstunnel"; export PPROXY_PROXY
2381                         PPROXY_DEST="$localhost:$pstunnel"; export PPROXY_DEST
2382                         STUNNEL_ONCE=1; export STUNNEL_ONCE
2383                         STUNNEL_MAX_CLIENTS=1; export STUNNEL_MAX_CLIENTS
2384                 else
2385                         PPROXY_REVERSE="$localhost:$port"; export PPROXY_REVERSE
2386                         PPROXY_SLEEP=1; export PPROXY_SLEEP;
2387                 fi
2388                 PPROXY_KILLPID=+1; export PPROXY_KILLPID;
2389                 $ptmp &
2390         fi
2391         $VNCVIEWERCMD "$@" -listen $N2
2392 fi
2393
2394 sleep 1