Home | History | Annotate | Download | only in util
      1 #!/bin/sh
      2 # the next line restarts using wish \
      3 exec wish "$0" "$@"
      4 
      5 #
      6 # Copyright (c) 2006-2010 by Karl J. Runge <runge (at) karlrunge.com>
      7 #
      8 # ssvnc.tcl: gui wrapper to the programs in this
      9 # package. Also sets up service port forwarding.
     10 #
     11 set version 1.0.28
     12 
     13 set buck_zero $argv0
     14 
     15 proc center_win {w} {
     16 	global is_windows
     17 	update
     18 	set W [winfo screenwidth  $w]
     19 	set W [expr $W + 1]
     20 	wm geometry $w +$W+0
     21 	update
     22 	set x [expr [winfo screenwidth  $w]/2 - [winfo width  $w]/2]
     23 	set y [expr [winfo screenheight $w]/2 - [winfo height $w]/2]
     24 
     25 	if {$is_windows} {
     26 		set y [expr "$y - 30"]
     27 		if {$y <= 0} {
     28 			set y 1
     29 		}
     30 	}
     31 	wm geometry $w +$x+$y
     32 	wm deiconify $w
     33 	update
     34 }
     35 
     36 proc small_height {} {
     37 	set H [winfo screenheight .]
     38 	if {$H < 700} {
     39 		return 1
     40 	} else {
     41 		return 0
     42 	}
     43 }
     44 
     45 proc mac_raise {} {
     46 	global uname
     47 	if {$uname == "Darwin"} {
     48 		catch {exec /bin/sh -c {osascript -e 'tell application "Wish Shell" to activate' >/dev/null 2>&1 &}}
     49 		after 150
     50 		update
     51 		update idletasks
     52 	}
     53 }
     54 
     55 proc toplev {w} {
     56 	catch {destroy $w}
     57 	toplevel $w
     58 	catch {wm withdraw $w}
     59 }
     60 
     61 proc apply_bg {w} {
     62 	global is_windows system_button_face
     63 	if {$is_windows && $system_button_face != ""} {
     64 		catch {$w configure -bg "$system_button_face"}
     65 	}
     66 }
     67 
     68 proc line_count {{str ""} {pad 0}} {
     69 	set n $pad
     70 	foreach l [split $str "\n"] {
     71 		incr n
     72 	}
     73 	return $n
     74 }
     75 
     76 proc scroll_text {fr {w 80} {h 35}} {
     77 	global help_font is_windows scroll_text_focus
     78 
     79 	if {$h == 35 && [small_height]} {
     80 		set h 28
     81 	}
     82 	catch {destroy $fr}
     83 
     84 	frame $fr -bd 0
     85 
     86 	eval text $fr.t -width $w -height $h $help_font \
     87 		 -setgrid 1 -bd 2 -yscrollcommand {"$fr.y set"} -relief ridge
     88 
     89 	apply_bg $fr.t
     90 
     91 	scrollbar $fr.y -orient v -relief sunken -command "$fr.t yview"
     92 	pack $fr.y -side right -fill y
     93 	pack $fr.t -side top -fill both -expand 1
     94 
     95 	if {$scroll_text_focus} {
     96 		focus $fr.t
     97 	}
     98 }
     99 
    100 proc scroll_text_dismiss {fr {w 80} {h 35}} {
    101 	global help_font
    102 
    103 	if {$h == 35 && [small_height]} {
    104 		set h 28
    105 	}
    106 	scroll_text $fr $w $h
    107 
    108 	set up $fr
    109 	regsub {\.[^.]*$} $up "" up
    110 
    111 	button $up.d -text "Dismiss" -command "destroy $up"
    112 	bind $up <Escape> "destroy $up"
    113 	pack $up.d -side bottom -fill x
    114 	pack $fr -side top -fill both -expand 1
    115 }
    116 
    117 proc jiggle_text {w} {
    118 	global uname
    119 	if {$uname == "Darwin"} {
    120 		$w yview scroll 1 pages
    121 		update idletasks
    122 		$w yview scroll -1 pages
    123 		update idletasks
    124 	}
    125 }
    126 
    127 proc ts_help {} {
    128 	toplev .h
    129 
    130 	scroll_text_dismiss .h.f
    131 
    132 	center_win .h
    133 	wm title .h "Terminal Services VNC Viewer Help"
    134 
    135 	set msg {
    136  Terminal Services:
    137 
    138     The Terminal Services VNC Viewer uses SSH to establish an encrypted
    139     and authenticated connection to the remote server.
    140 
    141     Through the SSH channel, it automatically starts x11vnc in terminal
    142     services mode on the remote server to find or create your desktop
    143     session.  x11vnc is used for both the session management and the
    144     VNC transport.
    145 
    146     You MUST be able to log in via SSH to the remote terminal server.
    147     Ask your administrator to set this up for you if it isn't already.
    148     x11vnc must also be installed on the remote server machine.
    149     See "Requirements" below.
    150 
    151     This mode is started by the commands 'tsvnc' or 'ssvnc -ts' or
    152     toggled by pressing Ctrl-t.  "SSVNC Mode" under Options -> Advanced
    153     will also return to the full SSVNC.
    154 
    155     Or in your ~/.ssvncrc (or ~/ssvnc_rc on Windows) put "mode=tsvnc"
    156     to have the tool always start up in that mode.  To constrain the UI,
    157     run with -tso or SSVNC_TS_ALWAYS set to prevent leaving the Terminal
    158     Services mode.
    159 
    160 
    161  Hosts and Displays:
    162 
    163     Enter the remote VNC Terminal Services hostname in the
    164     'VNC Terminal Server' entry.
    165 
    166     Examples:
    167 
    168            24.67.132.27
    169            far-away.east
    170            fred@someplace.no
    171 
    172     Then click on "Connect".
    173 
    174     Once the SSH is running (you may need to type a password or accept
    175     a new ssh key in the terminal window that pops up), the VNC Viewer
    176     will be automatically started directed to the local port of the SSH
    177     tunnel which, in turn, encrypts and redirects the connection to the
    178     remote VNC server.
    179 
    180     x11vnc is run remotely to find or create your terminal services desktop
    181     session.  It must be installed and accessible on the remote system.
    182 
    183     Enter "user (at) hostname.com" in 'VNC Terminal Server' if the remote
    184     username is different from the yours on this machine.  On Windows
    185     you *MUST* supply the remote username due to a deficiency in Plink.
    186     This entry is passed to SSH; it could also be an SSH alias you have
    187     created (in ~/.ssh/config).
    188 
    189     If the remote SSH server is run on a non-standard port, e.g. 2222, use
    190     something like one of these:
    191 
    192            far-away.east:2222
    193            fred@someplace.no:2222
    194 
    195     (unlike SSVNC mode, the number is the SSH port, not the VNC display)
    196 
    197     If you find yourself in the unfortunate circumstance that your ssh
    198     username has a space in it, use %SPACE (or %TAB) like this:
    199 
    200            fred%SPACEflintstone@xyzzy.net
    201 
    202 
    203  Zeroconf/Bonjour:
    204 
    205     On Unix or Mac OS X, if the 'avahi-browse' or 'dns-sd' command is
    206     available on the system and in your PATH, a 'Find' button is placed by
    207     'VNC Host:Display'.  Clicking on Find will try to find VNC Servers
    208     on your Local Network that advertize via the Zeroconf protocol.
    209     A menu of found hosts is presented for you to select from.
    210 
    211 
    212  Profiles:
    213 
    214     Use "Save" to save a profile (i.e. a host:display and its specific
    215     settings) with a name.  The "TS-" prefix will be suggested to help
    216     you distinguish between Terminal Services and regular profiles.
    217 
    218     To load in a saved Options profile, click on the "Load" button,
    219     and choose which one you want.
    220 
    221     To list your profiles from the command line use:
    222 
    223          tsvnc -profiles    (or -list)
    224 
    225     To launch profile1 directly from the command-line, or to a server
    226     use things like:
    227 
    228          tsvnc profile1
    229          tsvnc /path/to/profile1.vnc
    230          tsvnc hostname
    231          tsvnc user@hostname
    232 
    233     Note that the 'Verify All Certs' setting is NOT saved in profiles.
    234 
    235 
    236  Proxies/Gateways:
    237 
    238     Proxy/Gateway is usually a gateway machine to log into via SSH that is
    239     not the machine running the VNC terminal services.  However, Web and
    240     SOCKS proxies can also be used (see below).
    241 
    242     For example if a company had a central login server: "ssh.company.com"
    243     (accessible from the internet) and the internal server name was
    244     "ts-server", one could put in
    245 
    246            VNC Terminal Server:   ts-server
    247            Proxy/Gateway:         ssh.company.com
    248 
    249     It is OK if the hostname "ts-server" only resolves inside the firewall.
    250 
    251     The 2nd host, ts-server in this example, MUST also be running an SSH
    252     server and you must be able to log into it.  You may need to supply
    253     a 2nd password to it to login.
    254 
    255     Use username@host (e.g. joe@ts-server or jsmith@ssh.company.com)
    256     if the user name differs between machines.
    257 
    258     NOTE: On Windows you MUST always supply the username@ because putty's
    259     plink requires it.
    260 
    261 
    262     NON-STANDARD SSH PORT: To use a non-standard ssh port (i.e. a port other
    263     than 22) you need to use the Proxy/Gateways as well.  E.g. something
    264     like this for port 2222:
    265 
    266            VNC Terminal Server:  ts-server
    267            Proxy/Gateway:        jsmith@ssh.company.com:2222
    268 
    269     On Unix/MacOSX the username@ is not needed if it is the same as on this
    270     machine.
    271 
    272 
    273     A Web or SOCKS proxy can also be used.  Use this if you are inside a
    274     firewall that prohibits direct connections to remote SSH servers.
    275     In Terminal Services SSH mode, the "http://" prefix is required for
    276     web proxies.
    277 
    278            VNC Terminal Server:  fred@someplace.no
    279            Proxy/Gateway:        http://myproxy.west:8080
    280 
    281     or for SOCKS:
    282 
    283            VNC Terminal Server:  fred@someplace.no
    284            Proxy/Gateway:        socks://mysocks.west:1080
    285 
    286     use socks5://... to force the SOCKS5 version.  For a non-standard
    287     port the above would be, e.g., fred@someplace.no:2222
    288 
    289     As with a username that contains a space, use %SPACE (or %TAB) to
    290     indicate it in the SSH proxies, e.g. john%SPACEsmith@ssh.company.com
    291 
    292     One can also chain proxies and other things.  See the section
    293     "SSH Proxies/Gateways" in the Main SSVNC Help for full details.
    294 
    295 
    296  Options:
    297 
    298     Click on Options to get to dialog boxes to:
    299 
    300            - Desktop Type        (kde, gnome, failsafe, twm...)
    301            - Desktop Size        (Geometry WxH and pixel depth)
    302            - X Server Type       (Xvfb, Xdummy, Xvnc)
    303            - Enable Printing     (CUPS and/or SMB/Windows)
    304            - Enable Sound        (TBD, ESD partially working)
    305            - File Transfer       (Ultra or TightVNC filexfer)
    306            - View Only           (View only client)
    307            - Change VNC Viewer   (Realvnc, ultra, etc...)
    308            - X11 viewer MacOSX   (use bundled X11 vncviewer)
    309            - Delete Profile...   (Delete a saved profile)
    310 
    311            - Advanced Options:
    312 
    313            - VNC Shared          (optional traditional VNC sharing)
    314            - Multiple Sessions   (more than 1 session per server)
    315            - X Login Greeter     (Connect to Login/Greeter Display)
    316            - Other VNC Server    (redirect to 3rd party VNC Server)
    317            - Use unixpw          (optional x11vnc login mode)
    318            - Client 8bit Color   (VNC Viewer requests low color mode)
    319            - Client-Side Caching (experimental x11vnc speedup)
    320            - X11VNC Options      (set any extra x11vnc options)
    321            - Extra Sleep         (delay a bit before starting viewer)
    322            - Putty Args          (Windows: string for plink/putty cmd)
    323            - Putty Agent         (Windows: launch pageant)
    324            - Putty Key-Gen       (Windows: launch puttygen)
    325            - SSH Local Protections  (a bit of safety on local side)
    326            - SSH KnownHosts file (to avoid SSH 'localhost' collisions)
    327            - SSVNC Mode          (Return to full SSVNC mode)
    328 
    329            - Unix ssvncviewer    (set options for supplied Unix viewer)
    330 
    331 
    332  Requirements:
    333 
    334     When running this application on Unix/MacOSX the ssh(1) program must
    335     be installed locally.  On Windows a plink/putty binary is included.
    336 
    337     On the remote VNC Terminal Services host, x11vnc must be installed
    338     (0.9.3 or higher), and at least one virtual X server: Xvfb, Xdummy,
    339     or Xvnc must be available.  Xvfb is the most often used one.  All of
    340     these programs must be available in $PATH on the remote server when
    341     logged in via SSH.
    342 
    343     The VNC terminal services administrator can make "x11vnc" be a wrapper
    344     script that sets everything up correctly and then runs the real x11vnc.
    345 
    346 
    347  Real X servers:
    348 
    349     As a *BONUS*, if on the remote host, say a workstation, you have a
    350     regular X session running on the physical hardware that you are
    351     ALREADY logged into you can access to that display as well (x11vnc
    352     will find it).
    353 
    354     So this tool can be used as a simple way to launch x11vnc to find
    355     your real X display on your workstation and connect to it.
    356 
    357     The Printing and Sound redirection won't work for this mode however.
    358     You will need to use the full SSVNC application to attempt that.
    359 
    360     If you (mistakenly) have not logged into an X session on the real
    361     X server on the workstation, a VIRTUAL (Xvfb, etc.) server will be
    362     created for you (that may or may not be what you want).
    363 
    364     The X Login Advanced setting can be used to connect to a X Display
    365     Manger Greeter login panel (no one is logged in yet).  This requires
    366     sudo(1) privileges on the remote machine.
    367 
    368  More Info:
    369 
    370     See these links for more information:
    371 
    372         http://www.karlrunge.com/x11vnc/#tunnelling
    373 }
    374 
    375 	global version
    376 	set msg "                             SSVNC version: $version\n$msg"
    377 
    378 	.h.f.t insert end $msg
    379 	jiggle_text .h.f.t
    380 }
    381 
    382 proc help {} {
    383 	global ts_only
    384 	if {$ts_only} {
    385 		ts_help
    386 		return
    387 	}
    388 	toplev .h
    389 
    390 	set h 37
    391 	if [small_height] {
    392 		set h 26
    393 	}
    394 	scroll_text_dismiss .h.f 82 $h
    395 
    396 	center_win .h
    397 	wm title .h "SSL/SSH VNC Viewer Help"
    398 
    399 	global help_main help_prox help_misc help_tips
    400 
    401 	set help_main {
    402  Hosts and Displays:
    403 
    404     Enter the VNC host and display in the  'VNC Host:Display'  entry box.
    405 
    406     It is of the form "host:number", where "host" is the hostname of the
    407     machine running the VNC Server and "number" is the VNC display number;
    408     it is often "0".  Some Examples:
    409 
    410            snoopy:0
    411 
    412            far-away.east:0
    413 
    414            sunray-srv1.west:17
    415 
    416            24.67.132.27:0
    417 
    418     Then click on "Connect".  When you do the STUNNEL program will be started
    419     locally to provide you with an outgoing SSL tunnel.
    420 
    421     Once the STUNNEL is running, the TightVNC Viewer (Or perhaps Chicken of
    422     the VNC on Mac OS X, or one you set under Options) will be automatically
    423     started and directed to the local port of the SSL tunnel which, in turn,
    424     encrypts and redirects the connection to the remote VNC server.
    425 
    426     The remote VNC server **MUST** support an initial SSL/TLS handshake before
    427     using the VNC protocol (i.e. VNC is tunnelled through the SSL channel
    428     after it is established).  "x11vnc -ssl ..."  does this, and any VNC server
    429     can be made to do this by using, e.g., STUNNEL or socat on the remote side.
    430     SSVNC also supports VeNCrypt and ANONTLS SSL/TLS VNC servers (see below.)
    431 
    432     * Automatic SSH Tunnels are described below.
    433 
    434     * The 'No Encryption' / 'None' option provides a direct connection without
    435       encryption (disable the button with the -enc option, or Options menu.)
    436       More info in Tip 5.
    437 
    438  Port numbers:
    439 
    440     If you are using a port less than the default VNC port 5900 (usually
    441     the VNC display = port - 5900), use the full port number itself, e.g.:
    442 
    443          24.67.132.27:443
    444 
    445     Note, however, if the number n after the colon is < 200, then a
    446     port number 5900 + n is assumed; i.e. n is the VNC display number.
    447     If you must use a TCP port less than 200, specify a negative value,
    448     e.g.:  24.67.132.27:-80
    449 
    450     For Reverse VNC connections (listening viewer, See Tip 2 and
    451     Options -> Help), the port mapping is similar, except "listening
    452     display :0" corresponds to port 5500, :1 to 5501, etc.
    453     Specify a specific interface, e.g. 192.168.1.1:0 to have stunnel
    454     listen on that interface only.  Listening on IPv6 can also be done, use
    455     e.g. :::0 or ::1:0  This listening on IPv6 (:::0) works for UN-encrypted
    456     reverse connections as well (mode 'None').
    457 
    458 
    459  Zeroconf/Bonjour:
    460 
    461     On Unix or Mac OS X, if the 'avahi-browse' or 'dns-sd' command is
    462     available on the system and in your PATH, a 'Find' button is placed by
    463     'VNC Host:Display'.  Clicking on Find will try to find VNC Servers on
    464     your Local Network that advertize via the Zeroconf protocol.  A menu of
    465     found hosts is presented for you to select from.
    466 
    467 
    468  VNC Password:
    469 
    470     On Unix or MacOSX IF there is a VNC password for the server you can
    471     enter it in the "VNC Password:" entry box.
    472 
    473     This is *REQUIRED* on MacOSX when Chicken of the VNC is used, because
    474     that viewer does not put up a user password prompt when it learns
    475     that a password is needed.
    476 
    477     On Unix (including MacOSX using the X11 viewer) if you choose not to
    478     enter the password you will simply be prompted for it in the terminal
    479     window running TightVNC viewer if one is required.
    480 
    481     On Windows TightVNC viewer will prompt you if a password is required.
    482 
    483     NOTE: when you Save a VNC profile, the password is NOT saved (you need
    484     to enter it each time).  Nor is the 'Verify All Certs' setting.
    485 
    486 
    487  Profiles:
    488 
    489     Use "Save" to save a profile (i.e. a host:display and its specific
    490     settings) with a name.
    491 
    492     To load in a saved Options profile, click on the "Load" button.
    493 
    494     To list your profiles from the command line use:
    495 
    496         ssvnc -profiles    (or -list)
    497 
    498     You can launch ssvnc and have it immediately connect to the server
    499     by invoking it something like this:
    500 
    501         ssvnc profile1              (launches profile named "profile1")
    502         ssvnc /path/to/profile.vnc  (loads the profile file, no launching)
    503         ssvnc hostname:0            (connect to hostname VNC disp 0 via SSL)
    504         ssvnc vnc+ssl://hostname:0  (same)
    505         ssvnc vnc+ssh://hostname:0  (connect to hostname VNC disp 0 via SSH)
    506 
    507     see the Tips 5 and 7 for more about the URL-like syntax.
    508 
    509     If you don't want "ssvnc profile1" to immediately launch the connection
    510     to the VNC server set the SSVNC_PROFILE_LOADONLY env. var. to 1.
    511     (or specify the full path to the profile.vnc as shown above.)
    512 
    513 
    514  SSL Certificate Verification:
    515 
    516     *** IMPORTANT ***: If you do not take the steps to VERIFY the VNC Server's
    517     SSL Certificate, you are in principle vulnerable to a Man-In-The-Middle
    518     attack.  Without SSL Certificate verification, only passive network
    519     sniffing attacks will be guaranteed to be prevented.  There are hacker
    520     tools like dsniff/webmitm and cain that implement SSL Man-In-The-Middle
    521     attacks.  They rely on the client user not bothering to check the cert.
    522 
    523     Some people may be confused by the above because they are familiar with
    524     their Web Browser using SSL (i.e. https://... websites) and those sites
    525     are authenticated securely without the user's need to verify anything
    526     manually.  The reason why this happens automatically is because 1) their
    527     web browser comes with a bundle of Certificate Authority certificates
    528     and 2) the https sites have paid money to the Certificate Authorities to
    529     have their website certificate signed by them.  When using SSL in VNC we
    530     normally do not do something this sophisticated, and so we have to verify
    531     the certificates manually.  However, it is possible to use Certificate
    532     Authorities with SSVNC; that method is described below.
    533 
    534     You can use the "Fetch Cert" button to retrieve the Cert and then
    535     after you check it is OK (say, via comparing the MD5 or other info)
    536     you can "Save" it and use it to verify future connections to servers.
    537     (However, see the note at the end of this section about CA certificates.)
    538 
    539     When "Verify All Certs" is checked, this check is always enforced,
    540     and so the first time you connect to a new server you may need to
    541     follow a few dialogs to inspect and save the server certificate.
    542     See the "Certs... -> Help" for information on how to manage certificates.
    543 
    544     "Verify All Certs" is on by default.
    545 
    546     Note, however, "Fetch Cert" and "Verify All Certs" are currently disabled
    547     in the very rare "SSH + SSL" usage mode to avoid SSHing in twice.
    548     You can manually set a ServerCert or CertsDir in this case if you like.
    549 
    550 
    551     Advanced Method: Certificate Authority (CA):
    552 
    553     If you, or your site administrator, goes though the steps of setting up
    554     a Certificate Authority (CA) to sign the VNC server and/or VNC client
    555     Certs, that can be used instead and avoids the need to manually verify
    556     every cert while still authenticating every connection.  More info:
    557     http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-ca
    558 
    559     See the cmdline option -cacert file below in 'SSL Certificates'
    560     for setting a default ServerCert/CA Cert.
    561 
    562     You may also Import the CA Cert and save it to the 'Accepted Certs'
    563     directory so the "Verify All Certs" automatic checking will find it.
    564 
    565     Note that if a Server is using a CA signed certificate instead of
    566     its own Self-Signed one, then the default "Verify All Certs/Fetch Cert"
    567     saving mechanism will NOT succeed.  You must obtain the CA certificate
    568     and explicitly set it as the ServerCert or Import it to Accepted Certs.
    569 
    570 
    571  SSL/TLS Variants; VeNCrypt and ANONTLS:
    572 
    573     SSVNC can also connect to VNC SSL/TLS variants; namely the VeNCrypt and
    574     "TLS" VNC Security types.  Vino uses the latter (we call it "ANONTLS");
    575     and a growing number use VeNCrypt (QEMU, ggi, virt-manager, VeNCrypt, Xen.)
    576 
    577     Via the VeNCrypt bridge that SSVNC provides, the VeNCrypt/ANONTLS
    578     support ALSO works with ANY 3rd party VNC Viewers you specify via
    579     'Change VNC Viewer' (e.g. RealVNC, TightVNC, UltraVNC, etc.) that do
    580     not directly support VeNCrypt or ANONTLS.  This works on all platforms:
    581     Unix, MacOSX, and Windows.
    582 
    583 
    584     Notes on VeNCrypt/ANONTLS Auto-detection:
    585 
    586     IMPORTANT: VeNCrypt Server Auto-detection *ONLY* occurs in SSL mode
    587     and when an initial fetch-cert action takes place.
    588 
    589     While the initial certificate fetch is taking place SSVNC applies
    590     heuristics to try to automatically detect the VeNCrypt or ANONTLS
    591     protocol use by the VNC server.  This way it learns that the server
    592     is using it and then knows to switch to VeNCrypt encrypted SSL/TLS at
    593     the right point.  Then SSVNC makes a second (the real) connection to
    594     VNC server and connects the VNC viewer to it.
    595 
    596     In the default "Verify All Certs" mode, a fetch cert action always
    597     takes place, and so VeNCrypt/ANONTLS will be autodected.
    598 
    599     However, if you have specified an explicit ServerCert or disabled
    600     "Verify All Certs" then even though the initial fetch cert action is no
    601     longer needed, it is performed anyway because it allows VeNCrypt/ANONTLS
    602     auto-detection.
    603 
    604     To disabled this initial fetch (e.g. you know the VNC server is normal
    605     SSL and not VeNCrypt/ANONTLS and want to connect more quickly) then
    606     select "Do not Probe for VeNCrypt" in the Advanced Options menu.
    607 
    608     On the other hand, if you know the VNC server ONLY supports VeNCrypt or
    609     ANONTLS, to improve the accuracy and speed with which the connection
    610     takes place, you can specify the one or both of the 'Server uses
    611     VeNCrypt SSL encryption' and 'Server uses Anonymous Diffie-Hellman'
    612     in the 'Advanced' options panel.  That way guessing via an initial
    613     probe is not needed or performed.  See each options's Advanced Options
    614     Help for more info.
    615 
    616     Note that if you are using VeNCrypt or ANONTLS for REVERSE connections
    617     (Listen) then you *MUST* set the 'Server uses VeNCrypt SSL encryption'
    618     (and the ANON-DH if it applies) option in Advanced.  Note also that
    619     REVERSE VeNCrypt and ANONTLS connections currently do not work on
    620     Windows.
    621 
    622     Also, if you are using the "Use SSH+SSL" double tunnel, you MUST set
    623     'Server uses VeNCrypt SSL encryption' (and the ANON-DH if it applies)
    624     because the initial fetch cert is disabled in SSH+SSL mode.
    625 
    626 
    627  Deciphering SSL Negotiation Success or Failure:
    628 
    629     Since SSVNC is a "glue program", in this case gluing VNCViewer and stunnel
    630     together (with possibly a proxy helper) reporting is clumsy at best.
    631     (In SSH encryption mode, it glues to ssh instead of stunnel.)  In most
    632     cases the programs being "glued" are run in a terminal window where you
    633     can see the program's output.  On Windows you will need to double click
    634     on the stunnel tray icon to view its log.
    635 
    636     Although the output is quite cryptic, you are encouraged to learn to
    637     recognize some of the errors reported in it.
    638 
    639     Here is stunnel output for a case of successfully verifying the VNC
    640     Server's Certificate:
    641 
    642       2008.11.20 08:09:39 LOG5[1472]: VERIFY OK: depth=0, /C=AU/L=...
    643       2008.11.20 08:09:39 LOG6[1472]: SSL connected: new session negotiated
    644       2008.11.20 08:09:39 LOG6[1472]: Negotiated ciphers: AES256-SHA SSLv3 ...
    645 
    646     Here is a case where the Server's Cert did not match the ServerCert
    647     we set:
    648 
    649       2008.11.20 08:12:31 LOG4[1662]: VERIFY ERROR: depth=0, error=self ...
    650       2008.11.20 08:12:31 LOG3[1662]: SSL_connect: 14090086: error:14090086:SSL
    651            routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
    652 
    653     Here is a case where the Server's Cert has expired:
    654 
    655       2009.12.27 12:20:25 LOG4[25500]: VERIFY ERROR: depth=0, error=certificate
    656            has expired: /C=AU/L=...
    657       2009.12.27 12:20:25 LOG3[25500]: SSL_connect: 14090086: error:14090086:SSL
    658            routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
    659 
    660 
    661     If you disable "Verify All Certs" and do not supply a ServerCert,
    662     then there will be no 'VERIFY ...' in the output because the SSVNC
    663     stunnel accepts the server's cert without question (this is insecure.)
    664 
    665     Also in the output will be messages about whether the SSL VNC server
    666     rejected your connection because it requires you to authenticate
    667     yourself with a certificate (MyCert).  Here is the case when you
    668     supplied no MyCert:
    669 
    670       2008.11.20 08:16:29 LOG3[1746]: SSL_connect: 14094410: error:14094410:
    671           SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
    672 
    673     or you used a certificate the server did not recognize:
    674 
    675       2008.11.20 08:18:46 LOG3[1782]: SSL_connect: 14094412: error:14094412:
    676           SSL routines:SSL3_READ_BYTES:sslv3 alert bad certificate
    677 
    678     or your certificate has been revoked:
    679 
    680      2008.11.20 08:20:08 LOG3[1913]: SSL_connect: 14094414: error:14094414:
    681          SSL routines:SSL3_READ_BYTES:sslv3 alert certificate revoked
    682 
    683 
    684  SSH:
    685 
    686     Click on "Use SSH" if you want to use an *SSH* tunnel instead of SSL
    687     (then the VNC Server does not need to speak SSL or use STUNNEL or socat).
    688 
    689     You will need to be able to login to your account on the remote host
    690     via SSH (e.g. via password, ssh keys, or ssh-agent).
    691 
    692     Specify the SSH hostname and VNC display in the VNC Host:Display entry.
    693     Use something like:
    694 
    695            username@far-away.east:0
    696 
    697     if your remote username is different from the one on the local viewer
    698     machine.
    699 
    700     On Windows you *MUST* supply the "username@" part because Putty/Plink
    701     needs it to work correctly.
    702 
    703     "SSH + SSL" is similar but its use is more rare because it requires 2
    704     encrypted tunnels to reach the VNC server. See the Help under Options
    705     for more info.
    706 
    707     To connect to a non-standard SSH port, see SSH Proxies/Gateways section.
    708 
    709     See Tip 8) for how to make this application be SSH-only with the -ssh
    710     command line option or "sshvnc".
    711 
    712     If you find yourself in the unfortunate circumstance that your ssh
    713     username has a space in it, use %SPACE (or %TAB) like this:
    714 
    715            fred%SPACEflintstone@xyzzy.net:0
    716 
    717  Remote SSH Command:
    718 
    719     In SSH or SSH + SSL mode you can also specify a remote command to run
    720     on the remote ssh host in the "Remote SSH Command" entry.  The default
    721     is just to sleep a bit (e.g. sleep 15) to make sure the tunnel ports
    722     are established.  Alternatively you could have the remote command start
    723     the VNC server, e.g.
    724 
    725          x11vnc -display :0 -rfbport 5900 -localhost -nopw
    726 
    727     When starting the VNC server this way, note that sometimes you will need
    728     to correlate the VNC Display number with the "-rfbport" (or similar)
    729     option of the server.  E.g. for VNC display :2
    730 
    731          VNC Host:Display       username@somehost.com:2
    732          Remote SSH Command:    x11vnc -find -rfbport 5902 -nopw
    733 
    734     See the Tip 18) for using x11vnc PORT=NNNN feature (or vncserver(1)
    735     output) to not need to specify the VNC display number or the x11vnc
    736     -rfbport option.
    737 
    738     Windows SSH SERVER: if you are ssh'ing INTO Windows (e.g. CYGWIN SSHD
    739     server) there may be no "sleep" command so put in something like
    740     "ping localhost" or "ping -n 10 -w 1000 localhost" to set a short
    741     delay to let the tunnel ports get established.
    742 
    743 
    744  SSL Certificates:
    745 
    746     If you want to use a SSL Certificate (PEM) file to authenticate YOURSELF to
    747     the VNC server ("MyCert") and/or to verify the identity of the VNC Server
    748     ("ServerCert" or "CertsDir") select the certificate file by clicking the
    749     "Certs ..." button before connecting.
    750 
    751     Certificate verification is needed to prevent Man-In-The-Middle attacks;
    752     if it is not done then only passive network sniffing attacks are prevented.
    753     There are hacker tools like dsniff/webmitm and cain that implement SSL
    754     Man-In-The-Middle attacks.  They rely on the client user not bothering to
    755     check the cert.
    756 
    757 
    758     See the x11vnc documentation:
    759 
    760            http://www.karlrunge.com/x11vnc/ssl.html
    761 
    762     for how to create and use PEM SSL certificate files.  An easy way is:
    763 
    764            x11vnc -ssl SAVE ...
    765 
    766     where it will print out its automatically generated certificate to the
    767     screen and that can be copied safely to the viewer side.
    768 
    769     You can also use the "Create Certificate" feature of this program under
    770     "Certs ...".  Just click on it and follow the instructions in the dialog.
    771     Then copy the cert file to the VNC Server and specify the other one in
    772     the "Certs ..." dialog.
    773 
    774     Alternatively you can use the "Import Certificate" action to paste in a
    775     certificate or read one in from a file.  Or you can use the "Fetch Cert"
    776     button on the main panel.  If "Verify All Certs" is checked, you will
    777     be forced to check Certs of any new servers the first time you connect.
    778 
    779     Note that "Verify All Certs" is on by default so that users who do not
    780     understand the SSL Man-In-The-Middle problem will not be left completely
    781     vulnerable to it (everyone still must make the effort to verify new
    782     certificates by an external method to be completely safe).
    783 
    784     To have "Verify All Certs" toggled off at startup, use "ssvnc -nv" or
    785     set SSVNC_NO_VERIFY_ALL=1 before starting.  If you do not even want to
    786     see the button, use "ssvnc -nvb" or SSVNC_NO_VERIFY_ALL_BUTTON=1.
    787 
    788     Use the "-mycert file" option (same as "-cert file") to set a default
    789     MyCert.  This is the same as "mycert=file" (also "cert=file") in the
    790     ~/.ssvncrc file.  See Certs -> Help for more info.
    791 
    792     Use the "-cacert file" option (same as "-ca file") to set a default
    793     ServerCert (or CA).  This is the same as "cacert=file" (also "ca=file")
    794     in the ~/.ssvncrc file.  See Certs -> Help for more info.
    795 
    796     Use the "-crl file" option to set a default CRL File.  This is the same
    797     as "crl=file" in the ~/.ssvncrc file.  See Certs -> Help for more info.
    798 
    799     Prefix any of these files with "FORCE:" to make them immutable.
    800 
    801 
    802 
    803  More Options:
    804 
    805     To set other Options, e.g. for View-Only usage or to limit the number
    806     of colors used, click on the "Options ..." button and read the Help there.
    807 
    808  More Info:
    809 
    810     Press the 'Proxies', 'Misc', and 'Tips' buttons below.
    811 
    812     See also these links for more information:
    813 
    814         http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tunnel-ext
    815         http://stunnel.mirt.net
    816         http://www.tightvnc.com
    817 }
    818 
    819 	set help_misc {
    820  Windows STUNNEL problems:
    821 
    822     Note that on Windows when the Viewer connection is finished by default
    823     SSVNC will try to kill the STUNNEL process for you.
    824 
    825     If Options -> Kill Stunnel Automatically is not set you will be
    826     prompted if you want SSVNC to try to kill the STUNNEL process for you.
    827     Usually you will say Yes, however if there are problems connecting
    828     you may want to look at the STUNNEL Log first.
    829 
    830     Before it is killed, double clicking the STUNNEL tray icon (dark green)
    831     will show you its Log file (useful for debugging connection problems).
    832 
    833     Even though SSVNC will kill the STUNNEL process for you, you will
    834     still need to move the mouse over the icon to make the little picture
    835     go away!!!  This is unfortunate but there does not seem to be a way
    836     to avoid it.
    837 
    838     In some cases you may need to terminate STUNNEL manually from the System
    839     Tray (right click on dark green icon) and selecting "Exit".
    840 
    841     Use -nokillstunnel or killstunnel=0 in ~/.ssvncrc to have SSVNC
    842     start up with stunnel killing disabled.
    843 
    844  Untrusted Local Users:
    845 
    846     *IMPORTANT WARNING*:  If you run SSVNC on a workstation or computer
    847     that other users can log into and you DO NOT TRUST these users
    848     (it is a shame but sometimes one has to work in an environment like
    849     this), then please note the following warning.
    850 
    851     By 'do not trust' we mean they might try to gain access to remote
    852     machines you connect to via SSVNC.  Note that an untrusted local
    853     user can often obtain root access in a short amount of time; if a
    854     user has achieved that, then all bets are off for ANYTHING that you
    855     do on the workstation.  It is best to get rid of Untrusted Local
    856     Users as soon as possible.
    857 
    858     Both the SSL and SSH tunnels set up by SSVNC listen on certain ports
    859     on the 'localhost' address and redirect TCP connections to the remote
    860     machine; usually the VNC server running there (but it could also be
    861     another service, e.g. CUPS printing).  These are the stunnel(8) SSL
    862     redirection and the ssh(1) '-L' port redirection.  Because 'localhost'
    863     is used only users or programs on the same workstation that is
    864     running SSVNC can connect to these ports, however this includes any
    865     local users (not just the user running SSVNC.)
    866 
    867     If the untrusted local user tries to connect to these ports, he may
    868     succeed by varying degrees to gain access to the remote machine.
    869     We now list some safeguards one can put in place to try to make this
    870     more difficult to achieve.
    871 
    872     It probably pays to have the VNC server require a password, even
    873     though there has already been SSL or SSH authentication (via
    874     certificates or passwords).  In general if the VNC Server requires
    875     SSL authentication of the viewer that helps, unless the untrusted
    876     local user has gained access to your SSVNC certificate keys.
    877 
    878     If the VNC server is configured to only allow one viewer connection
    879     at a time, then the window of opportunity that the untrusted local
    880     user can use is greatly reduced: he might only have a second or two
    881     between the tunnel being set up and the SSVNC vncviewer connecting
    882     to it (i.e. if the VNC server only allows a single connection, the
    883     untrusted local user cannot connect once your session is established).
    884     Similarly, when you disconnect the tunnel is torn down quickly and
    885     there is little or no window of opportunity to connect (e.g. x11vnc
    886     in its default mode exits after the first client disconnects).
    887 
    888     Also for SSL tunnelling with stunnel(8) on Unix using one of the SSVNC
    889     prebuilt 'bundles', a patched stunnel is provided that denies all
    890     connections after the first one, and exits when the first one closes.
    891     This is not true if the system installed stunnel(8) is used and is
    892     not true when using SSVNC on Windows.
    893 
    894     The following are experimental features that are added to SSVNC to
    895     improve the situation for the SSL/stunnel and SSH cases.  Set them
    896     via Options -> Advanced -> "STUNNEL Local Port Protections" or
    897     "SSH Local Port Protections".
    898 
    899     STUNNEL:
    900 
    901     1) For SSL tunnelling with stunnel(8) on Unix there is a setting
    902        'Use stunnel EXEC mode' that will try to exec(2) stunnel
    903        instead of using a listening socket.  This will require using
    904        the specially modified vncviewer unix viewer provided by SSVNC.
    905        The mode works well and is currently set as the default.
    906        Disable it if it causes problems or conflicts.
    907 
    908     2) For SSL tunnelling with stunnel(8) on Unix there is a setting
    909        'Use stunnel IDENT check' (experimental) to limit socket
    910        connections to be from you (this assumes the untrusted local
    911        user has not become root on your workstation and has modified
    912        your local IDENT check service; if he has you have much bigger
    913        problems to worry about...)
    914 
    915        Neither of the above methods are available on Windows.
    916 
    917     SSH:
    918 
    919     1) There is also a simple LD_PRELOAD trick for SSH to limit the
    920        number of accepted port redirection connections.  This makes the
    921        window of time the untrusted local user can connect to the tunnel
    922        much smaller.  Enable it via Options -> Advanced -> "SSH Local
    923        Port Protections".  You will need to have the lim_accept.so file
    924        in your SSVNC package.  The mode works well and is currently set
    925        as the default.  Disable it if it causes problems or conflicts.
    926 
    927        The above method is not available on Windows.
    928 
    929     The main message is to 'Watch your Back' when you connect via the
    930     SSVNC tunnels and there are users you don't trust on your workstation.
    931     The same applies to ANY use of SSH '-L' port redirections or outgoing
    932     stunnel SSL redirection services.
    933 }
    934 
    935 	set help_prox {
    936  Here are a number of long sections on all sorts of proxies, Web, SOCKS,
    937  SSH tunnels/gateways, UltraVNC, Single Click, etc., etc.
    938 
    939 
    940  Proxies/Gateways:
    941 
    942     If an intermediate proxy is needed to make the SSL connection
    943     (e.g. a web gateway out of a firewall) enter it in the "Proxy/Gateway"
    944     entry box:
    945 
    946            VNC Host-Display:   host:number
    947            Proxy/Gateway:      proxy-host:port
    948     e.g.:
    949            VNC Host-Display:   far-away.east:0
    950            Proxy/Gateway:      myproxy.west:8080
    951 
    952 
    953     If the "double proxy" case is required (e.g. coming out of a web
    954     proxied firewall environment and then INTO a 2nd proxy to ultimately
    955     reach the VNC server), separate them via a comma, e.g.:
    956 
    957            VNC Host-Display:   far-away:0
    958            Proxy/Gateway:      myproxy.west:8080,myhome.net:443
    959 
    960     So it goes: viewer -> myproxy.west -> myhome.net -> far-away (VNC)
    961 
    962     The proxies are assumed to be Web proxies.  To use SOCKS proxies:
    963 
    964            VNC Host-Display:   far-away.east:0
    965            Proxy/Gateway:      socks://mysocks.west:1080
    966 
    967     Use socks5:// to force the SOCKS5 proxy protocol (e.g. for ssh -D).
    968 
    969     You can prefix web proxies with http:// in SSL mode but it doesn't matter
    970     since that is the default for a proxy.  (NOTE that in SSH or SSH+SSL
    971     mode you MUST supply the http:// prefix for web proxies because in those
    972     modes an SSH tunnel is the default proxy type: see the next section.)
    973 
    974     Note that Web proxies are often configured to ONLY allow outgoing
    975     connections to ports 443 (HTTPS) and 563 (SNEWS), so you might
    976     have run the VNC server (or router port redirector) on those ports.
    977     SOCKS proxies usually have no restrictions on port number.
    978 
    979     You can chain up to 3 proxies (any combination of web (http://) and
    980     socks://) by separating them with commas (i.e. first,second,third).
    981 
    982     Proxies also work for un-encrypted connections ("None" or vnc://, Tip 5)
    983 
    984     See the ss_vncviewer description and x11vnc FAQ for info on proxies:
    985 
    986         http://www.karlrunge.com/x11vnc/faq.html#ss_vncviewer
    987         http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-java-viewer-proxy
    988 
    989 
    990  SSH Proxies/Gateways:
    991 
    992     Proxy/Gateway also applies to SSH mode, it is a usually a gateway SSH
    993     machine to log into via ssh that is not the workstation running the
    994     VNC server.  However, Web and SOCKS proxies can also be used (see below).
    995 
    996     For example if a company had a central login server: "ssh.company.com"
    997     (accessible from the internet) and the internal workstation with VNC was
    998     named "joes-pc", then to create an SSH tunnel one could put this in:
    999 
   1000            VNC Host:Display:   joes-pc:0
   1001            Proxy/Gateway:      ssh.company.com
   1002 
   1003     It is OK if the hostname "joes-pc" only resolves inside the firewall.
   1004 
   1005     The 2nd leg, from ssh.company.com -> joes-pc is done by a ssh -L
   1006     redir and is not encrypted (but the viewer -> ssh.company.com 1st leg is
   1007     an encrypted tunnel).
   1008 
   1009     To SSH encrypt BOTH legs, try the "double SSH gateway" method using
   1010     the "comma" notation:
   1011 
   1012            VNC Host:Display:   localhost:0
   1013            Proxy/Gateway:      ssh.company.com,joes-pc
   1014 
   1015     this requires an SSH server also running on joes-pc.  So an initial SSH
   1016     login is done to ssh.company.com, then a 2nd SSH is performed (through
   1017     port a redirection of the first) to login straight to joes-pc where
   1018     the VNC server is running.
   1019 
   1020     Use username@host (e.g. joe@joes-pc  jsmith@ssh.company.com) if the
   1021     user names differ between the various machines.
   1022 
   1023     NOTE: On Windows you MUST always supply the username@ because putty's
   1024     plink requires it.
   1025 
   1026 
   1027     NON-STANDARD SSH PORT: To use a non-standard ssh port (i.e. a port other
   1028     than 22) you need to use the Proxy/Gateways as well.  E.g. something
   1029     like this for port 2222:
   1030 
   1031            VNC Host:Display:   localhost:0
   1032            Proxy/Gateway:      joe@far-away.east:2222
   1033 
   1034     On Unix/MacOSX the username@ is not needed if it is the same as on
   1035     the client.  This will also work going to a different internal machine,
   1036     e.g. "joes-pc:0" instead of "localhost:0", as in the first example.
   1037 
   1038 
   1039     A Web or SOCKS proxy can also be used with SSH.  Use this if you are
   1040     inside a firewall that prohibits direct connections to remote SSH servers.
   1041 
   1042            VNC Host:Display:   joe@far-away.east:0
   1043            Proxy/Gateway:      http://myproxy.west:8080
   1044 
   1045     or for SOCKS:
   1046 
   1047            VNC Host:Display:   joe@far-away.east:0
   1048            Proxy/Gateway:      socks://mysocks.west:1080
   1049 
   1050     Use socks5://... to force the SOCKS5 version.  Note that the http://
   1051     prefix is REQUIRED for web proxies in SSH or SSH+SSL modes (but it is
   1052     the default proxy type in SSL mode.)
   1053 
   1054     You can chain up to 3 proxies (any combination of http://, socks://
   1055     and ssh) by separating them with commas (i.e. first,second,third).
   1056 
   1057     Note: the Web and/or SOCKS proxies must come before any SSH gateways.
   1058 
   1059     For a non-standard SSH port and a Web or SOCKS proxy try:
   1060 
   1061            VNC Host:Display:   localhost:0
   1062            Proxy/Gateway:      http://myproxy.west:8080,joe@far-away.east:2222
   1063 
   1064     Even the "double SSH gateway" method (2 SSH encrypted legs) described
   1065     above works with an initial Web or SOCKS proxy, e.g.:
   1066 
   1067            VNC Host:Display:   localhost:0
   1068            Proxy/Gateway:      socks://mysocks.west:1080,ssh.company.com,joes-pc
   1069 
   1070 
   1071 
   1072     Some Notes on SSH localhost tunnelling with SSH options
   1073       NoHostAuthenticationForLocalhost=yes and UserKnownHostsFile=file:
   1074 
   1075     Warning:  Note that for proxy use with ssh(1), tunnels going through
   1076     'localhost' are used.  This means ssh(1) thinks the remote hostname is
   1077     'localhost', which may cause collisions and confusion when storing
   1078     and checking SSH keys.
   1079 
   1080     By default on Unix when a 'localhost' ssh host is involved the
   1081     ssh option -o NoHostAuthenticationForLocalhost=yes is applied (see
   1082     ssh_config(1) for details.)  This avoids the warnings and ssh refusing
   1083     to connect, but it reduces security.  A man in the middle attack may
   1084     be possible.  SSVNC prints out a warning in the terminal every time
   1085     the NoHostAuthenticationForLocalhost option is used.
   1086 
   1087     On Unix to disable the use of NoHostAuthenticationForLocalhost set the env.
   1088     variable SSVNC_SSH_LOCALHOST_AUTH=1. This may induce extra ssh(1) dialogs.
   1089 
   1090     On Unix a MUCH SAFER and more convenient way to proceed is to set the
   1091     known hosts option in Options -> Advanced -> 'Private SSH KnownHosts file'
   1092     Then, only for the host in the current profile, a private known_hosts
   1093     file will be used and so there will be no 'localhost' collisions.
   1094     This method is secure (assuming you verify the SSH key fingerprint)
   1095     and avoids the man in the middle attack.
   1096 
   1097     On Windows, Putty/Plink is used and does not have the UserKnownHosts
   1098     or NoHostAuthenticationForLocalhost features.  Keys are stored in
   1099     the registry as localhost:port pairs and so it is possible to use the
   1100     'Port Slot' option to keep the keys separate to avoid the dialogs and
   1101     also maintain good security.
   1102 
   1103     Note that for the "double SSH gateway" method the risk from using
   1104     NoHostAuthenticationForLocalhost is significantly less because the first
   1105     ssh connection does not use the option (it connects directly to the remote
   1106     host) and the second one is only exposed for the leg inside the first
   1107     gateway (but is still vulnerable there when NoHostAuthenticationForLocalhost
   1108     is used.)
   1109 
   1110     As with a username that contains a space, use %SPACE (or %TAB) to
   1111     indicate it in the SSH proxies, e.g. john%SPACEsmith@ssh.company.com
   1112 
   1113  UltraVNC Proxies/Gateways:
   1114 
   1115     UltraVNC has a "repeater" tool (http://www.uvnc.com/addons/repeater.html
   1116     and http://koti.mbnet.fi/jtko/) that acts as a VNC proxy.  SSVNC can
   1117     work with both mode I and mode II schemes of this repeater.
   1118 
   1119     For Unix and MacOS X there is another re-implementation of the
   1120     UltraVNC repeater:
   1121 
   1122         http://www.karlrunge.com/x11vnc/ultravnc_repeater.pl
   1123 
   1124     So one does not need to run the repeater on a Windows machine.
   1125 
   1126     Note that even though the UltraVNC repeater tool is NOT SSL enabled,
   1127     it can nevertheless act as a proxy for SSVNC SSL connections.
   1128     This is because, just as with a Web proxy, the proxy negotiations
   1129     occur before the SSL traffic starts.  (There is a separate UltraVNC
   1130     tool, repeater_SSL.exe, that is SSL enabled and is discussed below.)
   1131 
   1132     Note: it seems only SSL SSVNC connections make sense with the
   1133     UltraVNC repeater.  SSH connections (previous section) do not seem to
   1134     and so are not enabled to (let us know if you find a way to use it.)
   1135 
   1136     Unencrypted (aka Direct) SSVNC VNC connections (Vnc:// prefix in
   1137     'VNC Host:Display'; see Tip 5) also work with the UltraVNC repeater.
   1138 
   1139     MODE I REPEATER:
   1140 
   1141     For the mode I UltraVNC repeater the Viewer initiates the connection
   1142     and passes a string that is the VNC server's IP address (or hostname)
   1143     and port or display to the repeater (the repeater then makes the
   1144     connection to the server host and then exchanges data back and forth.)
   1145     To do this in SSVNC:
   1146 
   1147            VNC Host:Display:   :0
   1148            Proxy/Gateway:      repeater://myuvncrep.west:5900+joes-pc:1
   1149 
   1150     Where "myuvncrep.west" is running the UltraVNC repeater and
   1151     "joes-pc:1" is the VNC server the repeater will connect us to.
   1152 
   1153     Note here that the VNC Host:Display can be anything because it is
   1154     not used; we choose :0.  You cannot leave VNC Host:Display empty.
   1155 
   1156     The Proxy/Gateway format is repeater://proxy:port+vncserver:display.
   1157     The string after the "+" sign is passed to the repeater server for
   1158     it to interpret (and so does not have to be the UltraVNC repeater;
   1159     you could create your own if you wanted to.)  For this example,
   1160     instead of joes-pc:1 it could be joes-pc:5901 or 192.168.1.4:1,
   1161     192.168.1.4:5901, etc.
   1162 
   1163     If you do not supply a proxy port, then the default 5900 is assumed,
   1164     e.g. use repeater://myuvncrep.west+joes-pc:1 for port 5900 on
   1165     myuvncrep.west then connecting to port 5901 on joes-pc.
   1166 
   1167     X11VNC: For mode I operation the VNC server x11vnc simply runs as
   1168     a normal SSL/VNC server:
   1169 
   1170        x11vnc -ssl SAVE
   1171 
   1172     because the repeater will connect to it as a VNC client would.
   1173     For mode II operation additional options are needed (see below.)
   1174 
   1175 
   1176     MODE II REPEATER:
   1177 
   1178     For the mode II repeater both the VNC viewer and VNC server initiate
   1179     TCP connections to the repeater proxy.  In this case they pass a string
   1180     that identifies their mutual connection via "ID:NNNN", for example:
   1181 
   1182            VNC Host:Display:   :0
   1183            Proxy/Gateway:      repeater://myuvncrep.west:5900+ID:2345
   1184 
   1185     again, the default proxy port is 5900 if not supplied.  And we need
   1186     to supply a placeholder display ":0".
   1187 
   1188     The fact that BOTH the VNC viewer and VNC server initiate outgoing
   1189     TCP connections to the repeater makes some things tricky, especially
   1190     for the SSL aspect.  In SSL one side takes the 'client' role and
   1191     the other side must take the 'server' role.  These roles must be
   1192     coordinated correctly or otherwise the SSL handshake will fail.
   1193 
   1194     We now describe two scenarios: 1) SSVNC in Listening mode with STUNNEL
   1195     in 'SSL server' role; and 2) SSVNC in Forward mode with STUNNEL in
   1196     'SSL client' role.  For both cases we show how the corresponding
   1197     VNC server x11vnc would be run.
   1198 
   1199     SSVNC Listening mode / STUNNEL 'SSL server' role:
   1200 
   1201       By default, when using SSL over a reverse connection the x11vnc VNC
   1202       server will take the 'SSL client' role.  This way it can connect to a
   1203       standard STUNNEL (SSL server) redirecting connections to a VNC viewer
   1204       in Listen mode.  This is how SSVNC with SSL is normally intended to
   1205       be used for reverse connections (i.e. without the UltraVNC Repeater.)
   1206 
   1207       To do it this way with the mode II UltraVNC Repeater; you set
   1208       Options -> Reverse VNC Connection, i.e. a "Listening Connection".
   1209       You should disable 'Verify All Certs' unless you have already
   1210       saved the VNC Server's certificate to Accepted Certs.  Or you can
   1211       set ServerCert to the saved certificate.  Then click 'Listen'.
   1212       In this case an outgoing connection is made to the UltraVNC
   1213       repeater, but everything else is as for a Reverse connection.
   1214 
   1215       Note that in Listening SSL mode you must supply a MyCert or use the
   1216       "listen.pem" one you are prompted by SSVNC to create.
   1217 
   1218       X11VNC command:
   1219 
   1220         x11vnc -ssl -connect_or_exit repeater://myuvncrep.west+ID:2345
   1221 
   1222 
   1223     SSVNC Forward mode / STUNNEL 'SSL client' role:
   1224 
   1225       x11vnc 0.9.10 and later can act in the 'SSL server' role for Reverse
   1226       connections (i.e. as it does for forward connections.)  Set these
   1227       x11vnc options: '-env X11VNC_DISABLE_SSL_CLIENT_MODE=1 -sslonly'
   1228 
   1229       The -sslonly option is to prevent x11vnc from thinking the delay in
   1230       connection implies VeNCrypt instead of VNC over SSL.  With x11vnc
   1231       in X11VNC_DISABLE_SSL_CLIENT_MODE mode, you can then have SSVNC make
   1232       a regular forward connection to the UltraVNC repeater.
   1233 
   1234       Note that SSVNC may attempt to do a 'Fetch Cert' action in forward
   1235       connection mode to either retrieve the certificate or probe for
   1236       VeNCrypt and/or ANONDH.  After that 'Fetch Cert' is done the
   1237       connection to the UltraVNC repeater will be dropped.  This is a
   1238       problem for the subsequent real VNC connection.  You can disable
   1239       'Verify All Certs' AND also set 'Do not Probe for VeNCrypt'
   1240       to avoid the 'Fetch Cert' action.  Or, perhaps better, add to
   1241       x11vnc command line '-connect_or_exit repeater://... -loop300,2'
   1242       (in addition to the options in the previous paragraphs.)  That way
   1243       x11vnc will reconnect once to the Repeater after the 'Fetch Cert'
   1244       action.  Then things should act pretty much as a normal forward
   1245       SSL connection.
   1246 
   1247       X11VNC 0.9.10 command (split into two lines):
   1248 
   1249         x11vnc -ssl -connect_or_exit repeater://myuvncrep.west+ID:2345 \
   1250              -env X11VNC_DISABLE_SSL_CLIENT_MODE=1 -loop300,2 -sslonly
   1251 
   1252     We recommend using "SSVNC Forward mode / STUNNEL 'SSL client' role"
   1253     if you are connecting to x11vnc 0.9.10 or later.  Since this does
   1254     not use Listen mode it should be less error prone and less confusing
   1255     and more compatible with other features.  Be sure to use all of
   1256     the x11vnc options in the above command line.  To enable VeNCrypt,
   1257     replace '-sslonly' with '-vencrypt force'.  If you do not indicate
   1258     them explicitly to SSVNC, SSVNC may have to probe multiple times for
   1259     VeNCrypt and/or ANONDH.  So you may need '-loop300,4' on the x11vnc
   1260     cmdline so it will reconnect to the UltraVNC repeater 3 times.
   1261 
   1262 
   1263     Note that for UNENCRYPTED (i.e. direct) SSVNC connections (see vnc://
   1264     in Tip 5) using the UltraVNC Repeater mode II there is no need to
   1265     use a reverse "Listening connection" and so you might as well use
   1266     a forward connection.
   1267 
   1268     For Listening connections, on Windows after the VNC connection you
   1269     MUST manually terminate the listening VNC Viewer (and connect again
   1270     if desired.)  Do this by going to the System Tray and terminating
   1271     the Listening VNC Viewer.  Subsequent connection attempts using the
   1272     repeater will fail unless you do this and restart the Listen.
   1273 
   1274     On Unix and MacOS X after the VNC connection the UltraVNC repeater
   1275     proxy script will automatically restart and reconnect to the repeater
   1276     for another connection.  So you do not need to manually restart it.
   1277     To stop the listening, kill the listening VNC Viewer with Ctrl-C.
   1278 
   1279     In the previous sections it was mentioned one can chain up to 3
   1280     proxies together by separating them with commas: proxy1,proxy2,proxy3.
   1281     Except where explicitly noted below this should work for "repeater://..."
   1282     as the final proxy.  E.g. you could use a web proxy to get out of a
   1283     firewall, and then connect to a remote repeater.
   1284 
   1285     The UltraVNC SSL enabled repeater_SSL.exe is discussed below.
   1286 
   1287 
   1288  UltraVNC Single Click:
   1289 
   1290     UltraVNC has Single Click (SC) Windows VNC servers that allow naive
   1291     users to get them running very easily (a EXE download and a few
   1292     mouse clicks).  See http://sc.uvnc.com/ for details on how to create
   1293     these binaries.  Also there is a how-to here:
   1294     http://www.simply-postcode-lookup.com/SingleClickUltraVNC/SingleClickVNC.htm
   1295 
   1296     The SC EXE is a VNC *server* that starts up a Reverse VNC connection
   1297     to a Listening Viewer (e.g. the viewer address/port/ID is hardwired
   1298     into the SC EXE).  So SC is not really a proxy, but it can be used
   1299     with UltraVNC repeater proxies and so we describe it here.
   1300 
   1301     One important point for SC III binary creation: do NOT include
   1302     "-id N" in the helpdesk.txt config file.  This is because the with
   1303     SSVNC the Ultra VNC repeater IS NOT USED (see below for how to
   1304     use it).  Use something like for helpdesk.txt:
   1305 
   1306        [TITLE]
   1307        My UltraVNC SC III
   1308 
   1309        [HOST]
   1310        Internet Support XYZ
   1311        -sslproxy -connect xx.xx.xx.xx:5500 -noregistry
   1312 
   1313     (replace xx.xx.xx.xx with IP address or hostname of the SSVNC machine.)
   1314 
   1315     The Unix SSVNC vncviewer supports the both the unencrypted "SC I"
   1316     mode and the SSL encrypted "SC III" mode.  For both cases SSVNC
   1317     must be run in Listening mode (Options -> Reverse VNC Connection)
   1318 
   1319     For SC I, enable Reverse VNC Connection and put Vnc://0 (see Tip 5
   1320     below) in the VNC Host:Display to disable encryption (use a different
   1321     number if you are not using the default listening port 5500).
   1322     Then click on the "Listen" button and finally have the user run your
   1323     Single Click I EXE.
   1324 
   1325     BTW, we used this for a SC I helpdesk.txt:
   1326 
   1327        [TITLE]
   1328        My UltraVNC SC I
   1329 
   1330        [HOST]
   1331        Internet Support XYZ
   1332        -connect xx.xx.xx.xx:5500 -noregistry
   1333 
   1334     For SC III (SSL), enable Reverse VNC Connection and then UNSET "Verify
   1335     All Certs" (this is required).  Let the VNC Host:Display be ":0"
   1336     (use a different number if you are not using the default listening
   1337     port 5500).  Then click on the "Listen" button and finally have the
   1338     user run your Single Click III EXE.
   1339 
   1340     Note that in Listening SSL mode you MUST supply a MyCert or use the
   1341     "listen.pem" one you are prompted by SSVNC to create.
   1342 
   1343 
   1344  UltraVNC repeater_SSL.exe proxy:
   1345 
   1346     For repeater_SSL.exe SSL usage, with Single Click III or otherwise
   1347     (available at http://www.uvnc.com/pchelpware/SCIII/index.html)
   1348     it helps to realize that the ENTIRE connection is SSL encrypted,
   1349     even the proxy host:port/ID:NNNN negotiation, and so a different
   1350     approach needs to be taken from that described above in 'UltraVNC
   1351     Proxies/Gateways'.  In this case do something like this:
   1352 
   1353            VNC Host:Display:   :0
   1354            Proxy/Gateway:      sslrepeater://myuvncrep.west:443+ID:2345
   1355 
   1356     The sslrepeater:// part indicates the entire ID:XYZ negotiation must
   1357     occur inside the SSL tunnel.  Listening mode is not required in this
   1358     case: a forward VNC connection works fine (and is recommended).
   1359     As before, the ":0" is simply a placeholder and is not used.
   1360     Note that the UltraVNC repeater_SSL.exe listens on port 443 (HTTPS),
   1361     (it is not clear that it can be modified to use another port.)
   1362 
   1363     Non-ID connections sslrepeater://myuvncrep.west:443+host:disp also
   1364     work, but the 2nd leg repeater <-> host:disp must be unencrypted.
   1365     The first leg SSVNC <-> repeater is, however, SSL encrypted.
   1366 
   1367     sslrepeater:// only works on Unix or MacOSX using the provided
   1368     SSVNC vncviewer.  The modified viewer is needed; stock VNC viewers
   1369     will not work.  Also, proxy chaining (bouncing off of more than one
   1370     proxy) currently does not work for repeater_SSL.exe.
   1371 
   1372 
   1373  VeNCrypt is treated as a proxy:
   1374 
   1375     SSVNC supports the VeNCrypt VNC security type.  You will find out more
   1376     about this security type in the other parts of the Help documentation.
   1377     In short, it does a bit of plain-text VNC protocol negotiation before
   1378     switching to SSL/TLS encryption and authentication.
   1379 
   1380     SSVNC implements its VeNCrypt support as final proxy in a chain
   1381     of proxies.  You don't need to know this or specify anything, but
   1382     it is good to know since it uses up one of the 3 proxies you are
   1383     allowed to chain together.  If you watch the command output you will
   1384     see the vencrypt:// proxy item.
   1385 
   1386     You can specify that a VNC server uses VeNCrypt (Options -> Advanced)
   1387     or you can let SSVNC try to autodetect VeNCrypt.
   1388 
   1389 
   1390  IPv6 can be treated as a proxy for UN-ENCRYPTED connections:
   1391 
   1392     Read Tip 20 about SSVNC's IPv6 (128 bit IP addresses) support.
   1393     In short, because stunnel and ssh support IPv6 hostnames and
   1394     addresses, SSVNC does too without you needing to do anything.
   1395 
   1396     However, in some rare usage modes you will need to specify the IPv6
   1397     server destination in the Proxy/Gateway entry box.  The only case
   1398     this appears to be needed is when making an un-encrypted connection
   1399     to an IPv6 VNC server.  In this case neither stunnel nor ssh are
   1400     used and you need to specify something like this:
   1401 
   1402               VNC Host:Display:       localhost:0
   1403               Proxy/Gateway:          ipv6://2001:4860:b009::68:5900
   1404 
   1405     and then select 'None' as the encryption type.  Note that the above
   1406     'localhost:0' setting can be anything; it is basically ignored.
   1407 
   1408     Note that on Unix, MacOSX, and Windows un-encrypted ipv6 connections
   1409     are AUTODETECTED and so you likely NEVER need to supply ipv6://
   1410     Only try it if you encounter problems.  Also note that the ipv6://
   1411     proxy type does not work on Windows, so only the autodetection is
   1412     available there.
   1413 
   1414     Note that if there is some other proxy, e.g. SOCKS or HTTP and that
   1415     proxy server is an IPv6 host (or will connect you to one) then any
   1416     sort of connection through that proxy will work OK: un-encrypted as
   1417     well as SSL or SSH connections, etc.
   1418 
   1419     Unencrypted connection is the only special case where you may need
   1420     to specify an ipv6:// proxy.  If you find another use let us know.
   1421 
   1422     See Tip 20 for more info.
   1423 }
   1424 
   1425 	set help_tips {
   1426  Tips and Tricks:
   1427 
   1428      Table of Contents:
   1429 
   1430       1) Connect to Non-Standard SSH port.
   1431       2) Reverse VNC connections (Listening)
   1432       3) Global options in ~/.ssvncrc
   1433       4) Fonts
   1434       5) vnc://host for un-encrypted connection
   1435       6) Home directory for memory stick usage, etc.
   1436       7) vncs:// vncssl:// vnc+ssl:// vnc+ssh:// URL-like prefixes
   1437       8) sshvnc / -ssh SSH only GUI
   1438       9) tsvnc / -ts Terminal services only GUI (SSH+x11vnc)
   1439      10) 2nd GUI window on Unix/MacOSX
   1440      11) Ctrl-L or Button3 to Load profile
   1441      12) SHELL command or Ctrl-S for SSH terminal w/o VNC
   1442      13) KNOCK command for port-knock sequence
   1443      14) Unix/MacOSX general SSL redirector (not just VNC)
   1444      15) Environment variables
   1445      16) Bigger "Open File" dialog window
   1446      17) Unix/MacOSX extra debugging output
   1447      18) Dynamic VNC Server Port determination with SSH
   1448      19) No -t ssh cmdline option for older sshd
   1449      20) IPv6 support.
   1450 
   1451      1) To connect in SSH-Mode to a server running SSH on a non-standard
   1452         port (22 is the standard port) you need to use the Proxy/Gateway
   1453         setting.  The following is from the Proxies Help panel:
   1454 
   1455         NON-STANDARD SSH PORT: To use a non-standard ssh port (i.e. a port other
   1456         than 22) you need to use the Proxy/Gateways as well.  E.g. something
   1457         like this for port 2222:
   1458 
   1459                VNC Host:Display:   localhost:0
   1460                Proxy/Gateway:      joe@far-away.east:2222
   1461 
   1462         The username@ is not needed if it is the same as on the client.  This
   1463         will also work going to a different internal machine, e.g. "joes-pc:0"
   1464         instead of "localhost:0", as in the first example.
   1465 
   1466      2) Reverse VNC connections (Listening) are possible as well.
   1467         In this case the VNC Server initiates the connection to your
   1468         waiting (i.e. listening) SSVNC viewer.
   1469 
   1470         Go to Options and select "Reverse VNC connection".  In the 'VNC
   1471         Host:Display' entry box put in the number (e.g. "0" or ":0", or
   1472         ":1", etc) that corresponds to the Listening display (0 -> port
   1473         5500, 1 -> port 5501, etc.) you want to use.  Then clicking on
   1474         'Listen' puts your SSVNC viewer in a "listening" state on that
   1475         port number, waiting for a connection from the VNC Server.
   1476 
   1477         On Windows or using a 3rd party VNC Viewer multiple, simultaneous
   1478         reverse connections are always enabled.  On Unix/MacOSX with the
   1479         provided ssvncviewer they are disabled by default.  To enable them:
   1480         Options -> Advanced -> Unix ssvncviewer -> Multiple LISTEN Connections
   1481 
   1482         Specify a specific interface, e.g. 192.168.1.1:0 to have stunnel
   1483         only listen on that interface.  IPv6 works too, e.g. :::0 or ::1:0
   1484         This also works for UN-encrypted reverse connections as well ('None').
   1485 
   1486         See the Options Help for more info.
   1487 
   1488      3) You can put global options in your ~/.ssvncrc file (ssvnc_rc on
   1489         Windows). Currently they are:
   1490 
   1491 	Put "mode=tsvnc" or "mode=sshvnc" in the ~/.ssvncrc file to have
   1492 	the application start up in the given mode.
   1493 
   1494         desktop_type=wmaker    (e.g.) to switch the default Desktop Type.
   1495 
   1496         desktop_size=1280x1024 (e.g.) to switch the default Desktop Size.
   1497 
   1498         desktop_depth=24       (e.g.) to switch the default Desktop Color Depth
   1499 
   1500         xserver_type=Xdummy    (e.g.) to switch the default X Server Type.
   1501 
   1502         (The above 4 settings apply only to the Terminal Services Mode.)
   1503 
   1504         noenc=1  (same as the -noenc option for a 'No Encryption' option)
   1505         noenc=0  (do not show the 'No Encryption' option)
   1506 
   1507         killstunnel=1 (same as -killstunnel), on Windows automatically kills
   1508         the STUNNEL process when the viewer exits.  Disable via killstunnel=0
   1509         and -nokillstunnel.
   1510 
   1511         ipv6=0   act as though IPv6 was not detected.
   1512         ipv6=1   act as though IPv6 was detected.
   1513 
   1514         cotvnc=1 have the default vncviewer on Mac OS X be the Chicken of
   1515         the VNC.  By default the included ssvnc X11 vncviewer is used
   1516         (requires Mac OS X X11 server to be running.)
   1517 
   1518         mycert=file (same as -mycert file option).  Set your default MyCert
   1519         to "file".  If file does not exist ~/.vnc/certs/file is used.
   1520 
   1521         cacert=file (same as -cacert file option).  Set your default ServerCert
   1522         to "file".  If file does not exist ~/.vnc/certs/file is used.  If
   1523         file is "CA" then ~/.vnc/certs/CA/cacert.pem is used.
   1524 
   1525         crl=file (same as -crl file option).  Set your default CRL File
   1526         to "file".  If file does not exist ~/.vnc/certs/file is used.
   1527 
   1528         Prefix any of these cert/key files with "FORCE:" to make them
   1529         immutable, e.g.  "cacert=FORCE:CA".
   1530 
   1531         You can set any environment variable in ~/.ssvncrc by using a line
   1532         like env=VAR=value, for example:  env=SSVNC_FINISH_SLEEP=2
   1533 
   1534         To change the fonts (see Tip 4 below for examples):
   1535 
   1536         font_default=tk-font-name     (sets the font for menus and buttons)
   1537         font_fixed=tk-font-name       (sets the font for help text)
   1538 
   1539      4) Fonts: To change the tk fonts, set these environment variables
   1540         before starting up ssvnc: SSVNC_FONT_DEFAULT and SSVNC_FONT_FIXED.
   1541         For example:
   1542 
   1543             % env SSVNC_FONT_DEFAULT='helvetica -20 bold' ssvnc
   1544             % env SSVNC_FONT_FIXED='courier -14' ssvnc
   1545 
   1546         or set both of them at once.  You can also set 'font_default' and
   1547         'font_fixed' in your ~/.ssvncrc.  E.g.:
   1548 
   1549         font_default=helvetica -16 bold
   1550         font_fixed=courier -12
   1551 
   1552      5) If you want to make a Direct VNC connection, WITH *NO* SSL OR
   1553         SSH ENCRYPTION or authentication, use the "vnc://" prefix in the
   1554         VNC Host:Display entry box, e.g. "vnc://far-away.east:0"  This
   1555         also works for reverse connections, e.g. vnc://0
   1556 
   1557         Use Vnc:// (i.e. capital 'V') to avoid being prompted if you are
   1558         sure you want no encryption.  For example, "Vnc://far-away.east:0"
   1559         Shift+Ctrl-E in the entry box is a short-cut to add or remove
   1560         the prefix "Vnc://" from the host:disp string.
   1561 
   1562         You can also run ssvnc with the '-noenc' cmdline option (now
   1563         the default) to have a check option 'None' that lets you turn off
   1564         Encryption (and profiles will store this setting).  Pressing Ctrl-E
   1565         on the main panel is a short-cut to toggle between the -noenc 'No
   1566         Encryption' mode and normal mode.  The option "Show 'No Encryption'
   1567         Option" under Options also toggles it.
   1568 
   1569         The '-enc' option disables the button (and so makes it less obvious
   1570         to naive users how to disable encryption.)
   1571 
   1572         Note as of SSVNC 1.0.25 the '-noenc' mode is now the default. I.e.
   1573         the 'No Encryption' option ('None') is shown by default.  When
   1574         you select 'None' you do not need to supply the "vnc://" prefix.
   1575         To disable the button supply the '-enc' cmdline option.
   1576 
   1577         Setting SSVNC_DISABLE_ENCRYPTION_BUTTON=1 in your environment is
   1578         the same as -noenc.  You can also put noenc=1 in your ~/.ssvncrc file.
   1579 
   1580         Setting SSVNC_DISABLE_ENCRYPTION_BUTTON=0 in your environment is
   1581         the same as -enc.  You can also put noenc=0 in your ~/.ssvncrc file.
   1582 
   1583         Please be cautious/thoughtful when you make a VNC connection with
   1584         encryption disabled.  You may send sensitive information (e.g. a
   1585         password) over the network that can be sniffed.
   1586 
   1587         It is also possible (although difficult) for someone to hijack an
   1588         existing unencrypted VNC session.
   1589 
   1590         Often SSVNC is used to connect to x11vnc where the Unix username and
   1591         password is sent over the channel.  It would be a very bad idea to
   1592         let that data be sent over an unencrypted connection!  In general,
   1593         it is not wise to have a plaintext VNC connection.
   1594 
   1595         Note that even the VNC Password challenge-response method (the password
   1596         is not sent in plaintext) leaves your VNC password susceptible to a
   1597         dictionary attack unless encryption is used to hide it.
   1598 
   1599         So (well, before we made the button visible by default!) we forced
   1600         you to learn about and supply the "vnc://" or "Vnc://" prefix to
   1601         the host:port or use -noenc or the "Show 'No Encryption' Option"
   1602         to disable encryption.  This is a small hurdle, but maybe someone
   1603         will think twice.  It is a shame that VNC has been around for
   1604         over 10 years and still does not have built-in strong encryption.
   1605 
   1606         Note the Vnc:// or vnc:// prefix will be stored in any profile that
   1607         you save so you do not have to enter it every time.
   1608 
   1609         Set the env var SSVNC_NO_ENC_WARN=1 to skip the warning prompts the
   1610         same as the capitalized Vnc:// does.
   1611 
   1612      6) Mobile USB memory stick / flash drive usage:  You can unpack
   1613         ssvnc to a flash drive for impromptu usage (e.g. from a friends
   1614         computer).
   1615 
   1616         If you create a directory "Home" in the toplevel ssvnc directory,
   1617         then that will be the default location for your VNC profiles
   1618         and certs.  So they follow the drive this way.  If you run like
   1619         this: "ssvnc ." or "ssvnc.exe ." the "Home" directory will be
   1620         created for you.
   1621 
   1622         WARNING: if you use ssvnc from an "Internet Cafe", i.e. an
   1623         untrusted computer, an unscrupulous person may be capturing
   1624         keystrokes, etc.!
   1625 
   1626 	You can also set the SSVNC_HOME env. var. to point to any
   1627 	directory you want. It can be set after starting ssvnc by putting
   1628 	HOME=/path/to/dir in the Host:Display box and clicking "Connect".
   1629 
   1630         For a Windows BAT file to get the "Home" directory correct
   1631         something like this might be needed:
   1632 
   1633          cd \ssvnc\Windows
   1634          start \ssvnc\Windows\ssvnc.exe
   1635 
   1636      7) In the VNC Host:Display entry you can also use these "URL-like"
   1637         prefixes:
   1638 
   1639            vncs://host:0, vncssl://host:0, vnc+ssl://host:0  for SSL
   1640 
   1641         and
   1642 
   1643            vncssh://host:0, vnc+ssh://host:0                 for SSH
   1644 
   1645         There is no need to toggle the SSL/SSH setting.  These also work
   1646         from the command line, e.g.:  ssvnc vnc+ssh://mymachine:10
   1647 
   1648      8) If you want this application to be SSH only, then supply the
   1649         command line option "-ssh" or set the env. var SSVNC_SSH_ONLY=1.
   1650 
   1651         Then no GUI elements specific to SSL will appear (the
   1652         documentation wills still refer to the SSL mode, however).
   1653         To convert a running app to ssh-only select "Mode: SSH-Only"
   1654         in Options.
   1655 
   1656         The wrapper scripts "sshvnc" and "sshvnc.bat" will start it up
   1657         automatically this way.
   1658 
   1659         Or in your ~/.ssvncrc (or ~/ssvnc_rc on Windows) put "mode=sshvnc"
   1660         to have the tool always start up in that mode.
   1661 
   1662      9) For an even simpler "Terminal Services" mode use "tsvnc" or
   1663         "tsvnc.bat" (or "-ts" option).  This mode automatically launches
   1664         x11vnc on the remote side to find or create your Desktop session
   1665         (usually the Xvfb X server).  So x11vnc must be available on the
   1666         remote server machines under "Terminal Services" mode.
   1667 
   1668         From a full ssvnc you can press Ctrl-h to go into ssh-only mode
   1669         and Ctrl-t to toggle between "tsvnc" and "ssvnc" modes.  The
   1670         Options Mode menu also let you switch.
   1671 
   1672         Or in your ~/.ssvncrc (or ~/ssvnc_rc on Windows) put "mode=tsvnc"
   1673         to have the tool always start up in that mode.
   1674 
   1675     10) On Unix to get a 2nd GUI (e.g. for a 2nd connection) press Ctrl-N
   1676         on the GUI.  If only the xterm window is visible you can press
   1677         Ctrl-N or try Ctrl-LeftButton -> New SSVNC_GUI.  On Windows you
   1678         will have to manually Start a new one: Start -> Run ..., etc.
   1679 
   1680     11) Pressing the "Load" button or pressing Ctrl-L or Clicking the Right
   1681         mouse button on the main GUI will invoke the Load dialog.
   1682 
   1683         Pressing Ctrl-O on the main GUI will bring up the Options Panel.
   1684         Pressing Ctrl-A on the main GUI will bring up the Advanced Options.
   1685 
   1686     12) If you use "SHELL" for the "Remote SSH Command" (or in the display
   1687         line: "user@hostname cmd=SHELL") then you get an SSH shell only:
   1688         no VNC viewer will be launched.  On Windows "PUTTY" will try
   1689         to use putty.exe (better terminal emulation than plink.exe).
   1690 
   1691         A ShortCut for this is Ctrl-S with user@hostname in the entry box.
   1692 
   1693     13) If you use "KNOCK" for the "Remote SSH Command" (or in the display
   1694         line "user@hostname cmd=KNOCK") then only the port-knocking is done.
   1695 
   1696         A ShortCut for this is Ctrl-P with hostname the entry box.
   1697 
   1698         If it is KNOCKF, i.e. an extra "F", then the port-knocking
   1699         "FINISH" sequence is sent, if any.  A ShortCut for this
   1700         Shift-Ctrl-P as long as hostname is present.
   1701 
   1702     14) On Unix to have SSVNC act as a general STUNNEL redirector (i.e. no
   1703         VNC), put the desired host:port in VNC Host:Display (use a
   1704         negative port value if it is to be less than 200), then go to
   1705         Options -> Advanced -> Change VNC Viewer.  Change the "viewer"
   1706         command to be "xmessage OK" or "xmessage <port>" (or sleep) where
   1707         port is the desired local listening port.  Then click Connect.
   1708         If you didn't set the local port look for it in the terminal output.
   1709 
   1710         On Windows set 'viewer' to "NOTEPAD" or similar; you can't
   1711         control the port though.  It is usually 5930, 5931, ... Watch
   1712         the messages or look at the stunnel log.
   1713 
   1714     15) Tricks with environment variables:
   1715 
   1716         You can change the X DISPLAY variable by typing DISPLAY=... into
   1717         VNC Host:Display and hitting Return or clicking Connect. Same
   1718         for HOME=.  On Mac, you can set DYLD_LIBRARY_PATH=... too.
   1719         It should propagate down the viewer.
   1720 
   1721         Setting SLEEP=n increases the amount of time waited before
   1722         starting the viewer.  The env. var. SSVNC_EXTRA_SLEEP also does
   1723         this (and also Sleep: Option setting) Setting FINISH=n sets the
   1724         amount of time slept before the Terminal window exits on Unix
   1725         and MacOS X.  (same as SSVNC_FINISH_SLEEP env. var.)
   1726 
   1727         Full list of parameters HOME/SSVNC_HOME, DISPLAY/SSVNC_DISPLAY
   1728         DYLD_LIBRARY_PATH/SSVNC_DYLD_LIBRARY_PATH, SLEEP/SSVNC_EXTRA_SLEEP
   1729         FINISH/SSVNC_FINISH_SLEEP, DEBUG_NETSTAT, REPEATER_FORCE,
   1730         SSH_ONLY, TS_ONLY, NO_DELETE, BAT_SLEEP, IPV6/SSVNC_IPV6=0 or 1.
   1731         See below for more info.  (the ones joined by "/" are equivalent
   1732         names, and the latter can be set as an env. var. as well.)
   1733 
   1734         After you set the parameter, clear out the 'VNC Host:Display'
   1735         entry and replace it with the actual host and display number.
   1736 
   1737         To replace the xterm terminal where most of the external commands
   1738         are run set SSVNC_XTERM_REPLACEMENT to a command that will run
   1739         a command in a terminal.  I.e.:  "$SSVNC_XTERM_REPLACEMENT cmd"
   1740         will run cmd.  If present, %GEOMETRY is expanded to a desired
   1741         +X+Y geometry.  If present, %TITLE is expanded to a desired title.
   1742         Examples: SSVNC_XTERM_REPLACEMENT='gnome-terminal -e'
   1743                   SSVNC_XTERM_REPLACEMENT='gnome-terminal -t "%TITLE" -e'
   1744                   SSVNC_XTERM_REPLACEMENT='konsole -e'
   1745 
   1746         More info: EXTRA_SLEEP: seconds of extra sleep in scripts;
   1747         FINISH_SLEEP: final extra sleep at end; DEBUG_NETSTAT put up a
   1748         window showing what netstat reports; NO_DELETE: do not delete tmp
   1749         bat files on Windows (for debugging); BAT_SLEEP: sleep this many
   1750         seconds at the end of each Windows bat file (for debugging.)
   1751 
   1752         You can also set any environment variable by entering in something
   1753         like ENV=VAR=VAL  e.g. ENV=SSH_AUTH_SOCK=/tmp/ssh-BF2297/agent.2297
   1754         Use an empty VAL to unset the variable.
   1755 
   1756         There are also a HUGE number of env. vars. that apply to the Unix
   1757         and MacOS X wrapper script 'ss_vncviewer' and/or the ssvncviewer
   1758         binary.  See Options -> Advanced -> Unix ssvncviewer -> Help for
   1759         all of them.
   1760 
   1761     16) On Unix you can make the "Open File" and "Save File" dialogs
   1762         bigger by setting the env. var. SSVNC_BIGGER_DIALOG=1 or
   1763         supplying the -bigger option.  If you set it to a Width x Height,
   1764         e.g. SSVNC_BIGGER_DIALOG=500x200, that size will be used.
   1765 
   1766     17) On Unix / MacOSX to enable debug output you can set these env.
   1767         vars to 1: SSVNC_STUNNEL_DEBUG, SSVNC_VENCRYPT_DEBUG, and
   1768         SS_DEBUG (very verbose)
   1769 
   1770     18) Dynamic VNC Server Port determination and redirection:  If you
   1771         are running SSVNC on Unix and are using SSH to start the remote
   1772         VNC server and the VNC server prints out the line "PORT=NNNN"
   1773         to indicate which dynamic port it is using (x11vnc does this),
   1774         then if you prefix the SSH command with "PORT=" SSVNC will watch
   1775         for the PORT=NNNN line and uses ssh's built in SOCKS proxy
   1776         (ssh -D ...) to connect to the dynamic VNC server port through
   1777         the SSH tunnel.  For example:
   1778 
   1779                 VNC Host:Display     user@somehost.com
   1780                 Remote SSH Command:  PORT= x11vnc -find -nopw
   1781 
   1782         or "PORT= x11vnc -display :0 -localhost", etc.  Or use "P= ..."
   1783 
   1784         There is also code to detect the display of the regular Unix
   1785         vncserver(1).  It extracts the display (and hence port) from
   1786         the lines "New 'X' desktop is hostname:4" and also
   1787         "VNC server is already running as :4".  So you can use
   1788         something like:
   1789 
   1790                 PORT= vncserver; sleep 15
   1791         or:     PORT= vncserver :4; sleep 15
   1792 
   1793         the latter is preferred because when you reconnect with it will
   1794         find the already running one.  The former one will keep creating
   1795         new X sessions if called repeatedly.
   1796 
   1797         On Windows if PORT= is supplied SOCKS proxying is not used, but
   1798         rather a high, random value of the VNC port is chosen (e.g. 8453)
   1799         and assumed to be free, and is passed to x11vnc's -rfbport option.
   1800         This only works with x11vnc (not vncserver).
   1801 
   1802     19) On Unix if you are going to an older SSH server (e.g. Solaris 10),
   1803         you will probably need to set the env. var. SS_VNCVIEWER_NO_T=1
   1804         to disable the ssh "-t" option being used (that can prevent the
   1805         command from being run).
   1806 
   1807     20) SSVNC is basically a wrapper for the stunnel and ssh programs,
   1808         and because those two programs have good IPv6 support SSVNC will
   1809         for most usage modes support it as well.  IPv6 is 128 bit internet
   1810         addresses (as opposed to IPv4 with its 32 bit xxx.yyy.zzz.nnn IPs.
   1811 
   1812         So for basic SSL and SSH connections if you type in an IPv6 IP
   1813         address, e.g. '2001:4860:b009::68', or a hostname with only an
   1814         IPv6 lookup, e.g. ipv6.l.google.com, the connection will work
   1815         because stunnel and ssh handle these properly.
   1816 
   1817         Note that you often need to supply a display number or port after
   1818         the address so put it, e.g. ':0' at the end: 2001:4860:b009::68:0
   1819         You can also use the standard notation [2001:4860:b009::68]:0
   1820         that is more clear.  You MUST specify the display if you use
   1821         the IPv6 address notation (but :0 is still the default for a
   1822         non-numeric hostname string.)
   1823 
   1824         IPv4 addresses encoded in IPv6 notation also work, e.g.
   1825         ::ffff:192.168.1.100 should work for the most part.
   1826 
   1827         SSVNC on Unix and MacOSX also has its own Proxy helper tool
   1828         (pproxy)  This script has been modified to handle IPv6 hostnames
   1829         and addresses as long as the IO::Socket::INET6 Perl module
   1830         is available.  On Windows the relay6.exe tool is used.
   1831 
   1832         So for the most part IPv6 should work without you having to do
   1833         anything special.  However, for rare usage, the proxy helper tool
   1834         can also treat and IPv6 address as a special sort of 'proxy'.
   1835         So in the entry Proxy/Gateway you can include ipv6://host:port
   1836         and the IPv6 host will simply be connected to and the data
   1837         transferred.  In this usage mode, set the VNC Host:Display
   1838         to anything, e.g. 'localhost:0'; it is ignored if the ipv6://
   1839         endpoint is specified as a proxy.  Need for ipv6:// usage proxy
   1840         should be rare.
   1841 
   1842         Note that for link local (not global) IPv6 addresses you may
   1843         need to include the network interface at the end of the address,
   1844         e.g. fe80::a00:20ff:fefd:53d4%eth0
   1845 
   1846         Note that one can use a 3rd party VNC Viewer with SSVNC (see
   1847         Options -> Advanced -> Change VNC Viewer.)  IPv6 will work for
   1848         them as well even if they do not support IPv6.
   1849 
   1850         IPv6 support on Unix, MacOSX, and Windows is essentially complete
   1851         for all types of connections (including proxied, unencrypted and
   1852         reverse connections.)  Let us know if you find a scenario that
   1853         does not work (see the known exception for putty/plink below.)
   1854 
   1855         You can set ipv6=0 in your ssvncrc, then no special relaying for
   1856         IPv6 will be done (do this if there are problems or slowness in
   1857         trying to relay ipv6 and you know you will not connect to any
   1858         such hosts.)  Set ipv6=1 to force the special processing even if
   1859         IPv6 was not autodetected.  To change this dynamically, you also
   1860         enter IPV6=... in the VNC Host:Display entry box and press Enter.
   1861         Also on Unix or MacOSX you can set the env. var. SSVNC_IPV6=0
   1862         to disable the wrapper script from checking if hosts have ipv6
   1863         addresses (this is the same as setting ipv6=0 in ssvncrc or by
   1864         the setting ipv6 in the Entry box.)
   1865 
   1866         On Windows plink.exe (SSH client) currently doesn't work for
   1867         IPv6 address strings (e.g. 2001:4860:b009::68) but it does work
   1868         for hostname strings that resolve to IPv6 addresses.
   1869 
   1870         Note that one can make a home-brew SOCKS5 ipv4-to-ipv6 gateway
   1871         proxy using ssh like this:
   1872 
   1873           ssh -D '*:1080' localhost "printf 'Press Enter to Exit: '; read x"
   1874 
   1875         then specify a proxy like socks5://hostname:1080 where hostname
   1876         is the machine running the above ssh command.  Add '-v' to the
   1877         ssh cmdline for verbose output.  See also the x11vnc inet6to4 tool
   1878         (a direct ipv4/6 relay, not socks.)
   1879 }
   1880 
   1881 	global version
   1882 	set help_main "                             SSVNC version: $version\n$help_main"
   1883 	set help_misc "                             SSVNC version: $version\n$help_misc"
   1884 	set help_prox "                             SSVNC version: $version\n$help_prox"
   1885 	set help_tips "                             SSVNC version: $version\n$help_tips"
   1886 
   1887 	frame .h.w
   1888 	button .h.w.b1 -text "Main"    -command {help_text main}
   1889 	button .h.w.b2 -text "Proxies" -command {help_text prox}
   1890 	button .h.w.b3 -text "Misc"    -command {help_text misc}
   1891 	button .h.w.b4 -text "Tips"    -command {help_text tips}
   1892 
   1893 	pack .h.w.b1 .h.w.b2 .h.w.b3 .h.w.b4 -side left -fill x -expand 1
   1894 
   1895 	pack .h.w -side bottom -after .h.d -fill x
   1896 
   1897 	.h.f.t insert end $help_main
   1898 	jiggle_text .h.f.t
   1899 }
   1900 
   1901 proc help_text {which} {
   1902 	global help_main help_misc help_prox help_tips
   1903 	set txt ""
   1904 	if {$which == "main"} {
   1905 		set txt $help_main
   1906 	}
   1907 	if {$which == "misc"} {
   1908 		set txt $help_misc
   1909 	}
   1910 	if {$which == "prox"} {
   1911 		set txt $help_prox
   1912 	}
   1913 	if {$which == "tips"} {
   1914 		set txt $help_tips
   1915 	}
   1916 	catch {.h.f.t delete 0.0 end; .h.f.t insert end $txt; jiggle_text .h.f.t}
   1917 }
   1918 
   1919 proc ssvnc_escape_help {} {
   1920 	toplev .ekh
   1921 
   1922 	scroll_text_dismiss .ekh.f
   1923 
   1924 	center_win .ekh
   1925 	wm title .ekh "SSVNC Escape Keys Help"
   1926 
   1927 	set msg {
   1928  SSVNC Escape Keys:
   1929 
   1930    The Unix SSVNC VNC Viewer, ssvncviewer(1), has an 'Escape Keys'
   1931    mechanism that enables using keystrokes that are bound as 'Hot Keys'
   1932    to specific actions.
   1933 
   1934    So, when you have all of the modifier keys ('escape keys') pressed down,
   1935    then subsequent keystrokes are interpreted as local special actions
   1936    instead of being sent to the remote VNC server.
   1937 
   1938    This enables quick parameter changing and also panning of the viewport.
   1939    E.g. the keystroke 'r' is mapped to refresh the screen.
   1940 
   1941    Enter 'default' in the entry box to enable this feature and to use the
   1942    default modifier list (Alt_L,Super_L on unix and Control_L,Meta_L on
   1943    macosx) or set it to a list of modifier keys, e.g. Alt_L,Control_L.
   1944    Note that _L means left side of keyboard and _R means right side.
   1945 
   1946    Alt_L is the 'Alt' key on the left side of the keyboard, and Super_L
   1947    is usually the 'WindowsFlaggie(TM)' on the left side of the keyboard,
   1948    so when both of those are pressed, the escape keys mapping take effect.
   1949 
   1950 
   1951    Here is info from the ssvncviewer(1) manual page:
   1952 
   1953      -escape str    This sets the 'Escape Keys' modifier sequence and enables
   1954                     escape keys mode.  When the modifier keys escape sequence
   1955                     is held down, the next keystroke is interpreted locally
   1956                     to perform a special action instead of being sent to the
   1957                     remote VNC server.
   1958 
   1959                     Use '-escape default' for the default modifier sequence.
   1960                     (Unix: Alt_L,Super_L and MacOSX: Control_L,Meta_L)
   1961 
   1962     Here are the 'Escape Keys: Help+Set' instructions from the Popup Menu:
   1963 
   1964     Escape Keys:  Enter a comma separated list of modifier keys to be the
   1965     'escape sequence'.  When these keys are held down, the next keystroke is
   1966     interpreted locally to invoke a special action instead of being sent to
   1967     the remote VNC server.  In other words, a set of 'Hot Keys'.
   1968 
   1969     To enable or disable this, click on 'Escape Keys: Toggle' in the Popup.
   1970 
   1971     Here is the list of hot-key mappings to special actions:
   1972 
   1973        r: refresh desktop  b: toggle bell   c: toggle full-color
   1974        f: file transfer    x: x11cursor     z: toggle Tight/ZRLE
   1975        l: full screen      g: graball       e: escape keys dialog
   1976        s: scale dialog     +: scale up (=)  -: scale down (_)
   1977        t: text chat                         a: alphablend cursor
   1978        V: toggle viewonly  Q: quit viewer   1 2 3 4 5 6: UltraVNC scale 1/n
   1979 
   1980        Arrow keys:         pan the viewport about 10% for each keypress.
   1981        PageUp / PageDown:  pan the viewport by a screenful vertically.
   1982        Home   / End:       pan the viewport by a screenful horizontally.
   1983        KeyPad Arrow keys:  pan the viewport by 1 pixel for each keypress.
   1984        Dragging the Mouse with Button1 pressed also pans the viewport.
   1985        Clicking Mouse Button3 brings up the Popup Menu.
   1986 
   1987     The above mappings are *always* active in ViewOnly mode, unless you set the
   1988     Escape Keys value to 'never'.
   1989 
   1990     If the Escape Keys value below is set to 'default' then a default list of
   1991     of modifier keys is used.  For Unix it is: Alt_L,Super_L and for MacOSX it
   1992     is Control_L,Meta_L.  Note: the Super_L key usually has a Windows(TM) Flag
   1993     on it.  Also note the _L and _R mean the key is on the LEFT or RIGHT side
   1994     of the keyboard.
   1995 
   1996     On Unix   the default is Alt and Windows keys on Left side of keyboard.
   1997     On MacOSX the default is Control and Command keys on Left side of keyboard.
   1998 
   1999     Example: Press and hold the Alt and Windows keys on the LEFT side of the
   2000     keyboard and then press 'c' to toggle the full-color state.  Or press 't'
   2001     to toggle the ultravnc Text Chat window, etc.
   2002 
   2003     To use something besides the default, supply a comma separated list (or a
   2004     single one) from: Shift_L Shift_R Control_L Control_R Alt_L Alt_R Meta_L
   2005     Meta_R Super_L Super_R Hyper_L Hyper_R or Mode_switch.
   2006 }
   2007 
   2008 	.ekh.f.t insert end $msg
   2009 	jiggle_text .ekh.f.t
   2010 }
   2011 
   2012 #    Or Alternatively one can supply both hosts separated by
   2013 #    spaces (with the proxy second) in the VNC Host:Display box:
   2014 #
   2015 #           VNC Host-Display:   far-away.east:0    theproxy.net:8080
   2016 #
   2017 #    This looks a little strange, but it actually how SSVNC stores the
   2018 #    host info internally.
   2019 
   2020 #    You can also specify the remote SSH command by putting a string like
   2021 #
   2022 #         cmd=x11vnc -nopw -display :0 -rfbport 5900 -localhost
   2023 #
   2024 #    (use any command you wish to run) at the END of the VNC Host:Display
   2025 #    entry.  In general, you can cram it all in the VNC Host:Display if
   2026 #    you like:   host:disp  proxy:port  cmd=...  (this is the way it is
   2027 #    stored internally).
   2028 
   2029 proc help_certs {} {
   2030 	toplev .ch
   2031 
   2032 	set h 33
   2033 	if [small_height] {
   2034 		set h 28
   2035 	}
   2036 	scroll_text_dismiss .ch.f 87 $h
   2037 
   2038 	center_win .ch
   2039 	wm resizable .ch 1 0
   2040 
   2041 	wm title .ch "SSL Certificates Help"
   2042 
   2043 	set msg {
   2044  Description:
   2045 
   2046     *** IMPORTANT ***: Only with SSL Certificate verification (either manually
   2047     or via a Certificate Authority certificate) can Man-In-The-Middle attacks be
   2048     prevented.  Otherwise, only passive network sniffing attacks are prevented.
   2049     There are hacker tools like dsniff/webmitm and cain that implement SSL
   2050     Man-In-The-Middle attacks.  They rely on the client user not bothering to
   2051     check the cert.
   2052 
   2053     Some people may be confused by the above because they are familiar with
   2054     their Web Browser using SSL (i.e. https://... websites) and those sites
   2055     are authenticated securely without the user's need to verify anything
   2056     manually.  The reason why this happens automatically is because 1) their
   2057     web browser comes with a bundle of Certificate Authority certificates
   2058     and 2) the https sites have paid money to the Certificate Authorities to
   2059     have their website certificate signed by them.  When using SSL in VNC we
   2060     normally do not do something this sophisticated, and so we have to verify
   2061     the certificates manually.  However, it is possible to use Certificate
   2062     Authorities with SSVNC; that method is described below.
   2063 
   2064     The SSL Certificate files described below may have been created externally
   2065     (e.g. by x11vnc or openssl): you can import them via "Import Certificate".
   2066     OR you can click on "Create Certificate ..." to use THIS program to generate
   2067     a Certificate + Private Key pair for you (in this case you will need to
   2068     distribute one of the generated files to the VNC Server).
   2069 
   2070     Then you associate the Saved cert with the VNC server, see the panel entry
   2071     box description below.  Then click Connect.  You will usually want to Save
   2072     this association in a VNC Server profile for the next time you connect.
   2073 
   2074  Expiration:
   2075 
   2076     SSL Certificates will Expire after a certain period (usually 1-2 years;
   2077     if you create a cert with this tool you can set it to any length you want).
   2078     So if for a particular Cert you find you can no longer connect, check the
   2079     STUNNEL log output to see if the cert has expired.  Then create and distribute
   2080     a new one.
   2081 
   2082  Fetch Cert:
   2083 
   2084     You can also retrieve and view the VNC Server's Cert via the "Fetch Cert"
   2085     button on the main panel.  After you check that it is the correct Cert (e.g. by
   2086     comparing MD5 hash or other info), you can save it.  The file it was saved
   2087     as will be set as the "ServerCert" to verify against for the next connection.
   2088     To make this verification check permanent, you will need to save the profile
   2089     via 'Save'.
   2090 
   2091     NOTE: See the CA section below for how "Fetch Cert/Verify All Certs" WILL NOT
   2092     WORK when a Certificate Authority (CA) is used (i.e. you need to save the CA's
   2093     cert instead.)  It will work if the certificate is Self-Signed.
   2094 
   2095  Verify All Certs:
   2096 
   2097     If "Verify All Certs" is checked on the main panel, you are always forced
   2098     to check unrecognized server certs, and so the first time you connect to
   2099     a new server you may need to follow a few dialogs to inspect and save the
   2100     server certificate.
   2101 
   2102     Under "Verify All Certs", new certificates are saved in the 'Accepted Certs'
   2103     directory.  When the checkbox is set all host profiles with "CertsDir" set to
   2104     "ACCEPTED_CERTS" (and an empty "ServerCert" setting) will be checked against
   2105     the pool of accepted certificates in the 'Accepted Certs' directory.
   2106 
   2107     Note that we have "Verify All Certs" on by default so that users who do not
   2108     understand the SSL Man-In-The-Middle problem will not be left completely
   2109     vulnerable to it.  Everyone still must make the effort to verify new
   2110     certificates by an external method to be completely safe.
   2111 
   2112     To have "Verify All Certs" toggled off at startup, use "ssvnc -nv" or set
   2113     SSVNC_NO_VERIFY_ALL=1 before starting.  If you do not even want to see the
   2114     button, use "ssvnc -nvb" or SSVNC_NO_VERIFY_ALL_BUTTON=1.
   2115 
   2116     Note: "Fetch Cert" and "Verify All Certs" are currently not implemented in
   2117     "SSH + SSL" mode.  In this case to have server authentication "ServerCert"
   2118     must be set explicitly to a file (or "CertsDir" to a directory).
   2119 
   2120     Also note that "Fetch Cert" only works in a limited fashion in "Listen"
   2121     mode (it is the VNC Server that initiates the connection), and so you
   2122     may need to be set via "ServerCert" as well.
   2123 
   2124     NOTE: See the CA section below for how "Fetch Cert/Verify All Certs"
   2125     WILL NOT WORK when a Certificate Authority (CA) is used (i.e. you need
   2126     to save the CA's cert instead.)  The "Fetch Cert" saving method will
   2127     work if the certificate is Self-Signed.
   2128 
   2129  CA:
   2130 
   2131     One can make SSL VNC server authentication more "automatic" as it is in
   2132     Web Browsers going to HTTPS sites, by using a Certificate Authority (CA)
   2133     cert (e.g. a professional one like Verisign or Thawte, or one your company
   2134     or organization creates) for the "ServerCert".  This is described in detail
   2135     here: http://www.karlrunge.com/x11vnc/ssl.html
   2136 
   2137     CA's are not often used, but if the number of VNC Servers scales up it can
   2138     be very convenient because the viewers (i.e. SSVNC) only need the CA cert,
   2139     not all of the Server certs.
   2140 
   2141     IMPORTANT NOTE: if a VNC Server is using a CA signed certificate instead
   2142     of its own Self-Signed one, then "Fetch Cert", etc. saving mechanism
   2143     WILL NOT WORK.  You must obtain the CA certificate and explicitly set
   2144     it as the ServerCert or import it to 'Accepted Certs'.
   2145 
   2146 
   2147  Now what goes into the panel's entry boxes is described.
   2148 
   2149 
   2150  Your Certificate + Key (MyCert):
   2151 
   2152     You can specify YOUR own SSL certificate (PEM) file in "MyCert" in which
   2153     case it is used to authenticate YOU (the viewer) to the remote VNC Server.
   2154     If this fails the remote VNC Server will drop the connection.
   2155 
   2156     So the Server could use this method to authenticate Viewers instead of the
   2157     more common practice of using a VNC password or x11vnc's -unixpw mode.
   2158 
   2159 
   2160  Server Certificates (ServerCert/CertsDir):
   2161 
   2162     Server certs can be specified in one of two ways:
   2163 
   2164         - A single certificate (PEM) file for a single server
   2165           or a single Certificate Authority (CA)
   2166 
   2167         - A directory of certificate (PEM) files stored in
   2168           the special OpenSSL hash fashion.
   2169 
   2170     The former is set via "ServerCert" in this gui.
   2171     The latter is set via "CertsDir" in this gui.
   2172 
   2173     The former corresponds to the "CAfile" STUNNEL parameter.
   2174     The latter corresponds to the "CApath" STUNNEL parameter.
   2175 
   2176     See stunnel(8) or stunnel.mirt.net for more information.
   2177 
   2178     If the remote VNC Server fails to authenticate itself with respect to the
   2179     specified certificate(s), then the VNC Viewer (your side) will drop the
   2180     connection.
   2181 
   2182     Select which file or directory by clicking on the appropriate "Browse..."
   2183     button.  Once selected, if you click Info or the Right Mouse button on
   2184     "Browse..."  then information about the certificate will be displayed.
   2185 
   2186     If, as is the default, "CertsDir" is set to the token "ACCEPTED_CERTS"
   2187     (and "ServerCert" is unset) then the certificates accumulated in the special
   2188     'Accepted Certs' directory will be used.  "ACCEPTED_CERTS" is the default for
   2189     every server ("Verify All Certs").  Note that if you ever need to clean this
   2190     directory, each cert is saved in two files, for example:
   2191 
   2192           hostname-0=bf-d0-d6-9c-68-5a-fe-24-c6-60-ba-b4-14-e6-66-14.crt
   2193     and
   2194           9eb7c8be.0
   2195 
   2196     This is because of the way OpenSSL must use hash-based filenames in Cert dirs.
   2197     The file will have a "full filename:" line indicating the fingerprint and
   2198     hostname associated with it.  Be sure to remove both files.  The Delete Certs
   2199     dialog should automatically find the matching one for you and prompt you to
   2200     remove it as well.
   2201 
   2202  Certificate Revocation List (CRL File):
   2203 
   2204     For large scale deployments, usually involving a CA Cert, it is worthwhile
   2205     to be able to revoke individual certs (so that a new CA cert does not need to
   2206     be created and new keys distributed).  Set CRL File to the path to the
   2207     file containing the revoked certificates (or a directory containing
   2208     OpenSSL style hash-based filenames.)  See the x11vnc -sslCRL documentation
   2209     for how to create CRL's.  In short, the commands 'openssl ca -revoke ...'
   2210     and 'openssl ca -gencrl ...' are the ones to look for; See the ca(1) manpage.
   2211 
   2212  Create Certificate:
   2213 
   2214     A simple dialog to create a Self-Signed Certificate.  See the x11vnc
   2215     -sslGenCA, -sslGenCert options for creating a CA Cert and signing with it.
   2216 
   2217  Import Certificate:
   2218 
   2219     You can paste in a Certificate or read one in from a file to add to your
   2220     list of Server Certificates.  If (also) saved in the 'Accepted Certs'
   2221     directory, it will be automatically used to verify any Server when in
   2222     'Verify All Certs' Mode.
   2223 
   2224  Deleting Certificates:
   2225 
   2226     To delete a Certificate+private_key pair click on "Delete Certificate"
   2227     and select one in the menu.  You will be prompted to remove it,
   2228     and also any corresponding .pem or .crt file.  For "ACCEPTED_CERTS"
   2229     it will find the matching "HASH" file and prompt you to remove that too.
   2230 
   2231 
   2232  Default Certs and Keys:
   2233 
   2234     Use the "-mycert file" option (same as "-cert file") to set a default
   2235     MyCert.  The user will then have to manually clear the field to not
   2236     use a certificate.  This is the same as "mycert=file" (also "cert=file")
   2237     in the ~/.ssvncrc file.  If "file" does not exist, then ~/.vnc/certs is
   2238     prepended to it.
   2239 
   2240     Use the "-cacert file" option (same as "-ca file") to set a default
   2241     ServerCert.  The user will then have to manually clear the field to not
   2242     set a server cert.  This is the same as "cacert=file" (also "ca=file")
   2243     in the ~/.ssvncrc file.  If "file" does not exist, then ~/.vnc/certs is
   2244     prepended to it.  Use "-cacert CA" to set it to ~/.vnc/certs/CA/cacert.pem
   2245 
   2246     Use the "-crl file" option to set a default CRL File.  The user will
   2247     then have to manually clear the field to not use a CRL.  This is the
   2248     same as "crl=file" in the ~/.ssvncrc file.  If "file" does not exist,
   2249     then ~/.vnc/certs is prepended to it.
   2250 
   2251     A sys-admin might set up an SSVNC deployment for user's workstations or
   2252     laptops using one or more of -cacert (authenticate VNC server to the
   2253     user) or -mycert (authenticate user to VNC server) or -crl (supply a
   2254     list of revoked certificates).  Prefix either one with "FORCE:" to make
   2255     the setting unchangable.
   2256 
   2257 
   2258  Notes:
   2259 
   2260     If "Use SSH" has been selected then SSL certs are disabled.
   2261 
   2262     See the x11vnc and STUNNEL documentation for how to create and use PEM
   2263     certificate files:
   2264 
   2265         http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tunnel-ext
   2266         http://www.karlrunge.com/x11vnc/ssl.html
   2267         http://stunnel.mirt.net
   2268 
   2269     A common way to create and use a VNC Server certificate is:
   2270 
   2271         x11vnc -ssl SAVE ...
   2272 
   2273     and then copy the Server certificate to the local (viewer-side) machine.
   2274     x11vnc prints out to the screen the Server certificate it generates
   2275     (stored in ~/.vnc/certs/server.crt).  You can set "ServerCert" to it
   2276     directly or use the "Import Certificate" action to save it to a file.
   2277     Or use the "Fetch Cert" method to retrieve it (be sure to verify the
   2278     MD5 fingerprint, etc).
   2279 
   2280     x11vnc also has command line utilities to create server, client, and CA
   2281     (Certificate Authority) certificates and sign with it. See the above URLs.
   2282 }
   2283 
   2284 	.ch.f.t insert end $msg
   2285 	jiggle_text .ch.f.t
   2286 }
   2287 
   2288 proc help_ts_opts {} {
   2289 	toplev .oh
   2290 
   2291 	scroll_text_dismiss .oh.f
   2292 
   2293 	center_win .oh
   2294 
   2295 	wm title .oh "Terminal Services VNC Options Help"
   2296 
   2297 set msg {
   2298  Options:  Click on a checkbox to enable a feature and bring up its Dialog.
   2299  Deselecting a checkbox will disable the feature (but settings from the
   2300  Dialog are remembered).  Click on it again to re-enable.
   2301 
   2302 
   2303  Desktop Type:
   2304 
   2305     The default type of remote Desktop type is the "kde" (The K Desktop
   2306     Environment) You can choose a different type: gnome, failsafe,
   2307     twm, etc.
   2308 
   2309     This setting will ONLY be used if the desktop needs to be created.
   2310     If an existing session of yours is found it will be used instead
   2311     (log out of that session if you want to create a new Desktop type
   2312     or see the Multiple Sessions option under Advanced).
   2313 
   2314  Desktop Size:
   2315 
   2316     The default size of remote Desktop type is the "1280x1024" with a
   2317     Color depth of 16 bits per pixel (BPP).  Choose one of the standard
   2318     WxH values or enter a custom one (TBD).
   2319 
   2320     This setting will ONLY be used if the desktop needs to be created.
   2321     If an existing session of yours is found it will be used instead
   2322     (log out of that session if you want to create a new Desktop size
   2323     or see the Multiple Sessions option under Advanced).
   2324 
   2325     Some X servers, Xdummy or a real X server, will allow dynamic screen
   2326     size changing after the session has started via a GUI configuration
   2327     tool (or xrandr(1) from the command line).
   2328 
   2329  X Server Type:
   2330 
   2331     The default type of remote X session is the "Xvfb" (X virtual frame
   2332     buffer) X server.  It is available on most systems.  To choose a
   2333     different type, select "Xdummy", "Xvnc", "Xvnc.redirect".
   2334 
   2335     Xdummy is part of the x11vnc project and is a virtual X server with
   2336     some nice features, but it Linux only and requires root permission
   2337     to run.  One user put 'ALL ALL = NOPASSWD: /usr/local/bin/Xdummy*'
   2338     in his sudo(1) configuration (via visudo).
   2339 
   2340     For Xvnc that server is started up, and x11vnc polls it in its
   2341     normal way.  Use Xvnc.redirect if you want x11vnc to find and/or
   2342     create the Xvnc session, but after that merely transfer packets back
   2343     and forth between VNC viewer and Xvnc (I.e. x11vnc does no polling
   2344     or VNC protocol).
   2345 
   2346 
   2347  Enable Printing:
   2348 
   2349     This sets up a SSH port redirection for you from your remote session
   2350     to your local print server.  The CUPS mechanism is used.  The local
   2351     print server can also be SMB/Windows.
   2352 
   2353  Enable Sound:
   2354 
   2355     Not completely implemented yet.  A partially working ESD method
   2356     is provided.  It may change over to http://nas.sourceforge.net in
   2357     the future.  As with printing, it uses a SSH port redirection to a
   2358     server running locally.
   2359 
   2360  File Transfer:
   2361 
   2362     x11vnc supports both the UltraVNC and TightVNC file transfer
   2363     extensions.  On Windows both viewers support their file transfer
   2364     protocol.  On Unix only the SSVNC VNC Viewer has filexfer support;
   2365     it supports the UltraVNC flavor via a Java helper program.
   2366 
   2367     Choose the one you want based on VNC viewer you will use.
   2368     The defaults for the SSVNC viewer package are TightVNC on Windows
   2369     and UltraVNC on Unix.
   2370 
   2371  View Only:
   2372 
   2373     Start the VNC Viewer in View-Only mode (it may be switched to full
   2374     access later in the session).
   2375 
   2376  Change VNC Viewer:
   2377 
   2378     If you do not like the VNC Viewer bundled in the package, you can
   2379     indicate another one here.
   2380 
   2381  X11 viewer MacOSX:
   2382 
   2383     On MacOSX try to use the bundled X11 vncviewer instead of the
   2384     Chicken of the VNC viewer; the Xquartz X server must be installed
   2385     (it is by default on 10.5.x) and the DISPLAY variable must be set
   2386     (see Tip 15 of SSVNC Help to do this manually.)
   2387 
   2388 
   2389  Advanced Options:
   2390 
   2391  VNC Shared:
   2392 
   2393     Normal use of this program, 'tsvnc', *ALREADY* allows simultaneous
   2394     shared access of the remote desktop:   You simply log in as many
   2395     times from as many different locations with 'tsvnc' as you like.
   2396 
   2397     Select this option for the traditional VNC server shared mode of
   2398     operation using a single x11vnc server.  SSH access is still required.
   2399 
   2400  Multiple Sessions:
   2401 
   2402     To enable one user to have more than one Terminal Services Desktop
   2403     X session on a single machine, this option lets you create Tags for
   2404     multiple ones (e.g. KDE_BIG, TWM_800x600)
   2405 
   2406  X Login Greeter:
   2407 
   2408     If you have root (sudo(1)) permission on the remote machine,
   2409     you can have x11vnc try to connect to X displays that have nobody
   2410     logged in yet.  This is most likely the login greeter running on
   2411     the Physical console.  sudo(1) is used to run x11vnc with FD_XDM=1.
   2412 
   2413     An initial ssh running 'sudo id' is performed to try to 'prime'
   2414     sudo so the 2nd one that starts x11vnc does not need a password.
   2415 
   2416     Note that if someone is already logged into the console of the XDM
   2417     display you will see their X session.
   2418 
   2419  Other VNC Server:
   2420 
   2421     The x11vnc program running on the remote machine can be instructed to
   2422     immediately redirect to some other (3rd party, e.g. Xvnc or vnc.so)
   2423     VNC server.
   2424 
   2425  Use unixpw:
   2426 
   2427     This enables the x11vnc unixpw mode.  A Login: and Password: dialog
   2428     will be presented in the VNC Viewer for the user to provide any Unix
   2429     username and password whose session he wants to connect to.
   2430 
   2431     This mode is useful if a shared terminal services user (e.g. 'tsuser')
   2432     is used for the SSH login part (say via the SSH authorized_keys
   2433     mechanism and all users share the same private SSH key for 'tsuser').
   2434 
   2435     In normal usage the per-user SSH login should be the simplest and
   2436     sufficient, in which case the unixpw option should NOT be selected.
   2437 
   2438  Client 8bit Color:
   2439 
   2440     Have the VNC Viewer request low color mode (8 bits per pixel) for
   2441     slow links.  This may be disabled or further tuned (e.g. 64 color
   2442     mode) in the viewer during the session.
   2443 
   2444  Client-Side Caching:
   2445 
   2446     x11vnc has an experiment Client-Side caching scheme "-ncache n"
   2447     that can give nice speedups.  But there are some drawbacks
   2448     because the cache-region is visible and uses much RAM.
   2449     http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching
   2450 
   2451  X11VNC Options:
   2452 
   2453     If you are familiar with x11vnc, you can specify any of its features
   2454     that you would like enabled.
   2455 
   2456  SSVNC Mode:
   2457 
   2458     Clicking on this button will return you to the full SSVNC Mode.
   2459 
   2460  Unix ssvncviewer:
   2461 
   2462     Clicking on this button will popup a menu for setting options
   2463     of the Unix (and Mac OS X) provided SSVNC vncviewer.
   2464 
   2465 
   2466  ~/.ssvncrc file:
   2467 
   2468     You can put global options in your ~/.ssvncrc file (ssvnc_rc on
   2469     Windows). Currently they are:
   2470 
   2471     Put "mode=tsvnc" or "mode=sshvnc" in the ~/.ssvncrc file to have
   2472     the application start up in the given mode.
   2473 
   2474     desktop_type=wmaker  (e.g.) to switch the default Desktop Type.
   2475 
   2476     desktop_size=1280x1024  (e.g.) to switch the default Desktop Size.
   2477 
   2478     desktop_depth=24  (e.g.) to switch the default Desktop Color Depth.
   2479 
   2480     xserver_type=Xdummy  (e.g.) to switch the default X Server Type.
   2481 
   2482     (The above 4 settings apply only to the Terminal Services Mode.)
   2483 
   2484     noenc=1  (same as the -noenc option for a 'No Encryption' option)
   2485     noenc=0  (do not show the 'No Encryption' option)
   2486 
   2487     font_default=tk-font-name     (sets the font for menus and buttons)
   2488     font_fixed=tk-font-name       (sets the font for help text)
   2489 }
   2490 	.oh.f.t insert end $msg
   2491 	jiggle_text .oh.f.t
   2492 }
   2493 
   2494 proc help_opts {} {
   2495 	toplev .oh
   2496 
   2497 	scroll_text_dismiss .oh.f
   2498 
   2499 	center_win .oh
   2500 
   2501 	wm title .oh "SSL/SSH Viewer Options Help"
   2502 
   2503 set msg {
   2504   Use SSL:  The default, use SSL via STUNNEL (this requires SSL aware VNC
   2505             server, e.g. x11vnc -ssl SAVE ...)  See the description in the
   2506             main Help panel.
   2507 
   2508   Use SSH:  Instead of using STUNNEL SSL, use ssh(1) for the encrypted
   2509             tunnel.  You must be able to log in via ssh to the remote host.
   2510 
   2511             On Unix the cmdline ssh(1) program (it must already be installed)
   2512             will be run in an xterm for passphrase authentication, prompts
   2513             about RSA keys, etc.  On Windows the cmdline plink.exe program
   2514             will be launched in a Windows Console window. (Apologies for
   2515             the klunkiness..)
   2516 
   2517             You can set the "VNC Host:Display" to "user@host:disp" to
   2518             indicate ssh should log in as "user" on "host".  NOTE: On
   2519             Windows you *MUST* always supply the "user@" part (due to a
   2520             plink deficiency). E.g.:
   2521 
   2522                 VNC Host:Display:    fred@far-away.east:0
   2523 
   2524 
   2525             Gateway:  If an intermediate gateway machine must be used
   2526             (e.g. to enter a firewall; the VNC Server is not running on it),
   2527             put it in the Proxy/Gateway entry, e.g.:
   2528 
   2529                 VNC Host:Display:    workstation:0
   2530                 Proxy/Gateway:       user@gateway-host:port
   2531 
   2532             ssh is used to login to user@gateway-host and then a -L port
   2533             redirection is set up to go to workstation:0 from gateway-host.
   2534             ":port" is optional, use it if the gateway-host SSH port is
   2535             not the default value 22.
   2536 
   2537             Chaining 2 ssh's:  One can also do a "double ssh", i.e. a
   2538             first SSH to the gateway login machine then a 2nd ssh to the
   2539             destination machine (presumably it is running the vnc server).
   2540 
   2541             Unlike the above example, the "last leg" (gateway-host ->
   2542             workstation) is also encrypted by SSH this way.  Do this by
   2543             splitting the gateway in two with a comma, the part before it
   2544             is the first SSH:
   2545 
   2546                 VNC Host:Display: localhost:0
   2547                 Proxy/Gateway:    user@gateway-host:port,user@workstation:port
   2548 
   2549             Web and SOCKS proxies can also be used with SSH:
   2550 
   2551                 VNC Host:Display: user@workstation:0
   2552                 Proxy/Gateway:    socks://socks.server:1080
   2553 
   2554             See the "SSH Proxies/Gateways" in the Main Help document for full
   2555             details.
   2556 
   2557 
   2558             Remote Command:  In the "Remote SSH Command" entry you can to
   2559             indicate that a remote command to be run.  The default is
   2560             "sleep 15" to make sure port redirections get established. But you
   2561             can run anything else, for example, to run x11vnc on your X :0
   2562             workstation display:
   2563 
   2564                 x11vnc -display :0 -nopw
   2565 
   2566 
   2567             Windows SSH SERVER: if you are ssh'ing INTO Windows (e.g. CYGWIN
   2568             SSHD server) there may be no "sleep" command so put in something
   2569             like "ping localhost" or "ping -n 10 -w 1000 localhost" to
   2570             set a short delay to let the port redir get established.
   2571 
   2572 
   2573             Trick:  If you use "SHELL" asl the "Remote SSH Command" then
   2574             you get an SSH shell only: no VNC viewer will be launched.
   2575             On Windows "PUTTY" will try to use putty.exe (better terminal
   2576             emulation than plink.exe)  A shortcut for this is Ctrl-S as
   2577             long as user@hostname is present in the "VNC Host:Display" box.
   2578 
   2579 
   2580   Use SSH + SSL:
   2581 
   2582             Tunnel the SSL connection through a SSH tunnel.  Use this
   2583             if you want end-to-end SSL and must use a SSH gateway (e.g. to
   2584             enter a firewall) or if additional SSH port redirs are required
   2585             (CUPS, Sound, SMB tunnelling: See Advanced Options).
   2586 
   2587             This is a RARELY used mode, but included in case the need arises.
   2588 
   2589 
   2590   No Encryption:
   2591 
   2592             In '-noenc' mode, which is now the default, (Ctrl-E also toggles
   2593             this mode), use this to make a Direct connection to the VNC Server
   2594             with no encryption whatsoever.  (Be careful about passwords, etc.)
   2595 
   2596             The -noenc mode is now the default since SSVNC 1.0.25, use
   2597             the '-enc' cmdline option to disable the button.
   2598 
   2599 
   2600   Automatically Find X Session:
   2601 
   2602             When using SSH mode to connect, you can select this option.  It
   2603             simply sets the Remote SSH Command to:
   2604 
   2605                  PORT= x11vnc -find -localhost
   2606 
   2607             This requires that x11vnc is installed on the remote computer
   2608             and is available in $PATH for the ssh login.  The command
   2609             "x11vnc -find -localhost" command is run on the remote
   2610             machine.
   2611 
   2612             The -find option causes x11vnc to try to find an existing X
   2613             session owned by the user (i.e. who you ssh in as).  If it
   2614             does it attaches to it; otherwise the x11vnc VNC server exits
   2615             immediately followed by your VNC Viewer.
   2616 
   2617             The PORT= option just means to let x11vnc pick its own
   2618             VNC port and then connect to whatever it picked.  Use P=
   2619             for more debugging output.
   2620 
   2621             The idea for this mode is you simply type 'username@workstation'
   2622             in the VNC Host:Display box, Select 'Options -> Automatically
   2623             Find X Session', and then click Connect.  The tsvnc mode is
   2624             similar (it runs x11vnc on the remote side with the intent
   2625             of automatically finding, or creating, your desktop).
   2626 
   2627 
   2628   Unix Username & Password:
   2629 
   2630             This is only available on Unix and MacOSX and when using
   2631             the SSVNC enhanced TightVNC viewer (it has been modified to
   2632             do Unix logins).  It supports a login dialog with servers
   2633             doing something like x11vnc's "-unixpw" mode.  After any
   2634             regular VNC authentication takes place (VNC Password), then
   2635             it sends the Unix Username, a Return, the Unix Password and
   2636             a final Return.  This saves you from typing them into the
   2637             "login:" and "Password:" prompts in the viewer window.
   2638 
   2639             Note that the x11vnc -unixpw login mode is external to the
   2640             VNC protocol, so you need to be sure the VNC server is in
   2641             this mode and will be waiting for the dialog.  Otherwise the
   2642             username and password will be typed directly into the desktop
   2643             application that happens to have the focus!
   2644 
   2645             When you select this option "Unix Username:" and "Unix
   2646             Password:" entry boxes appear on the main panel where you can
   2647             type them in.  x11vnc has settings that can be specified after
   2648             a ":" in the Unix username; they may be used here as well.
   2649             (For example: username:3/4,nc for a smaller screen and -nocache)
   2650 
   2651             If the Unix Username is not set when you click Connect, then
   2652             any SSH username@host is used.  Otherwise the environment
   2653             variable $USER or $LOGNAME and finally whoami(1) is used.
   2654 
   2655             Also Note that the Unix Password is never saved in a VNC
   2656             profile (so you have to type it each time).  Also, the remote
   2657             x11vnc server is instructed to not echo the Username string
   2658             by sending an initial Escape.  Set the SSVNC_UNIXPW_NOESC=1
   2659             environment variable to override this.
   2660 
   2661   Reverse VNC Connection:
   2662 
   2663             Reverse (listening) VNC connections are possible as well.
   2664             Enable with this button "Reverse VNC Connection (-LISTEN)"
   2665 
   2666             In this case the VNC Server initiates the connection to your
   2667             waiting (i.e. listening) SSVNC viewer.
   2668 
   2669             For SSL connections in the 'VNC Host:Display' entry box put in
   2670             the number (e.g. "0" or ":0" or ":1", etc.) that corresponds to
   2671             the Listening display (0 -> port 5500, 1 -> port 5501, etc.) you
   2672             want to use.  For example x11vnc can then be used via:
   2673             "x11vnc ... -ssl SAVE -connect hostname:port" using the "port"
   2674             with the one you chose.
   2675 
   2676             Clicking on the 'Listen' button puts your SSVNC viewer
   2677             in a "listening" state on that port number, waiting for a
   2678             connection from the VNC Server.
   2679 
   2680             Then a VNC server should establish a reverse connection to
   2681             that port on this machine (e.g. -connect this-machine:5500
   2682             or -connect this-machine:5503, etc.)
   2683 
   2684             Server SSL certificates will be verified, however you WILL
   2685             NOT be prompted about unrecognized ones; rather, you MUST
   2686             set up the correct Server certificate (e.g. by importing).
   2687             prior to any connections.
   2688 
   2689             If the connection is failing in Reverse VNC (listening) mode,
   2690             check the STUNNEL log output to see if STUNNEL is unable to
   2691             authenticate the VNC Server.  If you want to allow in a
   2692             reverse connection with NO Server authentication, unset the
   2693             'Verify All Certs' option.
   2694 
   2695             When listening in SSL, you will ALSO need to specify YOUR
   2696             OWN SSL cert, "MyCert", or otherwise let the GUI prompt you
   2697             to create a "listen.pem" and use that.
   2698 
   2699             The "listen.pem" will be reused in later SSL Listening
   2700             connections unless you specify a different one with MyCert.
   2701 
   2702             On Windows or using a 3rd party VNC Viewer multiple,
   2703             simultaneous reverse connections are always enabled.
   2704             On Unix/MacOSX with the provided ssvncviewer they are disabled
   2705             by default.  To enable them:
   2706             Options -> Advanced -> Unix ssvncviewer -> Multiple LISTEN Conns.
   2707 
   2708             For reverse connections in SSH or SSH + SSL modes it is a
   2709             little trickier.  The SSH tunnel (with -R tunnel) must be
   2710             established and remain up waiting for reverse connections.
   2711             The default time is "sleep 1800", i.e. 30 mins.  You can put
   2712             a longer or shorter sleep in "Remote SSH Command" (perhaps
   2713             after your command runs:  cmd; sleep 3600).
   2714 
   2715             For SSH reverse connections put "hostname:n" in
   2716             'VNC Host:Display' or "user@hostname:n".  The "n" will be the
   2717             listening display on the *REMOTE* side.  So to have the remote
   2718             x11vnc connect use: "x11vnc ... -connect localhost:n" or
   2719             "x11vnc -R connect:localhost:n" (-ssl will be needed for SSH+SSL
   2720             mode).  If the -R port cannot be opened because it is in use
   2721             by another program you will have to kill everything and start
   2722             over using a different port.
   2723 
   2724             In reverse connections mode be careful to protect the listening
   2725             VNC Viewer from direct connections (neither SSL nor SSH)
   2726             connecting directly to its listening port thereby bypassing
   2727             the tunnel.  This can be done by a host-level firewall that
   2728             only lets in, say, port 5500 (the default one ":0" for stunnel
   2729             to listen on).  Or for SSH reverse connections allow NO 5500+n
   2730             ports in.  For reverse connections, the Unix enhanced tightvnc
   2731             viewers supplied in the SSVNC package will only listen on
   2732             localhost so these precautions are not needed.
   2733 
   2734             Specify a specific interface, e.g. 192.168.1.1:0 to have stunnel
   2735             only listen on that interface.  IPv6 works too, e.g. :::0 or ::1:0
   2736             Also works for UN-encrypted reverse connections as well ('None').
   2737 
   2738             Note that for SSL connections use of "Proxy/Gateway" does not
   2739             make sense: the remote side cannot initiate its reverse connection
   2740             via the Proxy.
   2741 
   2742             Note that for SSH or SSH+SSL connections use of "Proxy/Gateway"
   2743             does not make sense (the ssh cannot do a -R on a remote host:port),
   2744             unless it is a double proxy where the 2nd host is the machine with
   2745             the VNC server.
   2746 
   2747 
   2748   View Only:               Have VNC Viewer ignore mouse and keyboard input.
   2749 
   2750   Fullscreen:              Start the VNC Viewer in fullscreen mode.
   2751 
   2752   Raise On Beep:           Deiconify viewer when bell rings.
   2753 
   2754   Use 8bit color:          Request a very low-color pixel format.
   2755 
   2756   Do not use JPEG:         Do not use the jpeg aspect of the tight encoding.
   2757 
   2758   Use X11 vncviewer on MacOSX:
   2759                            On MacOSX try to use the bundled X11 vncviewer
   2760                            instead of the Chicken of the VNC viewer;
   2761                            The Xquartz X server must be installed (it is by
   2762                            default on 10.5.x) and the DISPLAY variable must
   2763                            be set (see Tip 15 of Help to do this manually.)
   2764                            Put cotvnc=1 in ~/.ssvncrc to switch the default.
   2765 
   2766   Kill Stunnel Automatically:
   2767                            On Windows, automatically try to kill the STUNNEL
   2768                            process when the VNC Viewer exits.  This is a
   2769                            global setting (not per-profile); it can be also
   2770                            set via either the -killstunnel cmdline option,
   2771                            or killstunnel=1 in ssvnc_rc.  To disable it supply
   2772                            -nokillstunnel or put killstunnel=0 in ssvnc_rc.
   2773                            As of 1/2009 this option is on by default.
   2774 
   2775                            The main drawback to having STUNNEL automatically
   2776                            killed is that you will not be able to view its
   2777                            logfile.  If you are having trouble connecting via
   2778                            SSL, disable this option and double click on the
   2779                            dark green STUNNEL icon in the tray to view the log.
   2780 
   2781 
   2782   Compress Level/Quality:  Set TightVNC encoding parameters.
   2783 
   2784 
   2785   Putty PW:  On Windows only: use the supplied password for plink SSH
   2786              logins.  Unlike the other options the value is not saved
   2787              when 'Save' is performed.  This feature is useful when
   2788              options under "Advanced" are set that require TWO SSH's:
   2789              you just have to type the password once in this entry box.
   2790              The bundled pageant.exe and puttygen.exe programs can also
   2791              be used to avoid repeatedly entering passwords (note this
   2792              requires setting up and distributing SSH keys).  Start up
   2793              pageant.exe or puttygen.exe and read the instructions there.
   2794 
   2795              Note, that there is a small exposure to someone seeing the
   2796              putty password on the plink command line.
   2797 
   2798              Note that the Putty PW is not cleared if you load in a
   2799              new VNC profile.
   2800 
   2801 
   2802   Port Slot: On Windows ports cannot be selected or checked as easily as
   2803              on Unix.  So listening ports for ssh redirs, proxy tunnelling,
   2804              and etc. things are picked via finding a free "slot".
   2805              The slots run from 30 to 99 and are locked based on the
   2806              existence of a file with the slot number in it.  When the
   2807              connection is about to be made, a free slot is found and used
   2808              to work out some ports (e.g. 5930 for the local VNC port,
   2809              etc.)  This way simultaneous SSVNC connections can take place.
   2810 
   2811              One drawback of this is that Putty/Plink stores SSH keys based
   2812              on hostname:port, and with a proxy tunnel the hostname is
   2813              "localhost".  So the Putty key store may have key collisions
   2814              for the localhost tunnels, and plink will prompt you to
   2815              resolve the conflict WRT a different SSH key being discovered.
   2816 
   2817              To work around this to some degree you can select a unique
   2818              Port Slot (in the range 50-99) for a specific host.  Then the
   2819              ssh redir port to this host will never change and so the
   2820              Putty localhost:fixed-port key should remain valid.
   2821 
   2822 
   2823   Mode:      To change the GUI Mode, select between the full SSVNC
   2824              (i.e. SSL and SSH), SSHVNC (i.e. SSH-Only), and Terminal
   2825              Services mode (TSVNC; uses x11vnc)
   2826 
   2827              Note: You can put "mode=tsvnc" or "mode=sshvnc" in your
   2828              ~/.ssvncrc file (ssvnc_rc on Windows) to have the application
   2829              start up in the given mode.
   2830 
   2831 
   2832   Show 'No Encryption' Option:
   2833 
   2834              Note: since SSVNC 1.0.25 the 'No Encryption' Option is
   2835              enabled by default.
   2836 
   2837              Select this to display a button that disables both SSL and
   2838              SSH encryption.  This is the same as Ctrl+E.  This puts
   2839              a check item "None" on the main panel and also a "No
   2840              Encryption" check item in the "Options" panel.  If you
   2841              select this item, there will be NO encryption for the VNC
   2842              connection (use cautiously) See Tip 5) under Help for more
   2843              information about disabling encryption.
   2844 
   2845 
   2846   Buttons:
   2847 
   2848   Use Defaults:    Set all options to their defaults (i.e. unset).
   2849 
   2850   Delete Profile:  Delete a saved profile.
   2851 
   2852   Advanced:        Bring up the Advanced Options dialog.
   2853 
   2854   Save and Load:
   2855 
   2856              You can Save the current settings by clicking on Save
   2857              (.vnc file) and you can also read in a saved one with Load
   2858              Profile.  Use the Browse... button to select the filename
   2859              via the GUI.
   2860 
   2861              Pressing Ctrl-L or Clicking the Right mouse button on the
   2862              main GUI will invoke the Load dialog.
   2863 
   2864              Note: On Windows since the TightVNC Viewer will save its own
   2865              settings in the Registry, some unexpected behavior is possible
   2866              because the viewer is nearly always directed to the VNC host
   2867              "localhost:30".  E.g. if you specify "View Only" in this gui
   2868              once but not next time the Windows VNC Viewer may remember
   2869              the setting.  Unfortunately there is not a /noreg option for
   2870              the Viewer.
   2871 }
   2872 	.oh.f.t insert end $msg
   2873 	jiggle_text .oh.f.t
   2874 }
   2875 
   2876 proc help_fetch_cert {{selfsigned 1}} {
   2877 	toplev .fh
   2878 
   2879 	set h 35
   2880 	if [small_height] {
   2881 		set h 28
   2882 	}
   2883 	scroll_text_dismiss .fh.f 85 $h
   2884 
   2885 	center_win .fh
   2886 	wm resizable .fh 1 0
   2887 
   2888 	wm title .fh "Fetch Certificates Help"
   2889 
   2890 	set msg {
   2891   The displayed SSL Certificate has been retrieved from the VNC Server via the
   2892   "Fetch Cert" action.
   2893 
   2894   It has merely been downloaded via the SSL Protocol:
   2895 
   2896          *** IT HAS NOT BEEN VERIFIED OR AUTHENTICATED IN ANY WAY ***
   2897 
   2898   So, in principle, it could be a fake certificate being inserted by a bad
   2899   person attempting to perform a Man-In-The-Middle attack on your SSL connection.
   2900 
   2901   If, however, by some external means you can verify the authenticity of this SSL
   2902   Certificate you can use it for your VNC SSL connection to the VNC server you
   2903   wish to connect to.  It will provide an authenticated and encrypted connection.
   2904 
   2905   You can verify the SSL Certificate by comparing the MD5 or SHA1 hash value
   2906   via a method/channel you know is safe (i.e. not also under control of a
   2907   Man-In-The-Middle attacker).  You could also check the text between the
   2908   -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- tags, etc.
   2909 
   2910   Once you are sure it is correct, you can press the Save button to save the
   2911   certificate to a file on the local machine for use when you connect via VNC
   2912   tunneled through SSL.  If you save it, then that file will be set as the
   2913   Certificate to verify the VNC server against.  You can see this in the dialog
   2914   started via the "Certs..." button on the main panel.
   2915 
   2916   NOTE: If you want to make Permanent the association of the saved SSL certificate
   2917   file with the VNC server host, you MUST save the setting as a profile for
   2918   loading later. To Save a Profile, click on Options -> Save Profile ...,
   2919   and choose a name for the profile and then click on Save.
   2920 
   2921   If "Verify All Certs" is checked, then you are forced to check all new certs.
   2922   In this case the certs are saved in the 'Accepted Certs' directory against
   2923   which all servers will be checked unless "ServerCert" or "CertsDir" has been
   2924   set to something else.
   2925 
   2926   To reload the profile at a later time, click on the "Load" button on the
   2927   main panel and then select the name and click "Open".  If you want to be
   2928   sure the certificate is still associated with the loaded in host, click on
   2929   "Certs..." button and make sure the "ServerCert" points to the desired SSL
   2930   filename.
   2931 
   2932   See the Certs... Help for more information.  A sophisticated method can be set
   2933   up using a Certificate Authority key to verify never before seen certificates
   2934   (i.e. like your web browser does).
   2935 }
   2936 
   2937 	set msg2 {
   2938   --------------------------------------------------------------------------
   2939   NOTE: The certificate that was just downloaded IS NOT a Self-Signed
   2940   certificate.  It was signed by a Certificate Authority (CA) instead.
   2941   So saving it does not make sense because it cannot be used to authenticate
   2942   anything.
   2943 
   2944   You need to Obtain and Save the CA's certificate instead.
   2945 
   2946   The remainder of this Help description applies ONLY to Self-Signed
   2947   certificates (i.e. NOT the most recently downloaded one.)
   2948   --------------------------------------------------------------------------
   2949 
   2950 
   2951 }
   2952 
   2953 	if {!$selfsigned} {
   2954 		regsub {  If, however,} $msg "$msg2  If, however," msg
   2955 	}
   2956 
   2957 	.fh.f.t insert end $msg
   2958 	jiggle_text .fh.f.t
   2959 }
   2960 
   2961 proc win_nokill_msg {} {
   2962 	global help_font is_windows system_button_face
   2963 	toplev .w
   2964 
   2965 	eval text .w.t -width 60 -height 11 $help_font
   2966 	button .w.d -text "Dismiss" -command {destroy .w}
   2967 	pack .w.t .w.d -side top -fill x
   2968 
   2969 	apply_bg .w.t
   2970 
   2971 	center_win .w
   2972 	wm resizable .w 1 0
   2973 
   2974 	wm title .w "SSL/SSH Viewer: Warning"
   2975 
   2976 	set msg {
   2977     The VNC Viewer has exited.
   2978 
   2979     You will need to terminate STUNNEL manually.
   2980 
   2981     To do this go to the System Tray and right-click on the STUNNEL
   2982     icon (dark green).  Then click "Exit".
   2983 
   2984     You can also double click on the STUNNEL icon to view the log
   2985     for error messages and other information.
   2986 }
   2987 	.w.t insert end $msg
   2988 }
   2989 
   2990 proc win_kill_msg {pids} {
   2991 	global terminate_pids
   2992 	global help_font
   2993 
   2994 	toplev .w
   2995 
   2996 	eval text .w.t -width 72 -height 21 $help_font
   2997 	button .w.d -text "Dismiss" -command {destroy .w; set terminate_pids no}
   2998 	button .w.k -text "Terminate STUNNEL" -command {destroy .w; set terminate_pids yes}
   2999 	pack .w.t .w.k .w.d -side top -fill x
   3000 
   3001 	apply_bg .w.t
   3002 
   3003 	center_win .w
   3004 	wm resizable .w 1 0
   3005 
   3006 	wm title .w "SSL/SSH Viewer: Warning"
   3007 
   3008 	set msg {
   3009     The VNC Viewer has exited.
   3010 
   3011     We can terminate the following still running STUNNEL process(es):
   3012 
   3013 }
   3014 	append msg "         $pids\n"
   3015 
   3016 	append msg {
   3017     Click on the "Terminate STUNNEL" button below to do so.
   3018 
   3019     Before terminating STUNNEL you can double click on the STUNNEL
   3020     Tray icon to view its log for error messages and other information.
   3021 
   3022     Note: You may STILL need to terminate STUNNEL manually if we are
   3023     unable to kill it.  To do this go to the System Tray and right-click
   3024     on the STUNNEL icon (dark green).  Then click "Exit".  You will
   3025     probably also need to hover the mouse over the STUNNEL Tray Icon to
   3026     make the Tray notice STUNNEL is gone...
   3027 
   3028     To have STUNNEL automatically killed when the Viewer exits use the
   3029     -killstunnel cmdline option, or set it under Options or in ssvnc_rc.
   3030 }
   3031 	.w.t insert end $msg
   3032 }
   3033 
   3034 proc win9x_plink_msg {file} {
   3035 	global help_font win9x_plink_msg_done
   3036 	toplev .pl
   3037 
   3038 	eval text .pl.t -width 90 -height 26 $help_font
   3039 	button .pl.d -text "OK" -command {destroy .pl; set win9x_plink_msg_done 1}
   3040 	wm protocol .pl WM_DELETE_WINDOW {catch {destroy .pl}; set win9x_plink_msg_done 1}
   3041 	pack .pl.t .pl.d -side top -fill x
   3042 
   3043 	apply_bg .pl.t
   3044 
   3045 	center_win .pl
   3046 	wm resizable .pl 1 0
   3047 
   3048 	wm title .pl "SSL/SSH Viewer: Win9x Warning"
   3049 
   3050 	set msg {
   3051     Due to limitations on Window 9x you will have to manually start up
   3052     a COMMAND.COM terminal and paste in the following command:
   3053 
   3054 }
   3055 	set pwd [pwd]
   3056 	regsub -all {/} $pwd "\\" pwd
   3057 	append msg "        $pwd\\$file\n"
   3058 
   3059 	append msg {
   3060     The reason for this is a poor Console application implementation that
   3061     affects many text based applications.
   3062 
   3063     To start up a COMMAND.COM terminal, click on the Start -> Run, and then
   3064     type COMMAND in the entry box and hit Return or click OK.
   3065 
   3066     To select the above command, highlight it with the mouse and then press
   3067     Ctrl-C.  Then go over to the COMMAND.COM window and click on the
   3068     Clipboard paste button.  Once pasted in, press Return to run the script.
   3069 
   3070     This will start up a PLINK.EXE ssh login to the remote computer,
   3071     and after you log in successfully and indicate (QUICKLY!!) that the
   3072     connection is OK by clicking OK in this dialog. If the SSH connection
   3073     cannot be autodetected you will ALSO need to click "Success" in the
   3074     "plink ssh status?" dialog, the VNC Viewer will be started going
   3075     through the SSH tunnel.
   3076 }
   3077 	.pl.t insert end $msg
   3078 	wm deiconify .pl
   3079 }
   3080 
   3081 proc mesg {str} {
   3082 	set maxx 60
   3083 	if [regexp {^INFO: without Certificate} $str] {
   3084 		set maxx 72
   3085 	}
   3086 	if {[string length $str] > $maxx} {
   3087 		set lend [expr $maxx - 1]
   3088 		set str [string range $str 0 $lend]
   3089 		append str " ..."
   3090 	}
   3091 	.l configure -text $str
   3092 	update
   3093 	global env
   3094 	if [info exists env(SSVNC_MESG_DELAY)] {
   3095 		after $env(SSVNC_MESG_DELAY)
   3096 	}
   3097 }
   3098 
   3099 proc get_ssh_hp {str} {
   3100 	regsub {cmd=.*$} $str "" str
   3101 	set str [string trim $str]
   3102 	regsub {[ 	].*$} $str "" str
   3103 	return $str
   3104 }
   3105 
   3106 proc get_ssh_cmd {str} {
   3107 	set str [string trim $str]
   3108 	global ts_only
   3109 	if {$ts_only} {
   3110 		return [ts_x11vnc_cmd]
   3111 	}
   3112 	if [regexp {cmd=(.*$)} $str m cmd] {
   3113 		set cmd [string trim $cmd]
   3114 		regsub -nocase {^%x11vncr$} $cmd "x11vnc -nopw -display none -rawfb rand" cmd
   3115 		regsub -nocase {^%x11vnc$}  $cmd "x11vnc -nopw -display none -rawfb null" cmd
   3116 		return $cmd
   3117 	} else {
   3118 		return ""
   3119 	}
   3120 }
   3121 
   3122 proc get_ssh_proxy {str} {
   3123 	set str [string trim $str]
   3124 	regsub {cmd=.*$} $str "" str
   3125 	set str [string trim $str]
   3126 	if { ![regexp {[ 	]} $str]} {
   3127 		return ""
   3128 	}
   3129 	regsub {^.*[ 	][ 	]*} $str "" str
   3130 	return $str
   3131 }
   3132 
   3133 proc ts_x11vnc_cmd {} {
   3134 	global is_windows
   3135 	global ts_xserver_type choose_xserver ts_desktop_type choose_desktop ts_unixpw ts_vncshared
   3136 	global ts_desktop_size ts_desktop_depth choose_desktop_geom
   3137 	global choose_filexfer ts_filexfer
   3138 	global ts_x11vnc_opts  ts_x11vnc_path ts_x11vnc_autoport choose_x11vnc_opts
   3139 	global ts_othervnc choose_othervnc ts_xlogin
   3140 	global choose_sleep extra_sleep
   3141 
   3142 	set cmd ""
   3143 	if {$choose_x11vnc_opts && $ts_x11vnc_path != ""} {
   3144 		set cmd $ts_x11vnc_path
   3145 	} else {
   3146 		set cmd "x11vnc"
   3147 	}
   3148 	if {! $is_windows} {
   3149 		set cmd "PORT= $cmd"
   3150 	} else {
   3151 		set cmd "PORT= $cmd"
   3152 	}
   3153 
   3154 	set type $ts_xserver_type;
   3155 	if {! $choose_xserver} {
   3156 		set type ""
   3157 	}
   3158 	if {$choose_othervnc && $ts_othervnc == "find"} {
   3159 		set type "Xvnc.redirect"
   3160 	}
   3161 
   3162 	if [info exists choose_sleep] {
   3163 		if {! $choose_sleep} {
   3164 			set extra_sleep ""
   3165 		}
   3166 	}
   3167 
   3168 	if {$choose_othervnc && $ts_othervnc != "find"} {
   3169 		set cmd "$cmd -redirect $ts_othervnc"
   3170 	} elseif {$type == ""} {
   3171 		global ts_xserver_type_def
   3172 		if {$ts_xserver_type_def != ""} {
   3173 			set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-$ts_xserver_type_def";
   3174 		} else {
   3175 			set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-Xvfb";
   3176 		}
   3177 	} elseif {$type == "Xvfb"} {
   3178 		set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-Xvfb";
   3179 	} elseif {$type == "Xdummy"} {
   3180 		set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-Xdummy";
   3181 	} elseif {$type == "Xvnc"} {
   3182 		set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-Xvnc";
   3183 	} elseif {$type == "Xvnc.redirect"} {
   3184 		set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-Xvnc.redirect";
   3185 	}
   3186 
   3187 	# TBD: Cups + sound
   3188 
   3189 	set cmd "$cmd -localhost";
   3190 	set cmd "$cmd -nopw";
   3191 	global ts_ncache choose_ncache
   3192 	if {$choose_ncache && [regexp {^[0-9][0-9]*$} $ts_ncache]} {
   3193 		set cmd "$cmd -ncache $ts_ncache";
   3194 	} else {
   3195 		#set cmd "$cmd -nonc";
   3196 	}
   3197 	set cmd "$cmd -timeout 120";
   3198 	global ts_multisession choose_multisession
   3199 	regsub -all {[^A-z0-9_-]} $ts_multisession "" ts_multisession
   3200 	if {$choose_multisession && $ts_multisession != ""} {
   3201 		set cmd "$cmd -env FD_TAG='$ts_multisession'";
   3202 	}
   3203 	if {$choose_filexfer && $ts_filexfer != ""} {
   3204 		if {$ts_filexfer == "tight"} {
   3205 			set cmd "$cmd -tightfilexfer";
   3206 		} else {
   3207 			set cmd "$cmd -ultrafilexfer";
   3208 		}
   3209 	}
   3210 	if {$ts_unixpw} {
   3211 		set cmd "$cmd -unixpw";
   3212 	}
   3213 	if {$ts_vncshared} {
   3214 		set cmd "$cmd -shared";
   3215 	}
   3216 	set u "unknown"
   3217 	global env
   3218 	if {[info exists env(USER)]} {
   3219 		regsub -all {[^A-z]} $env(USER) "_" u
   3220 	}
   3221 	set cmd "$cmd -o \$HOME/.tsvnc.log.$u";	# XXX perms
   3222 
   3223 	set sess "kde"
   3224 	global ts_desktop_type_def
   3225 	if {$ts_desktop_type_def != ""} {
   3226 		set sess $ts_desktop_type_def
   3227 	}
   3228 	if {$choose_desktop && $ts_desktop_type != ""} {
   3229 		set sess $ts_desktop_type
   3230 	}
   3231 	set cmd "$cmd -env FD_SESS=$sess";
   3232 
   3233 	if {$choose_desktop_geom} {
   3234 		set geom "1280x1024"
   3235 		set dep 16
   3236 		global ts_desktop_size_def ts_desktop_depth_def
   3237 		if {$ts_desktop_size_def != ""} {
   3238 			set geom $ts_desktop_size_def
   3239 		}
   3240 		if {$ts_desktop_depth_def != ""} {
   3241 			set dep $ts_desktop_depth_def
   3242 		}
   3243 		if {$ts_desktop_size != ""} {
   3244 			if [regexp {^[0-9][0-9]*x[0-9][0-9]*$} $ts_desktop_size] {
   3245 				set geom $ts_desktop_size
   3246 			}
   3247 			if {$ts_desktop_depth != ""} {
   3248 				set geom "${geom}x$ts_desktop_depth"
   3249 			} else {
   3250 				set geom "${geom}x$dep"
   3251 			}
   3252 		} else {
   3253 			set geom "${geom}x$dep"
   3254 		}
   3255 		set cmd "$cmd -env FD_GEOM=$geom";
   3256 	}
   3257 	if {$is_windows} {
   3258 		;
   3259 	} elseif {$choose_x11vnc_opts && $ts_x11vnc_autoport != "" && [regexp {^[0-9][0-9]*$} $ts_x11vnc_autoport]} {
   3260 		set cmd "$cmd -autoport $ts_x11vnc_autoport";
   3261 	} else {
   3262 		set cmd "$cmd -env AUTO_PORT=5950";
   3263 	}
   3264 	if {$choose_x11vnc_opts && $ts_x11vnc_opts != ""} {
   3265 		set cmd "$cmd $ts_x11vnc_opts";
   3266 	}
   3267 	if {$ts_xlogin} {
   3268 		regsub {PORT= } $cmd "PORT= sudo " cmd
   3269 		regsub {P= } $cmd "P= sudo " cmd
   3270 		regsub { -o [^ ][^ ]*} $cmd "" cmd
   3271 
   3272 		set cmd "$cmd -env FD_XDM=1";
   3273 	}
   3274 
   3275 	return $cmd
   3276 }
   3277 
   3278 proc set_defaults {} {
   3279 	global defs env
   3280 
   3281 	global mycert svcert crtdir crlfil
   3282 	global use_alpha use_turbovnc disable_pipeline use_grab use_ssl use_ssh use_sshssl use_viewonly use_fullscreen use_bgr233
   3283 	global use_send_clipboard use_send_always
   3284 	global disable_all_encryption
   3285 	global use_nojpeg use_raise_on_beep use_compresslevel use_quality use_x11_macosx
   3286 	global compresslevel_text quality_text
   3287 	global use_cups use_sound use_smbmnt
   3288 	global cups_local_server cups_remote_port cups_manage_rcfile ts_cups_manage_rcfile cups_x11vnc
   3289 	global cups_local_smb_server cups_remote_smb_port
   3290 	global change_vncviewer change_vncviewer_path vncviewer_realvnc4
   3291 	global choose_xserver ts_xserver_type choose_desktop ts_desktop_type ts_unixpw ts_vncshared
   3292 	global choose_filexfer ts_filexfer
   3293 	global ts_x11vnc_opts choose_x11vnc_opts ts_x11vnc_path ts_x11vnc_autoport ts_xlogin
   3294 	global ts_othervnc choose_othervnc choose_sleep
   3295 	global choose_ncache ts_ncache choose_multisession ts_multisession
   3296 	global ts_mode ts_desktop_size ts_desktop_depth choose_desktop_geom
   3297 	global additional_port_redirs additional_port_redirs_list
   3298 	global stunnel_local_protection stunnel_local_protection_type ssh_local_protection multiple_listen listen_once listen_accept_popup listen_accept_popup_sc
   3299 	global ssh_known_hosts ssh_known_hosts_filename
   3300 	global ultra_dsm ultra_dsm_type ultra_dsm_file ultra_dsm_noultra ultra_dsm_salt
   3301 	global sound_daemon_remote_cmd sound_daemon_remote_port sound_daemon_kill sound_daemon_restart
   3302 	global sound_daemon_local_cmd sound_daemon_local_port sound_daemon_local_kill sound_daemon_x11vnc sound_daemon_local_start
   3303 	global smb_su_mode smb_mount_list
   3304 	global use_port_knocking port_knocking_list port_slot putty_args
   3305 	global ycrop_string ssvnc_scale ssvnc_escape sbwid_string rfbversion ssvnc_encodings ssvnc_extra_opts use_x11cursor use_nobell use_rawlocal use_notty use_popupfix extra_sleep use_listen use_unixpw use_x11vnc_find unixpw_username
   3306 	global disable_ssl_workarounds disable_ssl_workarounds_type
   3307 	global no_probe_vencrypt server_vencrypt server_anondh
   3308 	global include_list
   3309 	global svcert_default mycert_default crlfil_default
   3310 
   3311 
   3312 	set defs(use_viewonly) 0
   3313 	set defs(use_listen) 0
   3314 	set defs(disable_ssl_workarounds) 0
   3315 	set defs(disable_ssl_workarounds_type) "none"
   3316 	set defs(use_unixpw) 0
   3317 	set defs(unixpw_username) ""
   3318 	set defs(use_x11vnc_find) 0
   3319 	set defs(use_fullscreen) 0
   3320 	set defs(use_raise_on_beep) 0
   3321 	set defs(use_bgr233) 0
   3322 	set defs(use_alpha) 0
   3323 	set defs(use_send_clipboard) 0
   3324 	set defs(use_send_always) 0
   3325 	set defs(use_turbovnc) 0
   3326 	set defs(disable_pipeline) 0
   3327 	set defs(no_probe_vencrypt) 0
   3328 	set defs(server_vencrypt) 0
   3329 	set defs(server_anondh) 0
   3330 	set defs(use_grab) 0
   3331 	set defs(use_nojpeg) 0
   3332 	set defs(use_x11_macosx) 1
   3333 	if [info exists env(SSVNC_COTVNC)] {
   3334 		if {$env(SSVNC_COTVNC) != 0} {
   3335 			set defs(use_x11_macosx) 0
   3336 		}
   3337 	} elseif {![info exists env(DISPLAY)]} {
   3338 		set defs(use_x11_macosx) 0
   3339 	}
   3340 	set defs(use_compresslevel) "default"
   3341 	set defs(use_quality) "default"
   3342 	set defs(compresslevel_text) "Compress Level: default"
   3343 	set defs(quality_text) "Quality: default"
   3344 
   3345 	set defs(mycert) $mycert_default
   3346 	set defs(svcert) $svcert_default
   3347 	set defs(crtdir) "ACCEPTED_CERTS"
   3348 	set defs(crlfil) $crlfil_default
   3349 
   3350 	set defs(use_cups) 0
   3351 	set defs(use_sound) 0
   3352 	set defs(use_smbmnt) 0
   3353 
   3354 	set defs(choose_xserver) 0
   3355 	set defs(ts_xserver_type) ""
   3356 	set defs(choose_desktop) 0
   3357 	set defs(ts_desktop_type) ""
   3358 	set defs(ts_desktop_size) ""
   3359 	set defs(ts_desktop_depth) ""
   3360 	set defs(choose_desktop_geom) 0
   3361 	set defs(ts_unixpw) 0
   3362 	set defs(ts_vncshared) 0
   3363 	set defs(ts_ncache) 8
   3364 	set defs(choose_ncache) 0
   3365 	set defs(ts_multisession) ""
   3366 	set defs(choose_multisession) 0
   3367 	set defs(ts_filexfer) ""
   3368 	set defs(choose_filexfer) 0
   3369 	set defs(choose_x11vnc_opts) 0
   3370 	set defs(ts_x11vnc_opts) ""
   3371 	set defs(ts_x11vnc_path) ""
   3372 	set defs(ts_x11vnc_autoport) ""
   3373 	set defs(ts_othervnc) ""
   3374 	set defs(choose_othervnc) 0
   3375 	set defs(ts_xlogin) 0
   3376 	set defs(ts_mode) 0
   3377 
   3378 	set defs(change_vncviewer) 0
   3379 	set defs(change_vncviewer_path) ""
   3380 	set defs(cups_manage_rcfile) 1
   3381 	set defs(ts_cups_manage_rcfile) 0
   3382 	set defs(cups_x11vnc) 0
   3383 	set defs(vncviewer_realvnc4) 0
   3384 
   3385 	set defs(additional_port_redirs) 0
   3386 	set defs(additional_port_redirs_list) ""
   3387 
   3388 	set defs(stunnel_local_protection) 1
   3389 	set defs(stunnel_local_protection_type) "exec"
   3390 	set defs(ssh_local_protection) 1
   3391 	set defs(ssh_known_hosts) 0
   3392 	set defs(ssh_known_hosts_filename) ""
   3393 	set defs(multiple_listen) 0
   3394 	set defs(listen_once) 0
   3395 	set defs(listen_accept_popup) 0
   3396 	set defs(listen_accept_popup_sc) 0
   3397 
   3398 	set defs(ultra_dsm) 0
   3399 	set defs(ultra_dsm_file) ""
   3400 	set defs(ultra_dsm_type) "guess"
   3401 	set defs(ultra_dsm_noultra) 0
   3402 	set defs(ultra_dsm_salt) ""
   3403 
   3404 	set defs(port_slot) ""
   3405 	set defs(putty_args) ""
   3406 
   3407 	set defs(cups_local_server) ""
   3408 	set defs(cups_remote_port) ""
   3409 	set defs(cups_local_smb_server) ""
   3410 	set defs(cups_remote_smb_port) ""
   3411 
   3412 	set defs(smb_su_mode) "sudo"
   3413 	set defs(smb_mount_list) ""
   3414 
   3415 	set defs(sound_daemon_remote_cmd) ""
   3416 	set defs(sound_daemon_remote_port) ""
   3417 	set defs(sound_daemon_kill) 0
   3418 	set defs(sound_daemon_restart) 0
   3419 
   3420 	set defs(sound_daemon_local_cmd) ""
   3421 	set defs(sound_daemon_local_port) ""
   3422 	set defs(sound_daemon_local_start) 0
   3423 	set defs(sound_daemon_local_kill) 0
   3424 	set defs(sound_daemon_x11vnc) 0
   3425 
   3426 	set defs(ycrop_string) ""
   3427 	set defs(ssvnc_scale) ""
   3428 	set defs(ssvnc_escape) ""
   3429 	set defs(sbwid_string) ""
   3430 	set defs(rfbversion) ""
   3431 	set defs(ssvnc_encodings) ""
   3432 	set defs(ssvnc_extra_opts) ""
   3433 	set defs(use_x11cursor) 0
   3434 	set defs(use_nobell) 0
   3435 	set defs(use_rawlocal) 0
   3436 	set defs(use_notty) 0
   3437 	set defs(use_popupfix) 0
   3438 	set defs(extra_sleep) ""
   3439 	set defs(use_port_knocking) 0
   3440 	set defs(port_knocking_list) ""
   3441 
   3442 	set defs(include_list) ""
   3443 
   3444 	set dir [get_profiles_dir]
   3445 	set deffile ""
   3446 	if [file exists "$dir/defaults"] {
   3447 		set deffile "$dir/defaults"
   3448 	} elseif [file exists "$dir/defaults.vnc"] {
   3449 		set deffile "$dir/defaults.vnc"
   3450 	}
   3451 	if {$deffile != ""} {
   3452 		set fh ""
   3453 		catch {set fh [open $deffile "r"]}
   3454 		if {$fh != ""} {
   3455 			while {[gets $fh line] > -1} {
   3456 				set line [string trim $line]
   3457 				if [regexp {^#} $line] {
   3458 					continue
   3459 				}
   3460 				if [regexp {^([^=]*)=(.*)$} $line m var val] {
   3461 					if {$var == "disp"} {
   3462 						continue
   3463 					}
   3464 					if [info exists defs($var)] {
   3465 						set pct 0
   3466 						if {$var == "smb_mount_list"} {
   3467 							set pct 1
   3468 						}
   3469 						if {$var == "port_knocking_list"} {
   3470 							set pct 1
   3471 						}
   3472 						if {$pct} {
   3473 							regsub -all {%%%} $val "\n" val
   3474 						}
   3475 						set defs($var) $val
   3476 					}
   3477 				}
   3478 			}
   3479 			close $fh
   3480 		}
   3481 	}
   3482 
   3483 	global ssh_only ts_only
   3484 	if {$ssh_only || $ts_only} {
   3485 		set defs(use_ssl) 0
   3486 		set defs(use_ssh) 1
   3487 		set defs(use_sshssl) 0
   3488 	} else {
   3489 		set defs(use_ssl) 1
   3490 		set defs(use_ssh) 0
   3491 		set defs(use_sshssl) 0
   3492 	}
   3493 	set defs(disable_all_encryption) 0
   3494 
   3495 	foreach var [array names defs] {
   3496 		set $var $defs($var)
   3497 	}
   3498 
   3499 	global vncauth_passwd unixpw_passwd
   3500 	set vncauth_passwd ""
   3501 	set unixpw_passwd ""
   3502 
   3503 	if {$ssh_only || $ts_only} {
   3504 		ssl_ssh_adjust ssh
   3505 	} else {
   3506 		ssl_ssh_adjust ssl
   3507 	}
   3508 	listen_adjust
   3509 	unixpw_adjust
   3510 
   3511 	global last_load
   3512 	set last_load ""
   3513 }
   3514 
   3515 proc windows_listening_message {n} {
   3516 	global did_listening_message
   3517 
   3518 	global extra_cmd
   3519 	set extra_cmd ""
   3520 	set cmd [get_cmd $n]
   3521 
   3522 	if {$did_listening_message < 2} {
   3523 		incr did_listening_message
   3524 		global listening_name
   3525 
   3526 		set ln $listening_name
   3527 		if {$ln == ""} {
   3528 			set ln "this-computer:$n"
   3529 		}
   3530 
   3531 		set msg "
   3532    About to start the Listening VNC Viewer (Reverse Connection).
   3533 
   3534    The VNC Viewer command to be run is:
   3535 
   3536        $cmd
   3537 
   3538    After the Viewer starts listening, the VNC server should
   3539    then Reverse connect to:
   3540 
   3541        $ln
   3542 
   3543    When the VNC Connection has ended **YOU MUST MANUALLY STOP**
   3544    the Listening VNC Viewer.
   3545 
   3546    To stop the Listening Viewer: right click on the VNC Icon in
   3547    the tray and select 'Close listening daemon' (or similar).
   3548 
   3549    ONLY AFTER THAT will you return to the SSVNC GUI.
   3550 
   3551    Click OK now to start the Listening VNC Viewer.$extra_cmd
   3552 "
   3553 		global use_ssh use_sshssl
   3554 		if {$use_ssh || $use_sshssl} {
   3555 			set msg "${msg}   NOTE: You will probably also need to kill the SSH in the\n   terminal via Ctrl-C"
   3556 		}
   3557 
   3558 		global help_font is_windows system_button_face
   3559 		toplev .wll
   3560 		global wll_done
   3561 
   3562 		set wll_done 0
   3563 
   3564 		eval text .wll.t -width 64 -height 22 $help_font
   3565 		button .wll.d -text "OK" -command {destroy .wll; set wll_done 1}
   3566 		pack .wll.t .wll.d -side top -fill x
   3567 
   3568 		apply_bg .wll.t
   3569 
   3570 		center_win .wll
   3571 		wm resizable .wll 1 0
   3572 
   3573 		wm title .wll "SSL/SSH Viewer: Listening VNC Info"
   3574 
   3575 		.wll.t insert end $msg
   3576 
   3577 		vwait wll_done
   3578 	}
   3579 }
   3580 
   3581 proc get_cmd {n} {
   3582 	global use_alpha use_grab use_x11cursor use_nobell use_ssh
   3583 	global use_sshssl use_viewonly use_fullscreen use_bgr233
   3584 	global use_nojpeg use_raise_on_beep use_compresslevel use_quality
   3585 	global use_send_clipboard use_send_always change_vncviewer
   3586 	global change_vncviewer_path vncviewer_realvnc4 use_listen
   3587 	global disable_ssl_workarounds disable_ssl_workarounds_type env
   3588 
   3589 	set cmd "vncviewer"
   3590 	if {$change_vncviewer && $change_vncviewer_path != ""} {
   3591 		set cmd [string trim $change_vncviewer_path]
   3592 		regsub -all {\\} $cmd {/} cmd
   3593 		if {[regexp {[ \t]} $cmd]} {
   3594 			if {[regexp -nocase {\.exe$} $cmd]} {
   3595 				if {! [regexp {["']} $cmd]} { #"
   3596 					# hmmm, not following instructions, are they?
   3597 					set cmd "\"$cmd\""
   3598 				}
   3599 			}
   3600 		}
   3601 	}
   3602 	if {$use_viewonly} {
   3603 		if {$vncviewer_realvnc4} {
   3604 			append cmd " viewonly=1"
   3605 		} else {
   3606 			append cmd " /viewonly"
   3607 		}
   3608 	}
   3609 	if {$use_fullscreen} {
   3610 		if {$vncviewer_realvnc4} {
   3611 			append cmd " fullscreen=1"
   3612 		} else {
   3613 			append cmd " /fullscreen"
   3614 		}
   3615 	}
   3616 	if {$use_bgr233} {
   3617 		if {$vncviewer_realvnc4} {
   3618 			append cmd " lowcolourlevel=1"
   3619 		} else {
   3620 			append cmd " /8bit"
   3621 		}
   3622 	}
   3623 	if {$use_nojpeg} {
   3624 		if {! $vncviewer_realvnc4} {
   3625 			append cmd " /nojpeg"
   3626 		}
   3627 	}
   3628 	if {$use_raise_on_beep} {
   3629 		if {! $vncviewer_realvnc4} {
   3630 			append cmd " /belldeiconify"
   3631 		}
   3632 	}
   3633 	if {$use_compresslevel != "" && $use_compresslevel != "default"} {
   3634 		if {$vncviewer_realvnc4} {
   3635 			append cmd " zliblevel=$use_compresslevel"
   3636 		} else {
   3637 			append cmd " /compresslevel $use_compresslevel"
   3638 		}
   3639 	}
   3640 	if {$use_quality != "" && $use_quality != "default"} {
   3641 		if {! $vncviewer_realvnc4} {
   3642 			append cmd " /quality $use_quality"
   3643 		}
   3644 	}
   3645 
   3646 	global extra_cmd
   3647 	set extra_cmd ""
   3648 	if {$use_listen} {
   3649 		if {$vncviewer_realvnc4} {
   3650 			append cmd " listen=1"
   3651 		} else {
   3652 			append cmd " /listen"
   3653 		}
   3654 		set nn $n
   3655 		if {$nn < 100} {
   3656 			set nn [expr "$nn + 5500"]
   3657 		}
   3658 		global direct_connect_reverse_host_orig is_win9x
   3659 		if {![info exists direct_connect_reverse_host_orig]} {
   3660 			set direct_connect_reverse_host_orig ""
   3661 		}
   3662 		if {$direct_connect_reverse_host_orig != "" && !$is_win9x} {
   3663 			set nn2 [expr $nn + 15]
   3664 			set h0 $direct_connect_reverse_host_orig
   3665 			global win_localhost
   3666 			set extra_cmd "\n\nrelay6.exe $nn $win_localhost $nn2 /b:$h0"
   3667 			set nn $nn2
   3668 		}
   3669 
   3670 		append cmd " $nn"
   3671 
   3672 	} else {
   3673 		if [regexp {^[0-9][0-9]*$} $n] {
   3674 			global win_localhost
   3675 			append cmd " $win_localhost:$n"
   3676 		} else {
   3677 			append cmd " $n"
   3678 		}
   3679 	}
   3680 	return $cmd
   3681 }
   3682 
   3683 proc do_viewer_windows {n} {
   3684 	global use_listen env
   3685 
   3686 	set cmd [get_cmd $n]
   3687 
   3688 	set ipv6_pid2 ""
   3689 	if {$use_listen} {
   3690 		set nn $n
   3691 		if {$nn < 100} {
   3692 			set nn [expr "$nn + 5500"]
   3693 		}
   3694 		global direct_connect_reverse_host_orig is_win9x
   3695 		if {![info exists direct_connect_reverse_host_orig]} {
   3696 			set direct_connect_reverse_host_orig ""
   3697 		}
   3698 		if {$direct_connect_reverse_host_orig != "" && !$is_win9x} {
   3699 			set nn2 [expr $nn + 15]
   3700 			set h0 $direct_connect_reverse_host_orig
   3701 			global win_localhost
   3702 			set ipv6_pid2 [exec relay6.exe $nn $win_localhost $nn2 /b:$h0 &]
   3703 			set nn $nn2
   3704 		}
   3705 	}
   3706 
   3707 	if [info exists env(SSVNC_EXTRA_SLEEP)] {
   3708 		set t $env(SSVNC_EXTRA_SLEEP)
   3709 		mesg "sleeping an extra $t seconds..."
   3710 		set t [expr "$t * 1000"]
   3711 		after $t
   3712 	}
   3713 	global extra_sleep
   3714 	if {$extra_sleep != ""} {
   3715 		set t $extra_sleep
   3716 		mesg "sleeping an extra $t seconds..."
   3717 		set t [expr "$t * 1000"]
   3718 		after $t
   3719 	}
   3720 
   3721 	mesg $cmd
   3722 	set emess ""
   3723 	set rc [catch {eval exec $cmd} emess]
   3724 
   3725 	if {$ipv6_pid2 != ""} {
   3726 		winkill $ipv6_pid2
   3727 	}
   3728 
   3729 	if {$rc != 0} {
   3730 		raise .
   3731 		tk_messageBox -type ok -icon error -message $emess -title "Error: $cmd"
   3732 	}
   3733 }
   3734 
   3735 proc get_netstat {} {
   3736 	set ns ""
   3737 	catch {set ns [exec netstat -an]}
   3738 	return $ns
   3739 }
   3740 
   3741 proc get_ipconfig {} {
   3742 	global is_win9x
   3743 	set ip ""
   3744 	if {! $is_win9x} {
   3745 		catch {set ip [exec ipconfig]}
   3746 		return $ip
   3747 	}
   3748 
   3749 	set file "ip"
   3750 	append file [pid]
   3751 	append file ".txt"
   3752 
   3753 	# VF
   3754 	catch {[exec winipcfg /Batch $file]}
   3755 
   3756 	if [file exists $file] {
   3757 		set fh [open $file "r"]
   3758 		while {[gets $fh line] > -1} {
   3759 			append ip "$line\n"
   3760 		}
   3761 		close $fh
   3762 		catch {file delete $file}
   3763 	}
   3764 	return $ip
   3765 }
   3766 
   3767 proc read_file {file} {
   3768 	set str ""
   3769 	if [file exists $file] {
   3770 		set fh ""
   3771 		catch {set fh [open $file "r"]}
   3772 		if {$fh != ""} {
   3773 			while {[gets $fh line] > -1} {
   3774 				append str "$line\n"
   3775 			}
   3776 			close $fh
   3777 		}
   3778 	}
   3779 	return $str
   3780 }
   3781 
   3782 proc guess_nat_ip {} {
   3783 	global save_nat last_save_nat
   3784 	set s ""
   3785 
   3786 	if {! [info exists save_nat]} {
   3787 		set save_nat ""
   3788 		set last_save_nat 0
   3789 	}
   3790 	if {$save_nat != ""} {
   3791 		set now [clock seconds]
   3792 		if {$now < $last_save_nat + 45} {
   3793 			return $save_nat
   3794 		}
   3795 	}
   3796 	set s ""
   3797 	catch {set s [socket "www.whatismyip.com" 80]}
   3798 	set ip "unknown"
   3799 	if {$s != ""} {
   3800 		fconfigure $s -buffering none
   3801 		#puts $s "GET / HTTP/1.1"
   3802 		puts $s "GET /automation/n09230945.asp HTTP/1.1"
   3803 		puts $s "Host: www.whatismyip.com"
   3804 		puts $s "Connection: close"
   3805 		puts $s ""
   3806 		flush $s
   3807 		set on 0
   3808 		while { [gets $s line] > -1 } {
   3809 			if {! $on && [regexp {<HEAD>}  $line]} {set on 1}
   3810 			if {! $on && [regexp {<HTML>}  $line]} {set on 1}
   3811 			if {! $on && [regexp {<TITLE>} $line]} {set on 1}
   3812 			if {! $on && [regexp {^[0-9][0-9]*\.[0-9]} $line]} {set on 1}
   3813 			if {! $on} {
   3814 				continue;
   3815 			}
   3816 			if [regexp {([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*)} $line ip] {
   3817 				break
   3818 			}
   3819 		}
   3820 		close $s
   3821 	}
   3822 	if {$ip != "unknown"} {
   3823 		set save_nat $ip
   3824 		set last_save_nat [clock seconds]
   3825 	}
   3826 	return $ip
   3827 }
   3828 
   3829 proc check_for_ipv6 {} {
   3830 	global is_windows have_ipv6
   3831 	if {$have_ipv6 != ""} {
   3832 		return
   3833 	}
   3834 	if {! $is_windows} {
   3835 		set out ""
   3836 		catch {set out [exec netstat -an]}
   3837 		if [regexp {tcp6} $out] {
   3838 			set have_ipv6 1
   3839 		} elseif [regexp {udp6} $out] {
   3840 			set have_ipv6 1
   3841 		} elseif [regexp {:::} $out] {
   3842 			set have_ipv6 1
   3843 		} elseif [regexp {::1} $out] {
   3844 			set have_ipv6 1
   3845 		} elseif [regexp {TCP: IPv6.*LISTEN} $out] {
   3846 			set have_ipv6 1
   3847 		} else {
   3848 			set have_ipv6 0
   3849 		}
   3850 	} else {
   3851 		set out [get_ipconfig]
   3852 		set out [string trim $out]
   3853 		if {$out == ""} {
   3854 			catch {set out [exec ping6 -n 1 -w 2000 ::1]}
   3855 			if [regexp {Reply from.*bytes} $out] {
   3856 				if [regexp {Received = 1} $out] {
   3857 					set have_ipv6 1
   3858 					return
   3859 				}
   3860 			}
   3861 			set have_ipv6 0
   3862 			return
   3863 		}
   3864 		foreach line [split $out "\n\r"] {
   3865 			if {[regexp -nocase {IP Address.*:[ \t]*[a-f0-9]*:[a-f0-9]*:} $line]} {
   3866 				set have_ipv6 1
   3867 				return
   3868 			}
   3869 		}
   3870 		set have_ipv6 0
   3871 	}
   3872 }
   3873 proc guess_ip {} {
   3874 	global is_windows
   3875 	if {! $is_windows} {
   3876 		set out ""
   3877 		set out [get_hostname]
   3878 		if {$out != ""} {
   3879 			set hout ""
   3880 			catch {set hout [exec host $out]}
   3881 			if {$hout != ""} {
   3882 				if [regexp {has address ([.0-9][.0-9]*)} $hout mvar ip] {
   3883 					set ip [string trim $ip]
   3884 					return $ip
   3885 				}
   3886 			}
   3887 		}
   3888 		return ""
   3889 	} else {
   3890 		set out [get_ipconfig]
   3891 		set out [string trim $out]
   3892 		if {$out == ""} {
   3893 			return ""
   3894 		}
   3895 		foreach line [split $out "\n\r"] {
   3896 			if {[regexp -nocase {IP Address.*:[ \t]*([.0-9][.0-9]*)} $line mvar ip]} {
   3897 				set ip [string trim $ip]
   3898 				if [regexp {^[.0]*$} $ip] {
   3899 					continue
   3900 				}
   3901 				if [regexp {127\.0\.0\.1} $ip] {
   3902 					continue
   3903 				}
   3904 				if {$ip != ""} {
   3905 					return $ip
   3906 				}
   3907 			}
   3908 		}
   3909 		foreach line [split $out "\n\r"] {
   3910 			if {[regexp -nocase {IP Address.*:[ \t]*([:a-f0-9][%:a-f0-9]*)} $line mvar ip]} {
   3911 				set ip [string trim $ip]
   3912 				if [regexp {^[.0]*$} $ip] {
   3913 					continue
   3914 				}
   3915 				if [regexp {127\.0\.0\.1} $ip] {
   3916 					continue
   3917 				}
   3918 				if {$ip != ""} {
   3919 					return $ip
   3920 				}
   3921 			}
   3922 		}
   3923 	}
   3924 }
   3925 
   3926 proc bat_sleep {fh} {
   3927 	global env
   3928 	if [info exists env(SSVNC_BAT_SLEEP)] {
   3929 		puts $fh "@echo ."
   3930 		puts $fh "@echo -----"
   3931 		puts $fh "@echo Debug: BAT SLEEP for $env(SSVNC_BAT_SLEEP) seconds ..."
   3932 		puts $fh "@ping -n $env(SSVNC_BAT_SLEEP) -w 1000 0.0.0.1 > NUL"
   3933 		puts $fh "@echo BAT SLEEP done."
   3934 	}
   3935 }
   3936 
   3937 proc windows_start_sound_daemon {file} {
   3938 	global env
   3939 	global use_sound sound_daemon_local_cmd sound_daemon_local_start
   3940 
   3941 	# VF
   3942 	regsub {\.bat} $file "snd.bat" file2
   3943 	set fh2 [open $file2 "w"]
   3944 
   3945 	puts $fh2 $sound_daemon_local_cmd
   3946 	bat_sleep $fh2
   3947 	puts $fh2 "del $file2"
   3948 	close $fh2
   3949 
   3950 	mesg "Starting SOUND daemon..."
   3951 	if [info exists env(COMSPEC)] {
   3952 		if [info exists env(SSVNC_BAT_SLEEP)] {
   3953 			exec $env(COMSPEC) /c start $env(COMSPEC) /c $file2 &
   3954 		} else {
   3955 			exec $env(COMSPEC) /c $file2 &
   3956 		}
   3957 	} else {
   3958 		if [info exists env(SSVNC_BAT_SLEEP)] {
   3959 			exec cmd.exe /c start cmd.exe /c $file2 &
   3960 		} else {
   3961 			exec cmd.exe /c $file2 &
   3962 		}
   3963 	}
   3964 	after 1500
   3965 }
   3966 
   3967 proc winkill {pid} {
   3968 	global is_win9x
   3969 
   3970 	if {$pid == ""} {
   3971 		return
   3972 	}
   3973 	if {! $is_win9x} {
   3974 		catch {exec tskill.exe $pid}
   3975 		after 100
   3976 		catch {exec taskkill.exe /PID $pid}
   3977 		after 100
   3978 	}
   3979 	catch {exec w98/kill.exe /f $pid}
   3980 }
   3981 
   3982 proc windows_stop_sound_daemon {} {
   3983 	global use_sound sound_daemon_local_cmd sound_daemon_local_start
   3984 
   3985 	set cmd [string trim $sound_daemon_local_cmd]
   3986 
   3987 	regsub {[ \t].*$} $cmd "" cmd
   3988 	regsub {^.*\\} $cmd "" cmd
   3989 	regsub {^.*/} $cmd "" cmd
   3990 
   3991 	if {$cmd == ""} {
   3992 		return
   3993 	}
   3994 
   3995 	set output [get_task_list]
   3996 
   3997 	foreach line [split $output "\n\r"] {
   3998 		if [regexp "$cmd" $line] {
   3999 			if [regexp {(-?[0-9][0-9]*)} $line m p] {
   4000 				set pids($p) $line
   4001 			}
   4002 		}
   4003 	}
   4004 
   4005 	set count 0
   4006 	foreach pid [array names pids] {
   4007 		mesg "Stopping SOUND pid: $pid"
   4008 		winkill $pid
   4009 		if {$count == 0} {
   4010 			after 1200
   4011 		} else {
   4012 			after 500
   4013 		}
   4014 		incr count
   4015 	}
   4016 }
   4017 
   4018 proc contag {} {
   4019 	global concount
   4020 	if {! [info exists concount]} {
   4021 		set concount 0
   4022 	}
   4023 	incr concount
   4024 	set str [pid]
   4025 	set str "-$str-$concount"
   4026 }
   4027 
   4028 proc make_plink {} {
   4029 	toplev .plink
   4030 	#wm geometry .plink +700+500
   4031 	wm geometry .plink -40-40
   4032 	wm title .plink "plink SSH status?"
   4033 	set wd 37
   4034 	label .plink.l1 -anchor w -text "Login via plink/ssh to the remote server" -width $wd
   4035 	label .plink.l2 -anchor w -text "(supply username and password as needed)." -width $wd
   4036 	label .plink.l3 -anchor w -text "" -width $wd
   4037 	label .plink.l4 -anchor w -text "After ssh is set up, AND if the connection" -width $wd
   4038 	label .plink.l5 -anchor w -text "success is not autodetected, please click" -width $wd
   4039 	label .plink.l6 -anchor w -text "one of these buttons:" -width $wd
   4040 	global plink_status
   4041 	button .plink.fail -text "Failed" -command {destroy .plink; set plink_status no}
   4042 	button .plink.ok   -text "Success" -command {destroy .plink; set plink_status yes}
   4043 	pack .plink.l1 .plink.l2 .plink.l3 .plink.l4 .plink.l5 .plink.l6 .plink.fail .plink.ok -side top -fill x
   4044 
   4045 	update
   4046 }
   4047 
   4048 proc ssh_split {str} {
   4049 	regsub { .*$} $str "" str
   4050 	if {! [regexp {:[0-9][0-9]*$} $str]} {
   4051 		append str ":22"
   4052 	}
   4053 	regsub {:[0-9][0-9]*$} $str "" ssh_host
   4054 	regsub {^.*:} $str "" ssh_port
   4055 	if {$ssh_port == ""} {
   4056 		set ssh_port 22
   4057 	}
   4058 	if [regexp {@} $ssh_host] {
   4059 		regsub {@.*$} $ssh_host "" ssh_user
   4060 		regsub {^.*@} $ssh_host "" ssh_host
   4061 	} else {
   4062 		set ssh_user ""
   4063 	}
   4064 	return [list $ssh_user $ssh_host $ssh_port]
   4065 }
   4066 
   4067 proc check_debug_netstat {port str wn} {
   4068 	global debug_netstat
   4069 	if {! [info exists debug_netstat]} {
   4070 		return
   4071 	}
   4072 	if {$debug_netstat == "0" || $debug_netstat == ""} {
   4073 		return
   4074 	}
   4075 	mesg "DBG: $wn"
   4076 
   4077 	toplev .dbns
   4078 
   4079 	set h 35
   4080 	if [small_height] {
   4081 		set h 28
   4082 	}
   4083 	scroll_text_dismiss .dbns.f 82 $h
   4084 	center_win .dbns
   4085 	.dbns.f.t insert end "LOOKING FOR PORT: $port\n\n$str"
   4086 	jiggle_text .dbns.f.t
   4087 	update
   4088 	after 1000
   4089 }
   4090 
   4091 proc launch_windows_ssh {hp file n} {
   4092 	global is_win9x env
   4093 	global use_sshssl use_ssh putty_pw putty_args
   4094 	global port_knocking_list
   4095 	global use_listen listening_name
   4096 	global disable_ssl_workarounds disable_ssl_workarounds_type
   4097 	global ts_only
   4098 	global debug_netstat
   4099 
   4100 	set hpnew  [get_ssh_hp $hp]
   4101 	set proxy  [get_ssh_proxy $hp]
   4102 	set sshcmd [get_ssh_cmd $hp]
   4103 
   4104 	global win_localhost
   4105 
   4106 	set vnc_host $win_localhost
   4107 	set vnc_disp $hpnew
   4108 	regsub {^.*:} $vnc_disp "" vnc_disp
   4109 
   4110 	regsub {\.bat} $file ".flg" flag
   4111 
   4112 	if {$ts_only} {
   4113 		regsub {:0$} $hpnew "" hpnew
   4114 		if {$proxy == ""} {
   4115 			if {[regexp {^(.*):([0-9][0-9]*)$} $hpnew mv sshhst sshpt]} {
   4116 				set proxy "$sshhst:$sshpt"
   4117 				set hpnew $win_localhost
   4118 			}
   4119 		} else {
   4120 			if {![regexp {,} $proxy]} {
   4121 				if {$hpnew != $win_localhost} {
   4122 					set proxy "$proxy,$hpnew"
   4123 					set hpnew $win_localhost
   4124 				}
   4125 			}
   4126 		}
   4127 	} elseif {![regexp {^-?[0-9][0-9]*$} $vnc_disp]} {
   4128 		if {[regexp {cmd=SHELL} $hp]} {
   4129 			;
   4130 		} elseif {[regexp {cmd=PUTTY} $hp]} {
   4131 			;
   4132 		} else {
   4133 			# XXX add :0 instead?
   4134 			if {1} {
   4135 				set vnc_disp "vnc_disp:0"
   4136 				mesg "Added :0 to $vnc_disp"
   4137 			} else {
   4138 				mesg "Bad vncdisp, missing :0 ?, $vnc_disp"
   4139 				bell
   4140 				return 0
   4141 			}
   4142 		}
   4143 	}
   4144 
   4145 	if {$use_listen} {
   4146 		set vnc_port 5500
   4147 	} else {
   4148 		set vnc_port 5900
   4149 	}
   4150 
   4151 	if {$ts_only || [regexp {PORT= .*x11vnc} $sshcmd] || [regexp {P= .*x11vnc} $sshcmd]} {
   4152 		regsub {PORT= [ 	]*} $sshcmd "" sshcmd
   4153 		regsub {P= [ 	]*} $sshcmd "" sshcmd
   4154 		set vnc_port [expr "8100 + int(4000 * rand())"]
   4155 		set sshcmd "$sshcmd -rfbport $vnc_port"
   4156 	} elseif {[regexp {^-[0-9][0-9]*$} $vnc_disp]} {
   4157 		set vnc_port [expr "- $vnc_disp"]
   4158 	} elseif {![regexp {^[0-9][0-9]*$} $vnc_disp]} {
   4159 		;
   4160 	} elseif {$vnc_disp < 200} {
   4161 		if {$use_listen} {
   4162 			set vnc_port [expr $vnc_disp + 5500]
   4163 		} else {
   4164 			set vnc_port [expr $vnc_disp + 5900]
   4165 		}
   4166 	} else {
   4167 		set vnc_port $vnc_disp
   4168 	}
   4169 
   4170 	global ssh_ipv6_pid
   4171 	set ssh_ipv6_pid ""
   4172 
   4173 	set ssh_port 22
   4174 	set ssh_host [host_part $hpnew]
   4175 
   4176 	set double_ssh ""
   4177 	set p_port ""
   4178 	if {$proxy != ""} {
   4179 		if [regexp -nocase {(http|https|socks|socks4|socks5|repeater)://} $proxy] {
   4180 			set pproxy ""
   4181 			set sproxy1 ""
   4182 			set sproxy_rest ""
   4183 			set sproxy1_host ""
   4184 			set sproxy1_user ""
   4185 			set sproxy1_port ""
   4186 			foreach part [split $proxy ","] {
   4187 				if {[regexp {^[ 	]*$} $part]} {
   4188 					continue
   4189 				}
   4190 				if [regexp -nocase {^(http|https|socks|socks4|socks5|repeater)://} $part] {
   4191 					if {$pproxy == ""} {
   4192 						set pproxy $part
   4193 					} else {
   4194 						set pproxy "$pproxy,$part"
   4195 					}
   4196 				} else {
   4197 					if {$sproxy1 == ""} {
   4198 						set sproxy1 $part
   4199 					} else {
   4200 						if {$sproxy_rest == ""} {
   4201 							set sproxy_rest $part
   4202 						} else {
   4203 							set sproxy_rest "$sproxy_rest,$part"
   4204 						}
   4205 					}
   4206 				}
   4207 			}
   4208 
   4209 #mesg "pproxy: $pproxy"; after 2000
   4210 #mesg "sproxy1: $sproxy1"; after 2000
   4211 #mesg "sproxy_rest: $sproxy_rest"; after 2000
   4212 #mesg "ssh_host: $ssh_host"; after 2000
   4213 #mesg "ssh_port: $ssh_port"; after 2000
   4214 
   4215 			if {$sproxy1 != ""} {
   4216 				regsub {:[0-9][0-9]*$} $sproxy1 "" sproxy1_host
   4217 				regsub {^.*@} $sproxy1_host "" sproxy1_host
   4218 				regsub {@.*$} $sproxy1 "" sproxy1_user
   4219 				regsub {^.*:} $sproxy1 "" sproxy1_port
   4220 			} else {
   4221 				regsub {:[0-9][0-9]*$} $ssh_host "" sproxy1_host
   4222 				regsub {^.*@} $sproxy1_host "" sproxy1_host
   4223 				regsub {@.*$} $ssh_host "" sproxy1_user
   4224 				regsub {^.*:} $ssh_host "" sproxy1_port
   4225 			}
   4226 			if {![regexp {^[0-9][0-9]*$} $sproxy1_port]} {
   4227 				set sproxy1_port 22
   4228 			}
   4229 			if {$sproxy1_user != ""} {
   4230 				set sproxy1_user "$sproxy1_user@"
   4231 			}
   4232 
   4233 #mesg "sproxy1_host: $sproxy1_host"; after 2000
   4234 #mesg "sproxy1_user: $sproxy1_user"; after 2000
   4235 #mesg "sproxy1_port: $sproxy1_port"; after 2000
   4236 
   4237 			set port2 ""
   4238 			if [regexp -- {-([0-9][0-9]*)} [file tail $file] mv dport] {
   4239 				set port2 [expr 21000 + $dport]
   4240 			} else {
   4241 				set port2 [rand_port]
   4242 			}
   4243 
   4244 			global have_ipv6
   4245 			if {$have_ipv6} {
   4246 				set res [ipv6_proxy $pproxy "" ""]
   4247 				set pproxy    [lindex $res 0]
   4248 				set ssh_ipv6_pid [lindex $res 3]
   4249 			}
   4250 
   4251 			set env(SSVNC_PROXY) $pproxy
   4252 			set env(SSVNC_LISTEN) $port2
   4253 			set env(SSVNC_DEST) "$sproxy1_host:$sproxy1_port"
   4254 
   4255 			mesg "Starting Proxy TCP helper on port $port2 ..."
   4256 			after 300
   4257 			# ssh br case:
   4258 			set proxy_pid [exec "connect_br.exe" &]
   4259 
   4260 			catch { unset env(SSVNC_PROXY)  }
   4261 			catch { unset env(SSVNC_LISTEN) }
   4262 			catch { unset env(SSVNC_DEST)   }
   4263 
   4264 			if {$sproxy1 == ""} {
   4265 				set proxy "$win_localhost:$port2"
   4266 				if [regexp {^(.*)@} $ssh_host mv u] {
   4267 					set proxy "$u@$proxy"
   4268 				}
   4269 			} else {
   4270 				set proxy "${sproxy1_user}$win_localhost:$port2"
   4271 			}
   4272 			if {$sproxy_rest != ""} {
   4273 				set proxy "$proxy,$sproxy_rest"
   4274 			}
   4275 			mesg "Set proxy to: $proxy"
   4276 			after 300
   4277 		}
   4278 		if [regexp {,} $proxy] {
   4279 			if {$is_win9x} {
   4280 				mesg "Double proxy does not work on Win9x"
   4281 				bell
   4282 				winkill $ssh_ipv6_pid
   4283 				set ssh_ipv6_pid ""
   4284 				return 0
   4285 			}
   4286 			# user1@gateway:port1,user2@workstation:port2
   4287 			set proxy1 ""
   4288 			set proxy2 ""
   4289 			set s [split $proxy ","]
   4290 			set proxy1 [lindex $s 0]
   4291 			set proxy2 [lindex $s 1]
   4292 
   4293 			set p_port ""
   4294 			if [regexp -- {-([0-9][0-9]*)} [file tail $file] mv dport] {
   4295 				set p_port [expr 4000 + $dport]
   4296 			} else {
   4297 				set p_port [expr 3000 + 1000 * rand()]
   4298 				set p_port [expr round($p_port)]
   4299 			}
   4300 
   4301 			set s [ssh_split $proxy1]
   4302 			set ssh_user1 [lindex $s 0]
   4303 			set ssh_host1 [lindex $s 1]
   4304 			set ssh_port1 [lindex $s 2]
   4305 
   4306 			set s [ssh_split $proxy2]
   4307 			set ssh_user2 [lindex $s 0]
   4308 			set ssh_host2 [lindex $s 1]
   4309 			set ssh_port2 [lindex $s 2]
   4310 
   4311 			if {! [regexp {^[0-9][0-9]*$} $ssh_port1]} {
   4312 				set ssh_port1 22
   4313 			}
   4314 			if {! [regexp {^[0-9][0-9]*$} $ssh_port2]} {
   4315 				set ssh_port2 22
   4316 			}
   4317 
   4318 			set u1 ""
   4319 			if {$ssh_user1 != ""} {
   4320 				set u1 "${ssh_user1}@"
   4321 			}
   4322 			set u2 ""
   4323 			if {$ssh_user2 != ""} {
   4324 				set u2 "${ssh_user2}@"
   4325 			}
   4326 
   4327 			set double_ssh "-L $p_port:$ssh_host2:$ssh_port2 -P $ssh_port1 $u1$ssh_host1"
   4328 			set proxy_use "${u2}$win_localhost:$p_port"
   4329 
   4330 		} else {
   4331 			# user1@gateway:port1
   4332 			set proxy_use $proxy
   4333 		}
   4334 
   4335 		set ssh_host [host_part $proxy_use]
   4336 
   4337 		set ssh_port [port_part $proxy_use]
   4338 		if {! [regexp {^[0-9][0-9]*$} $ssh_port]} {
   4339 			set ssh_port 22
   4340 		}
   4341 
   4342 		set vnc_host [host_part $hpnew]
   4343 		if {$vnc_host == ""} {
   4344 			set vnc_host $win_localhost
   4345 		}
   4346 	}
   4347 
   4348 	if {![regexp {^[^ 	][^ 	]*@} $ssh_host]} {
   4349 		mesg "You must supply a username: user (at) host..."
   4350 		bell
   4351 		winkill $ssh_ipv6_pid
   4352 		set ssh_ipv6_pid ""
   4353 		return 0
   4354 	}
   4355 
   4356 	set verb "-v"
   4357 
   4358 	set pwd ""
   4359 	if {$is_win9x} {
   4360 		set pwd [pwd]
   4361 		regsub -all {/} $pwd "\\" pwd
   4362 	}
   4363 	if {! [regexp {^[0-9][0-9]*$} $n]} {
   4364 		set n 0
   4365 	}
   4366 
   4367 	if {$use_listen} {
   4368 		set use [expr $n + 5500]
   4369 	} else {
   4370 		set use [expr $n + 5900]
   4371 	}
   4372 
   4373 	set_smb_mounts
   4374 
   4375 	global use_smbmnt use_sound sound_daemon_kill
   4376 	set do_pre 0
   4377 	if {$use_smbmnt}  {
   4378 		set do_pre 1
   4379 	} elseif {$use_sound && $sound_daemon_kill} {
   4380 		set do_pre 1
   4381 	}
   4382 
   4383 	global skip_pre
   4384 	if {$skip_pre} {
   4385 		set do_pre 0
   4386 		set skip_pre 0
   4387 	}
   4388 
   4389 	set pw ""
   4390 	if {$putty_pw != ""} {
   4391 		if {! [regexp {"} $putty_pw]} {  #"
   4392 			set pw "                                                      -pw                                                   \"$putty_pw\""
   4393 		}
   4394 	}
   4395 
   4396 	set tag [contag]
   4397 
   4398 	set file_double ""
   4399 
   4400 	set file_pre ""
   4401 	set file_pre_cmd ""
   4402 	if {$do_pre} {
   4403 		set setup_cmds [ugly_setup_scripts pre $tag]
   4404 
   4405 		if {$setup_cmds != ""} {
   4406 			# VF
   4407 			regsub {\.bat} $file "pre.cmd" file_pre_cmd
   4408 			set fh [open $file_pre_cmd "w"]
   4409 			puts $fh "$setup_cmds sleep 10; "
   4410 			bat_sleep $fh
   4411 			close $fh
   4412 
   4413 			# VF
   4414 			regsub {\.bat} $file "pre.bat" file_pre
   4415 			set fh [open $file_pre "w"]
   4416 			set plink_str "plink.exe -ssh -C -P $ssh_port -m $file_pre_cmd $verb -t"
   4417 			if {$putty_args != ""} {
   4418 				append plink_str " $putty_args"
   4419 			}
   4420 
   4421 			global smb_redir_0
   4422 			if {$smb_redir_0 != ""} {
   4423 				append plink_str " $smb_redir_0"
   4424 			}
   4425 
   4426 			if [regexp {%} $ssh_host] {
   4427 				set uath ""
   4428 				regsub -all {%SPACE} $ssh_host " " uath
   4429 				regsub -all {%TAB} $uath "	" uath
   4430 				append plink_str "$pw \"$uath\""
   4431 			} else {
   4432 				append plink_str "$pw $ssh_host"
   4433 			}
   4434 
   4435 			if {$pw != ""} {
   4436 				puts $fh "echo off"
   4437 			}
   4438 			puts $fh $plink_str
   4439 
   4440 			bat_sleep $fh
   4441 			if {![info exists env(SSVNC_NO_DELETE)]} {
   4442 				if {$file_pre_cmd != ""} {
   4443 					puts $fh "del $file_pre_cmd"
   4444 				}
   4445 				puts $fh "del $file_pre"
   4446 			}
   4447 			close $fh
   4448 		}
   4449 	}
   4450 
   4451 	if {$is_win9x} {
   4452 		set sleep 35
   4453 	} else {
   4454 		set sleep 20
   4455 	}
   4456 	if {$use_listen} {
   4457 		set sleep 1800
   4458 	}
   4459 
   4460 	set setup_cmds [ugly_setup_scripts post $tag]
   4461 
   4462 	set do_shell 0
   4463 	if {$sshcmd == "SHELL"} {
   4464 		set setup_cmds ""
   4465 		set sshcmd {$SHELL}
   4466 		set do_shell 1
   4467 	} elseif {$sshcmd == "PUTTY"} {
   4468 		set setup_cmds ""
   4469 		set do_shell 1
   4470 	}
   4471 
   4472 	if {$sshcmd != "SHELL" && [regexp -nocase {x11vnc} $sshcmd]} {
   4473 		global use_cups cups_x11vnc cups_remote_port
   4474 		global cups_remote_smb_port
   4475 		global use_sound sound_daemon_x11vnc sound_daemon_remote_port
   4476 		global ts_only
   4477 		if {$ts_only} {
   4478 			set cups_x11vnc 1
   4479 			set sound_daemon_x11vnc 1
   4480 		}
   4481 		if {$use_cups && $cups_x11vnc && $cups_remote_port != ""} {
   4482 			set crp $cups_remote_port
   4483 			if {$ts_only} {
   4484 				set cups_remote_port [rand_port]
   4485 				set crp "DAEMON-$cups_remote_port"
   4486 			}
   4487 			set sshcmd "$sshcmd -env FD_CUPS=$crp"
   4488 		}
   4489 		if {$use_cups && $cups_x11vnc && $cups_remote_smb_port != ""} {
   4490 			set csp $cups_remote_smb_port
   4491 			if {$ts_only} {
   4492 				set cups_remote_smb_port [rand_port]
   4493 				set csp "DAEMON-$cups_remote_smb_port"
   4494 			}
   4495 			set sshcmd "$sshcmd -env FD_SMB=$csp"
   4496 		}
   4497 		if {$use_sound && $sound_daemon_x11vnc && $sound_daemon_remote_port != ""} {
   4498 			set srp $sound_daemon_remote_port
   4499 			if {$ts_only} {
   4500 				set sound_daemon_remote_port [rand_port]
   4501 				set srp "DAEMON-$sound_daemon_remote_port"
   4502 			}
   4503 			set sshcmd "$sshcmd -env FD_ESD=$srp"
   4504 		}
   4505 	}
   4506 
   4507 	set file_cmd ""
   4508 	if {$setup_cmds != ""} {
   4509 		# VF
   4510 		regsub {\.bat} $file ".cmd" file_cmd
   4511 		set fh_cmd [open $file_cmd "w"]
   4512 
   4513 		set str $setup_cmds
   4514 		if {$sshcmd != ""} {
   4515 			append str " $sshcmd; "
   4516 		} else {
   4517 			append str " sleep $sleep; "
   4518 		}
   4519 		puts $fh_cmd $str
   4520 		bat_sleep $fh_cmd
   4521 		close $fh_cmd
   4522 
   4523 		set sshcmd $setup_cmds
   4524 	}
   4525 
   4526 	if {$sshcmd == ""} {
   4527 		set pcmd "echo; echo SSH connected OK.; echo If this state is not autodetected,; echo Go Click the Success button."
   4528 		set sshcmd "$pcmd; sleep $sleep"
   4529 	}
   4530 
   4531 	global use_sound sound_daemon_local_cmd sound_daemon_local_start
   4532 	if {! $do_shell && ! $is_win9x && $use_sound && $sound_daemon_local_start && $sound_daemon_local_cmd != ""} {
   4533 		windows_start_sound_daemon $file
   4534 	}
   4535 
   4536 	# VF
   4537 	set fh [open $file "w"]
   4538 	if {$is_win9x} {
   4539 		puts $fh "cd $pwd"
   4540 		if {$file_pre != ""} {
   4541 			puts $fh "echo Press Ctrl-C --HERE-- when done with the Pre-Command shell work."
   4542 			puts $fh "start /w command.com /c $file_pre"
   4543 		}
   4544 	}
   4545 
   4546 	global use_cups use_smbmnt
   4547 	set extra_redirs ""
   4548 	if {$use_cups} {
   4549 		append extra_redirs [get_cups_redir]
   4550 	}
   4551 	if {$use_sound} {
   4552 		append extra_redirs [get_sound_redir]
   4553 	}
   4554 	global additional_port_redirs
   4555 	if {$additional_port_redirs} {
   4556 		append extra_redirs [get_additional_redir]
   4557 	}
   4558 
   4559 	if {$vnc_host == ""} {
   4560 		set vnc_host $win_localhost
   4561 	}
   4562 	regsub {^.*@} $vnc_host "" vnc_host
   4563 
   4564 	set redir "-L $use:$vnc_host:$vnc_port"
   4565 	if {$use_listen} {
   4566 		set redir "-R $vnc_port:$vnc_host:$use"
   4567 		set listening_name "localhost:$vnc_port  (on remote SSH side)"
   4568 	}
   4569 
   4570 	set plink_str "plink.exe -ssh -P $ssh_port $verb $redir $extra_redirs -t"
   4571 	if {$putty_args != ""} {
   4572 		append plink_str " $putty_args"
   4573 	}
   4574 	if {$extra_redirs != ""} {
   4575 		regsub {exe} $plink_str "exe -C" plink_str
   4576 	} else {
   4577 		# hmm we used to have it off... why?
   4578 		# ssh typing response?
   4579 		regsub {exe} $plink_str "exe -C" plink_str
   4580 	}
   4581 	set uath $ssh_host
   4582 	if [regexp {%} $uath] {
   4583 		regsub -all {%SPACE} $uath " " uath
   4584 		regsub -all {%TAB} $uath "	" uath
   4585 		set uath "\"$uath\""
   4586 	}
   4587 	if {$do_shell} {
   4588 		if {$sshcmd == "PUTTY"} {
   4589 		    if [regexp {^".*@} $uath] { #"
   4590 			    regsub {@} $uath {" "} uath
   4591 			    set uath "-l $uath"
   4592 		    }
   4593 		    if {$is_win9x} {
   4594 			set plink_str "putty.exe -ssh -C -P $ssh_port $extra_redirs $putty_args -t $pw $uath"
   4595 		    } else {
   4596 			set plink_str "start \"putty $ssh_host\" putty.exe -ssh -C -P $ssh_port $extra_redirs $putty_args -t $pw $uath"
   4597 			if [regexp {FINISH} $port_knocking_list] {
   4598 				regsub {start} $plink_str "start /wait" plink_str
   4599 			}
   4600 		    }
   4601 		} else {
   4602 			set plink_str "plink.exe -ssh -C -P $ssh_port $extra_redirs $putty_args -t $pw $uath"
   4603 			append plink_str { "$SHELL"}
   4604 		}
   4605 	} elseif {$file_cmd != ""} {
   4606 		append plink_str " -m $file_cmd$pw $uath"
   4607 	} else {
   4608 		append plink_str "$pw $uath \"$sshcmd\""
   4609 	}
   4610 
   4611 	if {$pw != ""} {
   4612 		puts $fh "echo off"
   4613 	}
   4614 	if {$ts_only && [regexp {sudo } $sshcmd]} {
   4615 		puts $fh "echo \" \""
   4616 		puts $fh "echo \"Doing Initial SSH with sudo id to prime sudo...\""
   4617 		puts $fh "echo \" \""
   4618 		puts $fh "plink.exe -ssh $putty_args -t $uath \"sudo id; tty\""
   4619 		puts $fh "echo \" \""
   4620 	}
   4621 	puts $fh $plink_str
   4622 	bat_sleep $fh
   4623 	puts $fh "del $flag"
   4624 	if {![info exists env(SSVNC_NO_DELETE)]} {
   4625 		if {$file_cmd != ""} {
   4626 			puts $fh "del $file_cmd"
   4627 		}
   4628 		puts $fh "del $file"
   4629 	}
   4630 	close $fh
   4631 
   4632 	catch {destroy .o}
   4633 	catch {destroy .oa}
   4634 	catch {destroy .os}
   4635 
   4636 	if { ![do_port_knock $ssh_host start]} {
   4637 		if {![info exists env(SSVNC_NO_DELETE)]} {
   4638 			catch {file delete $file}
   4639 			if {$file_cmd != ""} {
   4640 				catch {file delete $file_cmd}
   4641 			}
   4642 			if {$file_pre != ""} {
   4643 				catch {file delete $file_pre}
   4644 			}
   4645 		}
   4646 		winkill $ssh_ipv6_pid
   4647 		set ssh_ipv6_pid ""
   4648 		return 0
   4649 	}
   4650 
   4651 	if {$double_ssh != ""} {
   4652 		set plink_str_double_ssh "plink.exe -ssh $putty_args -t $pw $double_ssh \"echo sleep 60 ...; sleep 60; echo done.\""
   4653 
   4654 		# VF
   4655 		regsub {\.bat} $file "dob.bat" file_double
   4656 		set fhdouble [open $file_double "w"]
   4657 		puts $fhdouble $plink_str_double_ssh
   4658 		bat_sleep $fhdouble
   4659 		puts $fhdouble "del $flag"
   4660 		if {![info exists env(SSVNC_NO_DELETE)]} {
   4661 			puts $fhdouble "del $file_double"
   4662 		}
   4663 		close $fhdouble
   4664 
   4665 		set com "cmd.exe"
   4666 		if [info exists env(COMSPEC)] {
   4667 			set com $env(COMSPEC)
   4668 		}
   4669 
   4670 		set ff [open $flag "w"]
   4671 		puts $ff "flag"
   4672 		close $ff
   4673 
   4674 		global env
   4675 		if [info exists env(SSVNC_BAT_SLEEP)] {
   4676 			exec $com /c start $com /c $file_double &
   4677 		} else {
   4678 			exec $com /c $file_double &
   4679 		}
   4680 
   4681 		set waited 0
   4682 		set gotit 0
   4683 		while {$waited < 30000} {
   4684 			after 500
   4685 			update
   4686 			if {$use_listen} {
   4687 				set gotit 1
   4688 				break;
   4689 			}
   4690 			set ns [get_netstat]
   4691 			set re ":$p_port"
   4692 			check_debug_netstat $p_port $ns $waited
   4693 			append re {[ 	][ 	]*[0:.][0:.]*[ 	][ 	]*LISTEN}
   4694 			if [regexp $re $ns] {
   4695 				set gotit 1
   4696 				break
   4697 			}
   4698 			set waited [expr "$waited + 500"]
   4699 			if {![file exists $flag]} {
   4700 				break
   4701 			}
   4702 		}
   4703 		catch {file delete $flag}
   4704 		if {! $gotit} {
   4705 			after 5000
   4706 		}
   4707 	}
   4708 
   4709 	vencrypt_tutorial_mesg
   4710 
   4711 	set wdraw 1
   4712 	#set wdraw 0
   4713 	if [info exists debug_netstat] {
   4714 		if {$debug_netstat != "" && $debug_netstat != "0"} {
   4715 			set wdraw 0
   4716 		}
   4717 	}
   4718 
   4719 	set ff [open $flag "w"]
   4720 	puts $ff "flag"
   4721 	close $ff
   4722 
   4723 	if {$is_win9x} {
   4724 		if {$wdraw} {
   4725 			wm withdraw .
   4726 		}
   4727 		update
   4728 		win9x_plink_msg $file
   4729 		global win9x_plink_msg_done
   4730 		set win9x_plink_msg_done 0
   4731 		vwait win9x_plink_msg_done
   4732 	} else {
   4733 		set com "cmd.exe"
   4734 		if [info exists env(COMSPEC)] {
   4735 			set com $env(COMSPEC)
   4736 		}
   4737 
   4738 		if {$file_pre != ""} {
   4739 			set sl 0
   4740 			if {$use_smbmnt}  {
   4741 				global smb_su_mode
   4742 				if {$smb_su_mode == "su"} {
   4743 					set sl [expr $sl + 15]
   4744 				} elseif {$smb_su_mode == "sudo"} {
   4745 					set sl [expr $sl + 15]
   4746 				} else {
   4747 					set sl [expr $sl + 3]
   4748 				}
   4749 			}
   4750 			if {$pw == ""} {
   4751 				set sl [expr $sl + 5]
   4752 			}
   4753 
   4754 			set sl [expr $sl + 5]
   4755 			set st [clock seconds]
   4756 			set dt 0
   4757 			global entered_gui_top button_gui_top
   4758 			set entered_gui_top 0
   4759 			set button_gui_top 0
   4760 
   4761 			catch {wm geometry . "-40-40"}
   4762 			catch {wm withdraw .; update; wm deiconify .; raise .; update}
   4763 			mesg "Click on *This* Label when done with 1st SSH 0/$sl"
   4764 			after 600
   4765 
   4766 			global env
   4767 			if [info exists env(SSVNC_BAT_SLEEP)] {
   4768 				exec $com /c start $com /c $file_pre &
   4769 			} else {
   4770 				exec $com /c $file_pre &
   4771 			}
   4772 
   4773 			catch {lower .; update; raise .; update}
   4774 
   4775 			while {$dt < $sl} {
   4776 				after 100
   4777 				set dt [clock seconds]
   4778 				set dt [expr $dt - $st]
   4779 				mesg "Click on *This* Label when done with 1st SSH $dt/$sl"
   4780 				update
   4781 				update idletasks
   4782 				if {$dt <= 1} {
   4783 					set button_gui_top 0
   4784 				}
   4785 				if {$button_gui_top != 0 && $dt >= 3} {
   4786 					mesg "Running 2nd SSH now ..."
   4787 					after 1000
   4788 					break
   4789 				}
   4790 			}
   4791 			mesg "Running 2nd SSH ..."
   4792 		}
   4793 
   4794 		if {! $do_shell} {
   4795 			make_plink
   4796 		}
   4797 		if {$wdraw} {
   4798 			wm withdraw .
   4799 		}
   4800 
   4801 		update
   4802 		if {$do_shell && [regexp {FINISH} $port_knocking_list]} {
   4803 			catch {exec $com /c $file}
   4804 		} else {
   4805 			global env
   4806 			if [info exists env(SSVNC_BAT_SLEEP)] {
   4807 				exec $com /c start $com /c $file &
   4808 			} else {
   4809 				exec $com /c $file &
   4810 			}
   4811 		}
   4812 		after 1000
   4813 	}
   4814 
   4815 	if {$do_shell} {
   4816 		wm deiconify .
   4817 		update
   4818 		if {[regexp {FINISH} $port_knocking_list]} {
   4819 			do_port_knock $ssh_host finish
   4820 		}
   4821 		return 1
   4822 	}
   4823 	set made_plink 0
   4824 	if {$is_win9x} {
   4825 		make_plink
   4826 		set made_plink 1
   4827 	}
   4828 	global plink_status
   4829 	set plink_status ""
   4830 	set waited 0
   4831 	set cnt 0
   4832 	while {$waited < 30000} {
   4833 		after 500
   4834 		update
   4835 		if {$use_listen} {
   4836 			set plink_status yes
   4837 			break;
   4838 		}
   4839 		set ns [get_netstat]
   4840 		set re ":$use"
   4841 		check_debug_netstat $use $ns $waited
   4842 		append re {[ 	][ 	]*[0:.][0:.]*[ 	][ 	]*LISTEN}
   4843 		if [regexp $re $ns] {
   4844 			set plink_status yes
   4845 		}
   4846 		if {$plink_status != ""} {
   4847 			catch {destroy .plink}
   4848 			break
   4849 		}
   4850 
   4851 		if {$waited == 0} {
   4852 			#wm deiconify .plink
   4853 		}
   4854 		set waited [expr "$waited + 500"]
   4855 
   4856 		incr cnt
   4857 		if {$cnt >= 12} {
   4858 			set cnt 0
   4859 		}
   4860 		if {![file exists $flag]} {
   4861 			set plink_status flag_gone
   4862 			break
   4863 		}
   4864 	}
   4865 	catch {file delete $flag}
   4866 	if {$plink_status == ""} {
   4867 		if {! $made_plink} {
   4868 			make_plink
   4869 			set made_plink 1
   4870 		}
   4871 		vwait plink_status
   4872 	}
   4873 
   4874 	if {$use_sshssl} {
   4875 		global launch_windows_ssh_files
   4876 		if {$file != ""} {
   4877 			append launch_windows_ssh_files "$file "
   4878 		}
   4879 		if {$file_pre != ""} {
   4880 			append launch_windows_ssh_files "$file_pre "
   4881 		}
   4882 		if {$file_pre_cmd != ""} {
   4883 			append launch_windows_ssh_files "$file_pre_cmd "
   4884 		}
   4885 		regsub { *$} $launch_windows_ssh_files "" launch_windows_ssh_files
   4886 		return 1
   4887 	}
   4888 
   4889 	if {$plink_status != "yes"} {
   4890 		set m "unknown"
   4891 		if {$plink_status == "flag_gone"} {
   4892 			set m "plink script failed"
   4893 		} elseif {$plink_status == ""} {
   4894 			set m "timeout"
   4895 		}
   4896 		mesg "Error ($m) to $hp"
   4897 		wm deiconify .
   4898 	} else {
   4899 		after 1000
   4900 		do_viewer_windows $n
   4901 		wm deiconify .
   4902 		mesg "Disconnected from $hp"
   4903 	}
   4904 	update
   4905 	if [regexp {FINISH} $port_knocking_list] {
   4906 		do_port_knock $ssh_host finish
   4907 	}
   4908 
   4909 	if {![info exists env(SSVNC_NO_DELETE)]} {
   4910 		if {$file != ""} {
   4911 			catch {file delete $file}
   4912 		}
   4913 		if {$file_pre != ""} {
   4914 			catch {file delete $file_pre}
   4915 		}
   4916 		if {$file_pre_cmd != ""} {
   4917 			catch {file delete $file_pre_cmd}
   4918 		}
   4919 		if {$file_double != ""} {
   4920 			catch {file delete $file_double}
   4921 		}
   4922 	}
   4923 
   4924 	winkill $ssh_ipv6_pid
   4925 	set ssh_ipv6_pid ""
   4926 
   4927 	global sound_daemon_local_kill
   4928 	if {! $is_win9x && $use_sound && $sound_daemon_local_kill && $sound_daemon_local_cmd != ""} {
   4929 		windows_stop_sound_daemon
   4930 	}
   4931 	return 1
   4932 }
   4933 
   4934 proc check_ssh_needed {} {
   4935 	globalize
   4936 
   4937 	if {$use_ssh || $use_sshssl} {
   4938 		return
   4939 	}
   4940 	set must_cups 0
   4941 	set must_snd 0
   4942 	set must_smb 0
   4943 	set must_addl 0
   4944 	if {$use_cups} {
   4945 		if {$cups_local_server != ""} {set must_cups 1}
   4946 		if {$cups_remote_port != ""} {set must_cups 1}
   4947 		if {$cups_local_smb_server != ""} {set must_cups 1}
   4948 		if {$cups_remote_smb_port != ""} {set must_cups 1}
   4949 		if {$cups_manage_rcfile != ""} {set must_cups 1}
   4950 	}
   4951 	if {$use_sound} {
   4952 		if {$sound_daemon_remote_cmd != ""} {set must_snd 1}
   4953 		if {$sound_daemon_remote_port != ""} {set must_snd 1}
   4954 		if {$sound_daemon_kill} {set must_snd 1}
   4955 		if {$sound_daemon_restart} {set must_snd 1}
   4956 		if {$sound_daemon_local_cmd != ""} {set must_snd 1}
   4957 		if {$sound_daemon_local_port != ""} {set must_snd 1}
   4958 		if {$sound_daemon_local_kill} {set must_snd 1}
   4959 		if {$sound_daemon_local_start} {set must_snd 1}
   4960 	}
   4961 	if {$use_smbmnt} {
   4962 		if {[regexp {//} $smb_mount_list]} {set must_smb 1}
   4963 	}
   4964 	if {$additional_port_redirs} {
   4965 		set must_addl 1
   4966 	}
   4967 	if {$must_cups || $must_snd || $must_smb || $must_addl} {
   4968 		mesg "Cannot do Port redirs in non-SSH mode (SSL)"
   4969 		set msg ""
   4970 		if {$must_smb} {
   4971 			append msg "  - SMB Mount Port Redirection\n"
   4972 		}
   4973 		if {$must_snd} {
   4974 			append msg "  - ESD Sound Port Redirection\n"
   4975 		}
   4976 		if {$must_cups} {
   4977 			append msg "  - CUPS Port Redirection\n"
   4978 		}
   4979 		if {$must_addl} {
   4980 			append msg "  - Additional Port Redirections\n"
   4981 		}
   4982                 set msg "\"Use SSL\" mode selected (no SSH)\nThe following options will be disabled:\n\n$msg"
   4983 		bell
   4984 		update
   4985 		raise .
   4986                 tk_messageBox -type ok -icon info -message $msg
   4987 	}
   4988 }
   4989 
   4990 proc set_smb_mounts {} {
   4991 	global smb_redir_0 smb_mounts use_smbmnt
   4992 
   4993 	set smb_redir_0 ""
   4994 	set smb_mounts ""
   4995 	if {$use_smbmnt} {
   4996 		set l2 [get_smb_redir]
   4997 		set smb_redir_0 [lindex $l2 0]
   4998 		set smb_redir_0 [string trim $smb_redir_0]
   4999 		set smb_mounts  [lindex $l2 1]
   5000 	}
   5001 }
   5002 
   5003 proc mytmp {tmp} {
   5004 	global is_windows mktemp env
   5005 
   5006 	if {$is_windows} {
   5007 		return $tmp
   5008 	}
   5009 
   5010 	if {! [info exists mktemp]} {
   5011 		set mktemp ""
   5012 		foreach dir {/bin /usr/bin /usr/local/bin} {
   5013 			if [file exists "$dir/mktemp"] {
   5014 				set mktemp "$dir/mktemp"
   5015 				break
   5016 			}
   5017 		}
   5018 	}
   5019 	if {$mktemp != ""} {
   5020 		set tmp2 ""
   5021 		catch {set tmp2 [exec $mktemp "$tmp.XXXXXX"]}
   5022 		if [file exists $tmp2] {
   5023 			if [info exists env(DEBUG_MKTEMP)] {
   5024 				puts stderr "mytmp: $tmp2"
   5025 			}
   5026 			return $tmp2
   5027 		}
   5028 	}
   5029 	catch {exec rm -f $tmp}
   5030 	catch {file delete $tmp}
   5031 	if [file exists $tmp] {
   5032 		puts stderr "tmp file still exists: $tmp"
   5033 		exit 1
   5034 	}
   5035 	catch {exec touch $tmp}
   5036 	catch {exec chmod 600 $tmp}
   5037 	if [info exists env(DEBUG_MKTEMP)] {
   5038 		puts stderr "mytmp: $tmp"
   5039 	}
   5040 	return $tmp
   5041 }
   5042 
   5043 proc darwin_terminal_cmd {{title ""} {cmd ""} {bg 0}} {
   5044 	global darwin_terminal
   5045 
   5046 	set tries ""
   5047 	lappend tries "/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal"
   5048 
   5049 	if {! [info exists darwin_terminal]} {
   5050 		foreach try $tries {
   5051 			if [file exists $try] {
   5052 				if [file executable $try] {
   5053 					set darwin_terminal $try
   5054 					break
   5055 				}
   5056 			}
   5057 		}
   5058 		if {! [info exists darwin_terminal]} {
   5059 			set fh ""
   5060 			catch {set fh [open "| find /Applications -type f -name Terminal" "r"]}
   5061 			if {$fh != ""} {
   5062 				while {[gets $fh line] > -1} {
   5063 					if {! [file exists $line]} {
   5064 						continue
   5065 					}
   5066 					if {[file isdirectory $line]} {
   5067 						continue
   5068 					}
   5069 					if {! [regexp {/Terminal$} $line]} {
   5070 						continue
   5071 					}
   5072 					if {! [file executable $line]} {
   5073 						continue
   5074 					}
   5075 					set darwin_terminal $line
   5076 					break
   5077 				}
   5078 				close $fh
   5079 			}
   5080 		}
   5081 	}
   5082 	if {! [info exists darwin_terminal]} {
   5083 		raise .
   5084 		tk_messageBox -type ok -icon error -message "Cannot find Darwin Terminal program." -title "Cannot find Terminal program"
   5085 		mac_raise
   5086 		return
   5087 	}
   5088 
   5089 	global darwin_terminal_cnt
   5090 	set tmp /tmp/darwin_terminal_cmd.[tpid]
   5091 	if {! [info exists darwin_terminal_cnt]} {
   5092 		set darwin_terminal_cnt 0
   5093 	}
   5094 	incr darwin_terminal_cnt
   5095 	append tmp ".$darwin_terminal_cnt"
   5096 	set tmp [mytmp $tmp]
   5097 
   5098 	set fh ""
   5099 	catch {set fh [open $tmp w 0755]}
   5100 	catch {[exec chmod 755 $tmp]}
   5101 	if {$fh == ""} {
   5102 		raise .
   5103 		tk_messageBox -type ok -icon error -message "Cannot open temporary file: $tmp" -title "Cannot open file"
   5104 		mac_raise
   5105 		return
   5106 	}
   5107 	global env
   5108 	puts $fh "#!/bin/sh"
   5109 	puts $fh "PATH=$env(PATH)"
   5110 	puts $fh "export PATH"
   5111 	puts $fh "tmp=$tmp"
   5112 	puts $fh "sleep 1"
   5113 	puts $fh {if [ "X$DDDBG" != "X" ]; then ps www; fi}
   5114 	puts $fh {termpid=`ps www | grep -w Terminal | grep $tmp | grep -v grep | awk '{print $1}' | sort -n | tail -1`}
   5115 	puts $fh {echo try-1: termpid=$termpid mypid=$$}
   5116 	puts $fh {if [ "X$termpid" = "X" ]; then}
   5117 	puts $fh {	termpid=`ps www | grep -w Terminal | grep -v grep | awk '{print $1}' | sort -n | tail -1`}
   5118 	puts $fh {	echo try-2: termpid=$termpid mypid=$$}
   5119 	puts $fh {fi}
   5120 	puts $fh {if [ "X$termpid" = "X" ]; then}
   5121 	puts $fh {	termpid=`ps wwwwaux | grep -w Terminal | grep $tmp | grep -v grep | awk '{print $2}' | sort -n | tail -1`}
   5122 	puts $fh {	echo try-3: termpid=$termpid mypid=$$}
   5123 	puts $fh {fi}
   5124 	puts $fh {if [ "X$termpid" = "X" ]; then}
   5125 	puts $fh {	termpid=$$}
   5126 	puts $fh {	echo termpid-find-fail: termpid=$termpid mypid=$$}
   5127 	puts $fh {fi}
   5128 	puts $fh {trap "rm -f $tmp; kill -TERM $termpid; kill -TERM $mypid; kill -KILL $mypid; exit 0" 0 2 15}
   5129 	puts $fh {osascript -e 'tell application "Terminal" to activate' >/dev/null 2>&1 &}
   5130 	puts $fh "$cmd"
   5131 	puts $fh "sleep 1"
   5132 	puts $fh {rm -f $tmp}
   5133 	puts $fh {kill -TERM $termpid}
   5134 	puts $fh {kill -TERM $mypid}
   5135 	puts $fh {kill -KILL $mypid}
   5136 	puts $fh "exit 0"
   5137 	close $fh
   5138 	if {$bg} {
   5139 		catch {exec $darwin_terminal $tmp &}
   5140 	} else {
   5141 		catch {exec $darwin_terminal $tmp}
   5142 	}
   5143 }
   5144 
   5145 proc unix_terminal_cmd {{geometry "+100+100"} {title "xterm-command"} {cmd "echo test"} {bg 0} {xrm1 ""} {xrm2 ""} {xrm3 ""}} {
   5146 	global uname env
   5147 	if {$uname == "Darwin"} {
   5148 		global env
   5149 		set doX  0;
   5150 		if {! $doX} {
   5151 			darwin_terminal_cmd $title $cmd $bg
   5152 			return
   5153 		}
   5154 	}
   5155 
   5156 	global checked_for_xterm
   5157 	if {![info exists checked_for_xterm]} {
   5158 		set p ""
   5159 		set r [catch {set p [exec /bin/sh -c {type xterm}]}]
   5160 		set checked_for_xterm 1
   5161 		if {$r != 0} {
   5162 			set p [exec /bin/sh -c {type xterm 2>&1; exit 0}]
   5163 			set txt "Problem finding the 'xterm' command:\n\n$p\n\n"
   5164 			append txt "Perhaps you need to install a package containing 'xterm'  (Sigh...)\n\n"
   5165 			fetch_dialog $txt "xterm" "xterm" 0 [line_count $txt]
   5166 			update
   5167 			after 1000
   5168 			catch {tkwait window .fetch}
   5169 			update
   5170 		}
   5171 	}
   5172 
   5173 	if [info exists env(SSVNC_XTERM_REPLACEMENT)] {
   5174 		set tcmd $env(SSVNC_XTERM_REPLACEMENT)
   5175 		if {$tcmd != ""} {
   5176 			regsub -all {%GEOMETRY} $tcmd $geometry tcmd
   5177 			regsub -all {%TITLE} $tcmd $title tcmd
   5178 
   5179 			set tmp1 /tmp/xterm_replacement1.[tpid]
   5180 			set tmp1 [mytmp $tmp1]
   5181 			set fh1 ""
   5182 			catch {set fh1 [open $tmp1 "w"]}
   5183 
   5184 			set tmp2 /tmp/xterm_replacement2.[tpid]
   5185 			set tmp2 [mytmp $tmp2]
   5186 			set fh2 ""
   5187 			catch {set fh2 [open $tmp2 "w"]}
   5188 			if {$fh1 != "" && $fh2 != ""} {
   5189 				puts $fh1 "#!/bin/sh";
   5190 				puts $fh1 "$cmd"
   5191 				puts $fh1 "rm -f $tmp1"
   5192 				close $fh1
   5193 				catch {exec chmod 755 $tmp1}
   5194 				puts $fh2 "#!/bin/sh"
   5195 				puts $fh2 "$tcmd $tmp1"
   5196 				puts $fh2 "rm -f $tmp2"
   5197 				close $fh2
   5198 				catch {exec chmod 755 $tmp2}
   5199 				if {$bg} {
   5200 					exec $tmp2 2>@stdout &
   5201 				} else {
   5202 					exec $tmp2 2>@stdout
   5203 				}
   5204 				return
   5205 			}
   5206 			catch {close $fh1}
   5207 			catch {close $fh2}
   5208 		}
   5209 	}
   5210 
   5211 	if {$bg} {
   5212 		if {$xrm1 == ""} {
   5213 			exec xterm -sb -sl 2000 -geometry "$geometry" -title "$title" -e sh -c "$cmd" 2>@stdout &
   5214 		} else {
   5215 			exec xterm -sb -sl 2000 -geometry "$geometry" -title "$title" -xrm "$xrm1" -xrm "$xrm2" -xrm "$xrm3" -e sh -c "$cmd" 2>@stdout &
   5216 		}
   5217 	} else {
   5218 		if {$xrm1 == ""} {
   5219 			exec xterm -sb -sl 2000 -geometry "$geometry" -title "$title" -e sh -c "$cmd" 2>@stdout
   5220 		} else {
   5221 			exec xterm -sb -sl 2000 -geometry "$geometry" -title "$title" -xrm "$xrm1" -xrm "$xrm2" -xrm "$xrm3" -e sh -c "$cmd" 2>@stdout
   5222 		}
   5223 	}
   5224 }
   5225 
   5226 proc xterm_center_geometry {} {
   5227 	set sh [winfo screenheight .]
   5228 	set sw [winfo screenwidth .]
   5229 	set gw 500
   5230 	set gh 300
   5231 	set x [expr $sw/2 - $gw/2]
   5232 	set y [expr $sh/2 - $gh/2]
   5233 	if {$x < 0} {
   5234 		set x 10
   5235 	}
   5236 	if {$y < 0} {
   5237 		set y 10
   5238 	}
   5239 
   5240 	return "+$x+$y"
   5241 }
   5242 
   5243 proc smbmnt_wait {tee} {
   5244 	if {$tee != ""} {
   5245 		set start [clock seconds]
   5246 		set cut 30
   5247 		while {1} {
   5248 			set now [clock seconds]
   5249 			if {$now > $start + $cut} {
   5250 				break;
   5251 			}
   5252 			if [file exists $tee] {
   5253 				set sz 0
   5254 				catch {set sz [file size $tee]}
   5255 				if {$sz > 50} {
   5256 					set cut 50
   5257 				}
   5258 			}
   5259 			set g ""
   5260 			catch {set g [exec grep main-vnc-helper-finished $tee]}
   5261 			if [regexp {main-vnc-helper-finished} $g] {
   5262 				break
   5263 			}
   5264 			after 1000
   5265 		}
   5266 		catch {file delete $tee}
   5267 	} else {
   5268 		global smb_su_mode
   5269 		if {$smb_su_mode == "su"} {
   5270 			after 15000
   5271 		} elseif {$smb_su_mode == "sudo"} {
   5272 			after 10000
   5273 		}
   5274 	}
   5275 }
   5276 
   5277 proc do_unix_pre {tag proxy hp pk_hp}  {
   5278 	global env smb_redir_0 use_smbmnt
   5279 	global did_port_knock
   5280 
   5281 	set setup_cmds [ugly_setup_scripts pre $tag]
   5282 	set c "ss_vncviewer -ssh"
   5283 
   5284 	if {$proxy == ""} {
   5285 		set pxy $hp
   5286 		regsub {:[0-9][0-9]*$} $pxy "" pxy
   5287 		set c "$c -proxy '$pxy'"
   5288 	} else {
   5289 		set c "$c -proxy '$proxy'"
   5290 	}
   5291 
   5292 	if {$setup_cmds != ""} {
   5293 		set env(SS_VNCVIEWER_SSH_CMD) "$setup_cmds sleep 10"
   5294 		set env(SS_VNCVIEWER_SSH_ONLY) 1
   5295 		if {$smb_redir_0 != ""} {
   5296 			set c "$c -sshargs '$smb_redir_0'"
   5297 		}
   5298 
   5299 		if {! [do_port_knock $pk_hp start]} {
   5300 			return
   5301 		}
   5302 		set did_port_knock 1
   5303 
   5304 		if {$use_smbmnt} {
   5305 			set title "SSL/SSH VNC Viewer $hp -- SMB MOUNTS"
   5306 		} else {
   5307 			set title "SSL/SSH VNC Viewer $hp -- Pre Commands"
   5308 		}
   5309 
   5310 		set tee ""
   5311 		if {$use_smbmnt} {
   5312 			set tee $env(SSVNC_HOME)
   5313 			append tee "/.tee-etv$tag"
   5314 			set fh ""
   5315 			catch {set fh [open $tee "w"]}
   5316 			if {$fh == ""} {
   5317 				set tee ""
   5318 			} else {
   5319 				close $fh
   5320 				set c "$c | tee $tee"
   5321 			}
   5322 		}
   5323 
   5324 		unix_terminal_cmd "80x25+100+100" "$title" "set -xv; $c" 1
   5325 
   5326 		set env(SS_VNCVIEWER_SSH_CMD) ""
   5327 		set env(SS_VNCVIEWER_SSH_ONLY) ""
   5328 
   5329 		if {$use_smbmnt} {
   5330 			smbmnt_wait $tee
   5331 		} else {
   5332 			after 2000
   5333 		}
   5334 	}
   5335 }
   5336 proc init_vncdisplay {} {
   5337 	global vncdisplay vncproxy remote_ssh_cmd
   5338 	set vncdisplay [string trim $vncdisplay]
   5339 
   5340 	if {$vncdisplay == ""} {
   5341 		set vncproxy ""
   5342 		set remote_ssh_cmd ""
   5343 		return
   5344 	}
   5345 
   5346 	set hpnew  [get_ssh_hp $vncdisplay]
   5347 	set proxy  [get_ssh_proxy $vncdisplay]
   5348 	set sshcmd [get_ssh_cmd $vncdisplay]
   5349 
   5350 	set vncdisplay $hpnew
   5351 	set vncproxy $proxy
   5352 	set remote_ssh_cmd $sshcmd
   5353 
   5354 	global ssh_only ts_only
   5355 	if {$sshcmd != "" || $ssh_only || $ts_only} {
   5356 		global use_ssl use_ssh use_sshssl
   5357 		set use_ssl 0
   5358 		if {! $use_ssh && ! $use_sshssl} {
   5359 			set use_ssh 1
   5360 		}
   5361 	}
   5362 	# ssl_ssh_adjust will be called.
   5363 }
   5364 
   5365 proc get_vncdisplay {} {
   5366 	global vncdisplay vncproxy remote_ssh_cmd
   5367 	set vncdisplay [string trim $vncdisplay]
   5368 
   5369 	set t $vncdisplay
   5370 	regsub {[ \t]*cmd=.*$} $t "" t
   5371 	set t [string trim $t]
   5372 
   5373 	set str ""
   5374 	if [regexp {[ \t]} $t] {
   5375 		set str $t
   5376 	} else {
   5377 		if {$vncproxy != "" && $t == ""} {
   5378 			set str "--nohost-- $vncproxy"
   5379 		} else {
   5380 			set str "$t $vncproxy"
   5381 		}
   5382 	}
   5383 	if [regexp {cmd=.*$} $vncdisplay match] {
   5384 		if {$str == ""} {
   5385 			set str "--nohost--"
   5386 		}
   5387 		set str "$str $match"
   5388 	} else {
   5389 		if {$remote_ssh_cmd != ""} {
   5390 			if {$str == ""} {
   5391 				set str "--nohost--"
   5392 			}
   5393 			set str "$str cmd=$remote_ssh_cmd"
   5394 		}
   5395 	}
   5396 	set str [string trim $str]
   5397 	return $str
   5398 }
   5399 
   5400 proc port_knock_only {hp {mode KNOCK}} {
   5401 	if {$hp == ""} {
   5402 		set hp [get_vncdisplay]
   5403 		if {$hp == ""} {
   5404 			mesg "No host port found"
   5405 			bell
   5406 			return
   5407 		}
   5408 	}
   5409 	set hpnew  [get_ssh_hp $hp]
   5410 	set proxy  [get_ssh_proxy $hp]
   5411 	set sshcmd [get_ssh_cmd $hp]
   5412 	set hp $hpnew
   5413 
   5414 	set pk_hp ""
   5415 	if {$proxy != ""} {
   5416 		set pk_hp $proxy
   5417 	}
   5418 	if {$pk_hp == ""} {
   5419 		set pk_hp $hp
   5420 	}
   5421 	if {$mode == "KNOCK"} {
   5422 		do_port_knock $pk_hp start
   5423 	} elseif {$mode == "FINISH"} {
   5424 		do_port_knock $pk_hp finish
   5425 	}
   5426 }
   5427 
   5428 proc direct_connect_msg {} {
   5429 	set msg ""
   5430 	global env
   5431 	globalize
   5432 	if {$use_sshssl} {
   5433 		append msg "  - SSH + SSL tunnelling\n"
   5434 	} elseif {$use_ssh} {
   5435 		append msg "  - SSH tunnelling\n"
   5436 	} else {
   5437 		append msg "  - SSL tunnelling\n"
   5438 	}
   5439 	if [info exists env(SSVNC_NO_ENC_WARN)] {
   5440 		set msg ""
   5441 	}
   5442 	if {$use_smbmnt} {
   5443 		append msg "  - SMB Mount Port Redirection\n"
   5444 	}
   5445 	if {$use_sound} {
   5446 		append msg "  - ESD Sound Port Redirection\n"
   5447 	}
   5448 	if {$use_cups} {
   5449 		append msg "  - CUPS Port Redirection\n"
   5450 	}
   5451 	if {$additional_port_redirs} {
   5452 		append msg "  - Additional Port Redirections\n"
   5453 	}
   5454 	if {$mycert != "" || $svcert != "" || $crtdir != ""} {
   5455 		append msg "  - SSL certificate authentication\n"
   5456 	}
   5457 	if {$msg != ""} {
   5458 		set msg "Direct connect via vnc://hostname\nThe following options will be disabled:\n\n$msg"
   5459 		raise .
   5460 		tk_messageBox -type ok -icon info -message $msg
   5461 	}
   5462 }
   5463 
   5464 proc fetch_cert {save} {
   5465 	global env vncdisplay is_windows
   5466 	set hp [get_vncdisplay]
   5467 
   5468 	global vencrypt_detected
   5469 	set vencrypt_detected ""
   5470 
   5471 	global use_listen
   5472 	if {$use_listen} {
   5473 		if {$is_windows} {
   5474 			mesg "Fetch Cert not enabled for Reverse Connections"
   5475 			bell
   5476 			catch {raise .}
   5477 			mac_raise
   5478 			return
   5479 		}
   5480 		toplev .fcr
   5481 		global help_font
   5482 		wm title .fcr "Fetch Cert for Reverse Connections"
   5483 		global fcr_result
   5484 		set fcr_result 0
   5485 		eval text .fcr.t -width 55 -height 17 $help_font
   5486 		.fcr.t insert end {
   5487    In Reverse VNC Connections (-LISTEN) mode, the
   5488    Fetch Cert operation requires that the Remote
   5489    VNC Server makes an initial connection NOW so
   5490    we can collect its SSL Certificate.  Note that
   5491    this method does not work for VeNCrypt servers.
   5492    (If there are problems Fetching, one can always
   5493    copy and import the Cert file manually.)
   5494 
   5495    Do you want to Continue with this operation?
   5496    If so, press "Continue" and Then instruct the
   5497    remote VNC Server to make a Reverse Connection
   5498    to us.
   5499 
   5500    Otherwise, press "Cancel" to cancel the Fetch
   5501    Cert operation.
   5502 }
   5503 
   5504 		button .fcr.cancel   -text Cancel   -command {set fcr_result 0; destroy .fcr}
   5505 		button .fcr.continue -text Continue -command {set fcr_result 1; destroy .fcr}
   5506 		button .fcr.continu2 -text Continue -command {set fcr_result 1; destroy .fcr}
   5507 		global uname
   5508 		if {$uname == "Darwin"} {
   5509 			pack .fcr.t .fcr.continu2 .fcr.continue .fcr.cancel -side top -fill x
   5510 
   5511 		} else {
   5512 			pack .fcr.t .fcr.continue .fcr.cancel -side top -fill x
   5513 		}
   5514 		center_win .fcr
   5515 
   5516 		tkwait window .fcr
   5517 		update
   5518 		after 50
   5519 
   5520 		if {$fcr_result != 1}  {
   5521 			return
   5522 		}
   5523 		update idletasks
   5524 		after 50
   5525 	}
   5526 
   5527 	regsub {[ 	]*cmd=.*$} $hp "" tt
   5528 	if {[regexp {^[ 	]*$} $tt]} {
   5529 		mesg "No host:disp supplied."
   5530 		bell
   5531 		catch {raise .}
   5532 		mac_raise
   5533 		return
   5534 	}
   5535 	if {[regexp -- {--nohost--} $tt]} {
   5536 		mesg "No host:disp supplied."
   5537 		bell
   5538 		catch {raise .}
   5539 		mac_raise
   5540 		return
   5541 	}
   5542 	if {! [regexp ":" $hp]} {
   5543 		if {! [regexp {cmd=} $hp]} {
   5544 			append hp ":0"
   5545 		}
   5546 	}
   5547 	set hpnew  [get_ssh_hp $hp]
   5548 	set proxy  [get_ssh_proxy $hp]
   5549 
   5550 
   5551 	set pstr 1
   5552 	mesg "Fetching $hpnew Cert..."
   5553 	global cert_text
   5554 	set cert_text ""
   5555 	.f4.getcert configure -state disabled
   5556 	update
   5557 	if {! $is_windows} {
   5558 		catch {set cert_text [fetch_cert_unix $hp]}
   5559 	} else {
   5560 		set cert_text [fetch_cert_windows $hp]
   5561 	}
   5562 
   5563 	if [info exists env(CERTDBG)] {puts "\nFetch-0-\n$cert_text"}
   5564 
   5565 	set vencrypt 0
   5566 	set anondh 0
   5567 	if {![regexp {BEGIN CERTIFICATE} $cert_text]} {
   5568 		if [regexp {CONNECTED} $cert_text] {
   5569 			set m 0
   5570 			if {![regexp -nocase {GET_SERVER_HELLO} $cert_text]} {
   5571 				set m 1
   5572 			}
   5573 			if [regexp -nocase -line {GET_SERVER_HELLO.*unknown protocol} $cert_text] {
   5574 				set m 1
   5575 			}
   5576 			if {![regexp -nocase {show_cert: SSL_connect failed} $cert_text]} {
   5577 				set m 1
   5578 			}
   5579 			if {!$m && $is_windows} {
   5580 				if [regexp -nocase {write:errno} $cert_text] {
   5581 					if [regexp -nocase {no peer certificate} $cert_text] {
   5582 						set m 1
   5583 					}
   5584 				}
   5585 			}
   5586 			if {$m} {
   5587 				# suspect VeNCrypt or ANONTLS plaintext RFB
   5588 				set cert_text ""
   5589 				set vencrypt 1
   5590 				incr pstr
   5591 				mesg "#${pstr} Fetching $hpnew Cert... $vencrypt/$anondh"
   5592 				if {! $is_windows} {
   5593 					catch {set cert_text [fetch_cert_unix    $hp $vencrypt $anondh]}
   5594 				} else {
   5595 					after 600
   5596 					catch {set cert_text [fetch_cert_windows $hp $vencrypt $anondh]}
   5597 				}
   5598 	if [info exists env(CERTDBG)] {puts "\nFetch-1-\n$cert_text"}
   5599 			}
   5600 		}
   5601 	}
   5602 	if {![regexp {BEGIN CERTIFICATE} $cert_text]} {
   5603 		if [regexp {CONNECTED} $cert_text] {
   5604 			set m 0
   5605 			if [regexp -nocase -line {error.*handshake failure} $cert_text] {
   5606 				set m 1
   5607 			}
   5608 			if [regexp -nocase -line {error.*unknown protocol} $cert_text] {
   5609 				set m 1
   5610 			}
   5611 			if {![regexp -nocase {show_cert: SSL_connect failed} $cert_text]} {
   5612 				set m 1
   5613 			}
   5614 			if {!$m && $is_windows} {
   5615 				if [regexp -nocase {no peer certificate} $cert_text] {
   5616 					set m 1
   5617 				}
   5618 			}
   5619 			if {$m} {
   5620 				# suspect Anonymous Diffie Hellman
   5621 				set cert_text ""
   5622 				set anondh 1
   5623 				incr pstr
   5624 				mesg "#${pstr} Fetching $hpnew Cert... $vencrypt/$anondh"
   5625 				if {! $is_windows} {
   5626 					catch {set cert_text [fetch_cert_unix    $hp $vencrypt $anondh]}
   5627 				} else {
   5628 					after 600
   5629 					catch {set cert_text [fetch_cert_windows $hp $vencrypt $anondh]}
   5630 				}
   5631 	if [info exists env(CERTDBG)] {puts "\nFetch-2-\n$cert_text"}
   5632 			}
   5633 		}
   5634 	}
   5635 	if {![regexp {BEGIN CERTIFICATE} $cert_text]} {
   5636 		if [regexp {CONNECTED} $cert_text] {
   5637 			if {[regexp -nocase -line {cipher.*ADH} $cert_text]} {
   5638 				# it is Anonymous Diffie Hellman
   5639 				mesg "WARNING: Anonymous Diffie Hellman Server detected (NO CERT)"
   5640 				after 300
   5641 				.f4.getcert configure -state normal
   5642 				return $cert_text
   5643 			} else {
   5644 				global vencrypt_detected
   5645 				set vencrypt_detected ""
   5646 			}
   5647 		}
   5648 	}
   5649 
   5650 	global vencrypt_detected server_vencrypt
   5651 	if {$vencrypt_detected != "" && !$server_vencrypt} {
   5652 		mesg "VeNCrypt or ANONTLS server detected."
   5653 		after 600
   5654 	}
   5655 
   5656 	.f4.getcert configure -state normal
   5657 	mesg "Fetched $hpnew Cert"
   5658 
   5659 	set n 47
   5660 	set ok 1
   5661 	if {$cert_text == ""} {
   5662 		set cert_text "An Error occurred in fetching SSL Certificate from $hp"
   5663 		set ok 0
   5664 		set n 4
   5665 	} elseif {! [regexp {BEGIN CERTIFICATE} $cert_text]} {
   5666 		set cert_text "An Error occurred in fetching $hp\n\n$cert_text"
   5667 		set n [line_count $cert_text 1]
   5668 		set ok 0
   5669 	} else {
   5670 		if [regexp -- {-----BEGIN SSL SESSION PARAMETERS-----} $cert_text] {
   5671 			set new ""
   5672 			set off 0
   5673 			foreach line [split $cert_text "\n"] {
   5674 				if [regexp -- {RFB 00} $line] {
   5675 					continue
   5676 				}
   5677 				if [regexp -- {Using default temp} $line] {
   5678 					continue
   5679 				}
   5680 				if [regexp -- {-----BEGIN SSL SESSION PARAMETERS-----} $line] {
   5681 					set off 1
   5682 				}
   5683 				if [regexp -- {-----END SSL SESSION PARAMETERS-----} $line] {
   5684 					set off 0
   5685 					continue
   5686 				}
   5687 				if {$off} {
   5688 					continue;
   5689 				}
   5690 				append new "$line\n"
   5691 			}
   5692 			if [regexp -- {-----BEGIN CERTIFICATE-----} $new] {
   5693 				set cert_text $new
   5694 			}
   5695 		}
   5696 		set text ""
   5697 		set on 0
   5698 		set subject ""
   5699 		set curr_subject ""
   5700 		set chain_n -1
   5701 		set chain(__empty__) ""
   5702 		foreach line [split $cert_text "\n"] {
   5703 			if [regexp -- {-----BEGIN CERTIFICATE-----} $line] {
   5704 				incr on
   5705 			}
   5706 			if {$chain_n < -1} {
   5707 				;
   5708 			} elseif [regexp {^ *([0-9]) *s:(.*/[A-Z][A-Z]*=.*$)} $line m cn sb] {
   5709 				set cn [string trim $cn]
   5710 				set sb [string trim $sb]
   5711 				#puts cn=$cn
   5712 				#puts sb=$sb
   5713 				if {$subject == ""} {
   5714 					set subject $sb
   5715 				}
   5716 				if {$cn > $chain_n} {
   5717 					set chain_n $cn
   5718 					set curr_subject $sb
   5719 				} else {
   5720 					set chain_n -2
   5721 				}
   5722 			} elseif [regexp {^ *i:(.*/[A-Z][A-Z]*=.*$)} $line m is] {
   5723 				set is [string trim $is]
   5724 				#puts is=$is
   5725 				if {$curr_subject != ""} {
   5726 					set chain($curr_subject) $is
   5727 				}
   5728 			}
   5729 			if {$on != 1} {
   5730 				continue;
   5731 			}
   5732 			append text "$line\n"
   5733 			if [regexp -- {-----END CERTIFICATE-----} $line] {
   5734 				set on 2
   5735 			}
   5736 		}
   5737 		set chain_str "subject: not-known\n"
   5738 		set curr_subject $subject
   5739 		set self_signed 0
   5740 		set top_issuer ""
   5741 		for {set i 0} {$i < 10} {incr i} {
   5742 			if {$curr_subject != ""} {
   5743 				if {$i == 0} {
   5744 					set chain_str "- subject: $curr_subject\n\n"
   5745 				} else {
   5746 					set chain_str "${chain_str}- issuer$i: $curr_subject\n\n"
   5747 					set top_issuer $curr_subject;
   5748 				}
   5749 				if {![info exists chain($curr_subject)]} {
   5750 					break
   5751 				} elseif {$chain($curr_subject) == ""} {
   5752 					break
   5753 				} elseif {$curr_subject == $chain($curr_subject)} {
   5754 					set j [expr $i + 1]
   5755 					set chain_str "${chain_str}- issuer$j: $curr_subject\n\n"
   5756 					set top_issuer $curr_subject;
   5757 					if {$i == 0} {
   5758 						set self_signed 1
   5759 					}
   5760 					break;
   5761 				}
   5762 				set curr_subject $chain($curr_subject)
   5763 			}
   5764 		}
   5765 		set chain_str "${chain_str}INFO: SELF_SIGNED=$self_signed\n\n"
   5766 		if {$self_signed} {
   5767 			set chain_str "${chain_str}INFO: Certificate is Self-Signed.\n"
   5768 			set chain_str "${chain_str}INFO: It will successfully authenticate when used as a ServerCert or Accepted-Cert.\n"
   5769 			set chain_str "${chain_str}INFO: Be sure to check carefully that you trust this certificate before saving it.\n"
   5770 		} else {
   5771 			set chain_str "${chain_str}INFO: Certificate is signed by a Certificate Authority (CA).\n"
   5772 			set chain_str "${chain_str}INFO: It *WILL NOT* successfully authenticate when used as a ServerCert or Accepted-Cert.\n"
   5773 			set chain_str "${chain_str}INFO: You need to Obtain and Save the CA's Certificate (issuer) instead"
   5774 			if {$top_issuer != ""} {
   5775 				set chain_str "${chain_str}:\nINFO: CA: $top_issuer\n"
   5776 			} else {
   5777 				set chain_str "${chain_str}.\n"
   5778 			}
   5779 		}
   5780 		#puts "\n$chain_str\n"
   5781 
   5782 		global is_windows
   5783 		set tmp "/tmp/cert.hsh.[tpid]"
   5784 		set tmp [mytmp $tmp]
   5785 		if {$is_windows} {
   5786 			# VF
   5787 			set tmp cert.hsh
   5788 		}
   5789 		set fh ""
   5790 		catch {set fh [open $tmp "w"]}
   5791 		if {$fh != ""} {
   5792 			puts $fh $text
   5793 			close $fh
   5794 			set info ""
   5795 			catch {set info [get_x509_info $tmp]}
   5796 			catch {file delete $tmp}
   5797 			if [regexp -nocase {MD5 Finger[^\n]*} $info mvar] {
   5798 				set cert_text "$mvar\n\n$cert_text"
   5799 			}
   5800 			if [regexp -nocase {SHA. Finger[^\n]*} $info mvar] {
   5801 				set cert_text "$mvar\n\n$cert_text"
   5802 			}
   5803 			set cert_text "$cert_text\n\n----------------------------------\nOutput of  openssl x509 -text -fingerprint:\n\n$info"
   5804 		}
   5805 		set cert_text "==== SSL Certificate from $hp ====\n\n$chain_str\n$cert_text"
   5806 	}
   5807 
   5808 	if {! $save} {
   5809 		return $cert_text
   5810 	}
   5811 
   5812 	fetch_dialog $cert_text $hp $hpnew $ok $n
   5813 }
   5814 
   5815 proc skip_non_self_signed {w hp} {
   5816 	set msg "Certificate from $hp is not Self-Signed, it was signed by a Certificate Authority (CA).  Saving it does not make sense because it cannot be used to authenticate anything.  You need to Obtain and Save the CA Certificate instead.  Save it anyway?"
   5817 	set reply [tk_messageBox -type okcancel -default cancel -parent $w -icon warning -message $msg -title "CA Signed Certificate"]
   5818 	if {$reply == "cancel"} {
   5819 		return 1
   5820 	} else {
   5821 		return 0
   5822 	}
   5823 }
   5824 
   5825 proc fetch_dialog {cert_text hp hpnew ok n} {
   5826 	toplev .fetch
   5827 
   5828 	if [small_height] {
   5829 		set n 28
   5830 	}
   5831 
   5832 	scroll_text_dismiss .fetch.f 90 $n
   5833 
   5834 	if {$ok} {
   5835 		set ss 0
   5836 		if [regexp {INFO: SELF_SIGNED=1} $cert_text] {
   5837 			button .fetch.save -text Save -command "destroy .fetch; save_cert {$hpnew}"
   5838 			set ss 1
   5839 		} else {
   5840 			button .fetch.save -text Save -command "if \[skip_non_self_signed .fetch {$hpnew}\] {return} else {destroy .fetch; save_cert {$hpnew}}"
   5841 			set ss 0
   5842 		}
   5843 		button .fetch.help -text Help -command "help_fetch_cert $ss"
   5844 		pack .fetch.help .fetch.save -side bottom -fill x
   5845 		.fetch.d configure -text "Cancel"
   5846 	}
   5847 
   5848 	center_win .fetch
   5849 	wm title .fetch "$hp Certificate"
   5850 
   5851 	.fetch.f.t insert end $cert_text
   5852 	jiggle_text .fetch.f.t
   5853 }
   5854 
   5855 
   5856 proc host_part {hp} {
   5857 	regsub {^ *}  $hp "" hp
   5858 	regsub { .*$} $hp "" hp
   5859 	if [regexp {^[0-9][0-9]*$} $hp] {
   5860 		return ""
   5861 	}
   5862 	set h $hp
   5863 	regsub {:[0-9][0-9]*$} $hp "" h
   5864 	return $h
   5865 }
   5866 
   5867 proc port_part {hp} {
   5868 	regsub { .*$} $hp "" hp
   5869 	set p ""
   5870 	if [regexp {:([0-9][0-9]*)$} $hp m val] {
   5871 		set p $val
   5872 	}
   5873 	return $p
   5874 }
   5875 
   5876 proc get_vencrypt_proxy {hpnew} {
   5877 	if [regexp -nocase {^vnc://} $hpnew] {
   5878 		return ""
   5879 	}
   5880 	set hpnew  [get_ssh_hp $hpnew]
   5881 	regsub -nocase {^[a-z0-9+]*://} $hpnew "" hpnew
   5882 	set h [host_part $hpnew]
   5883 	set p [port_part $hpnew]
   5884 
   5885 	if {$p == ""} {
   5886 		# might not matter, i.e. SSH+SSL only...
   5887 		set p 5900
   5888 	}
   5889 	set hp2 $h
   5890 	if {$p < 0} {
   5891 		set hp2 "$hp2:[expr - $p]"
   5892 	} elseif {$p < 200} {
   5893 		set hp2 "$hp2:[expr $p + 5900]"
   5894 	} else {
   5895 		set hp2 "$hp2:$p"
   5896 	}
   5897 	return "vencrypt://$hp2"
   5898 }
   5899 
   5900 proc fetch_cert_unix {hp {vencrypt 0} {anondh 0}} {
   5901 	global use_listen
   5902 
   5903 	set hpnew  [get_ssh_hp $hp]
   5904 	set proxy  [get_ssh_proxy $hp]
   5905 
   5906 	if {$vencrypt} {
   5907 		global vencrypt_detected
   5908 		set vencrypt_detected [get_vencrypt_proxy $hpnew]
   5909 		if {$proxy != ""} {
   5910 			set proxy "$proxy,$vencrypt_detected"
   5911 		} else {
   5912 			set proxy $vencrypt_detected
   5913 		}
   5914 	}
   5915 
   5916 	set cmd [list ss_vncviewer]
   5917 	if {$anondh} {
   5918 		lappend cmd "-anondh"
   5919 	}
   5920 	if {$proxy != ""} {
   5921 		lappend cmd "-proxy"
   5922 		lappend cmd $proxy
   5923 	}
   5924 	if {$use_listen} {
   5925 		lappend cmd "-listen"
   5926 	}
   5927 	lappend cmd "-showcert"
   5928 	lappend cmd $hpnew
   5929 
   5930 	if {$proxy != ""} {
   5931 		lappend cmd "2>/dev/null"
   5932 	}
   5933 	global env
   5934 	if [info exists env(CERTDBG)] {puts "\nFetch-cmd: $cmd"}
   5935 	set env(SSVNC_SHOWCERT_EXIT_0) 1
   5936 
   5937 	return [eval exec $cmd]
   5938 }
   5939 
   5940 proc win_nslookup {host} {
   5941 	global win_nslookup_cache
   5942 	if [info exists win_nslookup_cache($host)] {
   5943 		return $win_nslookup_cache($host)
   5944 	}
   5945 	if [regexp -nocase {[^a-z0-9:._-]} $host]  {
   5946 		set win_nslookup_cache($host) "invalid"
   5947 		return $win_nslookup_cache($host)
   5948 	}
   5949 	if [regexp {^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$} $host] {
   5950 		set win_nslookup_cache($host) $host
   5951 		return $win_nslookup_cache($host)
   5952 	}
   5953 	if [regexp -nocase {^[a-f0-9]*:[a-f0-9:]*:[a-f0-9:]*$} $host] {
   5954 		set win_nslookup_cache($host) $host
   5955 		return $win_nslookup_cache($host)
   5956 	}
   5957 	set nsout ""
   5958 	catch {set nsout [exec nslookup $host]}
   5959 	if {$nsout == "" || [regexp -nocase {server failed} $nsout]} {
   5960 		after 250
   5961 		set nsout ""
   5962 		catch {set nsout [exec nslookup $host]}
   5963 	}
   5964 	if {$nsout == "" || [regexp -nocase {server failed} $nsout]} {
   5965 		set win_nslookup_cache($host) "unknown"
   5966 		return $win_nslookup_cache($host)
   5967 	}
   5968 	regsub -all {Server:[^\n]*\nAddress:[^\n]*} $nsout "" nsout
   5969 	regsub {^.*Name:} $nsout "" nsout
   5970 	if [regexp {Address:[ \t]*([^\n]+)} $nsout mv addr] {
   5971 		set addr [string trim $addr]
   5972 		if {$addr != ""} {
   5973 			set win_nslookup_cache($host) $addr
   5974 			return $win_nslookup_cache($host)
   5975 		}
   5976 	}
   5977 	set win_nslookup_cache($host) "unknown"
   5978 	return $win_nslookup_cache($host)
   5979 }
   5980 
   5981 proc win_ipv4 {host} {
   5982 	global win_localhost
   5983 	set ip [win_nslookup $host];
   5984 	if [regexp {^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$} $ip] {
   5985 		return 1
   5986 	}
   5987 	return 0
   5988 }
   5989 
   5990 proc ipv6_proxy {proxy host port} {
   5991 	global is_windows win_localhost have_ipv6
   5992 
   5993 	if {!$have_ipv6} {
   5994 		return [list $proxy $host $port ""]
   5995 	} elseif {!$is_windows} {
   5996 		return [list $proxy $host $port ""]
   5997 	} else {
   5998 		set h0 ""
   5999 		set p0 ""
   6000 		set port3 ""
   6001 		set ipv6_pid ""
   6002 		set proxy0 $proxy
   6003 		if {$proxy == ""} {
   6004 			if [win_ipv4 $host] {
   6005 				return [list $proxy $host $port ""]
   6006 			}
   6007 			set port3 [rand_port]
   6008 			set h0 $host
   6009 			set p0 $port
   6010 			set host $win_localhost
   6011 			set port $port3
   6012 		} else {
   6013 			set parts [split $proxy ","]
   6014 			set n [llength $parts]
   6015 			for {set i 0} {$i < $n} {incr i} {
   6016 				set part [lindex $parts $i]
   6017 				set prefix ""
   6018 				set repeater 0
   6019 				regexp -nocase {^[a-z0-9+]*://} $part prefix
   6020 				regsub -nocase {^[a-z0-9+]*://}	$part "" part
   6021 				if [regexp {^repeater://} $prefix] {
   6022 					regsub {\+.*$} $part "" part
   6023 					if {![regexp {:([0-9][0-9]*)$} $part]} {
   6024 						set part "$part:5900"
   6025 					}
   6026 				}
   6027 				set modit 0
   6028 				set h1 ""
   6029 				set p1 ""
   6030 				if [regexp {^(.*):([0-9][0-9]*)$} $part mvar h1 p1] {
   6031 					if {$h1 == "localhost" || $h1 == $win_localhost} {
   6032 						continue
   6033 					} elseif [win_ipv4 $h1] {
   6034 						break
   6035 					}
   6036 					set modit 1
   6037 				} else {
   6038 					break
   6039 				}
   6040 				if {$modit} {
   6041 					set port3 [rand_port]
   6042 					set h0 $h1
   6043 					set p0 $p1
   6044 					lset parts $i "$prefix$win_localhost:$port3"
   6045 					break
   6046 				}
   6047 			}
   6048 			if {$h0 != "" && $p0 != "" && $port3 != ""} {
   6049 				set proxy [join $parts ","]
   6050 				#mesg "Reset proxy: $proxy"; after 3000
   6051 			}
   6052 		}
   6053 		if {$h0 != "" && $p0 != "" && $port3 != ""} {
   6054 			mesg "Starting IPV6 helper on port $port3 ..."
   6055 			set ipv6_pid [exec relay6.exe $port3 "$h0" "$p0" /b:$win_localhost &]
   6056 			after 400
   6057 			#mesg "r6 $port3 $h0 $p0"; after 3000
   6058 		}
   6059 		return [list $proxy $host $port $ipv6_pid]
   6060 	}
   6061 }
   6062 
   6063 proc fetch_cert_windows {hp {vencrypt 0} {anondh 0}} {
   6064 	global have_ipv6
   6065 
   6066 	regsub {^vnc.*://} $hp "" hp
   6067 
   6068 	set hpnew  [get_ssh_hp $hp]
   6069 	set proxy  [get_ssh_proxy $hp]
   6070 
   6071 	if {$vencrypt} {
   6072 		global vencrypt_detected
   6073 		set vencrypt_detected [get_vencrypt_proxy $hpnew]
   6074 		if {$proxy != ""} {
   6075 			set proxy "$proxy,$vencrypt_detected"
   6076 		} else {
   6077 			set proxy $vencrypt_detected
   6078 		}
   6079 	}
   6080 
   6081 	set host [host_part $hpnew]
   6082 
   6083 	global win_localhost
   6084 
   6085 	if {$host == ""} {
   6086 		set host $win_localhost
   6087 	}
   6088 
   6089 	if [regexp {^.*@} $host match] {
   6090 		mesg "Trimming \"$match\" from hostname"
   6091 		regsub {^.*@} $host "" host
   6092 	}
   6093 
   6094 	set disp [port_part $hpnew]
   6095 
   6096 	if {[regexp {^-[0-9][0-9]*$} $disp]} {
   6097 		;
   6098 	} elseif {$disp == "" || ! [regexp {^[0-9][0-9]*$} $disp]} {
   6099 		set disp 0
   6100 	}
   6101 	if {$disp < 0} {
   6102 		set port [expr "- $disp"]
   6103 	} elseif {$disp < 200} {
   6104 		set port [expr "$disp + 5900"]
   6105 	} else {
   6106 		set port $disp
   6107 	}
   6108 
   6109 	set ipv6_pid ""
   6110 	if {$have_ipv6} {
   6111 		set res [ipv6_proxy $proxy $host $port]
   6112 		set proxy    [lindex $res 0]
   6113 		set host     [lindex $res 1]
   6114 		set port     [lindex $res 2]
   6115 		set ipv6_pid [lindex $res 3]
   6116 	}
   6117 
   6118 	if {$proxy != ""} {
   6119 		global env
   6120 
   6121 		set port2 [rand_port]
   6122 
   6123 		set sp ""
   6124 		if [info exists env(SSVNC_PROXY)] {
   6125 			set sp $env(SSVNC_PROXY)
   6126 		}
   6127 		set sl ""
   6128 		if [info exists env(SSVNC_LISTEN)] {
   6129 			set sl $env(SSVNC_LISTEN)
   6130 		}
   6131 		set sd ""
   6132 		if [info exists env(SSVNC_DEST)] {
   6133 			set sd $env(SSVNC_DEST)
   6134 		}
   6135 
   6136 		set env(SSVNC_PROXY) $proxy
   6137 		set env(SSVNC_LISTEN) $port2
   6138 		set env(SSVNC_DEST) "$host:$port"
   6139 
   6140 		set host $win_localhost
   6141 		set port $port2
   6142 
   6143 		mesg "Starting Proxy TCP helper on port $port2 ..."
   6144 		after 300
   6145 		# fetch cert br case:
   6146 		set proxy_pid [exec "connect_br.exe" &]
   6147 
   6148 		if {$sp == ""} {
   6149 			catch { unset env(SSVNC_PROXY) }
   6150 		} else {
   6151 			set env(SSVNC_PROXY) $sp
   6152 		}
   6153 		if {$sl == ""} {
   6154 			catch { unset env(SSVNC_LISTEN) }
   6155 		} else {
   6156 			set env(SSVNC_LISTEN) $sl
   6157 		}
   6158 		if {$sd == ""} {
   6159 			catch { unset env(SSVNC_DEST) }
   6160 		} else {
   6161 			set env(SSVNC_DEST) $sd
   6162 		}
   6163 	}
   6164 
   6165 	set ossl [get_openssl]
   6166 	update
   6167 	# VF
   6168 	set tin tmpin.txt
   6169 	set tou tmpout.txt
   6170 	set fh ""
   6171 	catch {set fh [open $tin "w"]}
   6172 	if {$fh != ""} {
   6173 		puts $fh "Q"
   6174 		puts $fh "GET /WOMBAT HTTP/1.1\r\nHost: wombat.com\r\n\r\n\r\n"
   6175 		close $fh
   6176 	}
   6177 
   6178 	if {1} {
   6179 		set ph ""
   6180 		if {$anondh} {
   6181 			set ph [open "| $ossl s_client -prexit -connect $host:$port -cipher ALL:RC4+RSA:+SSLv2:@STRENGTH < $tin 2>NUL" "r"]
   6182 		} else {
   6183 			set ph [open "| $ossl s_client -prexit -connect $host:$port < $tin 2>NUL" "r"]
   6184 		}
   6185 
   6186 		set text ""
   6187 		if {$ph != ""} {
   6188 			set pids [pid $ph]
   6189 			set got 0
   6190 			while {[gets $ph line] > -1} {
   6191 				append text "$line\n"
   6192 				if [regexp {END CERT} $line] {
   6193 					set got 1
   6194 				}
   6195 				if {$anondh && [regexp -nocase {cipher.*ADH} $line]} {
   6196 					set got 1
   6197 				}
   6198 				if {$got && [regexp {^ *Verify return code} $line]} {
   6199 					break
   6200 				}
   6201 				if [regexp {^RFB } $line] {
   6202 					break
   6203 				}
   6204 				if [regexp {^DONE} $line] {
   6205 					break
   6206 				}
   6207 			}
   6208 			foreach pid $pids {
   6209 				winkill $pid
   6210 			}
   6211 			if {$ipv6_pid != ""} {
   6212 				winkill $ipv6_pid
   6213 			}
   6214 
   6215 			catch {close $ph}
   6216 			catch {file delete $tin $tou}
   6217 			return $text
   6218 		}
   6219 	} else {
   6220 		set pids ""
   6221 
   6222 		if {1} {
   6223 			if {$anondh} {
   6224 				set ph2 [open "| $ossl s_client -prexit -connect $host:$port -cipher ALL:RC4+RSA:+SSLv2:@STRENGTH > $tou 2>NUL" "w"]
   6225 			} else {
   6226 				set ph2 [open "| $ossl s_client -prexit -connect $host:$port > $tou 2>NUL" "w"]
   6227 			}
   6228 			set pids [pid $ph2]
   6229 			after 500
   6230 			for {set i 0} {$i < 128} {incr i} {
   6231 				puts $ph2 "Q"
   6232 			}
   6233 			catch {close $ph2}
   6234 		} else {
   6235 			if {$anondh} {
   6236 				set pids [exec $ossl s_client -prexit -connect $host:$port -cipher ALL:RC4+RSA:+SSLv2:@STRENGTH < $tin >& $tou &]
   6237 			} else {
   6238 				set pids [exec $ossl s_client -prexit -connect $host:$port < $tin >& $tou &]
   6239 			}
   6240 		}
   6241 
   6242 		for {set i 0} {$i < 10} {incr i} {
   6243 			after 500
   6244 			set got 0
   6245 			set ph ""
   6246 			catch {set ph [open $tou "r"]}
   6247 			if {$ph != ""} {
   6248 				while {[gets $ph line] > -1} {
   6249 					if [regexp {END CERT} $line] {
   6250 						set got 1
   6251 						break
   6252 					}
   6253 				}
   6254 				close $ph
   6255 			}
   6256 			if {$got} {
   6257 				break
   6258 			}
   6259 		}
   6260 		foreach pid $pids {
   6261 			winkill $pid
   6262 		}
   6263 		after 500
   6264 		set ph ""
   6265 		catch {set ph [open $tou "r"]}
   6266 	}
   6267 	set text ""
   6268 	if {$ph != ""} {
   6269 		while {[gets $ph line] > -1} {
   6270 			append text "$line\n"
   6271 		}
   6272 		close $ph
   6273 	}
   6274 	catch {file delete $tin $tou}
   6275 	if {$ipv6_pid != ""} {
   6276 		winkill $ipv6_pid
   6277 	}
   6278 	return $text
   6279 }
   6280 
   6281 proc check_accepted_certs {{probe_only 0}} {
   6282 	global cert_text always_verify_ssl
   6283 	global skip_verify_accepted_certs use_listen
   6284 	global ultra_dsm env
   6285 	global server_vencrypt server_anondh no_probe_vencrypt
   6286 
   6287 	if {! $always_verify_ssl} {
   6288 		set skip_verify_accepted_certs 1
   6289 		if {$server_vencrypt} {
   6290 			return 1
   6291 		}
   6292 		if {$no_probe_vencrypt} {
   6293 			return 1
   6294 		}
   6295 	}
   6296 	if {$server_anondh} {
   6297 		mesg "WARNING: Anonymous Diffie Hellman (SKIPPING CERT CHECK)"
   6298 		after 1000
   6299 		set skip_verify_accepted_certs 1
   6300 		return 1
   6301 	}
   6302 	if {$ultra_dsm} {
   6303 		return 1;
   6304 	}
   6305 	if {$use_listen} {
   6306 		return 1;
   6307 	}
   6308 
   6309 	global anon_dh_detected
   6310 	set anon_dh_detected 0
   6311 
   6312 	set cert_text [fetch_cert 0]
   6313 
   6314 	set mvar ""
   6315 	if {[regexp -nocase -line {cipher.*ADH} $cert_text mvar]} {
   6316 
   6317 		if [info exists env(CERTDBG)] {puts "\nFetch-MSG-\n$cert_text"}
   6318 		if [info exists env(CERTDBG)] {puts "\nBEGIN_MVAR: $mvar\nEND_MVAR\n"}
   6319 
   6320 		set msg "Anonymous Diffie-Hellman server detected.  There will be encryption, but no SSL/TLS authentication. Continue?"
   6321 		set reply [tk_messageBox -type okcancel -default ok -icon warning -message $msg -title "Anonymous Diffie-Hellman Detected"]
   6322 		set anon_dh_detected 1
   6323 		if {$reply == "cancel"} {
   6324 			return 0
   6325 		} else {
   6326 			global skip_verify_accepted_certs
   6327 			set skip_verify_accepted_certs 1
   6328 			return 1
   6329 		}
   6330 	}
   6331 
   6332 	if {$probe_only} {
   6333 		return 1
   6334 	}
   6335 	if {! $always_verify_ssl} {
   6336 		return 1
   6337 	}
   6338 
   6339 	set from ""
   6340 	set fingerprint ""
   6341 	set fingerline ""
   6342 	set self_signed 1
   6343 	set subject_issuer ""
   6344 	set subject ""
   6345 	set issuer ""
   6346 
   6347 	set i 0
   6348 	foreach line [split $cert_text "\n"] {
   6349 		incr i
   6350 		if {$i > 50} {
   6351 			break
   6352 		}
   6353 		if [regexp {^- subject: *(.*)$} $line m val] {
   6354 			set val [string trim $val]
   6355 			set subject_issuer "${subject_issuer}subject:$val\n"
   6356 			set subject $val
   6357 		}
   6358 		if [regexp {^- (issuer[0-9][0-9]*): *(.*)$} $line m is val] {
   6359 			set val [string trim $val]
   6360 			set subject_issuer "${subject_issuer}$is:$val\n"
   6361 			set issuer $val
   6362 		}
   6363 		if [regexp {^INFO: SELF_SIGNED=(.*)$} $line m val] {
   6364 			set subject_issuer "${subject_issuer}SELF_SIGNED:$val\n"
   6365 		}
   6366 		if [regexp {^depth=} $line] {
   6367 			break
   6368 		}
   6369 		if [regexp {^verify } $line] {
   6370 			break
   6371 		}
   6372 		if [regexp {^CONNECTED} $line] {
   6373 			break
   6374 		}
   6375 		if [regexp {^Certificate chain} $line] {
   6376 			break
   6377 		}
   6378 		if [regexp {^==== SSL Certificate from (.*) ====} $line mv str] {
   6379 			set from [string trim $str]
   6380 		}
   6381 		if [regexp -nocase {Fingerprint=(.*)} $line mv str] {
   6382 			set fingerline $line
   6383 			set fingerprint [string trim $str]
   6384 		}
   6385 		if [regexp -nocase {^INFO: SELF_SIGNED=([01])} $line mv str] {
   6386 			set self_signed $str
   6387 		}
   6388 	}
   6389 
   6390 	set fingerprint [string tolower $fingerprint]
   6391 	regsub -all {:} $fingerprint "-" fingerprint
   6392 	regsub -all {[\\/=]} $fingerprint "_" fingerprint
   6393 
   6394 	set from [string tolower $from]
   6395 	regsub -all {[\[\]]} $from "" from
   6396 	regsub -all {^[+a-z]*://} $from "" from
   6397 	regsub -all {:} $from "-" from
   6398 	regsub -all {[\\/=]} $from "_" from
   6399 	regsub -all {[ 	]} $from "_" from
   6400 
   6401 	if {$from == "" || $fingerprint == ""} {
   6402 		bell
   6403 		catch {raise .; update}
   6404 		mesg "WARNING: Error fetching Server Cert"
   6405 		after 500
   6406 		set hp [get_vncdisplay]
   6407 		set n [line_count $cert_text 1]
   6408 		fetch_dialog $cert_text $hp $hp 0 $n
   6409 		update
   6410 		after 2000
   6411 		return 0
   6412 	}
   6413 
   6414 	set hp [get_vncdisplay]
   6415 
   6416 	set adir [get_idir_certs ""]
   6417 	catch {file mkdir $adir}
   6418 	set adir "$adir/accepted"
   6419 	catch {file mkdir $adir}
   6420 
   6421 	set crt "$adir/$from=$fingerprint.crt"
   6422 
   6423 	if [file exists $crt] {
   6424 		if {$self_signed} {
   6425 			mesg "OK: Certificate found in ACCEPTED_CERTS"
   6426 			after 750
   6427 			return 1
   6428 		}
   6429 	}
   6430 
   6431 	set cnt 0
   6432 	foreach f [glob -nocomplain -directory $adir "*$fingerprint*.crt"] {
   6433 		mesg "CERT: $f"
   6434 		after 150
   6435 		if {$self_signed} {
   6436 			incr cnt
   6437 		}
   6438 	}
   6439 
   6440 	set oth 0
   6441 	set others [list]
   6442 	foreach f [glob -nocomplain -directory $adir "*$from*.crt"] {
   6443 		if {$f == $crt}  {
   6444 			continue
   6445 		}
   6446 		set fb [file tail $f]
   6447 		mesg "OTHER CERT: $fb"
   6448 		if {$cnt > 0} {
   6449 			after 400
   6450 		} else {
   6451 			bell
   6452 			after 800
   6453 		}
   6454 		lappend others $f
   6455 		incr oth
   6456 	}
   6457 
   6458 	foreach f [glob -nocomplain -directory $adir "*.crt"] {
   6459 		if {$f == $crt}  {
   6460 			continue
   6461 		}
   6462 		set saw 0
   6463 		foreach o $others {
   6464 			if {$f == $o} 	{
   6465 				set saw 1
   6466 				break
   6467 			}
   6468 		}
   6469 		if {$saw} {
   6470 			continue
   6471 		}
   6472 		set fh [open $f "r"]
   6473 		if {$fh == ""} {
   6474 			continue
   6475 		}
   6476 		set same 0
   6477 		set sub ""
   6478 		set iss ""
   6479 		set isn -1;
   6480 		while {[gets $fh line] > -1} {
   6481 			if [regexp {^Host-Display: (.*)$} $line mv hd] {
   6482 				if {$hd == $hp || $hd == $from} {
   6483 					set same 1
   6484 				}
   6485 			}
   6486 			if [regexp {^subject:(.*)$} $line mv val] {
   6487 				set sub $val
   6488 			}
   6489 			if [regexp {^issue([0-9][0-9]*):(.*)$} $line mv in val] {
   6490 				if {$in > $isn} {
   6491 					set isn $in
   6492 					set iss $val
   6493 				}
   6494 			}
   6495 		}
   6496 		close $fh;
   6497 
   6498 		if {!$self_signed} {
   6499 			if {$sub == ""} {
   6500 				set ossl [get_openssl]
   6501 				set si_txt [exec $ossl x509 -subject -issuer -noout -in $f]
   6502 				foreach line [split $si_txt "\n"] {
   6503 					if [regexp -nocase {^subject= *(.*)$} $line mv str] {
   6504 						set str [string trim $str]
   6505 						if {$str != ""} {
   6506 							set sub $str
   6507 						}
   6508 					} elseif [regexp -nocase {^issuer= *(.*)$} $line mv str] {
   6509 						set str [string trim $str]
   6510 						if {$iss != ""} {
   6511 							set iss $str
   6512 						}
   6513 					}
   6514 				}
   6515 			}
   6516 			if {$issuer != "" && $sub != ""} {
   6517 				global env
   6518 				if [info exists env(CERTDBG)] {
   6519 					puts "f: $f"
   6520 					puts "s: $sub"
   6521 					puts "i: $issuer"
   6522 					puts "==================="
   6523 				}
   6524 				if {$issuer == $sub} {
   6525 					set fb [file tail $f]
   6526 					mesg "Certificate Authority (CA) CERT: $fb"
   6527 					incr cnt
   6528 					after 500
   6529 				}
   6530 			}
   6531 			continue
   6532 		}
   6533 
   6534 		if {! $same} {
   6535 			continue
   6536 		}
   6537 
   6538 		set fb [file tail $f]
   6539 		mesg "OTHER CERT: $fb"
   6540 		if {$cnt > 0} {
   6541 			after 400
   6542 		} else {
   6543 			bell
   6544 			after 800
   6545 		}
   6546 		lappend others $f
   6547 		incr oth
   6548 	}
   6549 
   6550 	if {$cnt > 0} {
   6551 		if {$self_signed} {
   6552 			mesg "OK: Server Certificate found in ACCEPTED_CERTS"
   6553 			after 400
   6554 		} else {
   6555 			mesg "OK: CA Certificate found in ACCEPTED_CERTS"
   6556 			after 800
   6557 		}
   6558 		return 1
   6559 	}
   6560 
   6561 	set hp2 [get_vncdisplay]
   6562 	set msg "
   6563     The Self-Signed SSL Certificate from host:
   6564 
   6565         $hp2
   6566 
   6567     Fingerprint: $fingerprint
   6568 
   6569     Subject: $subject
   6570 
   6571     is not present in the 'Accepted Certs' directory:
   6572 
   6573         $adir
   6574 %WARN
   6575     You will need to verify on your own that this is a certificate from a
   6576     VNC server that you trust (e.g. by checking the fingerprint with that
   6577     sent to you by the server administrator).
   6578 
   6579 
   6580     THE QUESTION: Do you want this certificate to be saved in the Accepted Certs
   6581     directory and then used to SSL authenticate VNC servers?
   6582 
   6583 
   6584     By clicking 'Inspect and maybe Save Cert' you will be given the opportunity
   6585     to inspect the certificate before deciding to save it or not.
   6586 "
   6587 
   6588 	set msg_bottom "
   6589     Choose 'Ignore Cert for One Connection' to connect a single time to the
   6590     server with *NO* certificate authentication.  You will see this dialog again
   6591     the next time you connect to the same server.
   6592 
   6593     Choose 'Continue as though I saved it' to launch stunnel and the VNC viewer.
   6594     Do this if you know the correct Certificate is in the 'Accepted Certs'
   6595     directory.  If it is not, stunnel will fail and report 'VERIFY ERROR:...'
   6596 
   6597     Choose 'Cancel' to not connect to the VNC Server at all.
   6598 "
   6599 
   6600 	set msg_ca "
   6601     The CA-signed SSL Certificate from host:
   6602 
   6603         $hp2
   6604 
   6605     Fingerprint: $fingerprint
   6606 
   6607     Subject: $subject
   6608 
   6609     Issuer:  $issuer
   6610 
   6611     is signed by a Certificate Authority (CA) (the 'Issuer' above.)
   6612 
   6613     However, the certificate of the CA 'Issuer' is not present in the
   6614     'Accepted Certs' directory:
   6615 
   6616         $adir
   6617 
   6618     You will need to obtain the certificate of the CA 'Issuer' via some means
   6619     (perhaps ask the VNC server administrator for it.)  Then, after you have
   6620     verified that the CA certificate is one that you trust, import the
   6621     certificate via Certs -> Import Certificate.  Be sure to select to also
   6622     save it to the Accepted Certs directory so it will automatically be used.
   6623 "
   6624 	set msg "$msg$msg_bottom"
   6625 	set msg_ca "$msg_ca$msg_bottom"
   6626 
   6627 	if {!$self_signed} {
   6628 		set msg $msg_ca
   6629 	}
   6630 
   6631 	if {$oth == 0} {
   6632 		regsub {%WARN} $msg "" msg
   6633 	} else {
   6634 		set warn ""
   6635 		set wfp ""
   6636 		if {$oth == 1} {
   6637 			set warn "
   6638 **WARNING** The Following Cert was previously saved FOR THE SAME HOST-DISPLAY:
   6639 
   6640 "
   6641 			set wfp "BUT WITH A DIFFERENT FINGERPRINT."
   6642 
   6643 		} else {
   6644 			set warn "
   6645 **WARNING** The Following Certs were previously saved FOR THE SAME HOST-DISPLAY:
   6646 
   6647 "
   6648 			set wfp "BUT WITH DIFFERENT FINGERPRINTS."
   6649 		}
   6650 
   6651 		foreach o $others {
   6652 			set fb [file tail $o]
   6653 			set warn "$warn        $fb\n"
   6654 		}
   6655 		set warn "$warn\n    $wfp\n"
   6656 		set warn "$warn\n    This could be a Man-In-The-Middle attack, or simply that the Server changed"
   6657 		set warn "$warn\n    its Certificate.  *PLEASE CHECK* before proceeding!\n"
   6658 		regsub {%WARN} $msg $warn msg
   6659 		bell
   6660 	}
   6661 
   6662 	set n 0
   6663 	foreach l [split $msg "\n"] {
   6664 		incr n
   6665 	}
   6666 	if {!$self_signed} {
   6667 		set n [expr $n + 2]
   6668 	} else {
   6669 		set n [expr $n + 1]
   6670 	}
   6671 	if [small_height] {
   6672 		if {$n > 26} {
   6673 			set n 26
   6674 		}
   6675 	}
   6676 	toplev .acert
   6677 	scroll_text .acert.f 83 $n
   6678 
   6679 	button .acert.inspect -text "Inspect and maybe Save Cert ..." -command "destroy .acert; set accept_cert_dialog 1"
   6680 	button .acert.accept  -text "Ignore Cert for One Connection  " -command "destroy .acert; set accept_cert_dialog 2"
   6681 	button .acert.continue -text "Continue as though I saved it     " -command "destroy .acert; set accept_cert_dialog 3"
   6682 	button .acert.cancel -text "Cancel"   -command "destroy .acert; set accept_cert_dialog 0"
   6683 
   6684 	wm title .acert "Unrecognized SSL Cert!"
   6685 
   6686 	.acert.f.t insert end $msg
   6687 
   6688 	pack .acert.cancel .acert.continue .acert.accept .acert.inspect -side bottom -fill x
   6689 	pack .acert.f -side top -fill both -expand 1
   6690 
   6691 	if {! $self_signed} {
   6692 		catch {.acert.inspect configure -state disabled}
   6693 	}
   6694 
   6695 	center_win .acert
   6696 
   6697 	global accept_cert_dialog
   6698 	set accept_cert_dialog ""
   6699 
   6700 	jiggle_text .acert.f.t
   6701 
   6702 	tkwait window .acert
   6703 
   6704 	if {$accept_cert_dialog == 2} {
   6705 		set skip_verify_accepted_certs 1
   6706 		return 1
   6707 	}
   6708 	if {$accept_cert_dialog == 3} {
   6709 		return 1
   6710 	}
   6711 	if {$accept_cert_dialog != 1} {
   6712 		return 0
   6713 	}
   6714 
   6715 	global accepted_cert_dialog_in_progress
   6716 	set accepted_cert_dialog_in_progress 1
   6717 
   6718 	global fetch_cert_filename
   6719 	set fetch_cert_filename $crt
   6720 
   6721 	global do_save_saved_it
   6722 	set do_save_saved_it 0
   6723 	global do_save_saved_hash_it
   6724 	set do_save_saved_hash_it 0
   6725 
   6726 	fetch_dialog $cert_text $hp $hp 1 47
   6727 	update; after 150
   6728 
   6729 	catch {tkwait window .fetch}
   6730 	update; after 250
   6731 	catch {tkwait window .scrt}
   6732 	update; after 250
   6733 	if [winfo exists .scrt] {
   6734 		catch {tkwait window .scrt}
   6735 	}
   6736 
   6737 	set fetch_cert_filename ""
   6738 	set accepted_cert_dialog_in_progress 0
   6739 
   6740 	if {!$do_save_saved_hash_it} {
   6741 		save_hash $crt $adir $hp $fingerline $from $fingerprint $subject_issuer
   6742 	}
   6743 
   6744 	if {$do_save_saved_it} {
   6745 		return 1
   6746 	} else {
   6747 		return 0
   6748 	}
   6749 }
   6750 
   6751 proc save_hash {crt adir hp fingerline from fingerprint {subject_issuer ""}} {
   6752 	if ![file exists $crt] {
   6753 		return
   6754 	}
   6755 	set ossl [get_openssl]
   6756 	set hash [exec $ossl x509 -hash -noout -in $crt]
   6757 	set hash [string trim $hash]
   6758 	if [regexp {^([0-9a-f][0-9a-f]*)} $hash mv h] {
   6759 		set hashfile "$adir/$h.0"
   6760 		set hn "$h.0"
   6761 		if [file exists $hashfile] {
   6762 			set hashfile "$adir/$h.1"
   6763 			set hn "$h.1"
   6764 			if [file exists $hashfile] {
   6765 				set hashfile "$adir/$h.2"
   6766 				set hn "$h.2"
   6767 			}
   6768 		}
   6769 		set fh [open $crt "a"]
   6770 		if {$fh != ""} {
   6771 			puts $fh ""
   6772 			puts $fh "SSVNC-info:"
   6773 			puts $fh "Host-Display: $hp"
   6774 			puts $fh "$fingerline"
   6775 			puts $fh "hash-filename: $hn"
   6776 			puts $fh "full-filename: $from=$fingerprint.crt"
   6777 			puts -nonewline $fh $subject_issuer
   6778 			close $fh
   6779 		}
   6780 		catch {file copy -force $crt $hashfile}
   6781 		if [file exists $hashfile] {
   6782 			return 1
   6783 		}
   6784 	}
   6785 }
   6786 
   6787 proc tpid {} {
   6788 	global is_windows
   6789 	set p ""
   6790 
   6791 	if {!$is_windows} {
   6792 		catch {set p [exec sh -c {echo $$}]}
   6793 	}
   6794 	if {$p == ""} {
   6795 		set p [pid];
   6796 	}
   6797 	append p [clock clicks]
   6798 	return $p
   6799 }
   6800 
   6801 proc repeater_proxy_check {proxy} {
   6802 	if [regexp {^repeater://.*\+ID:[0-9]} $proxy] {
   6803 		global env rpc_m1 rpc_m2
   6804 		if {![info exists rpc_m1]} {
   6805 			set rpc_m1 0
   6806 			set rpc_m2 0
   6807 		}
   6808 		set force 0
   6809 		if [info exists env(REPEATER_FORCE)] {
   6810 			if {$env(REPEATER_FORCE) != "" && $env(REPEATER_FORCE) != "0"} {
   6811 				# no longer makes a difference.
   6812 				set force 1
   6813 			}
   6814 		}
   6815 		global use_listen ultra_dsm
   6816 		if {! $use_listen} {
   6817 			if {$ultra_dsm} {
   6818 				return 1;
   6819 			} else {
   6820 				if {0} {
   6821 					mesg "WARNING: repeater:// ID:nnn proxy might need Listen Mode"
   6822 					incr rpc_m1
   6823 					if {$rpc_m1 <= 2} {
   6824 						after 1000
   6825 					} else {
   6826 						after 200
   6827 					}
   6828 				}
   6829 				if {0} {
   6830 					# no longer required by x11vnc (X11VNC_DISABLE_SSL_CLIENT_MODE)
   6831 					bell
   6832 					mesg "ERROR: repeater:// ID:nnn proxy must use Listen Mode"
   6833 					after 1000
   6834 					return 0
   6835 				}
   6836 			}
   6837 		}
   6838 		global always_verify_ssl
   6839 		if [info exists always_verify_ssl] {
   6840 			if {$always_verify_ssl} {
   6841 				mesg "WARNING: repeater:// ID:nnn Verify All Certs may fail"
   6842 				incr rpc_m2
   6843 				if {$rpc_m2 == 1} {
   6844 					after 1500
   6845 				} elseif {$rpc_m2 == 2} {
   6846 					after 500
   6847 				} else {
   6848 					after 200
   6849 				}
   6850 			}
   6851 		}
   6852 	}
   6853 	return 1
   6854 }
   6855 
   6856 proc fini_unixpw {} {
   6857 	global named_pipe_fh unixpw_tmp
   6858 
   6859 	if {$named_pipe_fh != ""} {
   6860 		catch {close $named_pipe_fh}
   6861 	}
   6862 	if {$unixpw_tmp  != ""} {
   6863 		catch {file delete $unixpw_tmp}
   6864 	}
   6865 }
   6866 
   6867 proc init_unixpw {hp} {
   6868 	global use_unixpw unixpw_username unixpw_passwd
   6869 	global named_pipe_fh unixpw_tmp env
   6870 
   6871 	set named_pipe_fh ""
   6872 	set unixpw_tmp ""
   6873 
   6874 	if {$use_unixpw} {
   6875 		set name $unixpw_username
   6876 		set env(SSVNC_UNIXPW) ""
   6877 		if {$name == ""} {
   6878 			regsub {^.*://} $hp "" hp
   6879 			set hptmp [get_ssh_hp $hp]
   6880 			if [regexp {^(.*)@} $hptmp mv m1] {
   6881 				set name $m1
   6882 			}
   6883 		}
   6884 		if {$name == ""} {
   6885 			if [info exists env(USER)] {
   6886 				set name $env(USER)
   6887 			}
   6888 		}
   6889 		if {$name == ""} {
   6890 			if [info exists env(LOGNAME)] {
   6891 				set name $env(LOGNAME)
   6892 			}
   6893 		}
   6894 		if {$name == ""} {
   6895 			set name [exec whoami]
   6896 		}
   6897 		if {$name == ""} {
   6898 			set name "unknown"
   6899 		}
   6900 
   6901 		set tmp "/tmp/unixpipe.[tpid]"
   6902 		set tmp [mytmp $tmp]
   6903 		# need to make it a pipe
   6904 		catch {file delete $tmp}
   6905 		if {[file exists $tmp]} {
   6906 			mesg "file still exists: $tmp"
   6907 			bell
   6908 			return
   6909 		}
   6910 
   6911 		catch {exec mknod $tmp p}
   6912 		set fh ""
   6913 		if {! [file exists $tmp]} {
   6914 			catch {set fh [open $tmp "w"]}
   6915 		} else {
   6916 			catch {set fh [open $tmp "r+"]}
   6917 			set named_pipe_fh $fh
   6918 		}
   6919 		catch {exec chmod 600 $tmp}
   6920 		if {! [file exists $tmp]} {
   6921 			mesg "cannot create: $tmp"
   6922 			if {$named_pipe_fh != ""} {catch close $named_pipe_fh}
   6923 			bell
   6924 			return
   6925 		}
   6926 		#puts [exec ls -l $tmp]
   6927 		set unixpw_tmp $tmp
   6928 		puts $fh $name
   6929 		puts $fh $unixpw_passwd
   6930 		if {$named_pipe_fh != ""} {
   6931 			flush $fh
   6932 		} else {
   6933 			close $fh
   6934 		}
   6935 		exec sh -c "sleep 60; /bin/rm -f $tmp" &
   6936 		if {$unixpw_passwd == ""} {
   6937 			set env(SSVNC_UNIXPW) "."
   6938 		} else {
   6939 			set env(SSVNC_UNIXPW) "rm:$tmp"
   6940 		}
   6941 	} else {
   6942 		if [info exists env(SSVNC_UNIXPW)] {
   6943 			set env(SSVNC_UNIXPW) ""
   6944 		}
   6945 	}
   6946 }
   6947 
   6948 proc check_for_listen_ssl_cert {} {
   6949 	global mycert use_listen use_ssh ultra_dsm
   6950 	if {! $use_listen} {
   6951 		return 1
   6952 	}
   6953 	if {$use_ssh} {
   6954 		return 1
   6955 	}
   6956 	if {$ultra_dsm} {
   6957 		return 1
   6958 	}
   6959 	if {$mycert != ""} {
   6960 		return 1
   6961 	}
   6962 
   6963 	set name [get_idir_certs ""]
   6964 	set name "$name/listen.pem"
   6965 	if {[file exists $name]} {
   6966 		set mycert $name
   6967 		mesg "Using Listen Cert: $name"
   6968 		after 700
   6969 		return 1
   6970 	}
   6971 
   6972 	set title "SSL Listen requires MyCert";
   6973 	set msg "In SSL Listen mode a cert+key is required, but you have not specified  'MyCert'.\n\nCreate a cert+key 'listen' now?"
   6974 	set reply [tk_messageBox -type okcancel -default ok -icon warning -message $msg -title $msg]
   6975 	if {$reply == "cancel"} {
   6976 		return 0
   6977 	}
   6978 	create_cert $name
   6979 	tkwait window .ccrt
   6980 	if {[file exists $name]} {
   6981 		set mycert $name
   6982 		mesg "Using Listen Cert: $name"
   6983 		after 700
   6984 		return 1
   6985 	}
   6986 	return 0
   6987 }
   6988 
   6989 proc listen_verify_all_dialog {hp} {
   6990 	global use_listen always_verify_ssl
   6991 	global did_listen_verify_all_dialog
   6992 	global svcert
   6993 	global sshssl_sw ultra_dsm
   6994 
   6995 	if {!$use_listen} {
   6996 		return 1
   6997 	}
   6998 	if {!$always_verify_ssl} {
   6999 		return 1
   7000 	}
   7001 	if {$svcert != ""} {
   7002 		return 1
   7003 	}
   7004 	if {$ultra_dsm} {
   7005 		return 1
   7006 	}
   7007 	if [regexp -nocase {^vnc://} $hp] {
   7008 		return 1
   7009 	}
   7010 	if [info exists sshssl_sw] {
   7011 		if {$sshssl_sw == "none"} {
   7012 			return 1
   7013 		}
   7014 		if {$sshssl_sw == "ssh"} {
   7015 			return 1
   7016 		}
   7017 	}
   7018 	if [info exists did_listen_verify_all_dialog] {
   7019 		return 1
   7020 	}
   7021 
   7022 	toplev .lvd
   7023 	global help_font
   7024 	wm title .lvd "Verify All Certs for Reverse Connections"
   7025 	eval text .lvd.t -width 55 -height 22 $help_font
   7026 	.lvd.t insert end {
   7027   Information:
   7028 
   7029     You have the 'Verify All Certs' option enabled
   7030     in Reverse VNC Connections (-LISTEN) mode.
   7031 
   7032     For this to work, you must have ALREADY saved
   7033     the remote VNC Server's Certificate to the
   7034     'Accepted Certs' directory.  Otherwise the
   7035     incoming Reverse connection will be rejected.
   7036 
   7037     You can save the Server's Certificate by using
   7038     the 'Import Certificate' dialog or on Unix
   7039     and MacOSX by pressing 'Fetch Cert' and then
   7040     have the Server make an initial connection.
   7041 
   7042     If you do not want to save the certificate of
   7043     the VNC Server making the Reverse connection,
   7044     you must disable 'Verify All Certs' (note that
   7045     this means the server authenticity will not be
   7046     checked.)
   7047 }
   7048 
   7049 	button .lvd.ok   -text OK   -command {destroy .lvd}
   7050 	button .lvd.ok2  -text OK   -command {destroy .lvd}
   7051 	button .lvd.disable   -text "Disable 'Verify All Certs'"  -command {set always_verify_ssl 0; destroy .lvd}
   7052 	global uname
   7053 	if {$uname == "Darwin"} {
   7054 		pack .lvd.t .lvd.ok2 .lvd.disable .lvd.ok -side top -fill x
   7055 	} else {
   7056 		pack .lvd.t .lvd.disable .lvd.ok -side top -fill x
   7057 	}
   7058 	center_win .lvd
   7059 	update
   7060 
   7061 	tkwait window .lvd
   7062 	update
   7063 	after 50
   7064 	update
   7065 
   7066 	set did_listen_verify_all_dialog 1
   7067 	return 1
   7068 }
   7069 
   7070 proc reset_stunnel_extra_opts {} {
   7071 	global stunnel_extra_opts0 stunnel_extra_svc_opts0 env
   7072 	global ssvnc_multiple_listen0
   7073 	if {$stunnel_extra_opts0 != "none"} {
   7074 		set env(STUNNEL_EXTRA_OPTS) $stunnel_extra_opts0
   7075 	}
   7076 	if {$stunnel_extra_svc_opts0 != "none"} {
   7077 		set env(STUNNEL_EXTRA_SVC_OPTS) $stunnel_extra_svc_opts0
   7078 	}
   7079 	set env(SSVNC_LIM_ACCEPT_PRELOAD) ""
   7080 	if {$ssvnc_multiple_listen0 != "none"} {
   7081 		set env(SSVNC_MULTIPLE_LISTEN) $ssvnc_multiple_listen0
   7082 	}
   7083 	set env(SSVNC_ULTRA_DSM) ""
   7084 	set env(SSVNC_TURBOVNC) ""
   7085 	catch { unset env(VNCVIEWER_NO_PIPELINE_UPDATES) }
   7086 	catch { unset env(VNCVIEWER_NOTTY) }
   7087 	catch { unset env(SSVNC_ACCEPT_POPUP)    }
   7088 	catch { unset env(SSVNC_ACCEPT_POPUP_SC) }
   7089 	catch { unset env(SSVNC_KNOWN_HOSTS_FILE)    }
   7090 }
   7091 
   7092 proc maybe_add_vencrypt {proxy hp} {
   7093 	global vencrypt_detected server_vencrypt
   7094 	set vpd ""
   7095 	if {$vencrypt_detected != ""} {
   7096 		set vpd $vencrypt_detected
   7097 		set vencrypt_detected ""
   7098 	} elseif {$server_vencrypt} {
   7099 		set vpd [get_vencrypt_proxy $hp]
   7100 	}
   7101 	if {$vpd != ""} {
   7102 		mesg "vencrypt proxy: $vpd"
   7103 		if {$proxy != ""} {
   7104 			set proxy "$proxy,$vpd"
   7105 		} else {
   7106 			set proxy "$vpd"
   7107 		}
   7108 	}
   7109 	return $proxy
   7110 }
   7111 
   7112 proc no_certs_tutorial_mesg {} {
   7113 	global svcert crtdir
   7114 	global server_anondh
   7115 	global always_verify_ssl
   7116 
   7117 	set doit 0
   7118 	if {!$always_verify_ssl} {
   7119 		if {$svcert == ""} {
   7120 			if {$crtdir == "" || $crtdir == "ACCEPTED_CERTS"} {
   7121 				set doit 1
   7122 			}
   7123 		}
   7124 	} elseif {$server_anondh} {
   7125 		set doit 1
   7126 	}
   7127 	if {$doit} {
   7128 		mesg "INFO: without Certificate checking man-in-the-middle attack is possible."
   7129 	} else {
   7130 		set str ""
   7131 		catch {set str [.l cget -text]}
   7132 		if {$str != "" && [regexp {^INFO: without Certificate} $str]} {
   7133 			mesg ""
   7134 		}
   7135 	}
   7136 }
   7137 
   7138 proc vencrypt_tutorial_mesg {} {
   7139 	global use_ssh use_sshssl use_listen
   7140 	global server_vencrypt no_probe_vencrypt
   7141 	global ultra_dsm
   7142 
   7143 	set m ""
   7144 	if {$use_ssh} {
   7145 		;
   7146 	} elseif {$server_vencrypt} {
   7147 		;
   7148 	} elseif {$ultra_dsm} {
   7149 		;
   7150 	} elseif {$use_listen} {
   7151 		set m "No VeNCrypt Auto-Detection:  Listen mode."
   7152 	} elseif {$use_sshssl} {
   7153 		set m "No VeNCrypt Auto-Detection:  SSH+SSL mode."
   7154 	} elseif {$no_probe_vencrypt} {
   7155 		set m "No VeNCrypt Auto-Detection:  Disabled."
   7156 	}
   7157 	if {$m != ""} {
   7158 		mesg $m
   7159 		after 1000
   7160 	}
   7161 	return $m
   7162 
   7163 	#global svcert always_verify_ssl
   7164 	#$svcert != "" || !$always_verify_ssl
   7165 	#	set m "No VeNCrypt Auto-Detection: 'Verify All Certs' disabled"
   7166 }
   7167 
   7168 proc launch_unix {hp} {
   7169 	global smb_redir_0 smb_mounts env
   7170 	global vncauth_passwd use_unixpw unixpw_username unixpw_passwd
   7171 	global ssh_only ts_only use_x11cursor use_nobell use_rawlocal use_notty use_popupfix ssvnc_scale ssvnc_escape
   7172 	global ssvnc_encodings ssvnc_extra_opts
   7173 
   7174 	globalize
   7175 
   7176 	set cmd ""
   7177 
   7178 	if {[regexp {^vncssh://} $hp] || [regexp {^vnc\+ssh://} $hp]} {
   7179 		set use_ssl 0
   7180 		set use_ssh 1
   7181 		sync_use_ssl_ssh
   7182 	} elseif {[regexp {^vncs://} $hp] || [regexp {^vncssl://} $hp] || [regexp {^vnc\+ssl://} $hp]} {
   7183 		set use_ssl 1
   7184 		set use_ssh 0
   7185 		sync_use_ssl_ssh
   7186 	}
   7187 	if {[regexp {^rsh:/?/?} $hp]} {
   7188 		set use_ssl 0
   7189 		set use_ssh 1
   7190 		sync_use_ssl_ssh
   7191 	}
   7192 
   7193 	check_ssh_needed
   7194 
   7195 	set_smb_mounts
   7196 
   7197 	global did_port_knock
   7198 	set did_port_knock 0
   7199 	set pk_hp ""
   7200 
   7201 	set skip_ssh 0
   7202 	set do_direct 0
   7203 
   7204 	if [regexp {vnc://} $hp] {
   7205 		set skip_ssh 1
   7206 		set do_direct 1
   7207 		if {! [info exists env(SSVNC_NO_ENC_WARN)]} {
   7208 			direct_connect_msg
   7209 		}
   7210 	}
   7211 
   7212 	listen_verify_all_dialog $hp
   7213 
   7214 	if {! $do_direct} {
   7215 		if {! [check_for_listen_ssl_cert]} {
   7216 			return
   7217 		}
   7218 	}
   7219 
   7220 	global stunnel_extra_opts0 stunnel_extra_svc_opts0
   7221 	set stunnel_extra_opts0 ""
   7222 	set stunnel_extra_svc_opts0 ""
   7223 	global ssvnc_multiple_listen0
   7224 	set ssvnc_multiple_listen0 ""
   7225 
   7226 	if {[regexp -nocase {sslrepeater://} $hp]} {
   7227 		if {$disable_ssl_workarounds} {
   7228 			set disable_ssl_workarounds 0
   7229 			mesg "Disabling SSL workarounds for 'UVNC Single Click III Bug'"
   7230 			after 400
   7231 		}
   7232 	}
   7233 
   7234 	if [info exists env(STUNNEL_EXTRA_OPTS)] {
   7235 		set stunnel_extra_opts0 $env(STUNNEL_EXTRA_OPTS)
   7236 		if {$disable_ssl_workarounds} {
   7237 			if {$disable_ssl_workarounds_type == "none"} {
   7238 				;
   7239 			} elseif {$disable_ssl_workarounds_type == "noempty"} {
   7240 				set env(STUNNEL_EXTRA_OPTS) "$env(STUNNEL_EXTRA_OPTS)\noptions = DONT_INSERT_EMPTY_FRAGMENTS"
   7241 			}
   7242 		} else {
   7243 			set env(STUNNEL_EXTRA_OPTS) "$env(STUNNEL_EXTRA_OPTS)\noptions = ALL"
   7244 		}
   7245 	} else {
   7246 		if {$disable_ssl_workarounds} {
   7247 			if {$disable_ssl_workarounds_type == "none"} {
   7248 				;
   7249 			} elseif {$disable_ssl_workarounds_type == "noempty"} {
   7250 				set env(STUNNEL_EXTRA_OPTS) "options = DONT_INSERT_EMPTY_FRAGMENTS"
   7251 			}
   7252 		} else {
   7253 			set env(STUNNEL_EXTRA_OPTS) "options = ALL"
   7254 		}
   7255 	}
   7256 	if {$stunnel_local_protection && ! $use_listen} {
   7257 		if {$stunnel_local_protection_type == "ident"} {
   7258 			set user ""
   7259 			if {[info exists env(USER)]} {
   7260 				set user $env(USER)
   7261 			} elseif {[info exists env(LOGNAME)]} {
   7262 				set user $env(USER)
   7263 			}
   7264 			if {$user != ""} {
   7265 				if [info exists env(STUNNEL_EXTRA_SVC_OPTS)] {
   7266 					set stunnel_extra_svc_opts0 $env(STUNNEL_EXTRA_SVC_OPTS)
   7267 					set env(STUNNEL_EXTRA_SVC_OPTS) "$env(STUNNEL_EXTRA_SVC_OPTS)\nident = $user"
   7268 				} else {
   7269 					set env(STUNNEL_EXTRA_SVC_OPTS) "ident = $user"
   7270 				}
   7271 			}
   7272 		} elseif {$stunnel_local_protection_type == "exec"} {
   7273 			if [info exists env(STUNNEL_EXTRA_SVC_OPTS)] {
   7274 				set stunnel_extra_svc_opts0 $env(STUNNEL_EXTRA_SVC_OPTS)
   7275 				set env(STUNNEL_EXTRA_SVC_OPTS) "$env(STUNNEL_EXTRA_SVC_OPTS)\n#stunnel-exec"
   7276 			} else {
   7277 				set env(STUNNEL_EXTRA_SVC_OPTS) "#stunnel-exec"
   7278 			}
   7279 		}
   7280 	}
   7281 	if {$ultra_dsm} {
   7282 		if {$ultra_dsm_type == "securevnc"} {
   7283 			;
   7284 		} elseif {![file exists $ultra_dsm_file] && ![regexp {pw=} $ultra_dsm_file]} {
   7285 			mesg "DSM key file does exist: $ultra_dsm_file"
   7286 			bell
   7287 			after 1000
   7288 			return
   7289 		}
   7290 		global vncauth_passwd
   7291 		if {$ultra_dsm_file == "pw=VNCPASSWORD" || $ultra_dsm_file == "pw=VNCPASSWD"} {
   7292 			if {![info exists vncauth_passwd] || $vncauth_passwd == ""} {
   7293 				mesg "For DSM pw=VNCPASSWD you must supply the VNC Password"
   7294 				bell
   7295 				after 1000
   7296 				return
   7297 			}
   7298 			if [regexp {'} $vncauth_passwd] {
   7299 				mesg "For DSM pw=VNCPASSWD password must not contain single quotes."
   7300 				bell
   7301 				after 1000
   7302 				return
   7303 			}
   7304 		}
   7305 		set dsm "ultravnc_dsm_helper "
   7306 		if {$ultra_dsm_noultra} {
   7307 			append dsm "noultra:"
   7308 		}
   7309 		if {$use_listen} {
   7310 			append dsm "rev:"
   7311 		}
   7312 		if {$ultra_dsm_type == "guess"} {
   7313 			append dsm "."
   7314 		} else {
   7315 			append dsm $ultra_dsm_type
   7316 		}
   7317 		if {$ultra_dsm_noultra} {
   7318 			if {$ultra_dsm_salt != ""} {
   7319 				append dsm "@$ultra_dsm_salt"
   7320 			}
   7321 		}
   7322 		if {$ultra_dsm_file == "pw=VNCPASSWORD" || $ultra_dsm_file == "pw=VNCPASSWD"} {
   7323 			append dsm " pw='$vncauth_passwd'"
   7324 		} else {
   7325 			if {$ultra_dsm_file == "" && $ultra_dsm_type == "securevnc"} {
   7326 				append dsm " none"
   7327 			} else {
   7328 				append dsm " $ultra_dsm_file"
   7329 			}
   7330 		}
   7331 		set env(SSVNC_ULTRA_DSM) $dsm
   7332 	}
   7333 	if {$multiple_listen && $use_listen} {
   7334 		if [info exists env(SSVNC_MULTIPLE_LISTEN)] {
   7335 			set ssvnc_multiple_listen0 $env(SSVNC_MULTIPLE_LISTEN)
   7336 		}
   7337 		set env(SSVNC_MULTIPLE_LISTEN) "1"
   7338 	}
   7339 
   7340 	if {$use_ssh} {
   7341 		;
   7342 	} elseif {$use_sshssl} {
   7343 		;
   7344 	} elseif {$use_ssl} {
   7345 		set prox  [get_ssh_proxy $hp]
   7346 		if {$prox != "" && [regexp {@} $prox]} {
   7347 			mesg "Error: proxy contains '@'  Did you mean to use SSH mode?"
   7348 			bell
   7349 			return
   7350 		}
   7351 		if [regexp {@} $hp] {
   7352 			mesg "Error: host contains '@'  Did you mean to use SSH mode?"
   7353 			bell
   7354 			return
   7355 		}
   7356 	}
   7357 
   7358 	if {$use_ssh || $use_sshssl} {
   7359 		if {$ssh_local_protection} {
   7360 			if {![info exists env(LIM_ACCEPT)]} {
   7361 				set env(LIM_ACCEPT) 1
   7362 			}
   7363 			if {![info exists env(LIM_ACCEPT_TIME)]} {
   7364 				set env(LIM_ACCEPT_TIME) 35
   7365 			}
   7366 			set env(SSVNC_LIM_ACCEPT_PRELOAD) "lim_accept.so"
   7367 			mesg "SSH LIM_ACCEPT($env(LIM_ACCEPT),$env(LIM_ACCEPT_TIME)): lim_accept.so"
   7368 			after 700
   7369 		}
   7370 		if {$skip_ssh || $ultra_dsm} {
   7371 			set cmd "ss_vncviewer"
   7372 		} elseif {$use_ssh} {
   7373 			set cmd "ss_vncviewer -ssh"
   7374 		} else {
   7375 			set cmd "ss_vncviewer -sshssl"
   7376 			if {$mycert != ""} {
   7377 				set cmd "$cmd -mycert '$mycert'"
   7378 			}
   7379 			if {$crlfil != ""} {
   7380 				set cmd "$cmd -crl '$crlfil'"
   7381 			}
   7382 			if {$svcert != ""} {
   7383 				set cmd "$cmd -verify '$svcert'"
   7384 			} elseif {$crtdir != "" && $crtdir != "ACCEPTED_CERTS"} {
   7385 				set cmd "$cmd -verify '$crtdir'"
   7386 			}
   7387 		}
   7388 		if {$use_listen} {
   7389 			set cmd "$cmd -listen"
   7390 		}
   7391 		if {$ssh_local_protection} {
   7392 			regsub {ss_vncviewer} $cmd "ssvnc_cmd" cmd
   7393 		}
   7394 		set hpnew  [get_ssh_hp $hp]
   7395 		set proxy  [get_ssh_proxy $hp]
   7396 		set sshcmd [get_ssh_cmd $hp]
   7397 
   7398 		if {$use_sshssl} {
   7399 			if {!$do_direct} {
   7400 				set proxy [maybe_add_vencrypt $proxy $hp]
   7401 			}
   7402 		}
   7403 
   7404 		if {$ts_only} {
   7405 			regsub {:0$} $hpnew "" hpnew
   7406 			if {$proxy == ""} {
   7407 				# XXX host_part
   7408 				if {[regexp {^([^:]*):([0-9][0-9]*)$} $hpnew mv sshhst sshpt]} {
   7409 					set proxy "$sshhst:$sshpt"
   7410 					set hpnew "localhost"
   7411 				}
   7412 			} else {
   7413 				if {![regexp {,} $proxy]} {
   7414 					if {$hpnew != "localhost"} {
   7415 						set proxy "$proxy,$hpnew"
   7416 						set hpnew "localhost"
   7417 					}
   7418 				}
   7419 			}
   7420 		}
   7421 
   7422 #puts hp=$hp
   7423 #puts hpn=$hpnew
   7424 #puts pxy=$proxy
   7425 #puts cmd=$sshcmd
   7426 
   7427 		set hp $hpnew
   7428 
   7429 		if {$proxy != ""} {
   7430 			set cmd "$cmd -proxy '$proxy'"
   7431 			set pk_hp $proxy
   7432 		}
   7433 		if {$pk_hp == ""} {
   7434 			set pk_hp $hp
   7435 		}
   7436 
   7437 		set do_pre 0
   7438 		if {$use_smbmnt}  {
   7439 			set do_pre 1
   7440 		} elseif {$use_sound && $sound_daemon_kill} {
   7441 			set do_pre 1
   7442 		}
   7443 		global skip_pre
   7444 		if {$skip_pre || $skip_ssh} {
   7445 			set do_pre 0
   7446 			set skip_pre 0
   7447 		}
   7448 
   7449 		set tag [contag]
   7450 
   7451 		if {$do_pre} {
   7452 			do_unix_pre $tag $proxy $hp $pk_hp
   7453 		}
   7454 
   7455 
   7456 		set setup_cmds [ugly_setup_scripts post $tag]
   7457 
   7458 		if {$skip_ssh} {
   7459 			set setup_cmds ""
   7460 		}
   7461 		if {$sshcmd != "SHELL" && [regexp -nocase {x11vnc} $sshcmd]} {
   7462 			global use_cups cups_x11vnc cups_remote_port
   7463 			global cups_remote_smb_port
   7464 			global use_sound sound_daemon_x11vnc sound_daemon_remote_port
   7465 			global ts_only
   7466 			if {$ts_only} {
   7467 				set cups_x11vnc 1
   7468 				set sound_daemon_x11vnc 1
   7469 			}
   7470 			if {$use_cups && $cups_x11vnc && $cups_remote_port != ""} {
   7471 				set crp $cups_remote_port
   7472 				if {$ts_only} {
   7473 					set cups_remote_port [rand_port]
   7474 					set crp "DAEMON-$cups_remote_port"
   7475 				}
   7476 				set sshcmd "$sshcmd -env FD_CUPS=$crp"
   7477 			}
   7478 			if {$use_cups && $cups_x11vnc && $cups_remote_smb_port != ""} {
   7479 				set csp $cups_remote_smb_port
   7480 				if {$ts_only} {
   7481 					set cups_remote_smb_port [rand_port]
   7482 					set csp "DAEMON-$cups_remote_smb_port"
   7483 				}
   7484 				set sshcmd "$sshcmd -env FD_SMB=$csp"
   7485 			}
   7486 			if {$use_sound && $sound_daemon_x11vnc && $sound_daemon_remote_port != ""} {
   7487 				set srp $sound_daemon_remote_port
   7488 				if {$ts_only} {
   7489 					set sound_daemon_remote_port [rand_port]
   7490 					set srp "DAEMON-$sound_daemon_remote_port"
   7491 				}
   7492 				set sshcmd "$sshcmd -env FD_ESD=$srp"
   7493 			}
   7494 		}
   7495 
   7496 		if {$sshcmd == "SHELL"} {
   7497 			set env(SS_VNCVIEWER_SSH_CMD) {$SHELL}
   7498 			set env(SS_VNCVIEWER_SSH_ONLY) 1
   7499 		} elseif {$setup_cmds != ""} {
   7500 			if {$sshcmd == ""} {
   7501 				set sshcmd "sleep 15"
   7502 			}
   7503 			set env(SS_VNCVIEWER_SSH_CMD) "$setup_cmds$sshcmd"
   7504 		} else {
   7505 			if {$sshcmd != ""} {
   7506 				set cmd "$cmd -sshcmd '$sshcmd'"
   7507 			}
   7508 		}
   7509 
   7510 		set sshargs ""
   7511 		if {$use_cups} {
   7512 			append sshargs [get_cups_redir]
   7513 		}
   7514 		if {$use_sound} {
   7515 			append sshargs [get_sound_redir]
   7516 		}
   7517 		if {$additional_port_redirs} {
   7518 			append sshargs [get_additional_redir]
   7519 		}
   7520 
   7521 		set sshargs [string trim $sshargs]
   7522 		if {$skip_ssh} {
   7523 			set sshargs ""
   7524 		}
   7525 		if {$sshargs != ""} {
   7526 			set cmd "$cmd -sshargs '$sshargs'"
   7527 			set env(SS_VNCVIEWER_USE_C) 1
   7528 		} else {
   7529 			# hmm we used to have it off... why?
   7530 			# ssh typing response?
   7531 			set env(SS_VNCVIEWER_USE_C) 1
   7532 		}
   7533 		if {$sshcmd == "SHELL"} {
   7534 			set env(SS_VNCVIEWER_SSH_ONLY) 1
   7535 			if {$proxy == ""} {
   7536 				set hpt $hpnew
   7537 				# XXX host_part
   7538 				regsub {:[0-9][0-9]*$} $hpt "" hpt
   7539 				set cmd "$cmd -proxy '$hpt'"
   7540 			}
   7541 			set geometry [xterm_center_geometry]
   7542 			if {$pk_hp == ""} {
   7543 				set pk_hp $hp
   7544 			}
   7545 			if {! $did_port_knock} {
   7546 				if {! [do_port_knock $pk_hp start]} {
   7547 					reset_stunnel_extra_opts
   7548 					return
   7549 				}
   7550 				set did_port_knock 1
   7551 			}
   7552 
   7553 			if {[regexp {FINISH} $port_knocking_list]} {
   7554 				wm withdraw .
   7555 				update
   7556 				unix_terminal_cmd $geometry "SHELL to $hp" "$cmd"
   7557 				wm deiconify .
   7558 				update
   7559 				do_port_knock $pk_hp finish
   7560 			} else {
   7561 				unix_terminal_cmd $geometry "SHELL to $hp" "$cmd" 1
   7562 			}
   7563 			set env(SS_VNCVIEWER_SSH_CMD) ""
   7564 			set env(SS_VNCVIEWER_SSH_ONLY) ""
   7565 			set env(SS_VNCVIEWER_USE_C) ""
   7566 			reset_stunnel_extra_opts
   7567 			return
   7568 		}
   7569 	} else {
   7570 		set cmd "ssvnc_cmd"
   7571 		set hpnew  [get_ssh_hp $hp]
   7572 		set proxy  [get_ssh_proxy $hp]
   7573 
   7574 		if {!$do_direct && ![repeater_proxy_check $proxy]} {
   7575 			reset_stunnel_extra_opts
   7576 			return
   7577 		}
   7578 
   7579 		if {! $do_direct && ! $ultra_dsm && ![regexp -nocase {ssh://} $hpnew]} {
   7580 			set did_check 0
   7581 			if {$mycert != ""} {
   7582 				set cmd "$cmd -mycert '$mycert'"
   7583 			}
   7584 			if {$crlfil != ""} {
   7585 				set cmd "$cmd -crl '$crlfil'"
   7586 			}
   7587 			if {$svcert != ""} {
   7588 				set cmd "$cmd -verify '$svcert'"
   7589 			} elseif {$crtdir != ""} {
   7590 				if {$crtdir == "ACCEPTED_CERTS"} {
   7591 					global skip_verify_accepted_certs
   7592 					set skip_verify_accepted_certs 0
   7593 
   7594 					set did_check 1
   7595 					if {! [check_accepted_certs 0]} {
   7596 						reset_stunnel_extra_opts
   7597 						return
   7598 					}
   7599 					if {! $skip_verify_accepted_certs} {
   7600 						set adir [get_idir_certs ""]
   7601 						set adir "$adir/accepted"
   7602 						catch {file mkdir $adir}
   7603 						set cmd "$cmd -verify '$adir'"
   7604 					}
   7605 
   7606 				} else {
   7607 					set cmd "$cmd -verify '$crtdir'"
   7608 				}
   7609 			}
   7610 			if {! $did_check} {
   7611 				check_accepted_certs 1
   7612 			}
   7613 		}
   7614 
   7615 		if {!$do_direct} {
   7616 			set proxy [maybe_add_vencrypt $proxy $hp]
   7617 		}
   7618 
   7619 		if {$proxy != ""} {
   7620 			set cmd "$cmd -proxy '$proxy'"
   7621 		}
   7622 		set hp $hpnew
   7623 		if [regexp {^.*@} $hp match] {
   7624 			catch {raise .; update}
   7625 			mesg "Trimming \"$match\" from hostname"
   7626 			after 700
   7627 			regsub {^.*@} $hp "" hp
   7628 		}
   7629 		if [regexp {@} $proxy] {
   7630 			bell
   7631 			catch {raise .; update}
   7632 			mesg "WARNING: SSL proxy contains \"@\" sign"
   7633 			after 1500
   7634 		}
   7635 	}
   7636 
   7637 	global anon_dh_detected
   7638 	if {$anon_dh_detected || $server_anondh} {
   7639 		if {!$do_direct} {
   7640 			set cmd "$cmd -anondh"
   7641 		}
   7642 		set anon_dh_detected 0
   7643 	}
   7644 	if {$use_alpha} {
   7645 		set cmd "$cmd -alpha"
   7646 	}
   7647 	if {$use_send_clipboard} {
   7648 		set cmd "$cmd -sendclipboard"
   7649 	}
   7650 	if {$use_send_always} {
   7651 		set cmd "$cmd -sendalways"
   7652 	}
   7653 	if {$use_turbovnc} {
   7654 		set env(SSVNC_TURBOVNC) 1
   7655 	}
   7656 	if {$disable_pipeline} {
   7657 		set env(VNCVIEWER_NO_PIPELINE_UPDATES) 1
   7658 	}
   7659 	if {$ssh_known_hosts_filename != ""} {
   7660 		set env(SSVNC_KNOWN_HOSTS_FILE) $ssh_known_hosts_filename
   7661 	}
   7662 	if {$use_grab} {
   7663 		set cmd "$cmd -grab"
   7664 	}
   7665 	if {$use_x11cursor} {
   7666 		set cmd "$cmd -x11cursor"
   7667 	}
   7668 	if {$use_nobell} {
   7669 		set cmd "$cmd -nobell"
   7670 	}
   7671 	if {$use_rawlocal} {
   7672 		set cmd "$cmd -rawlocal"
   7673 	}
   7674 	if {$use_notty} {
   7675 		set env(VNCVIEWER_NOTTY) 1
   7676 	}
   7677 	if {$use_popupfix} {
   7678 		set cmd "$cmd -popupfix"
   7679 	}
   7680 	if {$ssvnc_scale != ""} {
   7681 		set cmd "$cmd -scale '$ssvnc_scale'"
   7682 	}
   7683 	if {$ssvnc_escape != ""} {
   7684 		set cmd "$cmd -escape '$ssvnc_escape'"
   7685 	}
   7686 	if {$ssvnc_encodings != ""} {
   7687 		set cmd "$cmd -ssvnc_encodings '$ssvnc_encodings'"
   7688 	}
   7689 	if {$ssvnc_extra_opts != ""} {
   7690 		set cmd "$cmd -ssvnc_extra_opts '$ssvnc_extra_opts'"
   7691 	}
   7692 	if {$rfbversion != ""} {
   7693 		set cmd "$cmd -rfbversion '$rfbversion'"
   7694 	}
   7695 	if {$vncviewer_realvnc4} {
   7696 		set cmd "$cmd -realvnc4"
   7697 	}
   7698 	if {$use_listen} {
   7699 		set cmd "$cmd -listen"
   7700 		if {$listen_once} {
   7701 			set cmd "$cmd -onelisten"
   7702 		}
   7703 		if {$listen_accept_popup} {
   7704 			if {$listen_accept_popup_sc} {
   7705 				set env(SSVNC_ACCEPT_POPUP_SC) 1
   7706 			} else {
   7707 				set env(SSVNC_ACCEPT_POPUP) 1
   7708 			}
   7709 		}
   7710 	}
   7711 
   7712 	global darwin_cotvnc
   7713 	if {$darwin_cotvnc} {
   7714 		set env(DARWIN_COTVNC) 1
   7715 	} else {
   7716 		if [info exists env(DISPLAY)] {
   7717 			if {$env(DISPLAY) != ""} {
   7718 				set env(DARWIN_COTVNC) 0
   7719 			} else {
   7720 				set env(DARWIN_COTVNC) 1
   7721 			}
   7722 		} else {
   7723 			set env(DARWIN_COTVNC) 1
   7724 		}
   7725 	}
   7726 
   7727 	set do_vncspacewrapper 0
   7728 	if {$change_vncviewer && $change_vncviewer_path != ""} {
   7729 		set path [string trim $change_vncviewer_path]
   7730 		if [regexp {^["'].} $path]  {	# "
   7731 			set tmp "/tmp/vncspacewrapper.[tpid]"
   7732 			set tmp [mytmp $tmp]
   7733 			set do_vncspacewrapper 1
   7734 			if {0} {
   7735 				catch {file delete $tmp}
   7736 				if {[file exists $tmp]} {
   7737 					catch {destroy .c}
   7738 					mesg "file still exists: $tmp"
   7739 					bell
   7740 					reset_stunnel_extra_opts
   7741 					return
   7742 				}
   7743 			}
   7744 			catch {set fh [open $tmp "w"]}
   7745 			catch {exec chmod 700 $tmp}
   7746 			if {! [file exists $tmp]} {
   7747 				catch {destroy .c}
   7748 				mesg "cannot create: $tmp"
   7749 				bell
   7750 				reset_stunnel_extra_opts
   7751 				return
   7752 			}
   7753 			puts $fh "#!/bin/sh"
   7754 			puts $fh "echo $tmp; set -xv"
   7755 			puts $fh "$path \"\$@\""
   7756 			puts $fh "sleep 1; rm -f $tmp"
   7757 			close $fh
   7758 			set path $tmp
   7759 		}
   7760 		set env(VNCVIEWERCMD) $path
   7761 	} else {
   7762 		if [info exists env(VNCVIEWERCMD_OVERRIDE)] {
   7763 			set env(VNCVIEWERCMD) $env(VNCVIEWERCMD_OVERRIDE)
   7764 		} else {
   7765 			set env(VNCVIEWERCMD) ""
   7766 		}
   7767 	}
   7768 
   7769 	set realvnc4 $vncviewer_realvnc4
   7770 	set realvnc3 0
   7771 	set flavor ""
   7772 	if {! $darwin_cotvnc} {
   7773 		set done 0
   7774 		if {$do_vncspacewrapper} {
   7775 			if [regexp -nocase {ultra} $change_vncviewer_path] {
   7776 				set done 1
   7777 				set flavor "ultravnc"
   7778 			} elseif [regexp -nocase {chicken.of} $change_vncviewer_path] {
   7779 				set done 1
   7780 				set flavor "cotvnc"
   7781 			}
   7782 		}
   7783 		if {! $done} {
   7784 			catch {set flavor [exec ss_vncviewer -viewerflavor 2>/dev/null]}
   7785 		}
   7786 	}
   7787 	if [regexp {realvnc4} $flavor] {
   7788 		set realvnc4 1
   7789 	}
   7790 	if [regexp {tightvnc} $flavor] {
   7791 		set realvnc4 0
   7792 	}
   7793 	if [regexp {realvnc3} $flavor] {
   7794 		set realvnc4 0
   7795 		set realvnc3 1
   7796 	}
   7797 	if {$realvnc4} {
   7798 		set cmd "$cmd -realvnc4"
   7799 	}
   7800 
   7801 	set cmd "$cmd $hp"
   7802 
   7803 	set passwdfile ""
   7804 	if {$vncauth_passwd != ""} {
   7805 		global use_listen
   7806 		set footest [mytmp /tmp/.check.[tpid]]
   7807 		catch {file delete $footest}
   7808 		global mktemp
   7809 		set passwdfile "/tmp/.vncauth_tmp.[tpid]"
   7810 		if {$mktemp == ""} {
   7811 			set passwdfile "$env(SSVNC_HOME)/.vncauth_tmp.[tpid]"
   7812 		}
   7813 
   7814 		set passwdfile [mytmp $passwdfile]
   7815 		catch {exec vncstorepw $vncauth_passwd $passwdfile}
   7816 		catch {exec chmod 600 $passwdfile}
   7817 		if {$use_listen} {
   7818 			global env
   7819 			set env(SS_VNCVIEWER_RM) $passwdfile
   7820 		} else {
   7821 			if {$darwin_cotvnc} {
   7822 				catch {exec sh -c "sleep 60; rm $passwdfile 2>/dev/null" &}
   7823 			} else {
   7824 				catch {exec sh -c "sleep 20; rm $passwdfile 2>/dev/null" &}
   7825 			}
   7826 		}
   7827 		if {$darwin_cotvnc} {
   7828 			set cmd "$cmd --PasswordFile $passwdfile"
   7829 		} elseif {$flavor == "unknown"} {
   7830 			;
   7831 		} else {
   7832 			set cmd "$cmd -passwd $passwdfile"
   7833 		}
   7834 	}
   7835 
   7836 	if {$use_viewonly} {
   7837 		if {$darwin_cotvnc} {
   7838 			set cmd "$cmd --ViewOnly"
   7839 		} elseif {$flavor == "unknown"} {
   7840 			;
   7841 		} elseif {$flavor == "ultravnc"} {
   7842 			set cmd "$cmd /viewonly"
   7843 		} else {
   7844 			set cmd "$cmd -viewonly"
   7845 		}
   7846 	}
   7847 	if {$use_fullscreen} {
   7848 		if {$darwin_cotvnc} {
   7849 			set cmd "$cmd --FullScreen"
   7850 		} elseif {$flavor == "ultravnc"} {
   7851 			set cmd "$cmd /fullscreen"
   7852 		} elseif {$flavor == "unknown"} {
   7853 			if [regexp {vinagre} $change_vncviewer_path] {
   7854 				set cmd "$cmd -f"
   7855 			}
   7856 		} else {
   7857 			set cmd "$cmd -fullscreen"
   7858 		}
   7859 	}
   7860 	if {$use_bgr233} {
   7861 		if {$realvnc4} {
   7862 			set cmd "$cmd -lowcolourlevel 1"
   7863 		} elseif {$flavor == "ultravnc"} {
   7864 			set cmd "$cmd /8bit"
   7865 		} elseif {$flavor == "ultravnc"} {
   7866 			;
   7867 		} elseif {$flavor == "unknown"} {
   7868 			;
   7869 		} else {
   7870 			set cmd "$cmd -bgr233"
   7871 		}
   7872 	}
   7873 	if {$use_nojpeg} {
   7874 		if {$darwin_cotvnc} {
   7875 			;
   7876 		} elseif {$flavor == "ultravnc"} {
   7877 			;
   7878 		} elseif {$flavor == "unknown"} {
   7879 			;
   7880 		} elseif {! $realvnc4 && ! $realvnc3} {
   7881 			set cmd "$cmd -nojpeg"
   7882 		}
   7883 	}
   7884 	if {! $use_raise_on_beep} {
   7885 		if {$darwin_cotvnc} {
   7886 			;
   7887 		} elseif {$flavor == "ultravnc"} {
   7888 			;
   7889 		} elseif {$flavor == "unknown"} {
   7890 			;
   7891 		} elseif {! $realvnc4 && ! $realvnc3} {
   7892 			set cmd "$cmd -noraiseonbeep"
   7893 		}
   7894 	}
   7895 	if {$use_compresslevel != "" && $use_compresslevel != "default"} {
   7896 		if {$realvnc3} {
   7897 			;
   7898 		} elseif {$flavor == "ultravnc"} {
   7899 			;
   7900 		} elseif {$flavor == "unknown"} {
   7901 			;
   7902 		} elseif {$realvnc4} {
   7903 			set cmd "$cmd -zliblevel '$use_compresslevel'"
   7904 		} else {
   7905 			set cmd "$cmd -compresslevel '$use_compresslevel'"
   7906 		}
   7907 	}
   7908 	if {$use_quality != "" && $use_quality != "default"} {
   7909 		if {$darwin_cotvnc} {
   7910 			;
   7911 		} elseif {$flavor == "ultravnc"} {
   7912 			;
   7913 		} elseif {$flavor == "unknown"} {
   7914 			;
   7915 		} elseif {! $realvnc4 && ! $realvnc3} {
   7916 			set cmd "$cmd -quality '$use_quality'"
   7917 		}
   7918 	}
   7919 	if {$use_ssh || $use_sshssl} {
   7920 		# realvnc4 -preferredencoding zrle
   7921 		if {$darwin_cotvnc} {
   7922 			;
   7923 		} elseif {$flavor == "ultravnc"} {
   7924 			;
   7925 		} elseif {$flavor == "unknown"} {
   7926 			;
   7927 		} elseif {$realvnc4} {
   7928 			set cmd "$cmd -preferredencoding zrle"
   7929 		} else {
   7930 			set cmd "$cmd -encodings 'copyrect tight zrle zlib hextile'"
   7931 		}
   7932 	}
   7933 
   7934 	global ycrop_string
   7935 	global sbwid_string
   7936 	catch {unset env(VNCVIEWER_SBWIDTH)}
   7937 	catch {unset env(VNCVIEWER_YCROP)}
   7938 	if {[info exists ycrop_string] && $ycrop_string != ""}  {
   7939 		set t $ycrop_string
   7940 		if [regexp {,sb=([0-9][0-9]*)} $t m mv1]  {
   7941 			set env(VNCVIEWER_SBWIDTH) $mv1
   7942 		}
   7943 		regsub {,sb=([0-9][0-9]*)} $t "" t
   7944 		if {$t != ""} {
   7945 			set env(VNCVIEWER_YCROP) $t
   7946 		}
   7947 	}
   7948 	if {[info exists sbwid_string] && $sbwid_string != ""}  {
   7949 		set t $sbwid_string
   7950 		set env(VNCVIEWER_SBWIDTH) $sbwid_string
   7951 		if {$t != ""} {
   7952 			set env(VNCVIEWER_SBWIDTH) $t
   7953 		}
   7954 	}
   7955 
   7956 	catch {destroy .o}
   7957 	catch {destroy .oa}
   7958 	catch {destroy .os}
   7959 	update
   7960 
   7961 	if {$use_sound && $sound_daemon_local_start && $sound_daemon_local_cmd != ""} {
   7962 		mesg "running: $sound_daemon_local_cmd"
   7963 		global sound_daemon_local_pid
   7964 		set sound_daemon_local_pid ""
   7965 		#exec sh -c "$sound_daemon_local_cmd " >& /dev/null </dev/null &
   7966 		set sound_daemon_local_pid [exec sh -c "echo \$\$; exec $sound_daemon_local_cmd </dev/null 1>/dev/null 2>/dev/null &"]
   7967 		update
   7968 		after 500
   7969 	}
   7970 
   7971 	if {$pk_hp == ""} {
   7972 		set pk_hp $hp
   7973 	}
   7974 	if {! $did_port_knock} {
   7975 		if {! [do_port_knock $pk_hp start]} {
   7976 			wm deiconify .
   7977 			update
   7978 			reset_stunnel_extra_opts
   7979 			return
   7980 		}
   7981 		set did_port_knock 1
   7982 	}
   7983 
   7984 	init_unixpw $hp
   7985 
   7986 	if {! $do_direct} {
   7987 		vencrypt_tutorial_mesg
   7988 	}
   7989 
   7990 	wm withdraw .
   7991 	update
   7992 
   7993 	set geometry [xterm_center_geometry]
   7994 	set xrm1 "*.srinterCommand:true"
   7995 	set xrm2 $xrm1
   7996 	set xrm3 $xrm1
   7997 	if {[info exists env(SSVNC_GUI_CMD)]} {
   7998 		set xrm1 "*.printerCommand:env XTERM_PRINT=1 $env(SSVNC_GUI_CMD)"
   7999 		set xrm2 "XTerm*VT100*translations:#override Shift<Btn3Down>:print()\\nCtrl<Key>N:print()"
   8000 		set xrm3 "*mainMenu*print*Label:  New SSVNC_GUI"
   8001 	}
   8002 	set m "Done. You Can X-out or Ctrl-C this Terminal if you like.  Use Ctrl-\\\\ to pause."
   8003 	global uname
   8004 	if {$uname == "Darwin"} {
   8005 		regsub {X-out or } $m "" m
   8006 	}
   8007 	set te "set -xv; "
   8008 	if {$ts_only} {
   8009 		set te ""
   8010 	}
   8011 
   8012 	global extra_sleep
   8013 	set ssvnc_extra_sleep_save ""
   8014 	if {$extra_sleep != ""} {
   8015 		if [info exists env(SSVNC_EXTRA_SLEEP)] {
   8016 			set ssvnc_extra_sleep_save $env(SSVNC_EXTRA_SLEEP)
   8017 		}
   8018 		set env(SSVNC_EXTRA_SLEEP) $extra_sleep
   8019 	}
   8020 
   8021 	set sstx "SSL/SSH VNC Viewer"
   8022 	set hptx $hp
   8023 	global use_listen
   8024 	if {$use_listen} {
   8025 		set sstx "SSVNC"
   8026 		set hptx "$hp (Press Ctrl-C to Stop Listening)"
   8027 	}
   8028 
   8029 
   8030 	set s1 5
   8031 	set s2 4
   8032 	if [info exists env(SSVNC_FINISH_SLEEP)] {
   8033 		set s1 $env(SSVNC_FINISH_SLEEP);
   8034 		set s2 $s1
   8035 	}
   8036 
   8037 	unix_terminal_cmd $geometry "$sstx $hptx" \
   8038 	"$te$cmd; set +xv; ulimit -c 0; trap 'printf \"Paused. Press Enter to exit:\"; read x' QUIT; echo; echo $m; echo; echo sleep $s1; echo; sleep $s2" 0 $xrm1 $xrm2 $xrm3
   8039 
   8040 	set env(SS_VNCVIEWER_SSH_CMD) ""
   8041 	set env(SS_VNCVIEWER_USE_C) ""
   8042 
   8043 	if {$extra_sleep != ""} {
   8044 		if {$ssvnc_extra_sleep_save != ""} {
   8045 			set env(SSVNC_EXTRA_SLEEP) $ssvnc_extra_sleep_save
   8046 		} else {
   8047 			catch {unset env(SSVNC_EXTRA_SLEEP)}
   8048 		}
   8049 	}
   8050 
   8051 	if {$use_sound && $sound_daemon_local_kill && $sound_daemon_local_cmd != ""} {
   8052 		# XXX need to kill just one...
   8053 		set daemon [string trim $sound_daemon_local_cmd]
   8054 		regsub {^gw[ \t]*} $daemon "" daemon
   8055 		regsub {[ \t].*$} $daemon "" daemon
   8056 		regsub {^.*/} $daemon "" daemon
   8057 		mesg "killing sound daemon: $daemon"
   8058 		global sound_daemon_local_pid
   8059 		if {$sound_daemon_local_pid != ""} {
   8060 #puts pid=$sound_daemon_local_pid
   8061 			catch {exec sh -c "kill $sound_daemon_local_pid"  >/dev/null 2>/dev/null </dev/null &}
   8062 			incr sound_daemon_local_pid
   8063 			catch {exec sh -c "kill $sound_daemon_local_pid"  >/dev/null 2>/dev/null </dev/null &}
   8064 			set sound_daemon_local_pid ""
   8065 		} elseif {$daemon != ""} {
   8066 			catch {exec sh -c "killall $daemon"  >/dev/null 2>/dev/null </dev/null &}
   8067 			catch {exec sh -c "pkill -x $daemon" >/dev/null 2>/dev/null </dev/null &}
   8068 		}
   8069 	}
   8070 	if {$passwdfile != ""} {
   8071 		catch {file delete $passwdfile}
   8072 	}
   8073 	wm deiconify .
   8074 	mac_raise
   8075 	mesg "Disconnected from $hp"
   8076 	if {[regexp {FINISH} $port_knocking_list]} {
   8077 		do_port_knock $pk_hp finish
   8078 	}
   8079 
   8080 	reset_stunnel_extra_opts
   8081 
   8082 	fini_unixpw
   8083 }
   8084 
   8085 proc kill_stunnel {pids} {
   8086 	set count 0
   8087 	foreach pid $pids {
   8088 		mesg "killing STUNNEL pid: $pid"
   8089 		winkill $pid
   8090 		if {$count == 0} {
   8091 			after 600
   8092 		} else {
   8093 			after 300
   8094 		}
   8095 		incr count
   8096 	}
   8097 }
   8098 
   8099 proc get_task_list {} {
   8100 	global is_win9x
   8101 
   8102 	set output1 ""
   8103 	set output2 ""
   8104 	if {! $is_win9x} {
   8105 		# try for tasklist on XP pro
   8106 		catch {set output1 [exec tasklist.exe]}
   8107 	}
   8108 	catch {set output2 [exec w98/tlist.exe]}
   8109 
   8110 	set output $output1
   8111 	append output "\n"
   8112 	append output $output2
   8113 
   8114 	return $output
   8115 }
   8116 
   8117 proc note_stunnel_pids {when} {
   8118 	global is_win9x pids_before pids_after pids_new
   8119 
   8120 	if {$when == "before"} {
   8121 		array unset pids_before
   8122 		array unset pids_after
   8123 		set pids_new {}
   8124 		set pids_before(none) "none"
   8125 		set pids_after(none)  "none"
   8126 	}
   8127 
   8128 	set output [get_task_list]
   8129 
   8130 	foreach line [split $output "\n\r"] {
   8131 		set m 0
   8132 		if [regexp -nocase {stunnel} $line] {
   8133 			set m 1
   8134 		} elseif [regexp -nocase {connect_br} $line] {
   8135 			set m 1
   8136 		}
   8137 		if {$m} {
   8138 			if [regexp {(-?[0-9][0-9]*)} $line m p] {
   8139 				if {$when == "before"} {
   8140 					set pids_before($p) $line
   8141 				} else {
   8142 					set pids_after($p) $line
   8143 				}
   8144 			}
   8145 		}
   8146 	}
   8147 	if {$when == "after"} {
   8148 		foreach new [array names pids_after] {
   8149 			if {! [info exists pids_before($new)]} {
   8150 				lappend pids_new $new
   8151 			}
   8152 		}
   8153 	}
   8154 }
   8155 
   8156 proc del_launch_windows_ssh_files {} {
   8157 	global launch_windows_ssh_files
   8158 	global env
   8159 
   8160 	if {[info exists env(SSVNC_NO_DELETE)]} {
   8161 		return
   8162 	}
   8163 
   8164 	if {$launch_windows_ssh_files != ""} {
   8165 		foreach tf [split $launch_windows_ssh_files] {
   8166 			if {$tf == ""} {
   8167 				continue
   8168 			}
   8169 			catch {file delete $tf}
   8170 		}
   8171 	}
   8172 }
   8173 
   8174 proc launch_shell_only {} {
   8175 	global is_windows
   8176 	global skip_pre
   8177 	global use_ssl use_ssh use_sshssl
   8178 
   8179 	set hp [get_vncdisplay]
   8180 	regsub {cmd=.*$} $hp "" hp
   8181 	set hp [string trim $hp]
   8182 	if {$is_windows} {
   8183 		append hp " cmd=PUTTY"
   8184 	} else {
   8185 		append hp " cmd=SHELL"
   8186 	}
   8187 	set use_ssl_save $use_ssl
   8188 	set use_ssh_save $use_ssh
   8189 	set use_sshssl_save $use_sshssl
   8190 	set skip_pre 1
   8191 	if {! $use_ssh && ! $use_sshssl} {
   8192 		set use_ssh 1
   8193 		set use_ssl 1
   8194 	}
   8195 	launch $hp
   8196 
   8197 	set use_ssl $use_ssl_save
   8198 	set use_ssh $use_ssh_save
   8199 	set use_sshssl $use_sshssl_save
   8200 }
   8201 
   8202 proc to_sshonly {} {
   8203 	global ssh_only ts_only env
   8204 	global showing_no_encryption
   8205 	#if {$showing_no_encryption} {
   8206 	#	toggle_no_encryption
   8207 	#}
   8208 	if {$ssh_only && !$ts_only} {
   8209 		return
   8210 	}
   8211 	if {[info exists env(SSVNC_TS_ALWAYS)]} {
   8212 		return
   8213 	}
   8214 	set ssh_only 1
   8215 	set ts_only 0
   8216 
   8217 	set t "SSH VNC Viewer"
   8218 	wm title . $t
   8219 	catch {pack forget .f4}
   8220 	catch {pack forget .b.certs}
   8221 	catch {.l configure -text $t}
   8222 
   8223 	global vncdisplay vncauth_passwd unixpw_username vncproxy remote_ssh_cmd
   8224 	set vncdisplay ""
   8225 	set vncauth_passwd ""
   8226 	set unixpw_username ""
   8227 	set vncproxy ""
   8228 	set remote_ssh_cmd ""
   8229 
   8230 	set_defaults
   8231 }
   8232 
   8233 proc toggle_tsonly {} {
   8234 	global ts_only env
   8235 	if {$ts_only} {
   8236 		if {![info exists env(SSVNC_TS_ALWAYS)]} {
   8237 			to_ssvnc
   8238 		}
   8239 	} else {
   8240 		to_tsonly
   8241 	}
   8242 }
   8243 
   8244 proc toggle_sshonly {} {
   8245 	global ssh_only env
   8246 	if {$ssh_only} {
   8247 		to_ssvnc
   8248 	} else {
   8249 		to_sshonly
   8250 	}
   8251 }
   8252 
   8253 proc to_tsonly {} {
   8254 	global ts_only
   8255 	global showing_no_encryption
   8256 	#if {$showing_no_encryption} {
   8257 	#	toggle_no_encryption
   8258 	#}
   8259 	if {$ts_only} {
   8260 		return
   8261 	}
   8262 	set ts_only 1
   8263 	set ssh_only 1
   8264 
   8265 	set t "Terminal Services VNC Viewer"
   8266 	wm title . $t
   8267 	catch {pack forget .f4}
   8268 	catch {pack forget .f3}
   8269 	catch {pack forget .f1}
   8270 	catch {pack forget .b.certs}
   8271 	catch {.l configure -text $t}
   8272 	catch {.f0.l configure -text "VNC Terminal Server:"}
   8273 
   8274 	global vncdisplay vncauth_passwd unixpw_username vncproxy remote_ssh_cmd
   8275 	set vncdisplay ""
   8276 	set vncauth_passwd ""
   8277 	set unixpw_username ""
   8278 	set vncproxy ""
   8279 	set remote_ssh_cmd ""
   8280 
   8281 	set_defaults
   8282 }
   8283 
   8284 proc to_ssvnc {} {
   8285 	global ts_only ssh_only env
   8286 
   8287 	if {!$ts_only && !$ssh_only} {
   8288 		return;
   8289 	}
   8290 	if {[info exists env(SSVNC_TS_ALWAYS)]} {
   8291 		return
   8292 	}
   8293 	set ts_only 0
   8294 	set ssh_only 0
   8295 
   8296 	set t "SSL/SSH VNC Viewer"
   8297 	wm title . $t
   8298 	catch {pack configure .f1 -after .f0 -side top -fill x}
   8299 	catch {pack configure .f3 -after .f2 -side top -fill x}
   8300 	catch {pack configure .f4 -after .f3 -side top -fill x}
   8301 	catch {pack configure .b.certs -before .b.opts -side left -expand 1 -fill x}
   8302 	catch {.l configure -text $t}
   8303 	catch {.f0.l configure -text "VNC Host:Display"}
   8304 
   8305 	#global started_with_noenc
   8306 	#if {$started_with_noenc} {
   8307 	#	toggle_no_encryption
   8308 	#}
   8309 
   8310 	global vncdisplay vncauth_passwd unixpw_username vncproxy remote_ssh_cmd
   8311 	set vncdisplay ""
   8312 	set vncauth_passwd ""
   8313 	set unixpw_username ""
   8314 	set vncproxy ""
   8315 	set remote_ssh_cmd ""
   8316 
   8317 	set_defaults
   8318 }
   8319 
   8320 proc launch {{hp ""}} {
   8321 	global tcl_platform is_windows
   8322 	global mycert svcert crtdir crlfil
   8323 	global pids_before pids_after pids_new
   8324 	global env
   8325 	global use_ssl use_ssh use_sshssl sshssl_sw use_listen disable_ssl_workarounds
   8326 	global vncdisplay
   8327 
   8328 	set debug 0
   8329 	if {$hp == ""} {
   8330 		set hp [get_vncdisplay]
   8331 	}
   8332 
   8333 	set hpt [string trim $hp]
   8334 	regsub {[ 	].*$} $hpt "" hpt
   8335 
   8336 
   8337 	if {[regexp {^HOME=} $hpt] || [regexp {^SSVNC_HOME=} $hpt]} {
   8338 		set t $hpt
   8339 		regsub {^.*HOME=} $t "" t
   8340 		set t [string trim $t]
   8341 		set env(SSVNC_HOME) $t
   8342 		mesg "Set SSVNC_HOME to $t"
   8343 		set vncdisplay ""
   8344 		return 0
   8345 	}
   8346 	if {[regexp {^DISPLAY=} $hpt] || [regexp {^SSVNC_DISPLAY=} $hpt]} {
   8347 		set t $hpt
   8348 		regsub {^.*DISPLAY=} $t "" t
   8349 		set t [string trim $t]
   8350 		set env(DISPLAY) $t
   8351 		mesg "Set DISPLAY to $t"
   8352 		set vncdisplay ""
   8353 		global uname darwin_cotvnc
   8354 		if {$uname == "Darwin"} {
   8355 			if {$t != ""} {
   8356 				set darwin_cotvnc 0
   8357 			} else {
   8358 				set darwin_cotvnc 1
   8359 			}
   8360 		}
   8361 		return 0
   8362 	}
   8363 	if {[regexp {^DYLD_LIBRARY_PATH=} $hpt] || [regexp {^SSVNC_DYLD_LIBRARY_PATH=} $hpt]} {
   8364 		set t $hpt
   8365 		regsub {^.*DYLD_LIBRARY_PATH=} $t "" t
   8366 		set t [string trim $t]
   8367 		set env(DYLD_LIBRARY_PATH) $t
   8368 		set env(SSVNC_DYLD_LIBRARY_PATH) $t
   8369 		mesg "Set DYLD_LIBRARY_PATH to $t"
   8370 		set vncdisplay ""
   8371 		return 0
   8372 	}
   8373 	if {[regexp {^SLEEP=} $hpt] || [regexp {^SSVNC_EXTRA_SLEEP=} $hpt]} {
   8374 		set t $hpt
   8375 		regsub {^.*SLEEP=} $t "" t
   8376 		set t [string trim $t]
   8377 		set env(SSVNC_EXTRA_SLEEP) $t
   8378 		mesg "Set SSVNC_EXTRA_SLEEP to $t"
   8379 		set vncdisplay ""
   8380 		return 0
   8381 	}
   8382 	if {[regexp {^SSH=} $hpt]} {
   8383 		set t $hpt
   8384 		regsub {^.*SSH=} $t "" t
   8385 		set t [string trim $t]
   8386 		set env(SSH) $t
   8387 		mesg "Set SSH to $t"
   8388 		set vncdisplay ""
   8389 		return 0
   8390 	}
   8391 	if {[regexp {^FINISH=} $hpt] || [regexp {^SSVNC_FINISH_SLEEP=} $hpt]} {
   8392 		set t $hpt
   8393 		regsub {^.*=} $t "" t
   8394 		set t [string trim $t]
   8395 		set env(SSVNC_FINISH_SLEEP) $t
   8396 		mesg "Set SSVNC_FINISH_SLEEP to $t"
   8397 		set vncdisplay ""
   8398 		return 0
   8399 	}
   8400 	if {[regexp {^NO_DELETE=} $hpt] || [regexp {^SSVNC_NO_DELETE=} $hpt]} {
   8401 		set t $hpt
   8402 		regsub {^.*=} $t "" t
   8403 		set t [string trim $t]
   8404 		set env(SSVNC_NO_DELETE) $t
   8405 		mesg "Set SSVNC_NO_DELETE to $t"
   8406 		set vncdisplay ""
   8407 		return 0
   8408 	}
   8409 	if {[regexp {^BAT_SLEEP=} $hpt] || [regexp {^SSVNC_BAT_SLEEP=} $hpt]} {
   8410 		set t $hpt
   8411 		regsub {^.*=} $t "" t
   8412 		set t [string trim $t]
   8413 		set env(SSVNC_BAT_SLEEP) $t
   8414 		mesg "Set SSVNC_BAT_SLEEP to $t"
   8415 		set vncdisplay ""
   8416 		return 0
   8417 	}
   8418 	if {[regexp {^DEBUG_NETSTAT=} $hpt]} {
   8419 		set t $hpt
   8420 		regsub {^.*DEBUG_NETSTAT=} $t "" t
   8421 		global debug_netstat
   8422 		set debug_netstat $t
   8423 		mesg "Set DEBUG_NETSTAT to $t"
   8424 		set vncdisplay ""
   8425 		return 0
   8426 	}
   8427 	if {[regexp {^REPEATER_FORCE=} $hpt]} {
   8428 		set t $hpt
   8429 		regsub {^.*REPEATER_FORCE=} $t "" t
   8430 		set env(REPEATER_FORCE) $t
   8431 		mesg "Set REPEATER_FORCE to $t"
   8432 		set vncdisplay ""
   8433 		return 0
   8434 	}
   8435 	if {[regexp -nocase {^SSH.?ONLY} $hpt]} {
   8436 		global ssh_only
   8437 		if {$ssh_only} {
   8438 			return 0;
   8439 		}
   8440 		to_sshonly
   8441 
   8442 		return 0
   8443 	}
   8444 	if {[regexp -nocase {^TS.?ONLY} $hpt]} {
   8445 		global ts_only
   8446 		if {$ts_only} {
   8447 			return 0;
   8448 		}
   8449 		to_tsonly
   8450 
   8451 		return 0
   8452 	}
   8453 	if {[regexp -nocase {^IPV6=([01])} $hpt mv val]} {
   8454 		global env have_ipv6
   8455 		set have_ipv6 $val
   8456 		set env(SSVNC_IPV6) $val
   8457 		mesg "Set have_ipv6 to $val"
   8458 		set vncdisplay ""
   8459 		return 0
   8460 	}
   8461 	if {[regexp {^ENV=([A-z0-9][A-z0-9]*)=(.*)$} $hpt mv var val]} {
   8462 		global env
   8463 		if {$val == ""} {
   8464 			catch {unset env($var)}
   8465 			mesg "Unset $var"
   8466 		} else {
   8467 			set env($var) "$val"
   8468 			mesg "Set $var to $val"
   8469 		}
   8470 		set vncdisplay ""
   8471 		return 0
   8472 	}
   8473 
   8474 	regsub {[ 	]*cmd=.*$} $hp "" tt
   8475 
   8476 	if {[regexp {^[ 	]*$} $tt]} {
   8477 		mesg "No host:disp supplied."
   8478 		bell
   8479 		catch {raise .}
   8480 		mac_raise
   8481 		return
   8482 	}
   8483 	if {[regexp -- {--nohost--} $tt]} {
   8484 		mesg "No host:disp supplied."
   8485 		bell
   8486 		catch {raise .}
   8487 		mac_raise
   8488 		return
   8489 	}
   8490 	# XXX host_part
   8491 	if {! [regexp ":" $hp]} {
   8492 		if {! [regexp {cmd=} $hp]} {
   8493 			set s [string trim $hp]
   8494 			if {! [regexp { } $s]} {
   8495 				append hp ":0"
   8496 			} else {
   8497 				regsub { } $hp ":0 " hp
   8498 			}
   8499 		}
   8500 	}
   8501 
   8502 	if {!$use_ssl && !$use_ssh && !$use_sshssl && $sshssl_sw == "none"} {
   8503 		regsub -nocase {^[a-z0-9+]*://}	$hp "" hp
   8504 		set hp "Vnc://$hp"
   8505 	}
   8506 
   8507 	mesg "Using: $hp"
   8508 	after 600
   8509 
   8510 	set sc [get_ssh_cmd $hp]
   8511 	if {[regexp {^KNOCK} $sc]} {
   8512 		if [regexp {^KNOCKF} $sc] {
   8513 			port_knock_only $hp "FINISH"
   8514 		} else {
   8515 			port_knock_only $hp "KNOCK"
   8516 		}
   8517 		return
   8518 	}
   8519 
   8520 	if {$debug} {
   8521 		mesg "\"$tcl_platform(os)\" | \"$tcl_platform(osVersion)\""
   8522 		after 1000
   8523 	}
   8524 
   8525 	if [regexp {V[Nn][Cc]://} $hp] {
   8526 		set env(SSVNC_NO_ENC_WARN) 1
   8527 		regsub {V[Nn][Cc]://} $hp "vnc://" hp
   8528 	}
   8529 	regsub -nocase {^vnc://}	$hp "vnc://" hp
   8530 	regsub -nocase {^vncs://}	$hp "vncs://" hp
   8531 	regsub -nocase {^vncssl://}	$hp "vncssl://" hp
   8532 	regsub -nocase {^vnc\+ssl://}	$hp "vnc+ssl://" hp
   8533 	regsub -nocase {^vncssh://}	$hp "vncssh://" hp
   8534 	regsub -nocase {^vnc\+ssh://}	$hp "vnc+ssh://" hp
   8535 
   8536 	if {! $is_windows} {
   8537 		launch_unix $hp
   8538 		return
   8539 	}
   8540 
   8541 	##############################################################
   8542 	# WINDOWS BELOW:
   8543 
   8544 	if [regexp {^vnc://} $hp] {
   8545 		if {! [info exists env(SSVNC_NO_ENC_WARN)]} {
   8546 			direct_connect_msg
   8547 		}
   8548 		regsub {^vnc://} $hp "" hp
   8549 		direct_connect_windows $hp
   8550 		return
   8551 	} elseif [regexp {^vncs://} $hp] {
   8552 		set use_ssl 1
   8553 		set use_ssh 0
   8554 		regsub {^vncs://} $hp "" hp
   8555 		sync_use_ssl_ssh
   8556 	} elseif [regexp {^vncssl://} $hp] {
   8557 		set use_ssl 1
   8558 		set use_ssh 0
   8559 		regsub {^vncssl://} $hp "" hp
   8560 		sync_use_ssl_ssh
   8561 	} elseif [regexp {^vnc\+ssl://} $hp] {
   8562 		set use_ssl 1
   8563 		set use_ssh 0
   8564 		regsub {^vnc\+ssl://} $hp "" hp
   8565 		sync_use_ssl_ssh
   8566 	} elseif [regexp {^vncssh://} $hp] {
   8567 		set use_ssh 1
   8568 		set use_ssl 0
   8569 		regsub {vncssh://} $hp "" hp
   8570 		sync_use_ssl_ssh
   8571 	} elseif [regexp {^vnc\+ssh://} $hp] {
   8572 		set use_ssh 1
   8573 		set use_ssl 0
   8574 		regsub {^vnc\+ssh://} $hp "" hp
   8575 		sync_use_ssl_ssh
   8576 	}
   8577 
   8578 	check_ssh_needed
   8579 
   8580 	if {! $use_ssh} {
   8581 		if {$mycert != ""} {
   8582 			if {! [file exists $mycert]} {
   8583 				mesg "MyCert does not exist: $mycert"
   8584 				bell
   8585 				return
   8586 			}
   8587 		}
   8588 		if {$svcert != ""} {
   8589 			if {! [file exists $svcert]} {
   8590 				mesg "ServerCert does not exist: $svcert"
   8591 				bell
   8592 				return
   8593 			}
   8594 		} elseif {$crtdir != ""} {
   8595 			if {! [file exists $crtdir] && $crtdir != "ACCEPTED_CERTS"} {
   8596 				mesg "CertsDir does not exist: $crtdir"
   8597 				bell
   8598 				return
   8599 			}
   8600 		}
   8601 		if {$crlfil != ""} {
   8602 			if {! [file exists $crlfil]} {
   8603 				mesg "CRL File does not exist: $crlfil"
   8604 				bell
   8605 				return
   8606 			}
   8607 		}
   8608 	}
   8609 
   8610 	# VF
   8611 	set prefix "stunnel-vnc"
   8612 	set suffix "conf"
   8613 	if {$use_ssh || $use_sshssl} {
   8614 		set prefix "plink_vnc"
   8615 		set suffix "bat"
   8616 	}
   8617 
   8618 	set file1 ""
   8619 	set n1 ""
   8620 	set file2 ""
   8621 	set n2 ""
   8622 	set n3 ""
   8623 	set n4 ""
   8624 	set now [clock seconds]
   8625 
   8626 	set proxy [get_ssh_proxy $hp]
   8627 	if {$use_sshssl} {
   8628 		set proxy ""
   8629 	}
   8630 	if {! [repeater_proxy_check $proxy]} {
   8631 		return
   8632 	}
   8633 
   8634 	global port_slot
   8635 	if {$port_slot != ""} {
   8636 		set file1 "$prefix-$port_slot.$suffix"
   8637 		set n1 $port_slot
   8638 		set ps [expr $port_slot + 200]
   8639 		set file2 "$prefix-$ps.$suffix"
   8640 		set n2 $ps
   8641 		mesg "Using Port Slot: $port_slot"
   8642 		after 700
   8643 	}
   8644 
   8645 	for {set i 30} {$i <= 99} {incr i}  {
   8646 		set try "$prefix-$i.$suffix"
   8647 		if {$i == $port_slot} {
   8648 			continue
   8649 		}
   8650 		if {[file exists $try]}  {
   8651 			set mt [file mtime $try]
   8652 			set age [expr "$now - $mt"]
   8653 			set week [expr "7 * 3600 * 24"]
   8654 			if {$age > $week} {
   8655 				catch {file delete $try}
   8656 			}
   8657 		}
   8658 		if {! [file exists $try]}  {
   8659 			if {$file1 == ""} {
   8660 				set file1 $try
   8661 				set n1 $i
   8662 			} elseif {$file2 == ""} {
   8663 				set file2 $try
   8664 				set n2 $i
   8665 			} else {
   8666 				break
   8667 			}
   8668 		}
   8669 	}
   8670 
   8671 	if {$file1 == ""} {
   8672 		mesg "could not find free stunnel file"
   8673 		bell
   8674 		return
   8675 	}
   8676 
   8677 	if {$n1 == ""} {
   8678 		set n1 10
   8679 	}
   8680 	if {$n2 == ""} {
   8681 		set n2 11
   8682 	}
   8683 	set n3 [expr $n1 + 100]
   8684 	set n4 [expr $n2 + 100]
   8685 
   8686 	global launch_windows_ssh_files
   8687 	set launch_windows_ssh_files ""
   8688 
   8689 	set did_port_knock 0
   8690 
   8691 	global listening_name
   8692 	set listening_name ""
   8693 
   8694 	if {$use_ssh} {
   8695 		;
   8696 	} elseif {$use_sshssl} {
   8697 		;
   8698 	} elseif {$use_ssl} {
   8699 		if {$proxy != "" && [regexp {@} $proxy]} {
   8700 			mesg "Error: proxy contains '@'  Did you mean to use SSH mode?"
   8701 			bell
   8702 			return
   8703 		}
   8704 		if [regexp {@} $hp] {
   8705 			mesg "Error: host contains '@'  Did you mean to use SSH mode?"
   8706 			bell
   8707 			return
   8708 		}
   8709 	}
   8710 
   8711 	global ssh_ipv6_pid
   8712 	set ssh_ipv6_pid ""
   8713 
   8714 	if {$use_sshssl} {
   8715 		set rc [launch_windows_ssh $hp $file2 $n2]
   8716 		if {$rc == 0} {
   8717 			if {![info exists env(SSVNC_NO_DELETE)]} {
   8718 				catch {file delete $file1}
   8719 				catch {file delete $file2}
   8720 			}
   8721 			del_launch_windows_ssh_files
   8722 			return
   8723 		}
   8724 		set did_port_knock 1
   8725 	} elseif {$use_ssh} {
   8726 		launch_windows_ssh $hp $file1 $n1
   8727 		# WE ARE DONE.
   8728 		return
   8729 	}
   8730 
   8731 	set host [host_part $hp];
   8732 	set host_orig $host
   8733 
   8734 	global win_localhost
   8735 
   8736 	if {$host == ""} {
   8737 		set host $win_localhost
   8738 	}
   8739 
   8740 	if [regexp {^.*@} $host match] {
   8741 		catch {raise .; update}
   8742 		mesg "Trimming \"$match\" from hostname"
   8743 		after 700
   8744 		regsub {^.*@} $host "" host
   8745 	}
   8746 
   8747 	set disp [port_part $hp]
   8748 	if {[regexp {^-[0-9][0-9]*$} $disp]} {
   8749 		;
   8750 	} elseif {$disp == "" || ! [regexp {^[0-9][0-9]*$} $disp]} {
   8751 		set disp 0
   8752 	}
   8753 
   8754 	if {$disp < 0} {
   8755 		set port [expr "- $disp"]
   8756 	} elseif {$disp < 200} {
   8757 		if {$use_listen} {
   8758 			set port [expr "$disp + 5500"]
   8759 		} else {
   8760 			set port [expr "$disp + 5900"]
   8761 		}
   8762 	} else {
   8763 		set port $disp
   8764 	}
   8765 
   8766 	if {$debug} {
   8767 		mesg "file: $file1"
   8768 		after 1000
   8769 	}
   8770 
   8771 	listen_verify_all_dialog $hp
   8772 
   8773 	if {$use_listen && $mycert == ""} {
   8774 		if {! [check_for_listen_ssl_cert]} {
   8775 			return;
   8776 		}
   8777 	}
   8778 
   8779 	set fail 0
   8780 
   8781 	set fh [open $file1 "w"]
   8782 
   8783 	if {$use_listen} {
   8784 		puts $fh "client = no"
   8785 	} else {
   8786 		puts $fh "client = yes"
   8787 	}
   8788 	global disable_ssl_workarounds disable_ssl_workarounds_type
   8789 	if {$disable_ssl_workarounds} {
   8790 		if {$disable_ssl_workarounds_type == "noempty"} {
   8791 			puts $fh "options = DONT_INSERT_EMPTY_FRAGMENTS"
   8792 		}
   8793 	} else {
   8794 		puts $fh "options = ALL"
   8795 	}
   8796 
   8797 	puts $fh "taskbar = yes"
   8798 	puts $fh "RNDbytes = 2048"
   8799 	puts $fh "RNDfile = bananarand.bin"
   8800 	puts $fh "RNDoverwrite = yes"
   8801 	puts $fh "debug = 6"
   8802 
   8803 	if {$mycert != ""} {
   8804 		if {! [file exists $mycert]} {
   8805 			mesg "MyCert does not exist: $mycert"
   8806 			bell
   8807 			set fail 1
   8808 		}
   8809 		puts $fh "cert = $mycert"
   8810 	} elseif {$use_listen} {
   8811 		# see above, this should not happen.
   8812 		puts $fh "cert = _nocert_"
   8813 	}
   8814 	if {$crlfil != ""} {
   8815 		if [file isdirectory $crlfil] {
   8816 			puts $fh "CRLpath = $crlfil"
   8817 		} else {
   8818 			puts $fh "CRLfile = $crlfil"
   8819 		}
   8820 	}
   8821 
   8822 	set did_check 0
   8823 
   8824 	if {$svcert != ""} {
   8825 		if {! [file exists $svcert]} {
   8826 			mesg "ServerCert does not exist: $svcert"
   8827 			bell
   8828 			set fail 1
   8829 		}
   8830 		puts $fh "CAfile = $svcert"
   8831 		puts $fh "verify = 2"
   8832 	} elseif {$crtdir != ""} {
   8833 		if {$crtdir == "ACCEPTED_CERTS"} {
   8834 			global skip_verify_accepted_certs
   8835 			set skip_verify_accepted_certs 0
   8836 			set did_check 1
   8837 			if {$use_sshssl} {
   8838 				set skip_verify_accepted_certs 1
   8839 				set did_check 0
   8840 			} elseif {! [check_accepted_certs 0]} {
   8841 				set fail 1
   8842 			}
   8843 			if {! $skip_verify_accepted_certs} {
   8844 				set adir [get_idir_certs ""]
   8845 				set adir "$adir/accepted"
   8846 				catch {file mkdir $adir}
   8847 				puts $fh "CApath = $adir"
   8848 				puts $fh "verify = 2"
   8849 			}
   8850 		} else {
   8851 			if {! [file exists $crtdir]} {
   8852 				mesg "CertsDir does not exist: $crtdir"
   8853 				bell
   8854 				set fail 1
   8855 			}
   8856 			puts $fh "CApath = $crtdir"
   8857 			puts $fh "verify = 2"
   8858 		}
   8859 	}
   8860 
   8861 	if {!$did_check} {
   8862 		check_accepted_certs 1
   8863 	}
   8864 
   8865 	if {$use_sshssl} {
   8866 		set p [expr "$n2 + 5900"]
   8867 		set proxy [maybe_add_vencrypt $proxy "$win_localhost:$p"]
   8868 	} else {
   8869 		set proxy [maybe_add_vencrypt $proxy $hp]
   8870 	}
   8871 
   8872 	set ipv6_pid ""
   8873 	global have_ipv6
   8874 	if {$have_ipv6} {
   8875 		if {$proxy == "" && $use_ssl} {
   8876 			# stunnel can handle ipv6
   8877 		} else {
   8878 			set res [ipv6_proxy $proxy $host $port]
   8879 			set proxy    [lindex $res 0]
   8880 			set host     [lindex $res 1]
   8881 			set port     [lindex $res 2]
   8882 			set ipv6_pid [lindex $res 3]
   8883 		}
   8884 	}
   8885 
   8886 	set p_reverse 0
   8887 
   8888 	if {$proxy != ""} {
   8889 		if {$use_sshssl} {
   8890 			;
   8891 		} elseif [regexp {@} $proxy] {
   8892 			bell
   8893 			catch {raise .; update}
   8894 			mesg "WARNING: SSL proxy contains \"@\" sign"
   8895 			after 1500
   8896 		}
   8897 		set env(SSVNC_PROXY) $proxy
   8898 		set env(SSVNC_DEST) "$host:$port"
   8899 		if {$use_listen} {
   8900 			set env(SSVNC_REVERSE) "$win_localhost:$port"
   8901 			set env(CONNECT_BR_SLEEP) 3
   8902 			set p_reverse 1
   8903 		} else {
   8904 			if {$use_sshssl && [regexp {vencrypt:} $proxy]} {
   8905 				set env(SSVNC_LISTEN) [expr "$n4 + 5900"]
   8906 			} else {
   8907 				set env(SSVNC_LISTEN) [expr "$n2 + 5900"]
   8908 			}
   8909 		}
   8910 		if {[info exists env(PROXY_DEBUG)]} {
   8911 			foreach var [list SSVNC_PROXY SSVNC_DEST SSVNC_REVERSE CONNECT_BR_SLEEP SSVNC_LISTEN] {
   8912 				if [info exists env($var)] {
   8913 					mesg "$var $env($var)"; after 2500;
   8914 				}
   8915 			}
   8916 		}
   8917 	}
   8918 
   8919 	global anon_dh_detected server_anondh
   8920 	if {$anon_dh_detected || $server_anondh} {
   8921 		puts $fh "ciphers = ALL:RC4+RSA:+SSLv2:@STRENGTH"
   8922 		set anon_dh_detected 0
   8923 	}
   8924 
   8925 
   8926 	puts $fh "\[vnc$n1\]"
   8927 	set port2 ""
   8928 	set port3 ""
   8929 	if {! $use_listen} {
   8930 		set port2 [expr "$n1 + 5900"]
   8931 		if [regexp {vencrypt:} $proxy] {
   8932 			set port3 [expr "$n3 + 5900"]
   8933 			set port2 $port3
   8934 			puts $fh "accept = $win_localhost:$port3"
   8935 		} else {
   8936 			puts $fh "accept = $win_localhost:$port2"
   8937 		}
   8938 
   8939 		if {$use_sshssl && [regexp {vencrypt:} $proxy]} {
   8940 			set port [expr "$n4 + 5900"]
   8941 			puts $fh "connect = $win_localhost:$port"
   8942 		} elseif {$use_sshssl || $proxy != ""} {
   8943 			set port [expr "$n2 + 5900"]
   8944 			puts $fh "connect = $win_localhost:$port"
   8945 		} else {
   8946 			puts $fh "connect = $host:$port"
   8947 		}
   8948 	} else {
   8949 		set port2 [expr "$n1 + 5500"]
   8950 		set hloc ""
   8951 		if {$use_ssh} {
   8952 			# not reached?
   8953 			set hloc "$win_localhost:"
   8954 			set listening_name "$win_localhost:$port  (on remote SSH side)"
   8955 		} else {
   8956 			set hn [get_hostname]
   8957 			if {$hn == ""} {
   8958 				set hn "this-computer"
   8959 			}
   8960 			set listening_name "$hn:$port  (or nn.nn.nn.nn:$port, etc.)"
   8961 		}
   8962 		if {$host_orig != "" && $hloc == ""} {
   8963 			set hloc "$host_orig:"
   8964 		}
   8965 		puts $fh "accept = $hloc$port"
   8966 		puts $fh "connect = $win_localhost:$port2"
   8967 	}
   8968 
   8969 	puts $fh "delay = no"
   8970 	puts $fh ""
   8971 	close $fh
   8972 
   8973 	if {! $did_port_knock} {
   8974 		if {! [do_port_knock $host start]} {
   8975 			set fail 1
   8976 		}
   8977 		set did_port_knock 1
   8978 	}
   8979 
   8980 	if {$fail} {
   8981 		if {![info exists env(SSVNC_NO_DELETE)]} {
   8982 			catch {file delete $file1}
   8983 		}
   8984 		catch { unset env(SSVNC_PROXY) }
   8985 		catch { unset env(SSVNC_LISTEN) }
   8986 		catch { unset env(SSVNC_REVERSE) }
   8987 		catch { unset env(SSVNC_DEST) }
   8988 		catch { unset env(SSVNC_PREDIGESTED_HANDSHAKE) }
   8989 		catch { unset env(CONNECT_BR_SLEEP) }
   8990 		winkill $ipv6_pid
   8991 		winkill $ssh_ipv6_pid
   8992 		set ssh_ipv6_pid ""
   8993 		return
   8994 	}
   8995 
   8996 	note_stunnel_pids "before"
   8997 
   8998 	set proxy_pid ""
   8999 	set proxy_pid2 ""
   9000 
   9001 	if {$use_listen} {
   9002 		windows_listening_message $n1
   9003 	}
   9004 
   9005 	if {$proxy != ""} {
   9006 		if [regexp {vencrypt:} $proxy] {
   9007 			set vport [expr "$n1 + 5900"]
   9008 			mesg "Starting VeNCrypt helper on port $vport,$port3 ..."
   9009 			after 500
   9010 			if {![info exists env(SSVNC_NO_DELETE)]} {
   9011 				catch {file delete "$file1.pre"}
   9012 			}
   9013 			set env(SSVNC_PREDIGESTED_HANDSHAKE) "$file1.pre"
   9014 			set env(SSVNC_VENCRYPT_VIEWER_BRIDGE) "$vport,$port3"
   9015 			set proxy_pid2 [exec "connect_br.exe" &]
   9016 			catch { unset env(SSVNC_VENCRYPT_VIEWER_BRIDGE) }
   9017 		}
   9018 		mesg "Starting TCP helper on port $port ..."
   9019 		after 400
   9020 		# ssl br case:
   9021 		set proxy_pid [exec "connect_br.exe" &]
   9022 		catch { unset env(SSVNC_PROXY) }
   9023 		catch { unset env(SSVNC_LISTEN) }
   9024 		catch { unset env(SSVNC_REVERSE) }
   9025 		catch { unset env(SSVNC_DEST) }
   9026 		catch { unset env(SSVNC_PREDIGESTED_HANDSHAKE) }
   9027 		catch { unset env(CONNECT_BR_SLEEP) }
   9028 	}
   9029 
   9030 	mesg "Starting STUNNEL on port $port2 ..."
   9031 	after 500
   9032 
   9033 	set pids [exec stunnel $file1 &]
   9034 
   9035 	if {! $p_reverse} {
   9036 		after 300
   9037 		set vtm [vencrypt_tutorial_mesg]
   9038 		if {$vtm == ""} {
   9039 			after 300
   9040 		}
   9041 	}
   9042 
   9043 	note_stunnel_pids "after"
   9044 
   9045 	if {$debug} {
   9046 		after 1000
   9047 		mesg "pids $pids"
   9048 		after 1000
   9049 	} else {
   9050 		catch {destroy .o}
   9051 		catch {destroy .oa}
   9052 		catch {destroy .os}
   9053 		wm withdraw .
   9054 	}
   9055 
   9056 	do_viewer_windows $n1
   9057 
   9058 	del_launch_windows_ssh_files
   9059 
   9060 	if {![info exists env(SSVNC_NO_DELETE)]} {
   9061 		catch {file delete $file1}
   9062 	}
   9063 
   9064 	if {$debug} {
   9065 		;
   9066 	} else {
   9067 		wm deiconify .
   9068 	}
   9069 	mesg "Disconnected from $hp."
   9070 
   9071 	global port_knocking_list
   9072 	if [regexp {FINISH} $port_knocking_list] {
   9073 		do_port_knock $host finish
   9074 	}
   9075 
   9076 	if {[llength $pids_new] > 0} {
   9077 		set plist [join $pids_new ", "]
   9078 		global terminate_pids
   9079 		set terminate_pids ""
   9080 		global kill_stunnel
   9081 		if {$kill_stunnel} {
   9082 			set terminate_pids yes
   9083 		} else {
   9084 			win_kill_msg $plist
   9085 			update
   9086 			vwait terminate_pids
   9087 		}
   9088 		if {$terminate_pids == "yes"} {
   9089 			kill_stunnel $pids_new
   9090 		}
   9091 	} else {
   9092 		win_nokill_msg
   9093 	}
   9094 	mesg "Disconnected from $hp."
   9095 	winkill $ipv6_pid
   9096 	winkill $ssh_ipv6_pid
   9097 	set ssh_ipv6_pid ""
   9098 
   9099 	global is_win9x use_sound sound_daemon_local_kill sound_daemon_local_cmd
   9100 	if {! $is_win9x && $use_sound && $sound_daemon_local_kill && $sound_daemon_local_cmd != ""} {
   9101 		windows_stop_sound_daemon
   9102 	}
   9103 }
   9104 
   9105 proc direct_connect_windows {{hp ""}} {
   9106 	global tcl_platform is_windows
   9107 	global env use_listen
   9108 
   9109 	set proxy [get_ssh_proxy $hp]
   9110 
   9111 	set did_port_knock 0
   9112 
   9113 	global listening_name
   9114 	set listening_name ""
   9115 
   9116 	set host [host_part $hp]
   9117 
   9118 	set host_orig $host
   9119 
   9120 	global win_localhost
   9121 	if {$host == ""} {
   9122 		set host $win_localhost
   9123 	}
   9124 
   9125 	if [regexp {^.*@} $host match] {
   9126 		catch {raise .; update}
   9127 		mesg "Trimming \"$match\" from hostname"
   9128 		after 700
   9129 		regsub {^.*@} $host "" host
   9130 	}
   9131 
   9132 	set disp [port_part $hp]
   9133 	if {[regexp {^-[0-9][0-9]*$} $disp]} {
   9134 		;
   9135 	} elseif {$disp == "" || ! [regexp {^[0-9][0-9]*$} $disp]} {
   9136 		set disp 0
   9137 	}
   9138 
   9139 	if {$disp < 0} {
   9140 		set port [expr "- $disp"]
   9141 	} elseif {$disp < 200} {
   9142 		if {$use_listen} {
   9143 			set port [expr "$disp + 5500"]
   9144 		} else {
   9145 			set port [expr "$disp + 5900"]
   9146 		}
   9147 	} else {
   9148 		set port $disp
   9149 	}
   9150 
   9151 	global have_ipv6
   9152 	set ipv6_pid ""
   9153 	if {$have_ipv6 && !$use_listen} {
   9154 		set res [ipv6_proxy $proxy $host $port]
   9155 		set proxy    [lindex $res 0]
   9156 		set host     [lindex $res 1]
   9157 		set port     [lindex $res 2]
   9158 		set ipv6_pid [lindex $res 3]
   9159 	}
   9160 
   9161 	if {$proxy != ""} {
   9162 		if [regexp {@} $proxy] {
   9163 			bell
   9164 			catch {raise .; update}
   9165 			mesg "WARNING: SSL proxy contains \"@\" sign"
   9166 			after 1500
   9167 		}
   9168 		set n2 45
   9169 
   9170 		set env(SSVNC_PROXY) $proxy
   9171 		set env(SSVNC_LISTEN) [expr "$n2 + 5900"]
   9172 		set env(SSVNC_DEST) "$host:$port"
   9173 
   9174 		set port [expr $n2 + 5900]
   9175 		set host $win_localhost
   9176 	}
   9177 
   9178 	set fail 0
   9179 	if {! $did_port_knock} {
   9180 		if {! [do_port_knock $host start]} {
   9181 			set fail 1
   9182 		}
   9183 		set did_port_knock 1
   9184 	}
   9185 
   9186 	if {$fail} {
   9187 		catch { unset env(SSVNC_PROXY) }
   9188 		catch { unset env(SSVNC_LISTEN) }
   9189 		catch { unset env(SSVNC_DEST) }
   9190 		winkill $ipv6_pid
   9191 		return
   9192 	}
   9193 
   9194 	set proxy_pid ""
   9195 	if {$proxy != ""} {
   9196 		mesg "Starting Proxy TCP helper on port $port ..."
   9197 		after 400
   9198 		# unencrypted br case:
   9199 		set proxy_pid [exec "connect_br.exe" &]
   9200 		catch { unset env(SSVNC_PROXY) }
   9201 		catch { unset env(SSVNC_LISTEN) }
   9202 		catch { unset env(SSVNC_DEST) }
   9203 	}
   9204 
   9205 	vencrypt_tutorial_mesg
   9206 
   9207 	catch {destroy .o}
   9208 	catch {destroy .oa}
   9209 	catch {destroy .os}
   9210 	wm withdraw .
   9211 
   9212 	if {$use_listen} {
   9213 		set n $port
   9214 		if {$n >= 5500} {
   9215 			set n [expr $n - 5500]
   9216 		}
   9217 		global direct_connect_reverse_host_orig
   9218 		set direct_connect_reverse_host_orig $host_orig
   9219 
   9220 		do_viewer_windows "$n"
   9221 
   9222 		set direct_connect_reverse_host_orig ""
   9223 	} else {
   9224 		if {$port >= 5900 && $port < 6100} {
   9225 			set port [expr $port - 5900]
   9226 		}
   9227 		do_viewer_windows "$host:$port"
   9228 	}
   9229 
   9230 	wm deiconify .
   9231 
   9232 	mesg "Disconnected from $hp."
   9233 
   9234 	winkill $ipv6_pid
   9235 
   9236 	global port_knocking_list
   9237 	if [regexp {FINISH} $port_knocking_list] {
   9238 		do_port_knock $host finish
   9239 	}
   9240 
   9241 	mesg "Disconnected from $hp."
   9242 }
   9243 
   9244 proc get_idir_certs {str} {
   9245 	global is_windows env
   9246 	set idir ""
   9247 	if {$str != ""} {
   9248 		if [file isdirectory $str] {
   9249 			set idir $str
   9250 		} else {
   9251 			set idir [file dirname $str]
   9252 		}
   9253 		if {$is_windows} {
   9254 			regsub -all {\\} $idir "/" idir
   9255 			regsub -all {//*} $idir "/" idir
   9256 		}
   9257 	}
   9258 	if {$idir == ""} {
   9259 		if {$is_windows} {
   9260 			if [info exists env(SSVNC_HOME)] {
   9261 				set t "$env(SSVNC_HOME)/ss_vnc"
   9262 				regsub -all {\\} $t "/" t
   9263 				regsub -all {//*} $t "/" t
   9264 				if {! [file isdirectory $t]} {
   9265 					catch {file mkdir $t}
   9266 				}
   9267 				set t "$env(SSVNC_HOME)/ss_vnc/certs"
   9268 				regsub -all {\\} $t "/" t
   9269 				regsub -all {//*} $t "/" t
   9270 				if {! [file isdirectory $t]} {
   9271 					catch {file mkdir $t}
   9272 				}
   9273 				if [file isdirectory $t] {
   9274 					set idir $t
   9275 				}
   9276 			}
   9277 			if {$idir == ""} {
   9278 				set t [file dirname [pwd]]
   9279 				set t "$t/certs"
   9280 				if [file isdirectory $t] {
   9281 					set idir $t
   9282 				}
   9283 			}
   9284 		}
   9285 		if {$idir == ""} {
   9286 			if [info exists env(SSVNC_HOME)] {
   9287 				set t "$env(SSVNC_HOME)/.vnc"
   9288 				if {! [file isdirectory $t]} {
   9289 					catch {file mkdir $t}
   9290 				}
   9291 				set t "$env(SSVNC_HOME)/.vnc/certs"
   9292 				if {! [file isdirectory $t]} {
   9293 					catch {file mkdir $t}
   9294 				}
   9295 				if [file isdirectory $t] {
   9296 					set idir $t
   9297 				}
   9298 			}
   9299 		}
   9300 	}
   9301 	if {$idir == ""} {
   9302 		if {$is_windows} {
   9303 			set idir [get_profiles_dir]
   9304 		}
   9305 		if {$idir == ""} {
   9306 			set idir [pwd]
   9307 		}
   9308 	}
   9309 	return $idir
   9310 }
   9311 
   9312 proc delete_cert {{parent "."}} {
   9313 	set idir [get_idir_certs ""]
   9314 	set f ""
   9315 	unix_dialog_resize $parent
   9316 	if {$idir != ""} {
   9317 		set f [tk_getOpenFile -parent $parent -initialdir $idir]
   9318 	} else {
   9319 		set f [tk_getOpenFile -parent $parent]
   9320 	}
   9321 	if {$f != "" && [file exists $f]} {
   9322 		set reply [tk_messageBox -parent $parent -type yesno -icon question -title "Delete Cert" -message "Delete $f"]
   9323 		if {$reply == "yes"} {
   9324 			global mycert svcert crlfil
   9325 			set f_text [read_file $f]
   9326 			set f2 ""
   9327 			catch {file delete $f}
   9328 			if {$f == $mycert} { set mycert "" }
   9329 			if {$f == $svcert} { set svcert "" }
   9330 			if {$f == $crlfil} { set crlfil "" }
   9331 			if [regexp {\.crt$} $f] {
   9332 				regsub {\.crt$} $f ".pem" f2
   9333 			} elseif [regexp {\.pem$} $f] {
   9334 				regsub {\.pem$} $f ".crt" f2
   9335 			}
   9336 			if {$f2 != "" && [file exists $f2]} {
   9337 				set reply [tk_messageBox -parent $parent -type yesno -icon question -title "Delete Cert" -message "Delete $f2"]
   9338 				if {$reply == "yes"} {
   9339 					catch {file delete $f2}
   9340 					if {$f2 == $mycert} { set mycert "" }
   9341 					if {$f2 == $svcert} { set svcert "" }
   9342 					if {$f2 == $crlfil} { set crlfil "" }
   9343 				}
   9344 			}
   9345 			set dir [file dirname $f]
   9346 			if {$f_text != "" && [regexp {accepted$} $dir]} {
   9347 				foreach crt [glob -nocomplain -directory $dir {*.crt} {*.pem} {*.[0-9]}] {
   9348 					#puts "try $crt"
   9349 					set c_text [read_file $crt]
   9350 					if {$c_text == ""} {
   9351 						continue
   9352 					}
   9353 					if {$c_text != $f_text} {
   9354 						continue
   9355 					}
   9356 					set reply [tk_messageBox -parent $parent -type yesno -icon question -title "Delete Identical Cert" -message "Delete Identical $crt"]
   9357 					if {$reply == "yes"} {
   9358 						catch {file delete $crt}
   9359 					}
   9360 				}
   9361 			}
   9362 		}
   9363 	}
   9364 	catch {wm deiconify .c}
   9365 	update
   9366 }
   9367 
   9368 proc set_mycert {{parent "."}} {
   9369 	global mycert
   9370 	set idir [get_idir_certs $mycert]
   9371 	set t ""
   9372 	unix_dialog_resize $parent
   9373 	if {$idir != ""} {
   9374 		set t [tk_getOpenFile -parent $parent -initialdir $idir]
   9375 	} else {
   9376 		set t [tk_getOpenFile -parent $parent]
   9377 	}
   9378 	if {$t != ""} {
   9379 		set mycert $t
   9380 	}
   9381 	catch {wm deiconify .c}
   9382 	v_mycert
   9383 	update
   9384 }
   9385 
   9386 proc set_crlfil {{parent "."}} {
   9387 	global crlfil
   9388 	set idir [get_idir_certs $crlfil]
   9389 	set t ""
   9390 	unix_dialog_resize $parent
   9391 	if {$idir != ""} {
   9392 		set t [tk_getOpenFile -parent $parent -initialdir $idir]
   9393 	} else {
   9394 		set t [tk_getOpenFile -parent $parent]
   9395 	}
   9396 	if {$t != ""} {
   9397 		set crlfil $t
   9398 	}
   9399 	catch {wm deiconify .c}
   9400 	v_crlfil
   9401 	update
   9402 }
   9403 
   9404 proc set_ultra_dsm_file {{parent "."}} {
   9405 	global ultra_dsm_file
   9406 	set idir [get_idir_certs $ultra_dsm_file]
   9407 	set t ""
   9408 	unix_dialog_resize $parent
   9409 	if {$idir != ""} {
   9410 		set t [tk_getOpenFile -parent $parent -initialdir $idir]
   9411 	} else {
   9412 		set t [tk_getOpenFile -parent $parent]
   9413 	}
   9414 	if {$t != ""} {
   9415 		set ultra_dsm_file $t
   9416 	}
   9417 	update
   9418 }
   9419 
   9420 proc set_ssh_known_hosts_file {{parent "."}} {
   9421 	global ssh_known_hosts_filename is_windows uname
   9422 
   9423 	if {$ssh_known_hosts_filename == ""} {
   9424 		set pdir [get_profiles_dir]
   9425 		set pdir "$pdir/ssh_known_hosts"
   9426 		catch {file mkdir $pdir}
   9427 
   9428 		global last_load
   9429 		if {![info exists last_load]} {
   9430 			set last_load ""
   9431 		}
   9432 		if {$last_load != ""} {
   9433 			set dispf [string trim $last_load]
   9434 			set dispf [file tail $dispf]
   9435 
   9436 			regsub {\.vnc$} $dispf "" dispf
   9437 			if {![regexp {\.known$} $dispf]} {
   9438 				set dispf "$dispf.known"
   9439 			}
   9440 			set guess $dispf
   9441 		} else {
   9442 			set vncdisp [get_vncdisplay]
   9443 			set dispf [string trim $vncdisp]
   9444 			if {$dispf != ""} {
   9445 				regsub {[ 	].*$} $dispf "" dispf
   9446 				regsub -all {/} $dispf "" dispf
   9447 			} else {
   9448 				set dispf "unique-name-here"
   9449 			}
   9450 			if {$is_windows || $uname == "Darwin"} {
   9451 				regsub -all {:} $dispf "-" dispf
   9452 			} else {
   9453 				regsub -all {:} $dispf "-" dispf
   9454 			}
   9455 			if {![regexp {\.known$} $dispf]} {
   9456 				set dispf "$dispf.known"
   9457 			}
   9458 			set guess $dispf
   9459 		}
   9460 	} else {
   9461 		set pdir [file dirname $ssh_known_hosts_filename]
   9462 		set guess [file tail $ssh_known_hosts_filename]
   9463 	}
   9464 
   9465 	set t ""
   9466 	unix_dialog_resize $parent
   9467 	if {$pdir != ""} {
   9468 		set t [tk_getSaveFile -parent $parent -initialdir $pdir -initialfile $guess]
   9469 	} else {
   9470 		set t [tk_getSaveFile -parent $parent -initialfile $guess]
   9471 	}
   9472 	if {$t != ""} {
   9473 		set ssh_known_hosts_filename $t
   9474 	}
   9475 	update
   9476 }
   9477 
   9478 proc show_cert {crt} {
   9479 	if {$crt == ""} {
   9480 		bell
   9481 		return
   9482 	}
   9483 	if {! [file exists $crt]} {
   9484 		bell
   9485 		return
   9486 	}
   9487 	set info ""
   9488 	catch {set info [get_x509_info $crt]}
   9489 	if {$info == ""} {
   9490 		bell
   9491 		return
   9492 	}
   9493 
   9494 	set w .show_certificate
   9495 	toplev $w
   9496 	scroll_text $w.f
   9497 	button $w.b -text Dismiss -command "destroy $w"
   9498 	bind $w <Escape> "destroy $w"
   9499 	$w.f.t insert end $info
   9500 
   9501 	pack $w.b -side bottom -fill x
   9502 	pack $w.f -side top -fill both -expand 1
   9503 	center_win $w
   9504 	catch {raise $w}
   9505 }
   9506 
   9507 proc show_crl {crl} {
   9508 	if {$crl == ""} {
   9509 		bell
   9510 		return
   9511 	}
   9512 	if {! [file exists $crl]} {
   9513 		bell
   9514 		return
   9515 	}
   9516 
   9517 	set flist [list]
   9518 
   9519 	if [file isdirectory $crl] {
   9520 		foreach cfile [glob -nocomplain -directory $crl "*"] {
   9521 			if [file isfile $cfile] {
   9522 				lappend flist $cfile
   9523 			}
   9524 		}
   9525 	} else {
   9526 		lappend flist $crl
   9527 	}
   9528 
   9529 	set ossl [get_openssl]
   9530 	set info ""
   9531 
   9532 	foreach cfile $flist {
   9533 		catch {
   9534 			set ph [open "| $ossl crl -fingerprint -text -noout -in \"$cfile\"" "r"]
   9535 			while {[gets $ph line] > -1} {
   9536 				append info "$line\n"
   9537 			}
   9538 			close $ph
   9539 			append info "\n"
   9540 		}
   9541 	}
   9542 
   9543 	set w .show_crl
   9544 	toplev $w
   9545 	scroll_text $w.f
   9546 	button $w.b -text Dismiss -command "destroy $w"
   9547 	bind $w <Escape> "destroy $w"
   9548 	$w.f.t insert end $info
   9549 
   9550 	pack $w.b -side bottom -fill x
   9551 	pack $w.f -side top -fill both -expand 1
   9552 	center_win $w
   9553 	catch {raise $w}
   9554 }
   9555 
   9556 proc v_svcert {} {
   9557 	global svcert
   9558 	if {$svcert == "" || ! [file exists $svcert]} {
   9559 		catch {.c.svcert.i configure -state disabled}
   9560 	} else {
   9561 		catch {.c.svcert.i configure -state normal}
   9562 	}
   9563 	no_certs_tutorial_mesg
   9564 	return 1
   9565 }
   9566 
   9567 proc v_mycert {} {
   9568 	global mycert
   9569 	if {$mycert == "" || ! [file exists $mycert]} {
   9570 		catch {.c.mycert.i configure -state disabled}
   9571 	} else {
   9572 		catch {.c.mycert.i configure -state normal}
   9573 	}
   9574 	return 1
   9575 }
   9576 
   9577 proc v_crlfil {} {
   9578 	global crlfil
   9579 	if {$crlfil == "" || ! [file exists $crlfil]} {
   9580 		catch {.c.crlfil.i configure -state disabled}
   9581 	} else {
   9582 		catch {.c.crlfil.i configure -state normal}
   9583 	}
   9584 	return 1
   9585 }
   9586 
   9587 proc show_mycert {} {
   9588 	global mycert
   9589 	show_cert $mycert
   9590 }
   9591 
   9592 proc show_svcert {} {
   9593 	global svcert
   9594 	show_cert $svcert
   9595 }
   9596 
   9597 proc show_crlfil {} {
   9598 	global crlfil
   9599 	show_crl $crlfil
   9600 }
   9601 
   9602 proc set_svcert {{parent "."}} {
   9603 	global svcert crtdir
   9604 	set idir [get_idir_certs $svcert]
   9605 	set t ""
   9606 	unix_dialog_resize $parent
   9607 	if {$idir != ""} {
   9608 		set t [tk_getOpenFile -parent $parent -initialdir $idir]
   9609 	} else {
   9610 		set t [tk_getOpenFile -parent $parent]
   9611 	}
   9612 	if {$t != ""} {
   9613 		set crtdir ""
   9614 		set svcert $t
   9615 	}
   9616 	catch {wm deiconify .c}
   9617 	v_svcert
   9618 	update
   9619 }
   9620 
   9621 proc set_crtdir {{parent "."}} {
   9622 	global svcert crtdir
   9623 	set idir ""
   9624 	if {$crtdir == "ACCEPTED_CERTS"} {
   9625 		set idir [get_idir_certs ""]
   9626 	} else {
   9627 		set idir [get_idir_certs $crtdir]
   9628 	}
   9629 	set t ""
   9630 	unix_dialog_resize $parent
   9631 	if {$idir != ""} {
   9632 		set t [tk_chooseDirectory -parent $parent -initialdir $idir]
   9633 	} else {
   9634 		set t [tk_chooseDirectory -parent $parent]
   9635 	}
   9636 	if {$t != ""} {
   9637 		set svcert ""
   9638 		set crtdir $t
   9639 	}
   9640 	catch {wm deiconify .c}
   9641 	update
   9642 }
   9643 
   9644 proc set_createcert_file {} {
   9645 	global ccert
   9646 	if {[info exists ccert(FILE)]} {
   9647 		set idir [get_idir_certs $ccert(FILE)]
   9648 	}
   9649 	unix_dialog_resize .ccrt
   9650 	if {$idir != ""} {
   9651 		set t [tk_getSaveFile -parent .ccrt -defaultextension ".pem" -initialdir $idir]
   9652 	} else {
   9653 		set t [tk_getSaveFile -parent .ccrt -defaultextension ".pem"]
   9654 	}
   9655 	if {$t != ""} {
   9656 		set ccert(FILE) $t
   9657 	}
   9658 	catch {raise .ccrt}
   9659 	update
   9660 }
   9661 
   9662 proc check_pp {} {
   9663 	global ccert
   9664 	if {$ccert(ENC)} {
   9665 		catch {.ccrt.pf.e configure -state normal}
   9666 		catch {focus .ccrt.pf.e}
   9667 		catch {.ccrt.pf.e icursor end}
   9668 	} else {
   9669 		catch {.ccrt.pf.e configure -state disabled}
   9670 	}
   9671 }
   9672 
   9673 proc get_openssl {} {
   9674 	global is_windows
   9675 	if {$is_windows} {
   9676 		set ossl "openssl.exe"
   9677 	} else {
   9678 		set ossl "openssl"
   9679 	}
   9680 }
   9681 
   9682 proc get_x509_info {crt} {
   9683 	set ossl [get_openssl]
   9684 	set info ""
   9685 	update
   9686 	set ph [open "| $ossl x509 -text -fingerprint -in \"$crt\"" "r"]
   9687 	while {[gets $ph line] > -1} {
   9688 		append info "$line\n"
   9689 	}
   9690 	close $ph
   9691 	return $info
   9692 }
   9693 
   9694 proc do_oss_create {} {
   9695 	global is_windows is_win9x
   9696 
   9697 	set cfg {
   9698 [ req ]
   9699 default_bits            = 2048
   9700 encrypt_key             = yes
   9701 distinguished_name      = req_distinguished_name
   9702 
   9703 [ req_distinguished_name ]
   9704 countryName                     = Country Name (2 letter code)
   9705 countryName_default             = %CO
   9706 countryName_min                 = 2
   9707 countryName_max                 = 2
   9708 
   9709 stateOrProvinceName             = State or Province Name (full name)
   9710 stateOrProvinceName_default     = %ST
   9711 
   9712 localityName                    = Locality Name (eg, city)
   9713 localityName_default            = %LOC
   9714 
   9715 0.organizationName              = Organization Name (eg, company)
   9716 0.organizationName_default      = %ON
   9717 
   9718 organizationalUnitName          = Organizational Unit Name (eg, section)
   9719 organizationalUnitName_default  = %OUN
   9720 
   9721 commonName                      = Common Name (eg, YOUR name)
   9722 commonName_default              = %CN
   9723 commonName_max                  = 64
   9724 
   9725 emailAddress                    = Email Address
   9726 emailAddress_default            = %EM
   9727 emailAddress_max                = 64
   9728 }
   9729 
   9730 	global ccert
   9731 
   9732 	if {$ccert(FILE) == ""} {
   9733 		catch {destroy .c}
   9734 		mesg "No output cert file supplied"
   9735 		bell
   9736 		return
   9737 	}
   9738 	if {! [regexp {\.pem$} $ccert(FILE)]} {
   9739 		append ccert(FILE) ".pem"
   9740 	}
   9741 	set pem $ccert(FILE)
   9742 	regsub {\.pem$} $ccert(FILE) ".crt" crt
   9743 
   9744 	if {$ccert(ENC)} {
   9745 		if {[string length $ccert(PASS)] < 4} {
   9746 			catch {destroy .c}
   9747 			mesg "Passphrase must be at least 4 characters long."
   9748 			bell
   9749 			return
   9750 		}
   9751 	}
   9752 	if {[string length $ccert(CO)] != 2} {
   9753 		catch {destroy .c}
   9754 		mesg "Country Name must be at exactly 2 characters long."
   9755 		bell
   9756 		return
   9757 	}
   9758 	if {[string length $ccert(CN)] > 64} {
   9759 		catch {destroy .c}
   9760 		mesg "Common Name must be less than 65 characters long."
   9761 		bell
   9762 		return
   9763 	}
   9764 	if {[string length $ccert(EM)] > 64} {
   9765 		catch {destroy .c}
   9766 		mesg "Email Address must be less than 65 characters long."
   9767 		bell
   9768 		return
   9769 	}
   9770 
   9771 	foreach t {EM CN OUN ON LOC ST CO} {
   9772 
   9773 		set val $ccert($t)
   9774 		if {$val == ""} {
   9775 			set val "none"
   9776 		}
   9777 		regsub "%$t" $cfg "$val" cfg
   9778 	}
   9779 
   9780 	global is_windows
   9781 
   9782 	if {$is_windows} {
   9783 		# VF
   9784 		set tmp "cert.cfg"
   9785 	} else {
   9786 		set tmp "/tmp/cert.cfg.[tpid]"
   9787 		set tmp [mytmp $tmp]
   9788 		catch {set fh [open $tmp "w"]}
   9789 		catch {exec chmod 600 $tmp}
   9790 		if {! [file exists $tmp]} {
   9791 			catch {destroy .c}
   9792 			mesg "cannot create: $tmp"
   9793 			bell
   9794 			return
   9795 		}
   9796 	}
   9797 	set fh ""
   9798 	catch {set fh [open $tmp "w"]}
   9799 	if {$fh == ""} {
   9800 		catch {destroy .c}
   9801 		mesg "cannot create: $tmp"
   9802 		bell
   9803 		catch {file delete $tmp}
   9804 		return
   9805 	}
   9806 
   9807 	puts $fh $cfg
   9808 	close $fh
   9809 
   9810 	set ossl [get_openssl]
   9811 
   9812 	set cmd "$ossl req -config $tmp -nodes -new -newkey rsa:2048 -x509 -batch"
   9813 	if {$ccert(DAYS) != ""} {
   9814 		set cmd "$cmd -days $ccert(DAYS)"
   9815 	}
   9816 	if {$is_windows} {
   9817 		set cmd "$cmd -keyout {$pem} -out {$crt}"
   9818 	} else {
   9819 		set cmd "$cmd -keyout \"$pem\" -out \"$crt\""
   9820 	}
   9821 
   9822 	if {$is_windows} {
   9823 		set emess ""
   9824 		if {$is_win9x} {
   9825 			catch {file delete $pem}
   9826 			catch {file delete $crt}
   9827 			update
   9828 			eval exec $cmd &
   9829 			catch {raise .}
   9830 			set sl 0
   9831 			set max 100
   9832 			#if {$ccert(ENC)} {
   9833 			#	set max 100
   9834 			#}
   9835 			set maxms [expr $max * 1000]
   9836 			while {$sl < $maxms} {
   9837 				set s2 [expr $sl / 1000]
   9838 				mesg "running openssl ... $s2/$max"
   9839 				if {[file exists $pem] && [file exists $crt]} {
   9840 					after 2000
   9841 					break
   9842 				}
   9843 				after 500
   9844 				set sl [expr $sl + 500]
   9845 			}
   9846 			mesg ""
   9847 		} else {
   9848 			update
   9849 			set rc [catch {eval exec $cmd} emess]
   9850 			if {$rc != 0 && [regexp -nocase {error:} $emess]} {
   9851 				raise .
   9852 				tk_messageBox -type ok -icon error -message $emess -title "OpenSSL req command failed"
   9853 				return
   9854 			}
   9855 		}
   9856 	} else {
   9857 		set geometry [xterm_center_geometry]
   9858 		update
   9859 		unix_terminal_cmd $geometry "Running OpenSSL" "$cmd"
   9860 		catch {file attributes $pem -permissions go-rw}
   9861 		catch {file attributes $crt -permissions go-w}
   9862 	}
   9863 	catch {file delete $tmp}
   9864 
   9865 	set bad ""
   9866 	if {! [file exists $pem]} {
   9867 		set bad "$pem "
   9868 	}
   9869 	if {! [file exists $crt]} {
   9870 		set bad "$crt"
   9871 	}
   9872 	if {$bad != ""} {
   9873 		raise .
   9874 		tk_messageBox -type ok -icon error -message "Not created: $bad" -title "OpenSSL could not create cert"
   9875 		catch {raise .c}
   9876 		return
   9877 	}
   9878 
   9879 	if {$ccert(ENC) && $ccert(PASS) != ""} {
   9880 		set cmd "$ossl rsa -in \"$pem\" -des3 -out \"$pem\" -passout stdin"
   9881 		set ph ""
   9882 		set emess ""
   9883 		update
   9884 		set rc [catch {set ph [open "| $cmd" "w"]} emess]
   9885 		if {$rc != 0 || $ph == ""} {
   9886 			raise .
   9887 			tk_messageBox -type ok -icon error -message $emess -title "Could not encrypt private key"
   9888 			catch {file delete $pem}
   9889 			catch {file delete $crt}
   9890 			return
   9891 		}
   9892 		puts $ph $ccert(PASS)
   9893 		set emess ""
   9894 		set rc [catch {close $ph} emess]
   9895 		#puts $emess
   9896 		#puts $rc
   9897 	}
   9898 
   9899 	set in  [open $crt "r"]
   9900 	set out [open $pem "a"]
   9901 	while {[gets $in line] > -1} {
   9902 		puts $out $line
   9903 	}
   9904 	close $in
   9905 	close $out
   9906 
   9907 	catch {raise .c}
   9908 	set p .
   9909 	if [winfo exists .c] {
   9910 		set p .c
   9911 	}
   9912 
   9913 	set reply [tk_messageBox -parent $p -type yesno -title "View Cert" -message "View Certificate and Info?"]
   9914 	catch {raise .c}
   9915 	if {$reply == "yes"} {
   9916 		set w .view_cert
   9917 		toplev $w
   9918 		scroll_text $w.f
   9919 		set cert ""
   9920 		set fh ""
   9921 		catch {set fh [open $crt "r"]}
   9922 		if {$fh != ""} {
   9923 			while {[gets $fh line] > -1} {
   9924 				append cert "$line\n"
   9925 			}
   9926 			catch {close $fh}
   9927 		}
   9928 
   9929 		global yegg
   9930 		set yegg ""
   9931 		button $w.b -text Dismiss -command "destroy $w; set yegg 1"
   9932 		pack $w.b -side bottom -fill x
   9933 		bind $w <Escape> "destroy $w; set yegg 1"
   9934 
   9935 		$w.f.t insert end "\n"
   9936 		$w.f.t insert end "$crt:\n"
   9937 		$w.f.t insert end "\n"
   9938 		$w.f.t insert end $cert
   9939 		$w.f.t insert end "\n"
   9940 
   9941 		set info [get_x509_info $crt]
   9942 		$w.f.t insert end $info
   9943 
   9944 		pack $w.f -side top -fill both -expand 1
   9945 		center_win $w
   9946 		catch {raise $w}
   9947 		vwait yegg
   9948 		catch {raise .c}
   9949 	}
   9950 
   9951 	set p .
   9952 	if [winfo exists .c] {
   9953 		set p .c
   9954 	}
   9955 	set reply [tk_messageBox -parent $p -type yesno -title "View Private Key" -message "View Private Key?"]
   9956 	catch {raise .c}
   9957 	if {$reply == "yes"} {
   9958 		set w .view_key
   9959 		toplev $w
   9960 		scroll_text $w.f
   9961 		set key ""
   9962 		set fh [open $pem "r"]
   9963 		while {[gets $fh line] > -1} {
   9964 			append key "$line\n"
   9965 		}
   9966 		close $fh
   9967 
   9968 		global yegg
   9969 		set yegg ""
   9970 		button $w.b -text Dismiss -command "destroy $w; set yegg 1"
   9971 		pack $w.b -side bottom -fill x
   9972 		bind $w <Escape> "destroy $w; set yegg 1"
   9973 
   9974 		$w.f.t insert end "\n"
   9975 		$w.f.t insert end "$pem:\n"
   9976 		$w.f.t insert end "\n"
   9977 		$w.f.t insert end $key
   9978 		$w.f.t insert end "\n"
   9979 
   9980 		pack $w.f -side top -fill both -expand 1
   9981 		center_win $w
   9982 		catch {raise $w}
   9983 		vwait yegg
   9984 		catch {raise .c}
   9985 	}
   9986 }
   9987 
   9988 proc create_cert {{name ""}} {
   9989 
   9990 	toplev .ccrt
   9991 	wm title .ccrt "Create SSL Certificate"
   9992 
   9993 	global uname
   9994 	set h 27
   9995 	if [small_height] {
   9996 		set h 14
   9997 	} elseif {$uname == "Darwin"} {
   9998 		set h 20
   9999 	}
   10000 	scroll_text .ccrt.f 80 $h
   10001 
   10002 	set msg {
   10003     This dialog helps you to create a simple Self-Signed SSL certificate.
   10004 
   10005     On Unix the openssl(1) program must be installed and in $PATH.
   10006     On Windows, a copy of the openssl program is provided for convenience.
   10007 
   10008     The resulting certificate files can be used for either:
   10009 
   10010        1) authenticating yourself (VNC Viewer) to a VNC Server
   10011     or 2) your verifying the identity of a remote VNC Server.
   10012 
   10013     In either case you will need to safely copy one of the generated key or
   10014     certificate files to the remote VNC Server and have the VNC Server use
   10015     it.  Or you could send it to the system administrator of the VNC Server.
   10016 
   10017     For the purpose of description, assume that the filename selected in the
   10018     "Save to file" entry is "vnccert.pem".  That file will be generated
   10019     by this process and so will the "vnccert.crt" file.  "vnccert.pem"
   10020     contains both the Private Key and the Public Certificate.  "vnccert.crt"
   10021     only contains the Public Certificate.
   10022 
   10023     For case 1) you would copy "vnccert.crt" to the VNC Server side and
   10024     instruct the server to use it.  For x11vnc it would be for example:
   10025 
   10026         x11vnc -sslverify /path/to/vnccert.crt -ssl SAVE ...
   10027 
   10028     (it is also possible to handle many client certs at once in a directory,
   10029     see the -sslverify documentation).  Then you would use "vnccert.pem"
   10030     as the MyCert entry in the SSL Certificates dialog.
   10031 
   10032     For case 2) you would copy "vnccert.pem" to the VNC Server side and
   10033     instruct the server to use it.  For x11vnc it would be for example:
   10034 
   10035         x11vnc -ssl /path/to/vnccert.pem
   10036 
   10037     Then you would use "vnccert.crt" as the as the ServerCert entry in the
   10038     "SSL Certificates" dialog.
   10039 
   10040 
   10041     Creating the Certificate:
   10042 
   10043     Choose a output filename (ending in .pem) in the "Save to file" entry.
   10044 
   10045     Then fill in the identification information (Country, State or Province,
   10046     etc).
   10047 
   10048     The click on "Create" to generate the certificate files.
   10049 
   10050     Encrypting the Private Key:  It is a very good idea to encrypt the
   10051     Private Key that goes in the "vnccert.pem".  The downside is that
   10052     whenever that key is used (e.g. starting up x11vnc using it) then
   10053     the passphrase will need to be created.  If you do not encrypt it and
   10054     somebody steals a copy of the "vnccert.pem" file then they can pretend
   10055     to be you.
   10056 
   10057     After you have created the certificate files, you must copy and import
   10058     either "vnccert.pem" or "vnccert.pem" to the remote VNC Server and
   10059     also select the other file in the "SSL Certificates" dialog.
   10060     See the description above.
   10061 
   10062     For more information see:
   10063 
   10064            http://www.karlrunge.com/x11vnc/ssl.html
   10065            http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tunnel-int
   10066 
   10067     The first one describes how to use x11vnc to create Certificate
   10068     Authority (CA) certificates in addition to Self-Signed ones.
   10069 
   10070 
   10071     Tip: if you choose the "Common Name" to be the internet hostname
   10072     (e.g. gateway.mydomain.com) that connections will be made to or
   10073     from that will avoid many dialogs when connecting mentioning that
   10074     the hostname does not match the Common Name.
   10075 }
   10076 	.ccrt.f.t insert end $msg
   10077 
   10078 	global ccert ccert_init tcert
   10079 
   10080 
   10081 	if {! [info exists ccert_init]} {
   10082 		set ccert_init 1
   10083 		set ccert(CO) "US"
   10084 		set ccert(ST) "Massachusetts"
   10085 		set ccert(LOC) "Boston"
   10086 		set ccert(ON) "My Company"
   10087 		set ccert(OUN) "Product Development"
   10088 		set ccert(CN) "www.nowhere.none"
   10089 		set ccert(EM) "admin (at) nowhere.none"
   10090 		set ccert(DAYS) "730"
   10091 		set ccert(FILE) ""
   10092 	}
   10093 
   10094 	set ccert(ENC) 0
   10095 	set ccert(PASS) ""
   10096 
   10097 	set tcert(CO) "Country Name (2 letter code):"
   10098 	set tcert(ST) "State or Province Name (full name):"
   10099 	set tcert(LOC) "Locality Name (eg, city):"
   10100 	set tcert(ON) "Organization Name (eg, company):"
   10101 	set tcert(OUN) "Organizational Unit Name (eg, section):"
   10102 	set tcert(CN) "Common Name (eg, YOUR name):"
   10103 	set tcert(EM) "Email Address:"
   10104 	set tcert(DAYS) "Days until expiration:"
   10105 
   10106 	set idir [get_idir_certs ""]
   10107 	if {$name != ""} {
   10108 		if {[regexp {/} $name] || [regexp {\.pem$} $name] || [regexp {\.crt$} $name]} {
   10109 			set ccert(FILE) $name
   10110 		} else {
   10111 			set ccert(FILE) "$idir/$name.pem"
   10112 		}
   10113 	} elseif {$ccert(FILE) == ""} {
   10114 		set ccert(FILE) "$idir/vnccert.pem"
   10115 	}
   10116 
   10117 	button .ccrt.cancel -text "Cancel" -command {destroy .ccrt; catch {raise .c}}
   10118 	bind .ccrt <Escape> {destroy .ccrt; catch {raise .c}}
   10119 	wm protocol .ccrt WM_DELETE_WINDOW {destroy .ccrt; catch {raise .c}}
   10120 
   10121 	button .ccrt.create -text "Generate Cert" -command {destroy .ccrt; catch {raise .c}; do_oss_create}
   10122 
   10123 	pack .ccrt.create .ccrt.cancel -side bottom -fill x
   10124 
   10125 	set ew 40
   10126 
   10127 	set w .ccrt.pf
   10128 	frame $w
   10129 	checkbutton $w.check -anchor w -variable ccert(ENC) -text \
   10130 		"Encrypt Key with Passphrase" -command {check_pp}
   10131 
   10132 	entry $w.e -width $ew -textvariable ccert(PASS) -state disabled \
   10133 		-show *
   10134 
   10135 	pack $w.e -side right
   10136 	pack $w.check -side left -expand 1 -fill x
   10137 	pack $w -side bottom -fill x
   10138 
   10139 	set w .ccrt.fl
   10140 	frame $w
   10141 	label $w.l -anchor w -text "Save to file:"
   10142 
   10143 	entry $w.e -width $ew -textvariable ccert(FILE)
   10144 	button $w.b -text "Browse..." -command {set_createcert_file; catch {raise .ccrt}}
   10145 	if {$name != ""} {
   10146 		$w.b configure -state disabled
   10147 	}
   10148 
   10149 	pack $w.e -side right
   10150 	pack $w.b -side right
   10151 	pack $w.l -side left -expand 1 -fill x
   10152 	pack $w -side bottom -fill x
   10153 
   10154 	set i 0
   10155 	foreach t {DAYS EM CN OUN ON LOC ST CO} {
   10156 		set w .ccrt.f$i
   10157 		frame $w
   10158 		label $w.l -anchor w -text "$tcert($t)"
   10159 		entry $w.e -width $ew -textvariable ccert($t)
   10160 		pack $w.e  -side right
   10161 		pack $w.l  -side left -expand 1 -fill x
   10162 		pack $w -side bottom -fill x
   10163 		incr i
   10164 	}
   10165 
   10166 	pack .ccrt.f -side top -fill both -expand 1
   10167 
   10168 	center_win .ccrt
   10169 }
   10170 
   10171 proc import_check_mode {w} {
   10172 	global import_mode
   10173 	if {$import_mode == "paste"} {
   10174 		$w.mf.b configure -state disabled
   10175 		$w.mf.e configure -state disabled
   10176 		$w.plab configure -state normal
   10177 		$w.paste.t configure -state normal
   10178 	} else {
   10179 		$w.mf.b configure -state normal
   10180 		$w.mf.e configure -state normal
   10181 		$w.plab configure -state disabled
   10182 		$w.paste.t configure -state disabled
   10183 	}
   10184 }
   10185 
   10186 proc import_browse {par} {
   10187 	global import_file
   10188 
   10189 	set idir ""
   10190 	if {$import_file != ""} {
   10191 		set idir [get_idir_certs $import_file]
   10192 	}
   10193 	unix_dialog_resize $par
   10194 	if {$idir != ""} {
   10195 		set t [tk_getOpenFile -parent $par -initialdir $idir]
   10196 	} else {
   10197 		set t [tk_getOpenFile -parent $par]
   10198 	}
   10199 	if {$t != ""} {
   10200 		set import_file $t
   10201 	}
   10202 	catch {raise $par}
   10203 	update
   10204 }
   10205 
   10206 proc import_save_browse {{par ".icrt"}} {
   10207 	global import_save_file
   10208 
   10209 	set idir ""
   10210 	if {$import_save_file != ""} {
   10211 		set idir [get_idir_certs $import_save_file]
   10212 	}
   10213 	if {$idir == ""} {
   10214 		set idir [get_idir_certs ""]
   10215 	}
   10216 	unix_dialog_resize $par
   10217 	if {$idir != ""} {
   10218 		set t [tk_getSaveFile -parent $par -defaultextension ".crt" -initialdir $idir]
   10219 	} else {
   10220 		set t [tk_getSaveFile -parent $par -defaultextension ".crt"]
   10221 	}
   10222 	if {$t != ""} {
   10223 		set import_save_file $t
   10224 	}
   10225 	catch {raise $par}
   10226 	update
   10227 }
   10228 
   10229 proc do_save {par} {
   10230 	global import_mode import_file import_save_file
   10231 	global also_save_to_accepted_certs
   10232 
   10233 	if {![info exists also_save_to_accepted_certs]} {
   10234 		set also_save_to_accepted_certs 0
   10235 	}
   10236 
   10237 	if {$import_save_file == "" && ! $also_save_to_accepted_certs} {
   10238 		tk_messageBox -parent $par -type ok -icon error \
   10239 			-message "No Save File supplied" -title "Save File"
   10240 		return
   10241 	}
   10242 
   10243 	set str ""
   10244 	set subject_issuer ""
   10245 	if {$import_mode == "save_cert_text"} {
   10246 		global save_cert_text
   10247 		set str $save_cert_text
   10248 		set i 0
   10249 		foreach line [split $str "\n"] {
   10250 			incr i
   10251 			if {$i > 50} {
   10252 				break
   10253 			}
   10254 			if [regexp {^- subject: *(.*)$} $line m val] {
   10255 				set subject_issuer "${subject_issuer}subject:$val\n"
   10256 			}
   10257 			if [regexp {^- (issuer[0-9][0-9]*): *(.*)$} $line m is val] {
   10258 				set subject_issuer "${subject_issuer}$is:$val\n"
   10259 			}
   10260 			if [regexp {^INFO: SELF_SIGNED=(.*)$} $line m val] {
   10261 				set subject_issuer "${subject_issuer}SELF_SIGNED:$val\n"
   10262 			}
   10263 		}
   10264 	} elseif {$import_mode == "paste"} {
   10265 		set str [$par.paste.t get 1.0 end]
   10266 	} else {
   10267 		if {! [file exists $import_file]} {
   10268 			tk_messageBox -parent $par -type ok -icon error \
   10269 				-message "Input file \"$import_file\" does not exist." -title "Import File"
   10270 			return
   10271 		}
   10272 		set fh ""
   10273 		set emess ""
   10274 		set rc [catch {set fh [open $import_file "r"]} emess]
   10275 		if {$rc != 0 || $fh == ""} {
   10276 			tk_messageBox -parent $par -type ok -icon error \
   10277 				-message $emess -title "Import File: $import_file"
   10278 			return
   10279 		}
   10280 		while {[gets $fh line] > -1} {
   10281 			append str "$line\n"
   10282 		}
   10283 		close $fh
   10284 	}
   10285 
   10286 	if {! [regexp {BEGIN CERTIFICATE} $str]} {
   10287 		tk_messageBox -parent $par -type ok -icon error \
   10288 			-message "Import Text does not contain \"BEGIN CERTIFICATE\"" -title "Imported Text"
   10289 		return
   10290 	}
   10291 	if {! [regexp {END CERTIFICATE} $str]} {
   10292 		tk_messageBox -parent $par -type ok -icon error \
   10293 			-message "Import Text does not contain \"END CERTIFICATE\"" -title "Imported Text"
   10294 		return
   10295 	}
   10296 
   10297 	global is_windows
   10298 	set fh ""
   10299 	set emess ""
   10300 	set deltmp ""
   10301 	if {$import_save_file == ""} {
   10302 		if {! $is_windows} {
   10303 			set deltmp /tmp/import.[tpid]
   10304 		} else {
   10305 			set deltmp import.[tpid]
   10306 		}
   10307 		set deltmp [mytmp $deltmp]
   10308 		set import_save_file $deltmp
   10309 	}
   10310 	set rc [catch {set fh [open $import_save_file "w"]} emess]
   10311 	if {$rc != 0 || $fh == ""} {
   10312 		tk_messageBox -parent $par -type ok -icon error \
   10313 			-message $emess -title "Save File: $import_save_file"
   10314 		return
   10315 	}
   10316 	if {! $is_windows} {
   10317 		catch {file attributes $import_save_file -permissions go-w}
   10318 		if {[regexp {PRIVATE} $str] || [regexp {\.pem$} $import_save_file]} {
   10319 			catch {file attributes $import_save_file -permissions go-rw}
   10320 		}
   10321 	}
   10322 
   10323 	puts -nonewline $fh $str
   10324 	close $fh
   10325 
   10326 	global do_save_saved_it
   10327 	set do_save_saved_it 1
   10328 
   10329 	if {$also_save_to_accepted_certs} {
   10330 		set ossl [get_openssl]
   10331 		set fp_txt ""
   10332 		set fp_txt [exec $ossl x509 -fingerprint -noout -in $import_save_file]
   10333 
   10334 		set adir [get_idir_certs ""]
   10335 		set adir "$adir/accepted"
   10336 		catch {file mkdir $adir}
   10337 
   10338 		set fingerprint ""
   10339 		set fingerline ""
   10340 
   10341 		set i 0
   10342 		foreach line [split $fp_txt "\n"] {
   10343 			incr i
   10344 			if {$i > 5} {
   10345 				break
   10346 			}
   10347 			if [regexp -nocase {Fingerprint=(.*)} $line mv str] {
   10348 				set fingerline $line
   10349 				set fingerprint [string trim $str]
   10350 			}
   10351 		}
   10352 
   10353 		set fingerprint [string tolower $fingerprint]
   10354 		regsub -all {:} $fingerprint "-" fingerprint
   10355 		regsub -all {[\\/=]} $fingerprint "_" fingerprint
   10356 
   10357 		if {$subject_issuer == ""} {
   10358 			set si_txt ""
   10359 			set si_txt [exec $ossl x509 -subject -issuer -noout -in $import_save_file]
   10360 			set sub ""
   10361 			set iss ""
   10362 			foreach line [split $si_txt "\n"] {
   10363 				if [regexp -nocase {^subject= *(.*)$} $line mv str] {
   10364 					set str [string trim $str]
   10365 					set sub $str
   10366 				} elseif [regexp -nocase {^issuer= *(.*)$} $line mv str] {
   10367 					set str [string trim $str]
   10368 					set iss $str
   10369 				}
   10370 			}
   10371 			if {$sub != "" && $iss != ""} {
   10372 				set subject_issuer "subject:$sub\nissuer1:$iss\n"
   10373 				if {$sub == $iss} {
   10374 					set subject_issuer "${subject_issuer}SELF_SIGNED:1\n"
   10375 				} else {
   10376 					set subject_issuer "${subject_issuer}SELF_SIGNED:0\n"
   10377 				}
   10378 			}
   10379 		}
   10380 
   10381 		global vncdisplay
   10382 		set from [get_ssh_hp $vncdisplay]
   10383 		if {$from == ""} {
   10384 			set from [file tail $import_save_file]
   10385 			regsub {\..*$} $from "" from
   10386 		}
   10387 		if {$from == ""} {
   10388 			set from "import"
   10389 		}
   10390 		if [regexp -- {^:[0-9][0-9]*$} $from] {
   10391 			set from "listen$from"
   10392 		}
   10393 		set hp $from
   10394 
   10395 		set from [string tolower $from]
   10396 		regsub -all {^[+a-z]*://} $from "" from
   10397 		regsub -all {:} $from "-" from
   10398 		regsub -all {[\\/=]} $from "_" from
   10399 		regsub -all {[ 	]} $from "_" from
   10400 
   10401 		set crt "$adir/$from=$fingerprint.crt"
   10402 		catch {file copy -force $import_save_file $crt}
   10403 
   10404 		global do_save_saved_hash_it
   10405 		set do_save_saved_hash_it 1
   10406 		save_hash $crt $adir $hp $fingerline $from $fingerprint $subject_issuer
   10407 	}
   10408 
   10409 	catch {destroy $par}
   10410 	set p .c
   10411 	if {![winfo exists .c]} {
   10412 		global accepted_cert_dialog_in_progress
   10413 		if {! $accepted_cert_dialog_in_progress} {
   10414 			if {$deltmp == ""} {
   10415 				getcerts
   10416 				update
   10417 			}
   10418 		}
   10419 	}
   10420 	if {![winfo exists .c]} {
   10421 		set p .
   10422 	}
   10423 	catch {raise .c}
   10424 	catch {destroy .scrt}
   10425 	if {$deltmp != ""} {
   10426 		catch {file delete $deltmp}
   10427 		set import_save_file ""
   10428 		return;
   10429 	}
   10430 	tk_messageBox -parent $p -type ok -icon info \
   10431 		-message "Saved to file: $import_save_file" -title "Save File: $import_save_file"
   10432 }
   10433 
   10434 proc import_cert {} {
   10435 
   10436 	toplev .icrt
   10437 	wm title .icrt "Import SSL Certificate"
   10438 
   10439 	global scroll_text_focus
   10440 	set scroll_text_focus 0
   10441 	global uname
   10442 	set h 19
   10443 	if [small_height] {
   10444 		set h 12
   10445 	} elseif {$uname == "Darwin"} {
   10446 		set h 16
   10447 	}
   10448 	scroll_text .icrt.f 90 $h
   10449 	set scroll_text_focus 1
   10450 
   10451 	set msg {
   10452     This dialog lets you import a SSL Certificate by either pasting one in or by
   10453     loading from another file.  Choose which input mode you want to use by the toggle
   10454     "Paste / Read from File".
   10455 
   10456     There are two types of files we use 1) Certificate only, and 2) Private Key
   10457     and Certificate.
   10458 
   10459     Type 1) would be used to verify the identity of a remote VNC Server, whereas
   10460     type 2) would be used to authenticate ourselves to the remote VNC Server.
   10461 
   10462     A type 1) by convention ends with file suffix ".crt" and looks like:
   10463 
   10464 -----BEGIN CERTIFICATE-----
   10465 MIID2jCCAsKgAwIBAgIJALKypfV8BItCMA0GCSqGSIb3DQEBBAUAMIGgMQswCQYD
   10466 (more lines) ...
   10467 TCQ+tbQ/DOiTXGKx1nlcKoPdkG+QVQVJthlQcpam
   10468 -----END CERTIFICATE-----
   10469 
   10470     A type 2) by convention ends with file suffix ".pem" and looks like:
   10471 
   10472 -----BEGIN RSA PRIVATE KEY-----
   10473 MIIEpAIBAAKCAQEA4sApd7WaPKQRWnFe9T04D4pglQB0Ti0/dCVHxg8WEVQ8OdcW
   10474 (more lines) ...
   10475 9kBmNotUiTpvRM+e7E/zRemhvY9qraFooqMWzi9JrgYfeLfSvvFfGw==
   10476 -----END RSA PRIVATE KEY-----
   10477 -----BEGIN CERTIFICATE-----
   10478 MIID2jCCAsKgAwIBAgIJALKypfV8BItCMA0GCSqGSIb3DQEBBAUAMIGgMQswCQYD
   10479 (more lines) ...
   10480 TCQ+tbQ/DOiTXGKx1nlcKoPdkG+QVQVJthlQcpam
   10481 -----END CERTIFICATE-----
   10482 
   10483     You do not need to use the ".crt" or ".pem" convention if you do not want to.
   10484 
   10485     First, either paste in the text or set the "Read from File" filename.
   10486 
   10487     Next, set the "Save to File" name to the file where the imported certificate
   10488     will be saved.
   10489 
   10490     Then, click on "Save" to save the imported Certificate.
   10491 
   10492     After you have imported the Certificate (or Key + Certificate), select it to
   10493     use for a connection via the "MyCert" or "ServerCert" dialog.
   10494 }
   10495 	.icrt.f.t insert end $msg
   10496 
   10497 	global icert import_mode
   10498 
   10499 	set import_mode "paste"
   10500 
   10501 	set w .icrt.mf
   10502 	frame $w
   10503 
   10504 	radiobutton $w.p -pady 1 -anchor w -variable import_mode -value paste \
   10505 		-text "Paste" -command "import_check_mode .icrt"
   10506 
   10507 	radiobutton $w.f -pady 1 -anchor w -variable import_mode -value file \
   10508 		-text "Read from File:" -command "import_check_mode .icrt"
   10509 
   10510 	global import_file
   10511 	set import_file ""
   10512 	entry $w.e -width 40 -textvariable import_file
   10513 
   10514 	button $w.b -pady 1 -anchor w -text "Browse..." -command {import_browse .icrt}
   10515 	pack $w.b -side right
   10516 	pack $w.p $w.f -side left
   10517 	pack $w.e -side left -expand 1 -fill x
   10518 
   10519 	$w.b configure -state disabled
   10520 	$w.e configure -state disabled
   10521 
   10522 	label .icrt.plab -anchor w -text "Paste Certificate here:     (extra blank lines above or below are OK)"
   10523 	set h 22
   10524 	if [small_height] {
   10525 		set h 11
   10526 	} elseif {$uname == "Darwin"} {
   10527 		set h 11
   10528 	}
   10529 	scroll_text .icrt.paste 90 $h
   10530 
   10531 	button .icrt.cancel -text "Cancel" -command {destroy .icrt; catch {raise .c}}
   10532 	bind .icrt <Escape> {destroy .icrt; catch {raise .c}}
   10533 	wm protocol .icrt WM_DELETE_WINDOW {destroy .icrt; catch {raise .c}}
   10534 
   10535 	button .icrt.save -text "Save" -command {do_save .icrt}
   10536 
   10537 	set w .icrt.sf
   10538 	frame $w
   10539 
   10540 	label $w.l -text "Save to File:" -anchor w
   10541 	global import_save_file
   10542 	set import_save_file ""
   10543 	entry $w.e -width 40 -textvariable import_save_file
   10544 	button $w.b -pady 1 -anchor w -text "Browse..." -command import_save_browse
   10545 
   10546 	global also_save_to_accepted_certs
   10547 	set also_save_to_accepted_certs 0
   10548 	checkbutton .icrt.ac -anchor w -variable also_save_to_accepted_certs -text \
   10549 	    "Also Save to the 'Accepted Certs' directory" -relief raised
   10550 
   10551 	pack $w.b -side right
   10552 	pack $w.l -side left
   10553 	pack $w.e -side left -expand 1 -fill x
   10554 
   10555 	pack .icrt.save .icrt.cancel .icrt.ac .icrt.sf .icrt.mf -side bottom -fill x
   10556 	pack .icrt.paste .icrt.plab -side bottom -fill x
   10557 
   10558 	pack .icrt.f -side top -fill both -expand 1
   10559 
   10560 	.icrt.paste.t insert end ""
   10561 
   10562 	focus .icrt.paste.t
   10563 
   10564 	center_win .icrt
   10565 }
   10566 
   10567 proc save_cert {hp} {
   10568 
   10569 	global cert_text
   10570 
   10571 	toplev .scrt
   10572 	wm title .scrt "Import/Save SSL Certificate"
   10573 
   10574 	global scroll_text_focus
   10575 	set scroll_text_focus 0
   10576 	global uname
   10577 
   10578 	global accepted_cert_dialog_in_progress
   10579 	set h 20
   10580 	if {$accepted_cert_dialog_in_progress} {
   10581 		set mode "accepted"
   10582 		set h 15
   10583 		if [small_height] {
   10584 			set h 11
   10585 		}
   10586 	} else {
   10587 		set mode "normal"
   10588 		set h 20
   10589 		if [small_height] {
   10590 			set h 16
   10591 		}
   10592 	}
   10593 	scroll_text .scrt.f 90 $h
   10594 
   10595 	set scroll_text_focus 1
   10596 
   10597 	set msg1 {
   10598     This dialog lets you import a SSL Certificate retrieved from a VNC server.
   10599 
   10600     Be sure to have verified its authenticity via an external means (checking
   10601     the MD5 hash value sent to you by the administrator, etc)
   10602 
   10603     Set "Save to File" to the filename where the imported cert will be saved.
   10604 
   10605     If you also want the Certificate to be saved to the pool of certs in the
   10606     'Accepted Certs' directory, select the checkbox.  By default all Servers are
   10607     verified against the certificates in this pool.
   10608 
   10609     Then, click on "Save" to save the imported Certificate.
   10610 
   10611     After you have imported the Certificate it will be automatically selected as
   10612     the "ServerCert" for the next connection to this host: %HOST
   10613 
   10614     To make the ServerCert setting to the imported cert file PERMANENT, select
   10615     'Save' to save it in the profile for this host.
   10616 }
   10617 
   10618 	set msg2 {
   10619     This dialog lets you import a SSL Certificate retrieved from a VNC server.
   10620 
   10621     Be sure to have verified its authenticity via an external means (checking
   10622     the MD5 hash value sent to you by the administrator, etc)
   10623 
   10624     It will be added to the 'Accepted Certs' directory.  The "Save to File"
   10625     below is already set to the correct directory and file name.
   10626 
   10627     Click on "Save" to add it to the Accepted Certs.
   10628 
   10629     It, and the other certs in that directory, will be used to authenticate
   10630     any VNC Server that has "ACCEPTED_CERTS" as the "CertsDir" value in the
   10631     "Certs..." dialog.  This is the default checking policy.
   10632 }
   10633 
   10634 	set msg ""
   10635 	if {$mode == "normal"} {
   10636 		set msg $msg1
   10637 	} else {
   10638 		set msg $msg2
   10639 	}
   10640 
   10641 	regsub {%HOST} $msg "$hp" msg
   10642 	.scrt.f.t insert end $msg
   10643 
   10644 	set w .scrt.mf
   10645 	frame $w
   10646 
   10647 	global import_file
   10648 	set import_file ""
   10649 	entry $w.e -width 40 -textvariable import_file
   10650 
   10651 	set h 22
   10652 	if [small_height] {
   10653 		set h 10
   10654 	}
   10655 	scroll_text .scrt.paste 90 $h
   10656 
   10657 	button .scrt.cancel -text "Cancel" -command {destroy .scrt; catch {raise .c}}
   10658 	bind .scrt <Escape> {destroy .scrt; catch {raise .c}}
   10659 	wm protocol .scrt WM_DELETE_WINDOW {destroy .scrt; catch {raise .c}}
   10660 
   10661 	global import_save_file
   10662 	if {$mode == "normal"} {
   10663 		button .scrt.save -text "Save" -command {do_save .scrt; set svcert $import_save_file}
   10664 	} else {
   10665 		button .scrt.save -text "Save" -command {do_save .scrt}
   10666 	}
   10667 
   10668 	if [regexp -nocase -- {ACCEPT} $cert_text] {
   10669 		if [regexp -nocase -- {Client certificate} $cert_text] {
   10670 			if [regexp -- {^:[0-9][0-9]*$} $hp] {
   10671 				if [regexp -nocase {subject=.*CN=([^/][^/]*)/} $cert_text mv0 mv1] {
   10672 					regsub -all {[ 	]} $mv1 "" mv1
   10673 					set hp "$mv1$hp"
   10674 				} else {
   10675 					set hp "listen$hp"
   10676 				}
   10677 			}
   10678 		}
   10679 	}
   10680 
   10681 	set w .scrt.sf
   10682 	frame $w
   10683 
   10684 	label $w.l -text "Save to File:" -anchor w
   10685 	set import_save_file "server:$hp.crt"
   10686 	global is_windows
   10687 	regsub -all {:} $import_save_file "-" import_save_file
   10688 
   10689 	set import_save_file [get_idir_certs ""]/$import_save_file
   10690 
   10691 	global fetch_cert_filename
   10692 	if {$fetch_cert_filename != ""} {
   10693 		set import_save_file $fetch_cert_filename
   10694 	}
   10695 
   10696 	entry $w.e -width 40 -textvariable import_save_file
   10697 	button $w.b -pady 1 -anchor w -text "Browse..." -command {import_save_browse .scrt}
   10698 
   10699 	pack $w.b -side right
   10700 	pack $w.l -side left
   10701 	pack $w.e -side left -expand 1 -fill x
   10702 
   10703 	global also_save_to_accepted_certs
   10704 	set also_save_to_accepted_certs 0
   10705 	if [regexp -nocase -- {ACCEPT} $cert_text] {
   10706 		if [regexp -nocase -- {Client certificate} $cert_text] {
   10707 			set also_save_to_accepted_certs 1
   10708 		}
   10709 	}
   10710 	checkbutton .scrt.ac -anchor w -variable also_save_to_accepted_certs -text \
   10711 	    "Also Save to the 'Accepted Certs' directory" -relief raised
   10712 
   10713 	if {$mode == "normal"} {
   10714 		pack .scrt.cancel .scrt.save .scrt.sf .scrt.ac .scrt.mf -side bottom -fill x
   10715 	} else {
   10716 		pack .scrt.cancel .scrt.save .scrt.sf          .scrt.mf -side bottom -fill x
   10717 	}
   10718 	pack .scrt.paste -side bottom -fill x
   10719 
   10720 	pack .scrt.f -side top -fill both -expand 1
   10721 
   10722 	set text ""
   10723 	set on 0
   10724 	foreach line [split $cert_text "\n"] {
   10725 		if [regexp -- {-----BEGIN CERTIFICATE-----} $line] {
   10726 			incr on
   10727 		}
   10728 		if {$on != 1} {
   10729 			continue;
   10730 		}
   10731 		append text "$line\n"
   10732 		if [regexp -- {-----END CERTIFICATE-----} $line] {
   10733 			set on 2
   10734 		}
   10735 	}
   10736 	global save_cert_text
   10737 	set save_cert_text $text
   10738 	.scrt.paste.t insert end "$text"
   10739 	global import_mode
   10740 	set import_mode "save_cert_text"
   10741 
   10742 	focus .scrt.paste.t
   10743 
   10744 	center_win .scrt
   10745 }
   10746 
   10747 
   10748 proc getcerts {} {
   10749 	global mycert svcert crtdir crlfil
   10750 	global use_ssh use_sshssl
   10751 	toplev .c
   10752 	wm title .c "SSL Certificates"
   10753 	frame .c.mycert
   10754 	frame .c.svcert
   10755 	frame .c.crtdir
   10756 	frame .c.crlfil
   10757 	label .c.mycert.l -anchor w -width 12 -text "MyCert:"
   10758 	label .c.svcert.l -anchor w -width 12 -text "ServerCert:"
   10759 	label .c.crtdir.l -anchor w -width 12 -text "CertsDir:"
   10760 	label .c.crlfil.l -anchor w -width 12 -text "CRL File:"
   10761 
   10762 	entry .c.mycert.e -width 32 -textvariable mycert -vcmd v_mycert
   10763 	entry .c.svcert.e -width 32 -textvariable svcert -vcmd v_svcert
   10764 	entry .c.crtdir.e -width 32 -textvariable crtdir
   10765 	entry .c.crlfil.e -width 32 -textvariable crlfil -vcmd v_crlfil
   10766 
   10767 	bind .c.mycert.e <Enter> {.c.mycert.e validate}
   10768 	bind .c.mycert.e <Leave> {.c.mycert.e validate}
   10769 	bind .c.svcert.e <Enter> {.c.svcert.e validate}
   10770 	bind .c.svcert.e <Leave> {.c.svcert.e validate}
   10771 
   10772 	button .c.mycert.b -text "Browse..." -command {set_mycert .c; catch {raise .c}}
   10773 	button .c.svcert.b -text "Browse..." -command {set_svcert .c; catch {raise .c}}
   10774 	button .c.crtdir.b -text "Browse..." -command {set_crtdir .c; catch {raise .c}}
   10775 	button .c.crlfil.b -text "Browse..." -command {set_crlfil .c; catch {raise .c}}
   10776 
   10777 	button .c.mycert.i -text "Info" -command {show_mycert}
   10778 	button .c.svcert.i -text "Info" -command {show_svcert}
   10779 	button .c.crtdir.i -text "Info" -command {}
   10780 	button .c.crlfil.i -text "Info" -command {show_crlfil}
   10781 
   10782 	bind .c.mycert.b <Enter> "v_mycert"
   10783 	bind .c.svcert.b <Enter> "v_svcert"
   10784 	bind .c.crlfil.b <Enter> "v_crlfil"
   10785 
   10786 	.c.mycert.i configure -state disabled
   10787 	.c.svcert.i configure -state disabled
   10788 	.c.crtdir.i configure -state disabled
   10789 	.c.crlfil.i configure -state disabled
   10790 
   10791 	bind .c.mycert.b <B3-ButtonRelease>   "show_mycert"
   10792 	bind .c.svcert.b <B3-ButtonRelease>   "show_svcert"
   10793 	bind .c.crlfil.b <B3-ButtonRelease>   "show_crlfil"
   10794 
   10795 	set do_crl 1
   10796 	set do_row 1
   10797 
   10798 	set c .c
   10799 	if {$do_row} {
   10800 		frame .c.b0
   10801 		set c .c.b0
   10802 	}
   10803 
   10804 	button $c.create -text "Create Certificate ..." -command {create_cert}
   10805 	button $c.import -text "Import Certificate ..." -command {import_cert}
   10806 	button $c.delete -text "Delete Certificate ..." -command {delete_cert .c}
   10807 
   10808 	if {$c != ".c"} {
   10809 		pack $c.create $c.import $c.delete  -fill x -expand 1 -side left
   10810 	}
   10811 
   10812 	frame .c.b
   10813 	button .c.b.done -text "Done" -command {catch {destroy .c}}
   10814 	bind .c <Escape> {destroy .c}
   10815 	button .c.b.help -text "Help" -command help_certs
   10816 	pack .c.b.help .c.b.done -fill x -expand 1 -side left
   10817 
   10818 	set wlist [list mycert svcert crtdir]
   10819 	lappend wlist crlfil
   10820 
   10821 	foreach w $wlist {
   10822 		pack .c.$w.l -side left
   10823 		pack .c.$w.e -side left -expand 1 -fill x
   10824 		pack .c.$w.b -side left
   10825 		pack .c.$w.i -side left
   10826 		bind .c.$w.e <Return> ".c.$w.b invoke"
   10827 		if {$use_ssh} {
   10828 			.c.$w.l configure -state disabled
   10829 			.c.$w.e configure -state disabled
   10830 			.c.$w.b configure -state disabled
   10831 		}
   10832 	}
   10833 
   10834 	global svcert_default_force mycert_default_force crlfil_default_force
   10835 	if {$mycert_default_force} {
   10836 		.c.mycert.e configure -state readonly
   10837 		.c.mycert.b configure -state disabled
   10838 	}
   10839 	if {$svcert_default_force} {
   10840 		.c.svcert.e configure -state readonly
   10841 		.c.svcert.b configure -state disabled
   10842 		.c.crtdir.e configure -state readonly
   10843 		.c.crtdir.b configure -state disabled
   10844 	}
   10845 	if {$crlfil_default_force} {
   10846 		.c.crlfil.e configure -state readonly
   10847 		.c.crlfil.b configure -state disabled
   10848 	}
   10849 
   10850 	if {$mycert != ""} {
   10851 		v_mycert
   10852 	}
   10853 	if {$svcert != ""} {
   10854 		v_svcert
   10855 	}
   10856 	if {$crlfil != ""} {
   10857 		v_crlfil
   10858 	}
   10859 
   10860 	set wlist [list .c.mycert .c.svcert .c.crtdir]
   10861 	if {$do_crl} {
   10862 		lappend wlist .c.crlfil
   10863 	}
   10864 	if {$c != ".c"} {
   10865 		lappend wlist $c
   10866 	} else {
   10867 		lappend wlist .c.create .c.import .c.delete
   10868 	}
   10869 	lappend wlist .c.b
   10870 
   10871 	eval pack $wlist -side top -fill x
   10872 
   10873 	center_win .c
   10874 	wm resizable .c 1 0
   10875 
   10876 	focus .c
   10877 }
   10878 
   10879 proc get_profiles_dir {} {
   10880 	global env is_windows
   10881 
   10882 	set dir ""
   10883 	if {$is_windows} {
   10884 		if [info exists env(SSVNC_HOME)] {
   10885 			set t "$env(SSVNC_HOME)/ss_vnc"
   10886 			regsub -all {\\} $t "/" t
   10887 			regsub -all {//*} $t "/" t
   10888 			if {! [file isdirectory $t]} {
   10889 				catch {file mkdir $t}
   10890 			}
   10891 			if [file isdirectory $t] {
   10892 				set dir $t
   10893 				set s "$t/profiles"
   10894 				if {! [file exists $s]} {
   10895 					catch {file mkdir $s}
   10896 				}
   10897 			}
   10898 		}
   10899 		if {$dir == ""} {
   10900 			set t [file dirname [pwd]]
   10901 			set t "$t/profiles"
   10902 			if [file isdirectory $t] {
   10903 				set dir $t
   10904 			}
   10905 		}
   10906 	} elseif [info exists env(SSVNC_HOME)] {
   10907 		set t "$env(SSVNC_HOME)/.vnc"
   10908 		catch {file mkdir $t}
   10909 		if [file isdirectory $t] {
   10910 			set dir $t
   10911 			set s "$t/profiles"
   10912 			if {! [file exists $s]} {
   10913 				catch {file mkdir $s}
   10914 			}
   10915 		}
   10916 	}
   10917 
   10918 	if {$dir != ""} {
   10919 
   10920 	} elseif [info exists env(SSVNC_BASEDIR)] {
   10921 		set dir $env(SSVNC_BASEDIR)
   10922 	} else {
   10923 		set dir [pwd]
   10924 	}
   10925 	if [file isdirectory "$dir/profiles"] {
   10926 		set dir "$dir/profiles"
   10927 	}
   10928 	return $dir
   10929 }
   10930 
   10931 proc globalize {} {
   10932 	global defs
   10933 	foreach var [array names defs] {
   10934 		uplevel global $var
   10935 	}
   10936 }
   10937 
   10938 proc load_include {include dir} {
   10939 	global include_vars defs
   10940 
   10941 	if [info exists include_vars] {
   10942 		unset include_vars
   10943 	}
   10944 
   10945 	foreach inc [split $include ", "] {
   10946 		set f [string trim $inc]
   10947 #puts "f=$f";
   10948 		if {$f == ""} {
   10949 			continue
   10950 		}
   10951 		set try ""
   10952 		if {[regexp {/} $f] || [regexp {\\} $f]} {
   10953 			set try $f;
   10954 		} else {
   10955 			set try "$dir/$f"
   10956 		}
   10957 		if {! [file exists $try]} {
   10958 			set try "$dir/$f.vnc"
   10959 		}
   10960 #puts "try: $try"
   10961 		if [file exists $try] {
   10962 			set fh ""
   10963 			catch {set fh [open $try "r"]}
   10964 			if {$fh == ""} {
   10965 				continue
   10966 			}
   10967 			mesg "Applying template: $inc"
   10968 			after 100
   10969 			while {[gets $fh line] > -1} {
   10970 				append inc_str "$line\n"
   10971 				if [regexp {^([^=]*)=(.*)$} $line m var val] {
   10972 					if {! [info exists defs($var)]} {
   10973 						continue
   10974 					}
   10975 					if {$var == "include_list"} {
   10976 						continue
   10977 					}
   10978 					set pct 0
   10979 					if {$var == "smb_mount_list"} {
   10980 						set pct 1
   10981 					}
   10982 					if {$var == "port_knocking_list"} {
   10983 						set pct 1
   10984 					}
   10985 					if {$pct} {
   10986 						regsub -all {%%%} $val "\n" val
   10987 					}
   10988 					if {$val != $defs($var)} {
   10989 #puts "include_vars $var $val"
   10990 						set include_vars($var) $val
   10991 					}
   10992 				}
   10993 			}
   10994 			catch {close $fh}
   10995 		}
   10996 	}
   10997 }
   10998 
   10999 proc unix_dialog_resize {{w .}} {
   11000 	global env is_windows uname unix_dialog_size
   11001 	set ok 0
   11002 	set width 600
   11003 	set height 300
   11004 	if {[info exists env(SSVNC_BIGGER_DIALOG)]} {
   11005 		set ok 1
   11006 		if {[regexp {([0-9][0-9]*)x([0-9][0-9]*)} $env(SSVNC_BIGGER_DIALOG) m wi he]} {
   11007 			set width $wi;
   11008 			set height $he;
   11009 		}
   11010 	} elseif {[info exists env(USER)] && $env(USER) == "runge"} {
   11011 		set ok 1
   11012 	}
   11013 	if {$ok} {
   11014 		# this is a personal hack because tk_getOpenFile size is not configurable.
   11015 		if {!$is_windows && $uname != "Darwin"} {
   11016 			if {$w == "."} {
   11017 				set w2 .__tk_filedialog
   11018 			} else {
   11019 				set w2 $w.__tk_filedialog
   11020 			}
   11021 			set w3 $w2.icons.canvas
   11022 			global udr_w4
   11023 			set udr_w4 $w2.f2.cancel
   11024 			if {! [info exists unix_dialog_size($w)]} {
   11025 				after 50 {global udr_w4; catch {$udr_w4 invoke}}
   11026 				tk_getOpenFile -parent $w -initialdir /
   11027 				set unix_dialog_size($w) 1
   11028 			}
   11029 			if [winfo exists $w3] {
   11030 				catch {$w3 configure -width $width}
   11031 				catch {$w3 configure -height $height}
   11032 			}
   11033 		}
   11034 	}
   11035 }
   11036 
   11037 proc delete_profile {{parent "."}} {
   11038 
   11039 	globalize
   11040 
   11041 	set dir [get_profiles_dir]
   11042 
   11043 	unix_dialog_resize $parent
   11044 	set file [tk_getOpenFile -parent $parent -initialdir $dir -title "DELETE VNC Profile"]
   11045 
   11046 	if {$file == ""} {
   11047 		return
   11048 	}
   11049 
   11050 	set tail [file tail $file]
   11051 
   11052 	set ans [tk_messageBox -type okcancel -title "Delete $tail" -message "Really Delete $file?" -icon warning]
   11053 
   11054 	if {$ans == "ok"} {
   11055 		catch {file delete $file}
   11056 		mesg "Deleted $tail"
   11057 	} else {
   11058 		mesg "Delete Skipped."
   11059 	}
   11060 }
   11061 
   11062 proc load_profile {{parent "."} {infile ""}} {
   11063 	global profdone
   11064 	global vncdisplay
   11065 
   11066 	globalize
   11067 
   11068 	set dir [get_profiles_dir]
   11069 
   11070 	if {$infile != ""} {
   11071 		set file $infile
   11072 	} else {
   11073 		unix_dialog_resize
   11074 		set file [tk_getOpenFile -parent $parent -defaultextension \
   11075 			".vnc" -initialdir $dir -title "Load VNC Profile"]
   11076 	}
   11077 
   11078 	if {$file == ""} {
   11079 		set profdone 1
   11080 		return
   11081 	}
   11082 	set fh [open $file "r"]
   11083 	if {! [info exists fh]} {
   11084 		set profdone 1
   11085 		return
   11086 	}
   11087 
   11088 	set goto_mode "";
   11089 	set str ""
   11090 	set include ""
   11091 	set sw 1
   11092 	while {[gets $fh line] > -1} {
   11093 		append str "$line\n"
   11094 		if [regexp {^include_list=(.*)$} $line m val] {
   11095 			set include $val
   11096 		}
   11097 		global ssh_only ts_only
   11098 		if {$ssh_only || $ts_only} {
   11099 			if [regexp {use_ssh=0} $line] {
   11100 				if {$sw} {
   11101 					mesg "Switching to SSVNC mode."
   11102 					set goto_mode "ssvnc"
   11103 					update
   11104 					after 300
   11105 				} else {
   11106 					bell
   11107 					mesg "Cannot Load an SSL profile in SSH-ONLY mode."
   11108 					set profdone 1
   11109 					close $fh
   11110 					return
   11111 				}
   11112 			}
   11113 		}
   11114 		if {! $ts_only} {
   11115 			if [regexp {ts_mode=1} $line] {
   11116 				if {$sw} {
   11117 					mesg "Switching to Terminal Services mode."
   11118 					set goto_mode "tsonly"
   11119 					update
   11120 					after 300
   11121 				} else {
   11122 					bell
   11123 					mesg "Cannot Load a Terminal Svcs profile SSVNC mode."
   11124 					set profdone 1
   11125 					close $fh
   11126 					return
   11127 				}
   11128 			}
   11129 		} else {
   11130 			if [regexp {ts_mode=0} $line] {
   11131 				if {$sw} {
   11132 					mesg "Switching to SSVNC mode."
   11133 					set goto_mode "ssvnc"
   11134 					update
   11135 					after 300
   11136 				} else {
   11137 					bell
   11138 					mesg "Cannot Load a Terminal Svcs profile SSVNC mode."
   11139 					set profdone 1
   11140 					close $fh
   11141 					return
   11142 				}
   11143 			}
   11144 		}
   11145 	}
   11146 	close $fh
   11147 
   11148 	if {$include != ""} {
   11149 		load_include $include $dir
   11150 	}
   11151 
   11152 	if {$goto_mode == "tsonly"} {
   11153 		to_tsonly
   11154 	} elseif {$goto_mode == "ssvnc"} {
   11155 		to_ssvnc
   11156 	} elseif {$goto_mode == "sshvnc"} {
   11157 		to_sshvnc
   11158 	}
   11159 	set_defaults
   11160 
   11161 	global include_vars
   11162 	if [info exists include_vars] {
   11163 		foreach var [array names include_vars] {
   11164 			set $var $include_vars($var)
   11165 		}
   11166 	}
   11167 
   11168 
   11169 	global use_ssl use_ssh use_sshssl
   11170 	set use_ssl 0
   11171 	set use_ssh 0
   11172 	set use_sshssl 0
   11173 
   11174 	global defs
   11175 	foreach line [split $str "\n"] {
   11176 		set line [string trim $line]
   11177 		if [regexp {^#} $line] {
   11178 			continue
   11179 		}
   11180 		if [regexp {^([^=]*)=(.*)$} $line m var val] {
   11181 			if {$var == "disp"} {
   11182 				set vncdisplay $val
   11183 				continue
   11184 			}
   11185 			if [info exists defs($var)] {
   11186 				set pct 0
   11187 				if {$var == "smb_mount_list"} {
   11188 					set pct 1
   11189 				}
   11190 				if {$var == "port_knocking_list"} {
   11191 					set pct 1
   11192 				}
   11193 				if {$pct} {
   11194 					regsub -all {%%%} $val "\n" val
   11195 				}
   11196 				set $var $val
   11197 			}
   11198 		}
   11199 	}
   11200 
   11201 	init_vncdisplay
   11202 	if {! $use_ssl && ! $use_ssh && ! $use_sshssl} {
   11203 		if {! $disable_all_encryption} {
   11204 			set use_ssl 1
   11205 		}
   11206 	}
   11207 	if {$use_ssl} {
   11208 		set use_ssh 0
   11209 		set use_sshssl 0
   11210 	} elseif {$use_ssh && $use_sshssl} {
   11211 		set use_ssh 0
   11212 	}
   11213 	sync_use_ssl_ssh
   11214 
   11215 	set compresslevel_text "Compress Level: $use_compresslevel"
   11216 	set quality_text "Quality: $use_quality"
   11217 
   11218 	set profdone 1
   11219 	putty_pw_entry check
   11220 	listen_adjust
   11221 	unixpw_adjust
   11222 
   11223 	global last_load
   11224 	set last_load [file tail $file]
   11225 
   11226 	global uname darwin_cotvnc
   11227 	if {$uname == "Darwin"} {
   11228 		if {$use_x11_macosx} {
   11229 			set darwin_cotvnc 0;
   11230 		} else {
   11231 			set darwin_cotvnc 1;
   11232 		}
   11233 	}
   11234 
   11235 	mesg "Loaded [file tail $file]"
   11236 }
   11237 
   11238 proc sync_use_ssl_ssh {} {
   11239 	global use_ssl use_ssh use_sshssl
   11240 	global disable_all_encryption
   11241 	if {$use_ssl} {
   11242 		ssl_ssh_adjust ssl
   11243 	} elseif {$use_ssh} {
   11244 		ssl_ssh_adjust ssh
   11245 	} elseif {$use_sshssl} {
   11246 		ssl_ssh_adjust sshssl
   11247 	} elseif {$disable_all_encryption} {
   11248 		ssl_ssh_adjust none
   11249 	} else {
   11250 		ssl_ssh_adjust ssl
   11251 	}
   11252 }
   11253 
   11254 proc save_profile {{parent "."}} {
   11255 	global is_windows uname
   11256 	global profdone
   11257 	global include_vars defs
   11258 	global ts_only
   11259 	global last_load
   11260 
   11261 	globalize
   11262 
   11263 	set dir [get_profiles_dir]
   11264 
   11265 	set vncdisp [get_vncdisplay]
   11266 
   11267 	set dispf [string trim $vncdisp]
   11268 	if {$dispf != ""} {
   11269 		regsub {[ 	].*$} $dispf "" dispf
   11270 		regsub -all {/} $dispf "" dispf
   11271 	} else {
   11272 		global ts_only
   11273 		if {$ts_only} {
   11274 			mesg "No VNC Terminal Server supplied."
   11275 		} else {
   11276 			mesg "No VNC Host:Disp supplied."
   11277 		}
   11278 		bell
   11279 		return
   11280 	}
   11281 	if {$is_windows || $uname == "Darwin"} {
   11282 		regsub -all {:} $dispf "-" dispf
   11283 	} else {
   11284 		regsub -all {:} $dispf "-" dispf
   11285 	}
   11286 	regsub -all {[\[\]]} $dispf "" dispf
   11287 	if {$ts_only && ![regexp {^TS-} $dispf]} {
   11288 		set dispf "TS-$dispf"
   11289 	}
   11290 	if {![regexp {\.vnc$} $dispf]} {
   11291 		set dispf "$dispf.vnc"
   11292 	}
   11293 
   11294 	set guess $dispf
   11295 	if {$last_load != ""} {
   11296 		set guess $last_load
   11297 	}
   11298 
   11299 	unix_dialog_resize
   11300 	set file [tk_getSaveFile -parent $parent -defaultextension ".vnc" \
   11301 		-initialdir $dir -initialfile "$guess" -title "Save VNC Profile"]
   11302 	if {$file == ""} {
   11303 		set profdone 1
   11304 		return
   11305 	}
   11306 	set fh [open $file "w"]
   11307 	if {! [info exists fh]} {
   11308 		set profdone 1
   11309 		return
   11310 	}
   11311 	set h [string trim $vncdisp]
   11312 	set p $h
   11313 	# XXX host_part
   11314 	regsub {:[0-9][0-9]*$} $h "" h
   11315 	set host $h
   11316 	regsub {[ 	].*$} $p "" p
   11317 	regsub {^.*:} $p "" p
   11318 	regsub { .*$} $p "" p
   11319 	if {$p == ""} {
   11320 		set p 0
   11321 	} elseif {![regexp {^[-0-9][0-9]*$} $p]} {
   11322 		set p 0
   11323 	}
   11324 	if {$p < 0} {
   11325 		set port $p
   11326 	} elseif {$p < 200} {
   11327 		set port [expr $p + 5900]
   11328 	} else {
   11329 		set port $p
   11330 	}
   11331 
   11332 	set h [string trim $vncdisp]
   11333 	regsub {cmd=.*$} $h "" h
   11334 	set h [string trim $h]
   11335 	if {! [regexp {[ 	]} $h]} {
   11336 		set h ""
   11337 	} else {
   11338 		regsub {^.*[ 	]} $h "" h
   11339 	}
   11340 	if {$h == ""} {
   11341 		set proxy ""
   11342 		set proxyport ""
   11343 	} else {
   11344 		set p $h
   11345 		regsub {:[0-9][0-9]*$} $h "" h
   11346 		set proxy $h
   11347 		regsub {[ 	].*$} $p "" p
   11348 		regsub {^.*:} $p "" p
   11349 		if {$p == ""} {
   11350 			set proxyport 0
   11351 		} else {
   11352 			set proxyport $p
   11353 		}
   11354 	}
   11355 
   11356 	puts $fh "\[connection\]"
   11357 	puts $fh "host=$host"
   11358 	puts $fh "port=$port"
   11359 	puts $fh "proxyhost=$proxy"
   11360 	puts $fh "proxyport=$proxyport"
   11361 	puts $fh "disp=$vncdisp"
   11362 	puts $fh "\n\[options\]"
   11363 	puts $fh "# parameters commented out with '#' indicate the default setting."
   11364 
   11365 	if {$include_list != ""} {
   11366 		load_include $include_list [get_profiles_dir]
   11367 	}
   11368 	global sshssl_sw
   11369 	if {! $use_ssl && ! $use_ssh && ! $use_sshssl} {
   11370 		if {$sshssl_sw == "none"} {
   11371 			set disable_all_encryption 1
   11372 		}
   11373 	}
   11374 
   11375 	global ts_only ssh_only
   11376 	if {$ts_only} {
   11377 		set ts_mode 1
   11378 	} else {
   11379 		set ts_mode 0
   11380 	}
   11381 	foreach var [lsort [array names defs]] {
   11382 		eval set val \$$var
   11383 		set pre ""
   11384 		if {$val == $defs($var)} {
   11385 			set pre "#"
   11386 		}
   11387 		if {$ssh_only && $var == "use_ssh"} {
   11388 			set pre ""
   11389 		}
   11390 		set pct 0
   11391 		if {$var == "smb_mount_list"} {
   11392 			set pct 1
   11393 		}
   11394 		if {$var == "port_knocking_list"} {
   11395 			set pct 1
   11396 		}
   11397 		if {$include_list != "" && [info exists include_vars($var)]} {
   11398 			if {$val == $include_vars($var)} {
   11399 				if {$pct} {
   11400 					regsub -all "\n" $val "%%%" val
   11401 				}
   11402 				puts $fh "#from include: $var=$val"
   11403 				continue
   11404 			}
   11405 		}
   11406 		if {$pct} {
   11407 			regsub -all "\n" $val "%%%" val
   11408 		}
   11409 		puts $fh "$pre$var=$val"
   11410 	}
   11411 
   11412 	close $fh
   11413 
   11414 	mesg "Saved Profile: [file tail $file]"
   11415 
   11416 	set last_load [file tail $file]
   11417 
   11418 	set profdone 1
   11419 }
   11420 
   11421 proc set_ssh {} {
   11422 	global use_ssl
   11423 	if {$use_ssl} {
   11424 		ssl_ssh_adjust ssh
   11425 	}
   11426 }
   11427 
   11428 proc expand_IP {redir} {
   11429 	if {! [regexp {:IP:} $redir]} {
   11430 		return $redir
   11431 	}
   11432 	if {! [regexp {(-R).*:IP:} $redir]} {
   11433 		return $redir
   11434 	}
   11435 
   11436 	set ip [guess_ip]
   11437 	set ip [string trim $ip]
   11438 	if {$ip == ""} {
   11439 		return $redir
   11440 	}
   11441 
   11442 	regsub -all {:IP:} $redir ":$ip:" redir
   11443 	return $redir
   11444 }
   11445 
   11446 proc rand_port {} {
   11447 	global rand_port_list
   11448 
   11449 	set p ""
   11450 	for {set i 0} {$i < 30} {incr i} {
   11451 		set p [expr 25000 + 35000 * rand()]
   11452 		set p [expr round($p)]
   11453 		if {![info exists rand_port_list($p)]} {
   11454 			break
   11455 		}
   11456 	}
   11457 	if {$p == ""} {
   11458 		unset rand_port_list
   11459 		set p [expr 25000 + 35000 * rand()]
   11460 		set p [expr round($p)]
   11461 	}
   11462 	set rand_port_list($p) 1
   11463 	return $p
   11464 }
   11465 
   11466 proc get_cups_redir {} {
   11467 	global cups_local_server cups_remote_port
   11468 	global cups_local_smb_server cups_remote_smb_port
   11469 
   11470 	regsub -all {[ 	]} $cups_local_server "" cups_local_server
   11471 	regsub -all {[ 	]} $cups_remote_port "" cups_remote_port
   11472 	regsub -all {[ 	]} $cups_local_smb_server "" cups_local_smb_server
   11473 	regsub -all {[ 	]} $cups_remote_smb_port "" cups_remote_smb_port
   11474 
   11475 	set redir ""
   11476 
   11477 	if {$cups_local_server != "" && $cups_remote_port != ""} {
   11478 		set redir "$cups_remote_port:$cups_local_server"
   11479 		regsub -all {['" 	]} $redir {} redir; #"
   11480 		set redir " -R $redir"
   11481 	}
   11482 	if {$cups_local_smb_server != "" && $cups_remote_smb_port != ""} {
   11483 		set redir2 "$cups_remote_smb_port:$cups_local_smb_server"
   11484 		regsub -all {['" 	]} $redir2 {} redir2; #"
   11485 		set redir "$redir -R $redir2"
   11486 	}
   11487 	set redir [expand_IP $redir]
   11488 	return $redir
   11489 }
   11490 
   11491 proc get_additional_redir {} {
   11492 	global additional_port_redirs additional_port_redirs_list
   11493 	global ts_only choose_x11vnc_opts
   11494 	if {! $additional_port_redirs || $additional_port_redirs_list == ""} {
   11495 		return ""
   11496 	}
   11497 	if {$ts_only && !$choose_x11vnc_opts} {
   11498 		return ""
   11499 	}
   11500 	set redir [string trim $additional_port_redirs_list]
   11501 	regsub -all {['"]} $redir {} redir; #"
   11502 	set redir " $redir"
   11503 	set redir [expand_IP $redir]
   11504 	return $redir
   11505 }
   11506 
   11507 proc get_sound_redir {} {
   11508 	global sound_daemon_remote_port sound_daemon_local_port
   11509 	global sound_daemon_x11vnc
   11510 
   11511 	regsub -all {[ 	]} $sound_daemon_remote_port "" sound_daemon_remote_port
   11512 	regsub -all {[ 	]} $sound_daemon_local_port "" sound_daemon_local_port
   11513 
   11514 	set redir ""
   11515 	if {$sound_daemon_local_port == "" || $sound_daemon_remote_port == ""} {
   11516 		return $redir
   11517 	}
   11518 
   11519 	set loc $sound_daemon_local_port
   11520 	if {! [regexp {:} $loc]} {
   11521 		global uname
   11522 		if {$uname == "Darwin"} {
   11523 			set loc "127.0.0.1:$loc"
   11524 		} else {
   11525 			global is_windows
   11526 			if {$is_windows} {
   11527 				global win_localhost
   11528 				set loc "$win_localhost:$loc"
   11529 			} else {
   11530 				set loc "localhost:$loc"
   11531 			}
   11532 		}
   11533 	}
   11534 	set redir "$sound_daemon_remote_port:$loc"
   11535 	regsub -all {['" 	]} $redir {} redir; #"
   11536 	set redir " -R $redir"
   11537 	set redir [expand_IP $redir]
   11538 	return $redir
   11539 }
   11540 
   11541 proc get_smb_redir {} {
   11542 	global smb_mount_list
   11543 
   11544 	set s [string trim $smb_mount_list]
   11545 	if {$s == ""} {
   11546 		return ""
   11547 	}
   11548 
   11549 	set did(0) 1
   11550 	set redir ""
   11551 	set mntlist ""
   11552 
   11553 	foreach line [split $s "\r\n"] {
   11554 		set str [string trim $line]
   11555 		if {$str == ""} {
   11556 			continue
   11557 		}
   11558 		if {[regexp {^#} $str]} {
   11559 			continue
   11560 		}
   11561 
   11562 		set port ""
   11563 		if [regexp {^([0-9][0-9]*)[ \t][ \t]*(.*)} $str mvar port rest] {
   11564 			# leading port
   11565 			set str [string trim $rest]
   11566 		}
   11567 
   11568 		# grab:  //share /dest [host[:port]]
   11569 		set share ""
   11570 		set dest ""
   11571 		set hostport ""
   11572 		foreach item [split $str] {
   11573 			if {$item == ""} {
   11574 				continue
   11575 			}
   11576 			if {$share == ""} {
   11577 				set share [string trim $item]
   11578 			} elseif {$dest == ""} {
   11579 				set dest [string trim $item]
   11580 			} elseif {$hostport == ""} {
   11581 				set hostport [string trim $item]
   11582 			}
   11583 		}
   11584 
   11585 		regsub {^~/} $dest {$HOME/} dest
   11586 
   11587 		# work out the local host:port
   11588 		set lhost ""
   11589 		set lport ""
   11590 		if {$hostport != ""} {
   11591 			if [regexp {(.*):([0-9][0-9]*)} $hostport mvar lhost lport] {
   11592 				;
   11593 			} else {
   11594 				set lhost $hostport
   11595 				set lport 139
   11596 			}
   11597 		} else {
   11598 			if [regexp {//([^/][^/]*)/} $share mvar h] {
   11599 				if [regexp {(.*):([0-9][0-9]*)} $h mvar lhost lport] {
   11600 					;
   11601 				} else {
   11602 					set lhost $h
   11603 					set lport 139
   11604 				}
   11605 			} else {
   11606 				global is_windows win_localhost
   11607 				set lhost "localhost"
   11608 				if {$is_windows} {
   11609 					set lhost $win_localhost
   11610 				}
   11611 				set lport 139
   11612 			}
   11613 		}
   11614 
   11615 		if {$port == ""} {
   11616 			if [info exists did("$lhost:$lport")] {
   11617 				# reuse previous one:
   11618 				set port $did("$lhost:$lport")
   11619 			} else {
   11620 				# choose one at random:
   11621 				for {set i 0} {$i < 3} {incr i} {
   11622 					set port [expr 20100 + 9000 * rand()]
   11623 					set port [expr round($port)]
   11624 					if { ! [info exists did($port)] } {
   11625 						break
   11626 					}
   11627 				}
   11628 			}
   11629 			set did($port) 1
   11630 		}
   11631 
   11632 		if {$mntlist != ""} {
   11633 			append mntlist " "
   11634 		}
   11635 		append mntlist "$share,$dest,$port"
   11636 
   11637 		if { ! [info exists did("$lhost:$lport")] } {
   11638 			append redir " -R $port:$lhost:$lport"
   11639 			set did("$lhost:$lport") $port
   11640 		}
   11641 	}
   11642 
   11643 	regsub -all {['"]} $redir {} redir; #"
   11644 	set redir [expand_IP $redir]
   11645 
   11646 	regsub -all {['"]} $mntlist {} mntlist; #"
   11647 
   11648 	set l [list]
   11649 	lappend l $redir
   11650 	lappend l $mntlist
   11651 	return $l
   11652 }
   11653 
   11654 proc ugly_setup_scripts {mode tag} {
   11655 
   11656 set cmd(1) {
   11657 	SSHD_PID=""
   11658 	FLAG=$HOME/.vnc-helper-flag__PID__
   11659 
   11660 	if [ "X$USER" = "X" ]; then
   11661 		USER=$LOGNAME
   11662 	fi
   11663 
   11664 	DO_CUPS=0
   11665 	cups_dir=$HOME/.cups
   11666 	cups_cfg=$cups_dir/client.conf
   11667 	cups_host=localhost
   11668 	cups_port=NNNN
   11669 
   11670 	DO_SMB=0
   11671 	DO_SMB_SU=0
   11672 	DO_SMB_WAIT=0
   11673 	smb_mounts=
   11674 	DONE_PORT_CHECK=NNNN
   11675 	smb_script=$HOME/.smb-mounts__PID__.sh
   11676 
   11677 	DO_SOUND=0
   11678 	DO_SOUND_KILL=0
   11679 	DO_SOUND_RESTART=0
   11680 	sound_daemon_remote_prog=
   11681 	sound_daemon_remote_args=
   11682 
   11683 	findpid() {
   11684 		db=0
   11685 		back=30
   11686 		touch $FLAG
   11687 		tty=`tty | sed -e "s,/dev/,,"`
   11688 
   11689 		if [ "X$TOPPID" = "X" ]; then
   11690 			TOPPID=$$
   11691 			if [ $db = 1 ]; then echo "set TOPPID to $TOPPID"; fi
   11692 			back=70
   11693 		fi
   11694 		#back=5
   11695 		if [ $db = 1 ]; then echo "TOPPID=$TOPPID THISPID=$$ back=$back"; fi
   11696 
   11697 		i=1
   11698 		while [ $i -lt $back ]
   11699 		do
   11700 			try=`expr $TOPPID - $i`
   11701 			if [ $try -lt 1 ]; then
   11702 				try=`expr 32768 + $try`
   11703 			fi
   11704 			if [ $db = 1 ]; then echo try-1=$try; ps $try; fi
   11705 			if ps $try 2>/dev/null | grep "sshd.*$USER" | grep "$tty" >/dev/null; then
   11706 				if [ $db = 1 ]; then echo Found=$try; fi
   11707 				SSHD_PID="$try"
   11708 				echo
   11709 				ps $try
   11710 				echo
   11711 				break
   11712 			fi
   11713 			i=`expr $i + 1`
   11714 		done
   11715 
   11716 		if [ "X$SSHD_PID" = "X" ]; then
   11717 			back=`expr $back + 20`
   11718 			#back=5
   11719 
   11720 			for fallback in 2 3
   11721 			do
   11722 				i=1
   11723 				while [ $i -lt $back ]
   11724 				do
   11725 					try=`expr $TOPPID - $i`
   11726 					if [ $try -lt 1 ]; then
   11727 						try=`expr 32768 + $try`
   11728 					fi
   11729 					match="sshd.*$USER"
   11730 					if [ $fallback = 3 ]; then
   11731 						match="sshd"
   11732 					fi
   11733 					if [ $db = 1 ]; then echo "try-$fallback=$try match=$match"; ps $try; fi
   11734 					if ps $try 2>/dev/null | grep "$match" >/dev/null; then
   11735 						if [ $db = 1 ]; then echo Found=$try; fi
   11736 						SSHD_PID="$try"
   11737 						echo
   11738 						ps $try
   11739 						echo
   11740 						break
   11741 					fi
   11742 					i=`expr $i + 1`
   11743 				done
   11744 				if [ "X$SSHD_PID" != "X" ]; then
   11745 					break
   11746 				fi
   11747 			done
   11748 		fi
   11749 		#curlie}
   11750 };
   11751 
   11752 set cmd(2) {
   11753 		#curlie{
   11754 		if [ "X$SSHD_PID" = "X" ]; then
   11755 			if [ $db = 1 ]; then
   11756 				echo
   11757 				pstr=`ps -elf | grep "$USER" | grep "$tty" | grep -v grep | grep -v PID | grep -v "ps -elf"`
   11758 				echo "$pstr"
   11759 			fi
   11760 			plist=`ps -elf | grep "$USER" | grep "$tty" | grep -v grep | grep -v PID | grep -v "ps -elf" | awk "{print \\\$4}" | sort -n`
   11761 			if [ $db = 1 ]; then
   11762 				echo
   11763 				echo "$plist"
   11764 			fi
   11765 			for try in $plist
   11766 			do
   11767 				if [ $db = 1 ]; then echo try-final=$try; ps $try; fi
   11768 				if echo "$try" | grep "^[0-9][0-9]*\\\$" > /dev/null; then
   11769 					:
   11770 				else
   11771 					continue
   11772 				fi
   11773 				if ps $try | egrep vnc-helper > /dev/null; then
   11774 					:
   11775 				else
   11776 					if [ $db = 1 ]; then echo Found=$try; fi
   11777 					SSHD_PID=$try
   11778 					echo
   11779 					ps $try
   11780 					echo
   11781 					break
   11782 				fi
   11783 			done
   11784 		fi
   11785 		if [ "X$SSHD_PID" = "X" ]; then
   11786 			#ugh
   11787 			SSHD_PID=$$
   11788 		fi
   11789 
   11790 		echo "vnc-helper: [for cups/smb/esd]      SSHD_PID=$SSHD_PID MY_PID=$$ TTY=$tty"
   11791 		echo "vnc-helper: To force me to finish:  rm $FLAG"
   11792 	}
   11793 
   11794 	wait_til_ssh_gone() {
   11795 		try_perl=""
   11796 		if type perl >/dev/null 2>&1; then
   11797 			if [ -d /proc -a -e /proc/$$ ]; then
   11798 				try_perl="1"
   11799 			fi
   11800 		fi
   11801 		if [ "X$try_perl" = "X1" ]; then
   11802 			# try to avoid wasting pids:
   11803 			perl -e "while (1) {if(-d \"/proc\" && ! -e \"/proc/$SSHD_PID\"){exit} if(! -f \"$FLAG\"){exit} sleep 1;}"
   11804 		else
   11805 			while [ 1 ]
   11806 			do
   11807 				ps $SSHD_PID > /dev/null 2>&1
   11808 				if [ $? != 0 ]; then
   11809 					break
   11810 				fi
   11811 				if [ ! -f $FLAG ]; then
   11812 					break
   11813 				fi
   11814 				sleep 1
   11815 			done
   11816 		fi
   11817 		rm -f $FLAG
   11818 		if [ "X$DO_SMB_WAIT" = "X1" ]; then
   11819 			rm -f $smb_script
   11820 		fi
   11821 	}
   11822 };
   11823 
   11824 set cmd(3) {
   11825 	update_client_conf() {
   11826 		mkdir -p $cups_dir
   11827 
   11828 		if [ ! -f $cups_cfg.back ]; then
   11829 			touch $cups_cfg.back
   11830 		fi
   11831 		if [ ! -f $cups_cfg ]; then
   11832 			touch $cups_cfg
   11833 		fi
   11834 
   11835 		if grep ssvnc-auto $cups_cfg > /dev/null; then
   11836 			:
   11837 		else
   11838 			cp -p $cups_cfg $cups_cfg.back
   11839 		fi
   11840 
   11841 		echo "#-ssvnc-auto:" > $cups_cfg
   11842 		sed -e "s/^ServerName/#-ssvnc-auto-#ServerName/" $cups_cfg.back >> $cups_cfg
   11843 		echo "ServerName $cups_host:$cups_port" >> $cups_cfg
   11844 
   11845 		echo
   11846 		echo "-----------------------------------------------------------------"
   11847 		echo "On `hostname`:"
   11848 		echo
   11849 		echo "The CUPS $cups_cfg config file has been set to:"
   11850 		echo
   11851 		cat $cups_cfg | grep -v "^#-ssvnc-auto:" | sed -e "s/^/  /"
   11852 		echo
   11853 		echo "If there are problems automatically restoring it, edit or remove"
   11854 		echo "the file to go back to the local CUPS settings."
   11855 		echo
   11856 		echo "A backup has been placed in: $cups_cfg.back"
   11857 		echo
   11858 		echo "See the SSVNC CUPS dialog for more details on printing."
   11859 		if type lpstat >/dev/null 2>&1; then
   11860 			echo
   11861 			echo "lpstat -a output:"
   11862 			echo
   11863 			(lpstat -a 2>&1 | sed -e "s/^/  /") &
   11864 			sleep 0.5 >/dev/null 2>&1
   11865 		fi
   11866 		echo "-----------------------------------------------------------------"
   11867 		echo
   11868 	}
   11869 
   11870 	reset_client_conf() {
   11871 		cp $cups_cfg $cups_cfg.tmp
   11872 		grep -v "^ServerName" $cups_cfg.tmp | grep -v "^#-ssvnc-auto:" | sed -e "s/^#-ssvnc-auto-#ServerName/ServerName/" > $cups_cfg
   11873 		rm -f $cups_cfg.tmp
   11874 	}
   11875 
   11876 	cupswait() {
   11877 		trap "" INT QUIT HUP
   11878 		trap "reset_client_conf; rm -f $FLAG; exit" TERM
   11879 		wait_til_ssh_gone
   11880 		reset_client_conf
   11881 	}
   11882 };
   11883 
   11884 #		if [ "X$DONE_PORT_CHECK" != "X" ]; then
   11885 #			if type perl >/dev/null 2>&1; then
   11886 #				perl -e "use IO::Socket::INET; \$SIG{INT} = \"IGNORE\"; \$SIG{QUIT} = \"IGNORE\"; \$SIG{HUP} = \"INGORE\"; my \$client = IO::Socket::INET->new(Listen => 5, LocalAddr => \"localhost\", LocalPort => $DONE_PORT_CHECK, Proto => \"tcp\")->accept(); \$line = <\$client>; close \$client; unlink \"$smb_script\";" </dev/null >/dev/null 2>/dev/null &
   11887 #				if [ $? = 0 ]; then
   11888 #					have_perl_done="1"
   11889 #				fi
   11890 #			fi
   11891 #		fi
   11892 
   11893 set cmd(4) {
   11894 	smbwait() {
   11895 		trap "" INT QUIT HUP
   11896 		wait_til_ssh_gone
   11897 	}
   11898 	do_smb_mounts() {
   11899 		if [ "X$smb_mounts" = "X" ]; then
   11900 			return
   11901 		fi
   11902 		echo > $smb_script
   11903 		have_perl_done=""
   11904 		echo "echo" >> $smb_script
   11905 		dests=""
   11906 		for mnt in $smb_mounts
   11907 		do
   11908 			smfs=`echo "$mnt" | awk -F, "{print \\\$1}"`
   11909 			dest=`echo "$mnt" | awk -F, "{print \\\$2}"`
   11910 			port=`echo "$mnt" | awk -F, "{print \\\$3}"`
   11911 			dest=`echo "$dest" | sed -e "s,__USER__,$USER,g" -e "s,__HOME__,$HOME,g"`
   11912 			if [ ! -d $dest ]; then
   11913 				mkdir -p $dest
   11914 			fi
   11915 			echo "echo SMBMOUNT:" >> $smb_script
   11916 			echo "echo smbmount $smfs $dest -o uid=$USER,ip=127.0.0.1,port=$port" >> $smb_script
   11917 			echo "smbmount \"$smfs\" \"$dest\" -o uid=$USER,ip=127.0.0.1,port=$port" >> $smb_script
   11918 			echo "echo; df \"$dest\"; echo" >> $smb_script
   11919 			dests="$dests $dest"
   11920 		done
   11921 		#curlie}
   11922 };
   11923 
   11924 set cmd(5) {
   11925 		echo "(" >> $smb_script
   11926 		echo "un_mnt() {" >> $smb_script
   11927 		for dest in $dests
   11928 		do
   11929 			echo "  echo smbumount $dest" >> $smb_script
   11930 			echo "  smbumount \"$dest\"" >> $smb_script
   11931 		done
   11932 		echo "}" >> $smb_script
   11933 		echo "trap \"\" INT QUIT HUP" >> $smb_script
   11934 		echo "trap \"un_mnt; exit\" TERM" >> $smb_script
   11935 
   11936 		try_perl=""
   11937 		if type perl >/dev/null 2>&1; then
   11938 			try_perl=1
   11939 		fi
   11940 		uname=`uname`
   11941 		if [ "X$uname" != "XLinux" -a "X$uname" != "XSunOS" -a "X$uname" != "XDarwin" ]; then
   11942 			try_perl=""
   11943 		fi
   11944 
   11945 		if [ "X$try_perl" = "X" ]; then
   11946 			echo "while [ -f $smb_script ]" >> $smb_script
   11947 			echo "do" >> $smb_script
   11948 			echo "     sleep 1" >> $smb_script
   11949 			echo "done" >> $smb_script
   11950 		else
   11951 			echo "perl -e \"while (-f \\\"$smb_script\\\") {sleep 1;} exit 0;\"" >> $smb_script
   11952 		fi
   11953 		echo "un_mnt" >> $smb_script
   11954 		echo ") &" >> $smb_script
   11955 		echo "-----------------------------------------------------------------"
   11956 		echo "On `hostname`:"
   11957 		echo
   11958 		if [ "$DO_SMB_SU" = "0" ]; then
   11959 			echo "We now run the smbmount script as user $USER"
   11960 			echo
   11961 			echo sh $smb_script
   11962 			sh $smb_script
   11963 			rc=0
   11964 		elif [ "$DO_SMB_SU" = "1" ]; then
   11965 			echo "We now run the smbmount script via su(1)"
   11966 			echo
   11967 			echo "The first \"Password:\" will be for that of root to run the smbmount script."
   11968 			echo
   11969 			echo "Subsequent \"Password:\" will be for the SMB share(s) (hit Return if no passwd)"
   11970 			echo
   11971 			echo SU:
   11972 			echo "su root -c \"sh $smb_script\""
   11973 			su root -c "sh $smb_script"
   11974 			rc=$?
   11975 		elif [ "$DO_SMB_SU" = "2" ]; then
   11976 			echo "We now run the smbmount script via sudo(8)"
   11977 			echo
   11978 			echo "The first \"Password:\" will be for that of the sudo(8) password."
   11979 			echo
   11980 			echo "Subsequent \"Password:\" will be for the SMB shares (hit enter if no passwd)"
   11981 			echo
   11982 			echo SUDO:
   11983 			sd="sudo"
   11984 			echo "$sd sh $smb_script"
   11985 			$sd sh $smb_script
   11986 			rc=$?
   11987 		fi
   11988 };
   11989 
   11990 set cmd(6) {
   11991 		#curlie{
   11992 		echo
   11993 		if [ "$rc" = 0 ]; then
   11994 			if [ "X$have_perl_done" = "X1" -o 1 = 1 ] ; then
   11995 				echo
   11996 				echo "Your SMB shares will be unmounted when the VNC connection closes,"
   11997 				echo "*AS LONG AS* No Applications have any of the share files opened or are"
   11998 				echo "cd-ed into any of the share directories."
   11999 				echo
   12000 				echo "Try to make sure nothing is accessing the SMB shares before disconnecting"
   12001 				echo "the VNC session.  If you fail to do that follow these instructions:"
   12002 			fi
   12003 			echo
   12004 			echo "To unmount your SMB shares make sure no applications are still using any of"
   12005 			echo "the files and no shells are still cd-ed into the share area, then type:"
   12006 			echo
   12007 			echo "   rm -f $smb_script"
   12008 			echo
   12009 			echo "In the worst case run: smbumount /path/to/mount/point for each mount as root"
   12010 			echo
   12011 			echo "Even with the remote redirection gone the kernel should umount after a timeout."
   12012 		else
   12013 			echo
   12014 			if [ "$DO_SMB_SU" = "1" ]; then
   12015 				echo "su(1) to run smbmount(8) failed."
   12016 			elif [ "$DO_SMB_SU" = "2" ]; then
   12017 				echo "sudo(8) to run smbmount(8) failed."
   12018 			fi
   12019 			rm -f $smb_script
   12020 		fi
   12021 		echo "-----------------------------------------------------------------"
   12022 		echo
   12023 	}
   12024 };
   12025 
   12026 set cmd(7) {
   12027 
   12028 	setup_sound() {
   12029 		dpid=""
   12030 		d=$sound_daemon_remote_prog
   12031 		if type pgrep >/dev/null 2>/dev/null; then
   12032 			dpid=`pgrep -U $USER -x $d | head -1`
   12033 		else
   12034 			dpid=`env PATH=/usr/ucb:$PATH ps wwwwaux | grep -w $USER | grep -w $d | grep -v grep | head -1`
   12035 		fi
   12036 		echo "-----------------------------------------------------------------"
   12037 		echo "On `hostname`:"
   12038 		echo
   12039 		echo "Setting up Sound: pid=$dpid"
   12040 		if [ "X$dpid" != "X" ]; then
   12041 			dcmd=`env PATH=/usr/ucb:$PATH ps wwwwaux | grep -w $USER | grep -w $d | grep -w $dpid | grep -v grep | head -1 | sed -e "s/^.*$d/$d/"`
   12042 			if [ "X$DO_SOUND_KILL" = "X1" ]; then
   12043 				echo "Stopping sound daemon: $sound_daemon_remote_prog $dpid"
   12044 				echo "sound cmd: $dcmd"
   12045 				kill -TERM $dpid
   12046 			fi
   12047 		fi
   12048 		echo "-----------------------------------------------------------------"
   12049 		echo
   12050 	}
   12051 
   12052 	reset_sound() {
   12053 		if [ "X$DO_SOUND_RESTART" = "X1" ]; then
   12054 			d=$sound_daemon_remote_prog
   12055 			a=$sound_daemon_remote_args
   12056 			echo "Restaring sound daemon: $d $a"
   12057 			$d $a </dev/null >/dev/null 2>&1 &
   12058 		fi
   12059 	}
   12060 
   12061 	soundwait() {
   12062 		trap "" INT QUIT HUP
   12063 		trap "reset_sound; rm -f $FLAG; exit" TERM
   12064 		wait_til_ssh_gone
   12065 		reset_sound
   12066 	}
   12067 
   12068 
   12069 	findpid
   12070 
   12071 	if [ $DO_SMB = 1 ]; then
   12072 		do_smb_mounts
   12073 	fi
   12074 
   12075 	waiter=0
   12076 
   12077 	if [ $DO_CUPS = 1 ]; then
   12078 		update_client_conf
   12079 		cupswait </dev/null >/dev/null 2>/dev/null &
   12080 		waiter=1
   12081 	fi
   12082 
   12083 	if [ $DO_SOUND = 1 ]; then
   12084 		setup_sound
   12085 		soundwait </dev/null >/dev/null 2>/dev/null &
   12086 		waiter=1
   12087 	fi
   12088 	if [ $DO_SMB_WAIT = 1 ]; then
   12089 		if [ $waiter != 1 ]; then
   12090 			smbwait </dev/null >/dev/null 2>/dev/null &
   12091 			waiter=1
   12092 		fi
   12093 	fi
   12094 
   12095 
   12096 	#FINMSG
   12097 	echo "--main-vnc-helper-finished--"
   12098 	#cat $0
   12099 	rm -f $0
   12100 	exit 0
   12101 };
   12102 
   12103 	set cmdall ""
   12104 
   12105 	for {set i 1} {$i <= 7} {incr i} {
   12106 		set v $cmd($i);
   12107 		regsub -all "\n" $v "%" v
   12108 		regsub -all {.curlie.} $v "" v
   12109 		set cmd($i) $v
   12110 		append cmdall "echo "
   12111 		if {$i == 1} {
   12112 			append cmdall {TOPPID=$$ %}
   12113 		}
   12114 		append cmdall {'}
   12115 		append cmdall $cmd($i)
   12116 		append cmdall {' | tr '%' '\n'}
   12117 		if {$i == 1} {
   12118 			append cmdall {>}
   12119 		} else {
   12120 			append cmdall {>>}
   12121 		}
   12122 		append cmdall {$HOME/.vnc-helper-cmd__PID__; }
   12123 	}
   12124 	append cmdall {sh $HOME/.vnc-helper-cmd__PID__; }
   12125 
   12126 	regsub -all {vnc-helper-cmd} $cmdall "vnc-helper-cmd-$mode" cmdall
   12127 	if {$tag == ""} {
   12128 		set tag [pid]
   12129 	}
   12130 	regsub -all {__PID__} $cmdall "$tag" cmdall
   12131 
   12132 	set orig $cmdall
   12133 
   12134 	global use_cups cups_local_server cups_remote_port cups_manage_rcfile ts_only ts_cups_manage_rcfile cups_x11vnc
   12135 	regsub -all {[ 	]} $cups_local_server "" cups_local_server
   12136 	regsub -all {[ 	]} $cups_remote_port "" cups_remote_port
   12137 	if {$use_cups} {
   12138 		set dorc 0
   12139 		if {$ts_only} {
   12140 			if {$ts_cups_manage_rcfile} {
   12141 				set dorc 1
   12142 			}
   12143 		} else {
   12144 			if {$cups_manage_rcfile} {
   12145 				set dorc 1
   12146 			}
   12147 		}
   12148 		if {$dorc && $mode == "post"} {
   12149 			if {$cups_local_server != "" && $cups_remote_port != ""} {
   12150 				regsub {DO_CUPS=0} $cmdall {DO_CUPS=1} cmdall
   12151 				regsub {cups_port=NNNN} $cmdall "cups_port=$cups_remote_port" cmdall
   12152 			}
   12153 		}
   12154 	}
   12155 
   12156 	global use_smbmnt smb_su_mode smb_mounts
   12157 	if {$use_smbmnt} {
   12158 		if {$smb_mounts != ""} {
   12159 			set smbm $smb_mounts
   12160 			regsub -all {%USER} $smbm "__USER__" smbm
   12161 			regsub -all {%HOME} $smbm "__HOME__" smbm
   12162 			if {$mode == "pre"} {
   12163 				regsub {DO_SMB=0} $cmdall {DO_SMB=1} cmdall
   12164 				if {$smb_su_mode == "su"} {
   12165 					regsub {DO_SMB_SU=0} $cmdall {DO_SMB_SU=1} cmdall
   12166 				} elseif {$smb_su_mode == "sudo"} {
   12167 					regsub {DO_SMB_SU=0} $cmdall {DO_SMB_SU=2} cmdall
   12168 				} elseif {$smb_su_mode == "none"} {
   12169 					regsub {DO_SMB_SU=0} $cmdall {DO_SMB_SU=0} cmdall
   12170 				} else {
   12171 					regsub {DO_SMB_SU=0} $cmdall {DO_SMB_SU=1} cmdall
   12172 				}
   12173 				regsub {smb_mounts=} $cmdall "smb_mounts=\"$smbm\"" cmdall
   12174 			} elseif {$mode == "post"} {
   12175 				regsub {DO_SMB_WAIT=0} $cmdall {DO_SMB_WAIT=1} cmdall
   12176 			}
   12177 		}
   12178 	}
   12179 
   12180 	global use_sound
   12181 	if {$use_sound} {
   12182 		if {$mode == "pre"} {
   12183 			global sound_daemon_remote_cmd sound_daemon_kill sound_daemon_restart
   12184 			if {$sound_daemon_kill} {
   12185 				regsub {DO_SOUND_KILL=0} $cmdall {DO_SOUND_KILL=1} cmdall
   12186 				regsub {DO_SOUND=0} $cmdall {DO_SOUND=1} cmdall
   12187 			}
   12188 			if {$sound_daemon_restart} {
   12189 				regsub {DO_SOUND_RESTART=0} $cmdall {DO_SOUND_RESTART=1} cmdall
   12190 				regsub {DO_SOUND=0} $cmdall {DO_SOUND=1} cmdall
   12191 			}
   12192 			set sp [string trim $sound_daemon_remote_cmd]
   12193 			regsub {[ \t].*$} $sp "" sp
   12194 			set sa [string trim $sound_daemon_remote_cmd]
   12195 			regsub {^[^ \t][^ \t]*[ \t][ \t]*} $sa "" sa
   12196 			regsub {sound_daemon_remote_prog=} $cmdall "sound_daemon_remote_prog=\"$sp\"" cmdall
   12197 			regsub {sound_daemon_remote_args=} $cmdall "sound_daemon_remote_args=\"$sa\"" cmdall
   12198 		}
   12199 	}
   12200 
   12201 	if {$mode == "pre"} {
   12202 		set dopre 0
   12203 		if {$use_smbmnt && $smb_mounts != ""} {
   12204 			set dopre 1
   12205 		}
   12206 		if {$use_sound && $sound_daemon_kill} {
   12207 			set dopre 1
   12208 		}
   12209 		if {$dopre} {
   12210 			global is_windows
   12211 			if {$is_windows} {
   12212 				regsub {#FINMSG} $cmdall {echo "Now Go Click on the Label to Start the 2nd SSH"} cmdall
   12213 			} else {
   12214 				regsub {#FINMSG} $cmdall {echo "Finished with the 1st SSH tasks, the 2nd SSH should start shortly..."} cmdall
   12215 			}
   12216 		}
   12217 	}
   12218 
   12219 	set cmdstr $cmdall
   12220 
   12221 	if {"$orig" == "$cmdall"} {
   12222 		set cmdstr ""
   12223 	}
   12224 	global env
   12225 	if [info exists env(SSVNC_DEBUG_CUPS)] {
   12226 		regsub -all {db=0} $cmdstr "db=1" cmdstr
   12227 		set pout ""
   12228 		regsub -all {%} $cmdstr "\n" pout
   12229 		puts stderr "\nSERVICE REDIR COMMAND:\n\n$pout\n"
   12230 	}
   12231 	return $cmdstr
   12232 }
   12233 
   12234 proc ts_unixpw_dialog {} {
   12235 
   12236 	toplev .uxpw
   12237 	wm title .uxpw "Use unixpw"
   12238 
   12239 	scroll_text .uxpw.f 80 14
   12240 
   12241 	global ts_unixpw
   12242 
   12243 	set msg {
   12244     This enables the x11vnc unixpw mode.  A Login: and Password: dialog
   12245     will be presented in the VNC Viewer for the user to provide any Unix
   12246     username and password whose session he wants to connect to.  So this
   12247     may require typing in the password a 2nd time after the one for SSH.
   12248 
   12249     This mode is useful if a shared terminal services user (e.g. 'tsuser')
   12250     is used for the SSH login part (say via the SSH authorized_keys
   12251     mechanism and all users share the same private SSH key for 'tsuser').
   12252 
   12253     Note, However that the default usage of a per-user SSH login should
   12254     be the simplest and also sufficient for most situations, in which
   12255     case this "Use unixpw" option should NOT be selected.
   12256 }
   12257 	.uxpw.f.t insert end $msg
   12258 
   12259 	button .uxpw.cancel -text "Cancel" -command {destroy .uxpw; set ts_unixpw 0}
   12260 	bind .uxpw <Escape> {destroy .uxpw; set ts_unixpw 0}
   12261 	wm protocol .uxpw WM_DELETE_WINDOW {destroy .uxpw; set ts_unixpw 0}
   12262 
   12263 	button .uxpw.done -text "Done" -command {destroy .uxpw; set ts_unixpw 1}
   12264 
   12265 	pack .uxpw.done .uxpw.cancel -side bottom -fill x
   12266 	pack .uxpw.f -side top -fill both -expand 1
   12267 
   12268 	center_win .uxpw
   12269 }
   12270 
   12271 proc ts_vncshared_dialog {} {
   12272 
   12273 	toplev .vncs
   12274 	wm title .vncs "VNC Shared"
   12275 
   12276 	scroll_text .vncs.f 80 23
   12277 
   12278 	global ts_vncshared
   12279 
   12280 	set msg {
   12281     Normal use of this program, 'tsvnc', *ALREADY* allows simultaneous
   12282     shared access of the remote desktop:   You simply log in as many
   12283     times from as many different locations with 'tsvnc' as you like.
   12284 
   12285     However, doing it that way starts up a new x11vnc for each connection.
   12286     In some circumstances you may want a single x11vnc running but allow
   12287     multiple VNC viewers to access it simultaneously.
   12288 
   12289     This option (VNC Shared) enables that rarer usage case by passing
   12290     '-shared' to the remote x11vnc command.
   12291 
   12292     With this option enabled, the new shared connections must
   12293     still connect to the Terminal Server via SSH for encryption and
   12294     authentication.  They must also do the normal SSH port redirection
   12295     to access the x11vnc port (usually 5900, but look for the PORT=
   12296     output for the actual value).
   12297 
   12298     They could use SSVNC for that, or do it manually in terminal
   12299     windows, more information:
   12300 
   12301        http://www.karlrunge.com/x11vnc/#tunnelling
   12302 }
   12303 	.vncs.f.t insert end $msg
   12304 
   12305 	button .vncs.cancel -text "Cancel" -command {destroy .vncs; set ts_vncshared 0}
   12306 	bind .vncs <Escape> {destroy .vncs; set ts_vncshared 0}
   12307 	wm protocol .vncs WM_DELETE_WINDOW {destroy .vncs; set ts_vncshared 0}
   12308 	button .vncs.done -text "Done" -command {destroy .vncs; set ts_vncshared 1}
   12309 
   12310 	pack .vncs.done .vncs.cancel -side bottom -fill x
   12311 	pack .vncs.f -side top -fill both -expand 1
   12312 
   12313 	center_win .vncs
   12314 }
   12315 
   12316 proc ts_multi_dialog {} {
   12317 
   12318 	toplev .mult
   12319 	wm title .mult "Multiple Sessions"
   12320 
   12321 	scroll_text .mult.f 80 21
   12322 
   12323 	global ts_multisession choose_multisession
   12324 
   12325 	set msg {
   12326     Normally in Terminal Services mode (tsvnc) your user account (the
   12327     one you SSH in as) can only have a single Terminal Services X session
   12328     running at a time on one server machine.
   12329 
   12330     This is simply because x11vnc chooses the first Desktop (X session)
   12331     of yours that it can find.  It will never create a 2nd X session
   12332     because it keeps finding the 1st one.
   12333 
   12334     To have Multiple Sessions for one username on a single machine,
   12335     choose a unique Session "Tag", that will be associated with the X
   12336     session and x11vnc will only choose the one that has this Tag.
   12337 
   12338     For this to work ALL of your sessions on the server machine must
   12339     have a different tag (that is, if you have an existing session with
   12340     no tag, x11vnc might find a tagged one first instead of it).
   12341 
   12342     The tag must be made of only letters, numbers, dash, or underscore.
   12343 
   12344     Examples:  KDE_SMALL,  gnome-2,  test1
   12345 }
   12346 	.mult.f.t insert end $msg
   12347 
   12348 	frame .mult.c
   12349 	label .mult.c.l -anchor w -text "Tag:"
   12350 	entry .mult.c.e -width 20 -textvariable ts_multisession
   12351 	pack .mult.c.l -side left
   12352 	pack .mult.c.e -side left -expand 1 -fill x
   12353 
   12354 	button .mult.cancel -text "Cancel" -command {destroy .mult; set choose_multisession 0}
   12355 	bind .mult <Escape> {destroy .mult; set choose_multisession 0}
   12356 	wm protocol .mult WM_DELETE_WINDOW {destroy .mult; set choose_multisession 0}
   12357 
   12358 	bind .mult.c.e <Return> {destroy .mult; set choose_multisession 1}
   12359 	button .mult.done -text "Done" -command {destroy .mult; set choose_multisession 1}
   12360 
   12361 	pack .mult.done .mult.cancel .mult.c -side bottom -fill x
   12362 	pack .mult.f -side top -fill both -expand 1
   12363 
   12364 	center_win .mult
   12365 	focus .mult.c.e
   12366 }
   12367 
   12368 proc ts_xlogin_dialog {} {
   12369 
   12370 	toplev .xlog
   12371 	wm title .xlog "X Login Greeter"
   12372 
   12373 	set h 33
   12374 	if [small_height] {
   12375 		set h 28
   12376 	}
   12377 	scroll_text .xlog.f 80 $h
   12378 
   12379 	global ts_xlogin
   12380 
   12381 	set msg {
   12382     If you have root (sudo(1)) permission on the remote machine, you
   12383     can have x11vnc try to connect to a X display(s) that has No One
   12384     Logged In Yet.  This is most likely the login greeter running on
   12385     the Physical console.  sudo(1) is used to run x11vnc with FD_XDM=1.
   12386 
   12387     This is different from tsvnc's regular Terminal Services mode where
   12388     usually a virtual (RAM only, e.g. Xvfb) X server used.  With this option
   12389     it is the physical graphics hardware that will be connected to.
   12390 
   12391     Note that if your user is ALREADY logged into the physical display,
   12392     you don't need to use this X Login option because x11vnc should find
   12393     it in its normal find-display procedure and not need sudo(1).
   12394 
   12395     An initial ssh running 'sudo id' is performed to try to 'prime'
   12396     sudo so the 2nd one that runs x11vnc does not need a password.
   12397     This may not always succeed...
   12398 
   12399     Note that if someone is already logged into the display console
   12400     via XDM (GDM, KDM etc.) you will see and control their X session.
   12401 
   12402     Otherwise, you will get the Greeter X login screen where you can
   12403     log in via username and password.  Your SSVNC 'Terminal Services'
   12404     Desktop Type, Size, Printing etc. settings will be ignored in this
   12405     case of course because XDM, GDM, or KDM is creating your X session,
   12406     not x11vnc.
   12407 
   12408     Note that the GDM display manager has a setting KillInitClients in
   12409     gdm.conf that will kill x11vnc right after you log in, and so you would
   12410     have to repeat the whole process ('Connect' button) to attach to your
   12411     session. See http://www.karlrunge.com/x11vnc/faq.html#faq-display-manager
   12412     for more info.
   12413 }
   12414 	.xlog.f.t insert end $msg
   12415 
   12416 	button .xlog.cancel -text "Cancel" -command {destroy .xlog; set ts_xlogin 0}
   12417 	bind .xlog <Escape> {destroy .xlog; set ts_xlogin 0}
   12418 	wm protocol .xlog WM_DELETE_WINDOW {destroy .xlog; set ts_xlogin 0}
   12419 
   12420 	button .xlog.done -text "Done" -command {destroy .xlog; set ts_xlogin 1}
   12421 
   12422 	pack .xlog.done .xlog.cancel -side bottom -fill x
   12423 	pack .xlog.f -side top -fill both -expand 1
   12424 
   12425 	center_win .xlog
   12426 }
   12427 
   12428 
   12429 proc ts_othervnc_dialog {} {
   12430 
   12431 	toplev .ovnc
   12432 	wm title .ovnc "Other VNC Server"
   12433 
   12434 	scroll_text .ovnc.f 80 21
   12435 
   12436 	global ts_othervnc choose_othervnc
   12437 
   12438 	set msg {
   12439     The x11vnc program running on the remote machine can be instructed to
   12440     immediately redirect to some other (3rd party, e.g. Xvnc or vnc.so)
   12441     VNC server.
   12442 
   12443     It should be a little faster to have x11vnc forward the VNC protocol
   12444     rather than having it poll the corresponding X server for changes
   12445     in the way it normally does and translate to VNC.
   12446 
   12447     This mode also enables a simple way to add SSL or find X display
   12448     support to a 3rd party VNC Server lacking these features.
   12449 
   12450     In the entry box put the other vnc display, e.g. "localhost:0" or
   12451     "somehost:5".
   12452 
   12453     The string "find" in the entry will have x11vnc try to find an X
   12454     display in its normal way, and then redirect to the corresponding VNC
   12455     server port.  This assumes if the X display is, say, :2 (i.e. port
   12456     6002) then the VNC display is also :2 (i.e. port 5902).  This mode is
   12457     the same as an "X Server Type" of "Xvnc.redirect" (and overrides it).
   12458 }
   12459 	.ovnc.f.t insert end $msg
   12460 
   12461 	frame .ovnc.c
   12462 	label .ovnc.c.l -anchor w -text "Other VNC Server:"
   12463 	entry .ovnc.c.e -width 20 -textvariable ts_othervnc
   12464 	pack .ovnc.c.l -side left
   12465 	pack .ovnc.c.e -side left -expand 1 -fill x
   12466 
   12467 	button .ovnc.cancel -text "Cancel" -command {destroy .ovnc; set choose_othervnc 0}
   12468 	bind .ovnc <Escape> {destroy .ovnc; set choose_othervnc 0}
   12469 	wm protocol .ovnc WM_DELETE_WINDOW {destroy .ovnc; set choose_othervnc 0}
   12470 	button .ovnc.done -text "Done" -command {destroy .ovnc; set choose_othervnc 1}
   12471 	bind .ovnc.c.e <Return> {destroy .ovnc; set choose_othervnc 1}
   12472 
   12473 	if {$ts_othervnc == ""} {
   12474 		set ts_othervnc "find"
   12475 	}
   12476 
   12477 	pack .ovnc.done .ovnc.cancel .ovnc.c -side bottom -fill x
   12478 	pack .ovnc.f -side top -fill both -expand 1
   12479 
   12480 	center_win .ovnc
   12481 	focus .ovnc.c.e
   12482 }
   12483 
   12484 proc ts_sleep_dialog {} {
   12485 
   12486 	toplev .eslp
   12487 	wm title .eslp "Extra Sleep"
   12488 
   12489 	scroll_text .eslp.f 80 5
   12490 
   12491 	global extra_sleep
   12492 
   12493 	set msg {
   12494     Sleep: Enter a number to indicate how many extra seconds to sleep
   12495     while waiting for the VNC viewer to start up.  On Windows this
   12496     can give extra time to enter the Putty/Plink password, etc.
   12497 }
   12498 	.eslp.f.t insert end $msg
   12499 
   12500 	frame .eslp.c
   12501 	label .eslp.c.l -anchor w -text "Extra Sleep:"
   12502 	entry .eslp.c.e -width 20 -textvariable extra_sleep
   12503 	pack .eslp.c.l -side left
   12504 	pack .eslp.c.e -side left -expand 1 -fill x
   12505 
   12506 	button .eslp.cancel -text "Cancel" -command {destroy .eslp; set choose_sleep 0}
   12507 	bind .eslp <Escape> {destroy .eslp; set choose_sleep 0}
   12508 	wm protocol .eslp WM_DELETE_WINDOW {destroy .eslp; set choose_sleep 0}
   12509 	button .eslp.done -text "Done" -command {destroy .eslp; set choose_sleep 1}
   12510 	bind .eslp.c.e <Return> {destroy .eslp; set choose_sleep 1}
   12511 
   12512 	global choose_sleep
   12513 	if {! $choose_sleep} {
   12514 		set extra_sleep ""
   12515 	}
   12516 
   12517 	pack .eslp.done .eslp.cancel .eslp.c -side bottom -fill x
   12518 	pack .eslp.f -side top -fill both -expand 1
   12519 
   12520 	center_win .eslp
   12521 	focus .eslp.c.e
   12522 }
   12523 
   12524 proc ts_putty_args_dialog {} {
   12525 
   12526 	toplev .parg
   12527 	wm title .parg "Putty Args"
   12528 
   12529 	scroll_text .parg.f 80 5
   12530 
   12531 	global putty_args
   12532 
   12533 	set msg {
   12534     Putty Args: Enter a string to be added to every plink.exe and putty.exe
   12535     command line.  For example: -i C:\mykey.ppk
   12536 }
   12537 	.parg.f.t insert end $msg
   12538 
   12539 	frame .parg.c
   12540 	label .parg.c.l -anchor w -text "Putty Args:"
   12541 	entry .parg.c.e -width 20 -textvariable putty_args
   12542 	pack .parg.c.l -side left
   12543 	pack .parg.c.e -side left -expand 1 -fill x
   12544 
   12545 	button .parg.cancel -text "Cancel" -command {destroy .parg; set choose_parg 0}
   12546 	bind .parg <Escape> {destroy .parg; set choose_parg 0}
   12547 	wm protocol .parg WM_DELETE_WINDOW {destroy .parg; set choose_parg 0}
   12548 	button .parg.done -text "Done" -command {destroy .parg; set choose_parg 1}
   12549 	bind .parg.c.e <Return> {destroy .parg; set choose_parg 1}
   12550 
   12551 	global choose_parg
   12552 	if {! $choose_parg} {
   12553 		set putty_args ""
   12554 	}
   12555 
   12556 	pack .parg.done .parg.cancel .parg.c -side bottom -fill x
   12557 	pack .parg.f -side top -fill both -expand 1
   12558 
   12559 	center_win .parg
   12560 	focus .parg.c.e
   12561 }
   12562 
   12563 proc ts_ncache_dialog {} {
   12564 
   12565 	toplev .nche
   12566 	wm title .nche "Client-Side Caching"
   12567 
   12568 	scroll_text .nche.f 80 22
   12569 
   12570 	global ts_ncache choose_ncache
   12571 
   12572 	set msg {
   12573     This enables the *experimental* x11vnc client-side caching mode.
   12574     It often gives nice speedups, but can sometimes lead to painting
   12575     errors or window "flashing". (you can repaint the screen by tapping
   12576     the Left Alt key 3 times in a row)
   12577 
   12578     It is a very simple but hoggy method: uncompressed image pixmaps are
   12579     stored in the viewer in a large (20-100MB) display region beneath
   12580     the actual display screen.  You may need also to adjust your VNC Viewer
   12581     to not show this region (the SSVNC Unix viewer does it automatically).
   12582 
   12583     The scheme uses a lot of RAM, but at least it has the advantage that
   12584     it works with every VNC Viewer.  Otherwise the VNC protocol would
   12585     need to be modified, changing both the server and the viewer.
   12586 
   12587     Set the x11vnc "-ncache" parameter to an even integer between 2
   12588     and 20.  This is the increase in area factor over the normal screen
   12589     for the caching region.  So 10 means use 10 times the RAM to store
   12590     pixmaps.  The default is 8.
   12591 
   12592     More info: http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching
   12593 }
   12594 	.nche.f.t insert end $msg
   12595 
   12596 	frame .nche.c
   12597 	label .nche.c.l -anchor w -text "ncache:"
   12598 	radiobutton .nche.c.r2  -text "2"  -variable ts_ncache -value "2"
   12599 	radiobutton .nche.c.r4  -text "4"  -variable ts_ncache -value "4"
   12600 	radiobutton .nche.c.r6  -text "6"  -variable ts_ncache -value "6"
   12601 	radiobutton .nche.c.r8  -text "8"  -variable ts_ncache -value "8"
   12602 	radiobutton .nche.c.r10 -text "10" -variable ts_ncache -value "10"
   12603 	radiobutton .nche.c.r12 -text "12" -variable ts_ncache -value "12"
   12604 	radiobutton .nche.c.r14 -text "14" -variable ts_ncache -value "14"
   12605 	radiobutton .nche.c.r16 -text "16" -variable ts_ncache -value "16"
   12606 	radiobutton .nche.c.r18 -text "18" -variable ts_ncache -value "18"
   12607 	radiobutton .nche.c.r20 -text "20" -variable ts_ncache -value "20"
   12608 	pack .nche.c.l -side left
   12609 	pack .nche.c.r2 .nche.c.r4 .nche.c.r6 .nche.c.r8 .nche.c.r10 \
   12610 		.nche.c.r12 .nche.c.r14 .nche.c.r16 .nche.c.r18  .nche.c.r20 -side left
   12611 	button .nche.cancel -text "Cancel" -command {destroy .nche; set choose_ncache 0}
   12612 	bind .nche <Escape> {destroy .nche; set choose_ncache 0}
   12613 	wm protocol .nche WM_DELETE_WINDOW {destroy .nche; set choose_ncache 0}
   12614 	button .nche.done -text "Done" -command {destroy .nche; set choose_ncache 1}
   12615 
   12616 	pack .nche.done .nche.cancel .nche.c -side bottom -fill x
   12617 	pack .nche.f -side top -fill both -expand 1
   12618 
   12619 	center_win .nche
   12620 }
   12621 
   12622 proc ts_x11vnc_opts_dialog {} {
   12623 
   12624 	toplev .x11v
   12625 	wm title .x11v "x11vnc Options"
   12626 
   12627 	set h 23
   12628 	if [small_height] {
   12629 		set h 21
   12630 	}
   12631 	scroll_text .x11v.f 80 $h
   12632 
   12633 	global ts_x11vnc_opts ts_x11vnc_path ts_x11vnc_autoport choose_x11vnc_opts
   12634 	global additional_port_redirs_list
   12635 
   12636 	set msg {
   12637     If you are an expert with x11vnc's endless options and tweaking
   12638     parameters feel free to specify any you want here in "Options".
   12639 
   12640     Also, if you need to specify the path to the x11vnc program on the
   12641     remote side because it will not be in $PATH, put it in the "Full
   12642     Path" entry.
   12643 
   12644     Port Redirs are additional SSH "-L port:host:port" or "-R port:host:port"
   12645     (forward or reverse, resp.) port redirections you want.  In SSVNC mode,
   12646     see the detailed description under: Options -> Advanced -> Port Redirs.
   12647 
   12648     Some potentially useful options:
   12649 
   12650 	-solid		-scale		-scale_cursor
   12651 	-passwd		-rfbauth	-http
   12652 	-xrandr		-rotate		-noxdamage
   12653 	-xkb		-skip_lockkeys	-nomodtweak
   12654 	-repeat		-cursor		-wmdt
   12655 	-nowireframe	-ncache_cr	-speeds
   12656 
   12657     More info: http://www.karlrunge.com/x11vnc/faq.html#faq-cmdline-opts
   12658 }
   12659 #    In Auto Port put a starting port for x11vnc to try autoprobing
   12660 #    instead of the default 5900.  It starts at the value you supply and
   12661 #    works upward until a free one is found. (x11vnc 0.9.3 or later).
   12662 
   12663 	.x11v.f.t insert end $msg
   12664 
   12665 	frame .x11v.c
   12666 	label .x11v.c.l -width 10 -anchor w -text "Options:"
   12667 	entry .x11v.c.e -textvariable ts_x11vnc_opts
   12668 	pack .x11v.c.l -side left
   12669 	pack .x11v.c.e -side left -expand 1 -fill x
   12670 
   12671 	frame .x11v.c2
   12672 	label .x11v.c2.l -width 10 -anchor w -text "Full Path:"
   12673 	entry .x11v.c2.e -textvariable ts_x11vnc_path
   12674 	pack .x11v.c2.l -side left
   12675 	pack .x11v.c2.e -side left -expand 1 -fill x
   12676 
   12677 #	frame .x11v.c3
   12678 #	label .x11v.c3.l -width 10 -anchor w -text "Auto Port:"
   12679 #	entry .x11v.c3.e -textvariable ts_x11vnc_autoport
   12680 #	pack .x11v.c3.l -side left
   12681 #	pack .x11v.c3.e -side left -expand 1 -fill x
   12682 
   12683 	frame .x11v.c4
   12684 	label .x11v.c4.l -width 10 -anchor w -text "Port Redirs:"
   12685 	entry .x11v.c4.e -textvariable additional_port_redirs_list
   12686 	pack .x11v.c4.l -side left
   12687 	pack .x11v.c4.e -side left -expand 1 -fill x
   12688 
   12689 	button .x11v.cancel -text "Cancel" -command {destroy .x11v; set choose_x11vnc_opts 0}
   12690 	bind .x11v <Escape> {destroy .x11v; set choose_x11vnc_opts 0}
   12691 	wm protocol .x11v WM_DELETE_WINDOW {destroy .x11v; set choose_x11vnc_opts 0}
   12692 	button .x11v.done -text "Done" -command {destroy .x11v; set choose_x11vnc_opts 1;
   12693 			if {$additional_port_redirs_list != ""} {set additional_port_redirs 1} else {set additional_port_redirs 0}}
   12694 
   12695 #	pack .x11v.done .x11v.cancel .x11v.c4 .x11v.c3 .x11v.c2 .x11v.c -side bottom -fill x
   12696 	pack .x11v.done .x11v.cancel .x11v.c4 .x11v.c2 .x11v.c -side bottom -fill x
   12697 	pack .x11v.f -side top -fill both -expand 1
   12698 
   12699 	center_win .x11v
   12700 	focus .x11v.c.e
   12701 }
   12702 
   12703 
   12704 proc ts_filexfer_dialog {} {
   12705 
   12706 	toplev .xfer
   12707 	wm title .xfer "File Transfer"
   12708 	global choose_filexfer ts_filexfer
   12709 
   12710 	scroll_text .xfer.f 70 13
   12711 
   12712 	set msg {
   12713     x11vnc supports both the UltraVNC and TightVNC file transfer
   12714     extensions.  On Windows both viewers support their file transfer
   12715     protocol.  On Unix only the SSVNC VNC Viewer can do filexfer; it
   12716     supports the UltraVNC flavor via a Java helper program (and so
   12717     java(1) is required on the viewer-side).
   12718 
   12719     Choose the one you want based on VNC viewer you will use.
   12720     The defaults for the SSVNC viewer package are TightVNC on
   12721     Windows and UltraVNC on Unix.
   12722 
   12723     For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-filexfer
   12724 }
   12725 	.xfer.f.t insert end $msg
   12726 
   12727 	global is_windows
   12728 	if {$ts_filexfer == ""} {
   12729 		if {$is_windows} {
   12730 			set ts_filexfer "tight"
   12731 		} else {
   12732 			set ts_filexfer "ultra"
   12733 		}
   12734 	}
   12735 
   12736 	frame .xfer.c
   12737 	radiobutton .xfer.c.tight  -text "TightVNC"  -variable ts_filexfer -value "tight" -relief ridge
   12738 	radiobutton .xfer.c.ultra  -text "UltraVNC"  -variable ts_filexfer -value "ultra" -relief ridge
   12739 
   12740 	pack .xfer.c.ultra .xfer.c.tight -side left -fill x -expand 1
   12741 
   12742 	button .xfer.cancel -text "Cancel" -command {destroy .xfer; set choose_filexfer 0}
   12743 	bind .xfer <Escape> {destroy .xfer; set choose_filexfer 0}
   12744 	wm protocol .xfer WM_DELETE_WINDOW {destroy .xfer; set choose_filexfer 0}
   12745 	button .xfer.done -text "Done" -command {destroy .xfer; set choose_filexfer 1}
   12746 
   12747 	pack .xfer.done .xfer.cancel -side bottom -fill x
   12748 	pack .xfer.c -side bottom -fill x -expand 1
   12749 	pack .xfer.f -side top -fill both -expand 1
   12750 
   12751 	center_win .xfer
   12752 }
   12753 
   12754 proc ts_cups_dialog {} {
   12755 
   12756 	toplev .cups
   12757 	wm title .cups "CUPS and SMB Printing"
   12758 	global cups_local_server cups_remote_port cups_manage_rcfile ts_cups_manage_rcfile cups_x11vnc
   12759 	global cups_local_smb_server cups_remote_smb_port
   12760 
   12761 	set h 30
   12762 	if [small_height] {
   12763 		set h 24
   12764 	}
   12765 	scroll_text .cups.f 80 $h
   12766 
   12767 
   12768 	set msg {
   12769     This method requires a working CUPS Desktop setup on the remote side
   12770     of the connection and working CUPS (or possibly Windows SMB or IPP)
   12771     printing on the local viewer-side of the connection.
   12772 
   12773     For CUPS printing redirection to work properly, you MUST enable it for
   12774     the connection that *creates* your terminal services X session (i.e. the
   12775     first connection.)  You cannot retroactively enable CUPS redirection
   12776     on an already existing terminal services X session.  (See CUPS printing
   12777     for normal SSVNC mode for how you might do that.)
   12778 
   12779     Enter the VNC Viewer side (i.e. where you are sitting) CUPS server
   12780     under "Local CUPS Server".  Use "localhost:631" if there is one
   12781     on your viewer machine (normally the case if you set up a printer
   12782     on your unix or macosx system), or, e.g., "my-print-srv:631" for a
   12783     nearby CUPS print server.  Note that 631 is the default CUPS port.
   12784 
   12785     (On MacOSX it seems better to use "127.0.0.1" instead of "localhost".)
   12786 
   12787     The SSVNC Terminal Services created remote Desktop session will have
   12788     the variables CUPS_SERVER and IPP_PORT set so all printing applications
   12789     will be redirected to your local CUPS server.  So your locally available
   12790     printers should appear in the remote print dialogs.
   12791 
   12792 
   12793     Windows/SMB Printers:  Under "Local SMB Print Server" you can set a
   12794     port redirection for a Windows (non-CUPS) SMB printer.  If localhost:139
   12795     does not work, try the literal string "IP:139", or use the known value
   12796     of the IP address manually.  139 is the default SMB port; nowadays 445
   12797     might be a better possibility.
   12798 
   12799     For Windows/SMB Printers if there is no local CUPS print server, it is
   12800     usually a very good idea to make the CUPS Server setting EMPTY (to avoid
   12801     desktop apps trying incessantly to reach the nonexistent CUPS server.)
   12802 
   12803     On the remote side, in the Desktop session the variables $SMB_SERVER,
   12804     $SMB_HOST, and $SMB_PORT will be set for you to use.
   12805 
   12806     Unfortunately, printing to Windows may only ve partially functional due
   12807     to the general lack PostScript support on Windows.
   12808 
   12809     If you have print admin permission on the remote machine you can
   12810     configure CUPS to know about your Windows printer via lpadmin(8) or
   12811     a GUI tool.  You give it the URI:
   12812 
   12813         smb://localhost:port/printername
   12814 
   12815     or possibly:
   12816 
   12817         smb://localhost:port/computer/printername
   12818 
   12819     "port" will be found in the $SMB_PORT.  You also need to identify
   12820     the printer type.  NOTE: You will leave "Local CUPS Server" blank in
   12821     this case.  The smbspool(1) command should also work as well, at least
   12822     for PostScript printers.
   12823 
   12824     A similar thing can be done with CUPS printers if you are having problems
   12825     with the above default mechanism.  Use
   12826 
   12827         http://localhost:port/printers/printername
   12828 
   12829     For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-cups
   12830 }
   12831 
   12832 #    The "Manage 'ServerName' in .cups/client.conf for me" setting is usually
   12833 #    NOT needed unless you are using Terminal Services to connect to an
   12834 #    existing Session that did NOT have CUPS print redirection set at session
   12835 #    start time (i.e. IPP_PORT and CUPS_SERVER were not set up).  In that
   12836 #    case, select this option as a workaround: NOTE that the client.conf
   12837 #    setting will REDIRECT ALL PRINTING for apps with the same $HOME/.cups
   12838 #    directory (which you probably do not want), however it will be reset
   12839 #    when the SSVNC viewer disconnects.
   12840 
   12841 	.cups.f.t insert end $msg
   12842 
   12843 	global uname
   12844 	if {$cups_local_server == ""} {
   12845 		if {$uname == "Darwin"} {
   12846 			set cups_local_server "127.0.0.1:631"
   12847 		} else {
   12848 			set cups_local_server "localhost:631"
   12849 		}
   12850 	}
   12851 	if {$cups_remote_port == ""} {
   12852 		set cups_remote_port [expr "6731 + int(1000 * rand())"]
   12853 	}
   12854 	if {$cups_local_smb_server == ""} {
   12855 		global is_windows
   12856 		if {$is_windows} {
   12857 			set cups_local_smb_server "IP:139"
   12858 		} elseif {$uname == "Darwin"} {
   12859 			set cups_local_smb_server "127.0.0.1:139"
   12860 		} else {
   12861 			set cups_local_smb_server "localhost:139"
   12862 		}
   12863 	}
   12864 	if {$cups_remote_smb_port == ""} {
   12865 		set cups_remote_smb_port [expr "7731 + int(1000 * rand())"]
   12866 	}
   12867 
   12868 	frame .cups.serv
   12869 	label .cups.serv.l -anchor w -text "Local CUPS Server:      "
   12870 	entry .cups.serv.e -width 40 -textvariable cups_local_server
   12871 	pack .cups.serv.e -side right
   12872 	pack .cups.serv.l -side left -expand 1 -fill x
   12873 
   12874 	frame .cups.smbs
   12875 	label .cups.smbs.l -anchor w -text "Local SMB Print Server:      "
   12876 	entry .cups.smbs.e -width 40 -textvariable cups_local_smb_server
   12877 	pack .cups.smbs.e -side right
   12878 	pack .cups.smbs.l -side left -expand 1 -fill x
   12879 
   12880 	# not working with x11vnc:
   12881 	checkbutton .cups.cupsrc -anchor w -variable ts_cups_manage_rcfile -text \
   12882 		"Manage 'ServerName' in the remote \$HOME/.cups/client.conf file for me"
   12883 
   12884 	button .cups.cancel -text "Cancel" -command {destroy .cups; set use_cups 0}
   12885 	bind .cups <Escape> {destroy .cups; set use_cups 0}
   12886 	wm protocol .cups WM_DELETE_WINDOW {destroy .cups; set use_cups 0}
   12887 	button .cups.done -text "Done" -command {destroy .cups; if {$use_cups} {set_ssh}}
   12888 
   12889 	pack .cups.done .cups.cancel .cups.smbs .cups.serv -side bottom -fill x
   12890 	pack .cups.f -side top -fill both -expand 1
   12891 
   12892 	center_win .cups
   12893 	focus .cups.serv.e
   12894 }
   12895 
   12896 
   12897 proc cups_dialog {} {
   12898 
   12899 	toplev .cups
   12900 	wm title .cups "CUPS Tunnelling"
   12901 	global cups_local_server cups_remote_port cups_manage_rcfile cups_x11vnc
   12902 	global cups_local_smb_server cups_remote_smb_port
   12903 	global ts_only
   12904 	if {$ts_only} {
   12905 		ts_cups_dialog
   12906 		return
   12907 	}
   12908 
   12909 	global uname
   12910 	set h 33
   12911 	if [small_height] {
   12912 		set h 17
   12913 	} elseif {$uname == "Darwin"} {
   12914 		set h 24
   12915 	}
   12916 	scroll_text .cups.f 80 $h
   12917 
   12918 
   12919 	set msg {
   12920     CUPS Printing requires SSH be used to set up the CUPS Print service TCP
   12921     port redirection.  This will be either of the "Use SSH" or "SSH+SSL" modes.
   12922     NOTE:  For pure SSL tunnelling it currently will not work.
   12923 
   12924     This method requires working CUPS software setups on BOTH the remote
   12925     and local sides of the connection.
   12926 
   12927     If the remote VNC server is Windows you probably cannot SSH into it
   12928     anyway...  If you can, you will still need to set up a special printer
   12929     TCP port redirection on your own.  Perhaps adding and configuring a
   12930     "Unix Printer" under Windows (like Method #2 below) will work.
   12931 
   12932     If the local machine (SSVNC side) is Windows, see the bottom of this
   12933     help for redirecting to SMB printers.
   12934 
   12935     If the remote VNC server is Mac OS X this method may or may not work.
   12936     Sometimes applications need to be restarted to get them to notice the
   12937     new printers.  Adding and configuring a special "Unix Printer",
   12938     (Method #2) below, might yield more reliable results at the cost of
   12939     additional setup and permissions.
   12940 
   12941     For Unix/Linux remote VNC servers, applications may also need to be
   12942     restarted to notice the new printers.  The only case known to work
   12943     well is the one where the remote side has no CUPS printers configured.
   12944     As mentioned above, see Method #2 for another method.
   12945 
   12946     *************************************************************************
   12947     *** Directions:
   12948 
   12949     You choose your own remote CUPS redir port below under "Use Remote
   12950     CUPS Port".  6631 is our default and is used in the examples below.
   12951     Use it or some random value greater than 1024.  Note that the standard
   12952     CUPS server port is 631.
   12953 
   12954     The port you choose must be unused on the VNC server machine (it is NOT
   12955     checked for you).  Print requests connecting to it are redirected to
   12956     your local VNC viewer-side CUPS server through the SSH tunnel.
   12957 
   12958     (Note: root SSH login permission is needed for ports less than 1024,
   12959     e.g. 631; this is not recommended, use something around 6631 instead).
   12960 
   12961     Then enter the VNC Viewer side (i.e. where you are sitting) CUPS server
   12962     into "Local CUPS Server".  A good choice is the default "localhost:631"
   12963     if there is a cups server on your viewer machine (this is usually the case
   12964     if you have set up a printer).  Otherwise enter, e.g., "my-print-srv:631"
   12965     for your nearby (viewer-side) CUPS print server.
   12966 
   12967 
   12968     The "Manage 'ServerName' in the $HOME/.cups/client.conf file for me"
   12969     setting below is enabled by default.  It should handle most situations.
   12970 
   12971     What it does is modify the .cups/client.conf file on the VNC server-side
   12972     to redirect the print requests while the SSVNC viewer is connected.  When
   12973     SSVNC disconnects .cups/client.conf is restored to its previous setting.
   12974 
   12975     If, for some reason, the SSVNC CUPS script fails to restore this file
   12976     after SSVNC disconnects, run this command on the remote machine:
   12977 
   12978         cp $HOME/.cups/client.conf.back $HOME/.cups/client.conf
   12979 
   12980     to regain your initial printing configuration.
   12981 
   12982 
   12983     You can also use CUPS on the VNC server-side to redirect to Windows
   12984     (SMB) printers.  See the additional info for Windows Printing at the
   12985     bottom of this help.
   12986 
   12987 
   12988     In case the default method (automatic .cups/client.conf modification)
   12989     fails, we describe below all of the possible methods that can be tried.
   12990 
   12991     As noted above, you may need to restart applications for them to notice
   12992     the new printers or for them to revert to the original printers.  If this
   12993     is not acceptable, consider Method #2 below if you have the permission
   12994     and ability to alter the print queues for this.
   12995 
   12996 
   12997     *************************************************************************
   12998     *** Method #1:  Manually create or edit the file $HOME/.cups/client.conf
   12999     on the VNC server side by putting in something like this in it:
   13000 
   13001     	ServerName localhost:6631
   13002 
   13003     based on the port you set in this dialog's entry box.
   13004 
   13005     After the remote VNC Connection is finished, to go back to the non-SSH
   13006     tunnelled CUPS server and either remove the client.conf file or comment
   13007     out the ServerName line.  This restores the normal CUPS server for
   13008     you on the remote VNC server machine.
   13009 
   13010     Select "Manage 'ServerName' in the $HOME/.cups/client.conf file for me"
   13011     to do this editing of the VNC server-side CUPS config file for you
   13012     automatically.  NOTE: It is now on by default (deselect it if you want
   13013     to manage the file manually; e.g. you print through the tunnel only very
   13014     rarely, or often print locally when the tunnel is up, etc.)
   13015 
   13016     Select "Pass -env FD_CUPS=<Port> to x11vnc command line" if you are
   13017     starting x11vnc as the Remote SSH Command, and x11vnc is running in
   13018     -create mode (i.e. FINDCREATEDISPLAY).  That way, when your X session
   13019     is created IPP_PORT will be set correctly for the entire session.
   13020     This is the mode used for 'Terminal Services' printing.
   13021 
   13022     NOTE: You probably would never select both of the above two options
   13023     at the same time, since they conflict with each other to some degree.
   13024 
   13025 
   13026     *************************************************************************
   13027     *** Method #2:  If you have admin permission on the VNC Server machine
   13028     you can likely "Add a Printer" via a GUI dialog, a Wizard, CUPS Web
   13029     interface (i.e. http://localhost:631/), lpadmin(8), etc.
   13030 
   13031     You will need to tell the dialog that the network printer located
   13032     is at, e.g., localhost:6631, and anything else needed to identify
   13033     the printer (type, model, etc).  NOTE: sometimes it is best to set
   13034     the model/type as "Generic / Postscript Printer" to avoid problems
   13035     with garbage being printed out.
   13036 
   13037     For the URI to use, we have successfully used ones like this with CUPS:
   13038 
   13039        http://localhost:6631/printers/Deskjet-3840
   13040         ipp://localhost:6631/printers/Deskjet-3840
   13041 
   13042     for an HP Deskjet-3840 printer.  See the CUPS documentation for more
   13043     about the URI syntax and pathname.
   13044 
   13045     This mode makes the client.conf ServerName parameter unnecessary
   13046     (BE SURE TO DISABLE the "Manage 'ServerName' ... for me"  option.)
   13047 
   13048 
   13049     *************************************************************************
   13050     *** Method #3:  Restarting individual applications with the IPP_PORT
   13051     set will enable redirected printing for them, e.g.:
   13052 
   13053        env IPP_PORT=6631 firefox
   13054 
   13055     If you can only get this method to work, an extreme application would
   13056     be to run the whole desktop, e.g. "env IPP_PORT=6631 gnome-session", but
   13057     then you would need some sort of TCP redirector (ssh -L comes to mind),
   13058     to direct it to 631 when not connected remotely.
   13059 
   13060 
   13061     *************************************************************************
   13062     *** Windows/SMB Printers:  Under "Local SMB Print Server" you can set
   13063     a port redirection for a Windows (non-CUPS) SMB printer.  E.g. port
   13064     6632 -> localhost:139.
   13065 
   13066     If localhost:139 does not work, try the literal string "IP:139", or
   13067     insert the actual IP address manually.  NOTE: Nowadays on Windows port
   13068     445 might be a better choice.
   13069 
   13070     For Windows printers, if there is no local CUPS print server, set the
   13071     'Local CUPS Server' and 'Use Remote CUPS Port' to be EMPTY (to avoid
   13072     desktop apps trying incessantly to reach the nonexistent CUPS server.)
   13073 
   13074     You must enable Sharing for your local Windows Printer.  Use Windows
   13075     Printer configuration dialogs to do this.
   13076 
   13077     Next, you need to have sudo or print admin permission so that you can
   13078     configure the *remote* CUPS to know about this Windows printer via
   13079     lpadmin(8) or GUI Printer Configuration dialog, etc (Method #2 above).
   13080     You basically give it the URI:
   13081 
   13082         smb://localhost:6632/printername
   13083 
   13084     For example, we have had success with GNOME CUPS printing configuration
   13085     using:
   13086 
   13087 	smb://localhost:6632/HPOffice
   13088 	smb://localhost:6632/COMPUTERNAME/HPOffice
   13089 
   13090     where "HPOffice" was the name Windows shares the printer as.
   13091 
   13092     Also with this SMB port redir mode, as a last resort you can often print
   13093     using the smbspool(8) program like this:
   13094 
   13095        smbspool smb://localhost:6632/printer job user title 1 "" myfile.ps
   13096 
   13097     You could put this in a script.  For this URI, it appears only the number
   13098     of copies ("1" above) and the file itself are important.
   13099 
   13100     If on the local (SSVNC viewer) side there is some nearby CUPS print server
   13101     that knows about your Windows printer, you might have better luck with
   13102     that instead of using SMB.  Set 'Local CUPS Server' to it.
   13103 
   13104     For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-cups
   13105 }
   13106 	.cups.f.t insert end $msg
   13107 
   13108 	global uname
   13109 	set something_set 0
   13110 
   13111 	if {$cups_local_server != ""} {
   13112 		set something_set 1
   13113 	}
   13114 	if {$cups_local_smb_server != ""} {
   13115 		set something_set 1
   13116 	}
   13117 
   13118 	if {$cups_local_server == "" && ! $something_set} {
   13119 		if {$uname == "Darwin"} {
   13120 			set cups_local_server "127.0.0.1:631"
   13121 		} else {
   13122 			set cups_local_server "localhost:631"
   13123 		}
   13124 	}
   13125 	if {$cups_remote_port == "" && ! $something_set} {
   13126 		set cups_remote_port "6631"
   13127 	}
   13128 	if {$cups_local_smb_server == "" && ! $something_set} {
   13129 		global is_windows
   13130 		if {$is_windows} {
   13131 			set cups_local_smb_server "IP:139"
   13132 		} elseif {$uname == "Darwin"} {
   13133 			set cups_local_smb_server "127.0.0.1:139"
   13134 		} else {
   13135 			set cups_local_smb_server "localhost:139"
   13136 		}
   13137 	}
   13138 	if {$cups_remote_smb_port == "" && ! $something_set} {
   13139 		set cups_remote_smb_port "6632"
   13140 	}
   13141 
   13142 	frame .cups.serv
   13143 	label .cups.serv.l -anchor w -text "Local CUPS Server:      "
   13144 	entry .cups.serv.e -width 40 -textvariable cups_local_server
   13145 	pack .cups.serv.e -side right
   13146 	pack .cups.serv.l -side left -expand 1 -fill x
   13147 
   13148 	frame .cups.port
   13149 	label .cups.port.l -anchor w -text "Use Remote CUPS Port:"
   13150 	entry .cups.port.e -width 40 -textvariable cups_remote_port
   13151 	pack .cups.port.e -side right
   13152 	pack .cups.port.l -side left -expand 1 -fill x
   13153 
   13154 	frame .cups.smbs
   13155 	label .cups.smbs.l -anchor w -text "Local SMB Print Server:      "
   13156 	entry .cups.smbs.e -width 40 -textvariable cups_local_smb_server
   13157 	pack .cups.smbs.e -side right
   13158 	pack .cups.smbs.l -side left -expand 1 -fill x
   13159 
   13160 	frame .cups.smbp
   13161 	label .cups.smbp.l -anchor w -text "Use Remote SMB Print Port:"
   13162 	entry .cups.smbp.e -width 40 -textvariable cups_remote_smb_port
   13163 	pack .cups.smbp.e -side right
   13164 	pack .cups.smbp.l -side left -expand 1 -fill x
   13165 
   13166 	checkbutton .cups.cupsrc -anchor w -variable cups_manage_rcfile -text \
   13167 		"Manage 'ServerName' in the remote \$HOME/.cups/client.conf file for me"
   13168 
   13169 	checkbutton .cups.x11vnc -anchor w -variable cups_x11vnc -text \
   13170 		"Pass -env FD_CUPS=<Port> to x11vnc command line."
   13171 
   13172 	button .cups.cancel -text "Cancel" -command {destroy .cups; set use_cups 0}
   13173 	bind .cups <Escape> {destroy .cups; set use_cups 0}
   13174 	wm protocol .cups WM_DELETE_WINDOW {destroy .cups; set use_cups 0}
   13175 	button .cups.done -text "Done" -command {destroy .cups; if {$use_cups} {set_ssh}}
   13176 
   13177 	button .cups.guess -text "Help me decide ..." -command {}
   13178 	.cups.guess configure -state disabled
   13179 
   13180 	pack .cups.done .cups.cancel .cups.guess .cups.x11vnc .cups.cupsrc .cups.smbp .cups.smbs .cups.port .cups.serv -side bottom -fill x
   13181 	pack .cups.f -side top -fill both -expand 1
   13182 
   13183 	center_win .cups
   13184 	focus .cups.serv.e
   13185 }
   13186 
   13187 proc ts_sound_dialog {} {
   13188 
   13189 	global is_windows
   13190 	global ts_only
   13191 
   13192 	toplev .snd
   13193 	wm title .snd "Sound Tunnelling"
   13194 
   13195 	scroll_text .snd.f 80 21
   13196 
   13197 	set msg {
   13198     Your remote Desktop will be started in an Enlightenment Sound Daemon
   13199     (ESD) environment (esddsp(1), which must be installed on the remote
   13200     machine), and a local ESD sound daemon (esd(1)) will be started to
   13201     play the sounds for you to hear.
   13202 
   13203     In the entry box below you can choose the port that the local esd
   13204     will use to listen on.  The default ESD port is 16001.  You will
   13205     need to choose different values if you will have more than one esd
   13206     running locally.
   13207 
   13208     The command run (with port replaced by your choice) will be:
   13209 
   13210       %RCMD
   13211 
   13212     Note: Unfortunately not all applications work with ESD.
   13213           And esd's LD_PRELOAD is broken on 64+32bit Linux (x86_64).
   13214           And so this mode is not working well currently...
   13215 
   13216     For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-sound
   13217 }
   13218 
   13219 
   13220 	global sound_daemon_remote_port sound_daemon_local_port sound_daemon_local_cmd
   13221 	global sound_daemon_local_start sound_daemon_local_kill
   13222 
   13223 	set sound_daemon_local_start 1
   13224 	set sound_daemon_local_kill 1
   13225 
   13226 	if {$sound_daemon_remote_port == ""} {
   13227 		set sound_daemon_remote_port 16010
   13228 	}
   13229 	if {$sound_daemon_local_port == ""} {
   13230 		set sound_daemon_local_port 16010
   13231 	}
   13232 
   13233 	if {$sound_daemon_local_cmd == ""} {
   13234 		global is_windows
   13235 		if {$is_windows} {
   13236 			set sound_daemon_local_cmd {esound\esd -promiscuous -as 5 -port %PORT -tcp -bind 127.0.0.1}
   13237 		} else {
   13238 			set sound_daemon_local_cmd {esd -promiscuous -as 5 -port %PORT -tcp -bind 127.0.0.1}
   13239 		}
   13240 	}
   13241 	regsub {%PORT} $sound_daemon_local_cmd $sound_daemon_local_port sound_daemon_local_cmd
   13242 
   13243 	regsub {%RCMD} $msg $sound_daemon_local_cmd msg
   13244 	.snd.f.t insert end $msg
   13245 
   13246 	frame .snd.lport
   13247 	label .snd.lport.l -anchor w -text "Local Sound Port:     "
   13248 	entry .snd.lport.e -width 45 -textvariable sound_daemon_local_port
   13249 	pack .snd.lport.e -side right
   13250 	pack .snd.lport.l -side left -expand 1 -fill x
   13251 
   13252 	button .snd.cancel -text "Cancel" -command {destroy .snd; set use_sound 0}
   13253 	bind .snd <Escape> {destroy .snd; set use_sound 0}
   13254 	wm protocol .snd WM_DELETE_WINDOW {destroy .snd; set use_sound 0}
   13255 	button .snd.done -text "Done" -command {destroy .snd; if {$use_sound} {set_ssh}}
   13256 	bind .snd.lport.e <Return> {destroy .snd; if {$use_sound} {set_ssh}}
   13257 
   13258 	pack .snd.done .snd.cancel .snd.lport -side bottom -fill x
   13259 	pack .snd.f -side bottom -fill both -expand 1
   13260 
   13261 	center_win .snd
   13262 	focus .snd.lport.e
   13263 }
   13264 
   13265 proc sound_dialog {} {
   13266 
   13267 	global is_windows
   13268 	global ts_only
   13269 	if {$ts_only} {
   13270 		ts_sound_dialog;
   13271 		return
   13272 	}
   13273 
   13274 	toplev .snd
   13275 	wm title .snd "ESD/ARTSD Sound Tunnelling"
   13276 
   13277 	global uname
   13278 	set h 28
   13279 	if [small_height] {
   13280 		set h 14
   13281 	} elseif {$uname == "Darwin"} {
   13282 		set h 20
   13283 	}
   13284 	scroll_text .snd.f 80 $h
   13285 
   13286 	set msg {
   13287     Sound tunnelling to a sound daemon requires SSH be used to set up the
   13288     service port redirection.  This will be either of the "Use SSH" or
   13289     "SSH+SSL" modes. NOTE: For pure SSL tunnelling it currently will not work.
   13290 
   13291     This method requires working Sound daemon (e.g. ESD or ARTSD) software
   13292     setups on BOTH the remote and local sides of the connection.
   13293 
   13294     Often this means you want to run your ENTIRE remote desktop with ALL
   13295     applications instructed to use the sound daemon's network port.  E.g.
   13296 
   13297         esddsp -s localhost:16001  startkde
   13298         esddsp -s localhost:16001  gnome-session
   13299 
   13300     and similarly for artsdsp, etc.  You put this in your ~/.xession,
   13301     or other startup file.  This is non standard.  If you do not want to
   13302     do this you still can direct *individual* sound applications through
   13303     the tunnel, for example "esddsp -s localhost:16001 soundapp", where
   13304     "soundapp" is some application that makes noise (say xmms or mpg123).
   13305 
   13306     Select "Pass -env FD_ESD=<Port> to x11vnc command line."  if you are
   13307     starting x11vnc as the Remote SSH Command, and x11vnc is running in
   13308     -create mode (i.e. FINDCREATEDISPLAY).  That way, your X session is
   13309     started via "esddsp -s ... <session>"  and the ESD variables will be
   13310     set correctly for the entire session.  (This mode make most sense for
   13311     a virtual, e.g. Xvfb or Xdummy session, not one a physical display).
   13312 
   13313     Also, usually the remote Sound daemon must be killed BEFORE the SSH port
   13314     redir is established (because it is listening on the port we want to use
   13315     for the SSH redir), and, presumably, restarted when the VNC connection
   13316     finished.
   13317 
   13318     One may also want to start and kill a local sound daemon that will
   13319     play the sound received over the network on the local machine.
   13320 
   13321     You can indicate the remote and local Sound daemon commands below and
   13322     how they should be killed and/or restart.  Some examples:
   13323 
   13324         esd -promiscuous -as 5 -port 16001 -tcp -bind 127.0.0.1
   13325         artsd -n -p 7265 -F 10 -S 4096 -n -s 5 -m artsmessage -l 3 -f
   13326 
   13327     or you can leave some or all blank and kill/start them manually.
   13328 
   13329     For convenience, a Windows port of ESD is provided in the util/esound
   13330     directory, and so this might work for a Local command:
   13331 
   13332         esound\esd -promiscuous -as 5 -port 16001 -tcp -bind 127.0.0.1
   13333 
   13334     NOTE: If you indicate "Remote Sound daemon: Kill at start." below,
   13335     then THERE WILL BE TWO SSH'S: THE FIRST ONE TO KILL THE DAEMON.
   13336     So you may need to supply TWO SSH PASSWORDS, unless you are using
   13337     something like ssh-agent(1), the Putty PW setting, etc.
   13338 
   13339     You will also need to supply the remote and local sound ports for
   13340     the SSH redirs.  For esd the default port is 16001, but you can choose
   13341     another one if you prefer.
   13342 
   13343     For "Local Sound Port" you can also supply "host:port" instead of just
   13344     a numerical port to specify non-localhost connections, e.g. to another
   13345     nearby machine.
   13346 
   13347     For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-sound
   13348 }
   13349 	.snd.f.t insert end $msg
   13350 
   13351 	global sound_daemon_remote_port sound_daemon_local_port sound_daemon_local_cmd
   13352 	if {$sound_daemon_remote_port == ""} {
   13353 		set sound_daemon_remote_port 16001
   13354 	}
   13355 	if {$sound_daemon_local_port == ""} {
   13356 		set sound_daemon_local_port 16001
   13357 	}
   13358 
   13359 	if {$sound_daemon_local_cmd == ""} {
   13360 		global is_windows
   13361 		if {$is_windows} {
   13362 			set sound_daemon_local_cmd {esound\esd -promiscuous -as 5 -port %PORT -tcp -bind 127.0.0.1}
   13363 		} else {
   13364 			set sound_daemon_local_cmd {esd -promiscuous -as 5 -port %PORT -tcp -bind 127.0.0.1}
   13365 		}
   13366 		regsub {%PORT} $sound_daemon_local_cmd $sound_daemon_local_port sound_daemon_local_cmd
   13367 	}
   13368 
   13369 
   13370 	frame .snd.remote
   13371 	label .snd.remote.l -anchor w -text "Remote Sound daemon cmd: "
   13372 	entry .snd.remote.e -width 45 -textvariable sound_daemon_remote_cmd
   13373 	pack .snd.remote.e -side right
   13374 	pack .snd.remote.l -side left -expand 1 -fill x
   13375 
   13376 	frame .snd.local
   13377 	label .snd.local.l -anchor w -text "Local Sound daemon cmd:     "
   13378 	entry .snd.local.e -width 45 -textvariable sound_daemon_local_cmd
   13379 	pack .snd.local.e -side right
   13380 	pack .snd.local.l -side left -expand 1 -fill x
   13381 
   13382 	frame .snd.rport
   13383 	label .snd.rport.l -anchor w -text "Remote Sound Port: "
   13384 	entry .snd.rport.e -width 45 -textvariable sound_daemon_remote_port
   13385 	pack .snd.rport.e -side right
   13386 	pack .snd.rport.l -side left -expand 1 -fill x
   13387 
   13388 	frame .snd.lport
   13389 	label .snd.lport.l -anchor w -text "Local Sound Port:     "
   13390 	entry .snd.lport.e -width 45 -textvariable sound_daemon_local_port
   13391 	pack .snd.lport.e -side right
   13392 	pack .snd.lport.l -side left -expand 1 -fill x
   13393 
   13394 
   13395 	checkbutton .snd.sdk -anchor w -variable sound_daemon_kill -text \
   13396 		"Remote Sound daemon: Kill at start."
   13397 
   13398 	checkbutton .snd.sdr -anchor w -variable sound_daemon_restart -text \
   13399 		"Remote Sound daemon: Restart at end."
   13400 
   13401 	checkbutton .snd.sdsl -anchor w -variable sound_daemon_local_start -text \
   13402 		"Local Sound daemon: Run at start."
   13403 
   13404 	checkbutton .snd.sdkl -anchor w -variable sound_daemon_local_kill -text \
   13405 		"Local Sound daemon: Kill at end."
   13406 
   13407 	checkbutton .snd.x11vnc -anchor w -variable sound_daemon_x11vnc -text \
   13408 		"Pass -env FD_ESD=<Port> to x11vnc command line."
   13409 
   13410 	button .snd.guess -text "Help me decide ..." -command {}
   13411 	.snd.guess configure -state disabled
   13412 
   13413 	global is_win9x
   13414 	if {$is_win9x} {
   13415 		.snd.local.e configure -state disabled
   13416 		.snd.local.l configure -state disabled
   13417 		.snd.sdsl configure -state disabled
   13418 		.snd.sdkl configure -state disabled
   13419 	}
   13420 
   13421 	button .snd.cancel -text "Cancel" -command {destroy .snd; set use_sound 0}
   13422 	bind .snd <Escape> {destroy .snd; set use_sound 0}
   13423 	wm protocol .snd WM_DELETE_WINDOW {destroy .snd; set use_sound 0}
   13424 	button .snd.done -text "Done" -command {destroy .snd; if {$use_sound} {set_ssh}}
   13425 
   13426 	pack .snd.done .snd.cancel .snd.guess .snd.x11vnc .snd.sdkl .snd.sdsl .snd.sdr .snd.sdk .snd.lport .snd.rport \
   13427 		.snd.local .snd.remote -side bottom -fill x
   13428 	pack .snd.f -side bottom -fill both -expand 1
   13429 
   13430 	center_win .snd
   13431 	focus .snd.remote.e
   13432 }
   13433 
   13434 # Share ideas.
   13435 #
   13436 # Unix:
   13437 #
   13438 # if type smbclient
   13439 # first parse smbclient -L localhost -N
   13440 # and/or      smbclient -L `hostname` -N
   13441 # Get Sharenames and Servers and Domain.
   13442 #
   13443 # loop over servers, doing smbclient -L server -N
   13444 # pile this into a huge list, sep by disk and printers.
   13445 #
   13446 # WinXP:
   13447 #
   13448 # parse "NET VIEW" output similarly.
   13449 #
   13450 # Have checkbox for each disk.  Set default root to /var/tmp/${USER}-mnts
   13451 # Let them change that at once and have it populate.
   13452 #
   13453 # use   //hostname/share  /var/tmp/runge-mnts/hostname/share
   13454 #
   13455 #
   13456 # Printers, hmmm.  Can't add to remote cups list...  I guess have the list
   13457 # ready for CUPS dialog to suggest which SMB servers they want to redirect
   13458 # to...
   13459 
   13460 proc get_hostname {} {
   13461 	global is_windows is_win9x
   13462 	set str ""
   13463 	if {$is_windows} {
   13464 		if {1} {
   13465 			catch {set str [exec hostname]}
   13466 			regsub -all {[\r]} $str "" str
   13467 		} else {
   13468 			catch {set str [exec net config]}
   13469 			if [regexp -nocase {Computer name[ \t]+\\\\([^ \t]+)} $str mv str] {
   13470 				;
   13471 			} else {
   13472 				set str ""
   13473 			}
   13474 		}
   13475 	} else {
   13476 		catch {set str [exec hostname]}
   13477 	}
   13478 	set str [string trim $str]
   13479 	return $str
   13480 }
   13481 
   13482 proc smb_list_windows {smbhost} {
   13483 	global smb_local smb_local_hosts smb_this_host
   13484 	global is_win9x
   13485 	set dbg 0
   13486 
   13487 	set domain ""
   13488 
   13489 	if {$is_win9x} {
   13490 		# exec net view ... doesn't work.
   13491 		set smb_this_host "unknown"
   13492 		return
   13493 	}
   13494 
   13495 	set this_host [get_hostname]
   13496 	set This_host [string toupper $this_host]
   13497 	set smb_this_host $This_host
   13498 
   13499 	if {$smbhost == $smb_this_host} {
   13500 		catch {set out0 [exec net view]}
   13501 		regsub -all {[\r]} $out0 "" out0
   13502 		foreach line [split $out0 "\n"] {
   13503 			if [regexp -nocase {in workgroup ([^ \t]+)} $line mv wg] {
   13504 				regsub -all {[.]} $wg "" wg
   13505 				set domain $wg
   13506 			} elseif [regexp {^\\\\([^ \t]+)[ \t]*(.*)} $line mv host comment] {
   13507 				set smb_local($smbhost:server:$host) $comment
   13508 			}
   13509 		}
   13510 	}
   13511 
   13512 	set out1 ""
   13513 	set h "\\\\$smbhost"
   13514 	catch {set out1 [exec net view $h]}
   13515 	regsub -all {[\r]} $out1 "" out1
   13516 
   13517 	if {$dbg} {puts "SMBHOST: $smbhost"}
   13518 
   13519 	set mode ""
   13520 	foreach line [split $out1 "\n"] {
   13521 		if [regexp {^[ \t]*---} $line] {
   13522 			continue
   13523 		}
   13524 		if [regexp -nocase {The command} $line] {
   13525 			continue
   13526 		}
   13527 		if [regexp -nocase {Shared resources} $line] {
   13528 			continue
   13529 		}
   13530 		if [regexp -nocase {^[ \t]*Share[ \t]*name} $line] {
   13531 			set mode "shares"
   13532 			continue
   13533 		}
   13534 		set line [string trim $line]
   13535 		if {$line == ""} {
   13536 			continue
   13537 		}
   13538 		if {$mode == "shares"} {
   13539 			if [regexp {^([^ \t]+)[ \t]+([^ \t]+)[ \t]*(.*)$} $line mv name type comment] {
   13540 				if {$dbg} {
   13541 					puts "SHR: $name"
   13542 					puts "---: $type"
   13543 					puts "---: $comment"
   13544 				}
   13545 				if [regexp -nocase {^Disk$} $type] {
   13546 					set smb_local($smbhost:disk:$name) $comment
   13547 				} elseif [regexp -nocase {^Print} $type] {
   13548 					set smb_local($smbhost:printer:$name) $comment
   13549 				}
   13550 			}
   13551 		}
   13552 	}
   13553 
   13554 	set smb_local($smbhost:domain) $domain
   13555 }
   13556 
   13557 proc smb_list_unix {smbhost} {
   13558 	global smb_local smb_local_hosts smb_this_host
   13559 	set smbclient [in_path smbclient]
   13560 	if {[in_path smbclient] == ""} {
   13561 		return ""
   13562 	}
   13563 	set dbg 0
   13564 
   13565 	set this_host [get_hostname]
   13566 	set This_host [string toupper $this_host]
   13567 	set smb_this_host $This_host
   13568 
   13569 	set out1 ""
   13570 	catch {set out1 [exec smbclient -N -L $smbhost 2>@ stdout]}
   13571 
   13572 	if {$dbg} {puts "SMBHOST: $smbhost"}
   13573 	if {$smbhost == $this_host || $smbhost == $This_host} {
   13574 		if {$out1 == ""} {
   13575 			catch {set out1 [exec smbclient -N -L localhost 2>@ stdout]}
   13576 		}
   13577 	}
   13578 
   13579 	set domain ""
   13580 	set mode ""
   13581 	foreach line [split $out1 "\n"] {
   13582 		if [regexp {^[ \t]*---} $line] {
   13583 			continue
   13584 		}
   13585 		if [regexp {Anonymous login} $line] {
   13586 			continue
   13587 		}
   13588 		if {$domain == "" && [regexp {Domain=\[([^\]]+)\]} $line mv domain]} {
   13589 			if {$dbg} {puts "DOM: $domain"}
   13590 			continue
   13591 		}
   13592 		if [regexp {^[ \t]*Sharename} $line] {
   13593 			set mode "shares"
   13594 			continue
   13595 		}
   13596 		if [regexp {^[ \t]*Server} $line] {
   13597 			set mode "server"
   13598 			continue
   13599 		}
   13600 		if [regexp {^[ \t]*Workgroup} $line] {
   13601 			set mode "workgroup"
   13602 			continue
   13603 		}
   13604 		set line [string trim $line]
   13605 		if {$mode == "shares"} {
   13606 			if [regexp {^([^ \t]+)[ \t]+([^ \t]+)[ \t]*(.*)$} $line mv name type comment] {
   13607 				if {$dbg} {
   13608 					puts "SHR: $name"
   13609 					puts "---: $type"
   13610 					puts "---: $comment"
   13611 				}
   13612 				if [regexp -nocase {^Disk$} $type] {
   13613 					set smb_local($smbhost:disk:$name) $comment
   13614 				} elseif [regexp -nocase {^Printer$} $type] {
   13615 					set smb_local($smbhost:printer:$name) $comment
   13616 				}
   13617 			}
   13618 		} elseif {$mode == "server"} {
   13619 			if [regexp {^([^ \t]+)[ \t]*(.*)$} $line mv host comment] {
   13620 				if {$dbg} {
   13621 					puts "SVR: $host"
   13622 					puts "---: $comment"
   13623 				}
   13624 				set smb_local($smbhost:server:$host) $comment
   13625 			}
   13626 		} elseif {$mode == "workgroup"} {
   13627 			if [regexp {^([^ \t]+)[ \t]+(.*)$} $line mv work host] {
   13628 				if {$dbg} {
   13629 					puts "WRK: $work"
   13630 					puts "---: $host"
   13631 				}
   13632 				if {$host != ""} {
   13633 					set smb_local($smbhost:master:$work) $host
   13634 				}
   13635 			}
   13636 		}
   13637 	}
   13638 
   13639 	set smb_local($smbhost:domain) $domain
   13640 }
   13641 
   13642 proc smb_list {} {
   13643 	global is_windows smb_local smb_local_hosts
   13644 	global smb_host_list
   13645 
   13646 	set smb_local(null) ""
   13647 
   13648 	if {! [info exists smb_host_list]} {
   13649 		set smb_host_list ""
   13650 	}
   13651 	if [info exists smb_local] {
   13652 		unset smb_local
   13653 	}
   13654 	if [info exists smb_local_hosts] {
   13655 		unset smb_local_hosts
   13656 	}
   13657 
   13658 	set this_host [get_hostname]
   13659 	set this_host [string toupper $this_host]
   13660 	if {$is_windows} {
   13661 		smb_list_windows $this_host
   13662 	} else {
   13663 		smb_list_unix $this_host
   13664 	}
   13665 	set did($this_host) 1
   13666 	set keys [array names smb_local]
   13667 	foreach item [split $smb_host_list] {
   13668 		if {$item != ""} {
   13669 			set item [string toupper $item]
   13670 			lappend keys "$this_host:server:$item"
   13671 		}
   13672 	}
   13673 	foreach key $keys {
   13674 		if [regexp "^$this_host:server:(.*)\$" $key mv host]  {
   13675 			if {$host == ""} {
   13676 				continue
   13677 			}
   13678 			set smb_local_hosts($host) 1
   13679 			if {! [info exists did($host)]} {
   13680 				if {$is_windows} {
   13681 					smb_list_windows $host
   13682 				} else {
   13683 					smb_list_unix $host
   13684 				}
   13685 				set did($host) 1
   13686 			}
   13687 		}
   13688 	}
   13689 }
   13690 
   13691 proc smb_check_selected {} {
   13692 	global smbmount_exists smbmount_sumode
   13693 	global smb_selected smb_selected_mnt smb_selected_cb smb_selected_en
   13694 
   13695 	set ok 0
   13696 	if {$smbmount_exists && $smbmount_sumode != "dontknow"} {
   13697 		set ok 1
   13698 	}
   13699 	set state disabled
   13700 	if {$ok} {
   13701 		set state normal
   13702 	}
   13703 
   13704 	foreach cb [array names smb_selected_cb] {
   13705 		catch {$cb configure -state $state}
   13706 	}
   13707 	foreach en [array names smb_selected_en] {
   13708 		catch {$en configure -state $state}
   13709 	}
   13710 }
   13711 
   13712 proc make_share_widgets {w} {
   13713 
   13714 	set share_label $w.f.hl
   13715 	catch {$share_label configure -text "Share Name: PROBING ..."}
   13716 	update
   13717 
   13718 	smb_list
   13719 
   13720 	set saw_f 0
   13721 	foreach child [winfo children $w] {
   13722 		if {$child == "$w.f"} {
   13723 			set saw_f 1
   13724 			continue
   13725 		}
   13726 		catch {destroy $child}
   13727 	}
   13728 
   13729 	set w1 47
   13730 	set w2 44
   13731 
   13732 	if {! $saw_f} {
   13733 		set wf $w.f
   13734 		frame $wf
   13735 		label $wf.hl -width $w1 -text "Share Name:" -anchor w
   13736 		label $wf.hr -width $w2 -text "  Mount Point:" -anchor w
   13737 
   13738 		pack $wf.hl $wf.hr -side left -expand 1
   13739 		pack $wf -side top -fill x
   13740 
   13741 		.smbwiz.f.t window create end -window $w
   13742 	}
   13743 
   13744 	global smb_local smb_local_hosts smb_this_host smb_selected smb_selected_mnt
   13745 	global smb_selected_host smb_selected_name
   13746 	global smb_selected_cb smb_selected_en
   13747 	global smb_host_list
   13748 	if [info exists smb_selected]      {array unset smb_selected }
   13749 	if [info exists smb_selected_mnt]  {array unset smb_selected_mnt}
   13750 	if [info exists smb_selected_cb]   {array unset smb_selected_cb}
   13751 	if [info exists smb_selected_en]   {array unset smb_selected_en}
   13752 	if [info exists smb_selected_host] {array unset smb_selected_host}
   13753 	if [info exists smb_selected_name] {array unset smb_selected_name}
   13754 
   13755 	set hosts [list $smb_this_host]
   13756 	lappend hosts [lsort [array names smb_local_hosts]]
   13757 
   13758 	set smb_host_list ""
   13759 	set i 0
   13760 
   13761 	global smb_mount_prefix
   13762 	set smb_mount_prefix "/var/tmp/%USER-mnts"
   13763 
   13764 	foreach host [lsort [array names smb_local_hosts]] {
   13765 
   13766 		if [info exists did($host)] {
   13767 			continue
   13768 		}
   13769 		set did($host) 1
   13770 
   13771 		append smb_host_list "$host "
   13772 
   13773 		foreach key [lsort [array names smb_local]] {
   13774 			if [regexp {^([^:]+):([^:]+):(.*)$} $key mv host2 type name] {
   13775 				if {$host2 != $host}  {
   13776 					continue
   13777 				}
   13778 				if {$type != "disk"} {
   13779 					continue
   13780 				}
   13781 				set wf $w.f$i
   13782 				frame $wf
   13783 				checkbutton $wf.c -anchor w -width $w1 -variable smb_selected($i) \
   13784 					-text "//$host/$name" -relief ridge
   13785 				if {! [info exists smb_selected($i)]} {
   13786 					set smb_selected($i) 0
   13787 				}
   13788 
   13789 				entry $wf.e -width $w2 -textvariable smb_selected_mnt($i)
   13790 				set smb_selected_mnt($i) "$smb_mount_prefix/$host/$name"
   13791 
   13792 				set smb_selected_host($i) $host
   13793 				set smb_selected_name($i) $name
   13794 
   13795 				set smb_selected_cb($wf.c) $i
   13796 				set smb_selected_en($wf.e) $i
   13797 				set comment $smb_local($key)
   13798 
   13799 				bind $wf.c <Enter> "$share_label configure -text {Share Name: $comment}"
   13800 				bind $wf.c <Leave> "$share_label configure -text {Share Name:}"
   13801 
   13802 				$wf.c configure -state disabled
   13803 				$wf.e configure -state disabled
   13804 
   13805 				pack $wf.c $wf.e -side left -expand 1
   13806 				pack $wf -side top -fill x
   13807 				incr i
   13808 			}
   13809 		}
   13810 	}
   13811 	if {$i == 0} {
   13812 		global is_win9x
   13813 		$share_label configure -text {Share Name: No SMB Share Hosts were found!}
   13814 		if {$is_win9x} {
   13815 			.smbwiz.f.t insert end "\n(this feature does not work on Win9x you have have to enter them manually: //HOST/share /var/tmp/mymnt)\n"
   13816 		}
   13817 	} else {
   13818 		$share_label configure -text "Share Name: Found $i SMB Shares"
   13819 	}
   13820 	smb_check_selected
   13821 }
   13822 
   13823 proc smb_help_me_decide {} {
   13824 	global is_windows
   13825 	global smb_local smb_local_hosts smb_this_host smb_selected smb_selected_mnt
   13826 	global smb_selected_host smb_selected_name
   13827 	global smb_selected_cb smb_selected_en
   13828 	global smb_host_list
   13829 
   13830 	toplev .smbwiz
   13831 	set title "SMB Filesystem Tunnelling -- Help Me Decide"
   13832 	wm title .smbwiz $title
   13833 	set id "  "
   13834 
   13835 	set h 40
   13836 	if [small_height] {
   13837 		set h 30
   13838 	}
   13839 	scroll_text .smbwiz.f 100 $h
   13840 
   13841 	set msg {
   13842 For now you will have to verify the following information manually.
   13843 
   13844 You can do this by either logging into the remote machine to find the info or asking the sysadmin for it.
   13845 
   13846 }
   13847 
   13848 	if {! $is_windows} {
   13849 		.smbwiz.f.t configure -font {Helvetica -12 bold}
   13850 	}
   13851 	.smbwiz.f.t insert end $msg
   13852 
   13853 	set w .smbwiz.f.t.f1
   13854 	frame $w -bd 1 -relief ridge -cursor {top_left_arrow}
   13855 
   13856 	.smbwiz.f.t insert end "\n"
   13857 
   13858 	.smbwiz.f.t insert end "1) Indicate the existence of the 'smbmount' command on the remote system:\n"
   13859 	.smbwiz.f.t insert end "\n$id"
   13860 	global smbmount_exists
   13861 	set smbmount_exists 0
   13862 
   13863 	checkbutton $w.smbmount_exists -pady 1 -anchor w -variable smbmount_exists \
   13864 		-text "Yes, the 'smbmount' command exists on the remote system." \
   13865 		-command smb_check_selected
   13866 
   13867 	pack $w.smbmount_exists
   13868 	.smbwiz.f.t window create end -window $w
   13869 
   13870 	.smbwiz.f.t insert end "\n\n\n"
   13871 
   13872 	set w .smbwiz.f.t.f2
   13873 	frame $w -bd 1 -relief ridge -cursor {top_left_arrow}
   13874 
   13875 	.smbwiz.f.t insert end "2) Indicate your authorization to run 'smbmount' on the remote system:\n"
   13876 	.smbwiz.f.t insert end "\n$id"
   13877 	global smbmount_sumode
   13878 	set smbmount_sumode "dontknow"
   13879 
   13880 	radiobutton $w.dk -pady 1 -anchor w -variable smbmount_sumode -value dontknow \
   13881 		-text "I do not know if I can mount SMB shares on the remote system via 'smbmount'" \
   13882 		-command smb_check_selected
   13883 	pack $w.dk -side top -fill x
   13884 
   13885 	radiobutton $w.su -pady 1 -anchor w -variable smbmount_sumode -value su \
   13886 		-text "I know the Password to run commands as root on the remote system via 'su'" \
   13887 		-command smb_check_selected
   13888 	pack $w.su -side top -fill x
   13889 
   13890 	radiobutton $w.sudo -pady 1 -anchor w -variable smbmount_sumode -value sudo \
   13891 		-text "I know the Password to run commands as root on the remote system via 'sudo'" \
   13892 		-command smb_check_selected
   13893 	pack $w.sudo -side top -fill x
   13894 
   13895 	radiobutton $w.ru -pady 1 -anchor w -variable smbmount_sumode -value none \
   13896 		-text "I do not need to be root on the remote system to mount SMB shares via 'smbmount'" \
   13897 		-command smb_check_selected
   13898 	pack $w.ru -side top -fill x
   13899 
   13900 	.smbwiz.f.t window create end -window $w
   13901 
   13902 	global smb_wiz_done
   13903 	set smb_wiz_done 0
   13904 
   13905 	button .smbwiz.cancel -text "Cancel" -command {set smb_wiz_done 1}
   13906 	button .smbwiz.done -text "Done" -command {set smb_wiz_done 1}
   13907 	pack .smbwiz.done -side bottom -fill x
   13908 	pack .smbwiz.f -side top -fill both -expand 1
   13909 
   13910 	wm protocol .smbwiz WM_DELETE_WINDOW {set smb_wiz_done 1}
   13911 	center_win .smbwiz
   13912 
   13913 	wm title .smbwiz "Searching for Local SMB shares..."
   13914 	update
   13915 	wm title .smbwiz $title
   13916 
   13917 	global smb_local smb_this_host
   13918 	.smbwiz.f.t insert end "\n\n\n"
   13919 
   13920 	set w .smbwiz.f.t.f3
   13921 	catch {destroy $w}
   13922 	frame $w -bd 1 -relief ridge -cursor {top_left_arrow}
   13923 
   13924 	.smbwiz.f.t insert end "3) Select SMB shares to mount and their mount point on the remote system:\n"
   13925 	.smbwiz.f.t insert end "\n${id}"
   13926 
   13927 	make_share_widgets $w
   13928 
   13929 	.smbwiz.f.t insert end "\n(%USER will be expanded to the username on the remote system and %HOME the home directory)\n"
   13930 
   13931 	.smbwiz.f.t insert end "\n\n\n"
   13932 
   13933 	.smbwiz.f.t insert end "You can change the list of Local SMB hosts to probe and the mount point prefix here:\n"
   13934 	.smbwiz.f.t insert end "\n$id"
   13935 	set w .smbwiz.f.t.f4
   13936 	frame $w -bd 1 -relief ridge -cursor {top_left_arrow}
   13937 	set wf .smbwiz.f.t.f4.f
   13938 	frame $wf
   13939 	label $wf.l -text "SMB Hosts:  "  -anchor w
   13940 	entry $wf.e -textvariable smb_host_list -width 60
   13941 	button $wf.b -text "Apply" -command {make_share_widgets .smbwiz.f.t.f3}
   13942 	bind $wf.e <Return> "$wf.b invoke"
   13943 	pack $wf.l $wf.e $wf.b -side left
   13944 	pack $wf
   13945 	pack $w
   13946 
   13947 	.smbwiz.f.t window create end -window $w
   13948 
   13949 	.smbwiz.f.t insert end "\n$id"
   13950 
   13951 	set w .smbwiz.f.t.f5
   13952 	frame $w -bd 1 -relief ridge -cursor {top_left_arrow}
   13953 	set wf .smbwiz.f.t.f5.f
   13954 	frame $wf
   13955 	label $wf.l -text "Mount Prefix:"  -anchor w
   13956 	entry $wf.e -textvariable smb_mount_prefix -width 60
   13957 	button $wf.b -text "Apply" -command {apply_mount_point_prefix .smbwiz.f.t.f5.f.e}
   13958 	bind $wf.e <Return> "$wf.b invoke"
   13959 	pack $wf.l $wf.e $wf.b -side left
   13960 	pack $wf
   13961 	pack $w
   13962 
   13963 	.smbwiz.f.t window create end -window $w
   13964 
   13965 	.smbwiz.f.t insert end "\n\n\n"
   13966 
   13967 	.smbwiz.f.t see 1.0
   13968 	.smbwiz.f.t configure -state disabled
   13969 	update
   13970 
   13971 	vwait smb_wiz_done
   13972 	catch {destroy .smbwiz}
   13973 
   13974 	if {! $smbmount_exists || $smbmount_sumode == "dontknow"} {
   13975 		tk_messageBox -type ok -parent .oa -icon warning -message "Sorry we couldn't help out!\n'smbmount' info on the remote system is required for SMB mounting" -title "SMB mounting -- aborting"
   13976 		global use_smbmnt
   13977 		set use_smbmnt 0
   13978 		catch {raise .oa}
   13979 		return
   13980 	}
   13981 	global smb_su_mode
   13982 	set smb_su_mode $smbmount_sumode
   13983 
   13984 	set max 0
   13985 	foreach en [array names smb_selected_en] {
   13986 		set i $smb_selected_en($en)
   13987 		set host $smb_selected_host($i)
   13988 		set name $smb_selected_name($i)
   13989 
   13990 		set len [string length "//$host/$name"]
   13991 		if {$len > $max} {
   13992 			set max $len
   13993 		}
   13994 	}
   13995 
   13996 	set max [expr $max + 8]
   13997 
   13998 	set strs ""
   13999 	foreach en [array names smb_selected_en] {
   14000 		set i $smb_selected_en($en)
   14001 		if {! $smb_selected($i)} {
   14002 			continue
   14003 		}
   14004 		set host $smb_selected_host($i)
   14005 		set name $smb_selected_name($i)
   14006 		set mnt $smb_selected_mnt($i)
   14007 
   14008 		set share "//$host/$name"
   14009 		set share [format "%-${max}s" $share]
   14010 
   14011 		lappend strs "$share $mnt"
   14012 	}
   14013 	set text ""
   14014 	foreach str [lsort $strs] {
   14015 		append text "$str\n"
   14016 	}
   14017 
   14018 	global smb_mount_list
   14019 	set smb_mount_list $text
   14020 
   14021 	smb_dialog
   14022 }
   14023 
   14024 proc apply_mount_point_prefix {w} {
   14025 	global smb_selected_host smb_selected_name
   14026 	global smb_selected_en smb_selected_mnt
   14027 
   14028 	set prefix ""
   14029 	catch {set prefix [$w get]}
   14030 	if {$prefix == ""} {
   14031 		mesg "No mount prefix."
   14032 		bell
   14033 		return
   14034 	}
   14035 
   14036 	foreach en [array names smb_selected_en] {
   14037 		set i $smb_selected_en($en)
   14038 		set host $smb_selected_host($i)
   14039 		set name $smb_selected_name($i)
   14040 		set smb_selected_mnt($i) "$prefix/$host/$name"
   14041 	}
   14042 }
   14043 
   14044 proc smb_dialog {} {
   14045 	toplev .smb
   14046 	wm title .smb "SMB Filesystem Tunnelling"
   14047 	global smb_su_mode smb_mount_list
   14048 	global use_smbmnt
   14049 
   14050 	global help_font
   14051 
   14052 	global uname
   14053 	set h 33
   14054 	if [small_height] {
   14055 		set h 17
   14056 	} elseif {$uname == "Darwin"} {
   14057 		set h 24
   14058 	}
   14059 	scroll_text .smb.f 80 $h
   14060 
   14061 	set msg {
   14062     Windows/Samba Filesystem mounting requires SSH be used to set up the SMB
   14063     service port redirection.  This will be either of the "Use SSH" or
   14064     "SSH+SSL" modes. NOTE: For pure SSL tunnelling it currently will not work.
   14065 
   14066     This method requires a working Samba software setup on the remote
   14067     side of the connection (VNC server) and existing Samba or Windows file
   14068     server(s) on the local side (VNC viewer).
   14069 
   14070     The smbmount(8) program MUST be installed on the remote side. This
   14071     evidently limits the mounting to Linux systems.  Let us know of similar
   14072     utilities on other Unixes.  Mounting onto remote Windows machines is
   14073     currently not supported (our SSH mode with services setup only works
   14074     to Unix).  On Debian and Ubuntu the smbmount program is currently in
   14075     the package named 'smbfs'.
   14076 
   14077     Depending on how smbmount is configured you may be able to run it
   14078     as a regular user, or it may require running under su(1) or sudo(8)
   14079     (root password or user password required, respectively).  You select
   14080     which one you want via the checkbuttons below.
   14081 
   14082     In addition to a possible su(1) or sudo(8) password, you may ALSO
   14083     need to supply passwords to mount each SMB share. This is an SMB passwd.
   14084     If it has no password just hit enter after the "Password:" prompt.
   14085 
   14086     The passwords are supplied when the 1st SSH connection starts up;
   14087     be prepared to respond to them.
   14088 
   14089     NOTE: USE OF SMB TUNNELLING MODE WILL REQUIRE TWO SSH'S, AND SO YOU
   14090     MAY NEED TO SUPPLY TWO LOGIN PASSWORDS UNLESS YOU ARE USING SOMETHING
   14091     LIKE ssh-agent(1) or the Putty PW setting.
   14092     %WIN
   14093 
   14094     To indicate the Windows/Samba shares to mount enter them one per line
   14095     in one of the forms:
   14096 
   14097       //machine1/share   ~/Desktop/my-mount1
   14098       //machine2/fubar   /var/tmp/my-foobar2  192.168.100.53:3456
   14099       1139  //machine3/baz  /var/tmp/baz      [...]
   14100 
   14101     The first part is the standard SMB host and share name //hostname/dir
   14102     (note this share is on the local viewer-side not on the remote end).
   14103     A leading '#' will cause the entire line to be skipped.
   14104 
   14105     The second part, e.g. /var/tmp/my-foobar2, is the directory to mount
   14106     the share on the remote (VNC Server) side.  You must be able to
   14107     write to this directory.  It will be created if it does not exist.
   14108     A leading character ~ will be expanded to $HOME.  So will the string
   14109     %HOME.  The string %USER will get expanded to the remote username.
   14110 
   14111     An optional part like 192.168.100.53:3456 is used to specify the real
   14112     hostname or IP address, and possible non-standard port, on the local
   14113     side if for some reason the //hostname is not sufficient.
   14114 
   14115     An optional leading numerical value, 1139 in the above example, indicates
   14116     which port to use on the Remote side to SSH redirect to the local side.
   14117     Otherwise a random one is tried (a unique one is needed for each SMB
   14118     server:port combination).  A fixed one is preferred: choose a free
   14119     remote port.
   14120 
   14121     The standard SMB service ports (local side) are 445 and 139.  139 is
   14122     used by this application.
   14123 
   14124     Sometimes "localhost" will not work on Windows machines for a share
   14125     hostname, and you will have to specify a different network interface
   14126     (e.g. the machine's IP address).  If you use the literal string "IP"
   14127     it will be attempted to replace it with the numerical IP address, e.g.:
   14128 
   14129       //machine1/share   ~/Desktop/my-mount1   IP
   14130 
   14131     VERY IMPORTANT: Before terminating the VNC Connection, make sure no
   14132     applications are using any of the SMB shares (or shells are cd-ed
   14133     into the share).  This way the shares will be automatically unmounted.
   14134     Otherwise you will need to log in again, stop processes from using
   14135     the share, become root and umount the shares manually ("smbumount
   14136     /path/to/share", etc.)
   14137 
   14138     For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-smb-shares
   14139 }
   14140 
   14141 	set msg2 {
   14142     To speed up moving to the next step, iconify the first SSH console
   14143     when you are done entering passwords, etc. and then click on the
   14144     main panel 'VNC Host:Display' label.
   14145 }
   14146 
   14147 	global is_windows
   14148 	if {! $is_windows} {
   14149 		regsub { *%WIN} $msg "" msg
   14150 	} else {
   14151 		set msg2 [string trim $msg2]
   14152 		regsub { *%WIN} $msg "    $msg2" msg
   14153 	}
   14154 	.smb.f.t insert end $msg
   14155 
   14156 	frame .smb.r
   14157 	label .smb.r.l -text "smbmount(8) auth mode:" -relief ridge
   14158 	radiobutton .smb.r.none -text "None" -variable smb_su_mode -value "none"
   14159 	radiobutton .smb.r.su   -text "su(1)" -variable smb_su_mode -value "su"
   14160 	radiobutton .smb.r.sudo -text "sudo(8)" -variable smb_su_mode -value "sudo"
   14161 
   14162 	pack .smb.r.l .smb.r.none .smb.r.sudo .smb.r.su -side left -fill x
   14163 
   14164 	label .smb.info -text "Supply the mounts (one per line) below:" -anchor w -relief ridge
   14165 
   14166 	eval text .smb.mnts -width 80 -height 5 $help_font
   14167 	.smb.mnts insert end $smb_mount_list
   14168 
   14169 	button .smb.guess -text "Help me decide ..." -command {destroy .smb; smb_help_me_decide}
   14170 
   14171 	button .smb.cancel -text "Cancel" -command {set use_smbmnt 0; destroy .smb}
   14172 	bind .smb <Escape> {set use_smbmnt 0; destroy .smb}
   14173 	wm protocol .smb WM_DELETE_WINDOW {set use_smbmnt 0; destroy .smb}
   14174 	button .smb.done -text "Done" -command {if {$use_smbmnt} {set_ssh; set smb_mount_list [.smb.mnts get 1.0 end]}; destroy .smb}
   14175 
   14176 	pack .smb.done .smb.cancel .smb.guess .smb.mnts .smb.info .smb.r -side bottom -fill x
   14177 	pack .smb.f -side top -fill both -expand 1
   14178 
   14179 	center_win .smb
   14180 }
   14181 
   14182 proc help_advanced_opts {} {
   14183 	toplev .ah
   14184 
   14185 	scroll_text_dismiss .ah.f
   14186 
   14187 	center_win .ah
   14188 
   14189 	wm title .ah "Advanced Options Help"
   14190 
   14191 	set msg {
   14192     These Advanced Options that may require extra software installed on
   14193     the VNC server-side (the remote server machine) and/or on the VNC
   14194     client-side (where this gui is running).
   14195 
   14196     The Service redirection options, CUPS, ESD/ARTSD, and SMB will
   14197     require that you use SSH for tunneling so that they can use the -R
   14198     port redirection will be enabled for each service.  I.e. "Use SSH"
   14199     or "SSH + SSL" mode.
   14200 
   14201     These options may also require additional configuration to get them
   14202     to work properly.  Please submit bug reports if it appears it should
   14203     be working for your setup but is not.
   14204 
   14205     Brief (and some not so brief) descriptions:
   14206 
   14207       CUPS Print tunnelling:
   14208 
   14209          Redirect localhost:6631 (say) on the VNC server to your local
   14210          CUPS server.  SSH mode is required.
   14211 
   14212       ESD/ARTSD Audio tunnelling:
   14213 
   14214          Redirect localhost:16001 (say) on the VNC server to your local
   14215          ESD, etc. sound server.  SSH mode is required.
   14216 
   14217       SMB mount tunnelling:
   14218 
   14219          Redirect localhost:1139 (say) on the VNC server and through that
   14220          mount SMB file shares from your local server.  The remote machine
   14221          must be Linux with smbmount installed. SSH mode is required.
   14222 
   14223       Additional Port Redirs (via SSH):
   14224 
   14225          Specify additional -L port:host:port and -R port:host:port
   14226          cmdline options for SSH to enable additional services.
   14227          SSH mode is required.
   14228 
   14229       Automatically Find X Login/Greeter:
   14230 
   14231          This mode is similar to "Automatically Find X Session" except
   14232          that it will attach to a X Login/Greeter screen that no one
   14233          has logged into yet.  It requires root privileges via sudo(1)
   14234          on the remote machine.  SSH mode is required.
   14235 
   14236          As with "Automatically Find X Session" it works only with SSH
   14237          mode and requires x11vnc be installed on the remote computer.
   14238 
   14239          It simply sets the Remote SSH Command to:
   14240 
   14241               PORT= sudo x11vnc -find -localhost -env FD_XDM=1
   14242 
   14243          An initial ssh running 'sudo id' is performed to try to
   14244          'prime' sudo so the 2nd one that runs x11vnc does not need
   14245          a password.  This may not always succeed... please mail us
   14246          the details if it doesn't.
   14247 
   14248          See the 'X Login' description in 'Terminal Services' Mode
   14249          Help for more info.
   14250 
   14251       Private SSH KnownHosts file:
   14252 
   14253          On Unix in SSH mode, let the user specify a non-default
   14254          ssh known_hosts file to be used only by the current profile.
   14255          This is the UserKnownHostsFile ssh option and is described in the
   14256          ssh_config(1) man page.  This is useful to avoid proxy 'localhost'
   14257          SSH key collisions.
   14258 
   14259          Normally one should simply let ssh use its default file
   14260          ~/.ssh/known_hosts for tracking SSH keys.  The only problem that
   14261          happens is when multiple SSVNC connections use localhost tunnel
   14262          port redirections.  These make ssh connect to 'localhost' on some
   14263          port (where the proxy is listening.)  Then the different keys
   14264          from the multiple ssh servers collide when ssh saves them under
   14265          'localhost' in ~/.ssh/known_hosts.
   14266 
   14267          So if you are using a proxy with SSVNC or doing a "double SSH
   14268          gateway" your ssh will connect to a proxy port on localhost, and you
   14269          should set a private KnownHosts file for that connection profile.
   14270          This is secure and avoids man-in-the-middle attack (as long as
   14271          you actually verify the initial save of the SSH key!)
   14272 
   14273          The default file location will be:
   14274 
   14275                   ~/.vnc/ssh_known_hosts/profile-name.known
   14276 
   14277          but you can choose any place you like.  It must of course be
   14278          unique and not shared with another ssh connection otherwise they
   14279          both may complain about the key for 'localhost' changing, etc.
   14280 
   14281       SSH Local Port Protections:
   14282 
   14283          An LD_PRELOAD hack to limit the number of SSH port redirections
   14284          to 1 and within the first 35 seconds.  So there is a smaller
   14285          window when the user can try to use your tunnel compared to
   14286          the duration of your session.  SSH mode is required.
   14287 
   14288       STUNNEL Local Port Protections:
   14289 
   14290          Try to prevent Untrusted Local Users (see the main Help panel)
   14291          from using your STUNNEL tunnel to connect to the remote VNC
   14292          Server.
   14293 
   14294       Change VNC Viewer:
   14295 
   14296          Specify a non-bundled VNC Viewer (e.g.  UltraVNC or RealVNC)
   14297          to run instead of the bundled TightVNC Viewer.
   14298 
   14299       Port Knocking:
   14300 
   14301          For "closed port" services, first "knock" on the firewall ports
   14302          in a certain way to open the door for SSH or SSL.  The port
   14303          can also be closed when the encrypted VNC connection finishes.
   14304 
   14305       UltraVNC DSM Encryption Plugin:
   14306 
   14307          On Unix only, by using the supplied tool, ultravnc_dsm_helper,
   14308          encrypted connections to UltraVNC servers using their plugins
   14309          is enabled.  Support for secret key encryption to Non-UltraVNC
   14310          DSM servers is also supported, e.g. x11vnc -enc blowfish:my.key
   14311 
   14312       Do not Probe for VeNCrypt:
   14313 
   14314          Disable VeNCrypt auto-detection probe when not needed.
   14315 
   14316          By default in SSL mode an initial probe for the use of the
   14317          VeNCrypt or ANONTLS protocol is performed.  This is done
   14318          during the initial fetch-cert action.  Once auto-detected in
   14319          the initial probe, the real connection to the VNC Server will
   14320          use this information to switch to SSL/TLS at the right point in
   14321          the VeNCrypt/ANONTLS handshake.
   14322 
   14323          In "Verify All Certs" mode initial the fetch-cert action is
   14324          required so the automatic probing for VeNCrypt is always done.
   14325          The fetch-cert is not needed if you specified a ServerCert or if
   14326          you disabled "Verify All Certs".  But by default the fetch-cert
   14327          is done anyway to try to auto-detect VeNCrypt/ANONTLS.
   14328 
   14329          Set 'Do not Probe for VeNCrypt' to skip this unneeded fetch-cert
   14330          action (and hence speed up connecting.)  Use this if you
   14331          know the VNC Server uses normal SSL and not VeNCrypt/ANONTLS.
   14332 
   14333          See also the next option, 'Server uses VeNCrypt SSL encryption'
   14334          to if you know it uses VeNCrypt/ANONTLS (the probing will also
   14335          be skipped if that option is set.)
   14336 
   14337       Server uses VeNCrypt SSL encryption:
   14338 
   14339          Indicate that the VNC server uses the VeNCrypt extension to VNC;
   14340          it switches to an SSL/TLS tunnel at a certain point in the
   14341          VNC Handshake.  This is in constrast to the default ssvnc/x11vnc
   14342          SSL tunnel behavior where the *entire* VNC traffic goes through
   14343          SSL (i.e. it is vncs:// in the way https:// uses SSL)
   14344 
   14345          Enable this option if you know the server supports VeNCrypt.
   14346          Also use this option for the older ANONTLS extension (vino).
   14347          Doing so will give the quickest and most reliable connection
   14348          to VeNCrypt/ANONTLS servers.  If set, any probing to try to
   14349          auto-detect VeNCrypt/ANONTLS will be skipped.
   14350 
   14351          Some VNC servers supporting VeNCrypt: VeNCrypt, QEMU, ggi,
   14352          virt-manager, and Xen.  Vino supports ANONTLS.
   14353 
   14354          The SSVNC VeNCrypt/ANONTLS support even works with 3rd party
   14355          VNC Viewers you specify via 'Change VNC Viewer' (e.g. RealVNC,
   14356          TightVNC, UltraVNC etc.) that do not directly support it.
   14357 
   14358          Note: many VeNCrypt servers only support Anonymous Diffie Hellman
   14359          TLS which has NO built in authentication and you will also need
   14360          to set the option described in the next section.
   14361 
   14362          If you are using VeNCrypt or ANONTLS for REVERSE connections
   14363          (Listen) then you *MUST* set this 'Server uses VeNCrypt SSL
   14364          encryption' option.   Note also that REVERSE connections using
   14365          VeNCrypt/ANONTLS currently do not work on Windows.
   14366 
   14367          Also, if you are using the "Use SSH+SSL" double tunnel to a
   14368          VeNCrypt/ANONTLS server, you MUST set 'Server uses VeNCrypt
   14369          SSL encryption' because "Verify All Certs" is disabled in
   14370          SSH+SSL mode.
   14371 
   14372       Server uses Anonymous Diffie-Hellman
   14373 
   14374          Anonymous Diffie-Hellman can be used for SSL/TLS connections but
   14375          there are no Certificates for authentication.  Therefore only
   14376          passive eavesdropping attacks are prevented, not Man-In-The-Middle
   14377          attacks.  Not recommended; try to use verified X509 certs instead.
   14378 
   14379          Enable this option if you know the server only supports Anon DH.
   14380          When you do so, remember that ALL Certificate checking will be
   14381          skipped (even if you have 'Verify All Certs' selected or set
   14382          a ServerCert.)
   14383 
   14384          SSVNC may be able to autodetect Anon DH even if you haven't
   14385          selected 'Server uses Anonymous Diffie-Hellman'. Once detected, it
   14386          will prompt you whether it should continue.  Set the 'Server uses
   14387          Anonymous Diffie-Hellman' option to avoid trying autodetection
   14388          (i.e. forcing the issue.)
   14389 
   14390          Note that most Anonymous Diffie-Hellman VNC Servers do so
   14391          via the VeNCrypt or ANONTLS VNC extensions (see the previous
   14392          section.)  For these servers if you select 'Server uses Anonymous
   14393          Diffie-Hellman' you *MUST* ALSO select 'Server uses VeNCrypt SSL
   14394          encryption', otherwise SSVNC may have no chance to auto-detect
   14395          the VeNCrypt/ANONTLS protocol.
   14396 
   14397          Also note, if you are using the "Use SSH+SSL" double tunnel to
   14398          a VeNCrypt/ANONTLS server using Anon DH you MUST set 'Server
   14399          uses Anonymous Diffie-Hellman' because "Verify All Certs"
   14400          is disabled in SSH+SSL mode.
   14401 
   14402       Include:
   14403 
   14404        Default settings and Include Templates:
   14405 
   14406          Before explaining how Include works, first note that if you
   14407          do not prefer some of SSVNC's default settings you can start
   14408          up SSVNC and then change the settings for the options that you
   14409          want to have a different default value.  Then type "defaults"
   14410          in VNC Host:Display entry box and press "Save" to save them in
   14411          the "defaults.vnc" profile.  After this, SSVNC will initialize
   14412          all of the default values and then apply your override values
   14413          in "defaults".
   14414 
   14415          For example, suppose you always want to use a different, 3rd
   14416          party VNC Viewer.  Set Options -> Advanced -> Change VNC Viewer
   14417          to what you want, and then save it as the "defaults" profile.
   14418          Now that default setting will apply to all profiles, and SSVNC
   14419          in its startup state.
   14420 
   14421          To edit the defaults Load it, make changes, and then Save it.
   14422          Delete the "defaults" profile to go back to no modifications.
   14423          Note that defaults created and saved while defaults.vnc existed
   14424          will NOT be automatically adjusted.
   14425 
   14426        Include Templates:
   14427 
   14428          Now suppose you have a certain class of settings that you do
   14429          not want to always be applied, but you want them to apply to a
   14430          group of profiles.
   14431 
   14432          For example, suppose you have some settings for very low
   14433          bandwidth connections (e.g. low color modes and/or aggressive
   14434          compression and quality settings.)  Set these values in SSVNC
   14435          and then in the VNC Host:Display entry box type in, say,
   14436          "slowlink" and then press Save.  This will save those settings
   14437          in the template profile named "slowlink.vnc".
   14438 
   14439          Now to create a real profile that uses this template type the
   14440          host:disp in "VNC Host:Display" and in Options -> Advanced
   14441          -> Includes type in "slowlink".  Then press Save to save the
   14442          host profile.  Then re-Load it.  The "slowlink" settings will
   14443          be applied after the defaults.  Make any other changes to the
   14444          setting for this profile and Save it again.  Next time you load
   14445          it in, the Include template settings will override the defaults
   14446          and then the profile itself is read in.
   14447 
   14448          You may supply a comma or space separated list of templates
   14449          to include.  They are applied in the order listed.  They can be
   14450          full path names or basenames relative to the profiles directory.
   14451          You do not need to supply the .vnc suffix.  The non-default
   14452          settings in them will be applied first, and then any values in
   14453          the loaded Profile will override them.
   14454 
   14455       Sleep:
   14456 
   14457          Enter a number to indicate how many extra seconds to sleep
   14458          while waiting for the VNC viewer to start up.  On Windows this
   14459          can give extra time to enter the Putty/Plink password, etc.
   14460 
   14461       Putty Args:
   14462 
   14463          Windows only, supply a string to be added to all plink.exe
   14464          and putty.exe commands.  Example: -i C:\mykey.ppk
   14465 
   14466       Launch Putty Pagent:
   14467 
   14468          Windows only, launch the Putty key agent tool (pageant) to hold
   14469          your SSH private keys for automatic logging in by putty/plink.
   14470 
   14471       Launch Putty Key-Gen:
   14472 
   14473          Windows only, launch the Putty key generation tool (puttygen)
   14474          to create new SSH private keys.
   14475 
   14476       Unix ssvncviewer:
   14477 
   14478          Display a popup menu with options that apply to the special
   14479          Unix SSVNC VNC Viewer (perhaps called 'ssvncviewer') provided by
   14480          this SSVNC package.  This only applies to Unix or Mac OS X.
   14481 
   14482       Use ssh-agent:
   14483 
   14484          On Unix only: restart the GUI in the presence of ssh-agent(1)
   14485          (e.g. in case you forgot to start your agent before starting
   14486          this GUI).  An xterm will be used to enter passphrases, etc.
   14487          This can avoid repeatedly entering passphrases for the SSH logins
   14488          (note this requires setting up and distributing SSH keys).
   14489 
   14490 
   14491     About the CheckButtons:
   14492 
   14493          Ahem, Well...., yes quite a klunky UI: you have to toggle the
   14494          CheckButton to pull up the Dialog box a 2nd, etc. time... don't
   14495          worry your settings will still be there!
   14496 }
   14497 
   14498 	.ah.f.t insert end $msg
   14499 	jiggle_text .ah.f.t
   14500 }
   14501 
   14502 proc help_ssvncviewer_opts {} {
   14503 	toplev .av
   14504 
   14505 	scroll_text_dismiss .av.f
   14506 
   14507 	center_win .av
   14508 
   14509 	wm title .av "Unix SSVNC viewer Options Help"
   14510 
   14511 	set msg {
   14512     These Unix SSVNC VNC Viewer Options apply only on Unix or Mac OS X
   14513     when using the viewer (ssvncviewer) supplied by this SSVNC package.
   14514 
   14515     Brief descriptions:
   14516 
   14517       Multiple LISTEN Connections:
   14518 
   14519          Allow multiple VNC servers to reverse connect at the same time
   14520          and so display each of their desktops on your screen at the
   14521          same time.
   14522 
   14523       Listen Once:
   14524 
   14525          Try to have the VNC Viewer exit after the first listening
   14526          connection. (It may not always be detected; use Ctrl-C to exit)
   14527 
   14528       Listen Accept Popup Dialog:
   14529 
   14530          In -listen (reverse connection listening) mode when a reverse
   14531          VNC connection comes in show a popup asking whether to Accept
   14532          or Reject the connection. (-acceptpopup vncviewer option.)
   14533 
   14534       Accept Popup UltraVNC Single Click:
   14535 
   14536          As in 'Listen Accept Popup Dialog', except assume the remote
   14537          VNC server is UltraVNC Single Click and force the execution of
   14538          the protocol to retrieve the extra remote-side info (Windows
   14539          User, ComputerName, etc) which is then also displayed in the
   14540          Popup window. (-acceptpopupsc vncviewer option.)
   14541 
   14542       Use X11 Cursor:
   14543 
   14544          When drawing the mouse cursor shape locally, use an X11 cursor
   14545          instead of drawing it directly into the framebuffer.  This
   14546          can sometimes give better response, and avoid problems under
   14547          'Scaling'.
   14548 
   14549       Disable Bell:
   14550 
   14551          Disable beeps coming from remote side.
   14552 
   14553       Use Raw Local:
   14554 
   14555          Use the VNC Raw encoding for 'localhost' connections (instead
   14556          of assuming there is a local tunnel, SSL or SSH, going to the
   14557          remote machine.
   14558 
   14559       Avoid Using Terminal:
   14560 
   14561          By default the Unix ssvncviewer will prompt for usernames,
   14562          passwords, etc. in the terminal it is running inside of.
   14563          Set this option to use windows for messages and prompting as
   14564          much as possible.  Messages will also go to the terminal, but
   14565          all prompts will be done via popup window.
   14566 
   14567          Note that stunnel(1) may prompt for a passphrase to unlock a
   14568          private SSL key.  This is fairly rare because it is usually
   14569          for Client-side SSL authentication.  stunnel will prompt from
   14570          the terminal; there seems to be no way around this.
   14571 
   14572          Also, note that ssh(1) may prompt for an ssh key passphrase
   14573          or Unix password.  This can be avoided in a number of ways,
   14574          the simplest one is to use ssh-agent(1) and ssh-add(1).
   14575          However ssh(1) may also prompt you to accept a new public key
   14576          for a host or warn you if the key has changed, etc.
   14577 
   14578       Use Popup Fix:
   14579 
   14580          Enable a fix that warps the popup (F8) to the mouse pointer.
   14581 
   14582       Use XGrabServer (for fullscreen):
   14583 
   14584          On Unix only, use the XGrabServer workaround for older window
   14585          managers.  Sometimes also needed on recent (2008) GNOME.  This
   14586          workaround can make going into/out-of Fullscreen work better.
   14587 
   14588       Cursor Alphablending:
   14589 
   14590          Use the x11vnc alpha hack for translucent cursors (requires Unix,
   14591          32bpp and same endianness)
   14592 
   14593       TurboVNC:
   14594 
   14595          If available on your platform, use a ssvncviewer compiled with
   14596          TurboVNC support.  This is based on the VirtualGL project:
   14597          http://www.sourceforge.net/projects/virtualgl	You will need
   14598          to install the VirtualGL's TurboJPEG library too.
   14599 
   14600          Currently (May/2009) only Linux.i686, Linux.x86_64, and
   14601          Darwin.i386 have vncviewer.turbovnc binaries shipped in the
   14602          ssvnc bundles.  See the build instructions for how you might
   14603          compile your own.
   14604 
   14605       Disable Pipelined Updates:
   14606 
   14607          Disable the TurboVNC-like pipelined updates mode.  Pipelined
   14608          updates is the default even when not TurboVNC enabled.  They
   14609          ask for the next screen update before the current one has
   14610          finished downloading, and so this might reduce the slowdown
   14611          due to high latency or low bandwidth by 2X or so.  Disable
   14612          them if they cause problems with the remote VNC Server or
   14613          use too much bandwidth.
   14614 
   14615       Send CLIPBOARD not PRIMARY:
   14616 
   14617          When sending locally selected text to the VNC server side,
   14618          send the CLIPBOARD selection instead of the PRIMARY selection.
   14619 
   14620       Send Selection Every time:
   14621 
   14622          Send selected text to the VNC server side every time the mouse
   14623          focus enters the main VNC Viewer window instead only when it
   14624          appears to have changed since the last send.
   14625 
   14626       Scaling:
   14627 
   14628          Use viewer-side (i.e. local) scaling of the VNC screen.  Supply
   14629          a fraction, e.g. 0.75 or 3/4, or a WxH geometry, e.g. 1280x1024,
   14630          or the string 'fit' to fill the current screen.  Use 'auto'
   14631          to scale the desktop to match the viewer window size.
   14632 
   14633          If you observe mouse trail painting errors try using X11 Cursor.
   14634 
   14635          Note that since the local scaling is done in software it can
   14636          be slow.  Since ZRLE is better than Tight in this regard, when
   14637          scaling is detected, the encoding will be switched to ZRLE.
   14638          Use the Popup to go back to Tight if you want to, or set the
   14639          env. var. SSVNC_PRESERVE_ENCODING=1 to disable the switch.
   14640 
   14641          For additional speedups under local scaling: try having a solid
   14642          desktop background on the remote side (either manually or using
   14643          'x11vnc -solid ...'); and also consider using client side caching
   14644          'x11vnc -ncache 10 ...' if the remote server is x11vnc.
   14645 
   14646       Escape Keys:
   14647 
   14648          Enable 'Escape Keys', a set of modifier keys that, if all are
   14649          pressed down, enable local Hot Key actions.  Set to 'default'
   14650          to use the default (Alt_L,Super_L on unix, Control_L,Meta_L
   14651          on macosx) or set to a list of modifier keys.
   14652 
   14653       Y Crop:
   14654 
   14655          This is for x11vnc's -ncache client side caching scheme with our
   14656          Unix TightVNC viewer.  Sets the Y value to "crop" the viewer
   14657          size at (below the cut is the pixel cache region you do not
   14658          want to see).  If the screen is tall (H > 2*W) ycropping will
   14659          be autodetected, or you can set to -1 to force autodection.
   14660          Otherwise, set it to the desired Y value.  You can also set
   14661          the scrollbar width (very thin by default) by appending ",sb=N"
   14662          (or use ",sb=N" by itself to just set the scrollbar width).
   14663 
   14664       ScrollBar Width:
   14665 
   14666          This is for x11vnc's -ncache client side caching scheme with our
   14667          Unix TightVNC viewer.  For Y-Crop mode, set the size of the
   14668          scrollbars (often one want it to be very narrow, e.g. 2 pixels
   14669          to be less distracting.
   14670 
   14671       RFB Version:
   14672 
   14673          Set the numerical version of RFB (VNC) protocol to pretend to
   14674          be, 3.x.  Usually only needed with UltraVNC servers.
   14675 
   14676       Encodings:
   14677 
   14678          List encodings in preferred order, for example
   14679          'copyrect zrle tight'   The list of encodings is:
   14680          copyrect tight zrle zywrle hextile zlib corre rre raw
   14681 
   14682       Extra Options:
   14683 
   14684          String of extra Unix ssvncviewer command line options.  I.e. for
   14685          ones like -16bpp that cannot be set inside this SSVNC GUI.  For a
   14686          list click Help then 'SSVNC vncviewer -help Output'.
   14687 
   14688 
   14689     These are environment variables one may set to affect the options
   14690     of the SSVNC vncviewer and also the ss_vncviewer wrapper script
   14691     (and hence may apply to 3rd party vncviewers too)
   14692 
   14693          VNCVIEWER_ALPHABLEND     (-alpha, see Cursor Alphablending above)
   14694          VNCVIEWER_POPUP_FIX      (-popupfix, warp popup to mouse location)
   14695          VNCVIEWER_GRAB_SERVER    (-graball, see Use XGrabServer above)
   14696          VNCVIEWER_YCROP          (-ycrop, see Y Crop above)
   14697          VNCVIEWER_SBWIDTH        (-sbwidth, see ScrollBar Width above)
   14698          VNCVIEWER_RFBVERSION     (-rfbversion, e.g. 3.6)
   14699          VNCVIEWER_ENCODINGS      (-encodings, e.g. "copyrect zrle hextile")
   14700          VNCVIEWER_NOBELL         (-nobell)
   14701          VNCVIEWER_X11CURSOR      (-x11cursor, see Use X11 Cursor above)
   14702          VNCVIEWER_RAWLOCAL       (-rawlocal, see Use Raw Local above)
   14703          VNCVIEWER_NOTTY          (-notty, see Avoid Using Terminal above)
   14704          VNCVIEWER_ESCAPE         (-escape, see Escape Keys above)
   14705          VNCVIEWER_ULTRADSM       (-ultradsm)
   14706          VNCVIEWER_PIPELINE_UPDATES (-pipeline, see above)
   14707          VNCVIEWER_SEND_CLIPBOARD (-sendclipboard)
   14708          VNCVIEWER_SEND_ALWAYS    (-sendalways)
   14709          VNCVIEWER_RECV_TEXT      (-recvtext clipboard/primary/both)
   14710          VNCVIEWER_NO_CUTBUFFER   (do not send CUTBUFFER0 as fallback)
   14711          VNCVIEWER_NO_PIPELINE_UPDATES (-nopipeline)
   14712          VNCVIEWER_ALWAYS_RECENTER (set to avoid(?) recentering on resize)
   14713          VNCVIEWER_IS_REALVNC4    (indicate vncviewer is realvnc4 flavor.)
   14714          VNCVIEWER_NO_IPV4        (-noipv4)
   14715          VNCVIEWER_NO_IPV6        (-noipv6)
   14716          VNCVIEWER_FORCE_UP       (force raise on fullscreen graball)
   14717          VNCVIEWER_PASSWORD       (danger: set vnc passwd via env. var.)
   14718          VNCVIEWER_MIN_TITLE      (minimum window title (appshare))
   14719 
   14720          VNCVIEWERCMD             (unix viewer command, default vncviewer)
   14721          VNCVIEWERCMD_OVERRIDE    (force override of VNCVIEWERCMD)
   14722          VNCVIEWERCMD_EXTRA_OPTS  (extra options to pass to VNCVIEWERCMD)
   14723          VNCVIEWER_LISTEN_LOCALHOST (force ssvncviewer to -listen on localhost)
   14724          VNCVIEWER_NO_SEC_TYPE_TIGHT(force ssvncviewer to skip rfbSecTypeTight)
   14725          HEXTILE_YCROP_TOO        (testing: nosync_ycrop for hextile updates.)
   14726 
   14727          SS_DEBUG                 (very verbose debug printout by script.)
   14728          SS_VNCVIEWER_LISTEN_PORT (force listen port.)
   14729          SS_VNCVIEWER_NO_F        (no -f for SSH.)
   14730          SS_VNCVIEWER_NO_T        (no -t for SSH.)
   14731          SS_VNCVIEWER_USE_C       (force -C compression for SSH.)
   14732          SS_VNCVIEWER_SSH_CMD     (override SSH command to run.)
   14733          SS_VNCVIEWER_NO_MAXCONN  (no maxconn for stunnel (obsolete))
   14734          SS_VNCVIEWER_RM          (file containing vnc passwd to remove.)
   14735          SS_VNCVIEWER_SSH_ONLY    (run the SSH command, then exit.)
   14736 
   14737          SSVNC_MULTIPLE_LISTEN    (-multilisten, see Multiple LISTEN above)
   14738          SSVNC_ACCEPT_POPUP       (-acceptpopup, see Accept Popup Dialog)
   14739          SSVNC_ACCEPT_POPUP_SC    (-acceptpopupsc, see Accept Popup Dialog)
   14740          SSVNC_TURBOVNC           (see TurboVNC above)
   14741          SSVNC_UNIXPW             (-unixpw)
   14742          SSVNC_UNIXPW_NOESC       (do not send escape in -unixpw mode)
   14743          SSVNC_SCALE              (-scale, see Scaling above)
   14744          SSVNC_NOSOLID            (do not do solid region speedup in
   14745                                    scaling mode.)
   14746          SSVNC_PRESERVE_ENCODING  (do not switch to ZRLE when scaling)
   14747          SSVNC_FINISH_SLEEP       (on unix/macosx sleep this many seconds
   14748                                    before exiting the terminal, default 5)
   14749 
   14750          Misc (special usage or debugging or ss_vncviewer settings):
   14751 
   14752          SSVNC_MESG_DELAY         (sleep this many millisec between messages)
   14753          SSVNC_NO_ENC_WARN        (do not print out a NO ENCRYPTION warning)
   14754          SSVNC_EXTRA_SLEEP        (same as Sleep: window)
   14755          SSVNC_NO_ULTRA_DSM       (disable ultravnc dsm encryption)
   14756          SSVNC_ULTRA_DSM          (the ultravnc_dsm_helper command)
   14757          SSVNC_ULTRA_FTP_JAR      (file location of ultraftp.jar jar file)
   14758          SSVNC_KNOWN_HOSTS_FILE   (file for per-connection ssh known hosts)
   14759          SSVNC_SCALE_STATS        (print scaling stats)
   14760          SSVNC_NOSOLID            (disable solid special case while scaling)
   14761          SSVNC_DEBUG_RELEASE      (debug printout for keyboard modifiers.)
   14762          SSVNC_DEBUG_ESCAPE_KEYS  (debug printout for escape keys)
   14763          SSVNC_NO_MAYBE_SYNC      (skip XSync() calls in certain painting)
   14764          SSVNC_MAX_LISTEN         (number of time to listen for reverse conn.)
   14765          SSVNC_LISTEN_ONCE        (listen for reverse conn. only once)
   14766          STUNNEL_LISTEN           (stunnel interface for reverse conn.
   14767          SSVNC_NO_MESSAGE_POPUP   (do not place info messages in popup.)
   14768          SSVNC_SET_SECURITY_TYPE  (force VeNCrypt security type)
   14769          SSVNC_PREDIGESTED_HANDSHAKE (string used for VeNCrypt, etc. connect)
   14770          SSVNC_SKIP_RFB_PROTOCOL_VERSION (force viewer to be RFB 3.8)
   14771          SSVNC_DEBUG_SEC_TYPES    (debug security types for VeNCrypt)
   14772          SSVNC_DEBUG_MSLOGON      (extra printout for ultravnc mslogon proto)
   14773          SSVNC_DEBUG_RECTS        (printout debug for RFB rectangles.)
   14774          SSVNC_DEBUG_CHAT         (printout debug info for chat mode.)
   14775          SSVNC_DELAY_SYNC         (faster local drawing delaying XSync)
   14776          SSVNC_DEBUG_SELECTION    (printout debug for selection/clipboard)
   14777          SSVNC_REPEATER           (URL-ish sslrepeater:// thing for UltraVNC)
   14778          SSVNC_VENCRYPT_DEBUG     (debug printout for VeNCrypt mode.)
   14779          SSVNC_VENCRYPT_USERPASS  (force VeNCrypt user:pass)
   14780          SSVNC_STUNNEL_DEBUG      (increase stunnel debugging printout)
   14781          SSVNC_STUNNEL_VERIFY3    (increase stunnel verify from 2 to 3)
   14782          SSVNC_LIM_ACCEPT_PRELOAD (preload library to limit accept(2))
   14783          SSVNC_SOCKS5             (socks5 for x11vnc PORT= mode, default)
   14784          SSVNC_SOCKS4		  (socks4 for x11vnc PORT= mode)
   14785          SSVNC_NO_IPV6_PROXY      (do not setup a ipv6:// proxy)
   14786          SSVNC_NO_IPV6_PROXY_DIRECT (do not setup a ipv6:// proxy unencrypted)
   14787          SSVNC_PORT_IPV6          (x11vnc PORT= mode is to ipv6-only)
   14788          SSVNC_IPV6               (0 to disable ss_vncviewer ipv6 check)
   14789          SSVNC_FETCH_TIMEOUT      (ss_vncviewer cert fetch timeout)
   14790          SSVNC_USE_S_CLIENT       (force cert fetch to be 'openssl s_client')
   14791          SSVNC_SHOWCERT_EXIT_0    (force showcert to exit with success)
   14792          SSVNC_SSH_LOCALHOST_AUTH (force SSH localhost auth check.)
   14793          SSVNC_TEST_SEC_TYPE      (force PPROXY VeNCrypt type; testing)
   14794          SSVNC_TEST_SEC_SUBTYPE   (force PPROXY VeNCrypt subtype; testing)
   14795          SSVNC_EXIT_DEBUG         (testing: prompt to exit at end.)
   14796          SSVNC_UP_DEBUG           (gui user/passwd debug mode.)
   14797          SSVNC_UP_FILE            (gui user/passwd file.)
   14798 
   14799          STUNNEL_EXTRA_OPTS       (extra options for stunnel.)
   14800 
   14801          X11VNC_APPSHARE_DEBUG    (for debugging -appshare mode.)
   14802          NO_X11VNC_APPSHARE       (shift down for escape keys.)
   14803          DEBUG_HandleFileXfer     (ultravnc filexfer)
   14804          DEBUG_RFB_SMSG           (RFB server message debug.)
   14805 }
   14806 
   14807 	.av.f.t insert end $msg
   14808 	button .av.htext -text "SSVNC vncviewer -help Output" -command show_viewer_help
   14809 	pack .av.htext -side bottom -fill x
   14810 	jiggle_text .av.f.t
   14811 }
   14812 
   14813 proc show_viewer_help {} {
   14814 	toplev .vhlp
   14815 
   14816 	set h 35
   14817 	if [small_height] {
   14818 		set h 30
   14819 	}
   14820 	scroll_text_dismiss .vhlp.f 83 $h
   14821 
   14822 	center_win .vhlp
   14823 	wm resizable .vhlp 1 0
   14824 
   14825 	wm title .vhlp "SSVNC vncviewer -help Output"
   14826 
   14827 	set msg "-- No Help Output --"
   14828 	catch {set msg [exec ss_vncviewer -viewerhelp 2>/dev/null]}
   14829 
   14830 	.vhlp.f.t insert end $msg
   14831 	jiggle_text .vhlp.f.t
   14832 }
   14833 
   14834 proc set_viewer_path {} {
   14835 	global change_vncviewer_path
   14836 	unix_dialog_resize .chviewer
   14837 	set change_vncviewer_path [tk_getOpenFile -parent .chviewer]
   14838 	catch {raise .chviewer}
   14839 	update
   14840 }
   14841 
   14842 proc change_vncviewer_dialog {} {
   14843 	global change_vncviewer change_vncviewer_path vncviewer_realvnc4
   14844 	global ts_only
   14845 
   14846 	toplev .chviewer
   14847 	wm title .chviewer "Change VNC Viewer"
   14848 
   14849 	global help_font
   14850 	if {$ts_only} {
   14851 		eval text .chviewer.t -width 90 -height 16 $help_font
   14852 	} else {
   14853 		eval text .chviewer.t -width 90 -height 27 $help_font
   14854 	}
   14855 	apply_bg .chviewer.t
   14856 
   14857 	set msg {
   14858     To use your own VNC Viewer (i.e. one installed by you, not included in this
   14859     package), e.g. UltraVNC or RealVNC, type in the program name, or browse for
   14860     the full path to it.  You can put command line arguments after the program.
   14861 
   14862     Note that due to incompatibilities with respect to command line options
   14863     there may be issues, especially if many command line options are supplied.
   14864     You can specify your own command line options below if you like (and try to
   14865     avoid setting any others in this GUI under "Options").
   14866 
   14867     If the path to the program name has spaces it in, surround it with double quotes:
   14868 
   14869         "C:\Program Files\My Vnc Viewer\VNCVIEWER.EXE"
   14870 
   14871     Make sure the very first character is a quote.  You should quote the command
   14872     even if it is only the command line arguments that need extra protection:
   14873 
   14874         "wine" -- "/home/fred/Program Flies/UltraVNC-1.0.2.exe" /64colors
   14875 
   14876     Since the command line options differ between them greatly, if you know it
   14877     is of the RealVNC 4.x flavor, indicate on the check box. Otherwise we guess.
   14878 
   14879     To have SSVNC act as a general STUNNEL redirector (no VNC) set the viewer to be
   14880     "xmessage OK" or "xmessage <port>" or "sleep n" or "sleep n <port>" (or "NOTEPAD"
   14881     on Windows).  The default listen port is 5930.  The destination is set in "VNC
   14882     Host:Display" (for a remote port less than 200 use the negative of the port value).
   14883 }
   14884 
   14885 	if {$ts_only} {
   14886 		regsub {Note that due(.|\n)*If the} $msg "If the" msg
   14887 		regsub {To have SSVNC act(.|\n)*} $msg "" msg
   14888 	}
   14889 	.chviewer.t insert end $msg
   14890 
   14891 	frame .chviewer.path
   14892 	label .chviewer.path.l -text "VNC Viewer:"
   14893 	entry .chviewer.path.e -width 40 -textvariable change_vncviewer_path
   14894 	button .chviewer.path.b -text "Browse..." -command set_viewer_path
   14895 	checkbutton .chviewer.path.r -anchor w -variable vncviewer_realvnc4 -text \
   14896 		"RealVNC 4.x"
   14897 
   14898 	pack .chviewer.path.l -side left
   14899 	pack .chviewer.path.e -side left -expand 1 -fill x
   14900 	pack .chviewer.path.b -side left
   14901 	pack .chviewer.path.r -side left
   14902 
   14903 	button .chviewer.cancel -text "Cancel" -command {destroy .chviewer; set change_vncviewer 0}
   14904 	bind .chviewer <Escape> {destroy .chviewer; set change_vncviewer 0}
   14905 	wm protocol .chviewer WM_DELETE_WINDOW {destroy .chviewer; set change_vncviewer 0}
   14906 	button .chviewer.done -text "Done" -command {destroy .chviewer; catch {raise .oa}}
   14907 	bind .chviewer.path.e <Return> {destroy .chviewer; catch {raise .oa}}
   14908 
   14909 	pack .chviewer.t .chviewer.path .chviewer.cancel .chviewer.done -side top -fill x
   14910 
   14911 	center_win .chviewer
   14912 	wm resizable .chviewer 1 0
   14913 
   14914 	focus .chviewer.path.e
   14915 }
   14916 
   14917 proc port_redir_dialog {} {
   14918 	global additional_port_redirs additional_port_redirs_list
   14919 
   14920 	toplev .redirs
   14921 	wm title .redirs "Additional Port Redirections (via SSH)"
   14922 
   14923 	global help_font uname
   14924 	set h 35
   14925 	if [small_height] {
   14926 		set h 27
   14927 	}
   14928 	eval text .redirs.t -width 80 -height $h $help_font
   14929 	apply_bg .redirs.t
   14930 
   14931 	set msg {
   14932     Specify any additional SSH port redirections you desire for the
   14933     connection.  Put as many as you want separated by spaces.  These only
   14934     apply to SSH and SSH+SSL connections, they do not apply to Pure SSL
   14935     connections.
   14936 
   14937     -L port1:host:port2  will listen on port1 on the local machine (where
   14938                          you are sitting) and redirect them to port2 on
   14939                          "host".  "host" is relative to the remote side
   14940                          (VNC Server).  Use "localhost" for the remote
   14941                          machine itself.
   14942 
   14943     -R port1:host:port2  will listen on port1 on the remote machine
   14944                          (where the VNC server is running) and redirect
   14945                          them to port2 on "host".  "host" is relative
   14946                          to the local side (where you are sitting).
   14947                          Use "localhost" for this machine.
   14948 
   14949     Perhaps you want a redir to a web server inside an intranet:
   14950 
   14951         -L 8001:web-int:80
   14952 
   14953     Or to redir a remote port to your local SSH daemon:
   14954 
   14955         -R 5022:localhost:22
   14956 
   14957     etc.  There are many interesting possibilities.
   14958 
   14959     Sometimes, especially for Windows Shares, you cannot do a -R redir to
   14960     localhost, but need to supply the IP address of the network interface
   14961     (e.g. by default the Shares do not listen on localhost:139).  As a
   14962     convenience you can do something like -R 1139:IP:139 (for any port
   14963     numbers) and the IP will be attempted to be expanded.  If this fails
   14964     for some reason you will have to use the actual numerical IP address.
   14965 }
   14966 	.redirs.t insert end $msg
   14967 
   14968 	frame .redirs.path
   14969 	label .redirs.path.l -text "Port Redirs:"
   14970 	entry .redirs.path.e -width 40 -textvariable additional_port_redirs_list
   14971 
   14972 	pack .redirs.path.l -side left
   14973 	pack .redirs.path.e -side left -expand 1 -fill x
   14974 
   14975 	button .redirs.cancel -text "Cancel" -command {set additional_port_redirs 0; destroy .redirs}
   14976 	bind .redirs <Escape> {set additional_port_redirs 0; destroy .redirs}
   14977 	wm protocol .redirs WM_DELETE_WINDOW {set additional_port_redirs 0; destroy .redirs}
   14978 	button .redirs.done -text "Done" -command {destroy .redirs}
   14979 
   14980 	pack .redirs.t .redirs.path .redirs.cancel .redirs.done -side top -fill x
   14981 
   14982 	center_win .redirs
   14983 	wm resizable .redirs 1 0
   14984 
   14985 	focus .redirs.path.e
   14986 }
   14987 
   14988 proc stunnel_sec_dialog {} {
   14989 	global stunnel_local_protection
   14990 
   14991 	toplev .stlsec
   14992 	wm title .stlsec "STUNNEL Local Port Protections"
   14993 
   14994 	global help_font uname
   14995 
   14996 	set h 37
   14997 	if [small_height] {
   14998 		set h 26
   14999 	}
   15000 	scroll_text .stlsec.f 82 $h
   15001 
   15002 	apply_bg .stlsec.f
   15003 
   15004 	set msg {
   15005     See the discussion of "Untrusted Local Users" in the main 'Help'
   15006     panel for info about users who are able to log into the workstation
   15007     you run SSVNC on and might try to use your encrypted tunnel to gain
   15008     access to the remote VNC machine.
   15009 
   15010     On Unix, for STUNNEL SSL tunnels we provide two options as extra
   15011     safeguards against untrusted local users.  Both only apply to Unix/MacOSX.
   15012     Note that Both options are *IGNORED* in reverse connection (Listen) mode.
   15013 
   15014     1) The first one 'Use stunnel EXEC mode' (it is mutually exclusive with
   15015        option 2).  For this case the modified SSVNC Unix viewer must be
   15016        used: it execs the stunnel program instead of connecting to it via
   15017        TCP/IP.  Thus there is no localhost listening port involved at all.
   15018 
   15019        This is the best solution for SSL stunnel tunnels, it works well and
   15020        is currently enabled by default.  Disable it if there are problems.
   15021 
   15022     2) The second one 'Use stunnel IDENT check', uses the stunnel(8)
   15023        'ident = username' to use the local identd daemon (IDENT RFC 1413
   15024        http://www.ietf.org/rfc/rfc1413.txt) to check that the locally
   15025        connecting program (the SSVNC vncviewer) is being run by your userid.
   15026        See the stunnel(8) man page for details.
   15027 
   15028        Normally the IDENT check service cannot be trusted much when used
   15029        *remotely* (the remote host may be have installed a modified daemon).
   15030        However when using the IDENT check service *locally* it should be
   15031        reliable.  If not, it means the local machine (where you run SSVNC)
   15032        has already been root compromised and you have a serious problem.
   15033 
   15034        Enabling 'Use stunnel IDENT check' requires a working identd on the
   15035        local machine.  Often it is not installed or enabled (because it is not
   15036        deemed to be useful, etc).  identd is usually run out of the inetd(8)
   15037        super-server.  Even when installed and running it is often configured
   15038        incorrectly.  On a Debian/lenny system we actually found that the
   15039        kernel module 'tcp_diag' needed to be loaded! ('modprobe tcp_diag')
   15040 }
   15041 	.stlsec.f.t insert end $msg
   15042 
   15043 	radiobutton .stlsec.ident -relief ridge -anchor w -variable stunnel_local_protection_type -value "ident" -text "Use stunnel IDENT check"
   15044 	radiobutton .stlsec.exec  -relief ridge -anchor w -variable stunnel_local_protection_type -value "exec"  -text "Use stunnel EXEC mode"
   15045 
   15046 	button .stlsec.cancel -text "Cancel" -command {set stunnel_local_protection 0; destroy .stlsec}
   15047 	bind .stlsec <Escape> {set stunnel_local_protection 0; destroy .stlsec}
   15048 	wm protocol .stlsec WM_DELETE_WINDOW {set stunnel_local_protection 0; destroy .stlsec}
   15049 	button .stlsec.done -text "Done" -command {if {$stunnel_local_protection_type == "none"} {set stunnel_local_protection 0}; destroy .stlsec}
   15050 
   15051 	pack .stlsec.f .stlsec.exec .stlsec.ident .stlsec.cancel .stlsec.done -side top -fill x
   15052 
   15053 	center_win .stlsec
   15054 	wm resizable .stlsec 1 0
   15055 }
   15056 
   15057 proc disable_ssl_workarounds_dialog {} {
   15058 	global disable_ssl_workarounds disable_ssl_workarounds_type
   15059 
   15060 	toplev .sslwrk
   15061 	wm title .sslwrk "Disable SSL Workarounds"
   15062 
   15063 	global help_font uname
   15064 	set h 36
   15065 	if [small_height] {
   15066 		set h 24
   15067 	}
   15068 	scroll_text .sslwrk.f 86 $h
   15069 
   15070 	apply_bg .sslwrk.f
   15071 
   15072 	set msg {
   15073     Some SSL implementations are incomplete or buggy or do not work properly
   15074     with other implementations.  SSVNC uses STUNNEL for its SSL encryption,
   15075     and STUNNEL uses the OpenSSL SSL implementation.
   15076 
   15077     This causes some problems with non-OpenSSL implementations on the VNC server
   15078     side.  The most noticable one is the UltraVNC Single Click III (SSL) server:
   15079 
   15080        http://www.uvnc.com/pchelpware/SCIII/index.html
   15081 
   15082     It can make a reverse connection to SSVNC via an encrypted SSL tunnel.
   15083 
   15084     Unfortunately, in the default operation with STUNNEL the connection will be
   15085     dropped after 2-15 minutes due to an unexpected packet.
   15086 
   15087     Because of this, by default SSVNC will enable some SSL workarounds to make
   15088     connections like these work.  This is the STUNNEL 'options = ALL' setting:
   15089     it enables a basic set of SSL workarounds.
   15090 
   15091     You can read all about these workarounds in the stunnel(8) manpage and the
   15092     OpenSSL SSL_CTX_set_options(3) manpage.
   15093 
   15094     Why are we mentioning this?  STUNNELS's 'options = ALL' lowers the SSL
   15095     security a little bit.  If you know you do not have an incompatible SSL
   15096     implementation on the server side (e.g. any one using OpenSSL is compatible,
   15097     x11vnc in particular), then you can regain that little bit of security by
   15098     selecting the "Disable SSL Workarounds" option.
   15099 
   15100     "Disable All SSL Workarounds" selected below will do that.  On the other hand,
   15101     choose "Keep the DONT_INSERT_EMPTY_FRAGMENTS Workaround" to retain that one,
   15102     commonly needed workaround.
   15103 
   15104     BTW, you can set the environment variable STUNNEL_EXTRA_OPTS_USER to add
   15105     any lines to the STUNNEL global config that you want to.  See the stunnel(8)
   15106     man page for more details.
   15107 }
   15108 	.sslwrk.f.t insert end $msg
   15109 
   15110 	radiobutton .sslwrk.none    -relief ridge -anchor w -variable disable_ssl_workarounds_type -value "none" -text "Disable All Workarounds"
   15111 	radiobutton .sslwrk.noempty  -relief ridge -anchor w -variable disable_ssl_workarounds_type -value "noempty"  -text "Keep the DONT_INSERT_EMPTY_FRAGMENTS Workaround"
   15112 
   15113 	button .sslwrk.cancel -text "Cancel" -command {set disable_ssl_workarounds 0; destroy .sslwrk}
   15114 	bind .sslwrk <Escape> {set disable_ssl_workarounds 0; destroy .sslwrk}
   15115 	wm protocol .sslwrk WM_DELETE_WINDOW {set disable_ssl_workarounds 0; destroy .sslwrk}
   15116 	button .sslwrk.done -text "Done" -command {destroy .sslwrk}
   15117 
   15118 	pack .sslwrk.f .sslwrk.none .sslwrk.noempty .sslwrk.cancel .sslwrk.done -side top -fill x
   15119 
   15120 	center_win .sslwrk
   15121 	wm resizable .sslwrk 1 0
   15122 }
   15123 
   15124 proc update_no_ultra_dsm {} {
   15125 	global ultra_dsm_noultra
   15126 	global ultra_dsm_type
   15127 
   15128 	foreach b {bf des3 aes aes256 l e} {
   15129 		if {! $ultra_dsm_noultra} {
   15130 			.ultradsm.nou.$b configure -state disabled
   15131 		} else {
   15132 			.ultradsm.nou.$b configure -state normal
   15133 		}
   15134 	}
   15135 	if {! $ultra_dsm_noultra} {
   15136 		if {$ultra_dsm_type == "arc4"} {
   15137 			;
   15138 		} elseif {$ultra_dsm_type == "aesv2"} {
   15139 			;
   15140 		} elseif {$ultra_dsm_type == "msrc4"} {
   15141 			;
   15142 		} elseif {$ultra_dsm_type == "msrc4_sc"} {
   15143 			;
   15144 		} elseif {$ultra_dsm_type == "securevnc"} {
   15145 			;
   15146 		} else {
   15147 			set ultra_dsm_type guess
   15148 		}
   15149 		catch {.ultradsm.key.securevnc configure -state normal}
   15150 		catch {.ultradsm.key.msrc4_sc  configure -state normal}
   15151 	} else {
   15152 		catch {.ultradsm.key.securevnc configure -state disabled}
   15153 		catch {.ultradsm.key.msrc4_sc  configure -state disabled}
   15154 	}
   15155 }
   15156 
   15157 proc ultra_dsm_dialog {} {
   15158 	global ultra_dsm ultra_dsm_file ultra_dsm_type
   15159 
   15160 	toplev .ultradsm
   15161 	wm title .ultradsm "UltraVNC DSM Encryption Plugin"
   15162 
   15163 	global help_font
   15164 	set h 40
   15165 	if [small_height] {
   15166 		set h 22
   15167 	}
   15168 	scroll_text .ultradsm.f 85 $h
   15169 
   15170 	set msg {
   15171     On Unix and MacOSX with the provided SSVNC vncviewer, you can connect to an
   15172     UltraVNC server that is using one of its DSM encryption plugins: MSRC4, ARC4,
   15173     AESV2, and SecureVNC. More info at: http://www.uvnc.com/features/encryption.html
   15174 
   15175     IMPORTANT: The UltraVNC DSM MSRC4, ARC4, and AESV2 implementations contain
   15176     unfixed errors that could allow an eavesdropper to recover the session
   15177     key or traffic easily.  They often do not provide strong encryption, but
   15178     only provide basic obscurity instead.  Do not use them with critical data.
   15179     The newer SecureVNC Plugin does not suffer from these problems.
   15180 
   15181     See the bottom of this help text for how to use symmetric encryption with
   15182     Non-UltraVNC servers (for example, x11vnc 0.9.5 or later).  This mode does not
   15183     suffer the shortcomings of the UltraVNC MSRC4, ARC4, and AESV2 implementations.
   15184 
   15185     You will need to specify the corresponding UltraVNC encryption key (created
   15186     by you using an UltraVNC server or viewer).  It is usually called 'rc4.key'
   15187     (for MSRC4), 'arc4.key' (for ARC4), and 'aesv2.key' (for AESV2).  Specify the
   15188     path to it or Browse for it.  Also, specify which type of plugin it is (or use
   15189     'guess' to have it guess via the before mentioned filenames).
   15190 
   15191     The choice "UVNC SC" enables a special workaround for use with UltraVNC Single
   15192     Click and the MSRC4 plugin.  It may not be needed on recent SC (e.g. from
   15193     ~2009 and later; select "MSRC4" for these newer ones.)
   15194 
   15195     You can also specify pw=my-password instead of a keyfile.  Use single quotes
   15196     pw='....' if the password contains shell meta-characters `!$&*(){}[]|;<>?
   15197 
   15198     Use the literal string 'pw=VNCPASSWD' to have the VNC password that you
   15199     entered into the 'VNC Password:' be used for the pw=...
   15200 
   15201     SSL and SSH tunnels do not apply in this mode (any settings are ignored.)
   15202 
   15203     Proxying works in this mode, as well as Reverse Connections (Listen)
   15204 
   15205     The choice "SecureVNC" refers to the SecureVNC Plugin using 128 bit AES or
   15206     ARC4 with 2048 bit RSA key exchange described here:
   15207 
   15208           http://adamwalling.com/SecureVNC
   15209 
   15210     Note in its default mode SecureVNC is *Vulnerable* to Man-In-The-Middle attacks
   15211     (encryption but no server authentication) so do not use it with critical data.
   15212     In SecureVNC mode you do not need to supply a 'Ultra DSM Keyfile'.  However,
   15213     if you DO supply a keyfile filename (recommended) if that file does not exist
   15214     you will be prompted if you want to save the UltraVNC server's RSA key in it.
   15215     The key's MD5 checksum is displayed so that you can verify that the key is
   15216     trusted.  One way to print out the SecureVNC public key MD5 checksum is:
   15217 
   15218     openssl rsa -inform DER -outform DER -pubout -in ./Server_SecureVNC.pkey | dd bs=1 skip=24 | md5sum
   15219 
   15220     Then on subsequent connections, if you continue to specify this filename, the
   15221     SecureVNCPlugin server's RSA key will be checked against the file's contents
   15222     and if they differ the connection will be dropped.
   15223 
   15224     NOTE, However, if the SecureVNC keyfile ends in the string 'ClientAuth.pkey'
   15225     then its contents are used for SecureVNC's normal Client Authentication dialog
   15226     (you need to use Windows SecureVNCPlugin to generate this file on the server
   15227     side, it is usually called "Viewer_ClientAuth.pkey", and then safely copy it
   15228     to the viewer side.)  If you want to do BOTH Client Auth and server RSA key
   15229     storing (recommended), have the keyfile end in 'ClientAuth.pkey.rsa'; that way
   15230     the file will be used for storing the server RSA key and then the '.rsa' is
   15231     trimmed off and the remainder used for the SecureVNC Client Auth data filename.
   15232 
   15233     Note that despite its intentions, Client Authentication in the FIRST release of
   15234     SecureVNC is still susceptible to Man-In-The-Middle attacks.  Even when that
   15235     is fixed, SecureVNC Client Authentication is still susceptible to "spoofing"
   15236     attacks where the viewer user may be tricked into revealing his VNC or MS-Logon
   15237     password if his connection is intercepted.  It is recommended you verify and
   15238     save the Server key (see above) in addition to using Client Authentication.
   15239 
   15240     UltraVNC DSM encryption modes are currently experimental because unfortunately
   15241     the UltraVNC DSM plugin also modifies the RFB protocol(!), and so the SSVNC
   15242     vncviewer had to be modified to support it.  The tight, zlib, and some minor
   15243     encodings currently do not work in this mode and are disabled.
   15244 
   15245     Note that this mode also requires the utility tool named 'ultravnc_dsm_helper'
   15246     that should be included in your SSVNC kit.
   15247 
   15248     Select 'Non-Ultra DSM' to use symmetric encryption to a Non-UltraVNC server via
   15249     a supported symmetric key cipher.  x11vnc supports symmetric encryption via,
   15250     e.g., "x11vnc -enc aesv2:./my.key".  Extra ciphers are enabled for this mode
   15251     (e.g. blowfish and 3des).  'UVNC SC' and SecureVNC do not apply in this mode.
   15252 
   15253     Note for the Non-Ultra DSM case it will also work with any VNC Viewer
   15254     (i.e. selected by Options -> Advanced -> Change VNC Viewer) not only the
   15255     supplied SSVNC vncviewer.
   15256 
   15257     For experts: You can also set the random salt size and initialization vector
   15258     size in Salt,IV for example "8,16".  See the x11vnc and 'ultravnc_dsm_helper
   15259     -help' documentation for more info on this.
   15260 }
   15261 
   15262 	.ultradsm.f.t insert end $msg
   15263 
   15264 	frame .ultradsm.path
   15265 	label .ultradsm.path.l -text "Ultra DSM Keyfile:"
   15266 	entry .ultradsm.path.e -width 40 -textvariable ultra_dsm_file
   15267 	button .ultradsm.path.b -text "Browse..." -command {set_ultra_dsm_file .ultradsm}
   15268 
   15269 	pack .ultradsm.path.l -side left
   15270 	pack .ultradsm.path.e -side left -expand 1 -fill x
   15271 	pack .ultradsm.path.b -side left
   15272 
   15273 	frame .ultradsm.key
   15274 	label .ultradsm.key.l -text "Type of Key:        "
   15275 	radiobutton .ultradsm.key.guess -pady 1 -anchor w -variable ultra_dsm_type -value guess \
   15276 		-text "Guess"
   15277 	radiobutton .ultradsm.key.arc4 -pady 1 -anchor w -variable ultra_dsm_type -value arc4 \
   15278 		-text "ARC4"
   15279 
   15280 	radiobutton .ultradsm.key.aesv2 -pady 1 -anchor w -variable ultra_dsm_type -value aesv2 \
   15281 		-text "AESV2"
   15282 
   15283 	radiobutton .ultradsm.key.msrc4 -pady 1 -anchor w -variable ultra_dsm_type -value msrc4 \
   15284 		-text "MSRC4"
   15285 
   15286 	radiobutton .ultradsm.key.msrc4_sc -pady 1 -anchor w -variable ultra_dsm_type -value msrc4_sc \
   15287 		-text "UVNC SC"
   15288 
   15289 	radiobutton .ultradsm.key.securevnc -pady 1 -anchor w -variable ultra_dsm_type -value securevnc \
   15290 		-text "SecureVNC"
   15291 
   15292 	pack .ultradsm.key.l -side left
   15293 	pack .ultradsm.key.guess -side left
   15294 	pack .ultradsm.key.arc4 -side left
   15295 	pack .ultradsm.key.aesv2 -side left
   15296 	pack .ultradsm.key.msrc4 -side left
   15297 	pack .ultradsm.key.msrc4_sc -side left
   15298 	pack .ultradsm.key.securevnc -side left
   15299 
   15300 	frame .ultradsm.nou
   15301 	checkbutton .ultradsm.nou.cb -text "Non-Ultra DSM" -variable ultra_dsm_noultra -command update_no_ultra_dsm
   15302 	radiobutton .ultradsm.nou.bf -pady 1 -anchor w -variable ultra_dsm_type -value blowfish \
   15303 		-text "Blowfish"
   15304 
   15305 	radiobutton .ultradsm.nou.des3 -pady 1 -anchor w -variable ultra_dsm_type -value 3des \
   15306 		-text "3DES"
   15307 
   15308 	radiobutton .ultradsm.nou.aes -pady 1 -anchor w -variable ultra_dsm_type -value "aes-cfb" \
   15309 		-text "AES-CFB"
   15310 
   15311 	radiobutton .ultradsm.nou.aes256 -pady 1 -anchor w -variable ultra_dsm_type -value "aes256" \
   15312 		-text "AES-256"
   15313 
   15314 	label .ultradsm.nou.l -text " Salt,IV"
   15315 	entry .ultradsm.nou.e -width 6 -textvariable ultra_dsm_salt
   15316 
   15317 	pack .ultradsm.nou.cb -side left
   15318 	pack .ultradsm.nou.bf -side left
   15319 	pack .ultradsm.nou.des3 -side left
   15320 	pack .ultradsm.nou.aes -side left
   15321 	pack .ultradsm.nou.aes256 -side left
   15322 	pack .ultradsm.nou.l -side left
   15323 	pack .ultradsm.nou.e -side left -expand 0
   15324 
   15325 	update_no_ultra_dsm
   15326 
   15327 	button .ultradsm.cancel -text "Cancel" -command {destroy .ultradsm; set ultra_dsm 0}
   15328 	bind .ultradsm <Escape> {destroy .ultradsm; set ultra_dsm 0}
   15329 	wm protocol .ultradsm WM_DELETE_WINDOW {destroy .ultradsm; set ultra_dsm 0}
   15330 	button .ultradsm.done -text "Done" -command {destroy .ultradsm; catch {raise .oa}}
   15331 	bind .ultradsm.path.e <Return> {destroy .ultradsm; catch {raise .oa}}
   15332 
   15333 	pack .ultradsm.f .ultradsm.path .ultradsm.key .ultradsm.nou .ultradsm.cancel .ultradsm.done -side top -fill x
   15334 
   15335 	center_win .ultradsm
   15336 	wm resizable .ultradsm 1 0
   15337 
   15338 	focus .ultradsm.path.e
   15339 }
   15340 
   15341 proc ssh_known_hosts_dialog {} {
   15342 	global ssh_known_hosts ssh_known_hosts_filename
   15343 
   15344 	toplev .sshknownhosts
   15345 	wm title .sshknownhosts "Private SSH KnownHosts file"
   15346 
   15347 	global help_font
   15348 	set h 31
   15349 	if [small_height] {
   15350 		set h 23
   15351 	}
   15352 	scroll_text .sshknownhosts.f 80 $h
   15353 
   15354 	set msg {
   15355       Private SSH KnownHosts file:
   15356 
   15357          On Unix in SSH mode, let the user specify a non-default
   15358          ssh known_hosts file to be used only by the current profile.
   15359          This is the UserKnownHostsFile ssh option and is described in the
   15360          ssh_config(1) man page.  This is useful to avoid proxy 'localhost'
   15361          SSH key collisions.
   15362 
   15363          Normally one should simply let ssh use its default file
   15364          ~/.ssh/known_hosts for tracking SSH keys.  The only problem with
   15365          that happens when multiple SSVNC connections use localhost tunnel
   15366          port redirections.  These make ssh connect to 'localhost' on some
   15367          port (where the proxy is listening.)  Then the different keys
   15368          from the multiple ssh servers collide when ssh saves them under
   15369          'localhost' in ~/.ssh/known_hosts.
   15370 
   15371          So if you are using a proxy with SSVNC or doing a "double SSH
   15372          gateway" your ssh will connect to a proxy port on localhost, and you
   15373          should set a private KnownHosts file for that connection profile.
   15374          This is secure and avoids man-in-the-middle attack (as long as
   15375          you actually verify the initial save of the SSH key!)
   15376 
   15377          The default file location will be:
   15378 
   15379                   ~/.vnc/ssh_known_hosts/profile-name.known
   15380 
   15381          but you can choose any place you like.  It must of course be
   15382          unique and not shared with another ssh connection otherwise they
   15383          both may complain about the key for 'localhost' changing, etc.
   15384 }
   15385 
   15386 	.sshknownhosts.f.t insert end $msg
   15387 
   15388 	frame .sshknownhosts.path
   15389 	label .sshknownhosts.path.l -text "SSH KnownHosts file:"
   15390 	entry .sshknownhosts.path.e -width 40 -textvariable ssh_known_hosts_filename
   15391 	button .sshknownhosts.path.b -text "Browse..." -command {set_ssh_known_hosts_file .sshknownhosts}
   15392 
   15393 	pack .sshknownhosts.path.l -side left
   15394 	pack .sshknownhosts.path.e -side left -expand 1 -fill x
   15395 	pack .sshknownhosts.path.b -side left
   15396 
   15397 	button .sshknownhosts.cancel -text "Cancel" -command {destroy .sshknownhosts; set ssh_known_hosts 0}
   15398 	bind .sshknownhosts <Escape> {destroy .sshknownhosts; set ssh_known_hosts 0}
   15399 	wm protocol .sshknownhosts WM_DELETE_WINDOW {destroy .sshknownhosts; set ssh_known_hosts 0}
   15400 	button .sshknownhosts.done -text "Done" -command {destroy .sshknownhosts; catch {raise .oa}}
   15401 	bind .sshknownhosts.path.e <Return> {destroy .sshknownhosts; catch {raise .oa}}
   15402 
   15403 	pack .sshknownhosts.f .sshknownhosts.path .sshknownhosts.cancel .sshknownhosts.done -side top -fill x
   15404 
   15405 	center_win .sshknownhosts
   15406 	wm resizable .sshknownhosts 1 0
   15407 
   15408 	focus .sshknownhosts.path.e
   15409 }
   15410 
   15411 proc ssh_sec_dialog {} {
   15412 	global ssh_local_protection
   15413 
   15414 	toplev .sshsec
   15415 	wm title .sshsec "SSH Local Port Protections"
   15416 
   15417 	global help_font
   15418 	eval text .sshsec.t -width 80 -height 28 $help_font
   15419 
   15420 	apply_bg .sshsec.t
   15421 
   15422 	set msg {
   15423     See the discussion of "Untrusted Local Users" in the main 'Help'
   15424     panel for info about users who are able to log into the workstation
   15425     you run SSVNC on and might try to use your encrypted tunnel to gain
   15426     access to the remote VNC machine.
   15427 
   15428     On Unix, for SSH tunnels we have an LD_PRELOAD hack (lim_accept.so)
   15429     that will limit ssh from accepting any local redirection connections
   15430     after the first one or after 35 seconds, whichever comes first.
   15431     The first SSH port redirection connection is intended to be the one
   15432     that tunnels your VNC Viewer to reach the remote server.
   15433 
   15434     You can adjust these defaults LIM_ACCEPT=1 LIM_ACCEPT_TIME=35 by
   15435     setting those env. vars. to different values.
   15436 
   15437     Note that there is still a window of a few seconds the Untrusted
   15438     Local User can try to connect before your VNC Viewer does.  So this
   15439     method is far from perfect.  But once your VNC session is established,
   15440     he should be blocked out.  Test to make sure blocking is taking place.
   15441 
   15442     Do not use this option if you are doing SSH Service redirections
   15443     'Additional Port Redirections (via SSH)' that redirect a local port
   15444     to the remote server via ssh -L.
   15445 
   15446     Note that if the shared object "lim_accept.so" cannot be found,
   15447     this option has no effect.  Watch the output in the terminal for
   15448     the "SSVNC_LIM_ACCEPT_PRELOAD" setting.
   15449 }
   15450 	.sshsec.t insert end $msg
   15451 
   15452 	button .sshsec.cancel -text "Cancel" -command {set ssh_local_protection 0; destroy .sshsec}
   15453 	bind .sshsec <Escape> {set ssh_local_protection 0; destroy .sshsec}
   15454 	wm protocol .sshsec WM_DELETE_WINDOW {set ssh_local_protection 0; destroy .sshsec}
   15455 	button .sshsec.done -text "Done" -command {destroy .sshsec}
   15456 
   15457 	pack .sshsec.t .sshsec.cancel .sshsec.done -side top -fill x
   15458 
   15459 	center_win .sshsec
   15460 	wm resizable .sshsec 1 0
   15461 }
   15462 
   15463 proc multilisten_dialog {} {
   15464 	global multiple_listen
   15465 
   15466 	toplev .multil
   15467 	wm title .multil "Multiple LISTEN Connections"
   15468 
   15469 	global help_font
   15470 	set h 36
   15471 	if [small_height] {
   15472 		set h 30
   15473 	}
   15474 	eval text .multil.t -width 84 -height $h $help_font
   15475 
   15476 	apply_bg .multil.t
   15477 
   15478 	set msg {
   15479     Set this option to allow SSVNC (when in LISTEN / Reverse connections
   15480     mode) to allow multiple VNC servers to connect at the same time and
   15481     so display each of their desktops on your screen at the same time.
   15482 
   15483     This option only applies on Unix or MaOSX when using the supplied
   15484     SSVNC vncviewer.  If you specify your own VNC Viewer it has no effect.
   15485 
   15486     On Windows (only the stock TightVNC viewer is provided) it has no effect
   15487     because the Windows SSVNC can ONLY do "Multiple LISTEN Connections".
   15488     Similarly on MacOSX if the COTVNC viewer is used there is no effect.
   15489 
   15490     Rationale:  To play it safe, the Unix vncviewer provided by SSVNC
   15491     (ssvncviewer) only allows one LISTEN reverse connection at a time.
   15492     This is to prohibit malicious people on the network from depositing
   15493     as many desktops on your screen as he likes, even if you are already
   15494     connected to VNC server you desire.
   15495 
   15496     For example, perhaps the malicious user could trick you into typing
   15497     a password into the desktop he displays on your screen.
   15498 
   15499     This protection is not perfect, because the malicious user could
   15500     try to reverse connect to you before the correct VNC server reverse
   15501     connects to you.  This is even more of a problem if you keep your
   15502     SSVNC viewer in LISTEN mode but unconnected for long periods of time.
   15503     Pay careful attention in this case if you are to supplying sensitive
   15504     information to the remote desktop.
   15505 
   15506     Enable 'Multiple LISTEN Connections' if you want to disable the default
   15507     protection in the Unix SSVNC vncviewer; i.e. allow multiple reverse
   15508     connections simultaneously (all vnc viewers we know of do this by default)
   15509 
   15510     For more control, do not select 'Multiple LISTEN Connections', but
   15511     rather set the env. var SSVNC_MULTIPLE_LISTEN=MAX:n to limit the number
   15512     of simultaneous reverse connections to "n"
   15513 }
   15514 	.multil.t insert end $msg
   15515 
   15516 	button .multil.cancel -text "Cancel" -command {set multiple_listen 0; destroy .multil}
   15517 	bind .multil <Escape> {set multiple_listen 0; destroy .multil}
   15518 	wm protocol .multil WM_DELETE_WINDOW {set multiple_listen 0; destroy .multil}
   15519 	button .multil.done -text "Done" -command {destroy .multil}
   15520 
   15521 	pack .multil.t .multil.cancel .multil.done -side top -fill x
   15522 
   15523 	center_win .multil
   15524 	wm resizable .multil 1 0
   15525 }
   15526 
   15527 proc use_grab_dialog {} {
   15528 	global usg_grab
   15529 
   15530 	toplev .usegrb
   15531 	wm title .usegrb "Use XGrabServer (for fullscreen)"
   15532 
   15533 	global help_font
   15534 	eval text .usegrb.t -width 85 -height 29 $help_font
   15535 
   15536 	apply_bg .usegrb.t
   15537 
   15538 	set msg {
   15539     On Unix, some Window managers and some Desktops make it difficult for the
   15540     SSVNC Unix VNC viewer to go into full screen mode (F9) and/or return.
   15541 
   15542     Sometimes one can go into full screen mode, but then your keystrokes or
   15543     Mouse actions do not get through.  This can leave you trapped because you
   15544     cannot inject input (F9 again) to get out of full screen mode.  (Tip:
   15545     press Ctrl-Alt-F2 for a console login shell; then kill your vncviewer
   15546     process, e.g. pkill vncviewer; then Alt-F7 to get back to your desktop)
   15547 
   15548     We have seen this in some very old Window managers (e.g. fvwm2 circa
   15549     1998) and some very new Desktops (e.g. GNOME circa 2008).  We try
   15550     to work around the problem on recent desktops by using the NEW_WM
   15551     interface, but if you use Fullscreen, you may need to use this option.
   15552 
   15553     The default for the SSVNC Unix VNC viewer is '-grabkbd' mode where it will
   15554     try to exclusively grab the keyboard.  This often works correctly.
   15555 
   15556     However if Fullscreen is not working properly, try setting this
   15557     'Use XGrabServer' option to enable '-graball' mode where it tries to grab
   15558     the entire X server.  This usually works, but can be a bit flakey.
   15559 
   15560     Sometimes toggling F9 a few times gets lets the vncviewer fill the whole
   15561     screen.  Sometimes tapping F9 very quickly gets it to snap in.  If GNOME
   15562     (or whatever desktop) is still showing its taskbars, it is recommended
   15563     you toggle F9 until it isn't. Otherwise, it is not clear who gets the input.
   15564 
   15565     Best of luck.
   15566 }
   15567 	.usegrb.t insert end $msg
   15568 
   15569 	button .usegrb.cancel -text "Cancel" -command {set use_grab 0; destroy .usegrb}
   15570 	bind .usegrb <Escape> {set use_grab 0; destroy .usegrb}
   15571 	wm protocol .usegrb WM_DELETE_WINDOW {set use_grab 0; destroy .usegrb}
   15572 	button .usegrb.done -text "Done" -command {destroy .usegrb}
   15573 
   15574 	pack .usegrb.t .usegrb.cancel .usegrb.done -side top -fill x
   15575 
   15576 	center_win .usegrb
   15577 	wm resizable .usegrb 1 0
   15578 }
   15579 
   15580 
   15581 proc find_netcat {} {
   15582 	global is_windows
   15583 
   15584 	set nc ""
   15585 
   15586 	if {! $is_windows} {
   15587 		set nc [in_path "netcat"]
   15588 		if {$nc == ""} {
   15589 			set nc [in_path "nc"]
   15590 		}
   15591 	} else {
   15592 		set try "netcat.exe"
   15593 		if [file exists $try] {
   15594 			set nc $try
   15595 		}
   15596 	}
   15597 	return $nc
   15598 }
   15599 
   15600 proc pk_expand {cmd host} {
   15601 	global tcl_platform
   15602 	set secs [clock seconds]
   15603 	set msecs [clock clicks -milliseconds]
   15604 	set user $tcl_platform(user)
   15605 	if [regexp {%IP} $cmd] {
   15606 		set ip [guess_ip]
   15607 		if {$ip == ""} {
   15608 			set ip "unknown"
   15609 		}
   15610 		regsub -all {%IP} $cmd $ip cmd
   15611 	}
   15612 	if [regexp {%NAT} $cmd] {
   15613 		set ip [guess_nat_ip]
   15614 		regsub -all {%NAT} $cmd $ip cmd
   15615 	}
   15616 	regsub -all {%HOST} $cmd $host cmd
   15617 	regsub -all {%USER} $cmd $user cmd
   15618 	regsub -all {%SECS} $cmd $secs cmd
   15619 	regsub -all {%MSECS} $cmd $msecs cmd
   15620 
   15621 	return $cmd
   15622 }
   15623 
   15624 proc backtick_expand {str} {
   15625 	set str0 $str
   15626 	set collect ""
   15627 	set count 0
   15628 	while {[regexp {^(.*)`([^`]+)`(.*)$} $str mv p1 cmd p2]} {
   15629 		set out [eval exec $cmd]
   15630 		set str "$p1$out$p2"
   15631 		incr count
   15632 		if {$count > 10}  {
   15633 			break
   15634 		}
   15635 	}
   15636 	return $str
   15637 }
   15638 
   15639 proc read_from_pad {file} {
   15640 	set fh ""
   15641 	if {[catch {set fh [open $file "r"]}] != 0} {
   15642 		return "FAIL"
   15643 	}
   15644 
   15645 	set accum ""
   15646 	set match ""
   15647 	while {[gets $fh line] > -1} {
   15648 		if [regexp {^[ \t]*#} $line] {
   15649 			append accum "$line\n"
   15650 		} elseif [regexp {^[ \t]*$} $line] {
   15651 			append accum "$line\n"
   15652 		} elseif {$match == ""} {
   15653 			set match $line
   15654 			append accum "# $line\n"
   15655 		} else {
   15656 			append accum "$line\n"
   15657 		}
   15658 	}
   15659 
   15660 	close $fh
   15661 
   15662 	if {$match == ""} {
   15663 		return "FAIL"
   15664 	}
   15665 
   15666 	if {[catch {set fh [open $file "w"]}] != 0} {
   15667 		return "FAIL"
   15668 	}
   15669 
   15670 	puts -nonewline $fh $accum
   15671 
   15672 	return $match
   15673 }
   15674 
   15675 proc do_port_knock {hp mode} {
   15676 	global use_port_knocking port_knocking_list
   15677 	global is_windows
   15678 
   15679 	if {! $use_port_knocking} {
   15680 		return 1
   15681 	}
   15682 	if {$port_knocking_list == ""} {
   15683 		return 1
   15684 	}
   15685 	set list $port_knocking_list
   15686 
   15687 	if {$mode == "finish"} {
   15688 		if {! [regexp {FINISH} $list]} {
   15689 			mesg "PortKnock(finish): done"
   15690 			return 1
   15691 		} else {
   15692 			regsub {^.*FINISH} $list "" list
   15693 		}
   15694 	} elseif {$mode == "start"} {
   15695 		if {[regexp {FINISH} $list]} {
   15696 			regsub {FINISH.*$} $list "" list
   15697 		}
   15698 	}
   15699 
   15700 	set default_delay 150
   15701 
   15702 	set host [string trim $hp]
   15703 	# XXX host_part
   15704 	regsub {^vnc://} $host "" host
   15705 	regsub {^.*@} $host "" host
   15706 	regsub {:[0-9][0-9]*$} $host "" host
   15707 	set host0 [string trim $host]
   15708 
   15709 	if {$host0 == ""} {
   15710 		bell
   15711 		mesg "PortKnock: No host: $hp"
   15712 		return 0
   15713 	}
   15714 
   15715 	set m ""
   15716 
   15717 	if [regexp {PAD=([^\n]+)} $list mv padfile] {
   15718 		set tlist [read_from_pad $padfile]
   15719 		set tlist [string trim $tlist]
   15720 		if {$tlist == "" || $tlist == "FAIL"} {
   15721 			raise .
   15722 			tk_messageBox -type ok -icon error \
   15723 				-message "Failed to read entry from $padfile" \
   15724 				-title "Error: Padfile $padfile"
   15725 			return 0
   15726 		}
   15727 		regsub -all {PAD=([^\n]+)} $list $tlist list
   15728 	}
   15729 
   15730 	set spl ",\n\r"
   15731 	if [regexp {CMD=}   $list] {set spl "\n\r"}
   15732 	if [regexp {CMDX=}  $list] {set spl "\n\r"}
   15733 	if [regexp {SEND=}  $list] {set spl "\n\r"}
   15734 	if [regexp {SENDX=} $list] {set spl "\n\r"}
   15735 
   15736 	set i 0
   15737 	set pi 0
   15738 
   15739 	foreach line [split $list $spl] {
   15740 		set line [string trim $line]
   15741 		set line0 $line
   15742 
   15743 		if {$line == ""} {
   15744 			continue
   15745 		}
   15746 		if [regexp {^#} $line] {
   15747 			continue
   15748 		}
   15749 
   15750 		if [regexp {^sleep[ \t][ \t]*([0-9][0-9]*)} $line mv sl] {
   15751 			set m "PortKnock: sleep $sl"
   15752 			mesg $m
   15753 			after $sl
   15754 			continue
   15755 		}
   15756 		if [regexp {^delay[ \t][ \t]*([0-9][0-9]*)} $line mv sl] {
   15757 			set m "PortKnock: delay=$sl"
   15758 			mesg $m
   15759 			set default_delay $sl
   15760 			continue
   15761 		}
   15762 
   15763 		if [regexp {^CMD=(.*)} $line mv cmd] {
   15764 			set m "PortKnock: CMD: $cmd"
   15765 			mesg $m
   15766 			eval exec $cmd
   15767 			continue
   15768 		}
   15769 		if [regexp {^CMDX=(.*)} $line mv cmd] {
   15770 			set cmd [pk_expand $cmd $host0]
   15771 			set m "PortKnock: CMDX: $cmd"
   15772 			mesg $m
   15773 			eval exec $cmd
   15774 			continue
   15775 		}
   15776 
   15777 		if [regexp {`} $line] {
   15778 			#set line [backtick_expand $line]
   15779 		}
   15780 
   15781 		set snd ""
   15782 		if [regexp {^(.*)SEND=(.*)$} $line mv line snd]  {
   15783 			set line [string trim $line]
   15784 			set snd [string trim $snd]
   15785 			regsub -all {%NEWLINE} $snd "\n" snd
   15786 		} elseif [regexp {^(.*)SENDX=(.*)$} $line mv line snd]  {
   15787 			set line [string trim $line]
   15788 			set snd [string trim $snd]
   15789 			set snd [pk_expand $snd $host0]
   15790 			regsub -all {%NEWLINE} $snd "\n" snd
   15791 		}
   15792 
   15793 		set udp 0
   15794 		if [regexp -nocase {[/:]udp} $line] {
   15795 			set udp 1
   15796 			regsub -all -nocase {[/:]udp} $line " " line
   15797 			set line [string trim $line]
   15798 		}
   15799 		regsub -all -nocase {[/:]tcp} $line " " line
   15800 		set line [string trim $line]
   15801 
   15802 		set delay 0
   15803 		if [regexp {^(.*)[ \t][ \t]*([0-9][0-9]*)$} $line mv first delay] {
   15804 			set line [string trim $first]
   15805 		}
   15806 
   15807 		if {[regexp {^(.*):([0-9][0-9]*)$} $line mv host port]} {
   15808 			;
   15809 		} else {
   15810 			set host $host0
   15811 			set port $line
   15812 		}
   15813 		set host [string trim $host]
   15814 		set port [string trim $port]
   15815 
   15816 		if {$host == ""} {
   15817 			set host $host0
   15818 		}
   15819 
   15820 		if {$port == ""} {
   15821 			bell
   15822 			set m "PortKnock: No port found: \"$line0\""
   15823 			mesg $m
   15824 			return 0
   15825 		}
   15826 		if {! [regexp {^[0-9][0-9]*$} $port]} {
   15827 			bell
   15828 			set m "PortKnock: Invalid port: \"$port\""
   15829 			mesg $m
   15830 			return 0
   15831 		}
   15832 		regsub {,.*$} $host "" host
   15833 		if {[regexp {[ \t]} $host]} {
   15834 			bell
   15835 			set m "PortKnock: Invalid host: \"$host\""
   15836 			mesg $m
   15837 			return 0
   15838 		}
   15839 		if {! [regexp {^[-A-z0-9_.][-A-z0-9_.]*$} $host]} {
   15840 			bell
   15841 			set m "PortKnock: Invalid host: \"$host\""
   15842 			mesg $m
   15843 			return 0
   15844 		}
   15845 
   15846 		set nc ""
   15847 		if {$udp || $snd != ""} {
   15848 			set nc [find_netcat]
   15849 			if {$nc == ""} {
   15850 				bell
   15851 				set m "PortKnock: UDP: netcat(1) not found"
   15852 				mesg $m
   15853 				after 1000
   15854 				continue
   15855 			}
   15856 		}
   15857 
   15858 		if {$snd != ""} {
   15859 			global env
   15860 			set pfile "payload$pi.txt"
   15861 			if {! $is_windows} {
   15862 				set pfile "$env(SSVNC_HOME)/.$pfile"
   15863 			}
   15864 			set pfiles($pi) $pfile
   15865 			incr pi
   15866 			set fh [open $pfile "w"]
   15867 			puts -nonewline $fh "$snd"
   15868 			close $fh
   15869 
   15870 			set m "PortKnock: SEND: $host $port"
   15871 			mesg $m
   15872 			if {$is_windows} {
   15873 				if {$udp} {
   15874 					catch {exec $nc -d -u -w 1 "$host" "$port" < $pfile &}
   15875 				} else {
   15876 					catch {exec $nc -d    -w 1 "$host" "$port" < $pfile &}
   15877 				}
   15878 			} else {
   15879 				if {$udp} {
   15880 					catch {exec $nc    -u -w 1 "$host" "$port" < $pfile &}
   15881 				} else {
   15882 					catch {exec $nc       -w 1 "$host" "$port" < $pfile &}
   15883 				}
   15884 			}
   15885 			catch {after 50; file delete $pfile}
   15886 
   15887 		} elseif {$udp} {
   15888 			set m "PortKnock: UDP: $host $port"
   15889 			mesg $m
   15890 			if {! $is_windows} {
   15891 				catch {exec echo a | $nc -u -w 1 "$host" "$port" &}
   15892 			} else {
   15893 				set fh [open "nc_in.txt" "w"]
   15894 				puts $fh "a"
   15895 				close $fh
   15896 				catch {exec $nc -d -u -w 1 "$host" "$port" < "nc_in.txt" &}
   15897 			}
   15898 		} else {
   15899 			set m "PortKnock: TCP: $host $port"
   15900 			mesg $m
   15901 			set s ""
   15902 			set emess ""
   15903 			set rc [catch {set s [socket -async $host $port]} emess]
   15904 			if {$rc != 0} {
   15905 				raise .
   15906 				tk_messageBox -type ok -icon error -message $emess -title "Error: socket -async $host $port"
   15907 			}
   15908 			set sockets($i) $s
   15909 			# seems we have to close it immediately to avoid multiple SYN's.
   15910 			# does not help on Win9x.
   15911 			catch {after 30; close $s};
   15912 			incr i
   15913 		}
   15914 
   15915 		if {$delay == 0} {
   15916 			if {$default_delay > 0} {
   15917 				after $default_delay
   15918 			}
   15919 		} elseif {$delay > 0} {
   15920 			after $delay
   15921 		}
   15922 	}
   15923 
   15924 	if {0} {
   15925 		for {set j 0} {$j < $i} {incr j} {
   15926 			set $s $sockets($j)
   15927 			if {$s != ""} {
   15928 				catch {close $s}
   15929 			}
   15930 		}
   15931 	}
   15932 	for {set j 0} {$j < $pi} {incr j} {
   15933 		set f $pfiles($j)
   15934 		if {$f != ""} {
   15935 			if [file exists $f] {
   15936 				after 100
   15937 			}
   15938 			catch {file delete $f}
   15939 		}
   15940 	}
   15941 	if {$is_windows} {
   15942 		catch {file delete "nc_in.txt"}
   15943 	}
   15944 	if {$m != ""} {
   15945 		set m "$m,"
   15946 	}
   15947 	if {$mode == "finish"} {
   15948 		mesg "PortKnock(finish): done"
   15949 	} else {
   15950 		mesg "PortKnock: done"
   15951 	}
   15952 	return 1
   15953 }
   15954 
   15955 proc port_knocking_dialog {} {
   15956 	toplev .pk
   15957 	wm title .pk "Port Knocking"
   15958 	global use_port_knocking port_knocking_list
   15959 
   15960 	global help_font
   15961 
   15962 	global uname
   15963 
   15964 	set h 35
   15965 	if [small_height] {
   15966 		set h 22
   15967 	} elseif {$uname == "Darwin"} {
   15968 		set h 25
   15969 	}
   15970 	scroll_text .pk.f 85 $h
   15971 
   15972 	set msg {
   15973  Description:
   15974 
   15975     Port Knocking is where a network connection to a service is not provided
   15976     to just any client, but rather only to those that immediately prior to
   15977     connecting send a more or less secret pattern of connections to other
   15978     ports on the firewall.
   15979 
   15980     Somewhat like "knocking" on the door with the correct sequence before it
   15981     being opened (but not necessarily letting you in yet).  It is also possible
   15982     to have a single encrypted packet (e.g. UDP) payload communicate with the
   15983     firewall instead of knocking on a sequence of ports.
   15984 
   15985     Only after the correct sequence of ports is observed by the firewall does
   15986     it allow the IP address of the client to attempt to connect to the service.
   15987 
   15988     So, for example, instead of allowing any host on the internet to connect
   15989     to your SSH service and then try to login with a username and password, the
   15990     client first must "tickle" your firewall with the correct sequence of ports.
   15991     Only then will it be allowed to connect to your SSH service at all.
   15992 
   15993     This does not replace the authentication and security of SSH, it merely
   15994     puts another layer of protection around it. E.g., suppose an exploit for
   15995     SSH was discovered, you would most likely have more time to fix/patch
   15996     the problem than if any client could directly connect to your SSH server.
   15997 
   15998     For more information http://www.portknocking.org/ and
   15999     http://www.linuxjournal.com/article/6811
   16000 
   16001 
   16002  Tip:
   16003 
   16004     If you just want to use the Port Knocking for an SSH shell and not
   16005     for a VNC tunnel, then specify something like "user@hostname cmd=SHELL"
   16006     (or "user@hostname cmd=PUTTY" on Windows) in the VNC Host:Display entry box
   16007     on the main panel.  This will do everything short of starting the viewer.
   16008     A shortcut for this is Ctrl-S as long as user@hostname is present.
   16009 
   16010 
   16011  Specifying the Knocks:
   16012 
   16013     In the text area below "Supply port knocking pattern" you put in the pattern
   16014     of "knocks" needed for this connection.  You can separate the knocks by
   16015     commas or put them one per line.
   16016 
   16017     Each "knock" is of this form:
   16018 
   16019            [host:]port[/udp] [delay]
   16020 
   16021     In the simplest form just a numerical port, e.g. 5433, is supplied.
   16022     Items inside [...] are optional and described below.
   16023 
   16024     The packet is sent to the same host that the VNC (or SSH) connection will
   16025     be made to.  If you want it to go to a different host or IP use the [host:]
   16026     prefix.  It can be either a hostname or numerical IP.
   16027 
   16028     A TCP packet is sent by default.
   16029 
   16030     If you need to send a UDP packet, the netcat (aka "nc") program must be
   16031     installed on Unix (tcl/tk does not support udp connections).  Indicate this
   16032     with "/udp" following the port number (you can also use "/tcp", but since
   16033     it is the default it is not necessary).  (You can also use ":udp" to match
   16034     the knockd syntax).  See the example below.  For convenience a Windows netcat
   16035     binary is supplied.
   16036 
   16037     The last field, [delay], is an optional number of milliseconds to delay
   16038     before continuing on to the next knock.
   16039 
   16040 
   16041  Examples:
   16042 
   16043            5433, 12321, 1661
   16044 
   16045            fw.example.com:5433, 12321/udp 3000, 1661 2000
   16046 
   16047            fw.example.com:5433
   16048            12321/udp 3000
   16049            1661 2000
   16050 
   16051     Note how the first two examples separate their knocks via commas ",".
   16052     The 3rd example is equivalent to the 2nd and splits them up by new lines.
   16053 
   16054     Note for each knock any second number (e.g. the "2000" in "1661 2000") is
   16055     a DELAY in milliseconds, not a port number.  If you had a comma separating
   16056     them: "1661, 2000" that would mean two separate knocks: one to port 1661
   16057     followed by one to 2000 (with basically no delay between them).
   16058 
   16059     In examples 2 and 3, "fw.example.com" represents some machine other than
   16060     the VNC/SSH host.  By default, the VNC/SSH host is the one the packet is
   16061     sent to.
   16062 
   16063     If one of the items is the string "FINISH", then the part before it is
   16064     used prior to connecting and the part after is used once the connection
   16065     is finished.  This can be used, say, to close the firewall port.  Example:
   16066 
   16067            5433, 12321, FINISH, 7659, 2314
   16068 
   16069     (or one can split them up via lines as above.)
   16070 
   16071 
   16072  Advanced port knock actions:
   16073 
   16074     If the string in the text field contains anywhere the strings "CMD=", "CMDX=",
   16075     or "SEND=", then splitting on commas is not done: it is only split on lines.
   16076 
   16077     Then, if a line begins CMD=... the string after the = is run as an
   16078     external command.  The command could be anything you want, e.g. it could
   16079     be a port-knocking client that does the knocking, perhaps encrypting the
   16080     "knocks" pattern somehow or using a Single Packet Authorization method such
   16081     as http://www.cipherdyne.com/fwknop/
   16082 
   16083     Extra quotes (sometimes "'foo bar'") may be needed to preserve spaces in
   16084     command line arguments because the tcl/tk eval(n) command is used.  You
   16085     can also use {...} for quoting strings with spaces.
   16086 
   16087     If a line begins CMDX=... then before the command is run the following
   16088     tokens are expanded to strings:
   16089 
   16090       %IP       Current machine's IP address (NAT may make this not useful).
   16091       %NAT      Try to get effective IP by contacting http://www.whatismyip.com
   16092       %HOST     The remote host of the connection.
   16093       %USER     The current user.
   16094       %SECS     The current time in seconds (platform dependent).
   16095       %MSECS    Platform dependent time having at least millisecond granularity.
   16096 
   16097    Lines not matching CMD= or CMDX= are treated as normal port knocks but with
   16098    one exception.  If a line ends in SEND=... (i.e. after the [host:]port,
   16099    etc., part) then the string after the = is sent as a payload for the tcp
   16100    or udp connection to [host:]port.  netcat is used for these SEND cases
   16101    (and must be available on Unix).  If newlines (\n) are needed in the
   16102    SEND string, use %NEWLINE.  Sending binary data is not yet supported;
   16103    use CMD= with your own program.
   16104 
   16105 
   16106  Advanced Examples:
   16107 
   16108       CMD=port_knock_client -password wombat33
   16109       CMDX=port_knock_client -password wombat33 -host %HOST -src %NAT
   16110 
   16111       fw.example.com:5433/udp SEND=ASDLFKSJDF
   16112 
   16113 
   16114  More tricks:
   16115 
   16116       To temporarily "comment out" a knock, insert a leading "#" character.
   16117 
   16118       Use "sleep N" to insert a raw sleep for N milliseconds (e.g. between
   16119       CMD=... items or at the very end of the knocks to wait).
   16120 
   16121       If a knock entry matches "delay N" the default delay is set to
   16122       N milliseconds (it is 150 initially).
   16123 
   16124 
   16125  One Time Pads:
   16126 
   16127       If the text contains a (presumably single) line of the form:
   16128 
   16129            PAD=/path/to/a/one/time/pad/file
   16130 
   16131       then that file is opened and the first non-blank line not beginning
   16132       with "#" is used as the knock pattern.  The pad file is rewritten
   16133       with that line starting with a "#" (so it will be skipped next time).
   16134 
   16135       The PAD=... string is replaced with the read-in knock pattern line.
   16136       So, if needed, one can preface the PAD=... with "delay N" to set the
   16137       default delay, and one can also put a "sleep N" after the PAD=...
   16138       line to indicate a final sleep.  One can also surround the PAD=
   16139       line with other knock and CMD= CMDX= lines, but that usage sounds
   16140       a bit rare.  Example:
   16141 
   16142            delay 1000
   16143            PAD=C:\My Pads\work-pad1.txt
   16144            sleep 4000
   16145 
   16146 
   16147  Port knock only:
   16148 
   16149       If, in the 'VNC Host:Display' entry, you use "user@hostname cmd=KNOCK"
   16150       then only the port-knocking is performed.  A shortcut for this is
   16151       Ctrl-P as long as hostname is present in the entry box.  If it
   16152       matches cmd=KNOCKF, i.e. an extra "F", then the port-knocking
   16153       "FINISH" sequence is sent, if any.  A shortcut for this Shift-Ctrl-P
   16154       as long as hostname is present.
   16155 }
   16156 	.pk.f.t insert end $msg
   16157 
   16158 	label .pk.info -text "Supply port knocking pattern:" -anchor w -relief ridge
   16159 
   16160 	eval text .pk.rule -width 80 -height 5 $help_font
   16161 	.pk.rule insert end $port_knocking_list
   16162 
   16163 	button .pk.cancel -text "Cancel" -command {set use_port_knocking 0; destroy .pk}
   16164 	bind .pk <Escape> {set use_port_knocking 0; destroy .pk}
   16165 	wm protocol .pk WM_DELETE_WINDOW {set use_port_knocking 0; destroy .pk}
   16166 	button .pk.done -text "Done" -command {if {$use_port_knocking} {set port_knocking_list [.pk.rule get 1.0 end]}; destroy .pk}
   16167 
   16168 	pack .pk.done .pk.cancel .pk.rule .pk.info -side bottom -fill x
   16169 	pack .pk.f -side top -fill both -expand 1
   16170 
   16171 	center_win .pk
   16172 }
   16173 
   16174 proc choose_desktop_dialog {} {
   16175 	toplev .sd
   16176 	wm title .sd "Desktop Type"
   16177 	global ts_desktop_type choose_desktop
   16178 
   16179 	global ts_desktop_type_def
   16180 	set def "kde"
   16181 	if {$ts_desktop_type_def != ""} {
   16182 		set def $ts_desktop_type_def
   16183 	}
   16184 
   16185 	if {$ts_desktop_type == ""} {
   16186 		set ts_desktop_type $def
   16187 	}
   16188 
   16189 	label .sd.l1 -anchor w -text "Select the type of remote Desktop"
   16190 	label .sd.l2 -anchor w -text "for your session (default: $def)"
   16191 
   16192 	radiobutton .sd.b1 -anchor w -variable ts_desktop_type -value kde      -text kde
   16193 	radiobutton .sd.b2 -anchor w -variable ts_desktop_type -value gnome    -text gnome
   16194 	radiobutton .sd.b3 -anchor w -variable ts_desktop_type -value Xsession -text cde
   16195 	radiobutton .sd.b4 -anchor w -variable ts_desktop_type -value mwm      -text mwm
   16196 	radiobutton .sd.b5 -anchor w -variable ts_desktop_type -value wmaker   -text wmaker
   16197 	radiobutton .sd.b6 -anchor w -variable ts_desktop_type -value xfce     -text xfce
   16198 	radiobutton .sd.b7 -anchor w -variable ts_desktop_type -value enlightenment   -text enlightenment
   16199 	radiobutton .sd.b8 -anchor w -variable ts_desktop_type -value twm      -text twm
   16200 	radiobutton .sd.b9 -anchor w -variable ts_desktop_type -value failsafe -text failsafe
   16201 
   16202 	button .sd.cancel -text "Cancel" -command {destroy .sd; set choose_desktop 0; set ts_desktop_type ""}
   16203 	bind .sd <Escape> {destroy .sd; set choose_desktop 0; set ts_desktop_type ""}
   16204 	wm protocol .sd WM_DELETE_WINDOW {destroy .sd; set choose_desktop 0; set ts_desktop_type ""}
   16205 	button .sd.done -text "Done" -command {destroy .sd}
   16206 
   16207 	pack .sd.l1 .sd.l2 .sd.b1 .sd.b2 .sd.b3 .sd.b4 .sd.b5 .sd.b6 .sd.b7 .sd.b8 .sd.b9 .sd.cancel .sd.done -side top -fill x
   16208 
   16209 	center_win .sd
   16210 }
   16211 
   16212 proc choose_size_dialog {} {
   16213 	toplev .sz
   16214 	wm title .sz "Desktop Size"
   16215 	global ts_desktop_size ts_desktop_depth choose_desktop_geom
   16216 
   16217 	set def1 "1280x1024"
   16218 	set def2 "16"
   16219 
   16220 	global ts_desktop_size_def ts_desktop_depth_def
   16221 	if {$ts_desktop_size_def != ""} {
   16222 		set def1 $ts_desktop_size_def
   16223 	}
   16224 	if {$ts_desktop_depth_def != ""} {
   16225 		set def2 $ts_desktop_depth_def
   16226 	}
   16227 
   16228 	if {$ts_desktop_size == ""} {
   16229 		set ts_desktop_size $def1
   16230 	}
   16231 	if {$ts_desktop_depth == ""} {
   16232 		set ts_desktop_depth $def2
   16233 	}
   16234 
   16235 	label .sz.l1 -anchor w -text "Select the Size and Color depth"
   16236 	label .sz.l2 -anchor w -text "for your Desktop session."
   16237 	label .sz.l3 -anchor w -text "Default: $def1 and $def2 bits/pixel."
   16238 
   16239 	label .sz.g0 -anchor w -text "Width x Height:" -relief groove
   16240 
   16241 	radiobutton .sz.g1 -anchor w -variable ts_desktop_size -value "640x480"   -text "    640x480"
   16242 	radiobutton .sz.g2 -anchor w -variable ts_desktop_size -value "800x600"   -text "    800x600"
   16243 	radiobutton .sz.g3 -anchor w -variable ts_desktop_size -value "1024x768"  -text "  1024x768"
   16244 	radiobutton .sz.g4 -anchor w -variable ts_desktop_size -value "1280x1024" -text "1280x1024"
   16245 	radiobutton .sz.g5 -anchor w -variable ts_desktop_size -value "1400x1050" -text "1400x1050"
   16246 	radiobutton .sz.g6 -anchor w -variable ts_desktop_size -value "1600x1200" -text "1600x1200"
   16247 	radiobutton .sz.g7 -anchor w -variable ts_desktop_size -value "1920x1200" -text "1920x1200"
   16248 
   16249 	frame .sz.c
   16250 	label .sz.c.l -anchor w -text "Custom:"
   16251 	entry .sz.c.e -width 10 -textvariable ts_desktop_size
   16252 	pack .sz.c.l -side left
   16253 	pack .sz.c.e -side left -expand 1 -fill x
   16254 	bind .sz.c.e <Return> {destroy .sz}
   16255 
   16256 	label .sz.d0 -anchor w -text "Color Depth:" -relief groove
   16257 
   16258 	radiobutton .sz.d1 -anchor w -variable ts_desktop_depth -value "8" -text  "  8 bits/pixel"
   16259 	radiobutton .sz.d2 -anchor w -variable ts_desktop_depth -value "16" -text "16 bits/pixel"
   16260 	radiobutton .sz.d3 -anchor w -variable ts_desktop_depth -value "24" -text "24 bits/pixel"
   16261 
   16262 	button .sz.cancel -text "Cancel" -command {destroy .sz; set choose_desktop_geom 0; set ts_desktop_size ""; set ts_desktop_depth ""}
   16263 	bind .sz <Escape> {destroy .sz; set choose_desktop_geom 0; set ts_desktop_size ""; set ts_desktop_depth ""}
   16264 	wm protocol .sz WM_DELETE_WINDOW {destroy .sz; set choose_desktop_geom 0; set ts_desktop_size ""; set ts_desktop_depth ""}
   16265 	button .sz.done -text "Done" -command {destroy .sz}
   16266 
   16267 	pack .sz.l1 .sz.l2 .sz.l3 \
   16268 		.sz.g0 .sz.g1 .sz.g2 .sz.g3 .sz.g4 .sz.g5 .sz.g6 .sz.g7 \
   16269 		.sz.c \
   16270 		.sz.d0 .sz.d1 .sz.d2 .sz.d3 \
   16271 		.sz.cancel .sz.done -side top -fill x
   16272 
   16273 	center_win .sz
   16274 	focus .sz.c.e
   16275 }
   16276 
   16277 proc choose_xserver_dialog {} {
   16278 	toplev .st
   16279 	wm title .st "X Server Type"
   16280 	global ts_xserver_type choose_xserver
   16281 
   16282 	set def "Xvfb"
   16283 	global ts_xserver_type_def
   16284 	if {$ts_xserver_type_def != ""} {
   16285 		set def $ts_xserver_type_def
   16286 	}
   16287 
   16288 	if {$ts_xserver_type == ""} {
   16289 		set ts_xserver_type $def
   16290 	}
   16291 
   16292 	label .st.l1 -anchor w -text "Select the type of remote X server"
   16293 	label .st.l2 -anchor w -text "for your session (default: $def)"
   16294 
   16295 	radiobutton .st.b1 -anchor w -variable ts_xserver_type -value Xvfb -text "Xvfb"
   16296 
   16297 	radiobutton .st.b2 -anchor w -variable ts_xserver_type -value Xdummy -text "Xdummy"
   16298 
   16299 	radiobutton .st.b3 -anchor w -variable ts_xserver_type -value Xvnc -text "Xvnc"
   16300 
   16301 	radiobutton .st.b4 -anchor w -variable ts_xserver_type -value Xvnc.redirect -text "Xvnc.redirect"
   16302 
   16303 	button .st.cancel -text "Cancel" -command {destroy .st; set choose_xserver 0; set ts_xserver_type ""}
   16304 	bind .st <Escape> {destroy .st; set choose_xserver 0; set ts_xserver_type ""}
   16305 	wm protocol .st WM_DELETE_WINDOW {destroy .st; set choose_xserver 0; set ts_xserver_type ""}
   16306 	button .st.done -text "Done" -command {destroy .st}
   16307 
   16308 	pack .st.l1 .st.l2 .st.b1 .st.b2 .st.b3 .st.b4 .st.cancel .st.done -side top -fill x
   16309 
   16310 	center_win .st
   16311 }
   16312 
   16313 proc set_ts_options {} {
   16314 	global use_cups use_sound use_smbmnt
   16315 	global change_vncviewer choose_xserver
   16316 	global ts_only is_windows
   16317 	global darwin_cotvnc use_x11_macosx uname
   16318 	if {! $ts_only} {
   16319 		return
   16320 	}
   16321 	catch {destroy .o}
   16322 	toplev .ot
   16323 	wm title .ot "Options"
   16324 
   16325 	set i 1
   16326 
   16327 	checkbutton .ot.b$i -anchor w -variable choose_desktop -text \
   16328 		"Desktop Type" \
   16329 		-command {if {$choose_desktop} {choose_desktop_dialog}}
   16330 	incr i
   16331 
   16332 	checkbutton .ot.b$i -anchor w -variable choose_desktop_geom -text \
   16333 		"Desktop Size" \
   16334 		-command {if {$choose_desktop_geom} {choose_size_dialog}}
   16335 	incr i
   16336 
   16337 	checkbutton .ot.b$i -anchor w -variable choose_xserver -text \
   16338 		"X Server Type" \
   16339 		-command {if {$choose_xserver} {choose_xserver_dialog}}
   16340 	incr i
   16341 
   16342 	checkbutton .ot.b$i -anchor w -variable use_cups -text \
   16343 		"Enable Printing" \
   16344 		-command {if {$use_cups} {cups_dialog}}
   16345 	incr i
   16346 
   16347 	checkbutton .ot.b$i -anchor w -variable use_sound -text \
   16348 		"Enable Sound" \
   16349 		-command {if {$use_sound} {sound_dialog}}
   16350 	incr i
   16351 
   16352 #	checkbutton .ot.b$i -anchor w -variable use_smbmnt -text \
   16353 #		"Enable SMB mount tunnelling" \
   16354 #		-command {if {$use_smbmnt} {smb_dialog}}
   16355 #	incr i
   16356 
   16357 	checkbutton .ot.b$i -anchor w -variable choose_filexfer -text \
   16358 		"File Transfer" \
   16359 		-command {if {$choose_filexfer} {ts_filexfer_dialog}}
   16360 	incr i
   16361 
   16362 	checkbutton .ot.b$i -anchor w -variable use_viewonly -text \
   16363 		"View Only"
   16364 	incr i
   16365 
   16366 	checkbutton .ot.b$i -anchor w -variable change_vncviewer -text \
   16367 		"Change VNC Viewer" \
   16368 		-command change_vncviewer_dialog_wrap
   16369 	incr i
   16370 
   16371 	if {!$is_windows && $uname == "Darwin"} {
   16372 		checkbutton .ot.b$i -anchor w -variable use_x11_macosx -text \
   16373 			"X11 viewer MacOSX" \
   16374 			-command {if {$use_x11_macosx} {set darwin_cotvnc 0} else {set darwin_cotvnc 1}; set_darwin_cotvnc_buttons}
   16375 		incr i
   16376 	}
   16377 
   16378 	button .ot.b$i -anchor w -text "   Delete Profile..." \
   16379 		-command {destroy .ot; delete_profile}
   16380 	incr i
   16381 
   16382 	button .ot.b$i -anchor w -text "   Advanced ..." -command {set_ts_adv_options}
   16383 	incr i
   16384 
   16385 	for {set j 1} {$j < $i} {incr j} {
   16386 		pack .ot.b$j -side top -fill x
   16387 	}
   16388 
   16389 	frame .ot.b
   16390 	button .ot.b.done -text "Done" -command {destroy .ot}
   16391 	button .ot.b.help -text "Help" -command help_ts_opts
   16392 	pack .ot.b.help .ot.b.done -fill x -expand 1 -side left
   16393 
   16394 	bind .ot <Escape> {destroy .ot}
   16395 	wm protocol .ot WM_DELETE_WINDOW {destroy .ot}
   16396 
   16397 	pack .ot.b -side top -fill x
   16398 
   16399 	center_win .ot
   16400 	wm resizable .ot 1 0
   16401 	focus .ot
   16402 }
   16403 
   16404 proc set_ts_adv_options {} {
   16405 	global ts_only ts_unixpw ts_vncshared
   16406 	global ts_ncache ts_multisession
   16407 	global choose_othervnc darwin_cotvnc choose_sleep
   16408 	global is_windows
   16409 
   16410 	if {! $ts_only} {
   16411 		return
   16412 	}
   16413 	catch {destroy .ot}
   16414 	toplev .ot2
   16415 	wm title .ot2 "Advanced"
   16416 
   16417 	set i 1
   16418 
   16419 	checkbutton .ot2.b$i -anchor w -variable ts_vncshared -text \
   16420 		"VNC Shared" \
   16421 		-command {if {$ts_vncshared} {ts_vncshared_dialog}}
   16422 	incr i
   16423 
   16424 	checkbutton .ot2.b$i -anchor w -variable choose_multisession -text \
   16425 		"Multiple Sessions" \
   16426 		-command {if {$choose_multisession} {ts_multi_dialog}}
   16427 	incr i
   16428 
   16429 	checkbutton .ot2.b$i -anchor w -variable ts_xlogin -text \
   16430 		"X Login Greeter" \
   16431 		-command {if {$ts_xlogin} {ts_xlogin_dialog}}
   16432 	incr i
   16433 
   16434 	checkbutton .ot2.b$i -anchor w -variable choose_othervnc -text \
   16435 		"Other VNC Server" \
   16436 		-command {if {$choose_othervnc} {ts_othervnc_dialog}}
   16437 	incr i
   16438 
   16439 	checkbutton .ot2.b$i -anchor w -variable ts_unixpw -text \
   16440 		"Use unixpw" \
   16441 		-command {if {$ts_unixpw} {ts_unixpw_dialog}}
   16442 	incr i
   16443 
   16444 	checkbutton .ot2.b$i -anchor w -variable use_bgr233 -text \
   16445 		"Client 8bit Color"
   16446 	if {$darwin_cotvnc} {.ot2.b$i configure -state disabled}
   16447 	global darwin_cotvnc_blist
   16448 	set darwin_cotvnc_blist(.ot2.b$i) 1
   16449 	incr i
   16450 
   16451 	checkbutton .ot2.b$i -anchor w -variable choose_ncache -text \
   16452 		"Client-Side Caching" \
   16453 		-command {if {$choose_ncache} {ts_ncache_dialog}}
   16454 	incr i
   16455 
   16456 	checkbutton .ot2.b$i -anchor w -variable choose_x11vnc_opts -text \
   16457 		"X11VNC Options" \
   16458 		-command {if {$choose_x11vnc_opts} {ts_x11vnc_opts_dialog}}
   16459 	incr i
   16460 
   16461 	checkbutton .ot2.b$i -anchor w -variable choose_sleep -text \
   16462 		"Extra Sleep" \
   16463 		-command {if {$choose_sleep} {ts_sleep_dialog}}
   16464 	incr i
   16465 
   16466         if {$is_windows} {
   16467 		checkbutton .ot2.b$i -anchor w -variable choose_parg -text \
   16468 			"Putty Args" \
   16469 			-command {if {$choose_parg} {ts_putty_args_dialog}}
   16470 		incr i
   16471         }
   16472 
   16473 	if {!$is_windows} {
   16474 		checkbutton .ot2.b$i -anchor w -variable ssh_local_protection -text \
   16475 			"SSH Local Protections" \
   16476 			-command {if {$ssh_local_protection} {ssh_sec_dialog}}
   16477 		if {$is_windows} {.ot2.b$i configure -state disabled}
   16478 		incr i
   16479 
   16480 		checkbutton .ot2.b$i -anchor w -variable ssh_known_hosts -text \
   16481 			"SSH KnownHosts file" \
   16482 			-command {if {$ssh_known_hosts} {ssh_known_hosts_dialog}}
   16483 		if {$is_windows} {.ot2.b$i configure -state disabled}
   16484 		incr i
   16485 	}
   16486 
   16487 	if {$is_windows} {
   16488 		button .ot2.b$i -anchor w -text "   Putty Agent" \
   16489 			-command {catch {exec pageant.exe &}}
   16490 		incr i
   16491 
   16492 		button .ot2.b$i -anchor w -text "   Putty Key-Gen" \
   16493 			-command {catch {exec puttygen.exe &}}
   16494 		incr i
   16495 	}
   16496 
   16497 	global env
   16498 	if {![info exists env(SSVNC_TS_ALWAYS)]} {
   16499 		button .ot2.b$i -anchor w -text "   SSVNC Mode" \
   16500 			-command {destroy .ot2; to_ssvnc}
   16501 		incr i
   16502 	}
   16503 
   16504 	if {!$is_windows} {
   16505 		button .ot2.b$i -anchor w -text "   Unix ssvncviewer ..." \
   16506 			-command {set_ssvncviewer_options}
   16507 		if {$is_windows} {
   16508 			.ot2.b$i configure -state disabled
   16509 		}
   16510 		global change_vncviewer
   16511 		if {$change_vncviewer} {
   16512 			.ot2.b$i configure -state disabled
   16513 		}
   16514 		global ts_uss_button
   16515 		set ts_uss_button .ot2.b$i
   16516 		incr i
   16517 	}
   16518 
   16519 	for {set j 1} {$j < $i} {incr j} {
   16520 		pack .ot2.b$j -side top -fill x
   16521 	}
   16522 
   16523 	frame .ot2.b
   16524 	button .ot2.b.done -text "Done" -command {destroy .ot2}
   16525 	button .ot2.b.help -text "Help" -command help_ts_opts
   16526 	pack .ot2.b.help .ot2.b.done -fill x -expand 1 -side left
   16527 
   16528 	bind .ot2 <Escape> {destroy .ot2}
   16529 	wm protocol .ot2 WM_DELETE_WINDOW {destroy .ot2}
   16530 
   16531 	pack .ot2.b -side top -fill x
   16532 
   16533 	center_win .ot2
   16534 	wm resizable .ot2 1 0
   16535 	focus .ot2
   16536 }
   16537 
   16538 proc change_vncviewer_dialog_wrap {} {
   16539 	global change_vncviewer ts_uss_button is_windows
   16540 	if {$change_vncviewer} {
   16541 		change_vncviewer_dialog
   16542 		catch {tkwait window .chviewer}
   16543 	}
   16544 	if {$change_vncviewer || $is_windows} {
   16545 		catch {.oa.ss configure -state disabled}
   16546 	} else {
   16547 		catch {.oa.ss configure -state normal}
   16548 	}
   16549 	if [info exists ts_uss_button] {
   16550 		if {$change_vncviewer || $is_windows} {
   16551 			catch {$ts_uss_button configure -state disabled}
   16552 		} else {
   16553 			catch {$ts_uss_button configure -state normal}
   16554 		}
   16555 	}
   16556 }
   16557 
   16558 proc set_advanced_options {} {
   16559 	global use_cups use_sound use_smbmnt
   16560 	global change_vncviewer
   16561 	global use_port_knocking port_knocking_list
   16562 	global is_windows darwin_cotvnc
   16563 	global use_ssh use_sshssl
   16564 	global use_x11_macosx
   16565 	global adv_ssh
   16566 	global showing_no_encryption
   16567 	global x11vnc_xlogin_widget
   16568 
   16569 	catch {destroy .o}
   16570 	toplev .oa
   16571 	wm title .oa "Advanced Options"
   16572 
   16573 	set i 1
   16574 
   16575 	checkbutton .oa.b$i -anchor w -variable use_cups -text \
   16576 		"Enable CUPS Print tunnelling" \
   16577 		-command {if {$use_cups} {cups_dialog}}
   16578 	if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled}
   16579 	set adv_ssh(cups) .oa.b$i
   16580 	incr i
   16581 
   16582 	checkbutton .oa.b$i -anchor w -variable use_sound -text \
   16583 		"Enable ESD/ARTSD Audio tunnelling" \
   16584 		-command {if {$use_sound} {sound_dialog}}
   16585 	if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled}
   16586 	set adv_ssh(snd) .oa.b$i
   16587 	incr i
   16588 
   16589 	checkbutton .oa.b$i -anchor w -variable use_smbmnt -text \
   16590 		"Enable SMB mount tunnelling" \
   16591 		-command {if {$use_smbmnt} {smb_dialog}}
   16592 	if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled}
   16593 	set adv_ssh(smb) .oa.b$i
   16594 	incr i
   16595 
   16596 	checkbutton .oa.b$i -anchor w -variable use_x11vnc_xlogin -text \
   16597 		"Automatically Find X Login/Greeter" -command {x11vnc_find_adjust "xlogin"}
   16598 	if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled}
   16599 	set x11vnc_xlogin_widget ".oa.b$i"
   16600 	incr i
   16601 
   16602 	checkbutton .oa.b$i -anchor w -variable additional_port_redirs -text \
   16603 		"Additional Port Redirs (via SSH)" \
   16604 		-command {if {$additional_port_redirs} {port_redir_dialog}}
   16605 	if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled}
   16606 	set adv_ssh(redirs) .oa.b$i
   16607 	incr i
   16608 
   16609 	global use_ssl use_ssh use_sshssl
   16610 
   16611 	if {!$is_windows} {
   16612 		checkbutton .oa.b$i -anchor w -variable ssh_known_hosts -text \
   16613 			"Private SSH KnownHosts file" \
   16614 			-command {if {$ssh_known_hosts} {ssh_known_hosts_dialog}}
   16615 		set adv_ssh(knownhosts) .oa.b$i
   16616 		if {$use_ssl}    {.oa.b$i configure -state disabled}
   16617 		if {$is_windows} {.oa.b$i configure -state disabled}
   16618 		incr i
   16619 
   16620 		checkbutton .oa.b$i -anchor w -variable ssh_local_protection -text \
   16621 			"SSH Local Port Protections" \
   16622 			-command {if {$ssh_local_protection} {ssh_sec_dialog}}
   16623 		global ssh_local_protection_button
   16624 		set ssh_local_protection_button .oa.b$i
   16625 		if {$use_ssl}    {.oa.b$i configure -state disabled}
   16626 		if {$is_windows} {.oa.b$i configure -state disabled}
   16627 		incr i
   16628 	}
   16629 
   16630    global ssh_only
   16631    if {!$ssh_only} {
   16632 	if {!$is_windows} {
   16633 		checkbutton .oa.b$i -anchor w -variable stunnel_local_protection -text \
   16634 			"STUNNEL Local Port Protections" \
   16635 			-command {if {$stunnel_local_protection} {stunnel_sec_dialog}}
   16636 		global stunnel_local_protection_button
   16637 		set stunnel_local_protection_button .oa.b$i
   16638 		if {$use_ssh}    {.oa.b$i configure -state disabled}
   16639 		if {$is_windows} {.oa.b$i configure -state disabled}
   16640 		incr i
   16641 	}
   16642 
   16643 	checkbutton .oa.b$i -anchor w -variable disable_ssl_workarounds -text \
   16644 		"Disable SSL Workarounds" \
   16645 		-command {if {$disable_ssl_workarounds} {disable_ssl_workarounds_dialog}}
   16646 	global disable_ssl_workarounds_button
   16647 	set disable_ssl_workarounds_button .oa.b$i
   16648 	if {$use_ssh}    {.oa.b$i configure -state disabled}
   16649 	incr i
   16650 
   16651 	if {!$is_windows} {
   16652 		checkbutton .oa.b$i -anchor w -variable ultra_dsm -text \
   16653 			"UltraVNC DSM Encryption Plugin" \
   16654 			-command {if {$ultra_dsm} {ultra_dsm_dialog}}
   16655 		global ultra_dsm_button
   16656 		set ultra_dsm_button .oa.b$i
   16657 		if {$is_windows} {.oa.b$i configure -state disabled}
   16658 		if {$use_ssh}    {.oa.b$i configure -state disabled}
   16659 		incr i
   16660 	}
   16661 
   16662 	checkbutton .oa.b$i -anchor w -variable no_probe_vencrypt -text \
   16663 		"Do not Probe for VeNCrypt"
   16664 	global no_probe_vencrypt_button
   16665 	set no_probe_vencrypt_button .oa.b$i
   16666 	if {$use_ssh}    {.oa.b$i configure -state disabled}
   16667 	incr i
   16668 
   16669 	checkbutton .oa.b$i -anchor w -variable server_vencrypt -text \
   16670 		"Server uses VeNCrypt SSL encryption"
   16671 	global vencrypt_button
   16672 	set vencrypt_button .oa.b$i
   16673 	if {$use_ssh}    {.oa.b$i configure -state disabled}
   16674 	incr i
   16675 
   16676 	checkbutton .oa.b$i -anchor w -variable server_anondh -text \
   16677 		"Server uses Anonymous Diffie-Hellman" -command no_certs_tutorial_mesg
   16678 	global anondh_button
   16679 	set anondh_button .oa.b$i
   16680 	if {$use_ssh}    {.oa.b$i configure -state disabled}
   16681 	incr i
   16682    }
   16683 
   16684 	checkbutton .oa.b$i -anchor w -variable change_vncviewer -text \
   16685 		"Change VNC Viewer" \
   16686 		-command change_vncviewer_dialog_wrap
   16687 	incr i
   16688 
   16689 	checkbutton .oa.b$i -anchor w -variable use_port_knocking -text \
   16690 		"Port Knocking" \
   16691 		-command {if {$use_port_knocking} {port_knocking_dialog}}
   16692 	incr i
   16693 
   16694 	for {set j 1} {$j < $i} {incr j} {
   16695 		pack .oa.b$j -side top -fill x
   16696 	}
   16697 
   16698 	global include_list extra_sleep
   16699 	frame .oa.fis
   16700 	frame .oa.fis.fL
   16701 	frame .oa.fis.fR
   16702 	label .oa.fis.fL.la -anchor w -text "Include:"
   16703 	label .oa.fis.fL.lb -anchor w -text "Sleep:"
   16704 	if {$is_windows} {
   16705 		label .oa.fis.fL.lc -anchor w -text "Putty Args:"
   16706 		pack .oa.fis.fL.la .oa.fis.fL.lb .oa.fis.fL.lc -side top -fill x
   16707 	} else {
   16708 		pack .oa.fis.fL.la .oa.fis.fL.lb -side top -fill x
   16709 	}
   16710 
   16711 	entry .oa.fis.fR.ea -width 10 -textvariable include_list
   16712 	entry .oa.fis.fR.eb -width 10 -textvariable extra_sleep
   16713 	if {$is_windows} {
   16714 		entry .oa.fis.fR.ec -width 10 -textvariable putty_args
   16715 		pack .oa.fis.fR.ea .oa.fis.fR.eb .oa.fis.fR.ec -side top -fill x
   16716 	} else {
   16717 		pack .oa.fis.fR.ea .oa.fis.fR.eb -side top -fill x
   16718 	}
   16719 
   16720 	pack .oa.fis.fL -side left
   16721 	pack .oa.fis.fR -side right -expand 1 -fill x
   16722 
   16723 	pack .oa.fis -side top -fill x
   16724 
   16725 
   16726 	if {!$is_windows} {
   16727 		global uname
   16728 		set t1 "         Unix ssvncviewer ..."
   16729 		if {$uname == "Darwin" } { regsub {^ *} $t1 "" t1 }
   16730 		button .oa.ss -anchor w -text $t1 -command set_ssvncviewer_options
   16731 		pack   .oa.ss -side top -fill x
   16732 		if {$is_windows} {
   16733 			.oa.ss configure -state disabled
   16734 		}
   16735 		global change_vncviewer
   16736 		if {$change_vncviewer} {
   16737 			.oa.ss configure -state disabled
   16738 		}
   16739 
   16740 		set t2 "         Use ssh-agent"
   16741 		if {$uname == "Darwin" } { regsub {^ *} $t2 "" t2 }
   16742 
   16743 		button .oa.sa -anchor w -text $t2 -command ssh_agent_restart
   16744 		pack .oa.sa -side top -fill x
   16745 		if {$is_windows} {
   16746 			.oa.sa configure -state disabled
   16747 		}
   16748 	} else {
   16749 		set t1 "         Launch Putty Agent"
   16750 		button .oa.pa -anchor w -text $t1 -command {catch {exec pageant.exe &}}
   16751 		pack   .oa.pa -side top -fill x
   16752 
   16753 		set t2 "         Launch Putty Key-Gen"
   16754 		button .oa.pg -anchor w -text $t2 -command {catch {exec puttygen.exe &}}
   16755 		pack   .oa.pg -side top -fill x
   16756 	}
   16757 
   16758 	frame .oa.b
   16759 	button .oa.b.done -text "Done" -command {destroy .oa}
   16760 	bind .oa <Escape> {destroy .oa}
   16761 	wm protocol .oa WM_DELETE_WINDOW {destroy .oa}
   16762 	button .oa.b.help -text "Help" -command help_advanced_opts
   16763 
   16764 	global use_listen
   16765 	if {$use_listen} {
   16766 		button .oa.b.connect -text "Listen" -command launch
   16767 	} else {
   16768 		button .oa.b.connect -text "Connect" -command launch
   16769 	}
   16770 
   16771 	pack .oa.b.help .oa.b.connect .oa.b.done -fill x -expand 1 -side left
   16772 
   16773 	pack .oa.b -side top -fill x
   16774 
   16775 	center_win .oa
   16776 	wm resizable .oa 1 0
   16777 	focus .oa
   16778 }
   16779 
   16780 proc set_ssvncviewer_options {} {
   16781 	global is_windows darwin_cotvnc
   16782 	global use_ssh use_sshssl use_x11cursor use_rawlocal use_notty use_popupfix use_alpha use_turbovnc disable_pipeline use_grab use_nobell
   16783 	global use_send_clipboard use_send_always
   16784 	global ssvnc_scale ssvnc_escape
   16785 	global server_vencrypt server_anondh
   16786 
   16787 	if {$is_windows} {
   16788 		return
   16789 	}
   16790 
   16791 	catch {destroy .oa}
   16792 	toplev .os
   16793 	wm title .os "Unix ssvncviewer Options"
   16794 
   16795 	set darwinlist [list]
   16796 
   16797 	set f0 .os.f
   16798 	frame $f0
   16799 	set fl $f0.fl
   16800 	frame $fl
   16801 	set fr $f0.fr
   16802 	frame $fr
   16803 
   16804 	set i 1
   16805 	set j 1
   16806 
   16807 	checkbutton $fl.b$i -anchor w -variable multiple_listen -text \
   16808 		"Multiple LISTEN Connections" \
   16809 		-command {if {$multiple_listen} {multilisten_dialog}}
   16810 	global multiple_listen_button use_listen
   16811 	set multiple_listen_button $fl.b$i
   16812 	if {$is_windows}  {$fl.b$i configure -state disabled}
   16813 	if {!$use_listen} {$fl.b$i configure -state disabled}
   16814 	lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
   16815 	incr i
   16816 
   16817 	checkbutton $fl.b$i -anchor w -variable listen_once -text \
   16818 		"Listen Once"
   16819 	global listen_once_button
   16820 	set listen_once_button $fl.b$i
   16821 	if {!$use_listen} {$fl.b$i configure -state disabled}
   16822 	lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
   16823 	incr i
   16824 
   16825 	checkbutton $fl.b$i -anchor w -variable listen_accept_popup -text \
   16826 		"Listen Accept Popup Dialog" \
   16827 		-command { if {$listen_accept_popup} { catch {$listen_accept_popup_button_sc configure -state normal} } else { catch {$listen_accept_popup_button_sc  configure -state disabled} } }
   16828 	global listen_accept_popup_button
   16829 	set listen_accept_popup_button $fl.b$i
   16830 	if {!$use_listen} {$fl.b$i configure -state disabled}
   16831 	lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
   16832 	incr i
   16833 
   16834 	global listen_accept_popup
   16835 	checkbutton $fl.b$i -anchor w -variable listen_accept_popup_sc -text \
   16836 		"   Accept Popup UltraVNC Single Click"
   16837 	global listen_accept_popup_button_sc
   16838 	set listen_accept_popup_button_sc $fl.b$i
   16839 	if {!$use_listen} {$fl.b$i configure -state disabled}
   16840 	if {!$listen_accept_popup} {$fl.b$i configure -state disabled}
   16841 	lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
   16842 	incr i
   16843 
   16844 	checkbutton $fl.b$i -anchor w -variable use_x11cursor -text \
   16845 		"Use X11 Cursor"
   16846 	lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
   16847 	incr i
   16848 
   16849 	checkbutton $fl.b$i -anchor w -variable use_nobell -text \
   16850 		"Disable Bell"
   16851 	lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
   16852 	incr i
   16853 
   16854 	checkbutton $fl.b$i -anchor w -variable use_rawlocal -text \
   16855 		"Use Raw Local"
   16856 	lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
   16857 	incr i
   16858 
   16859 	checkbutton $fl.b$i -anchor w -variable use_notty -text \
   16860 		"Avoid Using Terminal"
   16861 	lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
   16862 	incr i
   16863 
   16864 	checkbutton $fl.b$i -anchor w -variable use_popupfix -text \
   16865 		"Use Popup Fix"
   16866 	lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
   16867 	incr i
   16868 
   16869 	checkbutton $fl.b$i -anchor w -variable use_grab -text \
   16870 		"Use XGrabServer (for fullscreen)" \
   16871 		-command {if {$use_grab} {use_grab_dialog}}
   16872 	lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
   16873 	incr i
   16874 
   16875 	checkbutton $fl.b$i -anchor w -variable use_alpha -text \
   16876 		"Cursor Alphablending (32bpp required)     "
   16877 	lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
   16878 	incr i
   16879 
   16880 	checkbutton $fl.b$i -anchor w -variable use_turbovnc -text \
   16881 		"TurboVNC (if available on platform)"
   16882 	lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
   16883 	incr i
   16884 
   16885 	checkbutton $fl.b$i -anchor w -variable disable_pipeline -text \
   16886 		"Disable Pipelined Updates"
   16887 	lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
   16888 	incr i
   16889 
   16890 	checkbutton $fl.b$i -anchor w -variable use_send_clipboard -text \
   16891 		"Send CLIPBOARD not PRIMARY"
   16892 	lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
   16893 	incr i
   16894 
   16895 	checkbutton $fl.b$i -anchor w -variable use_send_always -text \
   16896 		"Send Selection Every time"
   16897 	lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled}
   16898 	incr i
   16899 
   16900 	set relief ridge
   16901 
   16902 	frame $fr.b$j -height 2; incr j
   16903 
   16904 	frame $fr.b$j -relief $relief -borderwidth 2
   16905 
   16906 	global ffont
   16907 	label $fr.b$j.l -font $ffont -anchor w -text "Examples: '0.75', '1024x768', 'fit' (fill screen), or 'auto' ";
   16908 
   16909 	global ssvnc_scale
   16910 	frame $fr.b$j.f
   16911 	label $fr.b$j.f.l -text "Scaling: "
   16912 	lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled}
   16913 	entry $fr.b$j.f.e -width 10 -textvariable ssvnc_scale
   16914 	lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled}
   16915 	pack $fr.b$j.f.l -side left
   16916 	pack $fr.b$j.f.e -side right -expand 1 -fill x
   16917 
   16918 	pack $fr.b$j.f $fr.b$j.l -side top -fill x
   16919 
   16920 	incr j
   16921 
   16922 	frame $fr.b$j -height 2; incr j
   16923 
   16924 	frame $fr.b$j -relief $relief -borderwidth 2
   16925 
   16926 	label $fr.b$j.l -font $ffont -anchor w -text "Examples: 'default', 'Control_L,Alt_L', 'never'";
   16927 
   16928 	global ssvnc_escape
   16929 	frame $fr.b$j.f
   16930 	label $fr.b$j.f.l -text "Escape Keys: "
   16931 	lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled}
   16932 	entry $fr.b$j.f.e -width 10 -textvariable ssvnc_escape
   16933 	lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled}
   16934 	button $fr.b$j.f.b -relief ridge -text Help -command ssvnc_escape_help
   16935 	lappend darwinlist $fr.b$j.f.b; if {$darwin_cotvnc} {$fr.b$j.f.b configure -state disabled}
   16936 	pack $fr.b$j.f.l -side left
   16937 	pack $fr.b$j.f.b -side right
   16938 	pack $fr.b$j.f.e -side right -expand 1 -fill x
   16939 
   16940 	pack $fr.b$j.f $fr.b$j.l -side top -fill x
   16941 
   16942 	incr j
   16943 
   16944 	frame $fr.b$j -height 2; incr j
   16945 
   16946 	frame $fr.b$j -relief $relief -borderwidth 2
   16947 
   16948 	label $fr.b$j.l -font $ffont -anchor w -text "Enter the max height in pixels, e.g. '900'";
   16949 
   16950 	global ycrop_string
   16951 	frame $fr.b$j.f
   16952 	label $fr.b$j.f.l -text "Y Crop: "
   16953 	lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled}
   16954 	entry $fr.b$j.f.e -width 10 -textvariable ycrop_string
   16955 	lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled}
   16956 	pack $fr.b$j.f.l -side left
   16957 	pack $fr.b$j.f.e -side right -expand 1 -fill x
   16958 
   16959 	pack $fr.b$j.f $fr.b$j.l -side top -fill x
   16960 
   16961 	incr j
   16962 
   16963 	frame $fr.b$j -height 2; incr j
   16964 
   16965 	frame $fr.b$j -relief $relief -borderwidth 2
   16966 
   16967 	label $fr.b$j.l -font $ffont -anchor w -text "Enter the scrollbar width in pixels, e.g. '4'";
   16968 
   16969 	global sbwid_string
   16970 	frame $fr.b$j.f
   16971 	label $fr.b$j.f.l -text "ScrollBar Width: "
   16972 	lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled}
   16973 	entry $fr.b$j.f.e -width 10 -textvariable sbwid_string
   16974 	lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled}
   16975 	pack $fr.b$j.f.l -side left
   16976 	pack $fr.b$j.f.e -side right -expand 1 -fill x
   16977 
   16978 	pack $fr.b$j.f $fr.b$j.l -side top -fill x
   16979 
   16980 	incr j
   16981 
   16982 	frame $fr.b$j -height 2; incr j
   16983 
   16984 	frame $fr.b$j -relief $relief -borderwidth 2
   16985 
   16986 	label $fr.b$j.l  -font $ffont -anchor w -text "Enter the RFB version to pretend to be using, e.g. '3.4'";
   16987 	label $fr.b$j.l2 -font $ffont -anchor w -text "Sometimes needed for UltraVNC: 3.4, 3.6, 3.14, 3.16";
   16988 
   16989 	global rfbversion
   16990 	frame $fr.b$j.f
   16991 	label $fr.b$j.f.l -text "RFB Version: "
   16992 	lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled}
   16993 	entry $fr.b$j.f.e -width 10 -textvariable rfbversion
   16994 	lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled}
   16995 	pack $fr.b$j.f.l -side left
   16996 	pack $fr.b$j.f.e -side right -expand 1 -fill x
   16997 
   16998 	pack $fr.b$j.f $fr.b$j.l $fr.b$j.l2  -side top -fill x
   16999 
   17000 	incr j
   17001 
   17002 	frame $fr.b$j -height 2; incr j
   17003 
   17004 	frame $fr.b$j -relief $relief -borderwidth 2
   17005 
   17006 	label $fr.b$j.l1 -font $ffont -anchor w -text "List encodings in preferred order, for example";
   17007 	label $fr.b$j.l2 -font $ffont -anchor w -text "'copyrect zrle tight'   The full list of encodings is:";
   17008 	label $fr.b$j.l3 -font $ffont -anchor w -text "copyrect tight zrle zywrle hextile zlib corre rre raw";
   17009 
   17010 	global ssvnc_encodings
   17011 	frame $fr.b$j.f
   17012 	label $fr.b$j.f.l -text "Encodings: "
   17013 	lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled}
   17014 	entry $fr.b$j.f.e -width 10 -textvariable ssvnc_encodings
   17015 	lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled}
   17016 	pack $fr.b$j.f.l -side left
   17017 	pack $fr.b$j.f.e -side right -expand 1 -fill x
   17018 
   17019 	pack $fr.b$j.f $fr.b$j.l1 $fr.b$j.l2 $fr.b$j.l3 -side top -fill x
   17020 
   17021 	incr j
   17022 
   17023 	frame $fr.b$j -height 2; incr j
   17024 
   17025 	frame $fr.b$j -relief $relief -borderwidth 2
   17026 
   17027 	label $fr.b$j.l1 -font $ffont -anchor w -text "Add any extra options for ssvncviewer that you want.";
   17028 	label $fr.b$j.l2 -font $ffont -anchor w -text "For example: -16bpp -appshare -noshm etc. See Help for a list.";
   17029 
   17030 	global ssvnc_extra_opts
   17031 	frame $fr.b$j.f
   17032 	label $fr.b$j.f.l -text "Extra Options: "
   17033 	lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled}
   17034 	entry $fr.b$j.f.e -width 10 -textvariable ssvnc_extra_opts
   17035 	lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled}
   17036 	pack $fr.b$j.f.l -side left
   17037 	pack $fr.b$j.f.e -side right -expand 1 -fill x
   17038 
   17039 	pack $fr.b$j.f $fr.b$j.l1 $fr.b$j.l2 -side top -fill x
   17040 
   17041 	incr j
   17042 
   17043 	frame $fr.b$j -height 2; incr j
   17044 
   17045 	for {set k 1} {$k < $i} {incr k} {
   17046 		pack $fl.b$k -side top -fill x
   17047 	}
   17048 	for {set k 1} {$k < $j} {incr k} {
   17049 		pack $fr.b$k -side top -fill x
   17050 	}
   17051 
   17052 	pack $fl -side left -fill both
   17053 	pack $fr -side left -fill both -expand 1
   17054 
   17055 	pack $f0 -side top -fill both
   17056 
   17057 	frame .os.b
   17058 	button .os.b.done -text "Done" -command {destroy .os}
   17059 	bind .os <Escape> {destroy .os}
   17060 	wm protocol .os WM_DELETE_WINDOW {destroy .os}
   17061 	button .os.b.help -text "Help" -command help_ssvncviewer_opts
   17062 
   17063 	global use_listen
   17064 	if {$use_listen} {
   17065 		button .os.b.connect -text "Listen" -command launch
   17066 	} else {
   17067 		button .os.b.connect -text "Connect" -command launch
   17068 	}
   17069 
   17070 	pack .os.b.help .os.b.connect .os.b.done -fill x -expand 1 -side left
   17071 
   17072 	pack .os.b -side top -fill x
   17073 
   17074 	global darwin_cotvnc_blist
   17075 	foreach b $darwinlist {
   17076 		set darwin_cotvnc_blist($b) 1
   17077 	}
   17078 
   17079 	center_win .os
   17080 	wm resizable .os 1 0
   17081 	wm minsize .os [winfo reqwidth .os] [winfo reqheight .os]
   17082 	focus .os
   17083 }
   17084 
   17085 
   17086 proc in_path {cmd} {
   17087 	global env
   17088 	set p $env(PATH)
   17089 	foreach dir [split $p ":"] {
   17090 		set try "$dir/$cmd"
   17091 		if [file exists $try] {
   17092 			return "$try"
   17093 		}
   17094 	}
   17095 	return ""
   17096 }
   17097 
   17098 proc ssh_agent_restart {} {
   17099 	global env
   17100 
   17101 	set got_ssh_agent 0
   17102 	set got_ssh_add 0
   17103 	set got_ssh_agent2 0
   17104 	set got_ssh_add2 0
   17105 
   17106 	if {[in_path "ssh-agent"]  != ""} {set got_ssh_agent 1}
   17107 	if {[in_path "ssh-agent2"] != ""} {set got_ssh_agent2 1}
   17108 	if {[in_path "ssh-add"]    != ""} {set got_ssh_add 1}
   17109 	if {[in_path "ssh-add2"]   != ""} {set got_ssh_add2 1}
   17110 
   17111 	set ssh_agent ""
   17112 	set ssh_add ""
   17113 	if {[info exists env(USER)] && $env(USER) == "runge"} {
   17114 		if {$got_ssh_agent2} {
   17115 			set ssh_agent "ssh-agent2"
   17116 		}
   17117 		if {$got_ssh_add2} {
   17118 			set ssh_add "ssh-add2"
   17119 		}
   17120 	}
   17121 	if {$ssh_agent == "" && $got_ssh_agent} {
   17122 		set ssh_agent "ssh-agent"
   17123 	}
   17124 	if {$ssh_add == "" && $got_ssh_add} {
   17125 		set ssh_add "ssh-add"
   17126 	}
   17127 	if {$ssh_agent == ""} {
   17128 		bell
   17129 		mesg "could not find ssh-agent in PATH"
   17130 		return
   17131 	}
   17132 	if {$ssh_add == ""} {
   17133 		bell
   17134 		mesg "could not find ssh-add in PATH"
   17135 		return
   17136 	}
   17137 	set tmp $env(SSVNC_HOME)/.vnc-sa[tpid]
   17138 	set tmp [mytmp $tmp]
   17139 	set fh ""
   17140 	catch {set fh [open $tmp "w"]}
   17141 	if {$fh == ""} {
   17142 		bell
   17143 		mesg "could not open tmp file $tmp"
   17144 		return
   17145 	}
   17146 
   17147 	puts $fh "#!/bin/sh"
   17148 	puts $fh "eval `$ssh_agent -s`"
   17149 	puts $fh "$ssh_add"
   17150 	puts $fh "SSVNC_GUI_CHILD=\"\""
   17151 	puts $fh "export SSVNC_GUI_CHILD"
   17152 
   17153 	global buck_zero
   17154 	set cmd $buck_zero
   17155 
   17156 	if [info exists env(SSVNC_GUI_CMD)] {
   17157 		set cmd $env(SSVNC_GUI_CMD)
   17158 	}
   17159 	#puts $fh "$cmd </dev/null 1>/dev/null 2>/dev/null &"
   17160 	puts $fh "nohup $cmd &"
   17161 	puts $fh "sleep 1"
   17162 	puts $fh "rm -f $tmp"
   17163 	close $fh
   17164 
   17165 	wm withdraw .
   17166 	catch {wm withdraw .o}
   17167 	catch {wm withdraw .oa}
   17168 
   17169 	unix_terminal_cmd "+200+200" "Restarting with ssh-agent/ssh-add" "sh $tmp" 1
   17170 	after 10000
   17171 	destroy .
   17172 	exit
   17173 }
   17174 
   17175 proc putty_pw_entry {mode} {
   17176 	if {$mode == "check"} {
   17177 		global use_sshssl use_ssh
   17178 		if {$use_sshssl || $use_ssh} {
   17179 			putty_pw_entry enable
   17180 		} else {
   17181 			putty_pw_entry disable
   17182 		}
   17183 		return
   17184 	}
   17185 	if {$mode == "disable"} {
   17186 		catch {.o.pw.l configure -state disabled}
   17187 		catch {.o.pw.e configure -state disabled}
   17188 	} else {
   17189 		catch {.o.pw.l configure -state normal}
   17190 		catch {.o.pw.e configure -state normal}
   17191 	}
   17192 }
   17193 proc adv_ssh_tog {on} {
   17194 	global adv_ssh
   17195 	foreach b {cups snd smb redirs knownhosts} {
   17196 		if [info exists adv_ssh($b)] {
   17197 			if {$on} {
   17198 				catch {$adv_ssh($b) configure -state normal}
   17199 			} else {
   17200 				catch {$adv_ssh($b) configure -state disabled}
   17201 			}
   17202 		}
   17203 	}
   17204 }
   17205 
   17206 proc adv_listen_ssl_tog {on} {
   17207 	global stunnel_local_protection_button is_windows
   17208 	global disable_ssl_workarounds_button
   17209 	global vencrypt_button no_probe_vencrypt_button anondh_button ultra_dsm_button
   17210 
   17211 	set blist [list]
   17212 	if [info exists stunnel_local_protection_button] {
   17213 		lappend blist $stunnel_local_protection_button
   17214 	}
   17215 	if [info exists disable_ssl_workarounds_button] {
   17216 		lappend blist $disable_ssl_workarounds_button
   17217 	}
   17218 	if [info exists ultra_dsm_button] {
   17219 		lappend blist $ultra_dsm_button
   17220 	}
   17221 	if [info exists no_probe_vencrypt_button] {
   17222 		lappend blist $no_probe_vencrypt_button
   17223 	}
   17224 	if [info exists vencrypt_button] {
   17225 		lappend blist $vencrypt_button
   17226 	}
   17227 	if [info exists anondh_button] {
   17228 		lappend blist $anondh_button
   17229 	}
   17230 	foreach b $blist {
   17231 		if {$on} {
   17232 			catch {$b configure -state normal}
   17233 		} else {
   17234 			catch {$b configure -state disabled}
   17235 		}
   17236 	}
   17237 
   17238 	if {$is_windows} {
   17239 		catch {$stunnel_local_protection_button configure -state disabled}
   17240 		catch {$ultra_dsm_button                configure -state disabled}
   17241 	}
   17242 }
   17243 
   17244 proc adv_listen_ssh_tog {on} {
   17245 	global ssh_local_protection_button is_windows
   17246 	if [info exists ssh_local_protection_button] {
   17247 		if {$on} {
   17248 			catch {$ssh_local_protection_button configure -state normal}
   17249 		} else {
   17250 			catch {$ssh_local_protection_button configure -state disabled}
   17251 		}
   17252 	}
   17253 	if {$is_windows} {
   17254 		catch {$ssh_local_protection_button configure -state disabled}
   17255 	}
   17256 }
   17257 
   17258 proc ssl_ssh_adjust {which} {
   17259 	global use_ssl use_ssh use_sshssl sshssl_sw
   17260 	global remote_ssh_cmd_list
   17261 	global x11vnc_find_widget x11vnc_xlogin_widget uvnc_bug_widget
   17262 
   17263 	if {$which == "ssl"} {
   17264 		set use_ssl 1
   17265 		set use_ssh 0
   17266 		set use_sshssl 0
   17267 		set sshssl_sw "ssl"
   17268 		catch {.f4.getcert configure -state normal}
   17269 		catch {.f4.always  configure -state normal}
   17270 		if [info exists x11vnc_find_widget] {
   17271 			catch {$x11vnc_find_widget configure -state disabled}
   17272 		}
   17273 		if [info exists x11vnc_xlogin_widget] {
   17274 			catch {$x11vnc_xlogin_widget configure -state disabled}
   17275 		}
   17276 		if [info exists uvnc_bug_widget] {
   17277 			catch {$uvnc_bug_widget configure -state normal}
   17278 		}
   17279 		adv_ssh_tog 0
   17280 		adv_listen_ssl_tog 1
   17281 		adv_listen_ssh_tog 0
   17282 	} elseif {$which == "none"} {
   17283 		set use_ssl 0
   17284 		set use_ssh 0
   17285 		set use_sshssl 0
   17286 		set sshssl_sw "none"
   17287 		catch {.f4.getcert configure -state disabled}
   17288 		catch {.f4.always  configure -state disabled}
   17289 		if [info exists x11vnc_find_widget] {
   17290 			catch {$x11vnc_find_widget configure -state disabled}
   17291 		}
   17292 		if [info exists x11vnc_xlogin_widget] {
   17293 			catch {$x11vnc_xlogin_widget configure -state disabled}
   17294 		}
   17295 		if [info exists uvnc_bug_widget] {
   17296 			catch {$uvnc_bug_widget configure -state normal}
   17297 		}
   17298 		adv_ssh_tog 0
   17299 		adv_listen_ssl_tog 0
   17300 		adv_listen_ssh_tog 0
   17301 	} elseif {$which == "ssh"} {
   17302 		set use_ssl 0
   17303 		set use_ssh 1
   17304 		set use_sshssl 0
   17305 		set sshssl_sw "ssh"
   17306 		catch {.f4.getcert configure -state disabled}
   17307 		catch {.f4.always  configure -state disabled}
   17308 		if [info exists x11vnc_find_widget] {
   17309 			catch {$x11vnc_find_widget configure -state normal}
   17310 		}
   17311 		if [info exists x11vnc_xlogin_widget] {
   17312 			catch {$x11vnc_xlogin_widget configure -state normal}
   17313 		}
   17314 		if [info exists uvnc_bug_widget] {
   17315 			catch {$uvnc_bug_widget configure -state disabled}
   17316 		}
   17317 		adv_ssh_tog 1
   17318 		adv_listen_ssl_tog 0
   17319 		adv_listen_ssh_tog 1
   17320 	} elseif {$which == "sshssl"} {
   17321 		set use_ssl 0
   17322 		set use_ssh 0
   17323 		set use_sshssl 1
   17324 		set sshssl_sw "sshssl"
   17325 		catch {.f4.getcert configure -state disabled}
   17326 		catch {.f4.always  configure -state disabled}
   17327 		if [info exists x11vnc_find_widget] {
   17328 			catch {$x11vnc_find_widget configure -state normal}
   17329 		}
   17330 		if [info exists x11vnc_xlogin_widget] {
   17331 			catch {$x11vnc_xlogin_widget configure -state normal}
   17332 		}
   17333 		if [info exists uvnc_bug_widget] {
   17334 			catch {$uvnc_bug_widget configure -state normal}
   17335 		}
   17336 		adv_ssh_tog 1
   17337 		adv_listen_ssl_tog 1
   17338 		adv_listen_ssh_tog 1
   17339 	}
   17340 
   17341 	if [info exists remote_ssh_cmd_list] {
   17342 		if {$use_ssh || $use_sshssl} {
   17343 			foreach w $remote_ssh_cmd_list {
   17344 				$w configure -state normal
   17345 			}
   17346 		}
   17347 		if {$use_ssl || $sshssl_sw == "none"} {
   17348 			foreach w $remote_ssh_cmd_list {
   17349 				$w configure -state disabled
   17350 			}
   17351 		}
   17352 	}
   17353 
   17354 	if {! $use_ssl && ! $use_ssh && ! $use_sshssl} {
   17355 		if {$sshssl_sw != "none"} {
   17356 			set use_ssl 1
   17357 			set sshssl_sw "ssl"
   17358 		}
   17359 	}
   17360 	global ssh_only ts_only
   17361 	if {$ssh_only || $ts_only} {
   17362 		set use_ssl 0
   17363 		set use_sshssl 0
   17364 		set use_ssh 1
   17365 		set sshssl_sw "ssh"
   17366 	}
   17367 
   17368 	putty_pw_entry check
   17369 }
   17370 
   17371 proc listen_adjust {} {
   17372 	global use_listen revs_button multiple_listen_button is_windows
   17373 	global listen_once_button listen_accept_popup_button listen_accept_popup_button_sc
   17374 	if {![info exists multiple_listen_button]} {
   17375 		set multiple_listen_button "none"
   17376 	}
   17377 	if {$use_listen} {
   17378 		catch {.b.conn configure -text "Listen"}
   17379 		catch {.o.b.connect configure -text "Listen"}
   17380 		catch {$multiple_listen_button configure -state normal}
   17381 		catch {$listen_once_button configure -state normal}
   17382 		catch {$listen_accept_popup_button configure -state normal}
   17383 		catch {$listen_accept_popup_button_sc configure -state normal}
   17384 		catch {mesg "Listen :N -> Port 5500+N, i.e. :0 -> 5500, :1 -> 5501, :2 -> 5502 ..."}
   17385 	} else {
   17386 		catch {.b.conn configure -text "Connect"}
   17387 		catch {.o.b.connect configure -text "Connect"}
   17388 		catch {$multiple_listen_button configure -state disabled}
   17389 		catch {$listen_once_button configure -state disabled}
   17390 		catch {$listen_accept_popup_button configure -state disabled}
   17391 		catch {$listen_accept_popup_button_sc configure -state disabled}
   17392 		catch {mesg "Switched to Forward Connection mode."}
   17393 	}
   17394 	if {$is_windows} {
   17395 		catch {$multiple_listen_button configure -state disabled}
   17396 		catch {$listen_once_button configure -state disabled}
   17397 		catch {$listen_accept_popup_button configure -state disabled}
   17398 		catch {$listen_accept_popup_button_sc configure -state disabled}
   17399 	}
   17400 }
   17401 
   17402 proc unixpw_adjust {} {
   17403 	global is_windows use_unixpw darwin_cotvnc
   17404 	if {$is_windows || $darwin_cotvnc} {
   17405 		return;
   17406 	}
   17407 	if {$use_unixpw} {
   17408 		pack configure .fu -after .f1 -fill x
   17409 		catch {focus .fu.e}
   17410 	} else {
   17411 		pack forget .fu
   17412 	}
   17413 }
   17414 
   17415 proc x11vnc_find_adjust {which} {
   17416 	global remote_ssh_cmd
   17417 	global use_x11vnc_find x11vnc_find_widget
   17418 	global use_x11vnc_xlogin x11vnc_xlogin_widget
   17419 
   17420 	if {$which == "find"} {
   17421 		if {$use_x11vnc_find} {
   17422 			set use_x11vnc_xlogin 0
   17423 		}
   17424 	} elseif {$which == "xlogin"} {
   17425 		if {$use_x11vnc_xlogin} {
   17426 			set use_x11vnc_find 0
   17427 		}
   17428 	}
   17429 	if {! $use_x11vnc_find && ! $use_x11vnc_xlogin} {
   17430 		set remote_ssh_cmd "";
   17431 		return
   17432 	}
   17433 	if {![regexp {x11vnc} $remote_ssh_cmd]} {
   17434 		set remote_ssh_cmd "";
   17435 	}
   17436 	regsub {^[ 	]*PORT= [ 	]*} $remote_ssh_cmd "" remote_ssh_cmd
   17437 	regsub {^[ 	]*P= [ 	]*} $remote_ssh_cmd "" remote_ssh_cmd
   17438 	regsub {^[ 	]*sudo x11vnc[ 	]*} $remote_ssh_cmd "" remote_ssh_cmd
   17439 	regsub {^[ 	]*x11vnc[ 	]*} $remote_ssh_cmd "" remote_ssh_cmd
   17440 	regsub -all {[ 	]*-find[ 	]*} $remote_ssh_cmd " " remote_ssh_cmd
   17441 	regsub -all {[ 	]*-localhost[ 	]*} $remote_ssh_cmd " " remote_ssh_cmd
   17442 	regsub -all {[ 	]*-env FD_XDM=1[ 	]*} $remote_ssh_cmd " " remote_ssh_cmd
   17443 	if {$use_x11vnc_find} {
   17444 		set remote_ssh_cmd "PORT= x11vnc -find -localhost -nopw $remote_ssh_cmd"
   17445 	} else {
   17446 		set remote_ssh_cmd "PORT= sudo x11vnc -find -localhost -env FD_XDM=1 -nopw $remote_ssh_cmd"
   17447 	}
   17448 	regsub {[ 	]*$} $remote_ssh_cmd "" remote_ssh_cmd
   17449 	regsub {^[ 	]*} $remote_ssh_cmd "" remote_ssh_cmd
   17450 	regsub -all {[ 	][ 	]*} $remote_ssh_cmd " " remote_ssh_cmd
   17451 }
   17452 
   17453 proc set_darwin_cotvnc_buttons {} {
   17454 	global darwin_cotvnc uname darwin_cotvnc_blist
   17455 
   17456 	if {$uname == "Darwin" && [info exists darwin_cotvnc_blist]} {
   17457 		foreach b [array names darwin_cotvnc_blist] {
   17458 			if {$darwin_cotvnc} {
   17459 				catch {$b configure -state disabled}
   17460 			} else {
   17461 				catch {$b configure -state normal}
   17462 			}
   17463 		}
   17464 	}
   17465 }
   17466 
   17467 proc disable_encryption {} {
   17468 	global env
   17469 	if {[info exists env(SSVNC_DISABLE_ENCRYPTION_BUTTON)]} {
   17470 		set s $env(SSVNC_DISABLE_ENCRYPTION_BUTTON)
   17471 		if {$s != "" && $s != "0"} {
   17472 			return 1;
   17473 		}
   17474 	}
   17475 	return 0;
   17476 }
   17477 proc set_options {} {
   17478 	global use_alpha use_grab use_ssh use_sshssl use_viewonly use_fullscreen use_bgr233
   17479 	global use_nojpeg use_raise_on_beep use_compresslevel use_quality use_x11_macosx
   17480 	global use_send_clipboard use_send_always
   17481 	global compresslevel_text quality_text
   17482 	global env is_windows darwin_cotvnc uname
   17483 	global use_listen
   17484 	global use_x11vnc_find x11vnc_find_widget
   17485 	global use_x11vnc_xlogin x11vnc_xlogin_widget uvnc_bug_widget
   17486 	global ts_only
   17487 	global darwin_cotvnc_blist
   17488 	global showing_no_encryption no_enc_button no_enc_prev
   17489 
   17490 	if {$ts_only} {
   17491 		set_ts_options
   17492 		return
   17493 	}
   17494 
   17495 	toplev .o
   17496 	wm title .o "SSL/SSH VNC Options"
   17497 
   17498 	set i 1
   17499 
   17500 	radiobutton .o.b$i -anchor w -variable sshssl_sw -value ssl -text \
   17501 		"Use SSL" -command {ssl_ssh_adjust ssl}
   17502 	incr i
   17503 
   17504 	radiobutton .o.b$i -anchor w -variable sshssl_sw -value ssh -text \
   17505 		"Use SSH" -command {ssl_ssh_adjust ssh}
   17506 	incr i
   17507 
   17508 	radiobutton .o.b$i -anchor w -variable sshssl_sw -value sshssl -text \
   17509 		"Use SSH+SSL" -command {ssl_ssh_adjust sshssl}
   17510 	set iss $i
   17511 	set no_enc_prev .o.b$i
   17512 	incr i
   17513 
   17514 	radiobutton .o.b$i -anchor w -variable sshssl_sw -value none -text \
   17515 		"No Encryption" -command {ssl_ssh_adjust none}
   17516 	set no_enc_button .o.b$i
   17517 	set ine $i
   17518 	incr i
   17519 
   17520 	checkbutton .o.b$i -anchor w -variable use_x11vnc_find -text \
   17521 		"Automatically Find X Session" -command {x11vnc_find_adjust "find"}
   17522 	if {!$use_ssh && !$use_sshssl} {.o.b$i configure -state disabled}
   17523 	set x11vnc_find_widget ".o.b$i"
   17524 	incr i
   17525 
   17526 	if {! $is_windows} {
   17527 		checkbutton .o.b$i -anchor w -variable use_unixpw -text \
   17528 			"Unix Username & Password" -command {unixpw_adjust}
   17529 		if {$darwin_cotvnc} {.o.b$i configure -state disabled}
   17530 		set darwin_cotvnc_blist(.o.b$i) 1
   17531 		incr i
   17532 	}
   17533 
   17534 	checkbutton .o.b$i -anchor w -variable use_listen -text \
   17535 		"Reverse VNC Connection (-LISTEN)" -command {listen_adjust; if {$vncdisplay == ""} {set vncdisplay ":0"} else {set vncdisplay ""}; if {0 && $use_listen} {destroy .o}}
   17536 	#if {$is_windows} {.o.b$i configure -state disabled}
   17537 	#if {$darwin_cotvnc} {.o.b$i configure -state disabled}
   17538 	#set darwin_cotvnc_blist(.o.b$i) 1
   17539 	incr i
   17540 
   17541 	checkbutton .o.b$i -anchor w -variable use_viewonly -text \
   17542 		"View Only"
   17543 	incr i
   17544 
   17545 	checkbutton .o.b$i -anchor w -variable use_fullscreen -text \
   17546 		"Fullscreen"
   17547 	incr i
   17548 
   17549 	checkbutton .o.b$i -anchor w -variable use_raise_on_beep -text \
   17550 		"Raise On Beep"
   17551 	if {$darwin_cotvnc} {.o.b$i configure -state disabled}
   17552 	set darwin_cotvnc_blist(.o.b$i) 1
   17553 	incr i
   17554 
   17555 	checkbutton .o.b$i -anchor w -variable use_bgr233 -text \
   17556 		"Use 8bit color (-bgr233)"
   17557 	if {$darwin_cotvnc} {.o.b$i configure -state disabled}
   17558 	set darwin_cotvnc_blist(.o.b$i) 1
   17559 	incr i
   17560 
   17561 	checkbutton .o.b$i -anchor w -variable use_nojpeg -text \
   17562 		"Do not use JPEG (-nojpeg)"
   17563 	if {$darwin_cotvnc} {.o.b$i configure -state disabled}
   17564 	set darwin_cotvnc_blist(.o.b$i) 1
   17565 	incr i
   17566 
   17567 	if {$uname == "Darwin"} {
   17568 		checkbutton .o.b$i -anchor w -variable use_x11_macosx -text \
   17569 			"Use X11 vncviewer on MacOSX" \
   17570 			-command {if {$use_x11_macosx} {set darwin_cotvnc 0} else {set darwin_cotvnc 1}; set_darwin_cotvnc_buttons}
   17571 		if {$uname != "Darwin"} {.o.b$i configure -state disabled}
   17572 		incr i
   17573 	}
   17574 
   17575 	if {$is_windows} {
   17576 		global kill_stunnel
   17577 		checkbutton .o.b$i -anchor w -variable kill_stunnel -text \
   17578 			"Kill Stunnel Automatically"
   17579 		incr i
   17580 	}
   17581 
   17582 
   17583 	menubutton .o.b$i -anchor w -menu .o.b$i.m -textvariable compresslevel_text -relief groove
   17584 	set compresslevel_text "Compress Level: $use_compresslevel"
   17585 	if {$darwin_cotvnc} {.o.b$i configure -state disabled}
   17586 	set darwin_cotvnc_blist(.o.b$i) 1
   17587 
   17588 	menu .o.b$i.m -tearoff 0
   17589 	for {set j -1} {$j < 10} {incr j} {
   17590 		set v $j
   17591 		set l $j
   17592 		if {$j == -1} {
   17593 			set v "default"
   17594 			set l "default"
   17595 		}
   17596 		.o.b$i.m add radiobutton -variable use_compresslevel \
   17597 			-value $v -label $l -command \
   17598 			{set compresslevel_text "Compress Level: $use_compresslevel"}
   17599 	}
   17600 	incr i
   17601 
   17602 	menubutton .o.b$i -anchor w -menu .o.b$i.m -textvariable quality_text -relief groove
   17603 	set quality_text "Quality: $use_quality"
   17604 	if {$darwin_cotvnc} {.o.b$i configure -state disabled}
   17605 	set darwin_cotvnc_blist(.o.b$i) 1
   17606 
   17607 	menu .o.b$i.m -tearoff 0
   17608 	for {set j -1} {$j < 10} {incr j} {
   17609 		set v $j
   17610 		set l $j
   17611 		if {$j == -1} {
   17612 			set v "default"
   17613 			set l "default"
   17614 		}
   17615 		.o.b$i.m add radiobutton -variable use_quality \
   17616 			-value $v -label $l -command \
   17617 			{set quality_text "Quality: $use_quality"}
   17618 	}
   17619 	incr i
   17620 
   17621 	global use_mode ts_only ssh_only
   17622 	if {$ts_only} {
   17623 		set use_mode "Terminal Services (tsvnc)"
   17624 	} elseif {$ssh_only} {
   17625 		set use_mode "SSH-Only (sshvnc)"
   17626 	} else {
   17627 		set use_mode "SSVNC"
   17628 	}
   17629 	global mode_text
   17630 	set mode_text "Mode: $use_mode"
   17631 
   17632 	menubutton .o.b$i -anchor w -menu .o.b$i.m -textvariable mode_text -relief groove
   17633 
   17634 	menu .o.b$i.m -tearoff 0
   17635 	.o.b$i.m add radiobutton -variable use_mode -value "SSVNC"  \
   17636 		-label "SSVNC" -command { if {$ts_only || $ssh_only} {to_ssvnc; set mode_text "Mode: SSVNC"; destroy .o}}
   17637 	.o.b$i.m add radiobutton -variable use_mode -value "SSH-Only (sshvnc)" \
   17638 		-label "SSH-Only (sshvnc)" -command { if {$ts_only || ! $ssh_only} {to_sshonly; set mode_text "Mode: SSH-Only (sshvnc)"; destroy .o}}
   17639 	.o.b$i.m add radiobutton -variable use_mode -value "Terminal Services (tsvnc)" \
   17640 		-label "Terminal Services (tsvnc)" -command {to_tsonly; set mode_text "Mode: Terminal Services (tsvnc)"; destroy .o}
   17641 	incr i
   17642 
   17643 	global started_with_noenc
   17644 
   17645 	if {0 && $started_with_noenc && $showing_no_encryption} {
   17646 		;
   17647 	} elseif {$ssh_only} {
   17648 		;
   17649 	} else {
   17650 		checkbutton .o.b$i -anchor w -variable showing_no_encryption -text \
   17651 			"Show 'No Encryption' Option" -pady 5 \
   17652 			-command {toggle_no_encryption 1}
   17653 		# -relief raised
   17654 		incr i
   17655 	}
   17656 
   17657 	for {set j 1} {$j < $i} {incr j} {
   17658 		global ssh_only ts_only
   17659 		if {$ssh_only && $j <= 3} {
   17660 			continue;
   17661 		}
   17662 		if {$ts_only && $j <= 3} {
   17663 			continue;
   17664 		}
   17665 		if {!$showing_no_encryption && $j == $ine} {
   17666 			continue;
   17667 		}
   17668 
   17669 		pack .o.b$j -side top -fill x
   17670 	}
   17671 
   17672 	if {$is_windows} {
   17673 		global port_slot putty_pw
   17674 
   17675 		frame .o.pp
   17676 		frame .o.pp.fL
   17677 		frame .o.pp.fR
   17678 		label .o.pp.fL.la -anchor w -text "Putty PW:"
   17679 		label .o.pp.fL.lb -anchor w -text "Port Slot:"
   17680 		pack .o.pp.fL.la .o.pp.fL.lb -side top -fill x
   17681 
   17682 		entry .o.pp.fR.ea -width 10 -show * -textvariable putty_pw
   17683 		entry .o.pp.fR.eb -width 10 -textvariable port_slot
   17684 		pack .o.pp.fR.ea .o.pp.fR.eb  -side top -fill x
   17685 
   17686 		pack .o.pp.fL -side left
   17687 		pack .o.pp.fR -side right -expand 1 -fill x
   17688 
   17689 		pack .o.pp -side top -fill x
   17690 
   17691 		putty_pw_entry check
   17692 	}
   17693 
   17694 	global uname
   17695 	set t1 "             Advanced ..."
   17696 	set t2 "             Use Defaults"
   17697 	set t3 "             Delete Profile ..."
   17698 	if {$uname == "Darwin"} {
   17699 		regsub {^ *} $t1 "" t1
   17700 		regsub {^ *} $t2 "" t2
   17701 		regsub {^ *} $t3 "" t3
   17702 	}
   17703 
   17704 	button .o.advanced -anchor w -text $t1 -command set_advanced_options
   17705 	button .o.clear    -anchor w -text $t2 -command {set_defaults; init_vncdisplay}
   17706 	button .o.delete   -anchor w -text $t3 -command {destroy .o; delete_profile}
   17707 
   17708 	pack .o.clear -side top -fill x
   17709 	pack .o.delete -side top -fill x
   17710 	pack .o.advanced -side top -fill x
   17711 
   17712 #	pack .o.s_prof -side top -fill x
   17713 #	pack .o.l_prof -side top -fill x
   17714 
   17715 	frame .o.b
   17716 	button .o.b.done -text "Done" -command {destroy .o}
   17717 	bind .o <Escape> {destroy .o}
   17718 	wm protocol .o WM_DELETE_WINDOW {destroy .o}
   17719 	button .o.b.help -text "Help" -command help_opts
   17720 	global use_listen
   17721 	if {$use_listen} {
   17722 		button .o.b.connect -text "Listen" -command launch
   17723 	} else {
   17724 		button .o.b.connect -text "Connect" -command launch
   17725 	}
   17726 
   17727 	pack .o.b.help .o.b.connect .o.b.done -fill x -expand 1 -side left
   17728 
   17729 	pack .o.b -side top -fill x
   17730 
   17731 	center_win .o
   17732 	wm resizable .o 1 0
   17733 	focus .o
   17734 }
   17735 
   17736 proc check_writable {} {
   17737 	set test test[pid].txt
   17738 	catch {set f [open $test "w"]; puts $f "test"; close $f}
   17739 
   17740 	###catch {file delete -force $test}	# testing.
   17741 
   17742 	if ![file exists $test] {
   17743 		global env
   17744 		if [info exists env(SSVNC_HOME)] {
   17745 			set dir "$env(SSVNC_HOME)/ss_vnc/cache"
   17746 			catch {file mkdir $dir}
   17747 			if ![file exists $dir] {
   17748 				return
   17749 			}
   17750 			foreach f [glob -type f * */* */*/*] {
   17751 				set dest "$dir/$f"
   17752 				set dirn [file dirname $dest]
   17753 				catch {file mkdir $dirn}
   17754 				catch {file copy -force -- $f $dest}
   17755 			}
   17756 			cd $dir
   17757 			###catch {set f [open $test "w"]; puts $f "test"; close $f}
   17758 		}
   17759 	} else {
   17760 		catch {file delete -force $test}
   17761 	}
   17762 }
   17763 
   17764 proc print_help {} {
   17765 
   17766 	global help_main help_prox help_misc help_tips
   17767 	set b "\n============================================================================\n"
   17768 	help
   17769 	#set str [.h.f.t get 1.0 end]
   17770 	#puts "${b}Help:\n$str"
   17771 	puts "${b}Help Main:\n$help_main"
   17772 	puts "${b}Help Proxies:\n$help_prox"
   17773 	puts "${b}Help Misc:\n$help_misc"
   17774 	puts "${b}Help Tips:\n$help_tips"
   17775 	destroy .h
   17776 
   17777 	help_opts
   17778 	set str [.oh.f.t get 1.0 end]
   17779 	puts "${b}SSL/SSH Viewer Options Help:\n$str"
   17780 	destroy .oh
   17781 
   17782 	help_advanced_opts
   17783 	set str [.ah.f.t get 1.0 end]
   17784 	puts "${b}Advanced Options Help:\n$str"
   17785 	destroy .ah
   17786 
   17787 	help_ssvncviewer_opts
   17788 	set str [.av.f.t get 1.0 end]
   17789 	puts "${b}ssvncviewer Options Help:\n$str"
   17790 	destroy .av
   17791 
   17792 	help_certs
   17793 	set str [.ch.f.t get 1.0 end]
   17794 	puts "${b}SSL Certificates Help:\n$str"
   17795 	destroy .ch
   17796 
   17797 	help_fetch_cert
   17798 	set str [.fh.f.t get 1.0 end]
   17799 	puts "${b}Fetch Certificates Help:\n$str"
   17800 	destroy .fh
   17801 
   17802 	create_cert
   17803 	set str [.ccrt.f.t get 1.0 end]
   17804 	puts "${b}Create SSL Certificate Dialog:\n$str"
   17805 	destroy .ccrt
   17806 
   17807 	import_cert
   17808 	set str [.icrt.f.t get 1.0 end]
   17809 	puts "${b}Import SSL Certificate Dialog:\n$str"
   17810 	destroy .icrt
   17811 
   17812 	global cert_text
   17813 	set cert_text "empty"
   17814 	save_cert "help:0"
   17815 	set str [.scrt.f.t get 1.0 end]
   17816 	puts "${b}Save SSL Certificate Dialog:\n$str"
   17817 	destroy .scrt
   17818 
   17819 	ts_help
   17820 	set str [.h.f.t get 1.0 end]
   17821 	puts "${b}Terminal Services Help:\n$str"
   17822 	destroy .h
   17823 
   17824 	help_ts_opts
   17825 	set str [.oh.f.t get 1.0 end]
   17826 	puts "${b}Terminal Services VNC Options Help:\n$str"
   17827 	destroy .oh
   17828 
   17829 	ts_unixpw_dialog
   17830 	set str [.uxpw.f.t get 1.0 end]
   17831 	puts "${b}Terminal Services Use unixpw Dialog:\n$str"
   17832 	destroy .uxpw
   17833 
   17834 	ts_vncshared_dialog
   17835 	set str [.vncs.f.t get 1.0 end]
   17836 	puts "${b}Terminal Services VNC Shared Dialog:\n$str"
   17837 	destroy .vncs
   17838 
   17839 	ts_multi_dialog
   17840 	set str [.mult.f.t get 1.0 end]
   17841 	puts "${b}Terminal Services Multiple Sessions Dialog:\n$str"
   17842 	destroy .mult
   17843 
   17844 	ts_xlogin_dialog
   17845 	set str [.xlog.f.t get 1.0 end]
   17846 	puts "${b}Terminal Services X Login Dialog:\n$str"
   17847 	destroy .xlog
   17848 
   17849 	ts_othervnc_dialog
   17850 	set str [.ovnc.f.t get 1.0 end]
   17851 	puts "${b}Terminal Services Other VNC Server Dialog:\n$str"
   17852 	destroy .ovnc
   17853 
   17854 	ts_ncache_dialog
   17855 	set str [.nche.f.t get 1.0 end]
   17856 	puts "${b}Terminal Services Client-Side Caching Dialog:\n$str"
   17857 	destroy .nche
   17858 
   17859 	ts_x11vnc_opts_dialog
   17860 	set str [.x11v.f.t get 1.0 end]
   17861 	puts "${b}Terminal Services x11vnc Options Dialog:\n$str"
   17862 	destroy .x11v
   17863 
   17864 	ts_filexfer_dialog
   17865 	set str [.xfer.f.t get 1.0 end]
   17866 	puts "${b}Terminal Services File Transfer Dialog:\n$str"
   17867 	destroy .xfer
   17868 
   17869 	ts_sound_dialog
   17870 	set str [.snd.f.t get 1.0 end]
   17871 	puts "${b}Terminal Services Sound Tunnelling Dialog:\n$str"
   17872 	destroy .snd
   17873 
   17874 	ts_cups_dialog
   17875 	set str [.cups.f.t get 1.0 end]
   17876 	puts "${b}Terminal Services CUPS Dialog:\n$str"
   17877 	destroy .cups
   17878 
   17879 	help_ssvncviewer_opts
   17880 	set str [.av.f.t get 1.0 end]
   17881 	puts "${b}Unix SSVNC viewer Options Help:\n$str"
   17882 	destroy .av
   17883 
   17884 	change_vncviewer_dialog
   17885 	set str [.chviewer.t get 1.0 end]
   17886 	puts "${b}Unix Change VNC Viewer Dialog:\n$str"
   17887 	destroy .chviewer
   17888 
   17889 	cups_dialog
   17890 	set str [.cups.f.t get 1.0 end]
   17891 	puts "${b}CUPS Dialog:\n$str"
   17892 	destroy .cups
   17893 
   17894 	sound_dialog
   17895 	set str [.snd.f.t get 1.0 end]
   17896 	puts "${b}ESD Audio Tunnelling Dialog:\n$str"
   17897 	destroy .snd
   17898 
   17899 	smb_dialog
   17900 	set str [.smb.f.t get 1.0 end]
   17901 	puts "${b}SMB Mounting Dialog:\n$str"
   17902 	destroy .smb
   17903 
   17904 	port_redir_dialog
   17905 	set str [.redirs.t get 1.0 end]
   17906 	puts "${b}Additional Port Redirections Dialog:\n$str"
   17907 	destroy .redirs
   17908 
   17909 	port_knocking_dialog
   17910 	set str [.pk.f.t get 1.0 end]
   17911 	puts "${b}Port Knocking Dialog:\n$str"
   17912 	destroy .pk
   17913 
   17914 	ssvnc_escape_help
   17915 	set str [.ekh.f.t get 1.0 end]
   17916 	puts "${b}SSVNC Escape Keys Help:\n$str"
   17917 	destroy .ekh
   17918 
   17919 	stunnel_sec_dialog
   17920 	set str [.stlsec.f.t get 1.0 end]
   17921 	puts "${b}STUNNEL Local Port Protections Dialog:\n$str"
   17922 	destroy .stlsec
   17923 
   17924 	disable_ssl_workarounds_dialog
   17925 	set str [.sslwrk.f.t get 1.0 end]
   17926 	puts "${b}Disable SSL Workarounds Dialog:\n$str"
   17927 	destroy .sslwrk
   17928 
   17929 	ultra_dsm_dialog
   17930 	set str [.ultradsm.f.t get 1.0 end]
   17931 	puts "${b}UltraVNC DSM Encryption Plugin Dialog:\n$str"
   17932 	destroy .ultradsm
   17933 
   17934 	ssh_known_hosts_dialog
   17935 	set str [.sshknownhosts.f.t get 1.0 end]
   17936 	puts "${b}Private SSH KnownHosts file Dialog:\n$str"
   17937 	destroy .sshknownhosts
   17938 
   17939 	ssh_sec_dialog
   17940 	set str [.sshsec.t get 1.0 end]
   17941 	puts "${b}SSH Local Port Protections Dialog:\n$str"
   17942 	destroy .sshsec
   17943 
   17944 	multilisten_dialog
   17945 	set str [.multil.t get 1.0 end]
   17946 	puts "${b}Multiple LISTEN Connections Dialog:\n$str"
   17947 	destroy .multil
   17948 
   17949 	use_grab_dialog
   17950 	set str [.usegrb.t get 1.0 end]
   17951 	puts "${b}Use XGrabServer (for fullscreen) Dialog:\n$str"
   17952 	destroy .usegrb
   17953 }
   17954 
   17955 proc zeroconf_fill {b m} {
   17956 	global is_windows zeroconf_command last_post
   17957 
   17958 	if {$is_windows} {
   17959 		return;
   17960 	}
   17961 
   17962 	if {![info exists last_post]} {
   17963 		set last_post 0
   17964 	}
   17965 	set now [clock seconds]
   17966 	if {$now < [expr $last_post + 10]} {
   17967 		# cache menu for 10 secs.
   17968 		return
   17969 	}
   17970 
   17971 	.  config -cursor {watch}
   17972 	$b config -cursor {watch}
   17973 	$b configure -state disabled
   17974 
   17975 	$m delete 0 end
   17976 	update
   17977 
   17978 	set emsg ""
   17979 	set output ""
   17980 	set none "No VNC servers detected"
   17981 
   17982 	set rc 1
   17983 	set rd 0
   17984 	if {$zeroconf_command == "avahi-browse"} {
   17985 		set rc [catch {set output [exec avahi-browse -r -t -p -k _rfb._tcp 2>/dev/null]} emsg]
   17986 	} elseif {$zeroconf_command == "dns-sd"} {
   17987 		set rc [catch {set output [exec /bin/sh -c {pid=$$; export pid; (sleep 1; kill $pid) & exec dns-sd -B _rfb._tcp} 2>/dev/null]} emsg]
   17988 		set rd 1
   17989 	} elseif {$zeroconf_command == "mDNS"} {
   17990 		set rc [catch {set output [exec /bin/sh -c {pid=$$; export pid; (sleep 1; kill $pid) & exec mDNS   -B _rfb._tcp} 2>/dev/null]} emsg]
   17991 		set rd 1
   17992 	}
   17993 
   17994 	#puts "rc=$rc output=$output"
   17995 	if {$rd == 1 && $rc != 0} {
   17996 		if [regexp {_rfb} $emsg] {
   17997 			set rc 0
   17998 			set output $emsg
   17999 		}
   18000 	}
   18001 
   18002 	set count 0
   18003 
   18004 	if {$rc != 0} {
   18005 		$m add command -label $none
   18006 		incr count
   18007 
   18008 	} elseif {$output == "" || [regexp {^[ \t\n]*$} $output]} {
   18009 		$m add command -label $none
   18010 		incr count
   18011 
   18012 	} elseif {$zeroconf_command == "avahi-browse"} {
   18013 		set lines [split $output "\n"]
   18014 		set saw("__none__") 1
   18015 		foreach line $lines {
   18016 			set items [split $line ";"]
   18017 			if {[llength $items] != 10} {
   18018 				continue
   18019 			}
   18020 			if {[lindex $items 0] != "="} {
   18021 				continue
   18022 			}
   18023 
   18024 			# =;eth0;IPv4;tmp2\0582;_rfb._tcp;local;tmp2.local;10.0.2.252;5902;
   18025 			set eth  [lindex $items 1]
   18026 			set ipv  [lindex $items 2]
   18027 			set name [lindex $items 3]
   18028 			set type [lindex $items 4]
   18029 			set loc  [lindex $items 5]
   18030 			set host [lindex $items 6]
   18031 			set ip   [lindex $items 7]
   18032 			set port [lindex $items 8]
   18033 
   18034 			if {![regexp -nocase {ipv4} $ipv]} {
   18035 				continue
   18036 			}
   18037 
   18038 			set name0 $name
   18039 			regsub -all {\\\\} $name "__bockslosh__" name
   18040 			regsub -all {\\\.} $name "." name
   18041 
   18042 			set n 0
   18043 			while {1} {
   18044 				incr n
   18045 				if {$n > 100} {
   18046 					break
   18047 				}
   18048 				if {[regexp {\\[0-9][0-9][0-9]} $name match]} {
   18049 					#puts "match1=$match"
   18050 					regsub {\\} $match "" match
   18051 					set d $match
   18052 					regsub {^0*} $d "" d
   18053 					set c [format "%c" $d]
   18054 					if {"$c" == "&"}  {
   18055 						set c "\\$c"
   18056 					}
   18057 					regsub "\\\\$match" $name $c name
   18058 					#puts "match: $match  c='$c'\nname=$name"
   18059 				} else {
   18060 					break
   18061 				}
   18062 			}
   18063 
   18064 			regsub -all {__bockslosh__} $name "\\" name
   18065 
   18066 			set hp $host
   18067 			if {$port >= 5900 && $port <= 6100} {
   18068 				set d [expr $port - 5900]
   18069 				set hp "$host:$d"
   18070 			} else {
   18071 				set hp "$host:$port"
   18072 			}
   18073 			if {![info exists saw($name)]} {
   18074 				regsub -all {[^[:alnum:],./:@%_=+-]} $hp "" hp
   18075 				$m add command -label "$name - $hp" -command "set vncdisplay \"$hp\""
   18076 				incr count
   18077 				set p $port
   18078 				if {$p <= 200} {
   18079 					set p "-$port"
   18080 				}
   18081 				regsub -all {[^[:alnum:],./:@%_=+-]} "$ip:$p" "" ipp
   18082 				$m add command -label "$name - $ipp" -command "set vncdisplay \"$ipp\""
   18083 				incr count
   18084 				set saw($name) 1
   18085 			}
   18086 		}
   18087 	} else {
   18088 		set lines [split $output "\n"]
   18089 		set saw("__none__") 1
   18090 		global dns_sd_cache last_dns_sd
   18091 		if {![info exists last_dns_sd]} {
   18092 			set last_dns_sd 0
   18093 		}
   18094 		if {[clock seconds] > [expr $last_dns_sd + 1800]} {
   18095 			catch { unset dns_sd_cache }
   18096 			set last_dns_sd [clock seconds]
   18097 		}
   18098 		foreach line $lines {
   18099 			if [regexp -nocase {^Browsing} $line] {
   18100 				continue;
   18101 			}
   18102 			if [regexp -nocase {^Timestamp} $line] {
   18103 				continue;
   18104 			}
   18105 			if [regexp -nocase {killed:} $line] {
   18106 				continue;
   18107 			}
   18108 			if {![regexp {_rfb\._tcp} $line]} {
   18109 				continue;
   18110 			}
   18111 			regsub {[ \t\n]*$} $line "" line
   18112 			regsub {^.*_rfb\._tcp[^ ]*  *} $line "" name
   18113 
   18114 			if {[info exists saw($name)]} {
   18115 				continue
   18116 			}
   18117 			set saw($name) 1
   18118 
   18119 			set hp "$name"
   18120 			if {[info exists dns_sd_cache($name)]} {
   18121 				set hp $dns_sd_cache($name)
   18122 			} else {
   18123 				global env
   18124 				regsub -all {"} $name "" name2
   18125 				set env(DNS_SD_LU) $name2
   18126 				set emsg ""
   18127 				if {$zeroconf_command == "dns-sd"} {
   18128 					set rc [catch {set output [exec /bin/sh -c {pid=$$; export pid; (sleep 1; kill $pid) & exec dns-sd -L "$DNS_SD_LU" _rfb._tcp .} 2>/dev/null]} emsg]
   18129 				} elseif {$zeroconf_command == "mDNS"} {
   18130 					set rc [catch {set output [exec /bin/sh -c {pid=$$; export pid; (sleep 1; kill $pid) & exec mDNS   -L "$DNS_SD_LU" _rfb._tcp .} 2>/dev/null]} emsg]
   18131 					regsub -all {[ \t][ \t]*:} $emsg ":" emsg
   18132 				}
   18133 				regsub -all {  *} $emsg " " emsg
   18134 				if [regexp -nocase {be reached at  *([^ \t\n][^ \t\n]*)} $emsg match hpm] {
   18135 					if [regexp {^(.*):([0-9][0-9]*)$} $hpm mv hm pm] {
   18136 						if {$pm >= 5900 && $pm <= 6100} {
   18137 							set pm [expr $pm - 5900]
   18138 						}
   18139 						set hp "$hm:$pm"
   18140 					} else {
   18141 						set hp $hpm
   18142 					}
   18143 					set dns_sd_cache($name) $hp
   18144 				} else {
   18145 					set hp "$name"
   18146 					if {![regexp {:[0-9][0-9]*$} $hp]} {
   18147 						set hp "$name:0"
   18148 					}
   18149 				}
   18150 			}
   18151 			regsub -all {[^[:alnum:],./:@%_=+-]} $hp "" hp
   18152 			$m add command -label "$name - $hp" -command "set vncdisplay \"$hp\""
   18153 			incr count
   18154 		}
   18155 	}
   18156 	$b configure -state normal
   18157 	.  config -cursor {}
   18158 	$b config -cursor {}
   18159 	if {$count == 0}  {
   18160 		$m add command -label $none
   18161 	}
   18162 	set last_post [clock seconds]
   18163 }
   18164 
   18165 proc check_zeroconf_browse {} {
   18166 	global is_windows zeroconf_command
   18167 
   18168 	set zeroconf_command ""
   18169 	if {$is_windows} {
   18170 		return 0;
   18171 	}
   18172 	set p ""
   18173 	set r [catch {set p [exec /bin/sh -c {type avahi-browse}]}]
   18174 	if {$r == 0} {
   18175 		regsub {^.* is  *} $p "" p
   18176 		regsub -all {[ \t\n\r]} $p "" p
   18177 		if [file exists $p] {
   18178 			set zeroconf_command "avahi-browse"
   18179 			return 1
   18180 		}
   18181 	}
   18182 	set p ""
   18183 	set r [catch {set p [exec /bin/sh -c {type dns-sd}]}]
   18184 	if {$r == 0} {
   18185 		regsub {^.* is  *} $p "" p
   18186 		regsub -all {[ \t\n\r]} $p "" p
   18187 		if [file exists $p] {
   18188 			set zeroconf_command "dns-sd"
   18189 			global env
   18190 			if [info exists env(USE_MDNS)] {
   18191 				# testing
   18192 				set zeroconf_command "mDNS"
   18193 			}
   18194 			return 1
   18195 		}
   18196 	}
   18197 	set p ""
   18198 	set r [catch {set p [exec /bin/sh -c {type mDNS}]}]
   18199 	if {$r == 0} {
   18200 		regsub {^.* is  *} $p "" p
   18201 		regsub -all {[ \t\n\r]} $p "" p
   18202 		if [file exists $p] {
   18203 			set zeroconf_command "mDNS"
   18204 			return 1
   18205 		}
   18206 	}
   18207 	return 0
   18208 }
   18209 
   18210 proc toggle_no_encryption {{rev 0}} {
   18211 	global showing_no_encryption
   18212 	global no_enc_button no_enc_prev
   18213 	global ts_only ssh_only
   18214 	global use_ssl use_ssh use_sshssl
   18215 
   18216 	if {$rev} {
   18217 		# reverse it first
   18218 		if {$showing_no_encryption} {
   18219 			set showing_no_encryption 0
   18220 		} else {
   18221 			set showing_no_encryption 1
   18222 		}
   18223 	}
   18224 
   18225 	if {$showing_no_encryption} {
   18226 		catch {pack forget .f4.none}
   18227 		catch {pack forget $no_enc_button}
   18228 		if {!$use_ssl && !$use_ssh && !$use_sshssl} {
   18229 			set use_ssl 1
   18230 			sync_use_ssl_ssh
   18231 		}
   18232 		set showing_no_encryption 0
   18233 	} else {
   18234 		if {$ts_only || $ssh_only} {
   18235 			return
   18236 		}
   18237 		catch {pack .f4.none -side left}
   18238 		if {![info exists no_enc_button]} {
   18239 			catch {destroy .o}
   18240 		} elseif {![winfo exists $no_enc_button]} {
   18241 			catch {destroy .o}
   18242 		} else {
   18243 			catch {pack $no_enc_button -after $no_enc_prev -fill x}
   18244 		}
   18245 		set showing_no_encryption 1
   18246 	}
   18247 }
   18248 
   18249 proc toggle_vnc_prefix {} {
   18250 	global vncdisplay
   18251 	if [regexp -nocase {^vnc://} $vncdisplay] {
   18252 		regsub -nocase {^vnc://} $vncdisplay "" vncdisplay
   18253 	} else {
   18254 		regsub -nocase {^[a-z0-9+]*://} $vncdisplay "" vncdisplay
   18255 		set vncdisplay "Vnc://$vncdisplay"
   18256 	}
   18257 	catch {.f0.e icursor end}
   18258 }
   18259 
   18260 ############################################
   18261 
   18262 global env
   18263 
   18264 if {[regexp -nocase {Windows.9} $tcl_platform(os)]} {
   18265 	set is_win9x 1
   18266 } else {
   18267 	set is_win9x 0
   18268 }
   18269 
   18270 set is_windows 0
   18271 if { [regexp -nocase {Windows} $tcl_platform(os)]} {
   18272 	set is_windows 1
   18273 }
   18274 
   18275 set uname ""
   18276 if {! $is_windows} {
   18277 	catch {set uname [exec uname]}
   18278 }
   18279 
   18280 set ffont "fixed"
   18281 
   18282 global have_ipv6
   18283 set have_ipv6 ""
   18284 check_for_ipv6
   18285 
   18286 # need to check if "fixed" font under XFT on tk8.5 is actually fixed width!!
   18287 if {$tcl_platform(platform) == "unix"} {
   18288 	set ls ""
   18289 	catch {set ls [font metrics $ffont -linespace]}
   18290 	set fs ""
   18291 	catch {set fs [font metrics $ffont -fixed]}
   18292 	set redo 0
   18293 	if {$fs != "" && $fs != "1"} {
   18294 		set redo 1
   18295 	}
   18296 	if {$ls != "" && $ls > 14} {
   18297 		set redo 1
   18298 	}
   18299 	if {$redo} {
   18300 		foreach fn [font names] {
   18301 			if {$fn == "TkFixedFont"} {
   18302 				set ffont $fn
   18303 				break
   18304 			}
   18305 		}
   18306 	}
   18307 	catch {option add *Dialog.msg.font {helvetica -14 bold}}
   18308 	catch {option add *Dialog.msg.wrapLength 4i}
   18309 }
   18310 
   18311 if {$uname == "Darwin"} {
   18312 	set ffont "Monaco 10"
   18313 
   18314 	#option add *Button.font Helvetica widgetDefault
   18315 	catch {option add *Button.font {System 10} widgetDefault}
   18316 }
   18317 
   18318 # set SSVNC_HOME to HOME in case we modify it for mobile use:
   18319 if [info exists env(HOME)] {
   18320 	if {! [info exists env(SSVNC_HOME)]} {
   18321 		set env(SSVNC_HOME) $env(HOME)
   18322 	}
   18323 }
   18324 
   18325 # For mobile use, e.g. from a USB flash drive, we look for a "home" or "Home"
   18326 # directory relative to this script where the profiles and certs will be kept
   18327 # by default.
   18328 if [file exists $buck_zero] {
   18329 	#puts "$buck_zero"
   18330 	set up [file dirname $buck_zero]
   18331 
   18332 	if {$up == "."} {
   18333 		# this is actually bad news on windows because we cd'd to util.
   18334 		set up ".."
   18335 	} else {
   18336 		set up [file dirname $up]
   18337 	}
   18338 	set dirs [list $up]
   18339 
   18340 	if {! $is_windows && $up != ".."} {
   18341 		# get rid of bin
   18342 		set up [file dirname $up]
   18343 		lappend dirs $up
   18344 	}
   18345 
   18346 	for {set i 0} {$i < $argc} {incr i} {
   18347 		set it0 [lindex $argv $i]
   18348 		if {$it0 == "."} {
   18349 			if {![file isdirectory "$up/home"] && ![file isdirectory "$up/Home"]} {
   18350 				catch {file mkdir "$up/Home"}
   18351 			}
   18352 			break
   18353 		}
   18354 	}
   18355 
   18356 	set gotone 0
   18357 
   18358 	foreach d $dirs {
   18359 		set try "$d/home"
   18360 		#puts "$try"
   18361 		if [file isdirectory $try] {
   18362 			set env(SSVNC_HOME) $try
   18363 			set gotone 1
   18364 			break
   18365 		}
   18366 		set try "$d/Home"
   18367 		#puts "$try"
   18368 		if [file isdirectory $try] {
   18369 			set env(SSVNC_HOME) $try
   18370 			set gotone 1
   18371 			break
   18372 		}
   18373 	}
   18374 	if {$gotone} {
   18375 		set b ""
   18376 		if {$is_windows} {
   18377 			set b "$env(SSVNC_HOME)/ss_vnc"
   18378 		} else {
   18379 			set b "$env(SSVNC_HOME)/.vnc"
   18380 		}
   18381 		catch {file mkdir $b}
   18382 		catch {file mkdir "$b/certs"}
   18383 		catch {file mkdir "$b/profiles"}
   18384 	}
   18385 	#puts "HOME: $env(SSVNC_HOME)"
   18386 }
   18387 
   18388 global svcert_default mycert_default crlfil_default
   18389 global svcert_default_force mycert_default_force crlfil_default_force
   18390 set svcert_default ""
   18391 set mycert_default ""
   18392 set crlfil_default ""
   18393 set svcert_default_force 0
   18394 set mycert_default_force 0
   18395 set crlfil_default_force 0
   18396 
   18397 set saw_ts_only 0
   18398 set saw_ssh_only 0
   18399 
   18400 set ssvncrc $env(SSVNC_HOME)/.ssvncrc
   18401 if {$is_windows} {
   18402 	set ssvncrc $env(SSVNC_HOME)/ssvnc_rc
   18403 }
   18404 
   18405 global ts_desktop_size_def ts_desktop_depth_def ts_desktop_type_def ts_xserver_type_def
   18406 set ts_desktop_size_def ""
   18407 set ts_desktop_depth_def ""
   18408 set ts_desktop_type_def ""
   18409 set ts_xserver_type_def ""
   18410 
   18411 global win_localhost
   18412 set win_localhost "127.0.0.1"
   18413 
   18414 global kill_stunnel
   18415 set kill_stunnel 1
   18416 
   18417 global started_with_noenc
   18418 
   18419 if {! [info exists env(SSVNC_DISABLE_ENCRYPTION_BUTTON)]} {
   18420 	set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 1
   18421 	set started_with_noenc 1
   18422 } else {
   18423 	if {$env(SSVNC_DISABLE_ENCRYPTION_BUTTON) == "0"} {
   18424 		set started_with_noenc 0
   18425 	} elseif {$env(SSVNC_DISABLE_ENCRYPTION_BUTTON) == "1"} {
   18426 		set started_with_noenc 1
   18427 	} else {
   18428 		set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 1
   18429 		set started_with_noenc 1
   18430 	}
   18431 }
   18432 
   18433 if [file exists $ssvncrc] {
   18434 	set fh ""
   18435 	catch {set fh [open $ssvncrc "r"]}
   18436 	if {$fh != ""} {
   18437 		while {[gets $fh line] > -1} {
   18438 			set str [string trim $line]
   18439 			if [regexp {^#} $str] {
   18440 				continue
   18441 			}
   18442 			if [regexp {^mode=tsvnc} $str] {
   18443 				set saw_ts_only 1
   18444 				set saw_ssh_only 0
   18445 			} elseif [regexp {^mode=sshvnc} $str] {
   18446 				set saw_ts_only 0
   18447 				set saw_ssh_only 1
   18448 			} elseif [regexp {^mode=ssvnc} $str] {
   18449 				set saw_ts_only 0
   18450 				set saw_ssh_only 0
   18451 			}
   18452 			if [regexp {^desktop_type=(.*)$} $str m val] {
   18453 				set val [string trim $val]
   18454 				set ts_desktop_type_def $val
   18455 			}
   18456 			if [regexp {^desktop_size=(.*)$} $str m val] {
   18457 				set val [string trim $val]
   18458 				set ts_desktop_size_def $val
   18459 			}
   18460 			if [regexp {^desktop_depth=(.*)$} $str m val] {
   18461 				set val [string trim $val]
   18462 				set ts_desktop_depth_def $val
   18463 			}
   18464 			if [regexp {^xserver_type=(.*)$} $str m val] {
   18465 				set val [string trim $val]
   18466 				set ts_xserver_type_def $val
   18467 			}
   18468 			if [regexp {^font_default=(.*)$} $str m val] {
   18469 				set val [string trim $val]
   18470 				catch {option add *font $val}
   18471 				catch {option add *Dialog.msg.font $val}
   18472 			}
   18473 			if [regexp {^font_fixed=(.*)$} $str m val] {
   18474 				set val [string trim $val]
   18475 				set ffont $val
   18476 			}
   18477 			if [regexp {^noenc=1} $str] {
   18478 				global env
   18479 				set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 1
   18480 				set started_with_noenc 1
   18481 			}
   18482 			if [regexp {^noenc=0} $str] {
   18483 				global env
   18484 				set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 0
   18485 				set started_with_noenc 0
   18486 			}
   18487 			if [regexp {^cotvnc=1} $str] {
   18488 				global env
   18489 				set env(SSVNC_COTVNC) 1
   18490 			}
   18491 			if [regexp {^cotvnc=0} $str] {
   18492 				global env
   18493 				set env(SSVNC_COTVNC) 0
   18494 			}
   18495 			if [regexp {^killstunnel=1} $str] {
   18496 				set kill_stunnel 1
   18497 			}
   18498 			if [regexp {^killstunnel=0} $str] {
   18499 				set kill_stunnel 0
   18500 			}
   18501 			global have_ipv6
   18502 			if [regexp {^ipv6=1} $str] {
   18503 				set have_ipv6 1
   18504 				set env(SSVNC_IPV6) 1
   18505 			}
   18506 			if [regexp {^ipv6=0} $str] {
   18507 				set have_ipv6 0
   18508 				set env(SSVNC_IPV6) 0
   18509 			}
   18510 			if [regexp {^mycert=(.*)$} $str m val] {
   18511 				set val [string trim $val]
   18512 				set mycert_default $val
   18513 			}
   18514 			if [regexp {^cert=(.*)$} $str m val] {
   18515 				set val [string trim $val]
   18516 				set mycert_default $val
   18517 			}
   18518 			if [regexp {^cacert=(.*)$} $str m val] {
   18519 				set val [string trim $val]
   18520 				set svcert_default $val
   18521 			}
   18522 			if [regexp {^ca=(.*)$} $str m val] {
   18523 				set val [string trim $val]
   18524 				set svcert_default $val
   18525 			}
   18526 			if [regexp {^crl=(.*)$} $str m val] {
   18527 				set val [string trim $val]
   18528 				set crlfil_default $val
   18529 			}
   18530 			if [regexp {^env=([^=]*)=(.*)$} $str m var val] {
   18531 				global env
   18532 				set env($var) $val
   18533 			}
   18534 		}
   18535 		close $fh
   18536 	}
   18537 }
   18538 
   18539 for {set i 0} {$i < $argc} {incr i} {
   18540 	set item [lindex $argv $i]
   18541 	regsub {^--} $item "-" item
   18542 	if {$item == "-profiles" || $item == "-list"} {
   18543 		set dir [get_profiles_dir]
   18544 		#puts stderr "VNC Profiles:"
   18545 		#puts stderr " "
   18546 		if {[info exists env(SSVNC_TS_ONLY)]} {
   18547 			set saw_ts_only 1
   18548 		} elseif {[info exists env(SSVNC_SSH_ONLY)]} {
   18549 			set saw_ssh_only 1
   18550 		}
   18551 		set profs [list]
   18552 		foreach prof [glob -nocomplain -directory $dir "*.vnc"] {
   18553 			set s [file tail $prof]
   18554 			regsub {\.vnc$} $s "" s
   18555 			if {$saw_ts_only || $saw_ssh_only} {
   18556 				set ok 0;
   18557 				set tsok 0;
   18558 				set fh ""
   18559 				catch {set fh [open $prof "r"]}
   18560 				if {$fh != ""} {
   18561 					while {[gets $fh line] > -1} {
   18562 						if {[regexp {use_ssh=1} $line]} {
   18563 							set ok 1
   18564 						}
   18565 						if {[regexp {ts_mode=1} $line]} {
   18566 							set tsok 1
   18567 						}
   18568 					}
   18569 					close $fh
   18570 				}
   18571 				if {$saw_ts_only && !$tsok} {
   18572 					continue;
   18573 				} elseif {! $ok} {
   18574 					continue
   18575 				}
   18576 			}
   18577 			lappend profs $s
   18578 		}
   18579 		foreach prof [lsort $profs] {
   18580 			puts "$prof"
   18581 		}
   18582 		exit
   18583 	} elseif {$item == "-nvb"} {
   18584 		global env
   18585 		set env(SSVNC_NO_VERIFY_ALL_BUTTON) 1
   18586 	} elseif {$item == "-noenc"} {
   18587 		global env
   18588 		set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 1
   18589 		set started_with_noenc 1
   18590 	} elseif {$item == "-enc"} {
   18591 		global env
   18592 		set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 0
   18593 	} elseif {$item == "-bigger"} {
   18594 		global env
   18595 		if {![info exists env(SSVNC_BIGGER_DIALOG)]} {
   18596 			set env(SSVNC_BIGGER_DIALOG) 1
   18597 		}
   18598 	} elseif {$item == "-ssh"} {
   18599 		set saw_ssh_only 1
   18600 		set saw_ts_only 0
   18601 	} elseif {$item == "-ts"} {
   18602 		set saw_ts_only 1
   18603 		set saw_ssh_only 0
   18604 	} elseif {$item == "-ssl" || $item == "-ss"} {
   18605 		set saw_ts_only 0
   18606 		set saw_ssh_only 0
   18607 	} elseif {$item == "-tso"} {
   18608 		global env
   18609 		set env(SSVNC_TS_ALWAYS) 1
   18610 		set saw_ts_only 1
   18611 	} elseif {$item == "-killstunnel"} {
   18612 		set kill_stunnel 1
   18613 	} elseif {$item == "-nokillstunnel"} {
   18614 		set kill_stunnel 0
   18615 	} elseif {$item == "-mycert" || $item == "-cert"} {
   18616 		incr i
   18617 		set mycert_default [lindex $argv $i]
   18618 	} elseif {$item == "-cacert" || $item == "-ca"} {
   18619 		incr i
   18620 		set svcert_default [lindex $argv $i]
   18621 	} elseif {$item == "-crl"} {
   18622 		incr i
   18623 		set crlfil_default [lindex $argv $i]
   18624 	}
   18625 }
   18626 
   18627 if [info exists env(SSVNC_FONT_FIXED)] {
   18628 	set ffont $env(SSVNC_FONT_FIXED)
   18629 }
   18630 
   18631 if [info exists env(SSVNC_FONT_DEFAULT)] {
   18632 	catch {option add *font $env(SSVNC_FONT_DEFAULT)}
   18633 	catch {option add *Dialog.msg.font $env(SSVNC_FONT_DEFAULT)}
   18634 }
   18635 
   18636 if [regexp {[ 	]} $ffont] {
   18637 	set help_font "-font \"$ffont\""
   18638 } else {
   18639 	set help_font "-font $ffont"
   18640 }
   18641 
   18642 if { [regexp -nocase {Windows} $tcl_platform(os)]} {
   18643 	cd util
   18644 	if {$help_font == "-font fixed"} {
   18645 		set help_font ""
   18646 	}
   18647 }
   18648 
   18649 if {$saw_ts_only && $saw_ssh_only} {
   18650 	set saw_ssh_only 0
   18651 }
   18652 
   18653 global ssh_only
   18654 set ssh_only 0
   18655 if {[info exists env(SSVNC_SSH_ONLY)] || $saw_ssh_only} {
   18656 	set ssh_only 1
   18657 }
   18658 
   18659 global ts_only
   18660 set ts_only 0
   18661 if {[info exists env(SSVNC_TS_ONLY)] || $saw_ts_only} {
   18662 	set ts_only 1
   18663 }
   18664 
   18665 if {$mycert_default != ""} {
   18666 	if [regexp -nocase {^FORCE:} $mycert_default] {
   18667 		set mycert_default_force 1
   18668 		regsub -nocase {^FORCE:} $mycert_default "" mycert_default
   18669 	}
   18670 	if {![file exists $mycert_default]} {
   18671 		set idir [get_idir_certs ""]
   18672 		set mycert_default "$idir/$mycert_default"
   18673 	}
   18674 }
   18675 
   18676 if {$svcert_default != ""} {
   18677 	if [regexp -nocase {^FORCE:} $svcert_default] {
   18678 		set svcert_default_force 1
   18679 		regsub -nocase {^FORCE:} $svcert_default "" svcert_default
   18680 	}
   18681 	if {![file exists $svcert_default]} {
   18682 		set idir [get_idir_certs ""]
   18683 		if {$svcert_default == "CA"} {
   18684 			set svcert_default "$idir/CA/cacert.pem"
   18685 		} else {
   18686 			set svcert_default "$idir/$svcert_default"
   18687 		}
   18688 	}
   18689 }
   18690 
   18691 if {$crlfil_default != ""} {
   18692 	if [regexp -nocase {^FORCE:} $crlfil_default] {
   18693 		set crlfil_default_force 1
   18694 		regsub -nocase {^FORCE:} $crlfil_default "" crlfil_default
   18695 	}
   18696 	if {![file exists $crlfil_default]} {
   18697 		set idir [get_idir_certs ""]
   18698 		set crlfil_default "$idir/$crlfil_default"
   18699 	}
   18700 }
   18701 
   18702 if {$is_windows} {
   18703 	check_writable
   18704 }
   18705 
   18706 
   18707 set darwin_cotvnc 0
   18708 if {$uname == "Darwin"} {
   18709 	if {! [info exists env(DISPLAY)]} {
   18710 		set darwin_cotvnc 1
   18711 	} elseif {[regexp {/tmp/} $env(DISPLAY)]} {
   18712 		set darwin_cotvnc 1
   18713 	}
   18714 	if [info exists env(SSVNC_HOME)] {
   18715 		set t "$env(SSVNC_HOME)/.vnc"
   18716 		if {! [file exists $t]} {
   18717 			catch {file mkdir $t}
   18718 		}
   18719 	}
   18720 }
   18721 
   18722 ##for testing macosx
   18723 if [info exists env(FORCE_DARWIN)] {
   18724 	set uname Darwin
   18725 	set darwin_cotvnc 1
   18726 }
   18727 
   18728 set putty_pw ""
   18729 
   18730 global scroll_text_focus
   18731 set scroll_text_focus 1
   18732 
   18733 set multientry 1
   18734 
   18735 wm withdraw .
   18736 if {$ssh_only} {
   18737 	wm title . "SSH VNC Viewer"
   18738 } elseif {$ts_only} {
   18739 	wm title . "Terminal Services VNC Viewer"
   18740 } else {
   18741 	wm title . "SSL/SSH VNC Viewer"
   18742 }
   18743 
   18744 wm resizable . 1 0
   18745 
   18746 set_defaults
   18747 if {$uname == "Darwin"} {
   18748 	if [info exists use_x11_macosx] {
   18749 		if {$use_x11_macosx} {
   18750 			set darwin_cotvnc 0
   18751 		}
   18752 	}
   18753 }
   18754 set skip_pre 0
   18755 
   18756 set vncdisplay ""
   18757 set last_load ""
   18758 set vncproxy ""
   18759 set remote_ssh_cmd ""
   18760 set vncauth_passwd ""
   18761 
   18762 global did_listening_message
   18763 set did_listening_message 0
   18764 
   18765 global accepted_cert_dialog_in_progress
   18766 set accepted_cert_dialog_in_progress 0
   18767 
   18768 global fetch_cert_filename
   18769 set fetch_cert_filename ""
   18770 
   18771 set vhd "VNC Host:Display"
   18772 if {$ssh_only} {
   18773 	label .l -text "SSH VNC Viewer" -relief ridge
   18774 } elseif {$ts_only} {
   18775 	label .l -text "Terminal Services VNC Viewer" -relief ridge
   18776 	set vhd "VNC Terminal Server:"
   18777 } else {
   18778 	label .l -text "SSL/SSH VNC Viewer" -relief ridge
   18779 }
   18780 
   18781 set wl 21
   18782 set we 40
   18783 frame .f0
   18784 if {$multientry} {
   18785 	label .f0.l -width $wl -anchor w -text "$vhd" -relief ridge
   18786 } else {
   18787 	label .f0.l -anchor w -text "$vhd" -relief ridge
   18788 }
   18789 entry .f0.e -width $we -textvariable vncdisplay
   18790 pack  .f0.l -side left
   18791 bind  .f0.e <Return> launch
   18792 bind  .f0.e <Control-E> {toggle_vnc_prefix}
   18793 pack  .f0.e -side left -expand 1 -fill x
   18794 
   18795 if {[check_zeroconf_browse]} {
   18796 	menubutton .f0.mb -relief ridge -menu .f0.mb.m -text "Find"
   18797 	menu .f0.mb.m -tearoff 0 -postcommand {zeroconf_fill .f0.mb .f0.mb.m}
   18798 	pack  .f0.mb -side left
   18799 }
   18800 
   18801 frame .f1
   18802 label .f1.l -width $wl -anchor w -text "VNC Password:" -relief ridge
   18803 entry .f1.e -width $we -textvariable vncauth_passwd -show *
   18804 pack  .f1.l -side left
   18805 pack  .f1.e -side left -expand 1 -fill x
   18806 bind  .f1.e <Return> launch
   18807 
   18808 frame .fu
   18809 label .fu.l -width $wl -anchor w -text "Unix Username:" -relief ridge
   18810 entry .fu.e -width 14 -textvariable unixpw_username
   18811 label .fu.m -anchor w -text "Unix Password:" -relief ridge
   18812 entry .fu.f -textvariable unixpw_passwd -show *
   18813 pack  .fu.l -side left
   18814 pack  .fu.e .fu.m -side left
   18815 pack  .fu.f -side left -expand 1 -fill x
   18816 bind  .fu.f <Return> launch
   18817 
   18818 frame .f2
   18819 label .f2.l -width $wl -anchor w -text "Proxy/Gateway:" -relief ridge
   18820 entry .f2.e -width $we -textvariable vncproxy
   18821 pack  .f2.l -side left
   18822 pack  .f2.e -side left -expand 1 -fill x
   18823 bind  .f2.e <Return> launch
   18824 
   18825 frame .f3
   18826 label .f3.l -width $wl -anchor w -text "Remote SSH Command:" -relief ridge
   18827 entry .f3.e -width $we -textvariable remote_ssh_cmd
   18828 pack  .f3.l -side left
   18829 pack  .f3.e -side left -expand 1 -fill x
   18830 .f3.l configure -state disabled
   18831 .f3.e configure -state disabled
   18832 bind  .f3.e <Return> launch
   18833 
   18834 set remote_ssh_cmd_list {.f3.e .f3.l}
   18835 
   18836 frame .f4
   18837 radiobutton .f4.ssl -anchor w    -variable sshssl_sw -value ssl    -command {ssl_ssh_adjust ssl}    -text "Use SSL"
   18838 radiobutton .f4.ssh -anchor w    -variable sshssl_sw -value ssh    -command {ssl_ssh_adjust ssh}    -text "Use SSH"
   18839 radiobutton .f4.sshssl -anchor w -variable sshssl_sw -value sshssl -command {ssl_ssh_adjust sshssl} -text "SSH+SSL"
   18840 pack .f4.ssl .f4.ssh .f4.sshssl -side left -fill x
   18841 
   18842 set showing_no_encryption 0
   18843 radiobutton .f4.none   -anchor w -variable sshssl_sw -value none   -command {ssl_ssh_adjust none}   -text "None   "
   18844 if [disable_encryption] {
   18845 	pack .f4.none -side left
   18846 	set showing_no_encryption 1
   18847 }
   18848 
   18849 global skip_verify_accepted_certs
   18850 set skip_verify_accepted_certs 0
   18851 global anon_dh_detected
   18852 set anon_dh_detected 0
   18853 global vencrypt_detected
   18854 set vencrypt_detected ""
   18855 
   18856 global always_verify_ssl
   18857 set always_verify_ssl 1;
   18858 if {[info exists env(SSVNC_NO_VERIFY_ALL)]} {
   18859 	set always_verify_ssl 0;
   18860 }
   18861 
   18862 if {$uname == "Darwin"} {
   18863 	button .f4.getcert -command {fetch_cert 1} -text "Fetch Cert"
   18864 } else {
   18865 	button .f4.getcert -command {fetch_cert 1} -text "Fetch Cert" -padx 3
   18866 }
   18867 checkbutton .f4.always -variable always_verify_ssl -text "Verify All Certs" -command no_certs_tutorial_mesg
   18868 pack .f4.getcert -side right -fill x
   18869 if {[info exists env(SSVNC_NO_VERIFY_ALL_BUTTON)]} {
   18870 	set always_verify_ssl 0;
   18871 } else {
   18872 	pack .f4.always -side right -fill x
   18873 }
   18874 
   18875 if {$ssh_only || $ts_only} {
   18876 	ssl_ssh_adjust ssh
   18877 } else {
   18878 	ssl_ssh_adjust ssl
   18879 }
   18880 
   18881 frame .b
   18882 button .b.help  -text "Help" -command help
   18883 button .b.certs -text "Certs ..." -command getcerts
   18884 button .b.opts  -text "Options ..." -command set_options
   18885 button .b.load  -text "Load" -command {load_profile}
   18886 button .b.save  -text "Save" -command {save_profile}
   18887 button .b.conn  -text "Connect" -command launch
   18888 button .b.exit  -text "Exit" -command {destroy .; exit}
   18889 
   18890 
   18891 if {$ssh_only || $ts_only} {
   18892 	pack          .b.opts .b.save .b.load .b.conn .b.help .b.exit -side left -expand 1 -fill x
   18893 } else {
   18894 	pack .b.certs .b.opts .b.save .b.load .b.conn .b.help .b.exit -side left -expand 1 -fill x
   18895 }
   18896 
   18897 if {$multientry} {
   18898 	if {! $is_windows} {
   18899 		if {$ssh_only} {
   18900 			pack .l .f0 .f1 .f2 .f3     .b -side top -fill x
   18901 		} elseif {$ts_only} {
   18902 			pack .l .f0     .f2         .b -side top -fill x
   18903 		} else {
   18904 			pack .l .f0 .f1 .f2 .f3 .f4 .b -side top -fill x
   18905 		}
   18906 	} else {
   18907 		if {$ssh_only} {
   18908 			pack .l .f0     .f2 .f3     .b -side top -fill x
   18909 		} elseif {$ts_only} {
   18910 			pack .l .f0     .f2         .b -side top -fill x
   18911 		} else {
   18912 			pack .l .f0     .f2 .f3 .f4 .b -side top -fill x
   18913 		}
   18914 	}
   18915 } else {
   18916 	pack .l .f0 .b -side top -fill x
   18917 }
   18918 if {![info exists env(SSVNC_GUI_CHILD)] || $env(SSVNC_GUI_CHILD) == ""} {
   18919 	center_win .
   18920 }
   18921 focus .f0.e
   18922 
   18923 wm deiconify .
   18924 
   18925 global system_button_face
   18926 set system_button_face ""
   18927 foreach item [.b.help configure -bg] {
   18928 	set system_button_face $item
   18929 }
   18930 
   18931 if {[info exists env(SSVNC_GUI_CMD)]} {
   18932 	set env(SSVNC_GUI_CHILD) 1
   18933 	bind . <Control-n> "exec $env(SSVNC_GUI_CMD) &"
   18934 }
   18935 bind . <Control-q> "destroy .; exit"
   18936 bind . <Shift-Escape> "destroy .; exit"
   18937 bind . <Control-s> "launch_shell_only"
   18938 bind . <Control-p> {port_knock_only "" "KNOCK"}
   18939 bind . <Control-P> {port_knock_only "" "FINISH"}
   18940 bind . <Control-l> {load_profile}
   18941 bind . <B3-ButtonRelease> {load_profile}
   18942 
   18943 bind . <Control-t> {toggle_tsonly}
   18944 bind . <Control-d> {delete_profile}
   18945 bind . <Shift-B3-ButtonRelease> {toggle_tsonly}
   18946 bind . <Shift-B2-ButtonRelease> {toggle_tsonly}
   18947 bind .l <Shift-ButtonRelease> {toggle_tsonly}
   18948 bind . <Control-h> {toggle_sshonly}
   18949 bind . <Control-T> {to_ssvnc}
   18950 bind . <Control-a> {set_advanced_options}
   18951 bind . <Control-o> {set_options}
   18952 bind . <Control-u> {set_ssvncviewer_options}
   18953 bind . <Control-e> {toggle_no_encryption}
   18954 
   18955 global entered_gui_top button_gui_top
   18956 set entered_gui_top 0
   18957 set button_gui_top 0
   18958 bind . <Enter> {set entered_gui_top 1}
   18959 bind .l <ButtonPress> {set button_gui_top 1}
   18960 bind .f0.l <ButtonPress> {set button_gui_top 1}
   18961 
   18962 update
   18963 
   18964 mac_raise
   18965 
   18966 set didload 0
   18967 
   18968 for {set i 0} {$i < $argc} {incr i} {
   18969 	set item [lindex $argv $i]
   18970 	regsub {^--} $item "-" item
   18971 	if {$item == "."} {
   18972 		;
   18973 	} elseif {$item == "-nv"} {
   18974 		set always_verify_ssl 0
   18975 	} elseif {$item == "-help"} {
   18976 		help
   18977 	} elseif {$item == "-ssh"} {
   18978 		;
   18979 	} elseif {$item == "-bigger"} {
   18980 		;
   18981 	} elseif {$item == "-ts"} {
   18982 		;
   18983 	} elseif {$item == "-ss"} {
   18984 		;
   18985 	} elseif {$item == "-ssl"} {
   18986 		;
   18987 	} elseif {$item == "-tso"} {
   18988 		;
   18989 	} elseif {$item == "-mycert" || $item == "-cert"} {
   18990 		incr i
   18991 	} elseif {$item == "-cacert" || $item == "-ca"} {
   18992 		incr i
   18993 	} elseif {$item == "-crl"} {
   18994 		incr i
   18995 	} elseif {$item == "-printhelp"} {
   18996 		print_help
   18997 		exit;
   18998 	} elseif {$item != ""} {
   18999 		if {[file exists $item] && [file isfile $item]}  {
   19000 			set didload 1
   19001 			load_profile . $item
   19002 		} else {
   19003 			set ok 0
   19004 			set dir [get_profiles_dir]
   19005 			set try "$dir/$item"
   19006 			foreach try [list $dir/$item $dir/$item.vnc] {
   19007 				if {[file exists $try] && [file isfile $try]} {
   19008 					load_profile . $try
   19009 					set ok 1
   19010 					break;
   19011 				}
   19012 			}
   19013 			if {! $ok && [regexp {:[0-9][0-9]*$} $item]} {
   19014 				global vncdisplay
   19015 				set vncdisplay $item
   19016 				set ok 1
   19017 			}
   19018 
   19019 			if {! $ok} {
   19020 			    if {$ts_only || $ssh_only} {
   19021 				global vncdisplay
   19022 				set vncdisplay $item
   19023 				set ok 1
   19024 			    }
   19025 			}
   19026 			if {$ok} {
   19027 				update
   19028 				set didload 1
   19029 				if [info exists env(SSVNC_PROFILE_LOADONLY)] {
   19030 					if {$env(SSVNC_PROFILE_LOADONLY) == "1"} {
   19031 						set ok 0
   19032 					}
   19033 				}
   19034 				if {$ok} {
   19035 					after 750
   19036 					launch
   19037 				}
   19038 			}
   19039 		}
   19040 	}
   19041 }
   19042